From 050b47b411293bb7842edd4323e263963b9c517a Mon Sep 17 00:00:00 2001 From: PSF Date: Sun, 14 Aug 2022 12:59:12 -0700 Subject: [PATCH 1/2] Added a new trainer battle type which does not warp the player after they white out, but instead continues the script. --- asm/macros/event.inc | 6 ++++++ include/constants/battle_setup.h | 1 + src/battle_setup.c | 12 +++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/asm/macros/event.inc b/asm/macros/event.inc index 661e675c9..94563acc9 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -699,6 +699,8 @@ .4byte \pointer3 @ event script .elseif \type == TRAINER_BATTLE_SINGLE_NO_INTRO_TEXT .4byte \pointer1 @ text + .elseif \type == TRAINER_BATTLE_CONTINUE_AFTER_LOSE + .4byte \pointer1 @ text .elseif \type == TRAINER_BATTLE_DOUBLE .4byte \pointer1 @ text .4byte \pointer2 @ text @@ -776,6 +778,10 @@ trainerbattle TRAINER_BATTLE_SINGLE_NO_INTRO_TEXT, \trainer, 0, \lose_text .endm + @ Starts a trainer battle, skipping intro text. Returns the overworld if the player loses or wins. Takes a trainer and loss text + .macro trainerbattle_continue_after_lose trainer:req, lose_text:req + trainerbattle TRAINER_BATTLE_CONTINUE_AFTER_LOSE, \trainer, 0, \lose_text + .endm @ Starts a trainer battle using the battle information stored in RAM (usually by the scripts in trainer_battle.inc, which @ are run by trainerbattle), and blocks script execution until the battle finishes. diff --git a/include/constants/battle_setup.h b/include/constants/battle_setup.h index d825c88bc..5c87f15bb 100644 --- a/include/constants/battle_setup.h +++ b/include/constants/battle_setup.h @@ -14,5 +14,6 @@ #define TRAINER_BATTLE_SET_TRAINER_A 10 #define TRAINER_BATTLE_SET_TRAINER_B 11 #define TRAINER_BATTLE_HILL 12 +#define TRAINER_BATTLE_CONTINUE_AFTER_LOSE 13 #endif // GUARD_CONSTANTS_BATTLE_SETUP_H diff --git a/src/battle_setup.c b/src/battle_setup.c index da51a7be6..99a8f13c7 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -83,6 +83,7 @@ static void TryUpdateGymLeaderRematchFromTrainer(void); static void CB2_GiveStarter(void); static void CB2_StartFirstBattle(void); static void CB2_EndFirstBattle(void); +static bool8 ShouldContinueAfterLose(void); static void CB2_EndTrainerBattle(void); static bool32 IsPlayerDefeated(u32 battleOutcome); static u16 GetRematchTrainerId(u16 trainerId); @@ -1107,6 +1108,7 @@ const u8 *BattleSetup_ConfigureTrainerBattle(const u8 *data) switch (sTrainerBattleMode) { case TRAINER_BATTLE_SINGLE_NO_INTRO_TEXT: + case TRAINER_BATTLE_CONTINUE_AFTER_LOSE: TrainerBattleLoadArgs(sOrdinaryNoIntroBattleParams, data); return EventScript_DoNoIntroTrainerBattle; case TRAINER_BATTLE_DOUBLE: @@ -1323,6 +1325,14 @@ void BattleSetup_StartTrainerBattle(void) ScriptContext1_Stop(); } +static bool8 ShouldContinueAfterLose() +{ + if (sTrainerBattleMode == TRAINER_BATTLE_CONTINUE_AFTER_LOSE) + return TRUE; + else + return FALSE; +} + static void CB2_EndTrainerBattle(void) { if (gTrainerBattleOpponent_A == TRAINER_SECRET_BASE) @@ -1331,7 +1341,7 @@ static void CB2_EndTrainerBattle(void) } else if (IsPlayerDefeated(gBattleOutcome) == TRUE) { - if (InBattlePyramid() || InTrainerHillChallenge()) + if (InBattlePyramid() || InTrainerHillChallenge() || ShouldContinueAfterLose()) SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); else SetMainCallback2(CB2_WhiteOut); From 9b94187f37cb6fec97043c9aae056dd3a93b198e Mon Sep 17 00:00:00 2001 From: PSF Date: Mon, 15 Aug 2022 16:45:42 -0700 Subject: [PATCH 2/2] Added trainerbattle_no_whiteout_continue and added new whiteout text --- asm/macros/event.inc | 20 ++++++++++---- data/battle_scripts_1.s | 7 +++++ include/constants/battle_setup.h | 3 ++- include/constants/battle_string_ids.h | 3 ++- src/battle_message.c | 2 ++ src/battle_setup.c | 39 ++++++++++++++------------- 6 files changed, 48 insertions(+), 26 deletions(-) diff --git a/asm/macros/event.inc b/asm/macros/event.inc index 94563acc9..726abfbd0 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -699,8 +699,6 @@ .4byte \pointer3 @ event script .elseif \type == TRAINER_BATTLE_SINGLE_NO_INTRO_TEXT .4byte \pointer1 @ text - .elseif \type == TRAINER_BATTLE_CONTINUE_AFTER_LOSE - .4byte \pointer1 @ text .elseif \type == TRAINER_BATTLE_DOUBLE .4byte \pointer1 @ text .4byte \pointer2 @ text @@ -734,6 +732,12 @@ .elseif \type == TRAINER_BATTLE_HILL .4byte \pointer1 @ text .4byte \pointer2 @ text + .elseif \type == TRAINER_BATTLE_NO_WHITEOUT_CONTINUE_SCRIPT + .4byte \pointer1 @ text + .4byte \pointer2 @ text + .4byte \pointer3 @ event script + .elseif \type == TRAINER_BATTLE_NO_INTRO_NO_WHITEOUT + .4byte \pointer1 @ text .endif .endm @@ -778,9 +782,15 @@ trainerbattle TRAINER_BATTLE_SINGLE_NO_INTRO_TEXT, \trainer, 0, \lose_text .endm - @ Starts a trainer battle, skipping intro text. Returns the overworld if the player loses or wins. Takes a trainer and loss text - .macro trainerbattle_continue_after_lose trainer:req, lose_text:req - trainerbattle TRAINER_BATTLE_CONTINUE_AFTER_LOSE, \trainer, 0, \lose_text + @ Starts a single trainer battle. Takes a trainer, intro text, loss text, and an event script which continues after the battle,regardless of the result. + @ When used with an event script, you can also pass in an optional flag to disable music + .macro trainerbattle_no_whiteout_continue_script trainer:req, intro_text:req, lose_text:req, event_script:req + trainerbattle TRAINER_BATTLE_NO_WHITEOUT_CONTINUE_SCRIPT, \trainer, 0, \intro_text, \lose_text, \event_script + .endm + + @ Starts a trainer battle, skipping intro text. Takes a trainer and loss text. Does not warp the player to last heal location if they lose. + .macro trainerbattle_no_intro_no_whiteout trainer:req, lose_text:req + trainerbattle TRAINER_BATTLE_NO_INTRO_NO_WHITEOUT, \trainer, 0, \lose_text .endm @ Starts a trainer battle using the battle information stored in RAM (usually by the scripts in trainer_battle.inc, which diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 880957859..681178cef 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3,6 +3,7 @@ #include "constants/pokemon.h" #include "constants/battle_script_commands.h" #include "constants/battle_anim.h" +#include "constants/battle_setup.h" #include "constants/battle_string_ids.h" #include "constants/abilities.h" #include "constants/moves.h" @@ -2950,10 +2951,16 @@ BattleScript_LocalBattleLost:: BattleScript_LocalBattleLostPrintWhiteOut:: printstring STRINGID_PLAYERWHITEOUT waitmessage B_WAIT_TIME_LONG + jumpifhalfword CMP_EQUAL, gTrainerBattleMode, TRAINER_BATTLE_NO_WHITEOUT_CONTINUE_SCRIPT, BattleScript_LocalBattleLostPrintNoWhiteout + jumpifhalfword CMP_EQUAL, gTrainerBattleMode, TRAINER_BATTLE_NO_INTRO_NO_WHITEOUT, BattleScript_LocalBattleLostPrintNoWhiteout printstring STRINGID_PLAYERWHITEOUT2 waitmessage B_WAIT_TIME_LONG BattleScript_LocalBattleLostEnd:: end2 +BattleScript_LocalBattleLostPrintNoWhiteout:: + printstring STRINGID_PLAYERWHITEOUT3 + waitmessage B_WAIT_TIME_LONG + end2 BattleScript_CheckDomeDrew:: jumpifbyte CMP_EQUAL, gBattleOutcome, B_OUTCOME_DREW, BattleScript_LocalBattleLostEnd_ BattleScript_LocalBattleLostPrintTrainersWinText:: diff --git a/include/constants/battle_setup.h b/include/constants/battle_setup.h index 5c87f15bb..e07645ebb 100644 --- a/include/constants/battle_setup.h +++ b/include/constants/battle_setup.h @@ -14,6 +14,7 @@ #define TRAINER_BATTLE_SET_TRAINER_A 10 #define TRAINER_BATTLE_SET_TRAINER_B 11 #define TRAINER_BATTLE_HILL 12 -#define TRAINER_BATTLE_CONTINUE_AFTER_LOSE 13 +#define TRAINER_BATTLE_NO_WHITEOUT_CONTINUE_SCRIPT 13 +#define TRAINER_BATTLE_NO_INTRO_NO_WHITEOUT 14 #endif // GUARD_CONSTANTS_BATTLE_SETUP_H diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index ae18b61ef..fb1c575f9 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -378,8 +378,9 @@ #define STRINGID_PKMNBOXLANETTESPCFULL 378 #define STRINGID_TRAINER1WINTEXT 379 #define STRINGID_TRAINER2WINTEXT 380 +#define STRINGID_PLAYERWHITEOUT3 381 -#define BATTLESTRINGS_COUNT 381 +#define BATTLESTRINGS_COUNT 382 // This is the string id that gBattleStringsTable starts with. // String ids before this (e.g. STRINGID_INTROMSG) are not in the table, diff --git a/src/battle_message.c b/src/battle_message.c index 677bb2fe3..f7d5478c2 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -76,6 +76,7 @@ static const u8 sText_TargetFainted[] = _("{B_DEF_NAME_WITH_PREFIX}\nfainted!\p" static const u8 sText_PlayerGotMoney[] = _("{B_PLAYER_NAME} got ¥{B_BUFF1}\nfor winning!\p"); static const u8 sText_PlayerWhiteout[] = _("{B_PLAYER_NAME} is out of\nusable POKéMON!\p"); static const u8 sText_PlayerWhiteout2[] = _("{B_PLAYER_NAME} whited out!{PAUSE_UNTIL_PRESS}"); +static const u8 sText_PlayerWhiteout3[] = _("{B_PLAYER_NAME} lost the battle!{PAUSE_UNTIL_PRESS}"); static const u8 sText_PreventsEscape[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} prevents\nescape with {B_SCR_ACTIVE_ABILITY}!\p"); static const u8 sText_CantEscape2[] = _("Can't escape!\p"); static const u8 sText_AttackerCantEscape[] = _("{B_ATK_NAME_WITH_PREFIX} can't escape!"); @@ -537,6 +538,7 @@ const u8 * const gBattleStringsTable[BATTLESTRINGS_COUNT - BATTLESTRINGS_TABLE_S [STRINGID_PLAYERGOTMONEY - BATTLESTRINGS_TABLE_START] = sText_PlayerGotMoney, [STRINGID_PLAYERWHITEOUT - BATTLESTRINGS_TABLE_START] = sText_PlayerWhiteout, [STRINGID_PLAYERWHITEOUT2 - BATTLESTRINGS_TABLE_START] = sText_PlayerWhiteout2, + [STRINGID_PLAYERWHITEOUT3 - BATTLESTRINGS_TABLE_START] = sText_PlayerWhiteout3, [STRINGID_PREVENTSESCAPE - BATTLESTRINGS_TABLE_START] = sText_PreventsEscape, [STRINGID_HITXTIMES - BATTLESTRINGS_TABLE_START] = sText_HitXTimes, [STRINGID_PKMNFELLASLEEP - BATTLESTRINGS_TABLE_START] = sText_PkmnFellAsleep, diff --git a/src/battle_setup.c b/src/battle_setup.c index 99a8f13c7..1ed187b69 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -83,7 +83,7 @@ static void TryUpdateGymLeaderRematchFromTrainer(void); static void CB2_GiveStarter(void); static void CB2_StartFirstBattle(void); static void CB2_EndFirstBattle(void); -static bool8 ShouldContinueAfterLose(void); +static bool8 BattleHasNoWhiteout(void); static void CB2_EndTrainerBattle(void); static bool32 IsPlayerDefeated(u32 battleOutcome); static u16 GetRematchTrainerId(u16 trainerId); @@ -92,7 +92,7 @@ static void HandleRematchVarsOnBattleEnd(void); static const u8 *GetIntroSpeechOfApproachingTrainer(void); static const u8 *GetTrainerCantBattleSpeech(void); -EWRAM_DATA static u16 sTrainerBattleMode = 0; +EWRAM_DATA u16 gTrainerBattleMode = 0; EWRAM_DATA u16 gTrainerBattleOpponent_A = 0; EWRAM_DATA u16 gTrainerBattleOpponent_B = 0; EWRAM_DATA u16 gPartnerTrainerId = 0; @@ -161,7 +161,7 @@ static const u8 sBattleTransitionTable_BattleDome[] = static const struct TrainerBattleParameter sOrdinaryBattleParams[] = { - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, {&gTrainerBattleOpponent_A, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerObjectEventLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerAIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, @@ -174,7 +174,7 @@ static const struct TrainerBattleParameter sOrdinaryBattleParams[] = static const struct TrainerBattleParameter sContinueScriptBattleParams[] = { - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, {&gTrainerBattleOpponent_A, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerObjectEventLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerAIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, @@ -187,7 +187,7 @@ static const struct TrainerBattleParameter sContinueScriptBattleParams[] = static const struct TrainerBattleParameter sDoubleBattleParams[] = { - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, {&gTrainerBattleOpponent_A, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerObjectEventLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerAIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, @@ -200,7 +200,7 @@ static const struct TrainerBattleParameter sDoubleBattleParams[] = static const struct TrainerBattleParameter sOrdinaryNoIntroBattleParams[] = { - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, {&gTrainerBattleOpponent_A, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerObjectEventLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerAIntroSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, @@ -213,7 +213,7 @@ static const struct TrainerBattleParameter sOrdinaryNoIntroBattleParams[] = static const struct TrainerBattleParameter sContinueScriptDoubleBattleParams[] = { - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, {&gTrainerBattleOpponent_A, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerObjectEventLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerAIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, @@ -226,7 +226,7 @@ static const struct TrainerBattleParameter sContinueScriptDoubleBattleParams[] = static const struct TrainerBattleParameter sTrainerBOrdinaryBattleParams[] = { - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, {&gTrainerBattleOpponent_B, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerObjectEventLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerBIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, @@ -239,7 +239,7 @@ static const struct TrainerBattleParameter sTrainerBOrdinaryBattleParams[] = static const struct TrainerBattleParameter sTrainerBContinueScriptBattleParams[] = { - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, {&gTrainerBattleOpponent_B, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerObjectEventLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, {&sTrainerBIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, @@ -1017,7 +1017,7 @@ void ResetTrainerOpponentIds(void) static void InitTrainerBattleVariables(void) { - sTrainerBattleMode = 0; + gTrainerBattleMode = 0; if (gApproachingTrainerId == 0) { sTrainerAIntroSpeech = NULL; @@ -1103,12 +1103,12 @@ void SetMapVarsToTrainer(void) const u8 *BattleSetup_ConfigureTrainerBattle(const u8 *data) { InitTrainerBattleVariables(); - sTrainerBattleMode = TrainerBattleLoadArg8(data); + gTrainerBattleMode = TrainerBattleLoadArg8(data); - switch (sTrainerBattleMode) + switch (gTrainerBattleMode) { case TRAINER_BATTLE_SINGLE_NO_INTRO_TEXT: - case TRAINER_BATTLE_CONTINUE_AFTER_LOSE: + case TRAINER_BATTLE_NO_INTRO_NO_WHITEOUT: TrainerBattleLoadArgs(sOrdinaryNoIntroBattleParams, data); return EventScript_DoNoIntroTrainerBattle; case TRAINER_BATTLE_DOUBLE: @@ -1116,6 +1116,7 @@ const u8 *BattleSetup_ConfigureTrainerBattle(const u8 *data) SetMapVarsToTrainer(); return EventScript_TryDoDoubleTrainerBattle; case TRAINER_BATTLE_CONTINUE_SCRIPT: + case TRAINER_BATTLE_NO_WHITEOUT_CONTINUE_SCRIPT: if (gApproachingTrainerId == 0) { TrainerBattleLoadArgs(sContinueScriptBattleParams, data); @@ -1230,7 +1231,7 @@ void SetTrainerFacingDirection(void) u8 GetTrainerBattleMode(void) { - return sTrainerBattleMode; + return gTrainerBattleMode; } bool8 GetTrainerFlag(void) @@ -1325,9 +1326,9 @@ void BattleSetup_StartTrainerBattle(void) ScriptContext1_Stop(); } -static bool8 ShouldContinueAfterLose() +static bool8 BattleHasNoWhiteout() { - if (sTrainerBattleMode == TRAINER_BATTLE_CONTINUE_AFTER_LOSE) + if (gTrainerBattleMode == TRAINER_BATTLE_NO_WHITEOUT_CONTINUE_SCRIPT || gTrainerBattleMode == TRAINER_BATTLE_NO_INTRO_NO_WHITEOUT) return TRUE; else return FALSE; @@ -1341,7 +1342,7 @@ static void CB2_EndTrainerBattle(void) } else if (IsPlayerDefeated(gBattleOutcome) == TRUE) { - if (InBattlePyramid() || InTrainerHillChallenge() || ShouldContinueAfterLose()) + if (InBattlePyramid() || InTrainerHillChallenge() || BattleHasNoWhiteout()) SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); else SetMainCallback2(CB2_WhiteOut); @@ -1456,8 +1457,8 @@ void PlayTrainerEncounterMusic(void) else trainerId = gTrainerBattleOpponent_B; - if (sTrainerBattleMode != TRAINER_BATTLE_CONTINUE_SCRIPT_NO_MUSIC - && sTrainerBattleMode != TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE_NO_MUSIC) + if (gTrainerBattleMode != TRAINER_BATTLE_CONTINUE_SCRIPT_NO_MUSIC + && gTrainerBattleMode != TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE_NO_MUSIC) { switch (GetTrainerEncounterMusicId(trainerId)) {