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.
This commit is contained in:
LOuroboros 2023-01-02 18:37:27 -03:00
parent d0f5653f5e
commit f1ca254c28
7 changed files with 74 additions and 111 deletions

View File

@ -2037,10 +2037,6 @@
various \battler, VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES various \battler, VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES
.endm .endm
.macro applymimicry battler:req
various \battler, VARIOUS_APPLY_MIMICRY
.endm
@ helpful macros @ helpful macros
.macro setstatchanger stat:req, stages:req, down:req .macro setstatchanger stat:req, stages:req, down:req
setbyte sSTATCHANGER, \stat | \stages << 3 | \down << 7 setbyte sSTATCHANGER, \stat | \stages << 3 | \down << 7

View File

@ -2526,26 +2526,8 @@ BattleScript_EffectPsychicTerrain:
playanimation BS_ATTACKER, B_ANIM_RESTORE_BG playanimation BS_ATTACKER, B_ANIM_RESTORE_BG
call BattleScript_ActivateTerrainAbilities call BattleScript_ActivateTerrainAbilities
call BattleScript_TerrainSeedLoop call BattleScript_TerrainSeedLoop
call BattleScript_TryToApplyMimicry
goto BattleScript_MoveEnd 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: BattleScript_EffectTopsyTurvy:
attackcanceler attackcanceler
attackstring attackstring

View File

@ -192,6 +192,7 @@ struct SpecialStatus
u8 dancerUsedMove:1; u8 dancerUsedMove:1;
u8 dancerOriginalTarget:3; u8 dancerOriginalTarget:3;
// End of byte // End of byte
u8 terrainAbilityDone:1;
}; };
struct SideTimer struct SideTimer

View File

@ -216,46 +216,44 @@
#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125 #define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125
#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126 #define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126
#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127 #define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127
#define VARIOUS_TRY_TO_APPLY_MIMICRY 128 #define VARIOUS_PHOTON_GEYSER_CHECK 128
#define VARIOUS_PHOTON_GEYSER_CHECK 129 #define VARIOUS_SHELL_SIDE_ARM_CHECK 129
#define VARIOUS_SHELL_SIDE_ARM_CHECK 130 #define VARIOUS_TRY_NO_RETREAT 130
#define VARIOUS_TRY_NO_RETREAT 131 #define VARIOUS_TRY_TAR_SHOT 131
#define VARIOUS_TRY_TAR_SHOT 132 #define VARIOUS_CAN_TAR_SHOT_WORK 132
#define VARIOUS_CAN_TAR_SHOT_WORK 133 #define VARIOUS_CHECK_POLTERGEIST 133
#define VARIOUS_CHECK_POLTERGEIST 134 #define VARIOUS_SET_OCTOLOCK 134
#define VARIOUS_SET_OCTOLOCK 135 #define VARIOUS_CUT_1_3_HP_RAISE_STATS 135
#define VARIOUS_CUT_1_3_HP_RAISE_STATS 136 #define VARIOUS_TRY_END_NEUTRALIZING_GAS 136
#define VARIOUS_TRY_END_NEUTRALIZING_GAS 137 #define VARIOUS_JUMP_IF_UNDER_200 137
#define VARIOUS_JUMP_IF_UNDER_200 138 #define VARIOUS_SET_SKY_DROP 138
#define VARIOUS_SET_SKY_DROP 139 #define VARIOUS_CLEAR_SKY_DROP 139
#define VARIOUS_CLEAR_SKY_DROP 140 #define VARIOUS_SKY_DROP_YAWN 140
#define VARIOUS_SKY_DROP_YAWN 141 #define VARIOUS_JUMP_IF_CANT_FLING 141
#define VARIOUS_JUMP_IF_CANT_FLING 142 #define VARIOUS_JUMP_IF_HOLD_EFFECT 142
#define VARIOUS_JUMP_IF_HOLD_EFFECT 143 #define VARIOUS_CURE_CERTAIN_STATUSES 143
#define VARIOUS_CURE_CERTAIN_STATUSES 144 #define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 144
#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 145 #define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 145
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 146 #define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 146
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 147 #define VARIOUS_SAVE_BATTLER_ITEM 147
#define VARIOUS_SAVE_BATTLER_ITEM 148 #define VARIOUS_RESTORE_BATTLER_ITEM 148
#define VARIOUS_RESTORE_BATTLER_ITEM 149 #define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 149
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 150 #define VARIOUS_SET_BEAK_BLAST 150
#define VARIOUS_SET_BEAK_BLAST 151 #define VARIOUS_SWAP_SIDE_STATUSES 151
#define VARIOUS_SWAP_SIDE_STATUSES 152 #define VARIOUS_SET_Z_EFFECT 152
#define VARIOUS_SET_Z_EFFECT 153 #define VARIOUS_TRY_SYMBIOSIS 153
#define VARIOUS_TRY_SYMBIOSIS 154 #define VARIOUS_CAN_TELEPORT 154
#define VARIOUS_CAN_TELEPORT 155 #define VARIOUS_GET_BATTLER_SIDE 155
#define VARIOUS_GET_BATTLER_SIDE 156 #define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 156
#define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 157 #define VARIOUS_SWAP_STATS 157
#define VARIOUS_SWAP_STATS 158 #define VARIOUS_JUMP_IF_ROD 158
#define VARIOUS_JUMP_IF_ROD 159 #define VARIOUS_JUMP_IF_ABSORB 159
#define VARIOUS_JUMP_IF_ABSORB 160 #define VARIOUS_JUMP_IF_MOTOR 160
#define VARIOUS_JUMP_IF_MOTOR 161 #define VARIOUS_TEATIME_INVUL 161
#define VARIOUS_TEATIME_INVUL 162 #define VARIOUS_TEATIME_TARGETS 162
#define VARIOUS_TEATIME_TARGETS 163 #define VARIOUS_TRY_WIND_RIDER_POWER 163
#define VARIOUS_TRY_WIND_RIDER_POWER 164 #define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 164
#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 165 #define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 165
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 166
#define VARIOUS_APPLY_MIMICRY 167
// Cmd_manipulatedamage // Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0 #define DMG_CHANGE_SIGN 0

View File

@ -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_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_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_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_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_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!"); 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_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_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_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_SunlightActivatedAbility[] = _("The harsh sunlight activated\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ABILITY}!");
static const u8 sText_StatWasHeightened[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1} was heightened!"); 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_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}!"); 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_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!"); static const u8 sText_AttackerGainedStrengthFromTheFallen[] = _("{B_ATK_NAME_WITH_PREFIX} gained strength\nfrom the fallen!");

View File

@ -6785,6 +6785,7 @@ static void Cmd_switchineffects(void)
gDisableStructs[gActiveBattler].truantSwitchInHack = 0; gDisableStructs[gActiveBattler].truantSwitchInHack = 0;
if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0) if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0)
|| (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY && AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, gActiveBattler, 0, 0, 0))
|| ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, gActiveBattler, FALSE) || ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, gActiveBattler, FALSE)
|| AbilityBattleEffects(ABILITYEFFECT_TRACE2, 0, 0, 0, 0) || AbilityBattleEffects(ABILITYEFFECT_TRACE2, 0, 0, 0, 0)
|| AbilityBattleEffects(ABILITYEFFECT_WEATHER_FORM, 0, 0, 0, 0)) || AbilityBattleEffects(ABILITYEFFECT_WEATHER_FORM, 0, 0, 0, 0))
@ -10209,9 +10210,6 @@ static void Cmd_various(void)
gBattlescriptCurrInstr += 3; gBattlescriptCurrInstr += 3;
AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, gActiveBattler, 0, 0, 0); AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, gActiveBattler, 0, 0, 0);
return; return;
case VARIOUS_APPLY_MIMICRY:
ChangeTypeBasedOnTerrain(gActiveBattler);
break;
} // End of switch (gBattlescriptCurrInstr[2]) } // End of switch (gBattlescriptCurrInstr[2])
gBattlescriptCurrInstr += 3; gBattlescriptCurrInstr += 3;

View File

@ -4297,28 +4297,24 @@ static u8 ForewarnChooseMove(u32 battler)
void ChangeTypeBasedOnTerrain(u8 battlerId) void ChangeTypeBasedOnTerrain(u8 battlerId)
{ {
u16 moveType, move; u8 battlerType;
u16 terrainFlags = VarGet(VAR_TERRAIN) & STATUS_FIELD_TERRAIN_ANY; u16 terrainFlags = VarGet(VAR_TERRAIN) & STATUS_FIELD_TERRAIN_ANY;
if (terrainFlags && gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) if (terrainFlags && gFieldStatuses & STATUS_FIELD_TERRAIN_ANY)
gFieldStatuses = terrainFlags | STATUS_FIELD_TERRAIN_PERMANENT; // terrain is permanent gFieldStatuses = terrainFlags | STATUS_FIELD_TERRAIN_PERMANENT; // terrain is permanent
GET_MOVE_TYPE(move, moveType);
{
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)
moveType = TYPE_ELECTRIC; battlerType = TYPE_ELECTRIC;
else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN)
moveType = TYPE_GRASS; battlerType = TYPE_GRASS;
else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)
moveType = TYPE_FAIRY; battlerType = TYPE_FAIRY;
else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN)
moveType = TYPE_PSYCHIC; battlerType = TYPE_PSYCHIC;
else // failsafe else // failsafe
moveType = gSpeciesInfo[battlerId].type1; battlerType = gSpeciesInfo[battlerId].type1;
} SET_BATTLER_TYPE(battlerId, battlerType);
SET_BATTLER_TYPE(battlerId, moveType); PREPARE_TYPE_BUFFER(gBattleTextBuff1, battlerType);
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, battlerId, gBattlerPartyIndexes[battlerId])
PREPARE_TYPE_BUFFER(gBattleTextBuff2, moveType);
} }
u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 moveArg) 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++; effect++;
} }
break; 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: case ABILITY_PROTOSYNTHESIS:
if (!gSpecialStatuses[battler].switchInAbilityDone && gBattleWeather & B_WEATHER_SUN) 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++; effect++;
} }
break; 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: case ABILITY_VESSEL_OF_RUIN:
if (!gSpecialStatuses[battler].switchInAbilityDone) if (!gSpecialStatuses[battler].switchInAbilityDone)
{ {
@ -6197,7 +6175,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
} }
break; break;
case ABILITYEFFECT_ON_WEATHER: // For ability effects that activate when the battle weather changes. 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)) switch (GetBattlerAbility(battler))
{ {
case ABILITY_FORECAST: case ABILITY_FORECAST:
@ -6224,12 +6202,22 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
} }
break; break;
case ABILITYEFFECT_ON_TERRAIN: // For ability effects that activate when the field terrain changes. 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)) switch (GetBattlerAbility(battler))
{ {
case ABILITY_QUARK_DRIVE: case ABILITY_MIMICRY:
if (IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN)) 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)); PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler));
BattleScriptPushCursorAndCallback(BattleScript_QuarkDriveActivates); BattleScriptPushCursorAndCallback(BattleScript_QuarkDriveActivates);
effect++; effect++;