From 0d1f9d96136ac32702632eecad2a3d233bf9af48 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Thu, 8 Dec 2022 22:29:07 -0300 Subject: [PATCH] Reimplemented Mimicry --- asm/macros/battle_script.inc | 9 +-- data/battle_scripts_1.s | 38 ++++----- include/battle.h | 7 ++ include/battle_scripts.h | 1 + include/battle_util.h | 4 +- include/constants/battle_script_commands.h | 1 + src/battle_script_commands.c | 19 +---- src/battle_util.c | 94 ++++++++++------------ 8 files changed, 78 insertions(+), 95 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 27c5a86c41..bc688855f8 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1899,11 +1899,6 @@ various \battler, VARIOUS_TRY_END_NEUTRALIZING_GAS .endm - .macro trytoapplymimicry battler:req, ptr:req - various \battler, VARIOUS_TRY_TO_APPLY_MIMICRY - .4byte \ptr - .endm - .macro trynoretreat battler:req, ptr:req various \battler, VARIOUS_TRY_NO_RETREAT .4byte \ptr @@ -2000,6 +1995,10 @@ .4byte \ptr .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 6b80677213..736d0d9145 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -2404,24 +2404,25 @@ BattleScript_EffectPsychicTerrain: waitmessage B_WAIT_TIME_LONG playanimation BS_ATTACKER, B_ANIM_RESTORE_BG call BattleScript_TerrainSeedLoop - jumpifabilitypresent ABILITY_MIMICRY, BattleScript_ApplyMimicry + call BattleScript_TryToApplyMimicry goto BattleScript_MoveEnd -BattleScript_ApplyMimicry:: +BattleScript_TryToApplyMimicry: savetarget setbyte gBattlerTarget, 0 -BattleScript_MimicryLoopIter: - copybyte sBATTLER, gBattlerTarget - trytoapplymimicry BS_TARGET, BattleScript_MimicryLoop_NextBattler - copybyte gBattlerAbility, sBATTLER +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_LONG -BattleScript_MimicryLoop_NextBattler: - addbyte gBattlerTarget, 0x1 - jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_MimicryLoopIter - restoretarget - goto BattleScript_MoveEnd + waitmessage B_WAIT_TIME_SHORT +BattleScript_TryToApplyMimicry_Increment: + addbyte gBattlerTarget, 1 + jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_TryToApplyMimicry_Loop + return BattleScript_EffectTopsyTurvy: attackcanceler @@ -8305,6 +8306,13 @@ BattleScript_AttackWeakenedByStrongWinds:: waitmessage B_WAIT_TIME_LONG return +BattleScript_MimicryActivates_End3:: + pause B_WAIT_TIME_SHORT + call BattleScript_AbilityPopUp + printstring STRINGID_BATTLERTYPECHANGEDTO + waitmessage B_WAIT_TIME_SHORT + end3 + BattleScript_SnowWarningActivates:: pause B_WAIT_TIME_SHORT call BattleScript_AbilityPopUp @@ -8590,12 +8598,6 @@ BattleScript_ColorChangeActivates:: waitmessage B_WAIT_TIME_LONG return -BattleScript_MimicryActivatesEnd3:: - call BattleScript_AbilityPopUp - printstring STRINGID_BATTLERTYPECHANGEDTO - waitmessage B_WAIT_TIME_LONG - end3 - BattleScript_ProteanActivates:: pause B_WAIT_TIME_SHORTEST call BattleScript_AbilityPopUp diff --git a/include/battle.h b/include/battle.h index ebc8be0575..eb31507c91 100644 --- a/include/battle.h +++ b/include/battle.h @@ -681,6 +681,13 @@ struct BattleStruct gBattleMons[battlerId].type2 = type; \ gBattleMons[battlerId].type3 = TYPE_MYSTERY; \ } +#define RESTORE_BATTLER_TYPE(battlerId) \ +{ \ + gBattleMons[battlerId].type1 = gSpeciesInfo[gBattleMons[battlerId].species].type1; \ + gBattleMons[battlerId].type2 = gSpeciesInfo[gBattleMons[battlerId].species].type2; \ + gBattleMons[battlerId].type3 = TYPE_MYSTERY; \ +} + #define IS_BATTLER_PROTECTED(battlerId)(gProtectStructs[battlerId].protected \ || gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD \ diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 23f18e3bed..654d21f00e 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -433,6 +433,7 @@ extern const u8 BattleScript_SymbiosisActivates[]; extern const u8 BattleScript_MultiHitPrintStrings[]; extern const u8 BattleScript_BurnUpRemoveType[]; extern const u8 BattleScript_TargetAbilityStatRaiseRet[]; +extern const u8 BattleScript_MimicryActivates_End3[]; // zmoves extern const u8 BattleScript_ZMoveActivateDamaging[]; diff --git a/include/battle_util.h b/include/battle_util.h index 3f516daba1..b3e1fe1322 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -181,9 +181,6 @@ void DoBurmyFormChange(u32 monId); bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget); u16 GetUsedHeldItem(u8 battler); bool32 IsBattlerWeatherAffected(u8 battlerId, u32 weatherFlags); -void TryToApplyMimicry(u8 battlerId, bool8 various); -void TryToRevertMimicry(void); -void RestoreBattlerOriginalTypes(u8 battlerId); u32 GetBattlerMoveTargetType(u8 battlerId, u16 move); bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move); bool8 IsMoveAffectedByParentalBond(u16 move, u8 battlerId); @@ -204,5 +201,6 @@ bool32 CanBeFrozen(u8 battlerId); bool32 CanBeConfused(u8 battlerId); bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag); u32 GetBattlerFriendshipScore(u8 battlerId); +void ChangeTypeBasedOnTerrain(u8 battlerId); #endif // GUARD_BATTLE_UTIL_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 06a09fc179..91a471162d 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -246,6 +246,7 @@ #define VARIOUS_CAN_TELEPORT 155 #define VARIOUS_GET_BATTLER_SIDE 156 #define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 157 +#define VARIOUS_APPLY_MIMICRY 158 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 09ef738dfe..55e0146e2b 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9590,7 +9590,6 @@ static void Cmd_various(void) break; } gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain - TryToRevertMimicry(); // restore the types of Pokémon with Mimicry break; case VARIOUS_JUMP_IF_UNDER_200: // If the Pokemon is less than 200 kg, or weighing less than 441 lbs, then Sky Drop will work. Otherwise, it will fail. @@ -9939,21 +9938,6 @@ static void Cmd_various(void) else gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); return; - case VARIOUS_TRY_TO_APPLY_MIMICRY: - { - bool8 isMimicryDone = FALSE; - - if (GetBattlerAbility(gActiveBattler) == ABILITY_MIMICRY) - { - TryToApplyMimicry(gActiveBattler, TRUE); - isMimicryDone = TRUE; - } - if (!isMimicryDone) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - else - gBattlescriptCurrInstr += 7; - return; - } case VARIOUS_JUMP_IF_CANT_FLING: if (!CanFling(gActiveBattler)) gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); @@ -10070,6 +10054,9 @@ static void Cmd_various(void) return; } break; + 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 d8ec3f0795..7e7ce212f5 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2073,57 +2073,6 @@ u8 GetImprisonedMovesCount(u8 battlerId, u16 move) return imprisonedMoves; } -void RestoreBattlerOriginalTypes(u8 battlerId) -{ - gBattleMons[battlerId].type1 = gSpeciesInfo[gBattleMons[battlerId].species].type1; - gBattleMons[battlerId].type2 = gSpeciesInfo[gBattleMons[battlerId].species].type2; -} - -void TryToApplyMimicry(u8 battlerId, bool8 various) -{ - u32 moveType, move; - - GET_MOVE_TYPE(move, moveType); - switch (gFieldStatuses) - { - case STATUS_FIELD_ELECTRIC_TERRAIN: - moveType = TYPE_ELECTRIC; - break; - case STATUS_FIELD_MISTY_TERRAIN: - moveType = TYPE_FAIRY; - break; - case STATUS_FIELD_GRASSY_TERRAIN: - moveType = TYPE_GRASS; - break; - case STATUS_FIELD_PSYCHIC_TERRAIN: - moveType = TYPE_PSYCHIC; - break; - default: - moveType = 0; - break; - } - - if (moveType != 0 && !IS_BATTLER_OF_TYPE(battlerId, moveType)) - { - SET_BATTLER_TYPE(battlerId, moveType); - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, battlerId, gBattlerPartyIndexes[battlerId]) - PREPARE_TYPE_BUFFER(gBattleTextBuff2, moveType); - if (!various) - BattleScriptPushCursorAndCallback(BattleScript_MimicryActivatesEnd3); - } -} - -void TryToRevertMimicry(void) -{ - s32 i; - - for (i = 0; i < MAX_BATTLERS_COUNT; i++) - { - if (GetBattlerAbility(i) == ABILITY_MIMICRY) - RestoreBattlerOriginalTypes(i); - } -} - u32 GetBattlerFriendshipScore(u8 battlerId) { u8 side = GetBattlerSide(battlerId); @@ -2143,6 +2092,17 @@ u32 GetBattlerFriendshipScore(u8 battlerId) return GetMonFriendshipScore(&party[gBattlerPartyIndexes[battlerId]]); } +static void TryToRevertMimicry(void) +{ + u8 i; + + for (i = 0; i < gBattlersCount; i++) + { + if (GetBattlerAbility(i) == ABILITY_MIMICRY) + RESTORE_BATTLER_TYPE(i); + } +} + enum { ENDTURN_ORDER, @@ -4355,6 +4315,32 @@ static u8 ForewarnChooseMove(u32 battler) Free(data); } +void ChangeTypeBasedOnTerrain(u8 battlerId) +{ + u16 moveType, move; + 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); +} + u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 moveArg) { u8 effect = 0; @@ -4866,9 +4852,11 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITY_MIMICRY: - if (gBattleMons[battler].hp != 0 && gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) + if (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY && !gSpecialStatuses[battler].switchInAbilityDone) { - TryToApplyMimicry(battler, FALSE); + ChangeTypeBasedOnTerrain(battler); + BattleScriptPushCursorAndCallback(BattleScript_MimicryActivates_End3); + gSpecialStatuses[battler].switchInAbilityDone = TRUE; effect++; } break;