diff --git a/soh/soh/Enhancements/Cheats/MoonJump.cpp b/soh/soh/Enhancements/Cheats/MoonJump.cpp new file mode 100644 index 000000000..e741fbb82 --- /dev/null +++ b/soh/soh/Enhancements/Cheats/MoonJump.cpp @@ -0,0 +1,26 @@ +#include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "macros.h" +extern PlayState* gPlayState; +} + +#define CVAR_MOON_JUMP_NAME "gCheats.MoonJumpOnL" +#define CVAR_MOON_JUMP_DEFAULT 0 +#define CVAR_MOON_JUMP_VALUE CVarGetInteger(CVAR_MOON_JUMP_NAME, CVAR_MOON_JUMP_DEFAULT) + +void OnPlayerUpdateMoonJump() { + Player* player = GET_PLAYER(gPlayState); + + if (player != nullptr && CHECK_BTN_ANY(gPlayState->state.input[0].cur.button, BTN_L)) { + player->actor.velocity.y = 6.34375f; + } +} + +void RegisterMoonJump() { + COND_HOOK(OnPlayerUpdate, CVAR_MOON_JUMP_VALUE, OnPlayerUpdateMoonJump); +} + +static RegisterShipInitFunc initFunc(RegisterMoonJump, { CVAR_MOON_JUMP_NAME }); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 754b77cc1..fbf36f995 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -592,15 +592,43 @@ struct HookInfo { #define GET_CURRENT_REGISTERING_INFO(type) HookRegisteringInfo{} #endif -#define REGISTER_VB_SHOULD(flag, body) \ +#define REGISTER_VB_SHOULD(flag, body) \ GameInteractor::Instance->RegisterGameHookForID( \ - flag, [](GIVanillaBehavior _, bool* should, va_list _originalArgs) { \ - va_list args; \ - va_copy(args, _originalArgs); \ - body; \ - va_end(args); \ + flag, [](GIVanillaBehavior _, bool* should, va_list _originalArgs) { \ + va_list args; \ + va_copy(args, _originalArgs); \ + body; \ + va_end(args); \ }) +#define COND_HOOK(hookType, condition, body) \ + { \ + static HOOK_ID hookId = 0; \ + GameInteractor::Instance->UnregisterGameHook(hookId); \ + hookId = 0; \ + if (condition) { \ + hookId = GameInteractor::Instance->RegisterGameHook(body); \ + } \ + } +#define COND_ID_HOOK(hookType, id, condition, body) \ + { \ + static HOOK_ID hookId = 0; \ + GameInteractor::Instance->UnregisterGameHookForID(hookId); \ + hookId = 0; \ + if (condition) { \ + hookId = GameInteractor::Instance->RegisterGameHookForID(id, body); \ + } \ + } +#define COND_VB_SHOULD(id, condition, body) \ + { \ + static HOOK_ID hookId = 0; \ + GameInteractor::Instance->UnregisterGameHookForID(hookId); \ + hookId = 0; \ + if (condition) { \ + hookId = REGISTER_VB_SHOULD(id, body); \ + } \ + } + class GameInteractor { public: static GameInteractor* Instance; diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 76cb6c00d..8444549a2 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -146,21 +146,6 @@ void RegisterInfiniteNayrusLove() { }); } -void RegisterMoonJumpOnL() { - GameInteractor::Instance->RegisterGameHook([]() { - if (!GameInteractor::IsSaveLoaded(true)) return; - - if (CVarGetInteger(CVAR_CHEAT("MoonJumpOnL"), 0) != 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 RegisterInfiniteISG() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; @@ -1473,7 +1458,6 @@ void InitMods() { RegisterInfiniteAmmo(); RegisterInfiniteMagic(); RegisterInfiniteNayrusLove(); - RegisterMoonJumpOnL(); RegisterInfiniteISG(); RegisterEzQPA(); RegisterUnrestrictedItems(); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 9189da7e5..95fa8777d 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -127,6 +127,7 @@ Sail* Sail::Instance; #include "soh/resource/importer/BackgroundFactory.h" #include "soh/config/ConfigUpdaters.h" +#include "soh/ShipInit.hpp" extern "C" { #include "src/overlays/actors/ovl_En_Dns/z_en_dns.h" @@ -1150,6 +1151,7 @@ extern "C" void InitOTR() { conf->RunVersionUpdates(); SohGui::SetupGuiElements(); + ShipInit::InitAll(); AudioCollection::Instance = new AudioCollection(); ActorDB::Instance = new ActorDB(); #ifdef __APPLE__ diff --git a/soh/soh/ShipInit.hpp b/soh/soh/ShipInit.hpp new file mode 100644 index 000000000..b7612eb06 --- /dev/null +++ b/soh/soh/ShipInit.hpp @@ -0,0 +1,43 @@ +#ifndef SHIP_INIT_HPP +#define SHIP_INIT_HPP + +#ifdef __cplusplus + +#include +#include +#include +#include + +struct ShipInit { + static std::unordered_map>>& GetAll() { + static std::unordered_map>> shipInitFuncs; + return shipInitFuncs; + } + + static void InitAll() { + ShipInit::Init("*"); + } + + static void Init(const std::string& path) { + auto& shipInitFuncs = ShipInit::GetAll(); + for (const auto& initFunc : shipInitFuncs[path]) { + initFunc(); + } + } +}; + +struct RegisterShipInitFunc { + RegisterShipInitFunc(std::function initFunc, const std::set& updatePaths = {}) { + auto& shipInitFuncs = ShipInit::GetAll(); + + shipInitFuncs["*"].push_back(initFunc); + + for (const auto& path : updatePaths) { + shipInitFuncs[path].push_back(initFunc); + } + } +}; + +#endif // __cplusplus + +#endif // SHIP_INIT_HPP diff --git a/soh/soh/UIWidgets.cpp b/soh/soh/UIWidgets.cpp index 23af9f613..9272cbefc 100644 --- a/soh/soh/UIWidgets.cpp +++ b/soh/soh/UIWidgets.cpp @@ -239,6 +239,7 @@ namespace UIWidgets { if (CustomCheckbox(text, &val, disabled, disabledGraphic)) { CVarSetInteger(cvarName, val); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ShipInit::Init(cvarName); changed = true; } @@ -298,6 +299,7 @@ namespace UIWidgets { selected = i; changed = true; Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ShipInit::Init(cvarName); } } } diff --git a/soh/soh/UIWidgets.hpp b/soh/soh/UIWidgets.hpp index 5903220d2..c0e1b4504 100644 --- a/soh/soh/UIWidgets.hpp +++ b/soh/soh/UIWidgets.hpp @@ -1,10 +1,3 @@ -// -// UIWidgets.hpp -// soh -// -// Created by David Chavez on 25.08.22. -// - #ifndef UIWidgets_hpp #define UIWidgets_hpp @@ -17,6 +10,7 @@ #define IMGUI_DEFINE_MATH_OPERATORS #endif #include +#include "soh/ShipInit.hpp" namespace UIWidgets {