mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-01-26 21:33:53 +01:00
check bad move
This commit is contained in:
parent
28698a982d
commit
ac332d5e98
@ -22,6 +22,7 @@ gBattleAI_ScriptsTable:: @ 82DBEF8
|
||||
.4byte AI_DoubleBattle @ AI_SCRIPT_DOUBLE_BATTLE
|
||||
.4byte AI_HPAware @ AI_SCRIPT_HP_AWARE
|
||||
|
||||
AI_TryToFaint:
|
||||
|
||||
AI_CheckBadMove:
|
||||
if_target_is_ally AI_Ret
|
||||
@ -3402,36 +3403,7 @@ AI_CV_DragonDance2:
|
||||
AI_CV_DragonDance_End:
|
||||
end
|
||||
|
||||
AI_TryToFaint:
|
||||
if_target_is_ally AI_Ret
|
||||
if_can_faint AI_TryToFaint_Can
|
||||
get_how_powerful_move_is
|
||||
if_equal MOVE_POWER_DISCOURAGED, Score_Minus1
|
||||
AI_TryToFaint2:
|
||||
if_type_effectiveness AI_EFFECTIVENESS_x4, AI_TryToFaint_DoubleSuperEffective
|
||||
goto AI_TryToFaint_CheckIfDanger
|
||||
AI_TryToFaint_DoubleSuperEffective:
|
||||
if_random_less_than 80, AI_TryToFaint_CheckIfDanger
|
||||
score +2
|
||||
goto AI_TryToFaint_CheckIfDanger
|
||||
AI_TryToFaint_Can:
|
||||
if_effect EFFECT_EXPLOSION, AI_TryToFaint_CheckIfDanger
|
||||
if_user_faster AI_TryToFaint_ScoreUp4
|
||||
if_move_flag FLAG_HIGH_CRIT, AI_TryToFaint_ScoreUp4
|
||||
score +2
|
||||
goto AI_TryToFaint_CheckIfDanger
|
||||
AI_TryToFaint_ScoreUp4:
|
||||
score +4
|
||||
AI_TryToFaint_CheckIfDanger:
|
||||
if_user_faster AI_TryToFaint_End
|
||||
if_ai_can_go_down AI_TryToFaint_Danger
|
||||
AI_TryToFaint_End:
|
||||
end
|
||||
AI_TryToFaint_Danger:
|
||||
get_how_powerful_move_is
|
||||
if_not_equal MOVE_POWER_BEST, Score_Minus1
|
||||
score +1
|
||||
goto AI_TryToFaint_End
|
||||
|
||||
|
||||
AI_SetupFirstTurn:
|
||||
if_target_is_ally AI_Ret
|
||||
|
@ -5,6 +5,8 @@
|
||||
#define AI_CHECK_FASTER 0 // if_user_faster
|
||||
#define AI_CHECK_SLOWER 1 // if_target_faster
|
||||
|
||||
#define FOE(battler) ((battler ^ BIT_SIDE) & BIT_SIDE)
|
||||
|
||||
void RecordLastUsedMoveByTarget(void);
|
||||
bool32 IsBattlerAIControlled(u32 battlerId);
|
||||
void ClearBattlerMoveHistory(u8 battlerId);
|
||||
@ -20,11 +22,73 @@ void RestoreBattlerData(u8 battlerId);
|
||||
|
||||
u32 GetHealthPercentage(u8 battler);
|
||||
bool32 IsBattlerTrapped(u8 battler, bool8 switching);
|
||||
bool32 IsBattlerFaster(u8 battler);
|
||||
bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk);
|
||||
s32 AI_GetAbility(u32 battlerId);
|
||||
u16 AI_GetHoldEffect(u32 battlerId);
|
||||
u32 AI_GetMoveAccuracy(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u8 atkHoldEffect, u8 defHoldEffect, u16 move);
|
||||
bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move);
|
||||
bool32 AI_WeatherHasEffect(void);
|
||||
bool32 CanAttackerFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index);
|
||||
s32 CountUsablePartyMons(u8 battlerId);
|
||||
bool32 IsPartyFullyHealedExceptBattler(u8 battler);
|
||||
bool32 AI_IsBattlerGrounded(u8 battlerId);
|
||||
bool32 BattlerHasDamagingMove(u8 battlerId);
|
||||
bool32 BattlerHasSecondaryDamage(u8 battlerId);
|
||||
bool32 BattlerWillFaintFromWeather(u8 battler, u16 ability);
|
||||
bool32 ShouldTryOHKO(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u32 accuracy, u16 move);
|
||||
bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 battlerDef, u32 recoilDmg, u8 moveIndex);
|
||||
u16 GetBattlerSideSpeedAverage(u8 battler);
|
||||
|
||||
// stat stage checks
|
||||
bool32 AnyStatIsRaised(u8 battlerId);
|
||||
bool32 BattlerStatCanFall(u8 battler, u16 battlerAbility, u8 stat);
|
||||
bool32 BattlerStatCanRise(u8 battler, u16 battlerAbility, u8 stat);
|
||||
bool32 AreBattlersStatsMaxed(u8 battler);
|
||||
bool32 BattlerHasAnyStatRaised(u8 battlerId);
|
||||
u32 CountPositiveStatStages(u8 battlerId);
|
||||
u32 CountNegativeStatStages(u8 battlerId);
|
||||
bool32 BattlerShouldRaiseAttacks(u8 battlerId, u16 ability);
|
||||
|
||||
// move checks
|
||||
u8 GetMovePowerResult(u16 move);
|
||||
u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef);
|
||||
u8 GetMoveEffectiveness(u16 move);
|
||||
bool32 IsBattlerFaster(u8 battler);
|
||||
bool32 CanTargetFaintAi(void);
|
||||
s32 AI_GetAbility(u32 battlerId, bool32 guess);
|
||||
u8 AI_GetMoveEffectiveness(u16 move);
|
||||
u16 *GetMovesArray(u32 battler);
|
||||
bool32 IsConfusionMoveEffect(u16 moveEffect);
|
||||
bool32 HasMoveWithSplit(u32 battler, u32 split);
|
||||
bool32 HasMoveWithType(u32 battler, u8 type);
|
||||
bool32 TestMoveFlagsInMoveset(u8 battler, u32 flags);
|
||||
bool32 IsAromaVeilProtectedMove(u16 move);
|
||||
bool32 IsNonVolatileStatusMoveEffect(u16 moveEffect);
|
||||
bool32 IsStatLoweringMoveEffect(u16 moveEffect);
|
||||
bool32 IsMoveRedirectionPrevented(u16 move, u16 atkAbility);
|
||||
bool32 IsMoveEncouragedToHit(u8 battlerAtk, u8 battlerDef, u16 move);
|
||||
bool32 IsHazardMoveEffect(u16 moveEffect);
|
||||
bool32 MoveCallsOtherMove(u16 move);
|
||||
bool32 MoveRequiresRecharging(u16 move);
|
||||
bool32 IsInstructBannedMove(u16 move);
|
||||
|
||||
// status checks
|
||||
bool32 AI_ShouldPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
|
||||
bool32 AI_ShouldPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
|
||||
bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
|
||||
bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof);
|
||||
bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
|
||||
bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
|
||||
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender);
|
||||
|
||||
// partner logic
|
||||
u16 GetAllyChosenMove(void);
|
||||
bool32 IsValidDoubleBattle(u8 battlerAtk);
|
||||
bool32 IsTargetingPartner(u8 battlerAtk, u8 battlerDef);
|
||||
bool32 DoesPartnerHaveSameMoveEffect(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove);
|
||||
bool32 PartnerHasSameMoveEffectWithoutTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove);
|
||||
bool32 PartnerMoveEffectIsStatusSameTarget(u8 battlerAtkPartner, u8 battlerDef, u16 partnerMove);
|
||||
bool32 PartnerMoveEffectIsWeather(u8 battlerAtkPartner, u16 partnerMove);
|
||||
bool32 PartnerMoveEffectIsTerrain(u8 battlerAtkPartner, u16 partnerMove);
|
||||
bool32 PartnerMoveIs(u8 battlerAtkPartner, u16 partnerMove, u16 moveCheck);
|
||||
bool32 PartnerMoveIsSameAsAttacker(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove);
|
||||
bool32 PartnerMoveIsSameNoTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove);
|
||||
|
||||
#endif //GUARD_BATTLE_AI_UTIL_H
|
@ -6,6 +6,12 @@
|
||||
#define WINDOW_CLEAR 0x1
|
||||
#define WINDOW_x80 0x80
|
||||
|
||||
struct StatFractions
|
||||
{
|
||||
u8 dividend;
|
||||
u8 divisor;
|
||||
};
|
||||
|
||||
s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbility);
|
||||
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
u8 GetBattlerTurnOrderNum(u8 battlerId);
|
||||
@ -26,8 +32,11 @@ u32 IsFlowerVeilProtected(u32 battler);
|
||||
u32 IsLeafGuardProtected(u32 battler);
|
||||
bool32 IsShieldsDownProtected(u32 battler);
|
||||
u32 IsAbilityStatusProtected(u32 battler);
|
||||
bool32 CanCamouflage(u8 battlerId);
|
||||
u16 GetNaturePowerMove(void);
|
||||
|
||||
extern void (* const gBattleScriptingCommandsTable[])(void);
|
||||
extern const u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4];
|
||||
extern const struct StatFractions gAccuracyStageRatios[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPT_COMMANDS_H
|
||||
|
@ -130,5 +130,19 @@ void ClearIllusionMon(u32 battlerId);
|
||||
bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId);
|
||||
bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battlerId);
|
||||
u8 GetBattleMoveSplit(u32 moveId);
|
||||
bool32 TestMoveFlags(u16 move, u32 flag);
|
||||
struct Pokemon *GetBattlerPartyData(u8 battlerId);
|
||||
bool32 CanFling(u8 battlerId);
|
||||
bool32 IsTelekinesisBannedSpecies(u16 species);
|
||||
bool32 IsHealBlockPreventingMove(u32 battler, u32 move);
|
||||
|
||||
// ability checks
|
||||
bool32 IsRolePlayBannedAbilityAtk(u16 ability);
|
||||
bool32 IsRolePlayBannedAbility(u16 ability);
|
||||
bool32 IsSkillSwapBannedAbility(u16 ability);
|
||||
bool32 IsWorrySeedBannedAbility(u16 ability);
|
||||
bool32 IsGastroAcidBannedAbility(u16 ability);
|
||||
bool32 IsEntrainmentBannedAbilityAttacker(u16 ability);
|
||||
bool32 IsEntrainmentTargetOrSimpleBeamBannedAbility(u16 ability);
|
||||
|
||||
#endif // GUARD_BATTLE_UTIL_H
|
||||
|
@ -220,6 +220,8 @@
|
||||
#define SIDE_STATUS_CRAFTY_SHIELD (1 << 20)
|
||||
#define SIDE_STATUS_MAT_BLOCK (1 << 21)
|
||||
|
||||
#define SIDE_HAZARDS_ANY (SIDE_STATUS_SPIKES | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES | SIDE_STATUS_STEALTH_ROCK)
|
||||
|
||||
// Field affecting statuses.
|
||||
#define STATUS_FIELD_MAGIC_ROOM 0x1
|
||||
#define STATUS_FIELD_TRICK_ROOM 0x2
|
||||
|
@ -35,20 +35,24 @@
|
||||
#define MOVE_POWER_GOOD 2 // Similar dmg range with best.
|
||||
#define MOVE_POWER_WEAK 3 // Significantly lower than best and good.
|
||||
|
||||
// script's table id to bit
|
||||
#define AI_SCRIPT_CHECK_BAD_MOVE (1 << 0)
|
||||
#define AI_SCRIPT_TRY_TO_FAINT (1 << 1)
|
||||
#define AI_SCRIPT_CHECK_VIABILITY (1 << 2)
|
||||
#define AI_SCRIPT_SETUP_FIRST_TURN (1 << 3)
|
||||
#define AI_SCRIPT_RISKY (1 << 4)
|
||||
#define AI_SCRIPT_PREFER_STRONGEST_MOVE (1 << 5)
|
||||
#define AI_SCRIPT_PREFER_BATON_PASS (1 << 6)
|
||||
#define AI_SCRIPT_DOUBLE_BATTLE (1 << 7)
|
||||
#define AI_SCRIPT_HP_AWARE (1 << 8)
|
||||
#define AI_SCRIPT_UNKNOWN (1 << 9)
|
||||
// 10 - 28 are not used
|
||||
#define AI_SCRIPT_ROAMING (1 << 29)
|
||||
#define AI_SCRIPT_SAFARI (1 << 30)
|
||||
#define AI_SCRIPT_FIRST_BATTLE (1 << 31)
|
||||
// AI Flags. Most run specific functions to update score, new flags are used for internal logic in other scripts
|
||||
#define AI_FLAG_CHECK_BAD_MOVE (1 << 0)
|
||||
#define AI_FLAG_TRY_TO_FAINT (1 << 1)
|
||||
#define AI_FLAG_CHECK_VIABILITY (1 << 2)
|
||||
#define AI_FLAG_SETUP_FIRST_TURN (1 << 3)
|
||||
#define AI_FLAG_RISKY (1 << 4)
|
||||
#define AI_FLAG_PREFER_STRONGEST_MOVE (1 << 5)
|
||||
#define AI_FLAG_PREFER_BATON_PASS (1 << 6)
|
||||
#define AI_FLAG_DOUBLE_BATTLE (1 << 7)
|
||||
#define AI_FLAG_HP_AWARE (1 << 8)
|
||||
// Flags that don't run specific checks themselves, but are used in other score functions
|
||||
#define AI_FLAG_NEGATE_AWARE (1 << 9) // AI is aware of negating effects like wonder room, mold breaker, etc (eg. smart trainers). TODO unfinished
|
||||
#define AI_FLAG_HELP_PARTNER (1 << 10) // AI can try to help partner. If not set, will tend not to target partner
|
||||
#define AI_FLAG_WILL_SUICIDE (1 << 11) // AI will use explosion / self destruct / final gambit / etc
|
||||
|
||||
// 'other' ai logic flags
|
||||
#define AI_FLAG_ROAMING (1 << 29)
|
||||
#define AI_FLAG_SAFARI (1 << 30)
|
||||
#define AI_FLAG_FIRST_BATTLE (1 << 31)
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_AI_H
|
||||
|
@ -123,6 +123,7 @@
|
||||
// Item settings
|
||||
#define B_HP_BERRIES GEN_6 // In Gen4+, berries which restore hp activate immediately after hp drops to half. In gen3, the effect occurs at the end of the turn.
|
||||
#define B_BERRIES_INSTANT GEN_6 // In Gen4+, most berries activate on battle start/switch-in if applicable. In gen3, they only activate either at the move end or turn end.
|
||||
#define B_MENTAL_HERB GEN_5 // In Gen5+, mental herb cures Taunt, Encore, Heal Block, and Disable
|
||||
|
||||
// Flag settings.
|
||||
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. Eg: Replace with FLAG_UNUSED_0x264 so you can use that flag for toggling the feature.
|
||||
|
@ -136,6 +136,14 @@
|
||||
#define HOLD_EFFECT_MEMORY 153
|
||||
#define HOLD_EFFECT_PLATE 154
|
||||
|
||||
// Gen8 hold effects
|
||||
#define HOLD_EFFECT_UTILITY_UMBRELLA 155
|
||||
#define HOLD_EFFECT_EJECT_PACK 156
|
||||
#define HOLD_EFFECT_ROOM_SERVICE 157
|
||||
#define HOLD_EFFECT_BLUNDER_POLICY 158
|
||||
#define HOLD_EFFECT_HEAVY_DUTY_BOOTS 159
|
||||
#define HOLD_EFFECT_THROAT_SPRAY 160
|
||||
|
||||
#define HOLD_EFFECT_CHOICE(holdEffect)((holdEffect == HOLD_EFFECT_CHOICE_BAND || holdEffect == HOLD_EFFECT_CHOICE_SCARF || holdEffect == HOLD_EFFECT_CHOICE_SPECS))
|
||||
|
||||
#endif // GUARD_HOLD_EFFECTS_H
|
||||
|
File diff suppressed because it is too large
Load Diff
1126
src/battle_ai_util.c
1126
src/battle_ai_util.c
File diff suppressed because it is too large
Load Diff
@ -850,13 +850,13 @@ u32 GetAiScriptsInBattleFactory(void)
|
||||
int challengeNum = gSaveBlock2Ptr->frontier.factoryWinStreaks[battleMode][lvlMode] / 7;
|
||||
|
||||
if (gTrainerBattleOpponent_A == TRAINER_FRONTIER_BRAIN)
|
||||
return AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY;
|
||||
return AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY;
|
||||
else if (challengeNum < 2)
|
||||
return 0;
|
||||
else if (challengeNum < 4)
|
||||
return AI_SCRIPT_CHECK_BAD_MOVE;
|
||||
return AI_FLAG_CHECK_BAD_MOVE;
|
||||
else
|
||||
return AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY;
|
||||
return AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -813,13 +813,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
|
||||
Cmd_metalburstdamagecalculator, // 0xFF
|
||||
};
|
||||
|
||||
struct StatFractions
|
||||
{
|
||||
u8 dividend;
|
||||
u8 divisor;
|
||||
};
|
||||
|
||||
static const struct StatFractions sAccuracyStageRatios[] =
|
||||
const struct StatFractions gAccuracyStageRatios[] =
|
||||
{
|
||||
{ 33, 100}, // -6
|
||||
{ 36, 100}, // -5
|
||||
@ -1536,8 +1530,8 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
if (defAbility == ABILITY_WONDER_SKIN && gBattleMoves[move].power == 0)
|
||||
moveAcc = 50;
|
||||
|
||||
calc = sAccuracyStageRatios[buff].dividend * moveAcc;
|
||||
calc /= sAccuracyStageRatios[buff].divisor;
|
||||
calc = gAccuracyStageRatios[buff].dividend * moveAcc;
|
||||
calc /= gAccuracyStageRatios[buff].divisor;
|
||||
|
||||
if (atkAbility == ABILITY_COMPOUND_EYES)
|
||||
calc = (calc * 130) / 100; // 1.3 compound eyes boost
|
||||
@ -7646,51 +7640,25 @@ static void Cmd_various(void)
|
||||
gBattlescriptCurrInstr += 7;
|
||||
return;
|
||||
case VARIOUS_SET_SIMPLE_BEAM:
|
||||
switch (gBattleMons[gActiveBattler].ability)
|
||||
if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gActiveBattler].ability))
|
||||
{
|
||||
case ABILITY_SIMPLE:
|
||||
case ABILITY_TRUANT:
|
||||
case ABILITY_STANCE_CHANGE:
|
||||
case ABILITY_DISGUISE:
|
||||
case ABILITY_MULTITYPE:
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gActiveBattler].ability = ABILITY_SIMPLE;
|
||||
gBattlescriptCurrInstr += 7;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case VARIOUS_TRY_ENTRAINMENT:
|
||||
switch (gBattleMons[gBattlerTarget].ability)
|
||||
if (IsEntrainmentBannedAbilityAttacker(gBattleMons[gBattlerAttacker].ability)
|
||||
|| IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability))
|
||||
{
|
||||
case ABILITY_TRUANT:
|
||||
case ABILITY_MULTITYPE:
|
||||
case ABILITY_STANCE_CHANGE:
|
||||
case ABILITY_SCHOOLING:
|
||||
case ABILITY_COMATOSE:
|
||||
case ABILITY_SHIELDS_DOWN:
|
||||
case ABILITY_DISGUISE:
|
||||
case ABILITY_RKS_SYSTEM:
|
||||
case ABILITY_BATTLE_BOND:
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
return;
|
||||
}
|
||||
switch (gBattleMons[gBattlerAttacker].ability)
|
||||
{
|
||||
case ABILITY_TRACE:
|
||||
case ABILITY_FORECAST:
|
||||
case ABILITY_FLOWER_GIFT:
|
||||
case ABILITY_ZEN_MODE:
|
||||
case ABILITY_ILLUSION:
|
||||
case ABILITY_IMPOSTER:
|
||||
case ABILITY_POWER_OF_ALCHEMY:
|
||||
case ABILITY_RECEIVER:
|
||||
case ABILITY_DISGUISE:
|
||||
case ABILITY_POWER_CONSTRUCT:
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability)
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
@ -10945,6 +10913,12 @@ static void Cmd_callterrainattack(void) // nature power
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
|
||||
u16 GetNaturePowerMove(void)
|
||||
{
|
||||
//TODO terrain
|
||||
return sNaturePowerMoves[gBattleTerrain];
|
||||
}
|
||||
|
||||
static void Cmd_cureifburnedparalysedorpoisoned(void) // refresh
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON))
|
||||
@ -11111,18 +11085,20 @@ static void Cmd_tryswapitems(void) // trick
|
||||
|
||||
static void Cmd_trycopyability(void) // role play
|
||||
{
|
||||
switch (gBattleMons[gBattlerTarget].ability)
|
||||
u16 defAbility = gBattleMons[gBattlerTarget].ability;
|
||||
|
||||
if (gBattleMons[gBattlerAttacker].ability == defAbility
|
||||
|| defAbility == ABILITY_NONE
|
||||
|| IsRolePlayBannedAbilityAtk(gBattleMons[gBattlerAttacker].ability)
|
||||
|| IsRolePlayBannedAbility(defAbility))
|
||||
{
|
||||
case ABILITY_NONE:
|
||||
case ABILITY_WONDER_GUARD:
|
||||
case ABILITY_DISGUISE:
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
break;
|
||||
default:
|
||||
gBattleMons[gBattlerAttacker].ability = gBattleMons[gBattlerTarget].ability;
|
||||
gLastUsedAbility = gBattleMons[gBattlerTarget].ability;
|
||||
gBattlescriptCurrInstr += 5;
|
||||
break;
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].ability = defAbility;
|
||||
gLastUsedAbility = defAbility;
|
||||
gBattlescriptCurrInstr += 5;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11176,23 +11152,14 @@ static void Cmd_settoxicspikes(void)
|
||||
|
||||
static void Cmd_setgastroacid(void)
|
||||
{
|
||||
switch (gBattleMons[gBattlerTarget].ability)
|
||||
if (IsGastroAcidBannedAbility(gBattleMons[gBattlerTarget].ability))
|
||||
{
|
||||
case ABILITY_MULTITYPE:
|
||||
case ABILITY_STANCE_CHANGE:
|
||||
case ABILITY_SCHOOLING:
|
||||
case ABILITY_COMATOSE:
|
||||
case ABILITY_SHIELDS_DOWN:
|
||||
case ABILITY_DISGUISE:
|
||||
case ABILITY_RKS_SYSTEM:
|
||||
case ABILITY_BATTLE_BOND:
|
||||
case ABILITY_POWER_CONSTRUCT:
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
else
|
||||
{
|
||||
gStatuses3[gBattlerTarget] |= STATUS3_GASTRO_ACID;
|
||||
gBattlescriptCurrInstr += 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11261,24 +11228,13 @@ static void Cmd_setroom(void)
|
||||
|
||||
static void Cmd_tryswapabilities(void) // skill swap
|
||||
{
|
||||
switch (gBattleMons[gBattlerAttacker].ability)
|
||||
if (IsSkillSwapBannedAbility(gBattleMons[gBattlerAttacker].ability)
|
||||
|| IsSkillSwapBannedAbility(gBattleMons[gBattlerTarget].ability))
|
||||
{
|
||||
case ABILITY_NONE:
|
||||
case ABILITY_WONDER_GUARD:
|
||||
case ABILITY_DISGUISE:
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (gBattleMons[gBattlerTarget].ability)
|
||||
{
|
||||
case ABILITY_NONE:
|
||||
case ABILITY_WONDER_GUARD:
|
||||
case ABILITY_DISGUISE:
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
@ -11751,6 +11707,13 @@ static void Cmd_tryrecycleitem(void)
|
||||
}
|
||||
}
|
||||
|
||||
bool32 CanCamouflage(u8 battlerId)
|
||||
{
|
||||
if (IS_BATTLER_OF_TYPE(battlerId, sTerrainToType[gBattleTerrain]))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void Cmd_settypetoterrain(void)
|
||||
{
|
||||
if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, sTerrainToType[gBattleTerrain]))
|
||||
@ -12271,11 +12234,36 @@ static void Cmd_trainerslideout(void)
|
||||
gBattlescriptCurrInstr += 2;
|
||||
}
|
||||
|
||||
static const u16 sTelekinesisBanList[] =
|
||||
{
|
||||
SPECIES_DIGLETT,
|
||||
SPECIES_DUGTRIO,
|
||||
#ifdef POKEMON_EXPANSION
|
||||
SPECIES_DIGLETT_ALOLAN,
|
||||
SPECIES_DUGTRIO_ALOLAN,
|
||||
SPECIES_SANDYGAST,
|
||||
SPECIES_PALOSSAND,
|
||||
SPECIES_GENGAR_MEGA,
|
||||
#endif
|
||||
};
|
||||
|
||||
bool32 IsTelekinesisBannedSpecies(u16 species)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(sTelekinesisBanList); i++)
|
||||
{
|
||||
if (species == sTelekinesisBanList[i])
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void Cmd_settelekinesis(void)
|
||||
{
|
||||
if (gStatuses3[gBattlerTarget] & (STATUS3_TELEKINESIS | STATUS3_ROOTED | STATUS3_SMACKED_DOWN)
|
||||
|| gFieldStatuses & STATUS_FIELD_GRAVITY
|
||||
|| (gBattleMons[gBattlerTarget].species == SPECIES_DIGLETT || gBattleMons[gBattlerTarget].species == SPECIES_DUGTRIO))
|
||||
|| IsTelekinesisBannedSpecies(gBattleMons[gBattlerTarget].species))
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
}
|
||||
@ -12343,19 +12331,14 @@ static void Cmd_trygetbaddreamstarget(void)
|
||||
|
||||
static void Cmd_tryworryseed(void)
|
||||
{
|
||||
switch (gBattleMons[gBattlerTarget].ability)
|
||||
if (IsWorrySeedBannedAbility(gBattleMons[gBattlerTarget].ability))
|
||||
{
|
||||
case ABILITY_INSOMNIA:
|
||||
case ABILITY_MULTITYPE:
|
||||
case ABILITY_TRUANT:
|
||||
case ABILITY_STANCE_CHANGE:
|
||||
case ABILITY_DISGUISE:
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gBattlerTarget].ability = ABILITY_INSOMNIA;
|
||||
gBattlescriptCurrInstr += 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,131 @@ static const u8 sPkblToEscapeFactor[][3] = {{0, 0, 0}, {3, 5, 0}, {2, 3, 0}, {1,
|
||||
static const u8 sGoNearCounterToCatchFactor[] = {4, 3, 2, 1};
|
||||
static const u8 sGoNearCounterToEscapeFactor[] = {4, 4, 4, 4};
|
||||
|
||||
static const u16 sSkillSwapBannedAbilities[] =
|
||||
{
|
||||
ABILITY_WONDER_GUARD,
|
||||
ABILITY_MULTITYPE,
|
||||
ABILITY_ILLUSION,
|
||||
ABILITY_STANCE_CHANGE,
|
||||
ABILITY_SCHOOLING,
|
||||
ABILITY_COMATOSE,
|
||||
ABILITY_SHIELDS_DOWN,
|
||||
ABILITY_DISGUISE,
|
||||
ABILITY_RKS_SYSTEM,
|
||||
ABILITY_BATTLE_BOND,
|
||||
ABILITY_POWER_CONSTRUCT,
|
||||
ABILITY_NEUTRALIZING_GAS,
|
||||
ABILITY_ICE_FACE,
|
||||
ABILITY_HUNGER_SWITCH,
|
||||
ABILITY_GULP_MISSILE,
|
||||
};
|
||||
|
||||
static const u16 sRolePlayBannedAbilities[] =
|
||||
{
|
||||
ABILITY_TRACE,
|
||||
ABILITY_WONDER_GUARD,
|
||||
ABILITY_FORECAST,
|
||||
ABILITY_FLOWER_GIFT,
|
||||
ABILITY_MULTITYPE,
|
||||
ABILITY_ILLUSION,
|
||||
ABILITY_ZEN_MODE,
|
||||
ABILITY_IMPOSTER,
|
||||
ABILITY_STANCE_CHANGE,
|
||||
ABILITY_POWER_OF_ALCHEMY,
|
||||
ABILITY_RECEIVER,
|
||||
ABILITY_SCHOOLING,
|
||||
ABILITY_COMATOSE,
|
||||
ABILITY_SHIELDS_DOWN,
|
||||
ABILITY_DISGUISE,
|
||||
ABILITY_RKS_SYSTEM,
|
||||
ABILITY_BATTLE_BOND,
|
||||
ABILITY_POWER_CONSTRUCT,
|
||||
ABILITY_ICE_FACE,
|
||||
ABILITY_HUNGER_SWITCH,
|
||||
ABILITY_GULP_MISSILE,
|
||||
};
|
||||
|
||||
static const u16 sRolePlayBannedAttackerAbilities[] =
|
||||
{
|
||||
ABILITY_MULTITYPE,
|
||||
ABILITY_ZEN_MODE,
|
||||
ABILITY_STANCE_CHANGE,
|
||||
ABILITY_SCHOOLING,
|
||||
ABILITY_COMATOSE,
|
||||
ABILITY_SHIELDS_DOWN,
|
||||
ABILITY_DISGUISE,
|
||||
ABILITY_RKS_SYSTEM,
|
||||
ABILITY_BATTLE_BOND,
|
||||
ABILITY_POWER_CONSTRUCT,
|
||||
ABILITY_ICE_FACE,
|
||||
ABILITY_GULP_MISSILE,
|
||||
};
|
||||
|
||||
static const u16 sWorrySeedBannedAbilities[] =
|
||||
{
|
||||
ABILITY_MULTITYPE,
|
||||
ABILITY_STANCE_CHANGE,
|
||||
ABILITY_SCHOOLING,
|
||||
ABILITY_COMATOSE,
|
||||
ABILITY_SHIELDS_DOWN,
|
||||
ABILITY_DISGUISE,
|
||||
ABILITY_RKS_SYSTEM,
|
||||
ABILITY_BATTLE_BOND,
|
||||
ABILITY_POWER_CONSTRUCT,
|
||||
ABILITY_TRUANT,
|
||||
ABILITY_ICE_FACE,
|
||||
ABILITY_GULP_MISSILE,
|
||||
};
|
||||
|
||||
static const u16 sGastroAcidBannedAbilities[] =
|
||||
{
|
||||
ABILITY_MULTITYPE,
|
||||
ABILITY_STANCE_CHANGE,
|
||||
ABILITY_SCHOOLING,
|
||||
ABILITY_COMATOSE,
|
||||
ABILITY_SHIELDS_DOWN,
|
||||
ABILITY_DISGUISE,
|
||||
ABILITY_RKS_SYSTEM,
|
||||
ABILITY_BATTLE_BOND,
|
||||
ABILITY_POWER_CONSTRUCT,
|
||||
ABILITY_ICE_FACE,
|
||||
ABILITY_GULP_MISSILE,
|
||||
};
|
||||
|
||||
static const u16 sEntrainmentBannedAttackerAbilities[] =
|
||||
{
|
||||
ABILITY_TRACE,
|
||||
ABILITY_FORECAST,
|
||||
ABILITY_FLOWER_GIFT,
|
||||
ABILITY_ZEN_MODE,
|
||||
ABILITY_ILLUSION,
|
||||
ABILITY_IMPOSTER,
|
||||
ABILITY_POWER_OF_ALCHEMY,
|
||||
ABILITY_RECEIVER,
|
||||
ABILITY_DISGUISE,
|
||||
ABILITY_POWER_CONSTRUCT,
|
||||
ABILITY_NEUTRALIZING_GAS,
|
||||
ABILITY_ICE_FACE,
|
||||
ABILITY_HUNGER_SWITCH,
|
||||
ABILITY_GULP_MISSILE,
|
||||
};
|
||||
|
||||
static const u16 sEntrainmentTargetSimpleBeamBannedAbilities[] =
|
||||
{
|
||||
ABILITY_TRUANT,
|
||||
ABILITY_MULTITYPE,
|
||||
ABILITY_STANCE_CHANGE,
|
||||
ABILITY_SCHOOLING,
|
||||
ABILITY_COMATOSE,
|
||||
ABILITY_SHIELDS_DOWN,
|
||||
ABILITY_DISGUISE,
|
||||
ABILITY_RKS_SYSTEM,
|
||||
ABILITY_BATTLE_BOND,
|
||||
ABILITY_ICE_FACE,
|
||||
ABILITY_GULP_MISSILE,
|
||||
};
|
||||
|
||||
// Functions
|
||||
void HandleAction_UseMove(void)
|
||||
{
|
||||
u32 i, side, moveType, var = 4;
|
||||
@ -1325,11 +1450,11 @@ static bool32 IsGravityPreventingMove(u32 move)
|
||||
}
|
||||
}
|
||||
|
||||
static bool32 IsHealBlockPreventingMove(u32 battler, u32 move)
|
||||
bool32 IsHealBlockPreventingMove(u32 battler, u32 move)
|
||||
{
|
||||
if (!(gStatuses3[battler] & STATUS3_HEAL_BLOCK))
|
||||
return FALSE;
|
||||
|
||||
|
||||
switch (gBattleMoves[move].effect)
|
||||
{
|
||||
case EFFECT_ABSORB:
|
||||
@ -5339,10 +5464,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
|
||||
u8 ppBonuses;
|
||||
u16 move;
|
||||
|
||||
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
||||
mon = &gPlayerParty[gBattlerPartyIndexes[battlerId]];
|
||||
else
|
||||
mon = &gEnemyParty[gBattlerPartyIndexes[battlerId]];
|
||||
mon = GetBattlerPartyData(battlerId);
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
move = GetMonData(mon, MON_DATA_MOVE1 + i);
|
||||
@ -7830,3 +7952,123 @@ u8 GetBattleMoveSplit(u32 moveId)
|
||||
else
|
||||
return SPLIT_SPECIAL;
|
||||
}
|
||||
|
||||
bool32 TestMoveFlags(u16 move, u32 flag)
|
||||
{
|
||||
if (gBattleMoves[move].flags & flag)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
struct Pokemon *GetBattlerPartyData(u8 battlerId)
|
||||
{
|
||||
struct Pokemon *mon;
|
||||
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
||||
mon = &gPlayerParty[gBattlerPartyIndexes[battlerId]];
|
||||
else
|
||||
mon = &gEnemyParty[gBattlerPartyIndexes[battlerId]];
|
||||
|
||||
return mon;
|
||||
}
|
||||
|
||||
//Make sure the input bank is any bank on the specific mon's side
|
||||
bool32 CanFling(u8 battlerId)
|
||||
{
|
||||
u16 item = gBattleMons[battlerId].item;
|
||||
u16 itemEffect = ItemId_GetHoldEffect(item);
|
||||
|
||||
if (item == ITEM_NONE
|
||||
|| GetBattlerAbility(battlerId) == ABILITY_KLUTZ
|
||||
|| gFieldStatuses & STATUS_FIELD_MAGIC_ROOM
|
||||
|| gDisableStructs[battlerId].embargoTimer != 0
|
||||
|| !CanBattlerGetOrLoseItem(battlerId, item)
|
||||
//|| itemEffect == HOLD_EFFECT_PRIMAL_ORB
|
||||
|| itemEffect == HOLD_EFFECT_GEMS
|
||||
#ifdef ITEM_ABILITY_CAPSULE
|
||||
|| item == ITEM_ABILITY_CAPSULE
|
||||
#endif
|
||||
|| (ItemId_GetPocket(item) == POCKET_BERRIES && IsAbilityOnSide(battlerId, ABILITY_UNNERVE))
|
||||
|| GetPocketByItemId(item) == POCKET_POKE_BALLS)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ability checks
|
||||
bool32 IsRolePlayBannedAbilityAtk(u16 ability)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < ARRAY_COUNT(sRolePlayBannedAttackerAbilities); i++)
|
||||
{
|
||||
if (ability == sRolePlayBannedAttackerAbilities[i])
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsRolePlayBannedAbility(u16 ability)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < ARRAY_COUNT(sRolePlayBannedAbilities); i++)
|
||||
{
|
||||
if (ability == sRolePlayBannedAbilities[i])
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsSkillSwapBannedAbility(u16 ability)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < ARRAY_COUNT(sSkillSwapBannedAbilities); i++)
|
||||
{
|
||||
if (ability == sSkillSwapBannedAbilities[i])
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsWorrySeedBannedAbility(u16 ability)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < ARRAY_COUNT(sWorrySeedBannedAbilities); i++)
|
||||
{
|
||||
if (ability == sWorrySeedBannedAbilities[i])
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsGastroAcidBannedAbility(u16 ability)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < ARRAY_COUNT(sGastroAcidBannedAbilities); i++)
|
||||
{
|
||||
if (ability == sGastroAcidBannedAbilities[i])
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsEntrainmentBannedAbilityAttacker(u16 ability)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < ARRAY_COUNT(sEntrainmentBannedAttackerAbilities); i++)
|
||||
{
|
||||
if (ability == sEntrainmentBannedAttackerAbilities[i])
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsEntrainmentTargetOrSimpleBeamBannedAbility(u16 ability)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < ARRAY_COUNT(sEntrainmentTargetSimpleBeamBannedAbilities); i++)
|
||||
{
|
||||
if (ability == sEntrainmentTargetSimpleBeamBannedAbilities[i])
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
1678
src/data/trainers.h
1678
src/data/trainers.h
File diff suppressed because it is too large
Load Diff
@ -897,7 +897,7 @@ void FillHillTrainersParties(void)
|
||||
// hill trainers.
|
||||
u32 GetTrainerHillAIFlags(void)
|
||||
{
|
||||
return (AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY);
|
||||
return (AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY);
|
||||
}
|
||||
|
||||
u8 GetTrainerEncounterMusicIdInTrainerHill(u16 trainerId)
|
||||
|
Loading…
x
Reference in New Issue
Block a user