diff --git a/mm/2s2h/BenMenuBar.cpp b/mm/2s2h/BenMenuBar.cpp index f61a425c9..7e8892265 100644 --- a/mm/2s2h/BenMenuBar.cpp +++ b/mm/2s2h/BenMenuBar.cpp @@ -276,6 +276,9 @@ void DrawDeveloperToolsMenu() { "Right, and open the debug menu with L on the pause screen" }); UIWidgets::CVarCheckbox("No Clip", "gDeveloperTools.NoClip"); + UIWidgets::CVarCheckbox("Moon Jump on L", "gDeveloperTools.MoonJumpOnL", { + .tooltip = "Holding L makes you float into the air" + }); if (gPlayState != NULL) { UIWidgets::PaddedSeparator(); UIWidgets::Checkbox("Frame Advance", (bool*)&gPlayState->frameAdvCtx.enabled, { diff --git a/mm/2s2h/BenPort.cpp b/mm/2s2h/BenPort.cpp index 7dc32b298..88b471f16 100644 --- a/mm/2s2h/BenPort.cpp +++ b/mm/2s2h/BenPort.cpp @@ -55,6 +55,8 @@ CrowdControl* CrowdControl::Instance; #include "BenJsonConversions.hpp" #include "Enhancements/controls/SohInputEditorWindow.h" +#include "Enhancements/GameInteractor/GameInteractor.h" +#include "Enhancements/mods.h" // Resource Types/Factories #include "2s2h/resource/type/Animation.h" @@ -86,6 +88,7 @@ CrowdControl* CrowdControl::Instance; #include "2s2h/resource/importer/TextureAnimationFactory.h" OTRGlobals* OTRGlobals::Instance; +GameInteractor* GameInteractor::Instance; extern "C" char** cameraStrings; std::vector> cameraStdStrings; @@ -301,7 +304,9 @@ extern "C" void InitOTR() { #endif OTRGlobals::Instance = new OTRGlobals(); + GameInteractor::Instance = new GameInteractor(); BenGui::SetupGuiElements(); + InitMods(); clearMtx = (uintptr_t)&gMtxClear; //OTRMessage_Init(); diff --git a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp new file mode 100644 index 000000000..ebede2459 --- /dev/null +++ b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp @@ -0,0 +1,3 @@ +#include "GameInteractor.h" + +#include \ No newline at end of file diff --git a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h new file mode 100644 index 000000000..a9828765e --- /dev/null +++ b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h @@ -0,0 +1,53 @@ +#ifndef GAME_INTERACTOR_H +#define GAME_INTERACTOR_H + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + + +#ifdef __cplusplus + +#include +#include + +#define DEFINE_HOOK(name, type) \ + struct name { \ + typedef std::function fn; \ + } + +class GameInteractor { +public: + static GameInteractor* Instance; + + // Game State + class State { + + }; + + // Game Hooks + template struct RegisteredGameHooks { inline static std::vector functions; }; + template void RegisterGameHook(typename H::fn h) { RegisteredGameHooks::functions.push_back(h); } + template void ExecuteHooks(Args&&... args) { + for (auto& fn : RegisteredGameHooks::functions) { + fn(std::forward(args)...); + } + } + + DEFINE_HOOK(OnGameStateMainFinish, void()); + DEFINE_HOOK(OnGameStateDrawFinish, void()); + DEFINE_HOOK(OnGameStateUpdate, void()); + + // Game Actions + class RawAction { + + }; + +}; + +#endif // __cplusplus + +#endif // GAME_INTERACTOR_H \ No newline at end of file diff --git a/mm/2s2h/Enhancements/GameInteractor/GameInteractorHooks.cpp b/mm/2s2h/Enhancements/GameInteractor/GameInteractorHooks.cpp new file mode 100644 index 000000000..904ac7c9e --- /dev/null +++ b/mm/2s2h/Enhancements/GameInteractor/GameInteractorHooks.cpp @@ -0,0 +1,15 @@ +#include "GameInteractorHooks.h" + +// Gameplay + +void GameInteractor_ExecuteOnGameStateMainFinish() { + GameInteractor::Instance->ExecuteHooks(); +} + +void GameInteractor_ExecuteOnGameStateDrawFinish() { + GameInteractor::Instance->ExecuteHooks(); +} + +void GameInteractor_ExecuteOnGameStateUpdate() { + GameInteractor::Instance->ExecuteHooks(); +} \ No newline at end of file diff --git a/mm/2s2h/Enhancements/GameInteractor/GameInteractorHooks.h b/mm/2s2h/Enhancements/GameInteractor/GameInteractorHooks.h new file mode 100644 index 000000000..032626ea4 --- /dev/null +++ b/mm/2s2h/Enhancements/GameInteractor/GameInteractorHooks.h @@ -0,0 +1,14 @@ +#include "GameInteractor.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Gameplay +void GameInteractor_ExecuteOnGameStateMainFinish(); +void GameInteractor_ExecuteOnGameStateDrawFinish(); +void GameInteractor_ExecuteOnGameStateUpdate(); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/mm/2s2h/Enhancements/mods.cpp b/mm/2s2h/Enhancements/mods.cpp new file mode 100644 index 000000000..834b69bc7 --- /dev/null +++ b/mm/2s2h/Enhancements/mods.cpp @@ -0,0 +1,29 @@ +#include "mods.h" +#include +#include "GameInteractor/GameInteractor.h" + +extern "C" { +#include +#include "macros.h" +// #include "functions.h" +// #include "variables.h" +extern PlayState* gPlayState; +} + +void RegisterMoonJumpOnL() { + GameInteractor::Instance->RegisterGameHook([]() { + if (!gPlayState) return; + + if (CVarGetInteger("gDeveloperTools.MoonJumpOnL", 0)) { + Player* player = GET_PLAYER(gPlayState); + + if (CHECK_BTN_ANY(gPlayState->state.input[0].cur.button, BTN_L)) { + player->actor.velocity.y = 6.34375f; + } + } + }); +} + +void InitMods() { + RegisterMoonJumpOnL(); +} \ No newline at end of file diff --git a/mm/2s2h/Enhancements/mods.h b/mm/2s2h/Enhancements/mods.h new file mode 100644 index 000000000..1edc61624 --- /dev/null +++ b/mm/2s2h/Enhancements/mods.h @@ -0,0 +1,9 @@ +#ifdef __cplusplus +extern "C" { +#endif + +void InitMods(); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/mm/src/code/game.c b/mm/src/code/game.c index a3f0ba824..4f653451a 100644 --- a/mm/src/code/game.c +++ b/mm/src/code/game.c @@ -13,6 +13,8 @@ #include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h" #include "debug.h" +#include "Enhancements/GameInteractor/GameInteractorHooks.h" + s32 gFramerateDivisor = 1; f32 gFramerateDivisorF = 1.0f; f32 gFramerateDivisorHalf = 1.0f / 2.0f; @@ -148,10 +150,15 @@ void GameState_Update(GameState* gameState) { gameState->main(gameState); + GameInteractor_ExecuteOnGameStateMainFinish(); + if (R_PAUSE_BG_PRERENDER_STATE != PAUSE_BG_PRERENDER_PROCESS) { GameState_Draw(gameState, gfxCtx); + GameInteractor_ExecuteOnGameStateDrawFinish(); GameState_DrawEnd(gfxCtx); } + + GameInteractor_ExecuteOnGameStateUpdate(); } void GameState_IncrementFrameCount(GameState* gameState) {