diff --git a/include/text_options_strings.h.in b/include/text_options_strings.h.in index a1ce481f2c..10f2b99bcc 100644 --- a/include/text_options_strings.h.in +++ b/include/text_options_strings.h.in @@ -84,6 +84,7 @@ #define TEXT_OPT_CHEAT7 _("EXIT COURSE AT ANY TIME") #define TEXT_OPT_CHEAT8 _("HUGE MARIO") #define TEXT_OPT_CHEAT9 _("TINY MARIO") +#define TEXT_OPT_CHEAT10 _("LEVEL RESET (PRESS L)") #else // VERSION @@ -148,6 +149,7 @@ #define TEXT_OPT_CHEAT7 _("Exit course at any time") #define TEXT_OPT_CHEAT8 _("Huge Mario") #define TEXT_OPT_CHEAT9 _("Tiny Mario") +#define TEXT_OPT_CHEAT10 _("Level Reset (Press L)") #endif // VERSION diff --git a/src/game/mario.c b/src/game/mario.c index 5f8e5114ef..1125ae1f7f 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1421,6 +1421,19 @@ void update_mario_inputs(struct MarioState *m) { } /*End of moonjump cheat */ + /* Level reset cheat */ + if (Cheats.LevelReset + && Cheats.EnableCheats + && m->controller->buttonDown & L_TRIG + // Prevent crashing if there's no warp destination + && sWarpDest.areaIdx != 0) { + m->health = 0x880; + m->numCoins = 0; + gHudDisplay.coins = 0; + sWarpDest.type = 2; + } + /* End of level reset cheat */ + if (gCameraMovementFlags & CAM_MOVE_C_UP_MODE) { if (m->action & ACT_FLAG_ALLOW_FIRST_PERSON) { m->input |= INPUT_FIRST_PERSON; diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index 7113e7c816..6150351a0a 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -19,6 +19,7 @@ #include "platform_displacement.h" #include "profiler.h" #include "spawn_object.h" +#include "pc/cheats.h" /** @@ -409,6 +410,18 @@ void set_object_respawn_info_bits(struct Object *obj, u8 bits) { u32 *info32; u16 *info16; + /* Level reset cheat */ + /* + * Force objects to respawn on level reset + * + * NOTE: This forces objects to respawn in cases where they wouldn't with + * the cheat disabled. The GameShark code also has this problem. + */ + if (Cheats.LevelReset && Cheats.EnableCheats) { + return; + } + /* End of level reset cheat */ + switch (obj->respawnInfoType) { case RESPAWN_INFO_TYPE_32: info32 = (u32 *) obj->respawnInfo; diff --git a/src/game/options_menu.c b/src/game/options_menu.c index 56dba619e3..6a3fd0442c 100644 --- a/src/game/options_menu.c +++ b/src/game/options_menu.c @@ -102,6 +102,7 @@ static const u8 optsCheatsStr[][64] = { { TEXT_OPT_CHEAT7 }, { TEXT_OPT_CHEAT8 }, { TEXT_OPT_CHEAT9 }, + { TEXT_OPT_CHEAT10 }, }; static const u8 bindStr[][32] = { @@ -279,6 +280,7 @@ static struct Option optsCheats[] = { DEF_OPT_TOGGLE( optsCheatsStr[6], &Cheats.ExitAnywhere ), DEF_OPT_TOGGLE( optsCheatsStr[7], &Cheats.HugeMario ), DEF_OPT_TOGGLE( optsCheatsStr[8], &Cheats.TinyMario ), + DEF_OPT_TOGGLE( optsCheatsStr[9], &Cheats.LevelReset ), }; diff --git a/src/pc/cheats.h b/src/pc/cheats.h index eaf71ab4b0..01b567b571 100644 --- a/src/pc/cheats.h +++ b/src/pc/cheats.h @@ -13,6 +13,7 @@ struct CheatList { bool ExitAnywhere; bool HugeMario; bool TinyMario; + bool LevelReset; }; extern struct CheatList Cheats;