Feature - Bonk damage under difficulty options (#2584)

This commit is contained in:
aMannus 2023-03-12 08:10:03 +01:00 committed by GitHub
parent 73052617ed
commit 76e99ffe19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 70 additions and 3 deletions

View File

@ -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));

View File

@ -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) {

View File

@ -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);

View File

@ -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();
}

View File

@ -82,6 +82,7 @@ const std::vector<const char*> enhancementsCvars = {
"gDamageMul",
"gFallDamageMul",
"gVoidDamageMul",
"gBonkDamageMul",
"gNoRandomDrops",
"gNoHeartDrops",
"gBombchuDrops",

View File

@ -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);

View File

@ -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;
}
}