Skip to content

Commit

Permalink
Removed some hardcoding of move IDs + Gen4/5 Defog (#5156)
Browse files Browse the repository at this point in the history
* Removed some hardcoding of move IDs

* Added Defog Gen6+ config (+ updated tests)
  • Loading branch information
AsparagusEduardo authored Aug 14, 2024
1 parent 38752b5 commit 6f0004e
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 54 deletions.
2 changes: 1 addition & 1 deletion include/config/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
#define B_BURN_HIT_THAW GEN_LATEST // In Gen6+, damaging moves with a chance of burn will thaw the target, regardless if they're fire-type moves or not.
#define B_HEALING_WISH_SWITCH GEN_LATEST // In Gen5+, the mon receiving Healing Wish is sent out at the end of the turn.
// Additionally, in gen8+ the Healing Wish's effect will be stored until the user switches into a statused or hurt mon.
#define B_DEFOG_CLEARS_TERRAIN GEN_LATEST // In Gen8+, Defog also clears active Terrain.
#define B_DEFOG_EFFECT_CLEARING GEN_LATEST // In Gen6+, Defog clears Spikes, Toxic Spikes, Stealth Rock and Sticky Web from both sides. In Gen8+, Defog also clears active Terrain.
#define B_STOCKPILE_RAISES_DEFS GEN_LATEST // In Gen4+, Stockpile also raises Defense and Sp. Defense stats. Once Spit Up / Swallow is used, these stat changes are lost.
#define B_TRANSFORM_SHINY GEN_LATEST // In Gen4+, Transform will copy the shiny state of the opponent instead of maintaining its own shiny state.
#define B_TRANSFORM_FORM_CHANGES GEN_LATEST // In Gen5+, Transformed Pokemon cannot change forms.
Expand Down
2 changes: 1 addition & 1 deletion src/battle_ai_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4056,7 +4056,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
ADJUST_SCORE(DECENT_EFFECT); // Force 'em out next turn
break;
default:
if (move != MOVE_BESTOW && aiData->items[battlerAtk] == ITEM_NONE)
if (gMovesInfo[gCurrentMove].effect != EFFECT_BESTOW && aiData->items[battlerAtk] == ITEM_NONE)
{
switch (aiData->holdEffects[battlerDef])
{
Expand Down
4 changes: 3 additions & 1 deletion src/battle_ai_switch_items.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,9 @@ static bool32 CanMonSurviveHazardSwitchin(u32 battler)
for (j = 0; j < MAX_MON_MOVES; j++)
{
aiMove = GetMonData(&party[i], MON_DATA_MOVE1 + j, NULL);
if (aiMove == MOVE_RAPID_SPIN || aiMove == MOVE_DEFOG || aiMove == MOVE_MORTAL_SPIN || aiMove == MOVE_TIDY_UP)
if (MoveHasAdditionalEffectSelf(aiMove, MOVE_EFFECT_RAPID_SPIN)
|| (B_DEFOG_EFFECT_CLEARING >= GEN_6 && gMovesInfo[aiMove].effect == EFFECT_DEFOG)
|| gMovesInfo[aiMove].effect == EFFECT_TIDY_UP)
{
// Have a mon that can clear the hazards, so switching out is okay
return TRUE;
Expand Down
21 changes: 12 additions & 9 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1491,14 +1491,14 @@ static bool32 AccuracyCalcHelper(u16 move)
return TRUE;
}
// If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits.
else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
{
if (!JumpIfMoveFailed(7, move))
RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD);
return TRUE;
}
// If the target has the ability No Guard and they aren't involved in a Sky Drop or the current move isn't Sky Drop, move hits.
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
{
if (!JumpIfMoveFailed(7, move))
RecordAbilityBattle(gBattlerTarget, ABILITY_NO_GUARD);
Expand Down Expand Up @@ -2165,7 +2165,7 @@ static void Cmd_attackanimation(void)
&& gCurrentMove != MOVE_SUBSTITUTE
&& gCurrentMove != MOVE_ALLY_SWITCH
// In a wild double battle gotta use the teleport animation if two wild pokemon are alive.
&& !(gCurrentMove == MOVE_TELEPORT && WILD_DOUBLE_BATTLE && GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker))))
&& !(gMovesInfo[gCurrentMove].effect == EFFECT_TELEPORT && WILD_DOUBLE_BATTLE && GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker))))
{
BattleScriptPush(cmd->nextInstr);
gBattlescriptCurrInstr = BattleScript_Pausex20;
Expand Down Expand Up @@ -8605,19 +8605,22 @@ static bool32 TryDefogClear(u32 battlerAtk, bool32 clear)
DEFOG_CLEAR(SIDE_STATUS_AURORA_VEIL, auroraVeilTimer, BattleScript_SideStatusWoreOffReturn, MOVE_AURORA_VEIL);
DEFOG_CLEAR(SIDE_STATUS_SAFEGUARD, safeguardTimer, BattleScript_SideStatusWoreOffReturn, MOVE_SAFEGUARD);
}
DEFOG_CLEAR(SIDE_STATUS_SPIKES, spikesAmount, BattleScript_SpikesDefog, 0);
DEFOG_CLEAR(SIDE_STATUS_STEALTH_ROCK, stealthRockAmount, BattleScript_StealthRockDefog, 0);
DEFOG_CLEAR(SIDE_STATUS_TOXIC_SPIKES, toxicSpikesAmount, BattleScript_ToxicSpikesDefog, 0);
DEFOG_CLEAR(SIDE_STATUS_STICKY_WEB, stickyWebAmount, BattleScript_StickyWebDefog, 0);
DEFOG_CLEAR(SIDE_STATUS_STEELSURGE, steelsurgeAmount, BattleScript_SteelsurgeDefog, 0);
if (B_DEFOG_EFFECT_CLEARING >= GEN_6)
{
DEFOG_CLEAR(SIDE_STATUS_SPIKES, spikesAmount, BattleScript_SpikesDefog, 0);
DEFOG_CLEAR(SIDE_STATUS_STEALTH_ROCK, stealthRockAmount, BattleScript_StealthRockDefog, 0);
DEFOG_CLEAR(SIDE_STATUS_TOXIC_SPIKES, toxicSpikesAmount, BattleScript_ToxicSpikesDefog, 0);
DEFOG_CLEAR(SIDE_STATUS_STICKY_WEB, stickyWebAmount, BattleScript_StickyWebDefog, 0);
DEFOG_CLEAR(SIDE_STATUS_STEELSURGE, steelsurgeAmount, BattleScript_SteelsurgeDefog, 0);
}
if (gBattleWeather & B_WEATHER_FOG)
{
gBattleWeather &= ~B_WEATHER_FOG;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_FogEnded_Ret;
return TRUE;
}
if (B_DEFOG_CLEARS_TERRAIN >= GEN_8 && (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY))
if (B_DEFOG_EFFECT_CLEARING >= GEN_8 && (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY))
{
RemoveAllTerrains();
BattleScriptPushCursor();
Expand Down
2 changes: 1 addition & 1 deletion src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -8391,7 +8391,7 @@ u8 IsMonDisobedient(void)
// is not obedient
if (gCurrentMove == MOVE_RAGE)
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RAGE;
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (gCurrentMove == MOVE_SNORE || gCurrentMove == MOVE_SLEEP_TALK))
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (gMovesInfo[gCurrentMove].effect == EFFECT_SNORE || gMovesInfo[gCurrentMove].effect == EFFECT_SLEEP_TALK))
{
gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep;
return 1;
Expand Down
21 changes: 11 additions & 10 deletions src/pokemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -6957,8 +6957,9 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler)
u32 ability = GetMonAbility(mon);
u32 type1 = gSpeciesInfo[species].types[0];
u32 type2 = gSpeciesInfo[species].types[1];
u32 effect = gMovesInfo[move].effect;

if (move == MOVE_IVY_CUDGEL
if (effect == EFFECT_IVY_CUDGEL
&& (species == SPECIES_OGERPON_WELLSPRING_MASK || species == SPECIES_OGERPON_WELLSPRING_MASK_TERA
|| species == SPECIES_OGERPON_HEARTHFLAME_MASK || species == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA
|| species == SPECIES_OGERPON_CORNERSTONE_MASK || species == SPECIES_OGERPON_CORNERSTONE_MASK_TERA))
Expand All @@ -6969,44 +6970,44 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler)
{
return TYPE_NORMAL;
}
else if (move == MOVE_TERA_BLAST && GetActiveGimmick(battler) == GIMMICK_TERA && gBattleMons[battler].species == species)
else if (effect == EFFECT_TERA_BLAST && GetActiveGimmick(battler) == GIMMICK_TERA && gBattleMons[battler].species == species)
{
return GetMonData(mon, MON_DATA_TERA_TYPE);
}
else if (move == MOVE_TERA_STARSTORM && species == SPECIES_TERAPAGOS_STELLAR)
else if (effect == EFFECT_TERA_STARSTORM && species == SPECIES_TERAPAGOS_STELLAR)
{
return TYPE_STELLAR;
}
else if (move == MOVE_HIDDEN_POWER)
{
return CalculateHiddenPowerType(mon);
}
else if (move == MOVE_AURA_WHEEL && species == SPECIES_MORPEKO_HANGRY)
else if (effect == EFFECT_AURA_WHEEL && species == SPECIES_MORPEKO_HANGRY)
{
type = TYPE_DARK;
}
else if (gMovesInfo[move].effect == EFFECT_CHANGE_TYPE_ON_ITEM)
else if (effect == EFFECT_CHANGE_TYPE_ON_ITEM)
{
if (heldItemEffect == gMovesInfo[move].argument)
return ItemId_GetSecondaryId(heldItem);
else
return TYPE_NORMAL;
}
else if (move == MOVE_NATURAL_GIFT)
else if (effect == EFFECT_NATURAL_GIFT)
{
if (ItemId_GetPocket(heldItem) == POCKET_BERRIES)
return gNaturalGiftTable[ITEM_TO_BERRY(heldItem)].type;
else
return TYPE_NORMAL;
}
else if (move == MOVE_RAGING_BULL
else if (effect == EFFECT_RAGING_BULL
&& (species == SPECIES_TAUROS_PALDEAN_COMBAT_BREED
|| species == SPECIES_TAUROS_PALDEAN_BLAZE_BREED
|| species == SPECIES_TAUROS_PALDEAN_AQUA_BREED))
{
return type2;
}
else if (move == MOVE_REVELATION_DANCE)
else if (effect == EFFECT_REVELATION_DANCE)
{
if (gBattleMons[battler].species != species && type1 != TYPE_MYSTERY)
type = type1;
Expand All @@ -7021,7 +7022,7 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler)
else if (gBattleMons[battler].types[2] != TYPE_MYSTERY)
type = gBattleMons[battler].types[2];
}
else if (gMovesInfo[move].effect == EFFECT_TERRAIN_PULSE
else if (effect == EFFECT_TERRAIN_PULSE
&& ((IsMonGrounded(heldItemEffect, ability, type1, type2) && gBattleMons[battler].species != species)
|| (IsBattlerTerrainAffected(battler, STATUS_FIELD_TERRAIN_ANY) && gBattleMons[battler].species == species)))
{
Expand All @@ -7037,7 +7038,7 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler)
type = TYPE_NORMAL;
}

if (gMovesInfo[move].effect == EFFECT_WEATHER_BALL)
if (effect == EFFECT_WEATHER_BALL)
{
if (gMain.inBattle && WEATHER_HAS_EFFECT)
{
Expand Down
77 changes: 46 additions & 31 deletions test/battle/move_effect/defog.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Mist and Safeguard
}
}

DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and Sticky Web from player's side")
DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and Sticky Web from player's side (Gen 6+)")
{
u16 move;

Expand All @@ -154,13 +154,15 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and S
if (move == MOVE_DEFOG) {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
MESSAGE("Foe Wobbuffet's evasiveness fell!");
MESSAGE("The pointed stones disappeared from around your team!");
MESSAGE("The sticky web has disappeared from the ground around your team!");
if (B_DEFOG_EFFECT_CLEARING >= GEN_6) {
MESSAGE("The pointed stones disappeared from around your team!");
MESSAGE("The sticky web has disappeared from the ground around your team!");
}
}
// Switch happens
SWITCH_OUT_MESSAGE("Wobbuffet");
SEND_IN_MESSAGE("Wobbuffet");
if (move != MOVE_DEFOG) {
if (move != MOVE_DEFOG || B_DEFOG_EFFECT_CLEARING <= GEN_5) {
HP_BAR(playerLeft);
MESSAGE("Pointed stones dug into Wobbuffet!");
MESSAGE("Wobbuffet was caught in a Sticky Web!");
Expand Down Expand Up @@ -198,12 +200,13 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Spikes from player
if (move == MOVE_DEFOG) {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
MESSAGE("Foe Wobbuffet's evasiveness fell!");
MESSAGE("The spikes disappeared from the ground around your team!");
if (B_DEFOG_EFFECT_CLEARING >= GEN_6)
MESSAGE("The spikes disappeared from the ground around your team!");
}
// Switch happens
SWITCH_OUT_MESSAGE("Wobbuffet");
SEND_IN_MESSAGE("Wobbuffet");
if (move != MOVE_DEFOG) {
if (move != MOVE_DEFOG || B_DEFOG_EFFECT_CLEARING <= GEN_5) {
HP_BAR(player);
MESSAGE("Wobbuffet is hurt by spikes!");
}
Expand All @@ -216,7 +219,7 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Spikes from player
}
}

SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain")
SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain (Gen 8+)")
{
u16 move;

Expand All @@ -225,7 +228,6 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain")
PARAMETRIZE { move = MOVE_MISTY_TERRAIN; }
PARAMETRIZE { move = MOVE_GRASSY_TERRAIN; }
GIVEN {
ASSUME(B_DEFOG_CLEARS_TERRAIN >= GEN_8);
PLAYER(SPECIES_WOBBUFFET) { Speed(50); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); }
} WHEN {
Expand All @@ -235,19 +237,29 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain")
ANIMATION(ANIM_TYPE_MOVE, MOVE_DEFOG, opponent);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
MESSAGE("Wobbuffet's evasiveness fell!");
if (move == MOVE_PSYCHIC_TERRAIN) {
MESSAGE("The weirdness disappeared from the battlefield.");
}
else if (move == MOVE_ELECTRIC_TERRAIN) {
MESSAGE("The electricity disappeared from the battlefield.");
}
else if (move == MOVE_MISTY_TERRAIN) {
MESSAGE("The mist disappeared from the battlefield.");
}
else if (move == MOVE_GRASSY_TERRAIN) {
MESSAGE("The grass disappeared from the battlefield.");
if (B_DEFOG_EFFECT_CLEARING >= GEN_8) {
if (move == MOVE_PSYCHIC_TERRAIN) {
MESSAGE("The weirdness disappeared from the battlefield.");
}
else if (move == MOVE_ELECTRIC_TERRAIN) {
MESSAGE("The electricity disappeared from the battlefield.");
}
else if (move == MOVE_MISTY_TERRAIN) {
MESSAGE("The mist disappeared from the battlefield.");
}
else if (move == MOVE_GRASSY_TERRAIN) {
MESSAGE("The grass disappeared from the battlefield.");
}
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_RESTORE_BG, player);
} else {
NONE_OF {
MESSAGE("The weirdness disappeared from the battlefield.");
MESSAGE("The electricity disappeared from the battlefield.");
MESSAGE("The mist disappeared from the battlefield.");
MESSAGE("The grass disappeared from the battlefield.");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_RESTORE_BG, player);
}
}
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_RESTORE_BG, player);
}
}

Expand All @@ -270,11 +282,12 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Toxic Spikes from
if (move == MOVE_DEFOG) {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
MESSAGE("Wobbuffet's evasiveness fell!");
MESSAGE("The poison spikes disappeared from the ground around the opposing team!");
if (B_DEFOG_EFFECT_CLEARING >= GEN_6)
MESSAGE("The poison spikes disappeared from the ground around the opposing team!");
}
// Switch happens
MESSAGE("2 sent out Wobbuffet!");
if (move != MOVE_DEFOG) {
if (move != MOVE_DEFOG || B_DEFOG_EFFECT_CLEARING <= GEN_5) {
MESSAGE("Foe Wobbuffet was poisoned!");
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
STATUS_ICON(opponent, poison: TRUE);
Expand Down Expand Up @@ -356,15 +369,17 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes everything it can"
MESSAGE("Ally's Aurora Veil wore off!");
MESSAGE("Ally's Safeguard wore off!");

MESSAGE("The spikes disappeared from the ground around your team!");
MESSAGE("The pointed stones disappeared from around your team!");
MESSAGE("The poison spikes disappeared from the ground around your team!");
MESSAGE("The sticky web has disappeared from the ground around your team!");
if (B_DEFOG_EFFECT_CLEARING >= GEN_6) {
MESSAGE("The spikes disappeared from the ground around your team!");
MESSAGE("The pointed stones disappeared from around your team!");
MESSAGE("The poison spikes disappeared from the ground around your team!");
MESSAGE("The sticky web has disappeared from the ground around your team!");

// Opponent side
MESSAGE("The spikes disappeared from the ground around the opposing team!");
MESSAGE("The pointed stones disappeared from around the opposing team!");
MESSAGE("The poison spikes disappeared from the ground around the opposing team!");
MESSAGE("The sticky web has disappeared from the ground around the opposing team!");
// Opponent side
MESSAGE("The spikes disappeared from the ground around the opposing team!");
MESSAGE("The pointed stones disappeared from around the opposing team!");
MESSAGE("The poison spikes disappeared from the ground around the opposing team!");
MESSAGE("The sticky web has disappeared from the ground around the opposing team!");
}
}
}

0 comments on commit 6f0004e

Please sign in to comment.