From f1ca254c28d85f563f66bc7bdd33f441135ceec9 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Mon, 2 Jan 2023 18:37:27 -0300 Subject: [PATCH] Updated the Mimicry reimplementation Mimicry is now a proud member of ABILITYEFFECT_ON_TERRAIN. Misc. changes: -Ditched the dependency on and usage of gBattlerAttacker for the effects inside ABILITYEFFECT_ON_WEATHER and ABILITYEFFECT_ON_TERRAIN. -Made Cmd_switchineffects activate ABILITYEFFECT_ON_TERRAIN to take into account overworld weather-induced field terrains. -Updated the text strings printed by the battle scripts inside the aforementioned AbilityBattleEffects caseIDs. -Removed constant label of unused VARIOUS_TRY_TO_APPLY_MIMICRY which I forgot about. -Updated ChangeTypeBasedOnTerrain, partly as a result of the aforementioned changes but also for optimization purposes. -There was never a reason to establish an empty scope, or to use GET_MOVE_TYPE and the variables that complemented it. -Removed case ABILITY_QUARK_DRIVE from AbilityBattleEffects' case ABILITYEFFECT_ON_SWITCHIN. --- asm/macros/battle_script.inc | 4 -- data/battle_scripts_1.s | 18 ----- include/battle.h | 1 + include/constants/battle_script_commands.h | 78 +++++++++++----------- src/battle_message.c | 8 +-- src/battle_script_commands.c | 10 ++- src/battle_util.c | 66 ++++++++---------- 7 files changed, 74 insertions(+), 111 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index d97dcb825..c29d8f7c4 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -2037,10 +2037,6 @@ various \battler, VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES .endm - .macro applymimicry battler:req - various \battler, VARIOUS_APPLY_MIMICRY - .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 21f424fe1..f9320a77d 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -2526,26 +2526,8 @@ BattleScript_EffectPsychicTerrain: playanimation BS_ATTACKER, B_ANIM_RESTORE_BG call BattleScript_ActivateTerrainAbilities call BattleScript_TerrainSeedLoop - call BattleScript_TryToApplyMimicry goto BattleScript_MoveEnd -BattleScript_TryToApplyMimicry: - savetarget - setbyte gBattlerTarget, 0 -BattleScript_TryToApplyMimicry_Loop: - jumpifword CMP_NOT_EQUAL, gFieldStatuses, STATUS_FIELD_TERRAIN_ANY, BattleScript_TryToApplyMimicry_Increment - jumpifability BS_TARGET, ABILITY_MIMICRY, BattleScript_TryToApplyMimicry_Effect -BattleScript_TryToApplyMimicry_Effect: - pause B_WAIT_TIME_SHORT - call BattleScript_AbilityPopUp - applymimicry BS_TARGET - printstring STRINGID_BATTLERTYPECHANGEDTO - waitmessage B_WAIT_TIME_SHORT -BattleScript_TryToApplyMimicry_Increment: - addbyte gBattlerTarget, 1 - jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_TryToApplyMimicry_Loop - return - BattleScript_EffectTopsyTurvy: attackcanceler attackstring diff --git a/include/battle.h b/include/battle.h index 8242d91d4..71eb3b1a8 100644 --- a/include/battle.h +++ b/include/battle.h @@ -192,6 +192,7 @@ struct SpecialStatus u8 dancerUsedMove:1; u8 dancerOriginalTarget:3; // End of byte + u8 terrainAbilityDone:1; }; struct SideTimer diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index e295609e0..a13423bcb 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -216,46 +216,44 @@ #define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125 #define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126 #define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127 -#define VARIOUS_TRY_TO_APPLY_MIMICRY 128 -#define VARIOUS_PHOTON_GEYSER_CHECK 129 -#define VARIOUS_SHELL_SIDE_ARM_CHECK 130 -#define VARIOUS_TRY_NO_RETREAT 131 -#define VARIOUS_TRY_TAR_SHOT 132 -#define VARIOUS_CAN_TAR_SHOT_WORK 133 -#define VARIOUS_CHECK_POLTERGEIST 134 -#define VARIOUS_SET_OCTOLOCK 135 -#define VARIOUS_CUT_1_3_HP_RAISE_STATS 136 -#define VARIOUS_TRY_END_NEUTRALIZING_GAS 137 -#define VARIOUS_JUMP_IF_UNDER_200 138 -#define VARIOUS_SET_SKY_DROP 139 -#define VARIOUS_CLEAR_SKY_DROP 140 -#define VARIOUS_SKY_DROP_YAWN 141 -#define VARIOUS_JUMP_IF_CANT_FLING 142 -#define VARIOUS_JUMP_IF_HOLD_EFFECT 143 -#define VARIOUS_CURE_CERTAIN_STATUSES 144 -#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 145 -#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 146 -#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 147 -#define VARIOUS_SAVE_BATTLER_ITEM 148 -#define VARIOUS_RESTORE_BATTLER_ITEM 149 -#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 150 -#define VARIOUS_SET_BEAK_BLAST 151 -#define VARIOUS_SWAP_SIDE_STATUSES 152 -#define VARIOUS_SET_Z_EFFECT 153 -#define VARIOUS_TRY_SYMBIOSIS 154 -#define VARIOUS_CAN_TELEPORT 155 -#define VARIOUS_GET_BATTLER_SIDE 156 -#define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 157 -#define VARIOUS_SWAP_STATS 158 -#define VARIOUS_JUMP_IF_ROD 159 -#define VARIOUS_JUMP_IF_ABSORB 160 -#define VARIOUS_JUMP_IF_MOTOR 161 -#define VARIOUS_TEATIME_INVUL 162 -#define VARIOUS_TEATIME_TARGETS 163 -#define VARIOUS_TRY_WIND_RIDER_POWER 164 -#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 165 -#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 166 -#define VARIOUS_APPLY_MIMICRY 167 +#define VARIOUS_PHOTON_GEYSER_CHECK 128 +#define VARIOUS_SHELL_SIDE_ARM_CHECK 129 +#define VARIOUS_TRY_NO_RETREAT 130 +#define VARIOUS_TRY_TAR_SHOT 131 +#define VARIOUS_CAN_TAR_SHOT_WORK 132 +#define VARIOUS_CHECK_POLTERGEIST 133 +#define VARIOUS_SET_OCTOLOCK 134 +#define VARIOUS_CUT_1_3_HP_RAISE_STATS 135 +#define VARIOUS_TRY_END_NEUTRALIZING_GAS 136 +#define VARIOUS_JUMP_IF_UNDER_200 137 +#define VARIOUS_SET_SKY_DROP 138 +#define VARIOUS_CLEAR_SKY_DROP 139 +#define VARIOUS_SKY_DROP_YAWN 140 +#define VARIOUS_JUMP_IF_CANT_FLING 141 +#define VARIOUS_JUMP_IF_HOLD_EFFECT 142 +#define VARIOUS_CURE_CERTAIN_STATUSES 143 +#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 144 +#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 145 +#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 146 +#define VARIOUS_SAVE_BATTLER_ITEM 147 +#define VARIOUS_RESTORE_BATTLER_ITEM 148 +#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 149 +#define VARIOUS_SET_BEAK_BLAST 150 +#define VARIOUS_SWAP_SIDE_STATUSES 151 +#define VARIOUS_SET_Z_EFFECT 152 +#define VARIOUS_TRY_SYMBIOSIS 153 +#define VARIOUS_CAN_TELEPORT 154 +#define VARIOUS_GET_BATTLER_SIDE 155 +#define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 156 +#define VARIOUS_SWAP_STATS 157 +#define VARIOUS_JUMP_IF_ROD 158 +#define VARIOUS_JUMP_IF_ABSORB 159 +#define VARIOUS_JUMP_IF_MOTOR 160 +#define VARIOUS_TEATIME_INVUL 161 +#define VARIOUS_TEATIME_TARGETS 162 +#define VARIOUS_TRY_WIND_RIDER_POWER 163 +#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 164 +#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 165 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_message.c b/src/battle_message.c index 1189cf3e1..c1ebe8d79 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -740,7 +740,7 @@ static const u8 sText_AbilityAllowsOnlyMove[] = _("{B_ATK_ABILITY} allows the\nu static const u8 sText_SwappedAbilities[] = _("{B_DEF_NAME_WITH_PREFIX} swapped Abilities\nwith its target!"); static const u8 sText_PastelVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is protected\nby a pastel veil!"); static const u8 sText_PastelVeilEnters[] = _("{B_DEF_NAME_WITH_PREFIX} was cured\nof its poisoning!"); -static const u8 sText_BattlerTypeChangedTo[] = _("{B_BUFF1}'s type\nchanged to {B_BUFF2}!"); +static const u8 sText_BattlerTypeChangedTo[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s type\nchanged to {B_BUFF1}!"); static const u8 sText_BothCanNoLongerEscape[] = _("Neither Pokémon can run away!"); static const u8 sText_CantEscapeDueToUsedMove[] = _("{B_ATK_NAME_WITH_PREFIX} can no longer escape\nbecause it used {B_CURRENT_MOVE}!"); static const u8 sText_PkmnBecameWeakerToFire[] = _("{B_DEF_NAME_WITH_PREFIX} became\nweaker to fire!"); @@ -762,9 +762,9 @@ static const u8 sText_TargetToughedItOut[] = _("{B_DEF_NAME_WITH_PREFIX} toughed static const u8 sText_AttackerLostElectricType[] = _("{B_ATK_NAME_WITH_PREFIX} used up all\nof its electricity!"); static const u8 sText_AttackerSwitchedStatWithTarget[] = _("{B_ATK_NAME_WITH_PREFIX} switched {B_BUFF1}\nwith its target!"); static const u8 sText_BeingHitChargedPkmnWithPower[] = _("Being hit by {B_CURRENT_MOVE}\ncharged {B_ATK_NAME_WITH_PREFIX} with power!"); -static const u8 sText_SunlightActivatedAbility[] = _("The harsh sunlight activated\n{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}!"); -static const u8 sText_StatWasHeightened[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1} was heightened!"); -static const u8 sText_ElectricTerrainActivatedAbility[] = _("The Electric Terrain activated\n{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}!"); +static const u8 sText_SunlightActivatedAbility[] = _("The harsh sunlight activated\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ABILITY}!"); +static const u8 sText_StatWasHeightened[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} was heightened!"); +static const u8 sText_ElectricTerrainActivatedAbility[] = _("The Electric Terrain activated\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ABILITY}!"); static const u8 sText_AbilityWeakenedSurroundingMonsStat[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\nweakened the {B_BUFF1} of\lall surrounding Pokémon!\p"); static const u8 sText_AttackerGainedStrengthFromTheFallen[] = _("{B_ATK_NAME_WITH_PREFIX} gained strength\nfrom the fallen!"); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d03d04cb6..26c82fc74 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6785,9 +6785,10 @@ static void Cmd_switchineffects(void) gDisableStructs[gActiveBattler].truantSwitchInHack = 0; if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0) - || ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, gActiveBattler, FALSE) - || AbilityBattleEffects(ABILITYEFFECT_TRACE2, 0, 0, 0, 0) - || AbilityBattleEffects(ABILITYEFFECT_WEATHER_FORM, 0, 0, 0, 0)) + || (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY && AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, gActiveBattler, 0, 0, 0)) + || ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, gActiveBattler, FALSE) + || AbilityBattleEffects(ABILITYEFFECT_TRACE2, 0, 0, 0, 0) + || AbilityBattleEffects(ABILITYEFFECT_WEATHER_FORM, 0, 0, 0, 0)) return; gSideStatuses[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_SPIKES_DAMAGED | SIDE_STATUS_TOXIC_SPIKES_DAMAGED | SIDE_STATUS_STEALTH_ROCK_DAMAGED | SIDE_STATUS_STICKY_WEB_DAMAGED); @@ -10209,9 +10210,6 @@ static void Cmd_various(void) gBattlescriptCurrInstr += 3; AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, gActiveBattler, 0, 0, 0); return; - case VARIOUS_APPLY_MIMICRY: - ChangeTypeBasedOnTerrain(gActiveBattler); - break; } // End of switch (gBattlescriptCurrInstr[2]) gBattlescriptCurrInstr += 3; diff --git a/src/battle_util.c b/src/battle_util.c index 85f9e73bf..dac4e00f5 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -4297,28 +4297,24 @@ static u8 ForewarnChooseMove(u32 battler) void ChangeTypeBasedOnTerrain(u8 battlerId) { - u16 moveType, move; + u8 battlerType; u16 terrainFlags = VarGet(VAR_TERRAIN) & STATUS_FIELD_TERRAIN_ANY; if (terrainFlags && gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) gFieldStatuses = terrainFlags | STATUS_FIELD_TERRAIN_PERMANENT; // terrain is permanent - GET_MOVE_TYPE(move, moveType); - { - if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) - moveType = TYPE_ELECTRIC; - else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) - moveType = TYPE_GRASS; - else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) - moveType = TYPE_FAIRY; - else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) - moveType = TYPE_PSYCHIC; - else // failsafe - moveType = gSpeciesInfo[battlerId].type1; - } - SET_BATTLER_TYPE(battlerId, moveType); - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, battlerId, gBattlerPartyIndexes[battlerId]) - PREPARE_TYPE_BUFFER(gBattleTextBuff2, moveType); + if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) + battlerType = TYPE_ELECTRIC; + else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) + battlerType = TYPE_GRASS; + else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) + battlerType = TYPE_FAIRY; + else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) + battlerType = TYPE_PSYCHIC; + else // failsafe + battlerType = gSpeciesInfo[battlerId].type1; + SET_BATTLER_TYPE(battlerId, battlerType); + PREPARE_TYPE_BUFFER(gBattleTextBuff1, battlerType); } u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 moveArg) @@ -4821,15 +4817,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; - case ABILITY_MIMICRY: - if (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY && !gSpecialStatuses[battler].switchInAbilityDone) - { - ChangeTypeBasedOnTerrain(battler); - BattleScriptPushCursorAndCallback(BattleScript_MimicryActivates_End3); - gSpecialStatuses[battler].switchInAbilityDone = TRUE; - effect++; - } - break; case ABILITY_PROTOSYNTHESIS: if (!gSpecialStatuses[battler].switchInAbilityDone && gBattleWeather & B_WEATHER_SUN) { @@ -4839,15 +4826,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; - case ABILITY_QUARK_DRIVE: - if (!gSpecialStatuses[battler].switchInAbilityDone && gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) - { - gSpecialStatuses[battler].switchInAbilityDone = TRUE; - PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); - BattleScriptPushCursorAndCallback(BattleScript_QuarkDriveActivates); - effect++; - } - break; case ABILITY_VESSEL_OF_RUIN: if (!gSpecialStatuses[battler].switchInAbilityDone) { @@ -6197,7 +6175,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITYEFFECT_ON_WEATHER: // For ability effects that activate when the battle weather changes. - battler = gBattlerAbility = gBattlerAttacker = gBattleScripting.battler; + battler = gBattlerAbility = gBattleScripting.battler; switch (GetBattlerAbility(battler)) { case ABILITY_FORECAST: @@ -6224,12 +6202,22 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITYEFFECT_ON_TERRAIN: // For ability effects that activate when the field terrain changes. - battler = gBattlerAbility = gBattlerAttacker = gBattleScripting.battler; + battler = gBattlerAbility = gBattleScripting.battler; switch (GetBattlerAbility(battler)) { - case ABILITY_QUARK_DRIVE: - if (IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN)) + case ABILITY_MIMICRY: + if (!gSpecialStatuses[battler].terrainAbilityDone) { + gSpecialStatuses[battler].terrainAbilityDone = TRUE; + ChangeTypeBasedOnTerrain(battler); + BattleScriptPushCursorAndCallback(BattleScript_MimicryActivates_End3); + effect++; + } + break; + case ABILITY_QUARK_DRIVE: + if (!gSpecialStatuses[battler].terrainAbilityDone && IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN)) + { + gSpecialStatuses[battler].terrainAbilityDone = TRUE; PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); BattleScriptPushCursorAndCallback(BattleScript_QuarkDriveActivates); effect++;