Fixes Quash (#4419)

* Fixes Quash

* Update test/battle/move_effect/quash.c

Co-authored-by: Bassoonian <iasperbassoonian@gmail.com>

* Update test/battle/move_effect/quash.c

Co-authored-by: Bassoonian <iasperbassoonian@gmail.com>

---------

Co-authored-by: Bassoonian <iasperbassoonian@gmail.com>
This commit is contained in:
Alex 2024-04-21 15:40:35 +02:00 committed by GitHub
parent 620c453fbd
commit 81a73deb76
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 189 additions and 126 deletions

View File

@ -1636,6 +1636,11 @@
callnative BS_TryGulpMissile
.endm
.macro tryquash failInstr:req
callnative BS_TryQuash
.4byte \failInstr
.endm
@ various command changed to more readable macros
.macro cancelmultiturnmoves battler:req
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES
@ -1827,11 +1832,6 @@
various \battler, VARIOUS_SET_LAST_USED_ABILITY
.endm
.macro tryquash failInstr:req
various BS_ATTACKER, VARIOUS_TRY_QUASH
.4byte \failInstr
.endm
.macro tryafteryou failInstr:req
various BS_ATTACKER, VARIOUS_AFTER_YOU
.4byte \failInstr

View File

@ -131,113 +131,112 @@
#define VARIOUS_SET_SIMPLE_BEAM 39
#define VARIOUS_TRY_ENTRAINMENT 40
#define VARIOUS_SET_LAST_USED_ABILITY 41
#define VARIOUS_TRY_QUASH 42
#define VARIOUS_INVERT_STAT_STAGES 43
#define VARIOUS_TRY_ME_FIRST 44
#define VARIOUS_JUMP_IF_BATTLE_END 45
#define VARIOUS_TRY_ELECTRIFY 46
#define VARIOUS_TRY_REFLECT_TYPE 47
#define VARIOUS_TRY_SOAK 48
#define VARIOUS_HANDLE_MEGA_EVO 49
#define VARIOUS_TRY_LAST_RESORT 50
#define VARIOUS_SET_ARG_TO_BATTLE_DAMAGE 51
#define VARIOUS_TRY_HIT_SWITCH_TARGET 52
#define VARIOUS_TRY_AUTOTOMIZE 53
#define VARIOUS_ABILITY_POPUP 54
#define VARIOUS_JUMP_IF_TARGET_ALLY 55
#define VARIOUS_TRY_SYNCHRONOISE 56
#define VARIOUS_PSYCHO_SHIFT 57
#define VARIOUS_CURE_STATUS 58
#define VARIOUS_POWER_TRICK 59
#define VARIOUS_AFTER_YOU 60
#define VARIOUS_BESTOW 61
#define VARIOUS_JUMP_IF_NOT_GROUNDED 62
#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 63
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF 64
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 65
#define VARIOUS_SET_AURORA_VEIL 66
#define VARIOUS_TRY_THIRD_TYPE 67
#define VARIOUS_ACUPRESSURE 68
#define VARIOUS_SET_POWDER 69
#define VARIOUS_SPECTRAL_THIEF 70
#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 71
#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 72
#define VARIOUS_JUMP_IF_ROAR_FAILS 73
#define VARIOUS_TRY_INSTRUCT 74
#define VARIOUS_JUMP_IF_NOT_BERRY 75
#define VARIOUS_TRACE_ABILITY 76
#define VARIOUS_UPDATE_NICK 77
#define VARIOUS_TRY_ILLUSION_OFF 78
#define VARIOUS_SET_SPRITEIGNORE0HP 79
#define VARIOUS_HANDLE_FORM_CHANGE 80
#define VARIOUS_GET_STAT_VALUE 81
#define VARIOUS_JUMP_IF_FULL_HP 82
#define VARIOUS_LOSE_TYPE 83
#define VARIOUS_TRY_ACTIVATE_SOULHEART 84
#define VARIOUS_TRY_ACTIVATE_RECEIVER 85
#define VARIOUS_TRY_ACTIVATE_BEAST_BOOST 86
#define VARIOUS_TRY_FRISK 87
#define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 88
#define VARIOUS_TRY_FAIRY_LOCK 89
#define VARIOUS_JUMP_IF_NO_ALLY 90
#define VARIOUS_POISON_TYPE_IMMUNITY 91
#define VARIOUS_JUMP_IF_HOLD_EFFECT 92
#define VARIOUS_INFATUATE_WITH_BATTLER 93
#define VARIOUS_SET_LAST_USED_ITEM 94
#define VARIOUS_PARALYZE_TYPE_IMMUNITY 95
#define VARIOUS_JUMP_IF_ABSENT 96
#define VARIOUS_DESTROY_ABILITY_POPUP 97
#define VARIOUS_TOTEM_BOOST 98
#define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 99
#define VARIOUS_MOVEEND_ITEM_EFFECTS 100
#define VARIOUS_TERRAIN_SEED 101
#define VARIOUS_MAKE_INVISIBLE 102
#define VARIOUS_ROOM_SERVICE 103
#define VARIOUS_EERIE_SPELL_PP_REDUCE 104
#define VARIOUS_JUMP_IF_TEAM_HEALTHY 105
#define VARIOUS_TRY_HEAL_QUARTER_HP 106
#define VARIOUS_REMOVE_TERRAIN 107
#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 108
#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 109
#define VARIOUS_GET_ROTOTILLER_TARGETS 110
#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 111
#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 112
#define VARIOUS_CONSUME_BERRY 113
#define VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL 114
#define VARIOUS_JUMP_IF_SPECIES 115
#define VARIOUS_UPDATE_ABILITY_POPUP 116
#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 117
#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 118
#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 119
#define VARIOUS_SHELL_SIDE_ARM_CHECK 120
#define VARIOUS_TRY_NO_RETREAT 121
#define VARIOUS_TRY_TAR_SHOT 122
#define VARIOUS_CAN_TAR_SHOT_WORK 123
#define VARIOUS_CHECK_POLTERGEIST 124
#define VARIOUS_CUT_1_3_HP_RAISE_STATS 125
#define VARIOUS_TRY_END_NEUTRALIZING_GAS 126
#define VARIOUS_JUMP_IF_UNDER_200 127
#define VARIOUS_SET_SKY_DROP 128
#define VARIOUS_CLEAR_SKY_DROP 129
#define VARIOUS_SKY_DROP_YAWN 130
#define VARIOUS_CURE_CERTAIN_STATUSES 131
#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 132
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 133
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 134
#define VARIOUS_SAVE_BATTLER_ITEM 135
#define VARIOUS_RESTORE_BATTLER_ITEM 136
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 137
#define VARIOUS_SET_BEAK_BLAST 138
#define VARIOUS_SWAP_SIDE_STATUSES 139
#define VARIOUS_SWAP_STATS 140
#define VARIOUS_TEATIME_INVUL 141
#define VARIOUS_TEATIME_TARGETS 142
#define VARIOUS_TRY_WIND_RIDER_POWER 143
#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 144
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 145
#define VARIOUS_STORE_HEALING_WISH 146
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 147
#define VARIOUS_TRY_REVIVAL_BLESSING 148
#define VARIOUS_INVERT_STAT_STAGES 42
#define VARIOUS_TRY_ME_FIRST 43
#define VARIOUS_JUMP_IF_BATTLE_END 44
#define VARIOUS_TRY_ELECTRIFY 45
#define VARIOUS_TRY_REFLECT_TYPE 46
#define VARIOUS_TRY_SOAK 47
#define VARIOUS_HANDLE_MEGA_EVO 48
#define VARIOUS_TRY_LAST_RESORT 49
#define VARIOUS_SET_ARG_TO_BATTLE_DAMAGE 50
#define VARIOUS_TRY_HIT_SWITCH_TARGET 51
#define VARIOUS_TRY_AUTOTOMIZE 52
#define VARIOUS_ABILITY_POPUP 53
#define VARIOUS_JUMP_IF_TARGET_ALLY 54
#define VARIOUS_TRY_SYNCHRONOISE 55
#define VARIOUS_PSYCHO_SHIFT 56
#define VARIOUS_CURE_STATUS 57
#define VARIOUS_POWER_TRICK 58
#define VARIOUS_AFTER_YOU 59
#define VARIOUS_BESTOW 60
#define VARIOUS_JUMP_IF_NOT_GROUNDED 61
#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 62
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF 63
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 64
#define VARIOUS_SET_AURORA_VEIL 65
#define VARIOUS_TRY_THIRD_TYPE 66
#define VARIOUS_ACUPRESSURE 67
#define VARIOUS_SET_POWDER 68
#define VARIOUS_SPECTRAL_THIEF 69
#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 70
#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 71
#define VARIOUS_JUMP_IF_ROAR_FAILS 72
#define VARIOUS_TRY_INSTRUCT 73
#define VARIOUS_JUMP_IF_NOT_BERRY 74
#define VARIOUS_TRACE_ABILITY 75
#define VARIOUS_UPDATE_NICK 76
#define VARIOUS_TRY_ILLUSION_OFF 77
#define VARIOUS_SET_SPRITEIGNORE0HP 78
#define VARIOUS_HANDLE_FORM_CHANGE 79
#define VARIOUS_GET_STAT_VALUE 80
#define VARIOUS_JUMP_IF_FULL_HP 81
#define VARIOUS_LOSE_TYPE 82
#define VARIOUS_TRY_ACTIVATE_SOULHEART 83
#define VARIOUS_TRY_ACTIVATE_RECEIVER 84
#define VARIOUS_TRY_ACTIVATE_BEAST_BOOST 85
#define VARIOUS_TRY_FRISK 86
#define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 87
#define VARIOUS_TRY_FAIRY_LOCK 88
#define VARIOUS_JUMP_IF_NO_ALLY 89
#define VARIOUS_POISON_TYPE_IMMUNITY 90
#define VARIOUS_JUMP_IF_HOLD_EFFECT 91
#define VARIOUS_INFATUATE_WITH_BATTLER 92
#define VARIOUS_SET_LAST_USED_ITEM 93
#define VARIOUS_PARALYZE_TYPE_IMMUNITY 94
#define VARIOUS_JUMP_IF_ABSENT 95
#define VARIOUS_DESTROY_ABILITY_POPUP 96
#define VARIOUS_TOTEM_BOOST 97
#define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 98
#define VARIOUS_MOVEEND_ITEM_EFFECTS 99
#define VARIOUS_TERRAIN_SEED 100
#define VARIOUS_MAKE_INVISIBLE 101
#define VARIOUS_ROOM_SERVICE 102
#define VARIOUS_EERIE_SPELL_PP_REDUCE 103
#define VARIOUS_JUMP_IF_TEAM_HEALTHY 104
#define VARIOUS_TRY_HEAL_QUARTER_HP 105
#define VARIOUS_REMOVE_TERRAIN 106
#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 107
#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 108
#define VARIOUS_GET_ROTOTILLER_TARGETS 109
#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 110
#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 111
#define VARIOUS_CONSUME_BERRY 112
#define VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL 113
#define VARIOUS_JUMP_IF_SPECIES 114
#define VARIOUS_UPDATE_ABILITY_POPUP 115
#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 116
#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 117
#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 118
#define VARIOUS_SHELL_SIDE_ARM_CHECK 119
#define VARIOUS_TRY_NO_RETREAT 120
#define VARIOUS_TRY_TAR_SHOT 121
#define VARIOUS_CAN_TAR_SHOT_WORK 122
#define VARIOUS_CHECK_POLTERGEIST 123
#define VARIOUS_CUT_1_3_HP_RAISE_STATS 124
#define VARIOUS_TRY_END_NEUTRALIZING_GAS 125
#define VARIOUS_JUMP_IF_UNDER_200 126
#define VARIOUS_SET_SKY_DROP 127
#define VARIOUS_CLEAR_SKY_DROP 128
#define VARIOUS_SKY_DROP_YAWN 129
#define VARIOUS_CURE_CERTAIN_STATUSES 130
#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 131
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 132
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 133
#define VARIOUS_SAVE_BATTLER_ITEM 134
#define VARIOUS_RESTORE_BATTLER_ITEM 135
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 136
#define VARIOUS_SET_BEAK_BLAST 137
#define VARIOUS_SWAP_SIDE_STATUSES 138
#define VARIOUS_SWAP_STATS 139
#define VARIOUS_TEATIME_INVUL 140
#define VARIOUS_TEATIME_TARGETS 141
#define VARIOUS_TRY_WIND_RIDER_POWER 142
#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 143
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 144
#define VARIOUS_STORE_HEALING_WISH 145
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 146
#define VARIOUS_TRY_REVIVAL_BLESSING 147
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

View File

@ -9585,20 +9585,6 @@ static void Cmd_various(void)
gLastUsedAbility = gBattleMons[battler].ability;
break;
}
case VARIOUS_TRY_QUASH:
{
VARIOUS_ARGS(const u8 *failInstr);
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) // It's true if foe is faster, has a bigger priority, or switches
{
gBattlescriptCurrInstr = cmd->failInstr; // This replaces the current battlescript with the "fail" script.
}
else // If the condition is not true, it means we are faster than the foe, so we can set the quash bit
{
gProtectStructs[gBattlerTarget].quash = TRUE;
gBattlescriptCurrInstr = cmd->nextInstr; // and then we proceed with the rest of our battlescript
}
return;
}
case VARIOUS_INVERT_STAT_STAGES:
{
VARIOUS_ARGS();
@ -16839,3 +16825,36 @@ void BS_TryGulpMissile(void)
else
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_TryQuash(void)
{
NATIVE_ARGS(const u8 *failInstr);
u32 i;
// It's true if foe is faster, has a bigger priority, or switches
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
{
gBattlescriptCurrInstr = cmd->failInstr;
return;
}
// 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++)
{
gBattlerByTurnOrder[i] = i;
}
for (i = 0; i < gBattlersCount - 1; i++)
{
s32 j;
for (j = i + 1; j < gBattlersCount; j++)
{
if (!gProtectStructs[i].quash
&& !gProtectStructs[j].quash
&& GetWhichBattlerFaster(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], FALSE) == -1)
SwapTurnOrder(i, j);
}
}
gBattlescriptCurrInstr = cmd->nextInstr;
}

View File

@ -0,0 +1,45 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(gMovesInfo[MOVE_QUASH].effect == EFFECT_QUASH);
}
DOUBLE_BATTLE_TEST("Quash-affected target will move last in the priority bracket")
{
GIVEN {
PLAYER(SPECIES_VOLBEAT) { Speed(10); Ability(ABILITY_PRANKSTER); }
PLAYER(SPECIES_WOBBUFFET) { Speed(30); }
OPPONENT(SPECIES_TORCHIC) { Speed(20); }
OPPONENT(SPECIES_TREECKO) { Speed(40); }
} WHEN {
TURN { MOVE(playerLeft, MOVE_QUASH, target: opponentRight); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUASH, playerLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
}
}
DOUBLE_BATTLE_TEST("Quash is not affected by dynamic speed")
{
GIVEN {
ASSUME(B_RECALC_TURN_AFTER_ACTIONS >= GEN_8);
ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND);
PLAYER(SPECIES_VOLBEAT) { Speed(10); Ability(ABILITY_PRANKSTER); }
PLAYER(SPECIES_WOBBUFFET) { Speed(30); }
OPPONENT(SPECIES_TORCHIC) { Speed(50); }
OPPONENT(SPECIES_TREECKO) { Speed(40); }
} WHEN {
TURN { MOVE(playerLeft, MOVE_QUASH, target: opponentRight);
MOVE(opponentLeft, MOVE_TAILWIND);
}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUASH, playerLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_TAILWIND, opponentLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
}
}