From 505b8b63ebbfd42476baf82250d45ef69ff2649c Mon Sep 17 00:00:00 2001 From: kittenchilly Date: Fri, 22 Dec 2023 09:45:55 -0600 Subject: [PATCH] Add Doodle + update ability banlists (#3609) * Add Doodle * Doodle test * Oops * Update battle_util.c --------- Co-authored-by: Bassoonian --- asm/macros/battle_script.inc | 12 +- data/battle_scripts_1.s | 31 ++- include/battle_util.h | 7 +- include/constants/battle_move_effects.h | 3 +- src/battle_ai_main.c | 12 +- src/battle_script_commands.c | 19 +- src/battle_util.c | 334 +++++++++++++++--------- src/data/battle_moves.h | 4 +- test/battle/move_effect/doodle.c | 26 ++ 9 files changed, 308 insertions(+), 140 deletions(-) create mode 100644 test/battle/move_effect/doodle.c diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index d155aebf66..30b0ab0ee2 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1087,8 +1087,9 @@ .4byte \failInstr .endm - .macro trycopyability failInstr:req + .macro trycopyability battler:req, failInstr:req .byte 0xd3 + .byte \battler .4byte \failInstr .endm @@ -2332,6 +2333,15 @@ goto \jumpInstr .endm + .macro setallytonextattacker jumpInstr:req + jumpifbyte CMP_GREATER_THAN, gBattlerAttacker, 0x1, 1f + addbyte gBattlerAttacker, 0x2 + goto \jumpInstr + 1: + subbyte gBattlerAttacker, 0x2 + goto \jumpInstr + .endm + .macro jumpifleafguardprotected battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED .4byte \jumpInstr diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 974a4ace76..b4d9c0c794 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -439,6 +439,35 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectGlaiveRush @ EFFECT_GLAIVE_RUSH .4byte BattleScript_EffectBrickBreak @ EFFECT_RAGING_BULL .4byte BattleScript_EffectHit @ EFFECT_RAGE_FIST + .4byte BattleScript_EffectDoodle @ EFFECT_DOODLE + +BattleScript_EffectDoodle: + attackcanceler + attackstring + ppreduce + attackanimation + waitanimation + setbyte gBattleCommunication, 0 +BattleScript_EffectDoodle_CopyAbility: + trycopyability BS_ATTACKER, BattleScript_ButItFailed +.if B_ABILITY_POP_UP == TRUE + setbyte sFIXED_ABILITY_POPUP, TRUE + showabilitypopup BS_ATTACKER + pause 60 + sethword sABILITY_OVERWRITE, 0 + updateabilitypopup BS_ATTACKER + pause 20 + destroyabilitypopup + pause 40 +.endif + printstring STRINGID_PKMNCOPIEDFOE + waitmessage B_WAIT_TIME_LONG + switchinabilities BS_ATTACKER + jumpifbyte CMP_NOT_EQUAL, gBattleCommunication, 0x0, BattleScript_MoveEnd + addbyte gBattleCommunication, 1 + jumpifnoally BS_TARGET, BattleScript_MoveEnd + setallytonextattacker BattleScript_EffectDoodle_CopyAbility + goto BattleScript_MoveEnd BattleScript_EffectGlaiveRush:: call BattleScript_EffectHit_Ret @@ -5915,7 +5944,7 @@ BattleScript_EffectRolePlay:: attackstring ppreduce accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON - trycopyability BattleScript_ButItFailed + trycopyability BS_ATTACKER, BattleScript_ButItFailed attackanimation waitanimation .if B_ABILITY_POP_UP == TRUE diff --git a/include/battle_util.h b/include/battle_util.h index 276f364615..18b27eed2c 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -223,13 +223,14 @@ bool32 IsAlly(u32 battlerAtk, u32 battlerDef); bool32 IsGen6ExpShareEnabled(void); // Ability checks -bool32 IsRolePlayBannedAbilityAtk(u16 ability); -bool32 IsRolePlayBannedAbility(u16 ability); 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 IsEntrainmentTargetOrSimpleBeamBannedAbility(u16 ability); +bool32 IsSimpleBeamBannedAbility(u16 ability); bool32 CanSleep(u32 battler); bool32 CanBePoisoned(u32 battlerAttacker, u32 battlerTarget); diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index a0b0fb1d4c..420433bd02 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -416,7 +416,8 @@ #define EFFECT_GLAIVE_RUSH 410 #define EFFECT_RAGING_BULL 411 #define EFFECT_RAGE_FIST 412 +#define EFFECT_DOODLE 413 -#define NUM_BATTLE_MOVE_EFFECTS 413 +#define NUM_BATTLE_MOVE_EFFECTS 414 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index dbdfeb84da..8980691356 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -2110,8 +2110,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 - || IsRolePlayBannedAbilityAtk(aiData->abilities[battlerAtk]) - || IsRolePlayBannedAbility(aiData->abilities[battlerDef])) + || IsRolePlayDoodleBannedAbilityAttacker(aiData->abilities[battlerAtk]) + || IsRolePlayDoodleBannedAbility(aiData->abilities[battlerDef])) ADJUST_SCORE(-10); else if (IsAbilityOfRating(aiData->abilities[battlerAtk], 5)) ADJUST_SCORE(-4); @@ -2158,7 +2158,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_ENTRAINMENT: if (aiData->abilities[battlerAtk] == ABILITY_NONE || IsEntrainmentBannedAbilityAttacker(aiData->abilities[battlerAtk]) - || IsEntrainmentTargetOrSimpleBeamBannedAbility(aiData->abilities[battlerDef]) + || IsEntrainmentBannedAbility(aiData->abilities[battlerDef]) || aiData->holdEffects[battlerAtk] == HOLD_EFFECT_ABILITY_SHIELD) ADJUST_SCORE(-10); break; @@ -2166,7 +2166,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_SIMPLE_BEAM: if (aiData->abilities[battlerDef] == ABILITY_SIMPLE - || IsEntrainmentTargetOrSimpleBeamBannedAbility(aiData->abilities[battlerDef]) + || IsSimpleBeamBannedAbility(aiData->abilities[battlerDef]) || aiData->holdEffects[battlerDef] == HOLD_EFFECT_ABILITY_SHIELD) ADJUST_SCORE(-10); break; @@ -4334,8 +4334,8 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score } break; case EFFECT_ROLE_PLAY: - if (!IsRolePlayBannedAbilityAtk(aiData->abilities[battlerAtk]) - && !IsRolePlayBannedAbility(aiData->abilities[battlerDef]) + if (!IsRolePlayDoodleBannedAbilityAttacker(aiData->abilities[battlerAtk]) + && !IsRolePlayDoodleBannedAbility(aiData->abilities[battlerDef]) && !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 225bef077c..c145d5855c 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9257,7 +9257,7 @@ static void Cmd_various(void) case VARIOUS_SET_SIMPLE_BEAM: { VARIOUS_ARGS(const u8 *failInstr); - if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability) + if (IsSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability) || gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); @@ -9282,7 +9282,7 @@ static void Cmd_various(void) { VARIOUS_ARGS(const u8 *failInstr); if (IsEntrainmentBannedAbilityAttacker(gBattleMons[gBattlerAttacker].ability) - || IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability)) + || IsEntrainmentBannedAbility(gBattleMons[gBattlerTarget].ability)) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); gBattlescriptCurrInstr = cmd->failInstr; @@ -13875,24 +13875,25 @@ static void Cmd_tryswapitems(void) } } -// Role Play +// Role Play, Doodle static void Cmd_trycopyability(void) { - CMD_ARGS(const u8 *failInstr); + CMD_ARGS(u8 battler, const u8 *failInstr); + u32 battler = GetBattlerForBattleScript(cmd->battler); u16 defAbility = gBattleMons[gBattlerTarget].ability; - if (gBattleMons[gBattlerAttacker].ability == defAbility + if (gBattleMons[battler].ability == defAbility || defAbility == ABILITY_NONE - || IsRolePlayBannedAbilityAtk(gBattleMons[gBattlerAttacker].ability) - || IsRolePlayBannedAbility(defAbility)) + || IsRolePlayDoodleBannedAbilityAttacker(gBattleMons[battler].ability) + || IsRolePlayDoodleBannedAbility(defAbility)) { gBattlescriptCurrInstr = cmd->failInstr; } else { - gBattleScripting.abilityPopupOverwrite = gBattleMons[gBattlerAttacker].ability; - gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = defAbility; + gBattleScripting.abilityPopupOverwrite = gBattleMons[battler].ability; + gBattleMons[battler].ability = gBattleStruct->overwrittenAbilities[battler] = defAbility; gLastUsedAbility = defAbility; gBattlescriptCurrInstr = cmd->nextInstr; } diff --git a/src/battle_util.c b/src/battle_util.c index be71068e2f..359ba8226b 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -96,81 +96,113 @@ 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_AS_ONE_ICE_RIDER, + ABILITY_AS_ONE_SHADOW_RIDER, ABILITY_BATTLE_BOND, - ABILITY_POWER_CONSTRUCT, - ABILITY_NEUTRALIZING_GAS, - ABILITY_ICE_FACE, - ABILITY_HUNGER_SWITCH, + 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 sRolePlayBannedAbilities[] = +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_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, ABILITY_ZERO_TO_HERO, }; -static const u16 sRolePlayBannedAttackerAbilities[] = +static const u16 sRolePlayDoodleBannedAttackerAbilities[] = { - ABILITY_MULTITYPE, - ABILITY_ZEN_MODE, - ABILITY_STANCE_CHANGE, - ABILITY_SCHOOLING, - ABILITY_COMATOSE, - ABILITY_SHIELDS_DOWN, - ABILITY_DISGUISE, - ABILITY_RKS_SYSTEM, + ABILITY_AS_ONE_ICE_RIDER, + ABILITY_AS_ONE_SHADOW_RIDER, ABILITY_BATTLE_BOND, - ABILITY_POWER_CONSTRUCT, - ABILITY_ICE_FACE, + 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_MULTITYPE, - ABILITY_STANCE_CHANGE, - ABILITY_SCHOOLING, - ABILITY_COMATOSE, - ABILITY_SHIELDS_DOWN, - ABILITY_DISGUISE, - ABILITY_RKS_SYSTEM, + ABILITY_AS_ONE_ICE_RIDER, + ABILITY_AS_ONE_SHADOW_RIDER, ABILITY_BATTLE_BOND, - ABILITY_POWER_CONSTRUCT, - ABILITY_TRUANT, - ABILITY_ICE_FACE, + 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, }; @@ -180,10 +212,13 @@ static const u16 sGastroAcidBannedAbilities[] = 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, @@ -193,38 +228,87 @@ static const u16 sGastroAcidBannedAbilities[] = 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_TRACE, - ABILITY_FORECAST, + ABILITY_AS_ONE_ICE_RIDER, + ABILITY_AS_ONE_SHADOW_RIDER, + ABILITY_BATTLE_BOND, + ABILITY_COMATOSE, + ABILITY_COMMANDER, + ABILITY_DISGUISE, ABILITY_FLOWER_GIFT, - ABILITY_ZEN_MODE, + ABILITY_FORECAST, + ABILITY_GULP_MISSILE, + ABILITY_HADRON_ENGINE, + ABILITY_HUNGER_SWITCH, + ABILITY_ICE_FACE, ABILITY_ILLUSION, ABILITY_IMPOSTER, - ABILITY_POWER_OF_ALCHEMY, - ABILITY_RECEIVER, - ABILITY_DISGUISE, - ABILITY_POWER_CONSTRUCT, + ABILITY_MULTITYPE, ABILITY_NEUTRALIZING_GAS, - ABILITY_ICE_FACE, - ABILITY_HUNGER_SWITCH, - ABILITY_GULP_MISSILE, + 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 sEntrainmentTargetSimpleBeamBannedAbilities[] = +static const u16 sSimpleBeamBannedAbilities[] = { - ABILITY_TRUANT, - ABILITY_MULTITYPE, - ABILITY_STANCE_CHANGE, - ABILITY_SCHOOLING, - ABILITY_COMATOSE, - ABILITY_SHIELDS_DOWN, - ABILITY_DISGUISE, - ABILITY_RKS_SYSTEM, + ABILITY_AS_ONE_ICE_RIDER, + ABILITY_AS_ONE_SHADOW_RIDER, ABILITY_BATTLE_BOND, - ABILITY_ICE_FACE, + 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, }; @@ -6193,28 +6277,33 @@ bool32 TryPrimalReversion(u32 battler) return FALSE; } -bool32 IsNeutralizingGasBannedAbility(u32 ability) +static const u16 sNeutralizingGasBannedAbilities[] = { - switch (ability) + 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++) { - case ABILITY_MULTITYPE: - case ABILITY_ZEN_MODE: - case ABILITY_STANCE_CHANGE: - case ABILITY_POWER_CONSTRUCT: - case ABILITY_SCHOOLING: - case ABILITY_RKS_SYSTEM: - case ABILITY_SHIELDS_DOWN: - case ABILITY_COMATOSE: - case ABILITY_DISGUISE: - case ABILITY_GULP_MISSILE: - case ABILITY_ICE_FACE: - case ABILITY_AS_ONE_ICE_RIDER: - case ABILITY_AS_ONE_SHADOW_RIDER: - case ABILITY_ZERO_TO_HERO: - return TRUE; - default: - return FALSE; + if (ability == sNeutralizingGasBannedAbilities[i]) + return TRUE; } + return FALSE; } bool32 IsNeutralizingGasOnField(void) @@ -10811,28 +10900,6 @@ bool32 CanFling(u32 battler) } // 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; @@ -10844,6 +10911,28 @@ bool32 IsSkillSwapBannedAbility(u16 ability) 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; @@ -10866,6 +10955,17 @@ bool32 IsGastroAcidBannedAbility(u16 ability) 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; @@ -10877,12 +10977,12 @@ bool32 IsEntrainmentBannedAbilityAttacker(u16 ability) return FALSE; } -bool32 IsEntrainmentTargetOrSimpleBeamBannedAbility(u16 ability) +bool32 IsSimpleBeamBannedAbility(u16 ability) { u32 i; - for (i = 0; i < ARRAY_COUNT(sEntrainmentTargetSimpleBeamBannedAbilities); i++) + for (i = 0; i < ARRAY_COUNT(sSimpleBeamBannedAbilities); i++) { - if (ability == sEntrainmentTargetSimpleBeamBannedAbilities[i]) + if (ability == sSimpleBeamBannedAbilities[i]) return TRUE; } return FALSE; diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 2d659c9632..8284bbe664 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -13269,13 +13269,13 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_DOODLE] = { - .effect = EFFECT_PLACEHOLDER, // EFFECT_DOODLE + .effect = EFFECT_DOODLE, .power = 0, .type = TYPE_NORMAL, .accuracy = 100, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_BOTH, + .target = MOVE_TARGET_SELECTED, .priority = 0, .category = BATTLE_CATEGORY_STATUS, .ignoresProtect = TRUE, diff --git a/test/battle/move_effect/doodle.c b/test/battle/move_effect/doodle.c new file mode 100644 index 0000000000..7147ee6154 --- /dev/null +++ b/test/battle/move_effect/doodle.c @@ -0,0 +1,26 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_DOODLE].effect == EFFECT_DOODLE); +} + +DOUBLE_BATTLE_TEST("Doodle gives the target's ability to user and ally") +{ + GIVEN { + PLAYER(SPECIES_WYNAUT); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_STENCH); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_DOODLE, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, playerLeft); + MESSAGE("Wynaut copied Foe Wobbuffet's Stench!"); + MESSAGE("Wynaut copied Foe Wobbuffet's Stench!"); + } THEN { + EXPECT(playerLeft->ability == ABILITY_STENCH); + EXPECT(playerRight->ability == ABILITY_STENCH); + } +}