summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraMannus <mannusmenting@gmail.com>2023-03-12 08:10:03 +0100
committerGitHub <noreply@github.com>2023-03-12 08:10:03 +0100
commit76e99ffe1919280ef307102cfda7eaf3cce89f9b (patch)
treea2a09cbc55f99d060dc0507b40c857f120b8d720
parent73052617eda789f957040f98d9368d9cf453a123 (diff)
Feature - Bonk damage under difficulty options (#2584)
-rw-r--r--soh/soh/Enhancements/game-interactor/GameInteractor.h1
-rw-r--r--soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp4
-rw-r--r--soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h1
-rw-r--r--soh/soh/Enhancements/mods.cpp51
-rw-r--r--soh/soh/Enhancements/presets.h1
-rw-r--r--soh/soh/GameMenuBar.cpp14
-rw-r--r--soh/src/overlays/actors/ovl_player_actor/z_player.c1
7 files changed, 70 insertions, 3 deletions
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h
index f60063dbd..927e59f23 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h
@@ -91,6 +91,7 @@ public:
DEFINE_HOOK(OnSaleEnd, void(GetItemEntry itemEntry));
DEFINE_HOOK(OnSceneInit, void(int16_t sceneNum));
DEFINE_HOOK(OnPlayerUpdate, void());
+ DEFINE_HOOK(OnPlayerBonk, void());
DEFINE_HOOK(OnSaveFile, void(int32_t fileNum));
DEFINE_HOOK(OnLoadFile, void(int32_t fileNum));
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
index f1daa659a..9b830563b 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
@@ -30,6 +30,10 @@ void GameInteractor_ExecuteOnPlayerUpdate() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnPlayerUpdate>();
}
+void GameInteractor_ExecuteOnPlayerBonk() {
+ GameInteractor::Instance->ExecuteHooks<GameInteractor::OnPlayerBonk>();
+}
+
// MARK: - Save Files
void GameInteractor_ExecuteOnSaveFile(int32_t fileNum) {
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
index 51d8ecce4..3a6373eff 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
@@ -8,6 +8,7 @@ extern "C" void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry)
extern "C" void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry);
extern "C" void GameInteractor_ExecuteOnSceneInit(int16_t sceneNum);
extern "C" void GameInteractor_ExecuteOnPlayerUpdate();
+extern "C" void GameInteractor_ExecuteOnPlayerBonk();
// MARK: - Save Files
extern "C" void GameInteractor_ExecuteOnSaveFile(int32_t fileNum);
diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp
index 16d72539b..95023dcf3 100644
--- a/soh/soh/Enhancements/mods.cpp
+++ b/soh/soh/Enhancements/mods.cpp
@@ -7,11 +7,9 @@ extern "C" {
#include <z64.h>
#include "macros.h"
#include "variables.h"
+#include "functions.h"
extern SaveContext gSaveContext;
extern PlayState* gPlayState;
-extern void Play_PerformSave(PlayState* play);
-extern s32 Health_ChangeBy(PlayState* play, s16 healthChange);
-extern void Rupees_ChangeBy(s16 rupeeChange);
}
void RegisterInfiniteMoney() {
@@ -266,6 +264,52 @@ void RegisterRupeeDash() {
});
}
+void RegisterBonkDamage() {
+ GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerBonk>([]() {
+ uint8_t bonkOption = CVarGetInteger("gBonkDamageMul", 0);
+ uint16_t bonkDamage = 0;
+ switch (bonkOption) {
+ // Quarter heart
+ case 1:
+ bonkDamage = 4;
+ break;
+ // Half a heart
+ case 2:
+ bonkDamage = 8;
+ break;
+ // Full heart
+ case 3:
+ bonkDamage = 16;
+ break;
+ // 2 hearts
+ case 4:
+ bonkDamage = 32;
+ break;
+ // 4 hearts
+ case 5:
+ bonkDamage = 64;
+ break;
+ // 8 hearts
+ case 6:
+ bonkDamage = 128;
+ break;
+ case 0:
+ case 7:
+ default:
+ break;
+ }
+ // OHKO
+ if (bonkOption == 7) {
+ gSaveContext.health = 0;
+ } else if (bonkDamage) {
+ Health_ChangeBy(gPlayState, -bonkDamage);
+ // Set invincibility to make Link flash red as a visual damage indicator.
+ Player* player = GET_PLAYER(gPlayState);
+ player->invincibilityTimer = 28;
+ }
+ });
+}
+
void InitMods() {
RegisterTTS();
RegisterInfiniteMoney();
@@ -280,4 +324,5 @@ void InitMods() {
RegisterSwitchAge();
RegisterRupeeDash();
RegisterAutoSave();
+ RegisterBonkDamage();
}
diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h
index dd5369d18..da89029a0 100644
--- a/soh/soh/Enhancements/presets.h
+++ b/soh/soh/Enhancements/presets.h
@@ -82,6 +82,7 @@ const std::vector<const char*> enhancementsCvars = {
"gDamageMul",
"gFallDamageMul",
"gVoidDamageMul",
+ "gBonkDamageMul",
"gNoRandomDrops",
"gNoHeartDrops",
"gBombchuDrops",
diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp
index e98e28659..a22ba5ee0 100644
--- a/soh/soh/GameMenuBar.cpp
+++ b/soh/soh/GameMenuBar.cpp
@@ -73,6 +73,17 @@ namespace GameMenuBar {
"Hexaquinquagintiducentuple (256x)"
};
+ const char* bonkDamageValues[8] = {
+ "No Damage",
+ "0.25 Heart",
+ "0.5 Heart",
+ "1 Heart",
+ "2 Hearts",
+ "4 Hearts",
+ "8 Hearts",
+ "OHKO"
+ };
+
// MARK: - Helpers
std::string GetWindowButtonText(const char* text, bool menuOpen) {
@@ -477,6 +488,9 @@ namespace GameMenuBar {
32x: Can survive void damage with max health and double defense\n\
64x: Cannot survive void damage"
);
+ UIWidgets::PaddedText("Bonk Damage Multiplier", true, false);
+ UIWidgets::EnhancementCombobox("gBonkDamageMul", bonkDamageValues, 8, 0);
+ UIWidgets::Tooltip("Modifies damage taken after bonking.");
UIWidgets::PaddedEnhancementCheckbox("Spawn with full health", "gFullHealthSpawn", true, false);
UIWidgets::Tooltip("Respawn with full health instead of 3 Hearts");
UIWidgets::PaddedEnhancementCheckbox("No Random Drops", "gNoRandomDrops", true, false);
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 5a4cc4f53..7c56b7f6c 100644
--- a/soh/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c
@@ -8679,6 +8679,7 @@ void func_80844708(Player* this, PlayState* play) {
func_80832698(this, NA_SE_VO_LI_CLIMB_END);
this->unk_850 = 1;
gSaveContext.sohStats.count[COUNT_BONKS]++;
+ GameInteractor_ExecuteOnPlayerBonk();
return;
}
}