mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-09-08 18:46:12 -05:00
Fix Shell Trap being delayed after a spread move hit (#10682)
Co-authored-by: PhallenTree <168426989+PhallenTree@users.noreply.github.com>
This commit is contained in:
@@ -407,7 +407,7 @@ void SetStartingStatus(enum StartingStatus status);
|
||||
void ResetStartingStatuses(void);
|
||||
bool32 IsUsableWhileAsleepEffect(enum BattleMoveEffects effect);
|
||||
void SetWrapTurns(enum BattlerId battler, enum HoldEffect holdEffect);
|
||||
bool32 ChangeOrderTargetAfterAttacker(void);
|
||||
bool32 ChangeOrderTargetAfterAttacker(enum BattlerId battlerDef);
|
||||
void TryUpdateEvolutionTracker(enum EvolutionConditions evolutionCondition, u32 upAmount, enum Move usedMove);
|
||||
bool32 CanUseMoveConsecutively(enum BattlerId battler);
|
||||
void TryResetConsecutiveUseCounter(enum BattlerId battler);
|
||||
|
||||
@@ -3697,6 +3697,8 @@ static enum MoveEndResult MoveEndAbilityEffectFoesFainted(struct BattleCalcValue
|
||||
|
||||
static enum MoveEndResult MoveEndShellTrap(struct BattleCalcValues *cv)
|
||||
{
|
||||
u32 shellTrapBattlerMask = 0;
|
||||
|
||||
for (enum BattlerId battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
||||
{
|
||||
if (battlerDef == cv->battlerAtk || IsBattlerAlly(battlerDef, cv->battlerAtk))
|
||||
@@ -3709,11 +3711,28 @@ static enum MoveEndResult MoveEndShellTrap(struct BattleCalcValues *cv)
|
||||
&& gProtectStructs[battlerDef].physicalBattlerId == cv->battlerAtk)
|
||||
{
|
||||
gProtectStructs[battlerDef].shellTrap = TRUE;
|
||||
if (IsDoubleBattle()) // Change move order in double battles, so the hit mon with shell trap moves immediately after being hit.
|
||||
ChangeOrderTargetAfterAttacker(); // In what order should 2 targets move that will activate a trap?
|
||||
shellTrapBattlerMask |= 1u << battlerDef;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsDoubleBattle() && shellTrapBattlerMask != 0)
|
||||
{
|
||||
enum BattlerId shellTrapBattlers[MAX_BATTLERS_COUNT];
|
||||
u32 numShellTrapBattlers = 0;
|
||||
|
||||
for (u32 i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
enum BattlerId battler = gBattlersBySpeed[i];
|
||||
|
||||
if (shellTrapBattlerMask & (1u << battler))
|
||||
shellTrapBattlers[numShellTrapBattlers++] = battler;
|
||||
}
|
||||
|
||||
// Each reorder inserts the battler immediately after the attacker, so use reverse turn order to keep faster battlers first.
|
||||
while (numShellTrapBattlers != 0)
|
||||
ChangeOrderTargetAfterAttacker(shellTrapBattlers[--numShellTrapBattlers]);
|
||||
}
|
||||
|
||||
gBattleScripting.moveendState++;
|
||||
return MOVEEND_RESULT_CONTINUE;
|
||||
}
|
||||
@@ -4381,7 +4400,7 @@ static enum MoveEndResult MoveEndPursuitNextAction(struct BattleCalcValues *cv)
|
||||
u32 storedTarget = gBattlerTarget;
|
||||
if (SetTargetToNextPursuiter(gBattlerTarget))
|
||||
{
|
||||
ChangeOrderTargetAfterAttacker();
|
||||
ChangeOrderTargetAfterAttacker(gBattlerTarget);
|
||||
gBattleStruct->moveTarget[gBattlerTarget] = storedTarget;
|
||||
gBattlerTarget = storedTarget;
|
||||
}
|
||||
|
||||
@@ -8468,7 +8468,7 @@ static void Cmd_jumpifnopursuitswitchdmg(void)
|
||||
|
||||
if (SetTargetToNextPursuiter(gBattlerAttacker))
|
||||
{
|
||||
ChangeOrderTargetAfterAttacker();
|
||||
ChangeOrderTargetAfterAttacker(gBattlerTarget);
|
||||
gBattleStruct->battlerState[gBattlerAttacker].pursuitTarget = TRUE;
|
||||
gBattleStruct->pursuitStoredSwitch = gBattleStruct->monToSwitchIntoId[gBattlerAttacker];
|
||||
gSpecialStatuses[gBattlerAttacker].queuedSwitch = NO_QUEUED_SWITCH; // Don't send out replacement before Pursuits
|
||||
@@ -13251,7 +13251,7 @@ void BS_PowerTrick(void)
|
||||
void BS_TryAfterYou(void)
|
||||
{
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
if (ChangeOrderTargetAfterAttacker())
|
||||
if (ChangeOrderTargetAfterAttacker(gBattlerTarget))
|
||||
{
|
||||
gSpecialStatuses[gBattlerTarget].afterYou = 1;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
||||
@@ -10819,13 +10819,13 @@ void SetWrapTurns(enum BattlerId battler, enum HoldEffect holdEffect)
|
||||
}
|
||||
|
||||
// Return True if the order was changed, and false if the order was not changed(for example because the target would move after the attacker anyway).
|
||||
bool32 ChangeOrderTargetAfterAttacker(void)
|
||||
bool32 ChangeOrderTargetAfterAttacker(enum BattlerId battlerDef)
|
||||
{
|
||||
u32 i;
|
||||
u8 data[MAX_BATTLERS_COUNT];
|
||||
u8 actionsData[MAX_BATTLERS_COUNT];
|
||||
u32 attackerTurnOrderNum = GetBattlerTurnOrderNum(gBattlerAttacker);
|
||||
u32 targetTurnOrderNum = GetBattlerTurnOrderNum(gBattlerTarget);
|
||||
u32 targetTurnOrderNum = GetBattlerTurnOrderNum(battlerDef);
|
||||
|
||||
if (attackerTurnOrderNum > targetTurnOrderNum)
|
||||
return FALSE;
|
||||
@@ -10839,14 +10839,14 @@ bool32 ChangeOrderTargetAfterAttacker(void)
|
||||
}
|
||||
if (attackerTurnOrderNum == 0 && targetTurnOrderNum == 2)
|
||||
{
|
||||
gBattlerByTurnOrder[1] = gBattlerTarget;
|
||||
gBattlerByTurnOrder[1] = battlerDef;
|
||||
gActionsByTurnOrder[1] = actionsData[2];
|
||||
gBattlerByTurnOrder[2] = data[1];
|
||||
gActionsByTurnOrder[2] = actionsData[1];
|
||||
}
|
||||
else if (attackerTurnOrderNum == 0 && targetTurnOrderNum == 3)
|
||||
{
|
||||
gBattlerByTurnOrder[1] = gBattlerTarget;
|
||||
gBattlerByTurnOrder[1] = battlerDef;
|
||||
gActionsByTurnOrder[1] = actionsData[3];
|
||||
gBattlerByTurnOrder[2] = data[1];
|
||||
gActionsByTurnOrder[2] = actionsData[1];
|
||||
@@ -10855,7 +10855,7 @@ bool32 ChangeOrderTargetAfterAttacker(void)
|
||||
}
|
||||
else // attackerTurnOrderNum == 1, targetTurnOrderNum == 3
|
||||
{
|
||||
gBattlerByTurnOrder[2] = gBattlerTarget;
|
||||
gBattlerByTurnOrder[2] = battlerDef;
|
||||
gActionsByTurnOrder[2] = actionsData[3];
|
||||
gBattlerByTurnOrder[3] = data[2];
|
||||
gActionsByTurnOrder[3] = actionsData[2];
|
||||
|
||||
@@ -280,14 +280,15 @@ DOUBLE_BATTLE_TEST("Shell Trap does not trigger when hit into Substitute")
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Shell Trap activates on both opposing Targets")
|
||||
DOUBLE_BATTLE_TEST("Shell Trap activates for both opposing targets in speed order")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == TARGET_FOES_AND_ALLY);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
ASSUME(GetMoveCategory(MOVE_EARTHQUAKE) == DAMAGE_CATEGORY_PHYSICAL);
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(1); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(2); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(4); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(3); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(playerLeft, MOVE_SHELL_TRAP);
|
||||
@@ -296,9 +297,30 @@ DOUBLE_BATTLE_TEST("Shell Trap activates on both opposing Targets")
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EARTHQUAKE, opponentLeft);
|
||||
// Order might be incorrect compared to vanilla
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, playerLeft);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Shell Trap activates immediately after its user is hit by a spread move")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == TARGET_FOES_AND_ALLY);
|
||||
ASSUME(GetMoveCategory(MOVE_EARTHQUAKE) == DAMAGE_CATEGORY_PHYSICAL);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(3); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(opponentLeft, MOVE_EARTHQUAKE);
|
||||
MOVE(playerRight, MOVE_SHELL_TRAP);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SHELL_TRAP_SETUP, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EARTHQUAKE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user