diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 244d23c75..eb5d4c772 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5050,7 +5050,7 @@ BattleScript_EffectBatonPass:: goto BattleScript_MoveEnd BattleScript_EffectRapidSpin:: -.if B_SPEED_BUFFING_RAPID_SPIN == GEN_8 +.if B_SPEED_BUFFING_RAPID_SPIN >= GEN_8 call BattleScript_EffectHit_Ret jumpifhalfword CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveEnd setmoveeffect MOVE_EFFECT_RAPIDSPIN | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN diff --git a/src/battle_interface.c b/src/battle_interface.c index 3256dda8f..64ea370d7 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -1468,11 +1468,10 @@ bool32 IsMegaTriggerSpriteActive(void) void HideMegaTriggerSprite(void) { - if (gBattleStruct->mega.triggerSpriteId != 0xFF) - { - ChangeMegaTriggerSprite(gBattleStruct->mega.triggerSpriteId, 0); - gSprites[gBattleStruct->mega.triggerSpriteId].tHide = TRUE; - } + if (gBattleStruct->mega.triggerSpriteId >= MAX_SPRITES) + return; + ChangeMegaTriggerSprite(gBattleStruct->mega.triggerSpriteId, 0); + gSprites[gBattleStruct->mega.triggerSpriteId].tHide = TRUE; } void HideTriggerSprites(void) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 18c28d709..575bc2aa4 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -13656,7 +13656,7 @@ static void Cmd_jumpifnopursuitswitchdmg(void) && !(gBattleMons[gBattlerTarget].status1 & (STATUS1_SLEEP | STATUS1_FREEZE)) && gBattleMons[gBattlerAttacker].hp && !gDisableStructs[gBattlerTarget].truantCounter - && gChosenMoveByBattler[gBattlerTarget] == MOVE_PURSUIT) + && gBattleMoves[gChosenMoveByBattler[gBattlerTarget]].effect == EFFECT_PURSUIT) { s32 i; @@ -13666,7 +13666,7 @@ static void Cmd_jumpifnopursuitswitchdmg(void) gActionsByTurnOrder[i] = B_ACTION_TRY_FINISH; } - gCurrentMove = MOVE_PURSUIT; + gCurrentMove = gChosenMoveByBattler[gBattlerTarget]; gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerTarget); gBattlescriptCurrInstr = cmd->nextInstr; gBattleScripting.animTurn = 1; @@ -15086,10 +15086,10 @@ static void Cmd_pursuitdoubles(void) if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gAbsentBattlerFlags & gBitTable[gActiveBattler]) && gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_MOVE - && gChosenMoveByBattler[gActiveBattler] == MOVE_PURSUIT) + && gBattleMoves[gChosenMoveByBattler[gActiveBattler]].effect == EFFECT_PURSUIT) { gActionsByTurnOrder[gActiveBattler] = B_ACTION_TRY_FINISH; - gCurrentMove = MOVE_PURSUIT; + gCurrentMove = gChosenMoveByBattler[gActiveBattler]; gBattlescriptCurrInstr = cmd->nextInstr; gBattleScripting.animTurn = 1; gBattleScripting.savedBattler = gBattlerAttacker; diff --git a/src/battle_util.c b/src/battle_util.c index 6f069a95d..b73014a11 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -10142,14 +10142,14 @@ bool32 CanMegaEvolve(u8 battlerId) species = GetMonData(mon, MON_DATA_SPECIES); itemId = GetMonData(mon, MON_DATA_HELD_ITEM); + if (itemId == ITEM_ENIGMA_BERRY_E_READER) + holdEffect = gEnigmaBerries[battlerId].holdEffect; + else + holdEffect = ItemId_GetHoldEffect(itemId); + // Check if there is an entry in the evolution table for regular Mega Evolution. if (GetBattleFormChangeTargetSpecies(battlerId, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM) != SPECIES_NONE) { - if (itemId == ITEM_ENIGMA_BERRY_E_READER) - holdEffect = gEnigmaBerries[battlerId].holdEffect; - else - holdEffect = ItemId_GetHoldEffect(itemId); - // Can Mega Evolve via Mega Stone. if (holdEffect == HOLD_EFFECT_MEGA_STONE) return TRUE; @@ -10157,7 +10157,11 @@ bool32 CanMegaEvolve(u8 battlerId) // Check if there is an entry in the evolution table for Wish Mega Evolution. if (GetBattleFormChangeTargetSpecies(battlerId, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE) != SPECIES_NONE) - return TRUE; + { + // Can't Wish Mega Evolve if holding a Z Crystal. + if (holdEffect != HOLD_EFFECT_Z_CRYSTAL) + return TRUE; + } // No checks passed, the mon CAN'T mega evolve. return FALSE; diff --git a/src/battle_z_move.c b/src/battle_z_move.c index 55cc157be..3983f96b9 100644 --- a/src/battle_z_move.c +++ b/src/battle_z_move.c @@ -159,7 +159,6 @@ void QueueZMove(u8 battlerId, u16 baseMove) bool32 IsViableZMove(u8 battlerId, u16 move) { struct Pokemon *mon; - struct MegaEvolutionData *mega = &(((struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]))->mega); u8 battlerPosition = GetBattlerPosition(battlerId); u8 partnerPosition = GetBattlerPosition(BATTLE_PARTNER(battlerId)); u32 item; @@ -185,15 +184,6 @@ bool32 IsViableZMove(u8 battlerId, u16 move) if ((GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT || (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && GetBattlerPosition(battlerId) == B_POSITION_PLAYER_RIGHT)) && !CheckBagHasItem(ITEM_Z_POWER_RING, 1)) return FALSE; - if (mega->alreadyEvolved[battlerPosition]) - return FALSE; // Trainer has mega evolved - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - if (IsPartnerMonFromSameTrainer(battlerId) && (mega->alreadyEvolved[partnerPosition] || (mega->toEvolve & gBitTable[BATTLE_PARTNER(battlerId)]))) - return FALSE; // Partner has mega evolved or is about to mega evolve - } - if (item == ITEM_ENIGMA_BERRY_E_READER) return FALSE; // HoldEffect = gEnigmaBerries[battlerId].holdEffect; else @@ -350,9 +340,12 @@ bool32 IsZMoveTriggerSpriteActive(void) void HideZMoveTriggerSprite(void) { - struct Sprite *sprite = &gSprites[gBattleStruct->zmove.triggerSpriteId]; - sprite->tHide = TRUE; + struct Sprite *sprite; gBattleStruct->zmove.viable = FALSE; + if (gBattleStruct->zmove.triggerSpriteId >= MAX_SPRITES) + return; + sprite = &gSprites[gBattleStruct->zmove.triggerSpriteId]; + sprite->tHide = TRUE; } static void ShowZMoveTriggerSprite(u8 battlerId) diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index c8c19573f..0902ea1ff 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -9942,7 +9942,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .priority = 0, .split = SPLIT_SPECIAL, .zMoveEffect = Z_EFFECT_NONE, - .soundMove = TRUE, + .sheerForceBoost = TRUE, .thawsUser = TRUE, .metronomeBanned = TRUE, }, diff --git a/src/data/items.h b/src/data/items.h index 802cd325d..5e15b2734 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -6,7 +6,7 @@ #define EVO_HELD_ITEM_FIELD_FUNC ItemUseOutOfBattle_CannotUse #endif -#if I_GEM_BOOST_POWER >= GEN_5 +#if I_GEM_BOOST_POWER >= GEN_6 #define GEM_BOOST_PARAM 30 #else #define GEM_BOOST_PARAM 50 diff --git a/test/ability_fluffy.c b/test/battle/ability/fluffy.c similarity index 100% rename from test/ability_fluffy.c rename to test/battle/ability/fluffy.c diff --git a/test/damage_formula.c b/test/battle/damage_formula.c similarity index 100% rename from test/damage_formula.c rename to test/battle/damage_formula.c diff --git a/test/move_effect_axe_kick.c b/test/battle/move_effect/axe_kick.c similarity index 100% rename from test/move_effect_axe_kick.c rename to test/battle/move_effect/axe_kick.c diff --git a/test/move_effect_collision_course.c b/test/battle/move_effect/collision_course.c similarity index 100% rename from test/move_effect_collision_course.c rename to test/battle/move_effect/collision_course.c diff --git a/test/move_effect_corrosive_gas.c b/test/battle/move_effect/corrosive_gas.c similarity index 100% rename from test/move_effect_corrosive_gas.c rename to test/battle/move_effect/corrosive_gas.c diff --git a/test/move_effect_infernal_parade.c b/test/battle/move_effect/infernal_parade.c similarity index 100% rename from test/move_effect_infernal_parade.c rename to test/battle/move_effect/infernal_parade.c diff --git a/test/move_effect_make_it_rain.c b/test/battle/move_effect/make_it_rain.c similarity index 100% rename from test/move_effect_make_it_rain.c rename to test/battle/move_effect/make_it_rain.c diff --git a/test/move_effect_mortal_spin.c b/test/battle/move_effect/mortal_spin.c similarity index 100% rename from test/move_effect_mortal_spin.c rename to test/battle/move_effect/mortal_spin.c diff --git a/test/move_effect_multi_hit.c b/test/battle/move_effect/multi_hit.c similarity index 100% rename from test/move_effect_multi_hit.c rename to test/battle/move_effect/multi_hit.c diff --git a/test/move_effect_population_bomb.c b/test/battle/move_effect/population_bomb.c similarity index 100% rename from test/move_effect_population_bomb.c rename to test/battle/move_effect/population_bomb.c diff --git a/test/move_effect_spin_out.c b/test/battle/move_effect/spin_out.c similarity index 100% rename from test/move_effect_spin_out.c rename to test/battle/move_effect/spin_out.c diff --git a/test/move_effect_take_heart.c b/test/battle/move_effect/take_heart.c similarity index 100% rename from test/move_effect_take_heart.c rename to test/battle/move_effect/take_heart.c diff --git a/test/move_effect_teatime.c b/test/battle/move_effect/teatime.c similarity index 100% rename from test/move_effect_teatime.c rename to test/battle/move_effect/teatime.c diff --git a/test/move_effect_triple_arrows.c b/test/battle/move_effect/triple_arrows.c similarity index 100% rename from test/move_effect_triple_arrows.c rename to test/battle/move_effect/triple_arrows.c diff --git a/test/battle/move_flags/damages_airborne_double_damage.c b/test/battle/move_flags/damages_airborne_double_damage.c new file mode 100644 index 000000000..5906e3b6b --- /dev/null +++ b/test/battle/move_flags/damages_airborne_double_damage.c @@ -0,0 +1,23 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Being airborne causes the target to take double damage from certain moves", s16 damage) +{ + bool32 useDive; + PARAMETRIZE { useDive = FALSE; } + PARAMETRIZE { useDive = TRUE; } + GIVEN { + ASSUME(gBattleMoves[MOVE_TWISTER].damagesAirborneDoubleDamage); + PLAYER(SPECIES_WOBBUFFET) { Speed(1); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } + } WHEN { + if (useDive) + TURN { MOVE(opponent, MOVE_FLY); MOVE(player, MOVE_TWISTER); } + else + TURN { MOVE(player, MOVE_TWISTER); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage); + } +} diff --git a/test/battle/move_flags/damages_underground.c b/test/battle/move_flags/damages_underground.c new file mode 100644 index 000000000..54af8b829 --- /dev/null +++ b/test/battle/move_flags/damages_underground.c @@ -0,0 +1,23 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Being underground causes the target to take double damage from certain moves", s16 damage) +{ + bool32 useDig; + PARAMETRIZE { useDig = FALSE; } + PARAMETRIZE { useDig = TRUE; } + GIVEN { + ASSUME(gBattleMoves[MOVE_EARTHQUAKE].damagesUnderground); + PLAYER(SPECIES_WOBBUFFET) { Speed(1); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } + } WHEN { + if (useDig) + TURN { MOVE(opponent, MOVE_DIG); MOVE(player, MOVE_EARTHQUAKE); } + else + TURN { MOVE(player, MOVE_EARTHQUAKE); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage); + } +} diff --git a/test/battle/move_flags/damages_underwater.c b/test/battle/move_flags/damages_underwater.c new file mode 100644 index 000000000..e8f45e8de --- /dev/null +++ b/test/battle/move_flags/damages_underwater.c @@ -0,0 +1,23 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Being underwater causes the target to take double damage from certain moves", s16 damage) +{ + bool32 useDive; + PARAMETRIZE { useDive = FALSE; } + PARAMETRIZE { useDive = TRUE; } + GIVEN { + ASSUME(gBattleMoves[MOVE_SURF].damagesUnderwater); + PLAYER(SPECIES_WOBBUFFET) { Speed(1); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } + } WHEN { + if (useDive) + TURN { MOVE(opponent, MOVE_DIVE); MOVE(player, MOVE_SURF); } + else + TURN { MOVE(player, MOVE_SURF); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage); + } +} diff --git a/test/battle/move_flags/minimize_double_damage.c b/test/battle/move_flags/minimize_double_damage.c new file mode 100644 index 000000000..6b631c9a3 --- /dev/null +++ b/test/battle/move_flags/minimize_double_damage.c @@ -0,0 +1,27 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("MinimizeDoubleDamage flag makes moves cause double damage to Minimized targets", s16 damage) +{ + bool32 useMinimize; + PARAMETRIZE { useMinimize = FALSE; } + PARAMETRIZE { useMinimize = TRUE; } + GIVEN { + ASSUME(gBattleMoves[MOVE_MINIMIZE].effect == EFFECT_MINIMIZE); + ASSUME(gBattleMoves[MOVE_STEAMROLLER].minimizeDoubleDamage); + PLAYER(SPECIES_WOBBUFFET) { Speed(1); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } + } WHEN { + if (useMinimize) + TURN { MOVE(opponent, MOVE_MINIMIZE); MOVE(player, MOVE_STEAMROLLER); } + else + TURN { MOVE(player, MOVE_STEAMROLLER); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage); + } +} + +// Remember to add ASSUME(B_MINIMIZE_DMG_ACC >= GEN_6) +TO_DO_BATTLE_TEST("MinimizeDoubleDamage flag allows moves to skip accuracy checks towards Minimized targets") diff --git a/test/status3.c b/test/status3.c deleted file mode 100644 index c8a438451..000000000 --- a/test/status3.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "global.h" -#include "test/battle.h" - -ASSUMPTIONS { - ASSUME(gBattleMoves[MOVE_MINIMIZE].effect == EFFECT_MINIMIZE); - ASSUME(gBattleMoves[MOVE_STEAMROLLER].minimizeDoubleDamage); - ASSUME(gBattleMoves[MOVE_EARTHQUAKE].damagesUnderground); - ASSUME(gBattleMoves[MOVE_SURF].damagesUnderwater); - ASSUME(gBattleMoves[MOVE_TWISTER].damagesAirborneDoubleDamage); -} - -SINGLE_BATTLE_TEST("Minimize causes the target to take double damage from certain moves", s16 damage) -{ - bool32 useMinimize; - PARAMETRIZE { useMinimize = FALSE; } - PARAMETRIZE { useMinimize = TRUE; } - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(1); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } - } WHEN { - if (useMinimize) - TURN { MOVE(opponent, MOVE_MINIMIZE); MOVE(player, MOVE_STEAMROLLER); } - else - TURN { MOVE(player, MOVE_STEAMROLLER); } - } SCENE { - HP_BAR(opponent, captureDamage: &results[i].damage); - } FINALLY { - EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage); - } -} - -SINGLE_BATTLE_TEST("Being underground causes the target to take double damage from certain moves", s16 damage) -{ - bool32 useDig; - PARAMETRIZE { useDig = FALSE; } - PARAMETRIZE { useDig = TRUE; } - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(1); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } - } WHEN { - if (useDig) - TURN { MOVE(opponent, MOVE_DIG); MOVE(player, MOVE_EARTHQUAKE); } - else - TURN { MOVE(player, MOVE_EARTHQUAKE); } - } SCENE { - HP_BAR(opponent, captureDamage: &results[i].damage); - } FINALLY { - EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage); - } -} - -SINGLE_BATTLE_TEST("Being underwater causes the target to take double damage from certain moves", s16 damage) -{ - bool32 useDive; - PARAMETRIZE { useDive = FALSE; } - PARAMETRIZE { useDive = TRUE; } - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(1); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } - } WHEN { - if (useDive) - TURN { MOVE(opponent, MOVE_DIVE); MOVE(player, MOVE_SURF); } - else - TURN { MOVE(player, MOVE_SURF); } - } SCENE { - HP_BAR(opponent, captureDamage: &results[i].damage); - } FINALLY { - EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage); - } -} - -SINGLE_BATTLE_TEST("Being airborne causes the target to take double damage from certain moves", s16 damage) -{ - bool32 useDive; - PARAMETRIZE { useDive = FALSE; } - PARAMETRIZE { useDive = TRUE; } - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(1); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } - } WHEN { - if (useDive) - TURN { MOVE(opponent, MOVE_FLY); MOVE(player, MOVE_TWISTER); } - else - TURN { MOVE(player, MOVE_TWISTER); } - } SCENE { - HP_BAR(opponent, captureDamage: &results[i].damage); - } FINALLY { - EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage); - } -}