Fix Quash implementation, adds After You and Quash missing configs + tests (#5400)
* Fix Quash + After You and Quash configs * Add tests
This commit is contained in:
parent
ac2b41ae71
commit
76656e85c2
@ -123,6 +123,8 @@
|
||||
#define B_HEAL_BELL_SOUNDPROOF GEN_LATEST // In Gen5, Heal Bell affects all mons with Soundproof. In Gen6-8 it affects inactive mons, but not battlers. In Gen9 it always affects the user.
|
||||
#define B_CHARGE GEN_LATEST // In Gen8-, Charge status is lost regardless of the typing of the next move.
|
||||
#define B_POWDER_RAIN GEN_LATEST // In Gen7+, Powder doesn't damage the user of a Fire type move in heavy rain.
|
||||
#define B_AFTER_YOU_TURN_ORDER GEN_LATEST // In Gen8+, After You doesn't fail if the turn order wouldn't change after use.
|
||||
#define B_QUASH_TURN_ORDER GEN_LATEST // In Gen8+, Quash-affected battlers move according to speed order. Before Gen8, Quash-affected battlers move in the order they were affected by Quash.
|
||||
|
||||
// Ability settings
|
||||
#define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters.
|
||||
|
||||
@ -8929,9 +8929,10 @@ static bool32 ChangeOrderTargetAfterAttacker(void)
|
||||
u8 data[MAX_BATTLERS_COUNT];
|
||||
u8 actionsData[MAX_BATTLERS_COUNT];
|
||||
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)
|
||||
|| GetBattlerTurnOrderNum(gBattlerAttacker) + 1 == GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
return FALSE;
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) + 1 == GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
return B_AFTER_YOU_TURN_ORDER >= GEN_8;
|
||||
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
{
|
||||
@ -8944,8 +8945,6 @@ static bool32 ChangeOrderTargetAfterAttacker(void)
|
||||
gActionsByTurnOrder[1] = actionsData[2];
|
||||
gBattlerByTurnOrder[2] = data[1];
|
||||
gActionsByTurnOrder[2] = actionsData[1];
|
||||
gBattlerByTurnOrder[3] = data[3];
|
||||
gActionsByTurnOrder[3] = actionsData[3];
|
||||
}
|
||||
else if (GetBattlerTurnOrderNum(gBattlerAttacker) == 0 && GetBattlerTurnOrderNum(gBattlerTarget) == 3)
|
||||
{
|
||||
@ -17110,7 +17109,7 @@ void BS_TryActivateGulpMissile(void)
|
||||
void BS_TryQuash(void)
|
||||
{
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
u32 i;
|
||||
u32 i, j;
|
||||
|
||||
// It's true if foe is faster, has a bigger priority, or switches
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
@ -17121,19 +17120,29 @@ void BS_TryQuash(void)
|
||||
|
||||
// If the above condition is not true, it means we are faster than the foe, so we can set the quash bit
|
||||
gProtectStructs[gBattlerTarget].quash = TRUE;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
|
||||
if (B_QUASH_TURN_ORDER < GEN_8)
|
||||
{
|
||||
gBattlerByTurnOrder[i] = i;
|
||||
}
|
||||
for (i = 0; i < gBattlersCount - 1; i++)
|
||||
{
|
||||
s32 j;
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
// Gen 7- config makes target go last so that the order of quash targets is kept for the correct turn order
|
||||
j = GetBattlerTurnOrderNum(gBattlerTarget);
|
||||
for (i = j + 1; i < gBattlersCount; i++)
|
||||
{
|
||||
if (!gProtectStructs[i].quash
|
||||
&& !gProtectStructs[j].quash
|
||||
&& GetWhichBattlerFaster(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], FALSE) == -1)
|
||||
SwapTurnOrder(i, j);
|
||||
SwapTurnOrder(i, j);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Gen 8+ config only alters Turn Order of battlers affected by Quash, dynamic speed should handle the rest
|
||||
for (i = gCurrentTurnActionNumber + 1; i < gBattlersCount - 1; i++)
|
||||
{
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
{
|
||||
u32 battler1 = gBattlerByTurnOrder[i], battler2 = gBattlerByTurnOrder[j];
|
||||
if ((gProtectStructs[battler1].quash || gProtectStructs[battler2].quash)
|
||||
&& GetWhichBattlerFaster(battler1, battler2, FALSE) == -1)
|
||||
SwapTurnOrder(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
||||
@ -52,7 +52,7 @@ DOUBLE_BATTLE_TEST("After You does nothing if the target has already moved")
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("After You calculates correct targets if only one pokemon is left on the opposing side")
|
||||
DOUBLE_BATTLE_TEST("After You calculates correct turn order if only one pokemon is left on the opposing side")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_GRENINJA) { Speed(120); }
|
||||
@ -86,5 +86,48 @@ DOUBLE_BATTLE_TEST("After You calculates correct targets if only one pokemon is
|
||||
}
|
||||
}
|
||||
|
||||
TO_DO_BATTLE_TEST("After You doesn't fail if the turner remains the same after After You (Gen8+)");
|
||||
TO_DO_BATTLE_TEST("After You ignores the effects of Quash");
|
||||
DOUBLE_BATTLE_TEST("After You doesn't fail if the turn order remains the same after After You (Gen8+)")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(B_AFTER_YOU_TURN_ORDER >= GEN_8);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(3); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(playerLeft, MOVE_CELEBRATE);
|
||||
MOVE(playerRight, MOVE_CELEBRATE);
|
||||
MOVE(opponentLeft, MOVE_CELEBRATE);
|
||||
MOVE(opponentRight, MOVE_AFTER_YOU, target: opponentLeft);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_AFTER_YOU, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("After You ignores the effects of Quash")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_QUASH].effect == EFFECT_QUASH);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(3); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(playerLeft, MOVE_QUASH, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_CELEBRATE);
|
||||
MOVE(opponentLeft, MOVE_CELEBRATE);
|
||||
MOVE(opponentRight, MOVE_AFTER_YOU, target: opponentLeft);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUASH, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_AFTER_YOU, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,14 +32,102 @@ DOUBLE_BATTLE_TEST("Quash is not affected by dynamic speed")
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(30); }
|
||||
OPPONENT(SPECIES_TORCHIC) { Speed(50); }
|
||||
OPPONENT(SPECIES_TREECKO) { Speed(40); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_QUASH, target: opponentLeft);
|
||||
MOVE(opponentRight, MOVE_TAILWIND);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUASH, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TAILWIND, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Quash calculates correct turn order if only one pokemon is left on the opposing side")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_GRENINJA) { Speed(120); }
|
||||
PLAYER(SPECIES_REGIROCK) { Speed(100); }
|
||||
OPPONENT(SPECIES_PIDGEOT) { Speed(10); }
|
||||
OPPONENT(SPECIES_DRAGONITE) { Speed(60); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(playerLeft, MOVE_QUASH, target: playerRight);
|
||||
MOVE(playerRight, MOVE_STONE_EDGE, target: opponentLeft);
|
||||
MOVE(opponentRight, MOVE_CELEBRATE);
|
||||
}
|
||||
TURN {
|
||||
MOVE(playerLeft, MOVE_QUASH, target: playerRight);
|
||||
MOVE(playerRight, MOVE_STONE_EDGE, target: opponentRight);
|
||||
MOVE(opponentRight, MOVE_CELEBRATE);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUASH, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STONE_EDGE, playerRight);
|
||||
HP_BAR(opponentLeft);
|
||||
MESSAGE("Foe Pidgeot fainted!");
|
||||
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUASH, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STONE_EDGE, playerRight);
|
||||
HP_BAR(opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Quash-affected targets move from fastest to slowest (Gen 8+) or from first affected battler to last (Gen 7-)")
|
||||
{
|
||||
u32 speedLeft, speedRight;
|
||||
|
||||
PARAMETRIZE { speedLeft = 60; speedRight = 50; }
|
||||
PARAMETRIZE { speedLeft = 50; speedRight = 60; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_VOLBEAT) { Speed(10); Ability(ABILITY_PRANKSTER); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(70); }
|
||||
OPPONENT(SPECIES_TORCHIC) { Speed(speedLeft); }
|
||||
OPPONENT(SPECIES_TREECKO) { Speed(speedRight); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_QUASH, target: opponentRight);
|
||||
MOVE(playerRight, MOVE_QUASH, target: opponentLeft);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUASH, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUASH, playerRight);
|
||||
if (B_QUASH_TURN_ORDER < GEN_8) {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft);
|
||||
}
|
||||
else if (speedLeft > speedRight) {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
|
||||
}
|
||||
else {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Quash-affected mon that acted early via After You is not affected by dynamic speed")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(B_RECALC_TURN_AFTER_ACTIONS >= GEN_8);
|
||||
ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND);
|
||||
ASSUME(gMovesInfo[MOVE_AFTER_YOU].effect == EFFECT_AFTER_YOU);
|
||||
PLAYER(SPECIES_VOLBEAT) { Speed(20); Ability(ABILITY_PRANKSTER); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(30); }
|
||||
OPPONENT(SPECIES_TORCHIC) { Speed(10); }
|
||||
OPPONENT(SPECIES_TREECKO) { Speed(40); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_QUASH, target: opponentLeft);
|
||||
MOVE(opponentRight, MOVE_AFTER_YOU, target: opponentLeft);
|
||||
MOVE(opponentLeft, MOVE_TAILWIND);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUASH, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_AFTER_YOU, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TAILWIND, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight); // this is the relevant part, testing if quash affected battler becomes last to move causing playerRight to not move
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user