diff --git a/include/battle.h b/include/battle.h index 1d60aacec1..ace178c0e7 100644 --- a/include/battle.h +++ b/include/battle.h @@ -763,7 +763,6 @@ struct BattleStruct bool8 effectsBeforeUsingMoveDone:1; // Mega Evo and Focus Punch/Shell Trap effects. u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit. u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching) - bool8 allowedToChangeFormInWeather[PARTY_SIZE][NUM_BATTLE_SIDES]; // For each party member and side, used by Ice Face. u8 battleBondTransformed[NUM_BATTLE_SIDES]; // Bitfield for each party. u8 storedHealingWish:4; // Each battler as a bit. u8 storedLunarDance:4; // Each battler as a bit. diff --git a/src/battle_main.c b/src/battle_main.c index e164976e9d..55337a045e 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3114,8 +3114,6 @@ static void BattleStartClearSetData(void) gBattleStruct->itemLost[B_SIDE_PLAYER][i].originalItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); gBattleStruct->itemLost[B_SIDE_OPPONENT][i].originalItem = GetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM); gPartyCriticalHits[i] = 0; - gBattleStruct->allowedToChangeFormInWeather[i][B_SIDE_PLAYER] = FALSE; - gBattleStruct->allowedToChangeFormInWeather[i][B_SIDE_OPPONENT] = FALSE; } gBattleStruct->swapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky diff --git a/src/battle_util.c b/src/battle_util.c index ada7cb20a3..c18b0544a0 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1671,7 +1671,6 @@ enum ENDTURN_ION_DELUGE, ENDTURN_FAIRY_LOCK, ENDTURN_RETALIATE, - ENDTURN_WEATHER_FORM, ENDTURN_STATUS_HEAL, ENDTURN_RAINBOW, ENDTURN_SEA_OF_FIRE, @@ -2171,18 +2170,6 @@ u8 DoFieldEndTurnEffects(void) gSideTimers[B_SIDE_OPPONENT].retaliateTimer--; gBattleStruct->turnCountersTracker++; break; - case ENDTURN_WEATHER_FORM: - for (i = 0; i < gBattlersCount; i++) - { - if (AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, i, 0, 0, 0)) - { - effect++; - break; - } - } - if (effect == 0) - gBattleStruct->turnCountersTracker++; - break; case ENDTURN_STATUS_HEAL: for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++) { @@ -3894,21 +3881,6 @@ static const u16 sWeatherFlagsInfo[][3] = [ENUM_WEATHER_FOG] = {B_WEATHER_FOG_TEMPORARY, B_WEATHER_FOG_PERMANENT, HOLD_EFFECT_NONE}, }; -static void ShouldChangeFormInWeather(u32 battler) -{ - int i; - int side = GetBattlerSide(battler); - struct Pokemon *party = GetSideParty(side); - - for (i = 0; i < PARTY_SIZE; i++) - { - if (GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_EISCUE_NOICE_FACE) - gBattleStruct->allowedToChangeFormInWeather[i][side] = TRUE; - else - gBattleStruct->allowedToChangeFormInWeather[i][side] = FALSE; - } -} - bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility) { u16 battlerAbility = GetBattlerAbility(battler); @@ -3922,7 +3894,6 @@ bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility) else if (B_ABILITY_WEATHER < GEN_6 && viaAbility && !(gBattleWeather & sWeatherFlagsInfo[weatherEnumId][1])) { gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1]); - ShouldChangeFormInWeather(battler); return TRUE; } else if (!(gBattleWeather & (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1]))) @@ -3932,7 +3903,6 @@ bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility) gWishFutureKnock.weatherDuration = 8; else gWishFutureKnock.weatherDuration = 5; - ShouldChangeFormInWeather(battler); return TRUE; } return FALSE; @@ -4961,6 +4931,17 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 effect++; } break; + case ABILITY_ICE_FACE: + if (IsBattlerWeatherAffected(battler, B_WEATHER_HAIL | B_WEATHER_SNOW) + && gBattleMons[battler].species == SPECIES_EISCUE_NOICE_FACE + && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)) + { + // TODO: Convert this to a proper FORM_CHANGE type. + gBattleMons[battler].species = SPECIES_EISCUE_ICE_FACE; + BattleScriptPushCursorAndCallback(BattleScript_BattlerFormChangeWithStringEnd3); + effect++; + } + break; } break; case ABILITYEFFECT_ENDTURN: @@ -6285,11 +6266,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITY_ICE_FACE: if (IsBattlerWeatherAffected(battler, B_WEATHER_HAIL | B_WEATHER_SNOW) && gBattleMons[battler].species == SPECIES_EISCUE_NOICE_FACE - && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED) - && gBattleStruct->allowedToChangeFormInWeather[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)]) + && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)) { // TODO: Convert this to a proper FORM_CHANGE type. - gBattleStruct->allowedToChangeFormInWeather[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)] = FALSE; gBattleMons[battler].species = SPECIES_EISCUE_ICE_FACE; BattleScriptPushCursorAndCallback(BattleScript_BattlerFormChangeWithStringEnd3); effect++; diff --git a/test/battle/ability/ice_face.c b/test/battle/ability/ice_face.c index 53917b5623..54a307754c 100644 --- a/test/battle/ability/ice_face.c +++ b/test/battle/ability/ice_face.c @@ -1,9 +1,137 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("Ice Face blocks physical moves, changing Eiscue into its Noice Face form"); // Include Special move in test -TO_DO_BATTLE_TEST("Ice Face is restored if hail or snow begins while Noice Face Eiscue is out"); -TO_DO_BATTLE_TEST("Ice Face is restored if Noice Face Eiscue is sent in while hail or snow is active"); -TO_DO_BATTLE_TEST("Ice Face is not restored if Eiscue changes into Noice Face form while there's already hail"); -TO_DO_BATTLE_TEST("Ice Face form change persists after switching out"); -TO_DO_BATTLE_TEST("Ice Face doesn't transform Eiscue if Cloud Nine/Air Lock is on the field"); +SINGLE_BATTLE_TEST("Ice Face blocks physical moves, changing Eiscue into its Noice Face form") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_EISCUE); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + } +} + +SINGLE_BATTLE_TEST("Ice Face does not block special moves, Eiscue stays in Ice Face form") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(gMovesInfo[MOVE_EMBER].category == DAMAGE_CATEGORY_SPECIAL); + PLAYER(SPECIES_EISCUE); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_EMBER); } + } SCENE { + NOT ABILITY_POPUP(player, ABILITY_ICE_FACE); + } +} + +SINGLE_BATTLE_TEST("Ice Face is restored if hail or snow begins while Noice Face Eiscue is out") +{ + u32 move; + PARAMETRIZE { move = MOVE_SNOWSCAPE; } + PARAMETRIZE { move = MOVE_HAIL; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); + ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + PLAYER(SPECIES_EISCUE); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(opponent, move); } + TURN { MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + } +} + +SINGLE_BATTLE_TEST("Ice Face is restored if Noice Face Eiscue is sent in while hail or snow is active") +{ + u32 move; + PARAMETRIZE { move = MOVE_SNOWSCAPE; } + PARAMETRIZE { move = MOVE_HAIL; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); + ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + PLAYER(SPECIES_EISCUE); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_TACKLE); } + TURN { SWITCH(player, 1); MOVE(opponent, move); } + TURN { SWITCH(player, 0); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + } +} + +SINGLE_BATTLE_TEST("Ice Face is not restored if Eiscue changes into Noice Face form while there's already hail or snow") +{ + u32 move; + PARAMETRIZE { move = MOVE_SNOWSCAPE; } + PARAMETRIZE { move = MOVE_HAIL; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); + ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + PLAYER(SPECIES_EISCUE) { HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, move); MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + MESSAGE("Eiscue used Celebrate!"); + MESSAGE("Eiscue fainted!"); + } +} + +SINGLE_BATTLE_TEST("Ice Face form change persists after switching out") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_EISCUE) { HP(1); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_CELEBRATE); } + TURN { SWITCH(player, 0); MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + MESSAGE("Eiscue fainted!"); + } +} + +SINGLE_BATTLE_TEST("Ice Face doesn't transform Eiscue if Cloud Nine/Air Lock is on the field") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_EISCUE) { HP(1); } + OPPONENT(SPECIES_RAYQUAZA) { Ability(ABILITY_AIR_LOCK); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_SNOWSCAPE); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + MESSAGE("Eiscue fainted!"); + } +}