Modularize Mirrored World mode hook (#5930)
* Modularize Mirrored World mode hook * Remove IS_RANDO from registration conditions Co-authored-by: Philip Dubé <serprex@users.noreply.github.com> --------- Co-authored-by: Philip Dubé <serprex@users.noreply.github.com>
This commit is contained in:
80
soh/soh/Enhancements/ExtraModes/MirroredWorld.cpp
Normal file
80
soh/soh/Enhancements/ExtraModes/MirroredWorld.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#include "soh/Enhancements/cosmetics/authenticGfxPatches.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/Enhancements/randomizer/3drando/random.hpp"
|
||||
#include "soh/Enhancements/randomizer/context.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
#include "soh/Enhancements/mods.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "variables.h"
|
||||
extern SaveContext gSaveContext;
|
||||
}
|
||||
|
||||
static constexpr MirroredWorldMode CVAR_MIRRORED_WORLD_DEFAULT = MIRRORED_WORLD_OFF;
|
||||
#define CVAR_MIRRORED_WORLD_NAME CVAR_ENHANCEMENT("MirroredWorld")
|
||||
#define CVAR_MIRRORED_WORLD_MODE_NAME CVAR_ENHANCEMENT("MirroredWorldMode")
|
||||
#define CVAR_MIRRORED_WORLD_MODE_VALUE CVarGetInteger(CVAR_MIRRORED_WORLD_MODE_NAME, CVAR_MIRRORED_WORLD_DEFAULT)
|
||||
|
||||
static bool prevMirroredWorld = false;
|
||||
|
||||
static bool MirroredWorld_IsInDungeon(int32_t sceneNum) {
|
||||
return (sceneNum >= SCENE_DEKU_TREE && sceneNum <= SCENE_INSIDE_GANONS_CASTLE_COLLAPSE &&
|
||||
sceneNum != SCENE_THIEVES_HIDEOUT) ||
|
||||
(sceneNum >= SCENE_DEKU_TREE_BOSS && sceneNum <= SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR) ||
|
||||
(sceneNum == SCENE_GANON_BOSS);
|
||||
}
|
||||
|
||||
static void MirroredWorld_InitRandomSeed(int32_t sceneNum) {
|
||||
uint32_t seed =
|
||||
sceneNum + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt);
|
||||
Random_Init(seed);
|
||||
}
|
||||
|
||||
static bool MirroredWorld_ShouldApply(int32_t sceneNum) {
|
||||
switch (CVAR_MIRRORED_WORLD_MODE_VALUE) {
|
||||
case MIRRORED_WORLD_ALWAYS:
|
||||
return true;
|
||||
case MIRRORED_WORLD_RANDOM_SEEDED:
|
||||
MirroredWorld_InitRandomSeed(sceneNum);
|
||||
case MIRRORED_WORLD_RANDOM:
|
||||
return Random(0, 2) == 1;
|
||||
case MIRRORED_WORLD_DUNGEONS_ALL:
|
||||
return MirroredWorld_IsInDungeon(sceneNum);
|
||||
case MIRRORED_WORLD_DUNGEONS_VANILLA:
|
||||
return MirroredWorld_IsInDungeon(sceneNum) && !ResourceMgr_IsSceneMasterQuest(sceneNum);
|
||||
case MIRRORED_WORLD_DUNGEONS_MQ:
|
||||
return MirroredWorld_IsInDungeon(sceneNum) && ResourceMgr_IsSceneMasterQuest(sceneNum);
|
||||
case MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED:
|
||||
MirroredWorld_InitRandomSeed(sceneNum);
|
||||
case MIRRORED_WORLD_DUNGEONS_RANDOM:
|
||||
return MirroredWorld_IsInDungeon(sceneNum) && (Random(0, 2) == 1);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void RegisterMirroredWorld() {
|
||||
COND_HOOK(OnSceneInit, CVAR_MIRRORED_WORLD_MODE_VALUE, UpdateMirrorModeState);
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterMirroredWorld, { CVAR_MIRRORED_WORLD_MODE_NAME });
|
||||
|
||||
void UpdateMirrorModeState(int32_t sceneNum) {
|
||||
bool nextMirroredWorld = MirroredWorld_ShouldApply(sceneNum);
|
||||
|
||||
if (prevMirroredWorld == nextMirroredWorld) {
|
||||
return;
|
||||
}
|
||||
prevMirroredWorld = nextMirroredWorld;
|
||||
|
||||
if (nextMirroredWorld) {
|
||||
CVarSetInteger(CVAR_MIRRORED_WORLD_NAME, 1);
|
||||
} else {
|
||||
CVarClear(CVAR_MIRRORED_WORLD_NAME);
|
||||
RegisterMirroredWorld();
|
||||
}
|
||||
|
||||
ApplyMirrorWorldGfxPatches();
|
||||
}
|
||||
@@ -8,8 +8,6 @@
|
||||
#include "soh/resource/type/Skeleton.h"
|
||||
#include "soh/Enhancements/boss-rush/BossRush.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
#include "soh/Enhancements/randomizer/3drando/random.hpp"
|
||||
#include "soh/Enhancements/cosmetics/authenticGfxPatches.h"
|
||||
#include <soh/Enhancements/item-tables/ItemTableManager.h>
|
||||
#include "soh/Enhancements/timesaver_hook_handlers.h"
|
||||
#include "soh/Enhancements/randomizer/hook_handlers.h"
|
||||
@@ -286,51 +284,6 @@ void UpdateHyperEnemiesState() {
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateMirrorModeState(int32_t sceneNum) {
|
||||
static bool prevMirroredWorld = false;
|
||||
bool nextMirroredWorld = false;
|
||||
|
||||
int16_t mirroredMode = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorldMode"), MIRRORED_WORLD_OFF);
|
||||
int16_t inDungeon = (sceneNum >= SCENE_DEKU_TREE && sceneNum <= SCENE_INSIDE_GANONS_CASTLE_COLLAPSE &&
|
||||
sceneNum != SCENE_THIEVES_HIDEOUT) ||
|
||||
(sceneNum >= SCENE_DEKU_TREE_BOSS && sceneNum <= SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR) ||
|
||||
(sceneNum == SCENE_GANON_BOSS);
|
||||
|
||||
if (mirroredMode == MIRRORED_WORLD_RANDOM_SEEDED || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) {
|
||||
uint32_t seed =
|
||||
sceneNum + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt);
|
||||
Random_Init(seed);
|
||||
}
|
||||
|
||||
bool randomMirror = Random(0, 2) == 1;
|
||||
|
||||
if (mirroredMode == MIRRORED_WORLD_ALWAYS ||
|
||||
((mirroredMode == MIRRORED_WORLD_RANDOM || mirroredMode == MIRRORED_WORLD_RANDOM_SEEDED) && randomMirror) ||
|
||||
// Dungeon modes
|
||||
(inDungeon &&
|
||||
(mirroredMode == MIRRORED_WORLD_DUNGEONS_ALL ||
|
||||
(mirroredMode == MIRRORED_WORLD_DUNGEONS_VANILLA && !ResourceMgr_IsSceneMasterQuest(sceneNum)) ||
|
||||
(mirroredMode == MIRRORED_WORLD_DUNGEONS_MQ && ResourceMgr_IsSceneMasterQuest(sceneNum)) ||
|
||||
((mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) &&
|
||||
randomMirror)))) {
|
||||
nextMirroredWorld = true;
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 1);
|
||||
} else {
|
||||
nextMirroredWorld = false;
|
||||
CVarClear(CVAR_ENHANCEMENT("MirroredWorld"));
|
||||
}
|
||||
|
||||
if (prevMirroredWorld != nextMirroredWorld) {
|
||||
prevMirroredWorld = nextMirroredWorld;
|
||||
ApplyMirrorWorldGfxPatches();
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterMirrorModeHandler() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>(
|
||||
[](int32_t sceneNum) { UpdateMirrorModeState(sceneNum); });
|
||||
}
|
||||
|
||||
void UpdatePatchHand() {
|
||||
if ((CVarGetInteger(CVAR_ENHANCEMENT("EquipmentAlwaysVisible"), 0)) && LINK_IS_CHILD) {
|
||||
ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "childHammer1", 92,
|
||||
@@ -736,7 +689,6 @@ void InitMods() {
|
||||
RegisterDeleteFileOnDeath();
|
||||
RegisterHyperBosses();
|
||||
UpdateHyperEnemiesState();
|
||||
RegisterMirrorModeHandler();
|
||||
RegisterEnemyDefeatCounts();
|
||||
RegisterBossDefeatTimestamps();
|
||||
RegisterRandomizedEnemySizes();
|
||||
|
||||
Reference in New Issue
Block a user