Skip to content

Commit

Permalink
Fixed Ice Face, implemented tests (#5171)
Browse files Browse the repository at this point in the history
* Fixed Ice Face, implemented tests

* Fixed agbcc and bad battle mon looping

* Fixed the ShouldChangeFormInWeather function again

* Cleaned up End of Turn weather form changes, simplified Ice Face

---------

Co-authored-by: Hedara <[email protected]>
  • Loading branch information
hedara90 and Hedara committed Aug 15, 2024
1 parent 18980b2 commit 45f10d7
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 42 deletions.
1 change: 0 additions & 1 deletion include/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 0 additions & 2 deletions src/battle_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
45 changes: 12 additions & 33 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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++)
{
Expand Down Expand Up @@ -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);
Expand All @@ -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])))
Expand All @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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++;
Expand Down
140 changes: 134 additions & 6 deletions test/battle/ability/ice_face.c
Original file line number Diff line number Diff line change
@@ -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!");
}
}

0 comments on commit 45f10d7

Please sign in to comment.