summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--soh/soh/Enhancements/cheat_hook_handlers.cpp56
-rw-r--r--soh/soh/Enhancements/cheat_hook_handlers.h6
-rw-r--r--soh/soh/Enhancements/game-interactor/GameInteractor.h7
-rw-r--r--soh/soh/Enhancements/mods.cpp2
-rw-r--r--soh/src/overlays/actors/ovl_player_actor/z_player.c37
5 files changed, 86 insertions, 22 deletions
diff --git a/soh/soh/Enhancements/cheat_hook_handlers.cpp b/soh/soh/Enhancements/cheat_hook_handlers.cpp
new file mode 100644
index 000000000..cdc8333ce
--- /dev/null
+++ b/soh/soh/Enhancements/cheat_hook_handlers.cpp
@@ -0,0 +1,56 @@
+#include <libultraship/bridge.h>
+#include "soh/OTRGlobals.h"
+#include "soh/Enhancements/game-interactor/GameInteractor.h"
+#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh/Enhancements/enhancementTypes.h"
+
+extern "C" {
+#include "macros.h"
+#include "variables.h"
+
+extern SaveContext gSaveContext;
+extern PlayState* gPlayState;
+}
+
+void CheatsOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* opt) {
+ switch (id) {
+ case GI_VB_DEKU_STICK_BREAK: {
+ if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) {
+ *should = false;
+ }
+ break;
+ }
+ case GI_VB_DEKU_STICK_BE_ON_FIRE: {
+ if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE) {
+ Player* player = GET_PLAYER(gPlayState);
+ player->unk_860 = 200; // Keeps the stick's flame lit
+ player->unk_85C = 1.0f; // Ensures the stick is the proper length
+ *should = true;
+ }
+ break;
+ }
+ case GI_VB_DEKU_STICK_BURN_OUT: {
+ if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) {
+ *should = false;
+ }
+ break;
+ }
+ case GI_VB_DEKU_STICK_BURN_DOWN: {
+ if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) {
+ *should = false;
+ }
+ break;
+ }
+ }
+}
+
+static uint32_t onVanillaBehaviorHook = 0;
+void CheatsRegisterHooks() {
+ GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>([](int32_t fileNum) mutable {
+
+ GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnVanillaBehavior>(onVanillaBehaviorHook);
+ onVanillaBehaviorHook = 0;
+ onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(CheatsOnVanillaBehaviorHandler);
+
+ });
+}
diff --git a/soh/soh/Enhancements/cheat_hook_handlers.h b/soh/soh/Enhancements/cheat_hook_handlers.h
new file mode 100644
index 000000000..88a79f285
--- /dev/null
+++ b/soh/soh/Enhancements/cheat_hook_handlers.h
@@ -0,0 +1,6 @@
+#ifndef CHEAT_HOOK_HANDLERS_H
+#define CHEAT_HOOK_HANDLERS_H
+
+void CheatsRegisterHooks();
+
+#endif // CHEAT_HOOK_HANDLERS_H
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h
index 716d20b08..17b6198b3 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h
@@ -377,6 +377,13 @@ typedef enum {
// Vanilla condition: false
GI_VB_FIX_SAW_SOFTLOCK,
+ /*** Cheats? ***/
+ GI_VB_DEKU_STICK_BE_ON_FIRE,
+ GI_VB_DEKU_STICK_BREAK,
+ GI_VB_DEKU_STICK_BURN_DOWN,
+ GI_VB_DEKU_STICK_BURN_OUT,
+ GI_VB_DEKU_UPDATE_BURNING_DEKU_STICK,
+
/*** Quick Boss Deaths ***/
// Vanilla condition: true
GI_VB_PHANTOM_GANON_DEATH_SCENE,
diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp
index 580c29b3c..c0425f148 100644
--- a/soh/soh/Enhancements/mods.cpp
+++ b/soh/soh/Enhancements/mods.cpp
@@ -11,6 +11,7 @@
#include <soh/Enhancements/item-tables/ItemTableManager.h>
#include "soh/Enhancements/nametag.h"
#include "soh/Enhancements/timesaver_hook_handlers.h"
+#include "soh/Enhancements/cheat_hook_handlers.h"
#include "soh/Enhancements/randomizer/hook_handlers.h"
#include "objects/object_gi_compass/object_gi_compass.h"
@@ -1715,6 +1716,7 @@ void RegisterRandomizerCompasses() {
void InitMods() {
RandomizerRegisterHooks();
TimeSaverRegisterHooks();
+ CheatsRegisterHooks();
RegisterTTS();
RegisterInfiniteMoney();
RegisterInfiniteHealth();
diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c
index 2b994f56f..43a34c778 100644
--- a/soh/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c
@@ -8515,15 +8515,14 @@ void func_80842A28(PlayState* play, Player* this) {
}
void func_80842A88(PlayState* play, Player* this) {
- if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) {
- Inventory_ChangeAmmo(ITEM_STICK, -1);
- Player_UseItem(play, this, ITEM_NONE);
- }
+ Inventory_ChangeAmmo(ITEM_STICK, -1);
+ Player_UseItem(play, this, ITEM_NONE);
}
s32 func_80842AC4(PlayState* play, Player* this) {
if ((this->heldItemAction == PLAYER_IA_DEKU_STICK) && (this->unk_85C > 0.5f)) {
- if (AMMO(ITEM_STICK) != 0 && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) {
+
+ if (GameInteractor_Should(GI_VB_DEKU_STICK_BREAK, AMMO(ITEM_STICK) != 0, NULL)) {
EffectSsStick_Spawn(play, &this->bodyPartsPos[PLAYER_BODYPART_R_HAND],
this->actor.shape.rot.y + 0x8000);
this->unk_85C = 0.5f;
@@ -10942,37 +10941,30 @@ static Vec3f D_808547B0 = { 0.0f, 0.5f, 0.0f };
static Color_RGBA8 D_808547BC = { 255, 255, 100, 255 };
static Color_RGBA8 D_808547C0 = { 255, 50, 0, 0 };
-void func_80848A04(PlayState* play, Player* this) {
+void Player_UpdateBurningDekuStick(PlayState* play, Player* this) {
f32 temp;
- if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE) {
- f32 temp2 = 1.0f; // Secondary temporary variable to use with the alleged draw flame function
- this->unk_860 = 200; // Keeps the stick's flame lit
- this->unk_85C = 1.0f; // Ensures the stick is the proper length
- func_8002836C(play, &this->meleeWeaponInfo[0].tip, &D_808547A4, &D_808547B0, &D_808547BC, &D_808547C0, temp2 * 200.0f,
- 0, 8); // I believe this draws the flame effect
- }
-
- if (this->unk_85C == 0.0f && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) {
- Player_UseItem(play, this, 0xFF);
+ if (GameInteractor_Should(GI_VB_DEKU_STICK_BURN_OUT, this->unk_85C == 0.0f, NULL)) {
+ Player_UseItem(play, this, ITEM_NONE);
return;
}
temp = 1.0f;
- if (DECR(this->unk_860) == 0 && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) {
+ uint8_t vanillaShouldBurnOutCondition = DECR(this->unk_860) == 0;
+ if (GameInteractor_Should(GI_VB_DEKU_STICK_BURN_OUT, vanillaShouldBurnOutCondition, NULL)) {
Inventory_ChangeAmmo(ITEM_STICK, -1);
this->unk_860 = 1;
temp = 0.0f;
this->unk_85C = temp;
} else if (this->unk_860 > 200) {
temp = (210 - this->unk_860) / 10.0f;
- } else if (this->unk_860 < 20 && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) {
+ } else if (GameInteractor_Should(GI_VB_DEKU_STICK_BURN_DOWN, this->unk_860 < 20, NULL)) {
temp = this->unk_860 / 20.0f;
this->unk_85C = temp;
}
- func_8002836C(play, &this->meleeWeaponInfo[0].tip, &D_808547A4, &D_808547B0, &D_808547BC, &D_808547C0, temp * 200.0f,
- 0, 8);
+ func_8002836C(play, &this->meleeWeaponInfo[0].tip, &D_808547A4, &D_808547B0, &D_808547BC, &D_808547C0,
+ temp * 200.0f, 0, 8);
}
void Player_UpdateBodyShock(PlayState* play, Player* this) {
@@ -11267,8 +11259,9 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
func_808473D4(play, this);
func_80836BEC(this, play);
- if ((this->heldItemAction == PLAYER_IA_DEKU_STICK) && ((this->unk_860 != 0) || CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE)) {
- func_80848A04(play, this);
+ if (this->heldItemAction == PLAYER_IA_DEKU_STICK &&
+ GameInteractor_Should(GI_VB_DEKU_STICK_BE_ON_FIRE, this->unk_860 != 0, NULL)) {
+ Player_UpdateBurningDekuStick(play, this);
} else if ((this->heldItemAction == PLAYER_IA_FISHING_POLE) && (this->unk_860 < 0)) {
this->unk_860++;
}