From af19b1319571a0286e2f30c61982ef138eb211e7 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Mon, 30 Dec 2024 09:18:23 +0100 Subject: [PATCH] Adds Pledge Side Statuses as Starting Statuses (#5899) --- data/battle_scripts_1.s | 4 +- include/constants/battle.h | 30 ++-- include/constants/battle_string_ids.h | 8 +- src/battle_message.c | 20 ++- src/battle_script_commands.c | 2 +- src/battle_util.c | 230 ++++++++++++++------------ 6 files changed, 164 insertions(+), 130 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 3e88c1f877..83f3fd346a 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5899,8 +5899,7 @@ BattleScript_OverworldStatusStarts:: BattleScript_OverworldStatusStarts_TryActivations: jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TRICK_ROOM, BattleScript_TryRoomServiceLoop - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TAILWIND_PLAYER, BattleScript_TryTailwindAbilitiesLoop - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TAILWIND_OPPONENT, BattleScript_TryTailwindAbilitiesLoop + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TAILWIND, BattleScript_TryTailwindAbilitiesLoop return BattleScript_OverworldWeatherStarts:: @@ -8333,7 +8332,6 @@ BattleScript_GrassyTerrainLoopIncrement:: addbyte gBattleCommunication, 1 jumpifbytenotequal gBattleCommunication, gBattlersCount, BattleScript_GrassyTerrainLoop bicword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE - jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_TERRAIN_PERMANENT, BattleScript_GrassyTerrainHealEnd BattleScript_GrassyTerrainHealEnd: return diff --git a/include/constants/battle.h b/include/constants/battle.h index a7300e6517..7d6da96b77 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -266,7 +266,6 @@ #define STATUS_FIELD_PSYCHIC_TERRAIN (1 << 9) #define STATUS_FIELD_ION_DELUGE (1 << 10) #define STATUS_FIELD_FAIRY_LOCK (1 << 11) -#define STATUS_FIELD_TERRAIN_PERMANENT (1 << 12) // Overworld thunderstorm generates electric terrain #define STATUS_FIELD_TERRAIN_ANY (STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN) @@ -539,15 +538,24 @@ // Constants for B_VAR_STARTING_STATUS // Timer value controlled by B_VAR_STARTING_STATUS_TIMER -#define STARTING_STATUS_NONE 0 -#define STARTING_STATUS_ELECTRIC_TERRAIN 1 -#define STARTING_STATUS_MISTY_TERRAIN 2 -#define STARTING_STATUS_GRASSY_TERRAIN 3 -#define STARTING_STATUS_PSYCHIC_TERRAIN 4 -#define STARTING_STATUS_TRICK_ROOM 5 -#define STARTING_STATUS_MAGIC_ROOM 6 -#define STARTING_STATUS_WONDER_ROOM 7 -#define STARTING_STATUS_TAILWIND_PLAYER 8 -#define STARTING_STATUS_TAILWIND_OPPONENT 9 +enum StartingStatus +{ + STARTING_STATUS_NONE, + STARTING_STATUS_ELECTRIC_TERRAIN, + STARTING_STATUS_MISTY_TERRAIN, + STARTING_STATUS_GRASSY_TERRAIN, + STARTING_STATUS_PSYCHIC_TERRAIN, + STARTING_STATUS_TRICK_ROOM, + STARTING_STATUS_MAGIC_ROOM, + STARTING_STATUS_WONDER_ROOM, + STARTING_STATUS_TAILWIND_PLAYER, + STARTING_STATUS_TAILWIND_OPPONENT, + STARTING_STATUS_RAINBOW_PLAYER, + STARTING_STATUS_RAINBOW_OPPONENT, + STARTING_STATUS_SEA_OF_FIRE_PLAYER, + STARTING_STATUS_SEA_OF_FIRE_OPPONENT, + STARTING_STATUS_SWAMP_PLAYER, + STARTING_STATUS_SWAMP_OPPONENT, +}; #endif // GUARD_CONSTANTS_BATTLE_H diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 5149e85bcf..463a7fdd81 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -1010,9 +1010,11 @@ #define B_MSG_SET_TRICK_ROOM 4 #define B_MSG_SET_MAGIC_ROOM 5 #define B_MSG_SET_WONDER_ROOM 6 -#define B_MSG_SET_TAILWIND_PLAYER 7 -#define B_MSG_SET_TAILWIND_OPPONENT 8 -#define B_MSG_STARTING_STATUS_COUNT 9 +#define B_MSG_SET_TAILWIND 7 +#define B_MSG_SET_RAINBOW 8 +#define B_MSG_SET_SEA_OF_FIRE 9 +#define B_MSG_SET_SWAMP 10 +#define B_MSG_STARTING_STATUS_COUNT 11 // gWrappedStringIds diff --git a/src/battle_message.c b/src/battle_message.c index 662473eb5d..998c8f8185 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -915,15 +915,17 @@ const u16 gMentalHerbCureStringIds[] = const u16 gStartingStatusStringIds[B_MSG_STARTING_STATUS_COUNT] = { - [B_MSG_TERRAIN_SET_MISTY] = STRINGID_TERRAINBECOMESMISTY, - [B_MSG_TERRAIN_SET_ELECTRIC] = STRINGID_TERRAINBECOMESELECTRIC, - [B_MSG_TERRAIN_SET_PSYCHIC] = STRINGID_TERRAINBECOMESPSYCHIC, - [B_MSG_TERRAIN_SET_GRASSY] = STRINGID_TERRAINBECOMESGRASSY, - [B_MSG_SET_TRICK_ROOM] = STRINGID_DIMENSIONSWERETWISTED, - [B_MSG_SET_MAGIC_ROOM] = STRINGID_BIZARREARENACREATED, - [B_MSG_SET_WONDER_ROOM] = STRINGID_BIZARREAREACREATED, - [B_MSG_SET_TAILWIND_PLAYER] = STRINGID_TAILWINDBLEW, - [B_MSG_SET_TAILWIND_OPPONENT] = STRINGID_TAILWINDBLEW, + [B_MSG_TERRAIN_SET_MISTY] = STRINGID_TERRAINBECOMESMISTY, + [B_MSG_TERRAIN_SET_ELECTRIC] = STRINGID_TERRAINBECOMESELECTRIC, + [B_MSG_TERRAIN_SET_PSYCHIC] = STRINGID_TERRAINBECOMESPSYCHIC, + [B_MSG_TERRAIN_SET_GRASSY] = STRINGID_TERRAINBECOMESGRASSY, + [B_MSG_SET_TRICK_ROOM] = STRINGID_DIMENSIONSWERETWISTED, + [B_MSG_SET_MAGIC_ROOM] = STRINGID_BIZARREARENACREATED, + [B_MSG_SET_WONDER_ROOM] = STRINGID_BIZARREAREACREATED, + [B_MSG_SET_TAILWIND] = STRINGID_TAILWINDBLEW, + [B_MSG_SET_RAINBOW] = STRINGID_ARAINBOWAPPEAREDONSIDE, + [B_MSG_SET_SEA_OF_FIRE] = STRINGID_SEAOFFIREENVELOPEDSIDE, + [B_MSG_SET_SWAMP] = STRINGID_SWAMPENVELOPEDSIDE, }; const u16 gTerrainStringIds[B_MSG_TERRAIN_COUNT] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 13c24466f5..1dff66341d 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -16988,7 +16988,7 @@ void BS_SetRemoveTerrain(void) { u32 atkHoldEffect = GetBattlerHoldEffect(gBattlerAttacker, TRUE); - gFieldStatuses &= ~(STATUS_FIELD_TERRAIN_ANY | STATUS_FIELD_TERRAIN_PERMANENT); + gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; gFieldStatuses |= statusFlag; gFieldTimers.terrainTimer = (atkHoldEffect == HOLD_EFFECT_TERRAIN_EXTENDER) ? 8 : 5; gBattlescriptCurrInstr = cmd->nextInstr; diff --git a/src/battle_util.c b/src/battle_util.c index c0038fd42a..6925a1c64d 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1554,7 +1554,7 @@ static bool32 EndTurnTerrain(u32 terrainFlag, u32 stringTableId) { if (terrainFlag & STATUS_FIELD_GRASSY_TERRAIN) BattleScriptExecute(BattleScript_GrassyTerrainHeals); - if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0) + if (gFieldTimers.terrainTimer > 0 && --gFieldTimers.terrainTimer == 0) { gFieldStatuses &= ~terrainFlag; TryToRevertMimicryAndFlags(); @@ -4049,7 +4049,7 @@ static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer) { if ((!(gFieldStatuses & statusFlag) && (!gBattleStruct->isSkyBattle))) { - gFieldStatuses &= ~(STATUS_FIELD_TERRAIN_ANY | STATUS_FIELD_TERRAIN_PERMANENT); + gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; gFieldStatuses |= statusFlag; gDisableStructs[battler].terrainAbilityDone = FALSE; @@ -4328,6 +4328,43 @@ u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 mov return effect; } +static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u8 *timer) +{ + if (!(gFieldStatuses & flag)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = message; + gFieldStatuses |= flag; + gBattleScripting.animArg1 = anim; + if (gBattleStruct->startingStatusTimer) + *timer = gBattleStruct->startingStatusTimer; + else + *timer = 0; // Infinite + + return 1; + } + + return 0; +} + +static inline u32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 anim, u8 *timer) +{ + if (!(gSideStatuses[side] & flag)) + { + gBattlerAttacker = gBattlerTarget = side; + gBattleCommunication[MULTISTRING_CHOOSER] = message; + gSideStatuses[side] |= flag; + gBattleScripting.animArg1 = anim; + if (gBattleStruct->startingStatusTimer) + *timer = gBattleStruct->startingStatusTimer; + else + *timer = 0; // Infinite + + return 1; + } + + return 0; +} + u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg) { u32 effect = 0; @@ -4359,125 +4396,110 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 { case ABILITYEFFECT_SWITCH_IN_STATUSES: // starting field/side/etc statuses with a variable { - u8 timerVal = gBattleStruct->startingStatusTimer; - gBattleScripting.battler = battler; switch (gBattleStruct->startingStatus) { case STARTING_STATUS_ELECTRIC_TERRAIN: - if (!(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC; - gFieldStatuses |= STATUS_FIELD_ELECTRIC_TERRAIN; - if (timerVal == 0) - gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT; - else - gFieldTimers.terrainTimer = timerVal; - effect = 2; - } + effect = SetStartingFieldStatus(STATUS_FIELD_ELECTRIC_TERRAIN, + B_MSG_TERRAIN_SET_ELECTRIC, + 0, + &gFieldTimers.terrainTimer); + effect = (effect == 1) ? 2 : 0; break; case STARTING_STATUS_MISTY_TERRAIN: - if (!(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY; - gFieldStatuses |= STATUS_FIELD_MISTY_TERRAIN; - if (timerVal == 0) - gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT; - else - gFieldTimers.terrainTimer = timerVal; - effect = 2; - } + effect = SetStartingFieldStatus(STATUS_FIELD_MISTY_TERRAIN, + B_MSG_TERRAIN_SET_MISTY, + 0, + &gFieldTimers.terrainTimer); + effect = (effect == 1) ? 2 : 0; break; case STARTING_STATUS_GRASSY_TERRAIN: - if (!(gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_GRASSY; - gFieldStatuses |= STATUS_FIELD_GRASSY_TERRAIN; - if (timerVal == 0) - gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT; - else - gFieldTimers.terrainTimer = timerVal; - effect = 2; - } + effect = SetStartingFieldStatus(STATUS_FIELD_GRASSY_TERRAIN, + B_MSG_TERRAIN_SET_GRASSY, + 0, + &gFieldTimers.terrainTimer); + effect = (effect == 1) ? 2 : 0; break; case STARTING_STATUS_PSYCHIC_TERRAIN: - if (!(gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC; - gFieldStatuses |= STATUS_FIELD_PSYCHIC_TERRAIN; - if (timerVal == 0) - gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT; - else - gFieldTimers.terrainTimer = timerVal; - effect = 2; - } + effect = SetStartingFieldStatus(STATUS_FIELD_PSYCHIC_TERRAIN, + B_MSG_TERRAIN_SET_PSYCHIC, + 0, + &gFieldTimers.terrainTimer); + effect = (effect == 1) ? 2 : 0; break; case STARTING_STATUS_TRICK_ROOM: - if (!(gFieldStatuses & STATUS_FIELD_TRICK_ROOM)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_TRICK_ROOM; - gFieldStatuses |= STATUS_FIELD_TRICK_ROOM; - gBattleScripting.animArg1 = B_ANIM_TRICK_ROOM; - if (timerVal == 0) - gFieldTimers.trickRoomTimer = 0; // infinite - else - gFieldTimers.trickRoomTimer = 5; - effect = 1; - } + effect = SetStartingFieldStatus(STATUS_FIELD_TRICK_ROOM, + B_MSG_SET_TRICK_ROOM, + B_ANIM_TRICK_ROOM, + &gFieldTimers.trickRoomTimer); break; case STARTING_STATUS_MAGIC_ROOM: - if (!(gFieldStatuses & STATUS_FIELD_MAGIC_ROOM)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_MAGIC_ROOM; - gFieldStatuses |= STATUS_FIELD_MAGIC_ROOM; - gBattleScripting.animArg1 = B_ANIM_MAGIC_ROOM; - if (timerVal == 0) - gFieldTimers.magicRoomTimer = 0; // infinite - else - gFieldTimers.magicRoomTimer = 5; - effect = 1; - } + effect = SetStartingFieldStatus(STATUS_FIELD_MAGIC_ROOM, + B_MSG_SET_MAGIC_ROOM, + B_ANIM_MAGIC_ROOM, + &gFieldTimers.magicRoomTimer); break; case STARTING_STATUS_WONDER_ROOM: - if (!(gFieldStatuses & STATUS_FIELD_WONDER_ROOM)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_WONDER_ROOM; - gFieldStatuses |= STATUS_FIELD_WONDER_ROOM; - gBattleScripting.animArg1 = B_ANIM_WONDER_ROOM; - if (timerVal == 0) - gFieldTimers.wonderRoomTimer = 0; // infinite - else - gFieldTimers.wonderRoomTimer = 5; - effect = 1; - } + effect = SetStartingFieldStatus(STATUS_FIELD_WONDER_ROOM, + B_MSG_SET_WONDER_ROOM, + B_ANIM_WONDER_ROOM, + &gFieldTimers.wonderRoomTimer); break; case STARTING_STATUS_TAILWIND_PLAYER: - if (!(gSideStatuses[B_SIDE_PLAYER] & SIDE_STATUS_TAILWIND)) - { - gBattlerAttacker = B_POSITION_PLAYER_LEFT; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_TAILWIND_PLAYER; - gSideStatuses[B_SIDE_PLAYER] |= SIDE_STATUS_TAILWIND; - gBattleScripting.animArg1 = B_ANIM_TAILWIND; - if (timerVal == 0) - gSideTimers[B_SIDE_PLAYER].tailwindTimer = 0; // infinite - else - gSideTimers[B_SIDE_PLAYER].tailwindTimer = 5; - effect = 1; - } + effect = SetStartingSideStatus(SIDE_STATUS_TAILWIND, + B_SIDE_PLAYER, + B_MSG_SET_TAILWIND, + B_ANIM_TAILWIND, + &gSideTimers[B_SIDE_PLAYER].tailwindTimer); break; case STARTING_STATUS_TAILWIND_OPPONENT: - if (!(gSideStatuses[B_SIDE_OPPONENT] & SIDE_STATUS_TAILWIND)) - { - gBattlerAttacker = B_POSITION_OPPONENT_LEFT; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_TAILWIND_OPPONENT; - gSideStatuses[B_SIDE_OPPONENT] |= SIDE_STATUS_TAILWIND; - gBattleScripting.animArg1 = B_ANIM_TAILWIND; - if (timerVal == 0) - gSideTimers[B_SIDE_OPPONENT].tailwindTimer = 0; // infinite - else - gSideTimers[B_SIDE_OPPONENT].tailwindTimer = 5; - effect = 1; - } + effect = SetStartingSideStatus(SIDE_STATUS_TAILWIND, + B_SIDE_OPPONENT, + B_MSG_SET_TAILWIND, + B_ANIM_TAILWIND, + &gSideTimers[B_SIDE_OPPONENT].tailwindTimer); + break; + case STARTING_STATUS_RAINBOW_PLAYER: + effect = SetStartingSideStatus(SIDE_STATUS_RAINBOW, + B_SIDE_PLAYER, + B_MSG_SET_RAINBOW, + B_ANIM_RAINBOW, + &gSideTimers[B_SIDE_PLAYER].rainbowTimer); + break; + case STARTING_STATUS_RAINBOW_OPPONENT: + effect = SetStartingSideStatus(SIDE_STATUS_RAINBOW, + B_SIDE_OPPONENT, + B_MSG_SET_RAINBOW, + B_ANIM_RAINBOW, + &gSideTimers[B_SIDE_OPPONENT].rainbowTimer); + break; + case STARTING_STATUS_SEA_OF_FIRE_PLAYER: + effect = SetStartingSideStatus(SIDE_STATUS_SEA_OF_FIRE, + B_SIDE_PLAYER, + B_MSG_SET_SEA_OF_FIRE, + B_ANIM_SEA_OF_FIRE, + &gSideTimers[B_SIDE_PLAYER].seaOfFireTimer); + break; + case STARTING_STATUS_SEA_OF_FIRE_OPPONENT: + effect = SetStartingSideStatus(SIDE_STATUS_SEA_OF_FIRE, + B_SIDE_OPPONENT, + B_MSG_SET_SEA_OF_FIRE, + B_ANIM_SEA_OF_FIRE, + &gSideTimers[B_SIDE_OPPONENT].seaOfFireTimer); + break; + case STARTING_STATUS_SWAMP_PLAYER: + effect = SetStartingSideStatus(SIDE_STATUS_SWAMP, + B_SIDE_PLAYER, + B_MSG_SET_SWAMP, + B_ANIM_SWAMP, + &gSideTimers[B_SIDE_PLAYER].swampTimer); + break; + case STARTING_STATUS_SWAMP_OPPONENT: + effect = SetStartingSideStatus(SIDE_STATUS_SWAMP, + B_SIDE_OPPONENT, + B_MSG_SET_SWAMP, + B_ANIM_SWAMP, + &gSideTimers[B_SIDE_OPPONENT].swampTimer); break; } @@ -4493,7 +4515,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && GetCurrentWeather() == WEATHER_RAIN_THUNDERSTORM) { // overworld weather started rain, so just do electric terrain anim - gFieldStatuses = (STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); + gFieldStatuses = STATUS_FIELD_ELECTRIC_TERRAIN; + gFieldTimers.terrainTimer = 0; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC; BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); effect++; @@ -4502,7 +4525,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && (GetCurrentWeather() == WEATHER_FOG_HORIZONTAL || GetCurrentWeather() == WEATHER_FOG_DIAGONAL) && !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)) { - gFieldStatuses = (STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); + gFieldStatuses = STATUS_FIELD_MISTY_TERRAIN; + gFieldTimers.terrainTimer = 0; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY; BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); effect++;