diff --git a/mm/2s2h/BenGui/SearchableMenuItems.h b/mm/2s2h/BenGui/SearchableMenuItems.h index ec8feb0cd..84ada9b16 100644 --- a/mm/2s2h/BenGui/SearchableMenuItems.h +++ b/mm/2s2h/BenGui/SearchableMenuItems.h @@ -1095,6 +1095,8 @@ void AddEnhancements() { WIDGET_CVAR_CHECKBOX }, { "Time Moves when you Move", "gModes.TimeMovesWhenYouMove", "Time only moves when Link is not standing still.", WIDGET_CVAR_CHECKBOX }, + { "Hyper Enemies", "gModes.HyperEnemies", + "Double the rate at which enemies are updated, making them more difficult", WIDGET_CVAR_CHECKBOX }, { "Mirrored World", "gModes.MirroredWorld.Mode", "Mirrors the world horizontally.", diff --git a/mm/2s2h/Enhancements/Modes/HyperEnemies.cpp b/mm/2s2h/Enhancements/Modes/HyperEnemies.cpp new file mode 100644 index 000000000..2d87e1b2a --- /dev/null +++ b/mm/2s2h/Enhancements/Modes/HyperEnemies.cpp @@ -0,0 +1,34 @@ +#include +#include "2s2h/GameInteractor/GameInteractor.h" +#include "2s2h/ShipInit.hpp" + +extern "C" { +#include "variables.h" +#include "functions.h" +} + +#define CVAR_NAME "gModes.HyperEnemies" +#define CVAR CVarGetInteger(CVAR_NAME, 0) + +void RegisterHyperEnemies() { + COND_HOOK(OnActorUpdate, CVAR, [](Actor* actor) { + if (actor->category != ACTORCAT_ENEMY) { + return; + } + + if (Player_InBlockingCsMode(gPlayState, GET_PLAYER(gPlayState))) { + return; + } + + if (actor->update != NULL) { + // Everywhere we need to disable the collision checks already checks if frameAdvance is enabled, so we abuse + // that temporarily. This doesn't have any _known_ side effects :) + bool prevFrameAdv = gPlayState->frameAdvCtx.enabled; + gPlayState->frameAdvCtx.enabled = true; + actor->update(actor, gPlayState); + gPlayState->frameAdvCtx.enabled = prevFrameAdv; + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterHyperEnemies, { CVAR_NAME });