From 166a1a4e63b22e16f3e8f76e0921a60ccda865db Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Mon, 25 Dec 2023 18:28:16 +0100 Subject: [PATCH] Adds ability Embody Aspect + minor fix to Hospitality (#3821) * Adds ability Embody Aspect + minor fix to Hospitality * comment out failing tests related to neutralizing gas * fixes neutralizing gas bug * leftover --- data/battle_scripts_1.s | 1 + src/battle_util.c | 37 ++++++++++++++-- test/battle/ability/dauntless_shield.c | 21 ++++++++- test/battle/ability/embody_aspect.c | 59 ++++++++++++++++++++++++++ test/battle/ability/intrepid_sword.c | 21 ++++++++- test/battle/move_effect/hit_escape.c | 1 - 6 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 test/battle/ability/embody_aspect.c diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index fd19ed79cc..09eb969168 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -9259,6 +9259,7 @@ BattleScript_BattlerAbilityStatRaiseOnSwitchIn:: waitanimation printstring STRINGID_BATTLERABILITYRAISEDSTAT waitmessage B_WAIT_TIME_LONG + copybyte gBattlerAttacker, sSAVED_BATTLER end3 BattleScript_ScriptingAbilityStatRaise:: diff --git a/src/battle_util.c b/src/battle_util.c index b720c5c832..da42b40010 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -4314,7 +4314,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 u32 moveType, move; u32 side; u32 i, j; - u32 partner, partnerMaxHP; + u32 partner; struct Pokemon *mon; if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) @@ -4800,6 +4800,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN) && !(gBattleStruct->intrepidSwordBoost[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]])) { + gBattleScripting.savedBattler = gBattlerAttacker; gBattlerAttacker = battler; if (B_INTREPID_SWORD == GEN_9) gBattleStruct->intrepidSwordBoost[GetBattlerSide(battler)] |= gBitTable[gBattlerPartyIndexes[battler]]; @@ -4813,6 +4814,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN) && !(gBattleStruct->dauntlessShieldBoost[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]])) { + gBattleScripting.savedBattler = gBattlerAttacker; gBattlerAttacker = battler; if (B_DAUNTLESS_SHIELD == GEN_9) gBattleStruct->dauntlessShieldBoost[GetBattlerSide(battler)] |= gBitTable[gBattlerPartyIndexes[battler]]; @@ -4925,17 +4927,44 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 break; case ABILITY_HOSPITALITY: partner = BATTLE_PARTNER(battler); - partnerMaxHP = GetNonDynamaxMaxHP(partner); - if (!gSpecialStatuses[battler].switchInAbilityDone && IsDoubleBattle() && gBattleMons[partner].hp < partnerMaxHP) + if (!gSpecialStatuses[battler].switchInAbilityDone && IsDoubleBattle() && gBattleMons[partner].hp < gBattleMons[partner].maxHP) { gBattlerTarget = partner; gSpecialStatuses[battler].switchInAbilityDone = TRUE; - gBattleMoveDamage = (partnerMaxHP / 4) * -1; + gBattleMoveDamage = (GetNonDynamaxMaxHP(partner) / 4) * -1; BattleScriptPushCursorAndCallback(BattleScript_HospitalityActivates); effect++; } break; + case ABILITY_EMBODY_ASPECT_TEAL: + case ABILITY_EMBODY_ASPECT_HEARTHFLAME: + case ABILITY_EMBODY_ASPECT_WELLSPRING: + case ABILITY_EMBODY_ASPECT_CORNERSTONE: + if (!gSpecialStatuses[battler].switchInAbilityDone) + { + u32 stat = STAT_SPATK; + + if (gLastUsedAbility == ABILITY_EMBODY_ASPECT_TEAL) + stat = STAT_SPATK; + else if (gLastUsedAbility == ABILITY_EMBODY_ASPECT_HEARTHFLAME) + stat = STAT_ATK; + else if (gLastUsedAbility == ABILITY_EMBODY_ASPECT_WELLSPRING) + stat = STAT_SPDEF; + else if (gLastUsedAbility == ABILITY_EMBODY_ASPECT_CORNERSTONE) + stat = STAT_DEF; + + if (CompareStat(battler, stat, MAX_STAT_STAGE, CMP_EQUAL)) + break; + + gBattleScripting.savedBattler = gBattlerAttacker; + gBattlerAttacker = battler; + gSpecialStatuses[battler].switchInAbilityDone = TRUE; + SET_STATCHANGER(stat, 1, FALSE); + BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn); + effect++; + } + break; } break; case ABILITYEFFECT_ENDTURN: // 1 diff --git a/test/battle/ability/dauntless_shield.c b/test/battle/ability/dauntless_shield.c index eb7b5c15cb..b646d00b0d 100644 --- a/test/battle/ability/dauntless_shield.c +++ b/test/battle/ability/dauntless_shield.c @@ -3,7 +3,6 @@ ASSUMPTIONS { - ASSUME(P_GEN_8_POKEMON == TRUE); ASSUME(B_PROTEAN_LIBERO == GEN_9); } @@ -45,3 +44,23 @@ SINGLE_BATTLE_TEST("Dauntless Shield raises Attack by one stage only once per ba EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE); } } + +SINGLE_BATTLE_TEST("Dauntless Shield activates when it's no longer effected by Neutralizing Gas") +{ + GIVEN { + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_ZAMAZENTA) { Ability(ABILITY_DAUNTLESS_SHIELD); } + } WHEN { + TURN { SWITCH(player, 1); } + } SCENE { + ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS); + MESSAGE("Neutralizing Gas filled the area!"); + MESSAGE("Weezing, that's enough! Come back!"); + MESSAGE("The effects of Neutralizing Gas wore off!"); + ABILITY_POPUP(opponent, ABILITY_DAUNTLESS_SHIELD); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Zamazenta's Dauntless Shield raised its Defense!"); + } +} + diff --git a/test/battle/ability/embody_aspect.c b/test/battle/ability/embody_aspect.c new file mode 100644 index 0000000000..8b37dd1a74 --- /dev/null +++ b/test/battle/ability/embody_aspect.c @@ -0,0 +1,59 @@ +#include "global.h" +#include "test/battle.h" + + +SINGLE_BATTLE_TEST("Embodoy Aspect raises a stat depending on the users form by one stage") +{ + u16 species, ability; + + PARAMETRIZE { species = SPECIES_OGERPON_TEAL_MASK_TERA; ability = ABILITY_EMBODY_ASPECT_TEAL; } + PARAMETRIZE { species = SPECIES_OGERPON_HEARTHFLAME_MASK_TERA; ability = ABILITY_EMBODY_ASPECT_HEARTHFLAME; } + PARAMETRIZE { species = SPECIES_OGERPON_WELLSPRING_MASK_TERA; ability = ABILITY_EMBODY_ASPECT_WELLSPRING; } + PARAMETRIZE { species = SPECIES_OGERPON_CORNERSTONE_MASK_TERA; ability = ABILITY_EMBODY_ASPECT_CORNERSTONE; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { } + } SCENE { + ABILITY_POPUP(opponent, ability); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + if (ability == ABILITY_EMBODY_ASPECT_TEAL) + MESSAGE("Foe Ogerpon's Embody Aspect raised its Sp. Atk!"); + else if (ability == ABILITY_EMBODY_ASPECT_HEARTHFLAME) + MESSAGE("Foe Ogerpon's Embody Aspect raised its Attack!"); + else if (ability == ABILITY_EMBODY_ASPECT_WELLSPRING) + MESSAGE("Foe Ogerpon's Embody Aspect raised its Sp. Def!"); + else if (ability == ABILITY_EMBODY_ASPECT_CORNERSTONE) + MESSAGE("Foe Ogerpon's Embody Aspect raised its Defense!"); + } THEN { + if (ability == ABILITY_EMBODY_ASPECT_TEAL) + EXPECT_EQ(opponent->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1); + else if (ability == ABILITY_EMBODY_ASPECT_HEARTHFLAME) + EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1); + else if (ability == ABILITY_EMBODY_ASPECT_WELLSPRING) + EXPECT_EQ(opponent->statStages[STAT_SPDEF], DEFAULT_STAT_STAGE + 1); + else if (ability == ABILITY_EMBODY_ASPECT_CORNERSTONE) + EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 1); + } +} + +SINGLE_BATTLE_TEST("Embodoy Aspect activates when it's no longer effected by Neutralizing Gas") +{ + GIVEN { + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_OGERPON_TEAL_MASK_TERA) { Ability(ABILITY_EMBODY_ASPECT_TEAL); } + } WHEN { + TURN { SWITCH(player, 1); } + } SCENE { + ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS); + MESSAGE("Neutralizing Gas filled the area!"); + MESSAGE("Weezing, that's enough! Come back!"); + MESSAGE("The effects of Neutralizing Gas wore off!"); + ABILITY_POPUP(opponent, ABILITY_EMBODY_ASPECT_TEAL); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Ogerpon's Embody Aspect raised its Sp. Atk!"); + } +} diff --git a/test/battle/ability/intrepid_sword.c b/test/battle/ability/intrepid_sword.c index 88228bbe78..9f2901a8d2 100644 --- a/test/battle/ability/intrepid_sword.c +++ b/test/battle/ability/intrepid_sword.c @@ -3,7 +3,6 @@ ASSUMPTIONS { - ASSUME(P_GEN_8_POKEMON == TRUE); ASSUME(B_INTREPID_SWORD == GEN_9); } @@ -45,3 +44,23 @@ SINGLE_BATTLE_TEST("Intrepid Sword raises Attack by one stage only once per batt EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE); } } + +SINGLE_BATTLE_TEST("Intrepid Sword activates when it's no longer effected by Neutralizing Gas") +{ + GIVEN { + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_ZACIAN) { Ability(ABILITY_INTREPID_SWORD); } + } WHEN { + TURN { SWITCH(player, 1); } + } SCENE { + ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS); + MESSAGE("Neutralizing Gas filled the area!"); + MESSAGE("Weezing, that's enough! Come back!"); + MESSAGE("The effects of Neutralizing Gas wore off!"); + ABILITY_POPUP(opponent, ABILITY_INTREPID_SWORD); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Zacian's Intrepid Sword raised its Attack!"); + } +} + diff --git a/test/battle/move_effect/hit_escape.c b/test/battle/move_effect/hit_escape.c index b9d1bc99e7..49a8c58627 100644 --- a/test/battle/move_effect/hit_escape.c +++ b/test/battle/move_effect/hit_escape.c @@ -98,7 +98,6 @@ SINGLE_BATTLE_TEST("U-turn switches the user out if Wimp Out fails to activate") SINGLE_BATTLE_TEST("U-turn switches the user out after Ice Face activates") { GIVEN { - ASSUME(P_GEN_8_POKEMON == TRUE); PLAYER(SPECIES_BEEDRILL); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_EISCUE) { Ability(ABILITY_ICE_FACE); }