diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index fbb18e9e4..c854e8320 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1709,6 +1709,11 @@ various \battler, VARIOUS_TRY_FRISK .endm + .macro jumpifshieldsdown battler:req, ptr:req + various \battler, VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED + .4byte \ptr + .endm + @ helpful macros .macro setstatchanger stat:req, stages:req, down:req setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index a3cf4b548..b4cfbcd3a 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -2101,6 +2101,7 @@ BattleScript_EffectSleep:: jumpifflowerveil BattleScript_FlowerVeilProtects jumpifability BS_TARGET_SIDE, ABILITY_SWEET_VEIL, BattleScript_SweetVeilProtects jumpifleafguard BattleScript_LeafGuardProtects + jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, BattleScript_SafeguardProtected @@ -2618,6 +2619,7 @@ BattleScript_EffectToxic:: jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects jumpifflowerveil BattleScript_FlowerVeilProtects jumpifleafguard BattleScript_LeafGuardProtects + jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects jumpifsubstituteblocks BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_POISON | STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed @@ -2944,6 +2946,7 @@ BattleScript_EffectPoison:: jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects jumpifflowerveil BattleScript_FlowerVeilProtects jumpifleafguard BattleScript_LeafGuardProtects + jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects jumpifsubstituteblocks BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_POISON, BattleScript_AlreadyPoisoned jumpifstatus BS_TARGET, STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned @@ -2968,6 +2971,7 @@ BattleScript_EffectParalyze: jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects jumpifflowerveil BattleScript_FlowerVeilProtects jumpifleafguard BattleScript_LeafGuardProtects + jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects jumpifsubstituteblocks BattleScript_ButItFailed typecalc jumpifmovehadnoeffect BattleScript_ButItFailed @@ -4156,6 +4160,7 @@ BattleScript_EffectWillOWisp:: jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects jumpifflowerveil BattleScript_FlowerVeilProtects jumpifleafguard BattleScript_LeafGuardProtects + jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, BattleScript_SafeguardProtected @@ -4429,6 +4434,7 @@ BattleScript_EffectYawn:: jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_PrintBankAbilityMadeIneffective jumpifflowerveil BattleScript_FlowerVeilProtects jumpifleafguard BattleScript_LeafGuardProtects + jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects jumpifsubstituteblocks BattleScript_ButItFailed jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, BattleScript_SafeguardProtected accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON @@ -5971,7 +5977,7 @@ BattleScript_MegaEvolution:: switchinabilities BS_ATTACKER end2 -BattleScript_StanceChangeActivates:: +BattleScript_AttackerFormChange:: pause 0x5 copybyte gBattlerAbility, gBattlerAttacker call BattleScript_AbilityPopUp @@ -5983,8 +5989,12 @@ BattleScript_StanceChangeActivates:: waitanimation handleformchange BS_ATTACKER, 2 return + +BattleScript_AttackerFormChangeEnd3:: + call BattleScript_AttackerFormChange + end3 -BattleScript_DisguiseBustedActivates:: +BattleScript_TargetFormChange:: pause 0x5 copybyte gBattlerAbility, gBattlerTarget call BattleScript_AbilityPopUp diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index 8fec39df3..cd8886f64 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -19,6 +19,8 @@ bool32 DoesDisguiseBlockMove(u8 battlerAtk, u8 battlerDef, u32 move); bool32 CanUseLastResort(u8 battlerId); u32 IsFlowerVeilProtected(u32 battler); u32 IsLeafGuardProtected(u32 battler); +bool32 IsShieldsDownProtected(u32 battler); +u32 IsAbilityStatusProtected(u32 battler); extern void (* const gBattleScriptingCommandsTable[])(void); extern const u8 gUnknown_0831C494[][4]; diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 493dc1cda..9dd97ac46 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -329,8 +329,9 @@ extern const u8 BattleScript_MoveEffectBugBite[]; 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[]; +extern const u8 BattleScript_AttackerFormChange[]; +extern const u8 BattleScript_AttackerFormChangeEnd3[]; +extern const u8 BattleScript_TargetFormChange[]; extern const u8 BattleScript_AnticipationActivates[]; extern const u8 BattleScript_SlowStartEnds[]; extern const u8 BattleScript_HealerActivates[]; diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index b93838b57..753ff8735 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -13,6 +13,10 @@ #define SPECIES_AEGISLASH_BLADE 10000 #define SPECIES_MIMIKYU 0 #define SPECIES_MIMIKYU_BUSTED 10001 +#define SPECIES_DARMANITAN 0 +#define SPECIES_DARMANITAN_ZEN 10002 +#define SPECIES_MINIOR_CORE 0 +#define SPECIES_MINIOR 10003 // Items with peculiar battle effects. Remove them if they're properly placed in constant/items.h #define ITEM_GRISEOUS_ORB 0 diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index bc88e04ad..17fd45809 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -153,6 +153,7 @@ #define VARIOUS_TRY_ACTIVATE_RECEIVER 90 #define VARIOUS_TRY_ACTIVATE_BEAST_BOOST 91 #define VARIOUS_TRY_FRISK 92 +#define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 93 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 698ab718f..1c0580d87 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1038,7 +1038,7 @@ static bool32 TryAegiFormChange(void) } BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_StanceChangeActivates; + gBattlescriptCurrInstr = BattleScript_AttackerFormChange; return TRUE; } @@ -1797,7 +1797,7 @@ static void Cmd_datahpupdate(void) { gBattleMons[gActiveBattler].species = SPECIES_MIMIKYU_BUSTED; BattleScriptPush(gBattlescriptCurrInstr + 2); - gBattlescriptCurrInstr = BattleScript_DisguiseBustedActivates; + gBattlescriptCurrInstr = BattleScript_TargetFormChange; } else { @@ -2224,8 +2224,7 @@ void SetMoveEffect(bool32 primary, u32 certain) || GetBattlerAbility(gEffectBattler) == ABILITY_INSOMNIA || GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE || IsAbilityOnSide(gEffectBattler, ABILITY_SWEET_VEIL) - || IsFlowerVeilProtected(gEffectBattler) - || IsLeafGuardProtected(gEffectBattler)) + || IsAbilityStatusProtected(gEffectBattler)) break; CancelMultiTurnMoves(gEffectBattler); @@ -2270,8 +2269,7 @@ void SetMoveEffect(bool32 primary, u32 certain) break; if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY || GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE - || IsFlowerVeilProtected(gEffectBattler) - || IsLeafGuardProtected(gEffectBattler)) + || IsAbilityStatusProtected(gEffectBattler)) break; statusChanged = TRUE; @@ -2310,8 +2308,7 @@ void SetMoveEffect(bool32 primary, u32 certain) break; if (GetBattlerAbility(gEffectBattler) == ABILITY_WATER_VEIL || GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE - || IsFlowerVeilProtected(gEffectBattler) - || IsLeafGuardProtected(gEffectBattler)) + || IsAbilityStatusProtected(gEffectBattler)) break; if (gBattleMons[gEffectBattler].status1) break; @@ -2329,8 +2326,7 @@ void SetMoveEffect(bool32 primary, u32 certain) break; if (GetBattlerAbility(gEffectBattler) == ABILITY_MAGMA_ARMOR || GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE - || IsFlowerVeilProtected(gEffectBattler) - || IsLeafGuardProtected(gEffectBattler)) + || IsAbilityStatusProtected(gEffectBattler)) break; CancelMultiTurnMoves(gEffectBattler); @@ -2375,8 +2371,7 @@ void SetMoveEffect(bool32 primary, u32 certain) break; if (GetBattlerAbility(gEffectBattler) == ABILITY_LIMBER || GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE - || IsFlowerVeilProtected(gEffectBattler) - || IsLeafGuardProtected(gEffectBattler)) + || IsAbilityStatusProtected(gEffectBattler)) break; if (gBattleMons[gEffectBattler].status1) break; @@ -2419,8 +2414,7 @@ void SetMoveEffect(bool32 primary, u32 certain) { if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY || GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE - || IsFlowerVeilProtected(gEffectBattler) - || IsLeafGuardProtected(gEffectBattler)) + || IsAbilityStatusProtected(gEffectBattler)) break; // It's redundant, because at this point we know the status1 value is 0. @@ -6748,6 +6742,19 @@ u32 IsLeafGuardProtected(u32 battler) return 0; } +bool32 IsShieldsDownProtected(u32 battler) +{ + return (gBattleMons[battler].ability == ABILITY_SHIELDS_DOWN + && gBattleMons[battler].species == SPECIES_MINIOR); +} + +u32 IsAbilityStatusProtected(u32 battler) +{ + return IsFlowerVeilProtected(battler) + || IsLeafGuardProtected(battler) + || IsShieldsDownProtected(battler); +} + static void RecalcBattlerStats(u32 battler, struct Pokemon *mon) { CalculateMonStats(mon); @@ -6809,6 +6816,12 @@ static void Cmd_various(void) else gBattlescriptCurrInstr += 7; return; + case VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED: + if (IsShieldsDownProtected(gActiveBattler)) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else + gBattlescriptCurrInstr += 7; + return; case VARIOUS_GET_STAT_VALUE: i = gBattlescriptCurrInstr[3]; gBattleMoveDamage = *(u16*)(&gBattleMons[gActiveBattler].attack) + (i - 1); diff --git a/src/battle_util.c b/src/battle_util.c index 6d099e60a..58d052ee7 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2745,6 +2745,37 @@ static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer) return FALSE; } +static bool32 ShouldChangeFormHpBased(u32 battler) +{ + // Ability, form >, form <= + static const u16 forms[][3] = + { + {ABILITY_ZEN_MODE, SPECIES_DARMANITAN, SPECIES_DARMANITAN_ZEN}, + {ABILITY_SHIELDS_DOWN, SPECIES_MINIOR, SPECIES_MINIOR_CORE}, + }; + u32 i; + + for (i = 0; i < ARRAY_COUNT(forms); i++) + { + if (gBattleMons[battler].ability == forms[i][0]) + { + if (gBattleMons[battler].species == forms[i][2] + && gBattleMons[battler].hp > gBattleMons[battler].maxHP / 2) + { + gBattleMons[battler].species = forms[i][1]; + return TRUE; + } + if (gBattleMons[battler].species == forms[i][1] + && gBattleMons[battler].hp <= gBattleMons[battler].maxHP / 2) + { + gBattleMons[battler].species = forms[i][2]; + return TRUE; + } + } + } + return FALSE; +} + u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveArg) { u8 effect = 0; @@ -3054,6 +3085,13 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA } } break; + case ABILITY_SHIELDS_DOWN: + if (ShouldChangeFormHpBased(battler)) + { + BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3); + effect++; + } + break; } break; case ABILITYEFFECT_ENDTURN: // 1 @@ -3203,6 +3241,11 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA effect++; } break; + case ABILITY_ZEN_MODE: + case ABILITY_SHIELDS_DOWN: + if ((effect = ShouldChangeFormHpBased(battler))) + BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3); + break; } } break; @@ -3563,8 +3606,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA && GetBattlerAbility(gBattlerAttacker) != ABILITY_INSOMNIA && GetBattlerAbility(gBattlerAttacker) != ABILITY_VITAL_SPIRIT && !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY) - && !IsFlowerVeilProtected(gBattlerAttacker) - && !IsLeafGuardProtected(gBattlerAttacker) + && !IsAbilityStatusProtected(gBattlerAttacker) && IsMoveMakingContact(move, gBattlerAttacker) && (Random() % 3) == 0) { @@ -3587,8 +3629,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_STEEL) && GetBattlerAbility(gBattlerAttacker) != ABILITY_IMMUNITY && !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY) - && !IsFlowerVeilProtected(gBattlerAttacker) - && !IsLeafGuardProtected(gBattlerAttacker) + && !IsAbilityStatusProtected(gBattlerAttacker) && IsMoveMakingContact(move, gBattlerAttacker) && (Random() % 3) == 0) { @@ -3609,8 +3650,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_ELECTRIC) && GetBattlerAbility(gBattlerAttacker) != ABILITY_LIMBER && !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY) - && !IsFlowerVeilProtected(gBattlerAttacker) - && !IsLeafGuardProtected(gBattlerAttacker) + && !IsAbilityStatusProtected(gBattlerAttacker) && IsMoveMakingContact(move, gBattlerAttacker) && (Random() % 3) == 0) { @@ -3630,8 +3670,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE) && GetBattlerAbility(gBattlerAttacker) != ABILITY_WATER_VEIL && !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY) - && !IsFlowerVeilProtected(gBattlerAttacker) - && !IsLeafGuardProtected(gBattlerAttacker) + && !IsAbilityStatusProtected(gBattlerAttacker) && (Random() % 3) == 0) { gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_BURN; @@ -3683,8 +3722,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA && !IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_STEEL) && GetBattlerAbility(gBattlerTarget) != ABILITY_IMMUNITY && !(gBattleMons[gBattlerTarget].status1 & STATUS1_ANY) - && !IsFlowerVeilProtected(gBattlerTarget) - && !IsLeafGuardProtected(gBattlerTarget) + && !IsAbilityStatusProtected(gBattlerTarget) && IsMoveMakingContact(move, gBattlerAttacker) && (Random() % 3) == 0) { @@ -6533,6 +6571,8 @@ void UndoFormChange(u32 monId, u32 side) { {SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH}, {SPECIES_MIMIKYU_BUSTED, SPECIES_MIMIKYU}, + {SPECIES_DARMANITAN_ZEN, SPECIES_DARMANITAN}, + {SPECIES_MINIOR, SPECIES_MINIOR_CORE}, }; currSpecies = GetMonData(&party[monId], MON_DATA_SPECIES, NULL);