diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 36ccef505..6b10cf944 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -11,12 +11,6 @@ extern "C" { #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); -extern Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 posX, f32 posY, f32 posZ, - s16 rotX, s16 rotY, s16 rotZ, s16 params, s16 canRandomize); -extern void Inventory_ChangeEquipment(s16 equipment, u16 value); } bool performDelayedSave = false; bool performSave = false; @@ -440,6 +434,25 @@ void RegisterHyperBosses() { }); } +void RegisterHyperEnemies() { + GameInteractor::Instance->RegisterGameHook([](void* refActor) { + // Run the update function a second time to make enemies and minibosses move and act twice as fast. + + Player* player = GET_PLAYER(gPlayState); + Actor* actor = static_cast(refActor); + + // Some enemies are not in the ACTORCAT_ENEMY category, and some are that aren't really enemies. + bool isEnemy = actor->category == ACTORCAT_ENEMY || actor->id == ACTOR_EN_TORCH2; + bool isExcludedEnemy = actor->id == ACTOR_EN_FIRE_ROCK || actor->id == ACTOR_EN_ENCOUNT2; + + // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some cutscenes. + if (CVarGetInteger("gHyperEnemies", 0) && isEnemy && !isExcludedEnemy && + !Player_InBlockingCsMode(gPlayState, player)) { + GameInteractor::RawAction::UpdateActor(actor); + } + }); +} + void RegisterBonkDamage() { GameInteractor::Instance->RegisterGameHook([]() { uint8_t bonkOption = CVarGetInteger("gBonkDamageMul", 0); @@ -521,6 +534,7 @@ void InitMods() { RegisterDaytimeGoldSkultullas(); RegisterRupeeDash(); RegisterHyperBosses(); + RegisterHyperEnemies(); RegisterBonkDamage(); RegisterMenuPathFix(); } diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index 206b29188..e3090861f 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -575,6 +575,8 @@ namespace GameMenuBar { UIWidgets::Tooltip("Disables heart drops, but not heart placements, like from a Deku Scrub running off\nThis simulates Hero Mode from other games in the series"); UIWidgets::PaddedEnhancementCheckbox("Hyper Bosses", "gHyperBosses", true, false); UIWidgets::Tooltip("All major bosses move and act twice as fast."); + UIWidgets::PaddedEnhancementCheckbox("Hyper Enemies", "gHyperEnemies", true, false); + UIWidgets::Tooltip("All regular enemies and mini-bosses move and act twice as fast."); UIWidgets::PaddedEnhancementCheckbox("Always Win Goron Pot", "gGoronPot", true, false); UIWidgets::Tooltip("Always get the heart piece/purple rupee from the spinning Goron pot"); UIWidgets::PaddedEnhancementCheckbox("Always Win Dampe Digging Game", "gDampeWin", true, false, SaveManager::Instance->IsRandoFile(),