From 620c453fbd2c049657c1ea9b15e6278741abcaef Mon Sep 17 00:00:00 2001 From: sneed <56992013+Sneed69@users.noreply.github.com> Date: Sun, 21 Apr 2024 15:10:14 +0300 Subject: [PATCH 01/11] Intimidate and Super Sweet Sugar prints the right message and doesn't play animation when already at -6 (#4406) * Intimidate won't print message or play animation at -6 Super Sweet Syrup included * Update intimidate.c * Update supersweet_syrup.c * Update test/battle/ability/supersweet_syrup.c --------- Co-authored-by: Bassoonian --- data/battle_scripts_1.s | 10 ++++++++++ test/battle/ability/intimidate.c | 26 ++++++++++++++++++++++++++ test/battle/ability/supersweet_syrup.c | 26 ++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 2e22c0df08..b815c04d6d 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -7784,6 +7784,7 @@ BattleScript_IntimidateEffect: statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_IntimidateLoopIncrement setgraphicalstatchangevalues jumpifability BS_TARGET, ABILITY_CONTRARY, BattleScript_IntimidateContrary + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_IntimidateWontDecrease playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 printstring STRINGID_PKMNCUTSATTACKWITH BattleScript_IntimidateEffect_WaitString: @@ -7800,6 +7801,10 @@ BattleScript_IntimidateEnd: pause B_WAIT_TIME_MED end3 +BattleScript_IntimidateWontDecrease: + printstring STRINGID_STATSWONTDECREASE + goto BattleScript_IntimidateEffect_WaitString + BattleScript_IntimidateContrary: call BattleScript_AbilityPopUpTarget jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_IntimidateContrary_WontIncrease @@ -7839,6 +7844,7 @@ BattleScript_SupersweetSyrupEffect: statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_SupersweetSyrupLoopIncrement setgraphicalstatchangevalues jumpifability BS_TARGET, ABILITY_CONTRARY, BattleScript_SupersweetSyrupContrary + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_SupersweetSyrupWontDecrease playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 printfromtable gStatDownStringIds BattleScript_SupersweetSyrupEffect_WaitString: @@ -7855,6 +7861,10 @@ BattleScript_SupersweetSyrupEnd: pause B_WAIT_TIME_MED end3 +BattleScript_SupersweetSyrupWontDecrease: + printstring STRINGID_STATSWONTDECREASE + goto BattleScript_SupersweetSyrupEffect_WaitString + BattleScript_SupersweetSyrupContrary: call BattleScript_AbilityPopUpTarget jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_SupersweetSyrupContrary_WontIncrease diff --git a/test/battle/ability/intimidate.c b/test/battle/ability/intimidate.c index 298e021732..08560ccb00 100644 --- a/test/battle/ability/intimidate.c +++ b/test/battle/ability/intimidate.c @@ -184,3 +184,29 @@ DOUBLE_BATTLE_TEST("Intimidate activates immediately after the mon was switched EXPECT_EQ(playerLeft->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 1); } } + +SINGLE_BATTLE_TEST("Intimidate can not further lower opponents Atk stat if it is at minimum stages") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } + } WHEN { + TURN { MOVE(opponent, MOVE_CHARM); } + TURN { MOVE(opponent, MOVE_CHARM); } + TURN { MOVE(opponent, MOVE_CHARM); } + TURN { SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARM, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARM, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARM, opponent); + ABILITY_POPUP(opponent, ABILITY_INTIMIDATE); + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Foe Arbok's Intimidate cuts Wobbuffet's attack!"); + } + MESSAGE("Wobbuffet's Attack won't go lower!"); + } THEN { + EXPECT_EQ(player->statStages[STAT_ATK], MIN_STAT_STAGE); + } +} diff --git a/test/battle/ability/supersweet_syrup.c b/test/battle/ability/supersweet_syrup.c index 016c621ee5..6a2fd4fd76 100644 --- a/test/battle/ability/supersweet_syrup.c +++ b/test/battle/ability/supersweet_syrup.c @@ -45,3 +45,29 @@ DOUBLE_BATTLE_TEST("Supersweet Syrup lowers evasion of both opposing mon's in ba EXPECT_EQ(playerRight->statStages[STAT_EVASION], DEFAULT_STAT_STAGE - 1); } } + +SINGLE_BATTLE_TEST("Supersweet Syrup can not further lower opponents evasion if it is at minimum stages") +{ + GIVEN { + PLAYER(SPECIES_ODDISH); + OPPONENT(SPECIES_ODDISH); + OPPONENT(SPECIES_HYDRAPPLE) { Ability(ABILITY_SUPERSWEET_SYRUP); } + } WHEN { + TURN { MOVE(opponent, MOVE_SWEET_SCENT); } + TURN { MOVE(opponent, MOVE_SWEET_SCENT); } + TURN { MOVE(opponent, MOVE_SWEET_SCENT); } + TURN { SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SWEET_SCENT, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SWEET_SCENT, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SWEET_SCENT, opponent); + ABILITY_POPUP(opponent, ABILITY_SUPERSWEET_SYRUP); + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Oddish's evasiveness fell!"); + } + MESSAGE("Oddish's evasiveness won't go lower!"); + } THEN { + EXPECT_EQ(player->statStages[STAT_EVASION], MIN_STAT_STAGE); + } +} From 81a73deb767e31756504c1426357faf5a566457c Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Sun, 21 Apr 2024 15:40:35 +0200 Subject: [PATCH 02/11] Fixes Quash (#4419) * Fixes Quash * Update test/battle/move_effect/quash.c Co-authored-by: Bassoonian * Update test/battle/move_effect/quash.c Co-authored-by: Bassoonian --------- Co-authored-by: Bassoonian --- asm/macros/battle_script.inc | 10 +- include/constants/battle_script_commands.h | 213 ++++++++++----------- src/battle_script_commands.c | 47 +++-- test/battle/move_effect/quash.c | 45 +++++ 4 files changed, 189 insertions(+), 126 deletions(-) create mode 100644 test/battle/move_effect/quash.c diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 25e0110a51..260257fc61 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -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 diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 641e644ebc..ef8803ce42 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -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 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d91f1d35d2..28d75cd161 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -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; +} diff --git a/test/battle/move_effect/quash.c b/test/battle/move_effect/quash.c new file mode 100644 index 0000000000..fd2bd9d877 --- /dev/null +++ b/test/battle/move_effect/quash.c @@ -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); + } +} From 9097f438f12340791d706e3fe7d9842d52a6aa22 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Mon, 22 Apr 2024 04:58:17 -0300 Subject: [PATCH 03/11] Fixes Will-O-Wisp's capitalization in gMovesInfo (#4425) --- src/data/moves_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/moves_info.h b/src/data/moves_info.h index 5ae99761ff..6fbe504a77 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -6358,7 +6358,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = [MOVE_WILL_O_WISP] = { - .name = COMPOUND_STRING("Will-o-Wisp"), + .name = COMPOUND_STRING("Will-O-Wisp"), .description = COMPOUND_STRING( "Inflicts a burn on the foe\n" "with intense fire."), From 6bde095ae883cd4ee0d78608839cea22878376c2 Mon Sep 17 00:00:00 2001 From: Bassoonian Date: Mon, 22 Apr 2024 10:20:37 +0200 Subject: [PATCH 04/11] Partner fixes (#4422) * Partner fixes * Generalise TRAINER_PARTNER(PARTNER_NONE) --- include/data.h | 4 ++-- src/battle_tower.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/data.h b/include/data.h index feae0d87b2..652f396c03 100644 --- a/include/data.h +++ b/include/data.h @@ -168,14 +168,14 @@ static inline const u8 GetTrainerClassFromId(u16 trainerId) static inline const u8 *GetTrainerClassNameFromId(u16 trainerId) { if (trainerId > TRAINER_PARTNER(PARTNER_NONE)) - return gTrainerClasses[gBattlePartners[trainerId].trainerClass].name; + return gTrainerClasses[gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerClass].name; return gTrainerClasses[GetTrainerClassFromId(trainerId)].name; } static inline const u8 *GetTrainerNameFromId(u16 trainerId) { if (trainerId > TRAINER_PARTNER(PARTNER_NONE)) - return gBattlePartners[trainerId].trainerName; + return gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName; return gTrainers[SanitizeTrainerId(trainerId)].trainerName; } diff --git a/src/battle_tower.c b/src/battle_tower.c index 477a08742b..cd94e7919b 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -1435,7 +1435,7 @@ u8 GetFrontierOpponentClass(u16 trainerId) } else if (trainerId > TRAINER_PARTNER(PARTNER_NONE)) { - trainerClass = gBattlePartners[GetTrainerClassFromId(trainerId - TRAINER_PARTNER(PARTNER_NONE))].trainerClass; + trainerClass = gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerClass; } else if (trainerId < FRONTIER_TRAINERS_COUNT) { From fa53e97f0c1a5e6117637262416c10d409d05afe Mon Sep 17 00:00:00 2001 From: sneed <56992013+Sneed69@users.noreply.github.com> Date: Mon, 22 Apr 2024 11:42:46 +0300 Subject: [PATCH 05/11] Add thunder cage to trapping move array (#4426) * Add thunder cage to trapping move array * align sTrappingMoves vertically --- src/battle_script_commands.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 28d75cd161..f65ed39037 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -317,7 +317,16 @@ static const s32 sExperienceScalingFactors[] = static const u16 sTrappingMoves[NUM_TRAPPING_MOVES] = { - MOVE_BIND, MOVE_WRAP, MOVE_FIRE_SPIN, MOVE_CLAMP, MOVE_WHIRLPOOL, MOVE_SAND_TOMB, MOVE_MAGMA_STORM, MOVE_INFESTATION, MOVE_SNAP_TRAP, + MOVE_BIND, + MOVE_WRAP, + MOVE_FIRE_SPIN, + MOVE_CLAMP, + MOVE_WHIRLPOOL, + MOVE_SAND_TOMB, + MOVE_MAGMA_STORM, + MOVE_INFESTATION, + MOVE_SNAP_TRAP, + MOVE_THUNDER_CAGE }; static const u16 sBadgeFlags[8] = { From d398b9e8e7f0a4ef851395cd55bccd92b1319ba0 Mon Sep 17 00:00:00 2001 From: kittenchilly Date: Mon, 22 Apr 2024 03:49:53 -0500 Subject: [PATCH 06/11] Fix ABILITY_POPUP not respecting abilityPopupOverwrite in tests (#4423) --- src/battle_interface.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/battle_interface.c b/src/battle_interface.c index d46c95dd3c..59f89ae30c 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -3243,6 +3243,9 @@ void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle) if (B_ABILITY_POP_UP == FALSE) return; + if (gBattleScripting.abilityPopupOverwrite != 0) + ability = gBattleScripting.abilityPopupOverwrite; + if (gTestRunnerEnabled) { TestRunner_Battle_RecordAbilityPopUp(battlerId, ability); @@ -3250,9 +3253,6 @@ void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle) return; } - if (gBattleScripting.abilityPopupOverwrite != 0) - ability = gBattleScripting.abilityPopupOverwrite; - if (!gBattleStruct->activeAbilityPopUps) { LoadSpriteSheet(&sSpriteSheet_AbilityPopUp); From b24714a5973d04ee0fce7457854d82ac93c25c91 Mon Sep 17 00:00:00 2001 From: Martin Griffin Date: Mon, 22 Apr 2024 14:03:55 +0100 Subject: [PATCH 07/11] Fix GiveBoxMonInitialMoveset_Fast --- src/pokemon.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pokemon.c b/src/pokemon.c index 0e145c2e4b..5b1a10a908 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -1689,7 +1689,7 @@ void GiveBoxMonInitialMoveset_Fast(struct BoxPokemon *boxMon) //Credit: Asparagu u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL); s32 level = GetLevelFromBoxMonExp(boxMon); s32 i; - u16 moves[MAX_MON_MOVES] = {0}; + u16 moves[MAX_MON_MOVES] = {MOVE_NONE}; u8 addedMoves = 0; const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species); @@ -1703,13 +1703,15 @@ void GiveBoxMonInitialMoveset_Fast(struct BoxPokemon *boxMon) //Credit: Asparagu if (learnset[i].level == 0) continue; - for (j = 0; j < addedMoves + 1; j++) + for (j = 0; j < addedMoves; j++) + { if (moves[j] == learnset[i].move) { alreadyKnown = TRUE; break; } - + } + if (!alreadyKnown) { if (addedMoves < MAX_MON_MOVES) From dbbe39709573e535cfede92144e8db3387dc3d3b Mon Sep 17 00:00:00 2001 From: Eemeliri Date: Tue, 23 Apr 2024 15:16:32 +0300 Subject: [PATCH 08/11] Fix Lycanroc dusk and midnight form backsprites and adjust back offset (#4430) --- src/data/pokemon/species_info/gen_7_families.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/pokemon/species_info/gen_7_families.h b/src/data/pokemon/species_info/gen_7_families.h index da640ca852..13bba7cd01 100644 --- a/src/data/pokemon/species_info/gen_7_families.h +++ b/src/data/pokemon/species_info/gen_7_families.h @@ -1761,7 +1761,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .frontPicYOffset = 0, .frontAnimFrames = sAnims_LycanrocMidnight, .frontAnimId = ANIM_SHRINK_GROW_VIBRATE_SLOW, - .backPic = gMonBackPic_LycanrocMidday, + .backPic = gMonBackPic_LycanrocMidnight, .backPicSize = MON_COORDS_SIZE(64, 56), .backPicYOffset = 7, .backAnimId = BACK_ANIM_SHRINK_GROW_VIBRATE, @@ -1814,9 +1814,9 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .frontPicYOffset = 6, .frontAnimFrames = sAnims_LycanrocDusk, .frontAnimId = ANIM_V_SHAKE, - .backPic = gMonBackPic_LycanrocMidday, + .backPic = gMonBackPic_LycanrocDusk, .backPicSize = MON_COORDS_SIZE(64, 56), - .backPicYOffset = 5, + .backPicYOffset = 6, .backAnimId = BACK_ANIM_V_SHAKE, .palette = gMonPalette_LycanrocDusk, .shinyPalette = gMonShinyPalette_LycanrocDusk, From edc98d664f5d4ecd604ab9d2347d4abec495a3f6 Mon Sep 17 00:00:00 2001 From: sneed <56992013+Sneed69@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:51:03 +0300 Subject: [PATCH 09/11] pokedex expYield matches SpeciesInfo type (#4432) --- src/pokedex_plus_hgss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pokedex_plus_hgss.c b/src/pokedex_plus_hgss.c index b65f60dc65..debf4d7fe0 100644 --- a/src/pokedex_plus_hgss.c +++ b/src/pokedex_plus_hgss.c @@ -385,7 +385,7 @@ struct PokemonStats u8 eggGroup1; u8 eggGroup2; u8 eggCycles; - u8 expYield; + u16 expYield; u8 friendship; u16 ability0; u16 ability1; From 87dca8eb1cf68e6f05a044b666e51a1ccd35d25d Mon Sep 17 00:00:00 2001 From: Martin Griffin Date: Tue, 23 Apr 2024 20:49:22 +0100 Subject: [PATCH 10/11] Fix typo in Rotom Catalog (#4433) https://discord.com/channels/419213663107416084/774393519569502268/1232372639562072084 --- src/data/items.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/items.h b/src/data/items.h index 3a65f8758c..04e578c3ca 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -10771,7 +10771,7 @@ const struct Item gItemsInfo[] = .importance = 1, .description = COMPOUND_STRING( "A catalog full of\n" - "deviced liked by\n" + "devices liked by\n" "Rotom."), .pocket = POCKET_KEY_ITEMS, .type = ITEM_USE_PARTY_MENU, From 94cb2133c6c2dd92f2e37e7de4d17216fb5cde77 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Thu, 25 Apr 2024 10:13:57 +0200 Subject: [PATCH 11/11] Fixes ability dancer not targeting multiply targets (#4437) * Fixes ability dancer not targeting multiply targets * remove file --- src/battle_util.c | 3 +++ test/battle/ability/dancer.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 65a4d79089..c68959a8ff 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5751,6 +5751,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 // Set the target to the original target of the mon that first used a Dance move gBattlerTarget = gBattleScripting.savedBattler & 0x3; + // Edge case for dance moves that hit multiply targets + gHitMarker &= ~HITMARKER_NO_ATTACKSTRING; + // Make sure that the target isn't an ally - if it is, target the original user if (GetBattlerSide(gBattlerTarget) == GetBattlerSide(gBattlerAttacker)) gBattlerTarget = (gBattleScripting.savedBattler & 0xF0) >> 4; diff --git a/test/battle/ability/dancer.c b/test/battle/ability/dancer.c index 7e520f440b..34af26e75e 100644 --- a/test/battle/ability/dancer.c +++ b/test/battle/ability/dancer.c @@ -36,11 +36,11 @@ SINGLE_BATTLE_TEST("Dancer can copy Teeter Dance") DOUBLE_BATTLE_TEST("Dancer can copy Teeter Dance and confuse both opposing targets") { - KNOWN_FAILING; // Fails because copied move that targets both opposing mons, targets only one when copied by Dancer GIVEN { ASSUME(gMovesInfo[MOVE_TEETER_DANCE].danceMove == TRUE); + ASSUME(gItemsInfo[ITEM_LUM_BERRY].holdEffect == HOLD_EFFECT_CURE_STATUS); PLAYER(SPECIES_WOBBUFFET) - PLAYER(SPECIES_WYNAUT) + PLAYER(SPECIES_WYNAUT) { Item(ITEM_LUM_BERRY); } OPPONENT(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); Item(ITEM_LUM_BERRY); } OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); } } WHEN { @@ -50,6 +50,6 @@ DOUBLE_BATTLE_TEST("Dancer can copy Teeter Dance and confuse both opposing targe ABILITY_POPUP(opponentLeft, ABILITY_DANCER); ANIMATION(ANIM_TYPE_MOVE, MOVE_TEETER_DANCE, opponentLeft); MESSAGE("Wobbuffet became confused!"); - MESSAGE("Wynaut became confusef!"); + MESSAGE("Wynaut became confused!"); } }