From ab75ad6d0289fe6f4e7eb30e3ef36d9136b5e9b5 Mon Sep 17 00:00:00 2001 From: Nephrite Date: Mon, 1 Jan 2024 14:03:34 +0000 Subject: [PATCH] Ability flags update (#3886) * Added five ability flags Omitted duplicate flags that are basically "can't copy" (Role Play, Receiver, Entrainment, Skill Swap), didn't bother adding Neutralizing Gas flag, * Mold Breaker and Trace * Gastro Acid, Simple Beam, Worry Seed Decided to keep the Simple Beam/Worry Seed functions * Entrainment done * Skill Swap * Doodle/Role Play + flag descriptions Also adjusted Doodle test * Wandering Spirit, Mummy, Neutralizing Gas Neutralizing Gas really only needs to check for other mons with Neutralizing Gas, otherwise unsuppressable abilities are handled separately. * Renamed flags --- include/battle_util.h | 10 - include/config/battle.h | 3 + include/pokemon.h | 7 + src/battle_ai_main.c | 21 +- src/battle_script_commands.c | 21 +- src/battle_util.c | 539 ++----------------------------- src/data/abilities.h | 224 +++++++++++++ test/battle/move_effect/doodle.c | 8 +- 8 files changed, 294 insertions(+), 539 deletions(-) diff --git a/include/battle_util.h b/include/battle_util.h index 18b27eed2c..575d18edf8 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -222,16 +222,6 @@ void RecalcBattlerStats(u32 battler, struct Pokemon *mon); bool32 IsAlly(u32 battlerAtk, u32 battlerDef); bool32 IsGen6ExpShareEnabled(void); -// Ability checks -bool32 IsSkillSwapBannedAbility(u16 ability); -bool32 IsRolePlayDoodleBannedAbility(u16 ability); -bool32 IsRolePlayDoodleBannedAbilityAttacker(u16 ability); -bool32 IsWorrySeedBannedAbility(u16 ability); -bool32 IsGastroAcidBannedAbility(u16 ability); -bool32 IsEntrainmentBannedAbility(u16 ability); -bool32 IsEntrainmentBannedAbilityAttacker(u16 ability); -bool32 IsSimpleBeamBannedAbility(u16 ability); - bool32 CanSleep(u32 battler); bool32 CanBePoisoned(u32 battlerAttacker, u32 battlerTarget); bool32 CanBeBurned(u32 battler); diff --git a/include/config/battle.h b/include/config/battle.h index acce0ac124..e963dc775b 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -71,6 +71,9 @@ #define B_PP_REDUCED_BY_SPITE GEN_LATEST // In Gen4+, Spite reduces the foe's last move's PP by 4, instead of 2 to 5. #define B_EXTRAPOLATED_MOVE_FLAGS TRUE // Adds move flags to moves that they don't officially have but would likely have if they were in the latest core series game. +// Ability data settings +#define B_UPDATED_ABILITY_DATA GEN_LATEST // Affects flags + // Move accuracy settings #define B_TOXIC_NEVER_MISS GEN_LATEST // In Gen6+, if Toxic is used by a Poison-type Pokémon, it will never miss. #define B_MINIMIZE_DMG_ACC GEN_LATEST // In Gen6+, moves that causes double damage to minimized Pokémon will also skip accuracy checks. diff --git a/include/pokemon.h b/include/pokemon.h index c95ecbf940..87d74b766c 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -514,6 +514,13 @@ struct Ability u8 name[ABILITY_NAME_LENGTH + 1]; const u8 *description; s8 aiRating; + u8 cantBeCopied:1; // cannot be copied by Role Play or Doodle + u8 cantBeSwapped:1; // cannot be swapped with Skill Swap or Wandering Spirit + u8 cantBeTraced:1; // cannot be copied by Trace - same as cantBeCopied except for Wonder Guard + u8 cantBeSuppressed:1; // cannot be negated by Gastro Acid or Neutralizing Gas + u8 cantBeOverwritten:1; // cannot be overwritten by Entrainment, Worry Seed or Simple Beam (but can be by Mummy) - same as cantBeSuppressed except for Truant + u8 breakable:1; // can be bypassed by Mold Breaker and clones + u8 failsOnImposter:1; // doesn't work on an Imposter mon; when can we actually use this? }; #define SPINDA_SPOT_WIDTH 16 diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 6aa8374b6f..ae06cdfb51 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -2153,8 +2153,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_ROLE_PLAY: if (aiData->abilities[battlerAtk] == aiData->abilities[battlerDef] || aiData->abilities[battlerDef] == ABILITY_NONE - || IsRolePlayDoodleBannedAbilityAttacker(aiData->abilities[battlerAtk]) - || IsRolePlayDoodleBannedAbility(aiData->abilities[battlerDef])) + || gAbilities[aiData->abilities[battlerAtk]].cantBeSuppressed + || gAbilities[aiData->abilities[battlerDef]].cantBeCopied) ADJUST_SCORE(-10); else if (IsAbilityOfRating(aiData->abilities[battlerAtk], 5)) ADJUST_SCORE(-4); @@ -2183,25 +2183,26 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_SKILL_SWAP: if (aiData->abilities[battlerAtk] == ABILITY_NONE || aiData->abilities[battlerDef] == ABILITY_NONE - || IsSkillSwapBannedAbility(aiData->abilities[battlerAtk]) || IsSkillSwapBannedAbility(aiData->abilities[battlerDef]) + || gAbilities[aiData->abilities[battlerAtk]].cantBeSwapped + || gAbilities[aiData->abilities[battlerDef]].cantBeSwapped || aiData->holdEffects[battlerDef] == HOLD_EFFECT_ABILITY_SHIELD) ADJUST_SCORE(-10); break; case EFFECT_WORRY_SEED: if (aiData->abilities[battlerDef] == ABILITY_INSOMNIA - || IsWorrySeedBannedAbility(aiData->abilities[battlerDef]) + || gAbilities[aiData->abilities[battlerDef]].cantBeOverwritten || aiData->holdEffects[battlerDef] == HOLD_EFFECT_ABILITY_SHIELD) ADJUST_SCORE(-10); break; case EFFECT_GASTRO_ACID: if (gStatuses3[battlerDef] & STATUS3_GASTRO_ACID - || IsGastroAcidBannedAbility(aiData->abilities[battlerDef])) + || gAbilities[aiData->abilities[battlerDef]].cantBeSuppressed) ADJUST_SCORE(-10); break; case EFFECT_ENTRAINMENT: if (aiData->abilities[battlerAtk] == ABILITY_NONE - || IsEntrainmentBannedAbilityAttacker(aiData->abilities[battlerAtk]) - || IsEntrainmentBannedAbility(aiData->abilities[battlerDef]) + || gAbilities[aiData->abilities[battlerAtk]].cantBeCopied + || gAbilities[aiData->abilities[battlerDef]].cantBeOverwritten || aiData->holdEffects[battlerAtk] == HOLD_EFFECT_ABILITY_SHIELD) ADJUST_SCORE(-10); break; @@ -2209,7 +2210,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_SIMPLE_BEAM: if (aiData->abilities[battlerDef] == ABILITY_SIMPLE - || IsSimpleBeamBannedAbility(aiData->abilities[battlerDef]) + || gAbilities[aiData->abilities[battlerDef]].cantBeOverwritten || aiData->holdEffects[battlerDef] == HOLD_EFFECT_ABILITY_SHIELD) ADJUST_SCORE(-10); break; @@ -4377,8 +4378,8 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score } break; case EFFECT_ROLE_PLAY: - if (!IsRolePlayDoodleBannedAbilityAttacker(aiData->abilities[battlerAtk]) - && !IsRolePlayDoodleBannedAbility(aiData->abilities[battlerDef]) + if (!gAbilities[aiData->abilities[battlerAtk]].cantBeSuppressed + && !gAbilities[aiData->abilities[battlerDef]].cantBeCopied && !IsAbilityOfRating(aiData->abilities[battlerAtk], 5) && IsAbilityOfRating(aiData->abilities[battlerDef], 5)) ADJUST_SCORE(2); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index efa31669e1..6cc177769f 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9329,7 +9329,7 @@ static void Cmd_various(void) case VARIOUS_SET_SIMPLE_BEAM: { VARIOUS_ARGS(const u8 *failInstr); - if (IsSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability) + if (gAbilities[gBattleMons[gBattlerTarget].ability].cantBeOverwritten || gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); @@ -9353,8 +9353,8 @@ static void Cmd_various(void) case VARIOUS_TRY_ENTRAINMENT: { VARIOUS_ARGS(const u8 *failInstr); - if (IsEntrainmentBannedAbilityAttacker(gBattleMons[gBattlerAttacker].ability) - || IsEntrainmentBannedAbility(gBattleMons[gBattlerTarget].ability)) + if (gAbilities[gBattleMons[gBattlerAttacker].ability].cantBeCopied + || gAbilities[gBattleMons[gBattlerTarget].ability].cantBeOverwritten) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); gBattlescriptCurrInstr = cmd->failInstr; @@ -13951,9 +13951,9 @@ static void Cmd_trycopyability(void) if (gBattleMons[battler].ability == defAbility || defAbility == ABILITY_NONE - || IsRolePlayDoodleBannedAbilityAttacker(gBattleMons[battler].ability) - || IsRolePlayDoodleBannedAbilityAttacker(gBattleMons[BATTLE_PARTNER(battler)].ability) - || IsRolePlayDoodleBannedAbility(defAbility)) + || gAbilities[gBattleMons[battler].ability].cantBeSuppressed + || gAbilities[gBattleMons[BATTLE_PARTNER(battler)].ability].cantBeSuppressed + || gAbilities[defAbility].cantBeCopied) { gBattlescriptCurrInstr = cmd->failInstr; } @@ -14029,7 +14029,7 @@ static void Cmd_setgastroacid(void) { CMD_ARGS(const u8 *failInstr); - if (IsGastroAcidBannedAbility(gBattleMons[gBattlerTarget].ability)) + if (gAbilities[gBattleMons[gBattlerTarget].ability].cantBeSuppressed) { gBattlescriptCurrInstr = cmd->failInstr; } @@ -14129,8 +14129,8 @@ static void Cmd_tryswapabilities(void) { CMD_ARGS(const u8 *failInstr); - if (IsSkillSwapBannedAbility(gBattleMons[gBattlerAttacker].ability) - || IsSkillSwapBannedAbility(gBattleMons[gBattlerTarget].ability)) + if (gAbilities[gBattleMons[gBattlerAttacker].ability].cantBeSwapped + || gAbilities[gBattleMons[gBattlerTarget].ability].cantBeSwapped) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); gBattlescriptCurrInstr = cmd->failInstr; @@ -15489,7 +15489,8 @@ static void Cmd_tryworryseed(void) { CMD_ARGS(const u8 *failInstr); - if (IsWorrySeedBannedAbility(gBattleMons[gBattlerTarget].ability)) + if (gAbilities[gBattleMons[gBattlerTarget].ability].cantBeOverwritten + || gBattleMons[gBattlerTarget].ability == ABILITY_INSOMNIA) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); diff --git a/src/battle_util.c b/src/battle_util.c index 86e616140a..04ba26ed86 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -94,224 +94,6 @@ static const u8 sPkblToEscapeFactor[][3] = { static const u8 sGoNearCounterToCatchFactor[] = {4, 3, 2, 1}; static const u8 sGoNearCounterToEscapeFactor[] = {4, 4, 4, 4}; -static const u16 sSkillSwapBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_HUNGER_SWITCH, - ABILITY_ICE_FACE, - ABILITY_ILLUSION, - ABILITY_MULTITYPE, - ABILITY_NEUTRALIZING_GAS, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_WONDER_GUARD, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sRolePlayDoodleBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_FLOWER_GIFT, - ABILITY_FORECAST, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_HUNGER_SWITCH, - ABILITY_ICE_FACE, - ABILITY_ILLUSION, - ABILITY_IMPOSTER, - ABILITY_MULTITYPE, - ABILITY_NEUTRALIZING_GAS, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_POWER_OF_ALCHEMY, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RECEIVER, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_TRACE, - ABILITY_WONDER_GUARD, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sRolePlayDoodleBannedAttackerAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_ICE_FACE, - ABILITY_MULTITYPE, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sWorrySeedBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_ICE_FACE, - ABILITY_INSOMNIA, - ABILITY_MULTITYPE, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_TRUANT, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sGastroAcidBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_ICE_FACE, - ABILITY_MULTITYPE, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sEntrainmentBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_ICE_FACE, - ABILITY_MULTITYPE, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_TRUANT, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sEntrainmentBannedAttackerAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_FLOWER_GIFT, - ABILITY_FORECAST, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_HUNGER_SWITCH, - ABILITY_ICE_FACE, - ABILITY_ILLUSION, - ABILITY_IMPOSTER, - ABILITY_MULTITYPE, - ABILITY_NEUTRALIZING_GAS, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_POWER_OF_ALCHEMY, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RECEIVER, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_TRACE, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sSimpleBeamBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_ICE_FACE, - ABILITY_MULTITYPE, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_SIMPLE, - ABILITY_STANCE_CHANGE, - ABILITY_TRUANT, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - static u8 CalcBeatUpPower(void) { u8 basePower; @@ -985,114 +767,6 @@ void HandleAction_ActionFinished(void) } } -static const u8 sAbilitiesAffectedByMoldBreaker[] = -{ - [ABILITY_BATTLE_ARMOR] = 1, - [ABILITY_CLEAR_BODY] = 1, - [ABILITY_DAMP] = 1, - [ABILITY_DRY_SKIN] = 1, - [ABILITY_FILTER] = 1, - [ABILITY_FLASH_FIRE] = 1, - [ABILITY_FLOWER_GIFT] = 1, - [ABILITY_HEATPROOF] = 1, - [ABILITY_HYPER_CUTTER] = 1, - [ABILITY_IMMUNITY] = 1, - [ABILITY_INNER_FOCUS] = 1, - [ABILITY_INSOMNIA] = 1, - [ABILITY_KEEN_EYE] = 1, - [ABILITY_LEAF_GUARD] = 1, - [ABILITY_LEVITATE] = 1, - [ABILITY_LIGHTNING_ROD] = 1, - [ABILITY_LIMBER] = 1, - [ABILITY_MAGMA_ARMOR] = 1, - [ABILITY_MARVEL_SCALE] = 1, - [ABILITY_MOTOR_DRIVE] = 1, - [ABILITY_OBLIVIOUS] = 1, - [ABILITY_OWN_TEMPO] = 1, - [ABILITY_SAND_VEIL] = 1, - [ABILITY_SHELL_ARMOR] = 1, - [ABILITY_SHIELD_DUST] = 1, - [ABILITY_SIMPLE] = 1, - [ABILITY_SNOW_CLOAK] = 1, - [ABILITY_SOLID_ROCK] = 1, - [ABILITY_SOUNDPROOF] = 1, - [ABILITY_STICKY_HOLD] = 1, - [ABILITY_STORM_DRAIN] = 1, - [ABILITY_STURDY] = 1, - [ABILITY_SUCTION_CUPS] = 1, - [ABILITY_TANGLED_FEET] = 1, - [ABILITY_THICK_FAT] = 1, - [ABILITY_UNAWARE] = 1, - [ABILITY_VITAL_SPIRIT] = 1, - [ABILITY_VOLT_ABSORB] = 1, - [ABILITY_WATER_ABSORB] = 1, - [ABILITY_WATER_VEIL] = 1, - [ABILITY_WHITE_SMOKE] = 1, - [ABILITY_WONDER_GUARD] = 1, - [ABILITY_BIG_PECKS] = 1, - [ABILITY_CONTRARY] = 1, - [ABILITY_FRIEND_GUARD] = 1, - [ABILITY_HEAVY_METAL] = 1, - [ABILITY_LIGHT_METAL] = 1, - [ABILITY_MAGIC_BOUNCE] = 1, - [ABILITY_MULTISCALE] = 1, - [ABILITY_SAP_SIPPER] = 1, - [ABILITY_TELEPATHY] = 1, - [ABILITY_WONDER_SKIN] = 1, - [ABILITY_AROMA_VEIL] = 1, - [ABILITY_BULLETPROOF] = 1, - [ABILITY_FLOWER_VEIL] = 1, - [ABILITY_FUR_COAT] = 1, - [ABILITY_OVERCOAT] = 1, - [ABILITY_SWEET_VEIL] = 1, - [ABILITY_DAZZLING] = 1, - [ABILITY_DISGUISE] = 1, - [ABILITY_FLUFFY] = 1, - [ABILITY_QUEENLY_MAJESTY] = 1, - [ABILITY_WATER_BUBBLE] = 1, - [ABILITY_MIRROR_ARMOR] = 1, - [ABILITY_PUNK_ROCK] = 1, - [ABILITY_ICE_SCALES] = 1, - [ABILITY_ICE_FACE] = 1, - [ABILITY_PASTEL_VEIL] = 1, - [ABILITY_ARMOR_TAIL] = 1, - [ABILITY_EARTH_EATER] = 1, - [ABILITY_GOOD_AS_GOLD] = 1, - [ABILITY_PURIFYING_SALT] = 1, - [ABILITY_WELL_BAKED_BODY] = 1, - [ABILITY_MINDS_EYE] = 1, - [ABILITY_ILLUMINATE] = 1, -}; - -static const u8 sAbilitiesNotTraced[ABILITIES_COUNT] = -{ - [ABILITY_AS_ONE_ICE_RIDER] = 1, - [ABILITY_AS_ONE_SHADOW_RIDER] = 1, - [ABILITY_BATTLE_BOND] = 1, - [ABILITY_COMATOSE] = 1, - [ABILITY_DISGUISE] = 1, - [ABILITY_FLOWER_GIFT] = 1, - [ABILITY_FORECAST] = 1, - [ABILITY_GULP_MISSILE] = 1, - [ABILITY_HUNGER_SWITCH] = 1, - [ABILITY_ICE_FACE] = 1, - [ABILITY_ILLUSION] = 1, - [ABILITY_IMPOSTER] = 1, - [ABILITY_MULTITYPE] = 1, - [ABILITY_NEUTRALIZING_GAS] = 1, - [ABILITY_NONE] = 1, - [ABILITY_POWER_CONSTRUCT] = 1, - [ABILITY_POWER_OF_ALCHEMY] = 1, - [ABILITY_RECEIVER] = 1, - [ABILITY_RKS_SYSTEM] = 1, - [ABILITY_SCHOOLING] = 1, - [ABILITY_SHIELDS_DOWN] = 1, - [ABILITY_STANCE_CHANGE] = 1, - [ABILITY_TRACE] = 1, - [ABILITY_ZEN_MODE] = 1, - [ABILITY_ZERO_TO_HERO] = 1, -}; - static const u8 sHoldEffectToType[][2] = { {HOLD_EFFECT_BUG_POWER, TYPE_BUG}, @@ -5459,34 +5133,22 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && IsBattlerAlive(gBattlerAttacker) && TARGET_TURN_DAMAGED && IsMoveMakingContact(move, gBattlerAttacker) - && gBattleStruct->overwrittenAbilities[gBattlerAttacker] != GetBattlerAbility(gBattlerTarget)) + && gBattleStruct->overwrittenAbilities[gBattlerAttacker] != GetBattlerAbility(gBattlerTarget) + && gBattleMons[gBattlerTarget].ability != ABILITY_MUMMY + && gBattleMons[gBattlerTarget].ability != ABILITY_LINGERING_AROMA + && !gAbilities[gBattleMons[gBattlerTarget].ability].cantBeSuppressed) { - switch (gBattleMons[gBattlerAttacker].ability) + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { - case ABILITY_MUMMY: - case ABILITY_BATTLE_BOND: - case ABILITY_COMATOSE: - case ABILITY_DISGUISE: - case ABILITY_MULTITYPE: - case ABILITY_POWER_CONSTRUCT: - case ABILITY_RKS_SYSTEM: - case ABILITY_SCHOOLING: - case ABILITY_SHIELDS_DOWN: - case ABILITY_STANCE_CHANGE: - break; - default: - if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) - { - RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); - break; - } - - gLastUsedAbility = gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MummyActivates; - effect++; + RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); break; } + + gLastUsedAbility = gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MummyActivates; + effect++; + break; } break; case ABILITY_WANDERING_SPIRIT: @@ -5494,40 +5156,22 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && IsBattlerAlive(gBattlerAttacker) && TARGET_TURN_DAMAGED && IsMoveMakingContact(move, gBattlerAttacker) - && !IsDynamaxed(gBattlerTarget)) + && !IsDynamaxed(gBattlerTarget) + && !gAbilities[gBattleMons[gBattlerAttacker].ability].cantBeSwapped) { - switch (gBattleMons[gBattlerAttacker].ability) + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { - case ABILITY_DISGUISE: - case ABILITY_FLOWER_GIFT: - case ABILITY_GULP_MISSILE: - case ABILITY_HUNGER_SWITCH: - case ABILITY_ICE_FACE: - case ABILITY_ILLUSION: - case ABILITY_IMPOSTER: - case ABILITY_RECEIVER: - case ABILITY_RKS_SYSTEM: - case ABILITY_SCHOOLING: - case ABILITY_STANCE_CHANGE: - case ABILITY_WONDER_GUARD: - case ABILITY_ZEN_MODE: - case ABILITY_ZERO_TO_HERO: - break; - default: - if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) - { - RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); - break; - } - - gLastUsedAbility = gBattleMons[gBattlerAttacker].ability; - gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; - gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = gLastUsedAbility; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_WanderingSpiritActivates; - effect++; + RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); break; } + + gLastUsedAbility = gBattleMons[gBattlerAttacker].ability; + gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; + gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = gLastUsedAbility; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_WanderingSpiritActivates; + effect++; + break; } break; case ABILITY_ANGER_POINT: @@ -6152,17 +5796,17 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) { - if (!sAbilitiesNotTraced[gBattleMons[target1].ability] && gBattleMons[target1].hp != 0 - && !sAbilitiesNotTraced[gBattleMons[target2].ability] && gBattleMons[target2].hp != 0) + if (!gAbilities[gBattleMons[target1].ability].cantBeTraced && gBattleMons[target1].hp != 0 + && !gAbilities[gBattleMons[target2].ability].cantBeTraced && gBattleMons[target2].hp != 0) chosenTarget = GetBattlerAtPosition((RandomPercentage(RNG_TRACE, 50) * 2) | side), effect++; - else if (!sAbilitiesNotTraced[gBattleMons[target1].ability] && gBattleMons[target1].hp != 0) + else if (!gAbilities[gBattleMons[target1].ability].cantBeTraced && gBattleMons[target1].hp != 0) chosenTarget = target1, effect++; - else if (!sAbilitiesNotTraced[gBattleMons[target2].ability] && gBattleMons[target2].hp != 0) + else if (!gAbilities[gBattleMons[target2].ability].cantBeTraced && gBattleMons[target2].hp != 0) chosenTarget = target2, effect++; } else { - if (!sAbilitiesNotTraced[gBattleMons[target1].ability] && gBattleMons[target1].hp != 0) + if (!gAbilities[gBattleMons[target1].ability].cantBeTraced && gBattleMons[target1].hp != 0) chosenTarget = target1, effect++; } @@ -6324,35 +5968,6 @@ bool32 TryPrimalReversion(u32 battler) return FALSE; } -static const u16 sNeutralizingGasBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_COMATOSE, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_ICE_FACE, - ABILITY_MULTITYPE, - ABILITY_POWER_CONSTRUCT, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -bool32 IsNeutralizingGasBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sNeutralizingGasBannedAbilities); i++) - { - if (ability == sNeutralizingGasBannedAbilities[i]) - return TRUE; - } - return FALSE; -} - bool32 IsNeutralizingGasOnField(void) { u32 i; @@ -6386,10 +6001,13 @@ bool32 IsMoldBreakerTypeAbility(u32 ability) u32 GetBattlerAbility(u32 battler) { + if (gAbilities[gBattleMons[battler].ability].cantBeSuppressed) + return gBattleMons[battler].ability; + if (gStatuses3[battler] & STATUS3_GASTRO_ACID) return ABILITY_NONE; - if (IsNeutralizingGasOnField() && !IsNeutralizingGasBannedAbility(gBattleMons[battler].ability)) + if (IsNeutralizingGasOnField() && gBattleMons[battler].ability != ABILITY_NEUTRALIZING_GAS) return ABILITY_NONE; if (IsMyceliumMightOnField()) @@ -6398,7 +6016,7 @@ u32 GetBattlerAbility(u32 battler) if (((IsMoldBreakerTypeAbility(gBattleMons[gBattlerAttacker].ability) && !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID)) || gBattleMoves[gCurrentMove].ignoresTargetAbility) - && sAbilitiesAffectedByMoldBreaker[gBattleMons[battler].ability] + && gAbilities[gBattleMons[battler].ability].breakable && gBattlerByTurnOrder[gCurrentTurnActionNumber] == gBattlerAttacker && gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE && gCurrentTurnActionNumber < gBattlersCount) @@ -10953,95 +10571,6 @@ bool32 CanFling(u32 battler) return TRUE; } -// Ability checks -bool32 IsSkillSwapBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sSkillSwapBannedAbilities); i++) - { - if (ability == sSkillSwapBannedAbilities[i]) - return TRUE; - } - return FALSE; -} - -bool32 IsRolePlayDoodleBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sRolePlayDoodleBannedAbilities); i++) - { - if (ability == sRolePlayDoodleBannedAbilities[i]) - return TRUE; - } - return FALSE; -} - -bool32 IsRolePlayDoodleBannedAbilityAttacker(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sRolePlayDoodleBannedAttackerAbilities); i++) - { - if (ability == sRolePlayDoodleBannedAttackerAbilities[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 IsEntrainmentBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sEntrainmentBannedAbilities); i++) - { - if (ability == sEntrainmentBannedAbilities[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 IsSimpleBeamBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sSimpleBeamBannedAbilities); i++) - { - if (ability == sSimpleBeamBannedAbilities[i]) - return TRUE; - } - return FALSE; -} - // Sort an array of battlers by speed // Useful for effects like pickpocket, eject button, red card, dancer void SortBattlersBySpeed(u8 *battlers, bool32 slowToFast) diff --git a/src/data/abilities.h b/src/data/abilities.h index 56f7547b23..81bfc995a3 100644 --- a/src/data/abilities.h +++ b/src/data/abilities.h @@ -5,6 +5,8 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("-------"), .description = COMPOUND_STRING("No special ability."), .aiRating = 0, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_STENCH] = @@ -33,6 +35,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Battle Armor"), .description = COMPOUND_STRING("Blocks critical hits."), .aiRating = 2, + .breakable = TRUE, }, [ABILITY_STURDY] = @@ -40,6 +43,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Sturdy"), .description = COMPOUND_STRING("Negates 1-hit KO attacks."), .aiRating = 6, + .breakable = TRUE, }, [ABILITY_DAMP] = @@ -47,6 +51,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Damp"), .description = COMPOUND_STRING("Prevents self-destruction."), .aiRating = 2, + .breakable = TRUE, }, [ABILITY_LIMBER] = @@ -54,6 +59,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Limber"), .description = COMPOUND_STRING("Prevents paralysis."), .aiRating = 3, + .breakable = TRUE, }, [ABILITY_SAND_VEIL] = @@ -61,6 +67,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Sand Veil"), .description = COMPOUND_STRING("Ups evasion in a sandstorm."), .aiRating = 3, + .breakable = TRUE, }, [ABILITY_STATIC] = @@ -75,6 +82,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Volt Absorb"), .description = COMPOUND_STRING("Turns electricity into HP."), .aiRating = 7, + .breakable = TRUE, }, [ABILITY_WATER_ABSORB] = @@ -82,6 +90,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Water Absorb"), .description = COMPOUND_STRING("Changes water into HP."), .aiRating = 7, + .breakable = TRUE, }, [ABILITY_OBLIVIOUS] = @@ -89,6 +98,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Oblivious"), .description = COMPOUND_STRING("Prevents attraction."), .aiRating = 2, + .breakable = TRUE, }, [ABILITY_CLOUD_NINE] = @@ -114,6 +124,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Insomnia"), .description = COMPOUND_STRING("Prevents sleep."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_COLOR_CHANGE] = @@ -128,6 +139,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Immunity"), .description = COMPOUND_STRING("Prevents poisoning."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_FLASH_FIRE] = @@ -135,6 +147,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Flash Fire"), .description = COMPOUND_STRING("Powers up if hit by fire."), .aiRating = 6, + .breakable = TRUE, }, [ABILITY_SHIELD_DUST] = @@ -142,6 +155,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Shield Dust"), .description = COMPOUND_STRING("Prevents added effects."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_OWN_TEMPO] = @@ -149,6 +163,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Own Tempo"), .description = COMPOUND_STRING("Prevents confusion."), .aiRating = 3, + .breakable = TRUE, }, [ABILITY_SUCTION_CUPS] = @@ -156,6 +171,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Suction Cups"), .description = COMPOUND_STRING("Firmly anchors the body."), .aiRating = 2, + .breakable = TRUE, }, [ABILITY_INTIMIDATE] = @@ -184,6 +200,9 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Wonder Guard"), .description = COMPOUND_STRING("“Supereffective” hits."), .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .breakable = TRUE, }, [ABILITY_LEVITATE] = @@ -191,6 +210,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Levitate"), .description = COMPOUND_STRING("Not hit by Ground attacks."), .aiRating = 7, + .breakable = TRUE, }, [ABILITY_EFFECT_SPORE] = @@ -212,6 +232,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Clear Body"), .description = COMPOUND_STRING("Prevents ability reduction."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_NATURAL_CURE] = @@ -230,6 +251,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Draws electrical moves."), .aiRating = 7, + .breakable = TRUE, }, [ABILITY_SERENE_GRACE] = @@ -258,6 +280,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Illuminate"), .description = COMPOUND_STRING("Encounter rate increases."), .aiRating = 0, + .breakable = TRUE, }, [ABILITY_TRACE] = @@ -265,6 +288,8 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Trace"), .description = COMPOUND_STRING("Copies special ability."), .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_HUGE_POWER] = @@ -286,6 +311,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Inner Focus"), .description = COMPOUND_STRING("Prevents flinching."), .aiRating = 2, + .breakable = TRUE, }, [ABILITY_MAGMA_ARMOR] = @@ -293,6 +319,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Magma Armor"), .description = COMPOUND_STRING("Prevents freezing."), .aiRating = 1, + .breakable = TRUE, }, [ABILITY_WATER_VEIL] = @@ -300,6 +327,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Water Veil"), .description = COMPOUND_STRING("Prevents burns."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_MAGNET_PULL] = @@ -314,6 +342,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Soundproof"), .description = COMPOUND_STRING("Avoids sound-based moves."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_RAIN_DISH] = @@ -342,6 +371,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Thick Fat"), .description = COMPOUND_STRING("Heat-and-cold protection."), .aiRating = 7, + .breakable = TRUE, }, [ABILITY_EARLY_BIRD] = @@ -370,6 +400,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Keen Eye"), .description = COMPOUND_STRING("Prevents loss of accuracy."), .aiRating = 1, + .breakable = TRUE, }, [ABILITY_HYPER_CUTTER] = @@ -377,6 +408,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Hyper Cutter"), .description = COMPOUND_STRING("Prevents Attack reduction."), .aiRating = 3, + .breakable = TRUE, }, [ABILITY_PICKUP] = @@ -391,6 +423,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Truant"), .description = COMPOUND_STRING("Moves only every two turns."), .aiRating = -2, + .cantBeOverwritten = TRUE, }, [ABILITY_HUSTLE] = @@ -426,6 +459,8 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Forecast"), .description = COMPOUND_STRING("Changes with the weather."), .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_STICKY_HOLD] = @@ -433,6 +468,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Sticky Hold"), .description = COMPOUND_STRING("Prevents item theft."), .aiRating = 3, + .breakable = TRUE, }, [ABILITY_SHED_SKIN] = @@ -454,6 +490,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Marvel Scale"), .description = COMPOUND_STRING("Ups Defense if suffering."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_LIQUID_OOZE] = @@ -517,6 +554,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Vital Spirit"), .description = COMPOUND_STRING("Prevents sleep."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_WHITE_SMOKE] = @@ -524,6 +562,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("White Smoke"), .description = COMPOUND_STRING("Prevents ability reduction."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_PURE_POWER] = @@ -538,6 +577,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Shell Armor"), .description = COMPOUND_STRING("Blocks critical hits."), .aiRating = 2, + .breakable = TRUE, }, [ABILITY_AIR_LOCK] = @@ -552,6 +592,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Tangled Feet"), .description = COMPOUND_STRING("Ups evasion if confused."), .aiRating = 2, + .breakable = TRUE, }, [ABILITY_MOTOR_DRIVE] = @@ -559,6 +600,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Motor Drive"), .description = COMPOUND_STRING("Electricity raises Speed."), .aiRating = 6, + .breakable = TRUE, }, [ABILITY_RIVALRY] = @@ -580,6 +622,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Snow Cloak"), .description = COMPOUND_STRING("Ups evasion in Hail or Snow."), .aiRating = 3, + .breakable = TRUE, }, [ABILITY_GLUTTONY] = @@ -608,6 +651,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Heatproof"), .description = COMPOUND_STRING("Heat and burn protection."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_SIMPLE] = @@ -615,6 +659,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Simple"), .description = COMPOUND_STRING("Prone to wild stat changes."), .aiRating = 8, + .breakable = TRUE, }, [ABILITY_DRY_SKIN] = @@ -622,6 +667,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Dry Skin"), .description = COMPOUND_STRING("Prefers moisture to heat."), .aiRating = 6, + .breakable = TRUE, }, [ABILITY_DOWNLOAD] = @@ -727,6 +773,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Leaf Guard"), .description = COMPOUND_STRING("Blocks status in sunshine."), .aiRating = 2, + .breakable = TRUE, }, [ABILITY_KLUTZ] = @@ -776,6 +823,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Unaware"), .description = COMPOUND_STRING("Ignores stat changes."), .aiRating = 6, + .breakable = TRUE, }, [ABILITY_TINTED_LENS] = @@ -790,6 +838,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Filter"), .description = COMPOUND_STRING("Weakens “supereffective”."), .aiRating = 6, + .breakable = TRUE, }, [ABILITY_SLOW_START] = @@ -811,6 +860,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Storm Drain"), .description = COMPOUND_STRING("Draws in Water moves."), .aiRating = 7, + .breakable = TRUE, }, [ABILITY_ICE_BODY] = @@ -825,6 +875,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Solid Rock"), .description = COMPOUND_STRING("Weakens “supereffective”."), .aiRating = 6, + .breakable = TRUE, }, [ABILITY_SNOW_WARNING] = @@ -860,6 +911,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Multitype"), .description = COMPOUND_STRING("Changes type to its Plate."), .aiRating = 8, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_FLOWER_GIFT] = @@ -867,6 +923,9 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Flower Gift"), .description = COMPOUND_STRING("Allies power up in sunshine."), .aiRating = 4, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, + .breakable = TRUE, }, [ABILITY_BAD_DREAMS] = @@ -895,6 +954,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Contrary"), .description = COMPOUND_STRING("Inverts stat changes."), .aiRating = 8, + .breakable = TRUE, }, [ABILITY_UNNERVE] = @@ -937,6 +997,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Friend Guard"), .description = COMPOUND_STRING("Lowers damage to partner."), .aiRating = 0, + .breakable = TRUE, }, [ABILITY_WEAK_ARMOR] = @@ -951,6 +1012,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Heavy Metal"), .description = COMPOUND_STRING("Doubles weight."), .aiRating = -1, + .breakable = TRUE, }, [ABILITY_LIGHT_METAL] = @@ -958,6 +1020,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Light Metal"), .description = COMPOUND_STRING("Halves weight."), .aiRating = 2, + .breakable = TRUE, }, [ABILITY_MULTISCALE] = @@ -965,6 +1028,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Multiscale"), .description = COMPOUND_STRING("Halves damage at full HP."), .aiRating = 8, + .breakable = TRUE, }, [ABILITY_TOXIC_BOOST] = @@ -993,6 +1057,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Telepathy"), .description = COMPOUND_STRING("Can't be damaged by an ally."), .aiRating = 0, + .breakable = TRUE, }, [ABILITY_MOODY] = @@ -1007,6 +1072,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Overcoat"), .description = COMPOUND_STRING("Blocks weather and powder."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_POISON_TOUCH] = @@ -1028,6 +1094,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Big Pecks"), .description = COMPOUND_STRING("Prevents Defense loss."), .aiRating = 1, + .breakable = TRUE, }, [ABILITY_SAND_RUSH] = @@ -1042,6 +1109,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Wonder Skin"), .description = COMPOUND_STRING("May avoid status problems."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_ANALYTIC] = @@ -1056,6 +1124,9 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Illusion"), .description = COMPOUND_STRING("Appears as a partner."), .aiRating = 8, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_IMPOSTER] = @@ -1063,6 +1134,8 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Imposter"), .description = COMPOUND_STRING("Transforms into the foe."), .aiRating = 9, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_INFILTRATOR] = @@ -1105,6 +1178,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Magic Bounce"), .description = COMPOUND_STRING("Reflects status moves."), .aiRating = 9, + .breakable = TRUE, }, [ABILITY_SAP_SIPPER] = @@ -1112,6 +1186,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Sap Sipper"), .description = COMPOUND_STRING("Grass increases Attack."), .aiRating = 7, + .breakable = TRUE, }, [ABILITY_PRANKSTER] = @@ -1140,6 +1215,10 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Zen Mode"), .description = COMPOUND_STRING("Transforms at half HP."), .aiRating = -1, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = B_UPDATED_ABILITY_DATA >= GEN_7, }, [ABILITY_VICTORY_STAR] = @@ -1168,6 +1247,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Aroma Veil"), .description = COMPOUND_STRING("Prevents limiting of moves."), .aiRating = 3, + .breakable = TRUE, }, [ABILITY_FLOWER_VEIL] = @@ -1238,6 +1318,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Sweet Veil"), .description = COMPOUND_STRING("Prevents party from sleep."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_STANCE_CHANGE] = @@ -1249,6 +1330,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Transforms as it battles."), .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_GALE_WINGS] = @@ -1274,6 +1360,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Grass Pelt"), .description = COMPOUND_STRING("Ups Defense in grass."), .aiRating = 2, + .breakable = TRUE, }, [ABILITY_SYMBIOSIS] = @@ -1420,6 +1507,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Shields Down"), .description = COMPOUND_STRING("Shell breaks at half HP."), .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_STAKEOUT] = @@ -1497,6 +1589,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Schooling"), .description = COMPOUND_STRING("Forms a school when strong."), .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_DISGUISE] = @@ -1504,6 +1601,12 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Disguise"), .description = COMPOUND_STRING("Decoy protects it once."), .aiRating = 8, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_BATTLE_BOND] = @@ -1511,6 +1614,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Battle Bond"), .description = COMPOUND_STRING("Changes form after a KO."), .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_POWER_CONSTRUCT] = @@ -1522,6 +1630,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Cells aid it when weakened."), .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_CORROSION] = @@ -1536,6 +1649,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Comatose"), .description = COMPOUND_STRING("Always drowsing."), .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_QUEENLY_MAJESTY] = @@ -1547,6 +1665,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Protects from priority."), .aiRating = 6, + .breakable = TRUE, }, [ABILITY_INNARDS_OUT] = @@ -1575,6 +1694,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Fluffy"), .description = COMPOUND_STRING("Tougher but flammable."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_DAZZLING] = @@ -1582,6 +1702,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Dazzling"), .description = COMPOUND_STRING("Protects from priority."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_SOUL_HEART] = @@ -1607,6 +1728,8 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Receiver"), .description = COMPOUND_STRING("Copies ally's ability."), .aiRating = 0, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_POWER_OF_ALCHEMY] = @@ -1618,6 +1741,8 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Copies ally's ability."), .aiRating = 0, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_BEAST_BOOST] = @@ -1632,6 +1757,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("RKS System"), .description = COMPOUND_STRING("Memories change its type."), .aiRating = 8, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_ELECTRIC_SURGE] = @@ -1764,6 +1894,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Mirror Armor"), .description = COMPOUND_STRING("Reflect stat decreases."), .aiRating = 6, + .breakable = TRUE, }, [ABILITY_GULP_MISSILE] = @@ -1771,6 +1902,9 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Gulp Missile"), .description = COMPOUND_STRING("If hit, spits prey from sea."), .aiRating = 3, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_STALWART] = @@ -1792,6 +1926,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Punk Rock"), .description = COMPOUND_STRING("Ups and resists sound."), .aiRating = 2, + .breakable = TRUE, }, [ABILITY_SAND_SPIT] = @@ -1806,6 +1941,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Ice Scales"), .description = COMPOUND_STRING("Halves special damage."), .aiRating = 7, + .breakable = TRUE, }, [ABILITY_RIPEN] = @@ -1820,6 +1956,13 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Ice Face"), .description = COMPOUND_STRING("Hail or Snow renew free hit."), .aiRating = 4, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, + .breakable = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_POWER_SPOT] = @@ -1896,6 +2039,10 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("All Abilities are nullified."), .aiRating = 5, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_PASTEL_VEIL] = @@ -1903,6 +2050,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Pastel Veil"), .description = COMPOUND_STRING("Protects team from poison."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_HUNGER_SWITCH] = @@ -1914,6 +2062,10 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Changes form each turn."), .aiRating = 2, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_QUICK_DRAW] = @@ -1978,6 +2130,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("As One"), .description = COMPOUND_STRING("Unnerve and Chilling Neigh."), .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_AS_ONE_SHADOW_RIDER] = @@ -1985,6 +2142,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("As One"), .description = COMPOUND_STRING("Unnerve and Grim Neigh."), .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_LINGERING_AROMA] = @@ -2014,6 +2176,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Fire hits up Attack."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_ANGER_SHELL] = @@ -2032,6 +2195,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Protected by pure salts."), .aiRating = 6, + .breakable = TRUE, }, [ABILITY_WELL_BAKED_BODY] = @@ -2043,6 +2207,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Strengthened by Fire."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_WIND_RIDER] = @@ -2050,6 +2215,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Wind Rider"), .description = COMPOUND_STRING("Ups Attack if hit by wind."), .aiRating = 4, + .breakable = TRUE, }, [ABILITY_GUARD_DOG] = @@ -2057,6 +2223,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Guard Dog"), .description = COMPOUND_STRING("Cannot be intimidated."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_ROCKY_PAYLOAD] = @@ -2082,6 +2249,12 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Zero to Hero"), .description = COMPOUND_STRING("Changes form on switch out."), .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_COMMANDER] = @@ -2089,6 +2262,9 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Commander"), .description = COMPOUND_STRING("Commands from Dondozo."), .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_ELECTROMORPHOSIS] = @@ -2111,6 +2287,10 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Sun boosts best stat."), .aiRating = 7, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_QUARK_DRIVE] = @@ -2118,6 +2298,10 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Quark Drive"), .description = COMPOUND_STRING("Elec. field ups best stat."), .aiRating = 7, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_GOOD_AS_GOLD] = @@ -2125,6 +2309,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Good as Gold"), .description = COMPOUND_STRING("Avoids status problems."), .aiRating = 8, + .breakable = TRUE, }, [ABILITY_VESSEL_OF_RUIN] = @@ -2136,6 +2321,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Lowers foes' sp. damage."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_SWORD_OF_RUIN] = @@ -2147,6 +2333,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Lowers foes' Defense."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_TABLETS_OF_RUIN] = @@ -2158,6 +2345,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Lowers foes' damage."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_BEADS_OF_RUIN] = @@ -2169,6 +2357,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Lowers foes' Sp. Defense."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_ORICHALCUM_PULSE] = @@ -2244,6 +2433,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Armor Tail"), .description = COMPOUND_STRING("Protects from priority."), .aiRating = 5, + .breakable = TRUE, }, [ABILITY_EARTH_EATER] = @@ -2251,6 +2441,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Earth Eater"), .description = COMPOUND_STRING("Eats ground to heal HP."), .aiRating = 7, + .breakable = TRUE, }, [ABILITY_MYCELIUM_MIGHT] = @@ -2276,6 +2467,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Mind's Eye"), .description = COMPOUND_STRING("Keen Eye and Scrappy."), .aiRating = 8, + .breakable = TRUE, }, [ABILITY_EMBODY_ASPECT_TEAL] = @@ -2287,6 +2479,10 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Raises Speed."), .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_EMBODY_ASPECT_HEARTHFLAME] = @@ -2298,6 +2494,10 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Raises Attack."), .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_EMBODY_ASPECT_WELLSPRING] = @@ -2309,6 +2509,10 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Raises Sp. Def."), .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_EMBODY_ASPECT_CORNERSTONE] = @@ -2320,6 +2524,10 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Raises Defense."), .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_TOXIC_CHAIN] = @@ -2345,6 +2553,12 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Tera Shift"), .description = COMPOUND_STRING("Terasteralizes upon entry."), .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_TERA_SHELL] = @@ -2352,6 +2566,10 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Tera Shell"), .description = COMPOUND_STRING("Resistant to types at full HP."), .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .breakable = TRUE, }, [ABILITY_TERAFORM_ZERO] = @@ -2363,6 +2581,9 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Removes weather and terrain."), .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_POISON_PUPPETEER] = @@ -2374,5 +2595,8 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #endif .description = COMPOUND_STRING("Confuses poisoned foes."), .aiRating = 8, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, }, }; diff --git a/test/battle/move_effect/doodle.c b/test/battle/move_effect/doodle.c index 8a7144b430..23671b3846 100644 --- a/test/battle/move_effect/doodle.c +++ b/test/battle/move_effect/doodle.c @@ -49,7 +49,7 @@ DOUBLE_BATTLE_TEST("Doodle can't copy a banned ability") DOUBLE_BATTLE_TEST("Doodle fails if user has a banned Ability") { GIVEN { - PLAYER(SPECIES_GREAT_TUSK) { Ability(ABILITY_PROTOSYNTHESIS); } + PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); } PLAYER(SPECIES_WYNAUT) { Ability(ABILITY_SHADOW_TAG); } OPPONENT(SPECIES_TORCHIC) { Ability(ABILITY_BLAZE); } OPPONENT(SPECIES_WOBBUFFET); @@ -59,7 +59,7 @@ DOUBLE_BATTLE_TEST("Doodle fails if user has a banned Ability") ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, playerLeft); MESSAGE("But it failed!"); } THEN { - EXPECT(playerLeft->ability == ABILITY_PROTOSYNTHESIS); + EXPECT(playerLeft->ability == ABILITY_GULP_MISSILE); EXPECT(playerRight->ability == ABILITY_SHADOW_TAG); } } @@ -68,7 +68,7 @@ DOUBLE_BATTLE_TEST("Doodle fails if partner has a banned Ability") { GIVEN { PLAYER(SPECIES_WYNAUT) { Ability(ABILITY_SHADOW_TAG); } - PLAYER(SPECIES_GREAT_TUSK) { Ability(ABILITY_PROTOSYNTHESIS); } + PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); } OPPONENT(SPECIES_TORCHIC) { Ability(ABILITY_BLAZE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -78,6 +78,6 @@ DOUBLE_BATTLE_TEST("Doodle fails if partner has a banned Ability") MESSAGE("But it failed!"); } THEN { EXPECT(playerLeft->ability == ABILITY_SHADOW_TAG); - EXPECT(playerRight->ability == ABILITY_PROTOSYNTHESIS); + EXPECT(playerRight->ability == ABILITY_GULP_MISSILE); } }