Modularize Hyper Enemies hook (#5968)
* Modularize Hyper Enemies hook * Use extern "C" * Make mod file self-contained
This commit is contained in:
33
soh/soh/Enhancements/Difficulty/HyperEnemies.cpp
Normal file
33
soh/soh/Enhancements/Difficulty/HyperEnemies.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <libultraship/bridge.h>
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
#include "functions.h"
|
||||
#include "macros.h"
|
||||
|
||||
extern "C" PlayState* gPlayState;
|
||||
|
||||
static constexpr int32_t CVAR_HYPER_ENEMIES_DEFAULT = 0;
|
||||
#define CVAR_HYPER_ENEMIES_NAME CVAR_ENHANCEMENT("HyperEnemies")
|
||||
#define CVAR_HYPER_ENEMIES_VALUE CVarGetInteger(CVAR_HYPER_ENEMIES_NAME, CVAR_HYPER_ENEMIES_DEFAULT)
|
||||
|
||||
static void MakeHyperEnemies(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<Actor*>(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 (isEnemy && !isExcludedEnemy && !Player_InBlockingCsMode(gPlayState, player)) {
|
||||
GameInteractor::RawAction::UpdateActor(actor);
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateHyperEnemiesState() {
|
||||
COND_HOOK(OnActorUpdate, CVAR_HYPER_ENEMIES_VALUE, MakeHyperEnemies);
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(UpdateHyperEnemiesState, { CVAR_HYPER_ENEMIES_NAME });
|
||||
@@ -198,34 +198,6 @@ void RegisterHyperBosses() {
|
||||
[](int16_t fileNum) { UpdateHyperBossesState(); });
|
||||
}
|
||||
|
||||
void UpdateHyperEnemiesState() {
|
||||
static uint32_t actorUpdateHookId = 0;
|
||||
if (actorUpdateHookId != 0) {
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(actorUpdateHookId);
|
||||
actorUpdateHookId = 0;
|
||||
}
|
||||
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("HyperEnemies"), 0)) {
|
||||
actorUpdateHookId =
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorUpdate>([](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<Actor*>(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(CVAR_ENHANCEMENT("HyperEnemies"), 0) && isEnemy && !isExcludedEnemy &&
|
||||
!Player_InBlockingCsMode(gPlayState, player)) {
|
||||
GameInteractor::RawAction::UpdateActor(actor);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// this map is used for enemies that can be uniquely identified by their id
|
||||
// and that are always counted
|
||||
// enemies that can't be uniquely identified by their id
|
||||
@@ -476,7 +448,6 @@ void InitMods() {
|
||||
RegisterTTS();
|
||||
RegisterOcarinaTimeTravel();
|
||||
RegisterHyperBosses();
|
||||
UpdateHyperEnemiesState();
|
||||
RegisterEnemyDefeatCounts();
|
||||
RegisterRandomizedEnemySizes();
|
||||
RandoKaleido_RegisterHooks();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void UpdateHyperEnemiesState();
|
||||
void UpdateHyperBossesState();
|
||||
void InitMods();
|
||||
void SwitchAge();
|
||||
|
||||
@@ -1291,7 +1291,6 @@ void SohMenu::AddMenuEnhancements() {
|
||||
.Options(CheckboxOptions().Tooltip("All Major Bosses move and act twice as fast."));
|
||||
AddWidget(path, "Hyper Enemies", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("HyperEnemies"))
|
||||
.Callback([](WidgetInfo& info) { UpdateHyperEnemiesState(); })
|
||||
.Options(CheckboxOptions().Tooltip("All Regular Enemies and Mini-Bosses move and act twice as fast."));
|
||||
AddWidget(path, "Enable Visual Guard Vision", WIDGET_CVAR_CHECKBOX).CVar(CVAR_ENHANCEMENT("GuardVision"));
|
||||
AddWidget(path, "Leever Spawn Rate: %d seconds", WIDGET_CVAR_SLIDER_INT)
|
||||
|
||||
Reference in New Issue
Block a user