Implemented Mimicry

Thanks to AsparagusEduardo for helping me optimize RestoreBattlerOriginalTypes.
This commit is contained in:
LOuroboros 2021-10-30 20:40:05 -03:00
parent 4c9f48e9d8
commit 69b42de0d9
9 changed files with 114 additions and 2 deletions

View File

@ -1874,6 +1874,11 @@
.4byte \ptr
.endm
.macro trytoapplymimicry battler:req, ptr:req
various \battler, VARIOUS_TRY_TO_APPLY_MIMICRY
.4byte \ptr
.endm
@ helpful macros
.macro setstatchanger stat:req, stages:req, down:req
setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7

View File

@ -1908,8 +1908,25 @@ BattleScript_EffectPsychicTerrain:
waitmessage B_WAIT_TIME_LONG
playanimation BS_SCRIPTING, B_ANIM_RESTORE_BG, NULL
call BattleScript_TerrainSeedLoop
jumpifabilitypresent ABILITY_MIMICRY, BattleScript_ApplyMimicry
goto BattleScript_MoveEnd
BattleScript_ApplyMimicry::
savetarget
setbyte gBattlerTarget, 0
BattleScript_MimicryLoopIter:
copybyte sBATTLER, gBattlerTarget
trytoapplymimicry BS_TARGET, BattleScript_MimicryLoop_NextBattler
copybyte gBattlerAbility, sBATTLER
call BattleScript_AbilityPopUp
printstring STRINGID_BATTLERTYPECHANGEDTO
waitmessage B_WAIT_TIME_LONG
BattleScript_MimicryLoop_NextBattler:
addbyte gBattlerTarget, 0x1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_MimicryLoopIter
restoretarget
end
BattleScript_EffectTopsyTurvy:
attackcanceler
attackstring
@ -7957,6 +7974,12 @@ BattleScript_ColorChangeActivates::
waitmessage B_WAIT_TIME_LONG
return
BattleScript_MimicryActivatesEnd3::
call BattleScript_AbilityPopUp
printstring STRINGID_BATTLERTYPECHANGEDTO
waitmessage B_WAIT_TIME_LONG
end3
BattleScript_ProteanActivates::
call BattleScript_AbilityPopUp
printstring STRINGID_PKMNCHANGEDTYPE

View File

@ -404,5 +404,7 @@ extern const u8 BattleScript_PrimalReversion[];
extern const u8 BattleScript_HyperspaceFuryRemoveProtect[];
extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTactics[];
extern const u8 BattleScript_WanderingSpiritActivates[];
extern const u8 BattleScript_MimicryActivatesEnd3[];
extern const u8 BattleScript_ApplyMimicry[];
#endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -157,6 +157,8 @@ 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 RestoreBattlerOriginalTypes(u8 battlerId);
// ability checks
bool32 IsRolePlayBannedAbilityAtk(u16 ability);

View File

@ -197,6 +197,7 @@
#define VARIOUS_UPDATE_ABILITY_POPUP 124
#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125
#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126
#define VARIOUS_TRY_TO_APPLY_MIMICRY 127
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

View File

@ -599,8 +599,9 @@
#define STRINGID_BROKETHROUGHPROTECTION 596
#define STRINGID_ABILITYALLOWSONLYMOVE 597
#define STRINGID_SWAPPEDABILITIES 598
#define STRINGID_BATTLERTYPECHANGEDTO 599
#define BATTLESTRINGS_COUNT 599
#define BATTLESTRINGS_COUNT 600
// The below IDs are all indexes into battle message tables,
// used to determine which of a set of messages to print.

View File

@ -725,9 +725,11 @@ static const u8 sText_ButHoopaCantUseIt[] = _("But Hoopa can't use it\nthe way i
static const u8 sText_BrokeThroughProtection[] = _("It broke through the\n{B_DEF_NAME_WITH_PREFIX}'s protection!");
static const u8 sText_AbilityAllowsOnlyMove[] = _("{B_ATK_ABILITY} allows the\nuse of only {B_CURRENT_MOVE}!\p");
static const u8 sText_SwappedAbilities[] = _("{B_DEF_NAME_WITH_PREFIX} swapped Abilities\nwith its target!");
static const u8 sText_BattlerTypeChangedTo[] = _("{B_BUFF1}'s type\nchanged to {B_BUFF2}!");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
[STRINGID_BATTLERTYPECHANGEDTO - 12] = sText_BattlerTypeChangedTo,
[STRINGID_SWAPPEDABILITIES - 12] = sText_SwappedAbilities,
[STRINGID_ABILITYALLOWSONLYMOVE - 12] = sText_AbilityAllowsOnlyMove,
[STRINGID_BROKETHROUGHPROTECTION - 12] = sText_BrokeThroughProtection,

View File

@ -54,6 +54,7 @@
#include "constants/rgb.h"
#include "data.h"
#include "constants/party_menu.h"
#include "battle_util.h"
extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern struct Evolution gEvolutionTable[][EVOS_PER_MON];
@ -9004,6 +9005,21 @@ static void Cmd_various(void)
gBattlescriptCurrInstr += 7;
}
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;
}
}
gBattlescriptCurrInstr += 3;

View File

@ -1894,6 +1894,46 @@ u8 GetImprisonedMovesCount(u8 battlerId, u16 move)
return imprisonedMoves;
}
void RestoreBattlerOriginalTypes(u8 battlerId)
{
gBattleMons[battlerId].type1 = gBaseStats[gBattleMons[battlerId].species].type1;
gBattleMons[battlerId].type2 = gBaseStats[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);
}
}
enum
{
ENDTURN_ORDER,
@ -2278,6 +2318,9 @@ u8 DoFieldEndTurnEffects(void)
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.electricTerrainTimer == 0))
{
gFieldStatuses &= ~(STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT);
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
if (GetBattlerAbility(i) == ABILITY_MIMICRY)
RestoreBattlerOriginalTypes(i);
BattleScriptExecute(BattleScript_ElectricTerrainEnds);
effect++;
}
@ -2288,6 +2331,9 @@ u8 DoFieldEndTurnEffects(void)
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.mistyTerrainTimer == 0))
{
gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN);
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
if (GetBattlerAbility(i) == ABILITY_MIMICRY)
RestoreBattlerOriginalTypes(i);
BattleScriptExecute(BattleScript_MistyTerrainEnds);
effect++;
}
@ -2298,8 +2344,12 @@ u8 DoFieldEndTurnEffects(void)
{
if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT)
&& (gFieldTimers.grassyTerrainTimer == 0 || --gFieldTimers.grassyTerrainTimer == 0))
{
gFieldStatuses &= ~(STATUS_FIELD_GRASSY_TERRAIN);
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
if (GetBattlerAbility(i) == ABILITY_MIMICRY)
RestoreBattlerOriginalTypes(i);
}
BattleScriptExecute(BattleScript_GrassyTerrainHeals);
effect++;
}
@ -2310,6 +2360,9 @@ u8 DoFieldEndTurnEffects(void)
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.psychicTerrainTimer == 0))
{
gFieldStatuses &= ~(STATUS_FIELD_PSYCHIC_TERRAIN);
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
if (GetBattlerAbility(i) == ABILITY_MIMICRY)
RestoreBattlerOriginalTypes(i);
BattleScriptExecute(BattleScript_PsychicTerrainEnds);
effect++;
}
@ -4380,6 +4433,13 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
effect++;
}
break;
case ABILITY_MIMICRY:
if (gBattleMons[battler].hp != 0 && gFieldStatuses & STATUS_FIELD_TERRAIN_ANY)
{
TryToApplyMimicry(battler, FALSE);
effect++;
}
break;
}
break;
case ABILITYEFFECT_ENDTURN: // 1