Reimplemented Mimicry

This commit is contained in:
LOuroboros 2022-12-08 22:29:07 -03:00
parent 3718f58a0a
commit 0d1f9d9613
8 changed files with 78 additions and 95 deletions

View File

@ -1899,11 +1899,6 @@
various \battler, VARIOUS_TRY_END_NEUTRALIZING_GAS various \battler, VARIOUS_TRY_END_NEUTRALIZING_GAS
.endm .endm
.macro trytoapplymimicry battler:req, ptr:req
various \battler, VARIOUS_TRY_TO_APPLY_MIMICRY
.4byte \ptr
.endm
.macro trynoretreat battler:req, ptr:req .macro trynoretreat battler:req, ptr:req
various \battler, VARIOUS_TRY_NO_RETREAT various \battler, VARIOUS_TRY_NO_RETREAT
.4byte \ptr .4byte \ptr
@ -2000,6 +1995,10 @@
.4byte \ptr .4byte \ptr
.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

@ -2404,24 +2404,25 @@ BattleScript_EffectPsychicTerrain:
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
playanimation BS_ATTACKER, B_ANIM_RESTORE_BG playanimation BS_ATTACKER, B_ANIM_RESTORE_BG
call BattleScript_TerrainSeedLoop call BattleScript_TerrainSeedLoop
jumpifabilitypresent ABILITY_MIMICRY, BattleScript_ApplyMimicry call BattleScript_TryToApplyMimicry
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_ApplyMimicry:: BattleScript_TryToApplyMimicry:
savetarget savetarget
setbyte gBattlerTarget, 0 setbyte gBattlerTarget, 0
BattleScript_MimicryLoopIter: BattleScript_TryToApplyMimicry_Loop:
copybyte sBATTLER, gBattlerTarget jumpifword CMP_NOT_EQUAL, gFieldStatuses, STATUS_FIELD_TERRAIN_ANY, BattleScript_TryToApplyMimicry_Increment
trytoapplymimicry BS_TARGET, BattleScript_MimicryLoop_NextBattler jumpifability BS_TARGET, ABILITY_MIMICRY, BattleScript_TryToApplyMimicry_Effect
copybyte gBattlerAbility, sBATTLER BattleScript_TryToApplyMimicry_Effect:
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp call BattleScript_AbilityPopUp
applymimicry BS_TARGET
printstring STRINGID_BATTLERTYPECHANGEDTO printstring STRINGID_BATTLERTYPECHANGEDTO
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_SHORT
BattleScript_MimicryLoop_NextBattler: BattleScript_TryToApplyMimicry_Increment:
addbyte gBattlerTarget, 0x1 addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_MimicryLoopIter jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_TryToApplyMimicry_Loop
restoretarget return
goto BattleScript_MoveEnd
BattleScript_EffectTopsyTurvy: BattleScript_EffectTopsyTurvy:
attackcanceler attackcanceler
@ -8305,6 +8306,13 @@ BattleScript_AttackWeakenedByStrongWinds::
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
return return
BattleScript_MimicryActivates_End3::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
printstring STRINGID_BATTLERTYPECHANGEDTO
waitmessage B_WAIT_TIME_SHORT
end3
BattleScript_SnowWarningActivates:: BattleScript_SnowWarningActivates::
pause B_WAIT_TIME_SHORT pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp call BattleScript_AbilityPopUp
@ -8590,12 +8598,6 @@ BattleScript_ColorChangeActivates::
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
return return
BattleScript_MimicryActivatesEnd3::
call BattleScript_AbilityPopUp
printstring STRINGID_BATTLERTYPECHANGEDTO
waitmessage B_WAIT_TIME_LONG
end3
BattleScript_ProteanActivates:: BattleScript_ProteanActivates::
pause B_WAIT_TIME_SHORTEST pause B_WAIT_TIME_SHORTEST
call BattleScript_AbilityPopUp call BattleScript_AbilityPopUp

View File

@ -681,6 +681,13 @@ struct BattleStruct
gBattleMons[battlerId].type2 = type; \ gBattleMons[battlerId].type2 = type; \
gBattleMons[battlerId].type3 = TYPE_MYSTERY; \ 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 \ #define IS_BATTLER_PROTECTED(battlerId)(gProtectStructs[battlerId].protected \
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD \ || gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD \

View File

@ -433,6 +433,7 @@ extern const u8 BattleScript_SymbiosisActivates[];
extern const u8 BattleScript_MultiHitPrintStrings[]; extern const u8 BattleScript_MultiHitPrintStrings[];
extern const u8 BattleScript_BurnUpRemoveType[]; extern const u8 BattleScript_BurnUpRemoveType[];
extern const u8 BattleScript_TargetAbilityStatRaiseRet[]; extern const u8 BattleScript_TargetAbilityStatRaiseRet[];
extern const u8 BattleScript_MimicryActivates_End3[];
// zmoves // zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[]; extern const u8 BattleScript_ZMoveActivateDamaging[];

View File

@ -181,9 +181,6 @@ void DoBurmyFormChange(u32 monId);
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget); bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget);
u16 GetUsedHeldItem(u8 battler); u16 GetUsedHeldItem(u8 battler);
bool32 IsBattlerWeatherAffected(u8 battlerId, u32 weatherFlags); 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); u32 GetBattlerMoveTargetType(u8 battlerId, u16 move);
bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move); bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move);
bool8 IsMoveAffectedByParentalBond(u16 move, u8 battlerId); bool8 IsMoveAffectedByParentalBond(u16 move, u8 battlerId);
@ -204,5 +201,6 @@ bool32 CanBeFrozen(u8 battlerId);
bool32 CanBeConfused(u8 battlerId); bool32 CanBeConfused(u8 battlerId);
bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag); bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag);
u32 GetBattlerFriendshipScore(u8 battlerId); u32 GetBattlerFriendshipScore(u8 battlerId);
void ChangeTypeBasedOnTerrain(u8 battlerId);
#endif // GUARD_BATTLE_UTIL_H #endif // GUARD_BATTLE_UTIL_H

View File

@ -246,6 +246,7 @@
#define VARIOUS_CAN_TELEPORT 155 #define VARIOUS_CAN_TELEPORT 155
#define VARIOUS_GET_BATTLER_SIDE 156 #define VARIOUS_GET_BATTLER_SIDE 156
#define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 157 #define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 157
#define VARIOUS_APPLY_MIMICRY 158
// Cmd_manipulatedamage // Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0 #define DMG_CHANGE_SIGN 0

View File

@ -9590,7 +9590,6 @@ static void Cmd_various(void)
break; break;
} }
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain
TryToRevertMimicry(); // restore the types of Pokémon with Mimicry
break; break;
case VARIOUS_JUMP_IF_UNDER_200: 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. // 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 else
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
return; 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: case VARIOUS_JUMP_IF_CANT_FLING:
if (!CanFling(gActiveBattler)) if (!CanFling(gActiveBattler))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
@ -10070,6 +10054,9 @@ static void Cmd_various(void)
return; return;
} }
break; break;
case VARIOUS_APPLY_MIMICRY:
ChangeTypeBasedOnTerrain(gActiveBattler);
break;
} // End of switch (gBattlescriptCurrInstr[2]) } // End of switch (gBattlescriptCurrInstr[2])
gBattlescriptCurrInstr += 3; gBattlescriptCurrInstr += 3;

View File

@ -2073,57 +2073,6 @@ u8 GetImprisonedMovesCount(u8 battlerId, u16 move)
return imprisonedMoves; 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) u32 GetBattlerFriendshipScore(u8 battlerId)
{ {
u8 side = GetBattlerSide(battlerId); u8 side = GetBattlerSide(battlerId);
@ -2143,6 +2092,17 @@ u32 GetBattlerFriendshipScore(u8 battlerId)
return GetMonFriendshipScore(&party[gBattlerPartyIndexes[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 enum
{ {
ENDTURN_ORDER, ENDTURN_ORDER,
@ -4355,6 +4315,32 @@ static u8 ForewarnChooseMove(u32 battler)
Free(data); 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 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 moveArg)
{ {
u8 effect = 0; u8 effect = 0;
@ -4866,9 +4852,11 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
} }
break; break;
case ABILITY_MIMICRY: 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++; effect++;
} }
break; break;