From 33e8e20118f21252d08911e2d06a0d0b2e9bd5b3 Mon Sep 17 00:00:00 2001 From: Eduardo Alvaro Quezada D'Ottone Date: Sat, 8 Feb 2020 15:29:51 -0300 Subject: [PATCH] Disguise ability (#258) * Protection from attacks. * Changes form when Busting Disguise. * Ability changing moves set to fail. - Simple Beam and Worry Seed now fail if the target has Disguise. - Role Play and Skill Swap now fail if either the attacker or the target have Disguise. * Disguise no longer triggers when transformed. * Mimikyu reverts to Disguised * No longer blocks from entry hazards and weather. * Applied review changes * Oops, new line * yeah --- data/battle_scripts_1.s | 13 +++++ include/battle_script_commands.h | 1 + include/battle_scripts.h | 1 + include/constants/battle_config.h | 2 + src/battle_script_commands.c | 83 +++++++++++++++++++++---------- src/battle_util.c | 1 + 6 files changed, 74 insertions(+), 27 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 825a1a93c..b13b67a5b 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5903,6 +5903,19 @@ BattleScript_StanceChangeActivates:: waitanimation handleformchange BS_ATTACKER, 2 return + +BattleScript_DisguiseBustedActivates:: + pause 0x5 + copybyte gBattlerAbility, gBattlerTarget + call BattleScript_AbilityPopUp + printstring STRINGID_EMPTYSTRING3 + waitmessage 0x1 + handleformchange BS_TARGET, 0 + handleformchange BS_TARGET, 1 + playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL + waitanimation + handleformchange BS_TARGET, 2 + return BattleScript_IllusionOff:: spriteignore0hp TRUE diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index 8bd94150a..ab2217712 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -14,6 +14,7 @@ void BufferMoveToLearnIntoBattleTextBuff2(void); void HandleBattleWindow(u8 xStart, u8 yStart, u8 xEnd, u8 yEnd, u8 flags); bool8 UproarWakeUpCheck(u8 battlerId); bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move); +bool32 DoesDisguiseBlockMove(u8 battlerAtk, u8 battlerDef, u32 move); bool32 CanUseLastResort(u8 battlerId); u32 IsFlowerVeilProtected(u32 battler); u32 IsLeafGuardProtected(u32 battler); diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 824b96548..93f4e3b09 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -329,5 +329,6 @@ extern const u8 BattleScript_IllusionOff[]; extern const u8 BattleScript_DancerActivates[]; extern const u8 BattleScript_AftermathDmg[]; extern const u8 BattleScript_StanceChangeActivates[]; +extern const u8 BattleScript_DisguiseBustedActivates[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index a5a9c8206..2f025053d 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -11,6 +11,8 @@ #define SPECIES_GENESECT 0 #define SPECIES_AEGISLASH 0 #define SPECIES_AEGISLASH_BLADE 10000 +#define SPECIES_MIMIKYU 0 +#define SPECIES_MIMIKYU_BUSTED 10001 // Items with peculiar battle effects. Remove them if they're properly placed in constant/items.h #define ITEM_GRISEOUS_ORB 0 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index e101e82be..0c5cf5374 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1532,6 +1532,8 @@ static void Cmd_adjustdamage(void) if (DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) goto END; + if (DoesDisguiseBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) + goto END; if (gBattleMons[gBattlerTarget].hp > gBattleMoveDamage) goto END; @@ -1709,17 +1711,9 @@ static void Cmd_healthbarupdate(void) { PrepareStringBattle(STRINGID_SUBSTITUTEDAMAGED, gActiveBattler); } - else + else if (!DoesDisguiseBlockMove(gBattlerAttacker, gActiveBattler, gCurrentMove)) { - s16 healthValue; - - s32 currDmg = gBattleMoveDamage; - s32 maxPossibleDmgValue = 10000; // not present in R/S, ensures that huge damage values don't change sign - - if (currDmg <= maxPossibleDmgValue) - healthValue = currDmg; - else - healthValue = maxPossibleDmgValue; + s16 healthValue = min(gBattleMoveDamage, 10000); // Max damage (10000) not present in R/S, ensures that huge damage values don't change sign BtlController_EmitHealthBarUpdate(0, healthValue); MarkBattlerForControllerExec(gActiveBattler); @@ -1774,6 +1768,12 @@ static void Cmd_datahpupdate(void) return; } } + else if (DoesDisguiseBlockMove(gBattlerAttacker, gActiveBattler, gCurrentMove)) + { + gBattleMons[gActiveBattler].species = SPECIES_MIMIKYU_BUSTED; + BattleScriptPush(gBattlescriptCurrInstr + 2); + gBattlescriptCurrInstr = BattleScript_DisguiseBustedActivates; + } else { gHitMarker &= ~(HITMARKER_IGNORE_SUBSTITUTE); @@ -7132,6 +7132,7 @@ static void Cmd_various(void) case ABILITY_SIMPLE: case ABILITY_TRUANT: case ABILITY_STANCE_CHANGE: + case ABILITY_DISGUISE: case ABILITY_MULTITYPE: gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); break; @@ -10570,16 +10571,18 @@ static void Cmd_tryswapitems(void) // trick static void Cmd_trycopyability(void) // role play { - if (gBattleMons[gBattlerTarget].ability != 0 - && gBattleMons[gBattlerTarget].ability != ABILITY_WONDER_GUARD) + switch (gBattleMons[gBattlerTarget].ability) { - gBattleMons[gBattlerAttacker].ability = gBattleMons[gBattlerTarget].ability; - gLastUsedAbility = gBattleMons[gBattlerTarget].ability; - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + 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; } } @@ -10718,14 +10721,28 @@ static void Cmd_setroom(void) static void Cmd_tryswapabilities(void) // skill swap { - if ((gBattleMons[gBattlerAttacker].ability == 0 - && gBattleMons[gBattlerTarget].ability == 0) - || gBattleMons[gBattlerAttacker].ability == ABILITY_WONDER_GUARD - || gBattleMons[gBattlerTarget].ability == ABILITY_WONDER_GUARD - || gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } + switch (gBattleMons[gBattlerAttacker].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); + } else { u8 abilityAtk = gBattleMons[gBattlerAttacker].ability; @@ -11133,6 +11150,17 @@ bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move) return TRUE; } +bool32 DoesDisguiseBlockMove(u8 battlerAtk, u8 battlerDef, u32 move) +{ + if (GetBattlerAbility(battlerDef) != ABILITY_DISGUISE + || gBattleMons[battlerDef].species != SPECIES_MIMIKYU + || gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED + || gBattleMoves[move].power == 0) + return FALSE; + else + return TRUE; +} + static void Cmd_jumpifsubstituteblocks(void) { if (DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) @@ -11740,6 +11768,7 @@ static void Cmd_tryworryseed(void) case ABILITY_MULTITYPE: case ABILITY_TRUANT: case ABILITY_STANCE_CHANGE: + case ABILITY_DISGUISE: gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); break; default: diff --git a/src/battle_util.c b/src/battle_util.c index cbcca73d7..964fd01fb 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6314,6 +6314,7 @@ void UndoFormChange(u32 monId, u32 side) static const u16 species[][2] = // changed form id, default form id { {SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH}, + {SPECIES_MIMIKYU_BUSTED, SPECIES_MIMIKYU}, }; currSpecies = GetMonData(&party[monId], MON_DATA_SPECIES, NULL);