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(); });
|
[](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
|
// this map is used for enemies that can be uniquely identified by their id
|
||||||
// and that are always counted
|
// and that are always counted
|
||||||
// enemies that can't be uniquely identified by their id
|
// enemies that can't be uniquely identified by their id
|
||||||
@@ -476,7 +448,6 @@ void InitMods() {
|
|||||||
RegisterTTS();
|
RegisterTTS();
|
||||||
RegisterOcarinaTimeTravel();
|
RegisterOcarinaTimeTravel();
|
||||||
RegisterHyperBosses();
|
RegisterHyperBosses();
|
||||||
UpdateHyperEnemiesState();
|
|
||||||
RegisterEnemyDefeatCounts();
|
RegisterEnemyDefeatCounts();
|
||||||
RegisterRandomizedEnemySizes();
|
RegisterRandomizedEnemySizes();
|
||||||
RandoKaleido_RegisterHooks();
|
RandoKaleido_RegisterHooks();
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void UpdateHyperEnemiesState();
|
|
||||||
void UpdateHyperBossesState();
|
void UpdateHyperBossesState();
|
||||||
void InitMods();
|
void InitMods();
|
||||||
void SwitchAge();
|
void SwitchAge();
|
||||||
|
|||||||
@@ -1291,7 +1291,6 @@ void SohMenu::AddMenuEnhancements() {
|
|||||||
.Options(CheckboxOptions().Tooltip("All Major Bosses move and act twice as fast."));
|
.Options(CheckboxOptions().Tooltip("All Major Bosses move and act twice as fast."));
|
||||||
AddWidget(path, "Hyper Enemies", WIDGET_CVAR_CHECKBOX)
|
AddWidget(path, "Hyper Enemies", WIDGET_CVAR_CHECKBOX)
|
||||||
.CVar(CVAR_ENHANCEMENT("HyperEnemies"))
|
.CVar(CVAR_ENHANCEMENT("HyperEnemies"))
|
||||||
.Callback([](WidgetInfo& info) { UpdateHyperEnemiesState(); })
|
|
||||||
.Options(CheckboxOptions().Tooltip("All Regular Enemies and Mini-Bosses move and act twice as fast."));
|
.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, "Enable Visual Guard Vision", WIDGET_CVAR_CHECKBOX).CVar(CVAR_ENHANCEMENT("GuardVision"));
|
||||||
AddWidget(path, "Leever Spawn Rate: %d seconds", WIDGET_CVAR_SLIDER_INT)
|
AddWidget(path, "Leever Spawn Rate: %d seconds", WIDGET_CVAR_SLIDER_INT)
|
||||||
|
|||||||
Reference in New Issue
Block a user