summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorballoondude2 <55861555+balloondude2@users.noreply.github.com>2024-08-05 13:12:08 -0600
committerGitHub <noreply@github.com>2024-08-05 15:12:08 -0400
commitd0caa0f78c8f17123007691e040700f29cfbcc1c (patch)
treead51f08828390ee734d5b64a18d51df338667c07
parent51af06463f536baae615289398469ed00c38e2d7 (diff)
[Cheat] Stop time in Temples and Dungeons (#700)
* add cheat to stop time in temples * better tooltip * adds option to stop time in dungeons * clean up * add other pirate fortress scenes * add new hook * update tooltips * rename hook * add clarification Co-authored-by: Archez <Archez@users.noreply.github.com> * clean combobox --------- Co-authored-by: Archez <Archez@users.noreply.github.com>
-rw-r--r--mm/2s2h/BenGui/BenMenuBar.cpp14
-rw-r--r--mm/2s2h/Enhancements/Cheats/TimeStop.cpp65
-rw-r--r--mm/2s2h/Enhancements/Cheats/TimeStop.h6
-rw-r--r--mm/2s2h/Enhancements/Enhancements.cpp1
-rw-r--r--mm/2s2h/Enhancements/Enhancements.h7
-rw-r--r--mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp7
-rw-r--r--mm/2s2h/Enhancements/GameInteractor/GameInteractor.h2
-rw-r--r--mm/2s2h/z_play_2SH.cpp4
8 files changed, 106 insertions, 0 deletions
diff --git a/mm/2s2h/BenGui/BenMenuBar.cpp b/mm/2s2h/BenGui/BenMenuBar.cpp
index edf218909..ba2b746e0 100644
--- a/mm/2s2h/BenGui/BenMenuBar.cpp
+++ b/mm/2s2h/BenGui/BenMenuBar.cpp
@@ -57,6 +57,12 @@ static const std::unordered_map<int32_t, const char*> alwaysWinDoggyraceOptions
{ ALWAYS_WIN_DOGGY_RACE_ALWAYS, "Always" },
};
+static const std::unordered_map<int32_t, const char*> timeStopOptions = {
+ { TIME_STOP_OFF, "Off" },
+ { TIME_STOP_TEMPLES, "Temples" },
+ { TIME_STOP_TEMPLES_DUNGEONS, "Temples + Mini Dungeons" },
+};
+
namespace BenGui {
std::shared_ptr<std::vector<Ship::WindowBackend>> availableWindowBackends;
std::unordered_map<Ship::WindowBackend, const char*> availableWindowBackendsMap;
@@ -678,6 +684,14 @@ void DrawCheatsMenu() {
{ .tooltip = "Holding L makes you float into the air" })) {
RegisterMoonJumpOnL();
}
+ UIWidgets::CVarCombobox(
+ "Stop Time in Dungeons", "gCheats.TempleTimeStop", timeStopOptions,
+ { .tooltip = "Stops time from advancing in selected areas. Requires a room change to update.\n\n"
+ "- Off: Vanilla behaviour.\n"
+ "- Temples: Stops time in Woodfall, Snowhead, Great Bay, and Stone Tower Temples.\n"
+ "- Temples + Mini Dungeons: In addition to the above temples, stops time in both Spider "
+ "Houses, Pirate's Fortress, Beneath the Well, Ancient Castle of Ikana, and Secret Shrine.",
+ .defaultIndex = TIME_STOP_OFF });
ImGui::EndMenu();
}
diff --git a/mm/2s2h/Enhancements/Cheats/TimeStop.cpp b/mm/2s2h/Enhancements/Cheats/TimeStop.cpp
new file mode 100644
index 000000000..fb12fc0b5
--- /dev/null
+++ b/mm/2s2h/Enhancements/Cheats/TimeStop.cpp
@@ -0,0 +1,65 @@
+#include <libultraship/libultraship.h>
+#include "BenPort.h"
+#include "Enhancements/GameInteractor/GameInteractor.h"
+#include "Enhancements/Enhancements.h"
+
+extern "C" {
+#include <variables.h>
+#include <functions.h>
+}
+
+void RegisterTimeStopInTemples() {
+ GameInteractor::Instance->RegisterGameHook<GameInteractor::AfterRoomSceneCommands>([](s16 sceneId, s8 roomNum) {
+ uint8_t selectedOption = CVarGetInteger("gCheats.TempleTimeStop", TIME_STOP_OFF);
+
+ switch (selectedOption) {
+ case TIME_STOP_TEMPLES_DUNGEONS:
+ switch (gPlayState->sceneId) {
+ // Swamp + Ocean Spider House
+ case SCENE_KINSTA1:
+ case SCENE_KINDAN2:
+ // Pirates' Fortress
+ case SCENE_KAIZOKU:
+ case SCENE_PIRATE:
+ case SCENE_TORIDE:
+ // Beneath the Well
+ case SCENE_REDEAD:
+ // Ancient Castle of Ikana + Igos's Lair
+ case SCENE_CASTLE:
+ case SCENE_IKNINSIDE:
+ // Secret Shrine
+ case SCENE_RANDOM:
+ R_TIME_SPEED = 0;
+ break;
+ default:
+ break;
+ }
+ // fallthrough
+ case TIME_STOP_TEMPLES:
+ switch (gPlayState->sceneId) {
+ // Woodfall Temple + Odolwa
+ case SCENE_MITURIN:
+ case SCENE_MITURIN_BS:
+ // Snowhead Temple + Goht
+ case SCENE_HAKUGIN:
+ case SCENE_HAKUGIN_BS:
+ // Great Bay Temple + Gyorg
+ case SCENE_SEA:
+ case SCENE_SEA_BS:
+ // Stone Tower Temple (+ inverted) + Twinmold
+ case SCENE_INISIE_N:
+ case SCENE_INISIE_R:
+ case SCENE_INISIE_BS:
+ R_TIME_SPEED = 0;
+ break;
+ default:
+ break;
+ }
+ break;
+ case TIME_STOP_OFF:
+ break;
+ default:
+ break;
+ }
+ });
+}
diff --git a/mm/2s2h/Enhancements/Cheats/TimeStop.h b/mm/2s2h/Enhancements/Cheats/TimeStop.h
new file mode 100644
index 000000000..a2729fe2d
--- /dev/null
+++ b/mm/2s2h/Enhancements/Cheats/TimeStop.h
@@ -0,0 +1,6 @@
+#ifndef CHEATS_TIME_STOPS_H
+#define CHEATS_TIME_STOPS_H
+
+void RegisterTimeStopInTemples();
+
+#endif // CHEATS_TIME_STOPS_H \ No newline at end of file
diff --git a/mm/2s2h/Enhancements/Enhancements.cpp b/mm/2s2h/Enhancements/Enhancements.cpp
index a5163d2aa..0f0867f8a 100644
--- a/mm/2s2h/Enhancements/Enhancements.cpp
+++ b/mm/2s2h/Enhancements/Enhancements.cpp
@@ -12,6 +12,7 @@ void InitEnhancements() {
RegisterMoonJumpOnL();
RegisterUnbreakableRazorSword();
RegisterUnrestrictedItems();
+ RegisterTimeStopInTemples();
// Clock
RegisterTextBasedClock();
diff --git a/mm/2s2h/Enhancements/Enhancements.h b/mm/2s2h/Enhancements/Enhancements.h
index 4d6dd518d..dbdc7364a 100644
--- a/mm/2s2h/Enhancements/Enhancements.h
+++ b/mm/2s2h/Enhancements/Enhancements.h
@@ -11,6 +11,7 @@
#include "Cheats/Cheats.h"
#include "Cheats/UnbreakableRazorSword.h"
#include "Cheats/UnrestrictedItems.h"
+#include "Cheats/TimeStop.h"
#include "Cycle/EndOfCycle.h"
#include "Equipment/SkipMagicArrowEquip.h"
#include "Masks/BlastMaskKeg.h"
@@ -37,6 +38,12 @@ enum AlwaysWinDoggyRaceOptions {
ALWAYS_WIN_DOGGY_RACE_ALWAYS,
};
+enum TimeStopOptions {
+ TIME_STOP_OFF,
+ TIME_STOP_TEMPLES,
+ TIME_STOP_TEMPLES_DUNGEONS,
+};
+
enum ClockTypeOptions {
CLOCK_TYPE_ORIGINAL,
CLOCK_TYPE_TEXT_BASED,
diff --git a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp
index d0d9e4218..f27becaa0 100644
--- a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp
+++ b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp
@@ -57,6 +57,13 @@ void GameInteractor_ExecuteOnRoomInit(s16 sceneId, s8 roomNum) {
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnRoomInit>(sceneId, roomNum);
}
+void GameInteractor_ExecuteAfterRoomSceneCommands(s16 sceneId, s8 roomNum) {
+ SPDLOG_DEBUG("AfterRoomSceneCommands: sceneId: {}, roomNum: {}", sceneId, roomNum);
+ GameInteractor::Instance->ExecuteHooks<GameInteractor::AfterRoomSceneCommands>(sceneId, roomNum);
+ GameInteractor::Instance->ExecuteHooksForID<GameInteractor::AfterRoomSceneCommands>(sceneId, sceneId, roomNum);
+ GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::AfterRoomSceneCommands>(sceneId, roomNum);
+}
+
void GameInteractor_ExecuteOnPlayDestroy() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnPlayDestroy>();
}
diff --git a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h
index 365a0f182..41d5f99ab 100644
--- a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h
+++ b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h
@@ -267,6 +267,7 @@ class GameInteractor {
DEFINE_HOOK(OnSceneInit, (s8 sceneId, s8 spawnNum));
DEFINE_HOOK(OnRoomInit, (s8 sceneId, s8 roomNum));
+ DEFINE_HOOK(AfterRoomSceneCommands, (s8 sceneId, s8 roomNum));
DEFINE_HOOK(OnPlayDestroy, ());
DEFINE_HOOK(ShouldActorInit, (Actor * actor, bool* should));
@@ -311,6 +312,7 @@ void GameInteractor_ExecuteBeforeMoonCrashSaveReset();
void GameInteractor_ExecuteOnSceneInit(s16 sceneId, s8 spawnNum);
void GameInteractor_ExecuteOnRoomInit(s16 sceneId, s8 roomNum);
+void GameInteractor_ExecuteAfterRoomSceneCommands(s16 sceneId, s8 roomNum);
void GameInteractor_ExecuteOnPlayDestroy();
bool GameInteractor_ShouldActorInit(Actor* actor);
diff --git a/mm/2s2h/z_play_2SH.cpp b/mm/2s2h/z_play_2SH.cpp
index 3432ab9e3..7cafb1ac5 100644
--- a/mm/2s2h/z_play_2SH.cpp
+++ b/mm/2s2h/z_play_2SH.cpp
@@ -3,6 +3,8 @@
#include "2s2h/resource/type/Scene.h"
#include <utils/StringHelper.h>
#include <Vertex.h>
+#include "2s2h/Enhancements/GameInteractor/GameInteractor.h"
+
extern "C" {
#include "global.h"
extern uintptr_t gSegments[NUM_SEGMENTS];
@@ -71,6 +73,8 @@ extern "C" s32 OTRfunc_800973FC(PlayState* play, RoomContext* roomCtx) {
if (Environment_GetStormState(play) == STORM_STATE_OFF) {
Environment_StopStormNatureAmbience(play);
}
+ // Insert hook
+ GameInteractor_ExecuteAfterRoomSceneCommands(play->sceneId, roomCtx->curRoom.num);
return 1;
}