fixed G-Max Wildfire, Max Guard interactions, and reworked changedSpecies

This commit is contained in:
AgustinGDLV 2023-03-26 19:14:33 -07:00
parent aac4ef4d2a
commit aa80e3fd4e
9 changed files with 36 additions and 29 deletions

View file

@ -10496,7 +10496,7 @@ BattleScript_DamageNonTypesLoopIncrement::
jumpifbytenotequal gBattleCommunication, gBattlersCount, BattleScript_DamageNonTypesLoop
BattleScript_DamageNonTypesContinuesEnd::
bicword gHitMarker, HITMARKER_SKIP_DMG_TRACK | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_GRUDGE
return
end2
BattleScript_EffectTryReducePP::
tryspiteppreduce BattleScript_MoveEnd

View file

@ -533,7 +533,6 @@ struct DynamaxData
u16 baseMove[MAX_BATTLERS_COUNT]; // base move of Max Move
u16 lastUsedBaseMove;
u16 levelUpHP;
u16 opponentBaseForm; // changedSpecies isn't used for opposing Pokemon
};
struct StolenItem
@ -660,7 +659,7 @@ struct BattleStruct
bool8 friskedAbility; // If identifies two mons, show the ability pop-up only once.
u8 sameMoveTurns[MAX_BATTLERS_COUNT]; // For Metronome, number of times the same moves has been SUCCESFULLY used.
u16 moveEffect2; // For Knock Off
u16 changedSpecies[PARTY_SIZE]; // For Zygarde or future forms when multiple mons can change into the same pokemon.
u16 changedSpecies[NUM_BATTLE_SIDES][PARTY_SIZE]; // For Zygarde or future forms when multiple mons can change into the same pokemon.
u8 quickClawBattlerId;
struct StolenItem itemStolen[PARTY_SIZE]; // Player's team that had items stolen (two bytes per party member)
u8 blunderPolicy:1; // should blunder policy activate

View file

@ -64,6 +64,7 @@ void PrepareBattlerForDynamax(u16 battlerId);
u16 GetNonDynamaxHP(u16 battlerId);
u16 GetNonDynamaxMaxHP(u16 battlerId);
void UndoDynamax(u16 battlerId);
bool32 IsMoveBlockedByMaxGuard(u16 move);
bool32 IsMoveBlockedByDynamax(u16 move);
bool32 ShouldUseMaxMove(u16 battlerId, u16 baseMove);

View file

@ -243,6 +243,25 @@ void UndoDynamax(u16 battlerId)
TryBattleFormChange(battlerId, FORM_CHANGE_END_BATTLE);
}
// Certain moves are blocked by Max Guard that normally ignore protection.
bool32 IsMoveBlockedByMaxGuard(u16 move)
{
switch (move)
{
case MOVE_BLOCK:
case MOVE_FLOWER_SHIELD:
case MOVE_GEAR_UP:
case MOVE_MAGNETIC_FLUX:
case MOVE_PHANTOM_FORCE:
case MOVE_PSYCH_UP:
case MOVE_SHADOW_FORCE:
case MOVE_TEATIME:
case MOVE_TRANSFORM:
return TRUE;
}
return FALSE;
}
// Weight-based moves (and some other moves in Raids) are blocked by Dynamax.
bool32 IsMoveBlockedByDynamax(u16 move)
{

View file

@ -5265,7 +5265,7 @@ static void HandleEndTurn_FinishBattle(void)
changedForm = TryFormChange(i, B_SIDE_PLAYER, FORM_CHANGE_END_BATTLE);
// Clear original species field
gBattleStruct->changedSpecies[i] = SPECIES_NONE;
gBattleStruct->changedSpecies[B_SIDE_PLAYER][i] = SPECIES_NONE;
#if B_RECALCULATE_STATS >= GEN_5
// Recalculate the stats of every party member before the end

View file

@ -10615,7 +10615,7 @@ static void Cmd_various(void)
{
gBattleStruct->battleBondTransformed[GET_BATTLER_SIDE2(gBattlerAttacker)] |= gBitTable[gBattlerPartyIndexes[gBattlerAttacker]];
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species);
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species;
gBattleStruct->changedSpecies[B_SIDE_PLAYER][gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species;
gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BattleBondActivatesOnMoveEndAttacker;

View file

@ -8268,6 +8268,10 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move)
&& (!gProtectStructs[battlerId].maxGuarded
|| gBattleMoves[move].argument == MAX_EFFECT_BYPASS_PROTECT))
return FALSE;
// Max Guard is silly about the moves it blocks, including Teatime.
if (gProtectStructs[battlerId].maxGuarded && IsMoveBlockedByMaxGuard(move))
return TRUE;
if (move == MOVE_TEATIME)
return FALSE;
@ -8275,7 +8279,8 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move)
// Protective Pads doesn't stop Unseen Fist from bypassing Protect effects, so IsMoveMakingContact() isn't used here.
// This means extra logic is needed to handle Shell Side Arm.
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNSEEN_FIST
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT || (gBattleMoves[move].effect == EFFECT_SHELL_SIDE_ARM && gBattleStruct->swapDamageCategory)))
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT || (gBattleMoves[move].effect == EFFECT_SHELL_SIDE_ARM && gBattleStruct->swapDamageCategory))
&& !gProtectStructs[battlerId].maxGuarded) // Max Guard cannot be bypassed by Unseen Fist
return FALSE;
else if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED))
return FALSE;
@ -10265,13 +10270,9 @@ bool32 TryBattleFormChange(u8 battlerId, u16 method)
targetSpecies = GetFormChangeTargetSpecies(&party[monId], method, 0);
if (targetSpecies != SPECIES_NONE)
{
// Saves the original species on the first form change for the player.
if (side == B_SIDE_PLAYER && gBattleStruct->changedSpecies[monId] == SPECIES_NONE)
gBattleStruct->changedSpecies[monId] = gBattleMons[battlerId].species;
// Saves the original species for Gigantamax forms for the opponent.
if (side == B_SIDE_OPPONENT && gBattleStruct->dynamax.opponentBaseForm == SPECIES_NONE)
gBattleStruct->dynamax.opponentBaseForm = gBattleMons[battlerId].species;
// Saves the original species on the first form change.
if (gBattleStruct->changedSpecies[side][monId] == SPECIES_NONE)
gBattleStruct->changedSpecies[side][monId] = gBattleMons[battlerId].species;
TryToSetBattleFormChangeMoves(&party[monId], method);
SetMonData(&party[monId], MON_DATA_SPECIES, &targetSpecies);
@ -10279,8 +10280,7 @@ bool32 TryBattleFormChange(u8 battlerId, u16 method)
RecalcBattlerStats(battlerId, &party[monId]);
return TRUE;
}
else if (gBattleStruct->changedSpecies[monId] != SPECIES_NONE
|| gBattleStruct->dynamax.opponentBaseForm != SPECIES_NONE)
else if (gBattleStruct->changedSpecies[side][monId] != SPECIES_NONE)
{
bool8 restoreSpecies = FALSE;
@ -10300,10 +10300,7 @@ bool32 TryBattleFormChange(u8 battlerId, u16 method)
{
// Reverts the original species
TryToSetBattleFormChangeMoves(&party[monId], method);
if (side == B_SIDE_PLAYER)
SetMonData(&party[monId], MON_DATA_SPECIES, &gBattleStruct->changedSpecies[monId]);
else
SetMonData(&party[monId], MON_DATA_SPECIES, &gBattleStruct->dynamax.opponentBaseForm);
SetMonData(&party[monId], MON_DATA_SPECIES, &gBattleStruct->changedSpecies[side][monId]);
RecalcBattlerStats(battlerId, &party[monId]);
return TRUE;
}

View file

@ -8720,7 +8720,7 @@ bool32 TryFormChange(u32 monId, u32 side, u16 method)
targetSpecies = GetFormChangeTargetSpecies(&party[monId], method, 0);
if (targetSpecies == SPECIES_NONE && gBattleStruct != NULL)
targetSpecies = gBattleStruct->changedSpecies[monId];
targetSpecies = gBattleStruct->changedSpecies[side][monId];
if (targetSpecies != SPECIES_NONE)
{

View file

@ -1,15 +1,6 @@
#include "global.h"
#include "test_battle.h"
// TODO:
// ==========
// TEST: Max Guard protects against Transform, Block (not Mean Look), Flower Shield, Gear Up, and so on (see Bulba).
// TEST: Imprison doesn't stop Max Moves. (YES!)
// TEST: Max Moves change type as you'd expect with Normalize, Weather Ball, etc. (YES!)
// TEST: You use Struggle while Dynamaxed if out of PP. (YES!)
// Dynamax should not reset Speed Swap, Soak, or anything else from form changing. (NO)
// Max Moves cannot be used against allies. (NO)
// ============= DYNAMAX AND MAX MOVE INTERACTIONS ===================
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax increases HP and max HP by 1.5x")
{