From 0cf2b3701334180a02694067b36e1a6564711a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= <159546+serprex@users.noreply.github.com> Date: Sun, 9 Aug 2026 23:46:51 +0000 Subject: [PATCH] Apply Enemy Rando Dark Link fixes to Crowd Control & Sail (#7054) --- .../ExtraModes/EnemyRandomizer.cpp | 58 -------------- soh/soh/Enhancements/Fixes/DarkLinkFixes.cpp | 77 +++++++++++++++++++ soh/soh/Network/CrowdControl/CrowdControl.cpp | 6 ++ soh/soh/Network/CrowdControl/CrowdControl.h | 1 + soh/soh/Network/Sail/Sail.cpp | 7 ++ soh/soh/Network/Sail/Sail.h | 1 + 6 files changed, 92 insertions(+), 58 deletions(-) create mode 100644 soh/soh/Enhancements/Fixes/DarkLinkFixes.cpp diff --git a/soh/soh/Enhancements/ExtraModes/EnemyRandomizer.cpp b/soh/soh/Enhancements/ExtraModes/EnemyRandomizer.cpp index 13eb8fe6b9..6a08945b9b 100644 --- a/soh/soh/Enhancements/ExtraModes/EnemyRandomizer.cpp +++ b/soh/soh/Enhancements/ExtraModes/EnemyRandomizer.cpp @@ -19,7 +19,6 @@ extern "C" { #include "src/overlays/actors/ovl_En_Encount1/z_en_encount1.h" #include "src/overlays/actors/ovl_En_GeldB/z_en_geldb.h" #include "src/overlays/actors/ovl_En_Peehat/z_en_peehat.h" -#include "src/overlays/actors/ovl_En_Rr/z_en_rr.h" #include "src/overlays/actors/ovl_En_Vali/z_en_vali.h" extern PlayState* gPlayState; @@ -652,63 +651,6 @@ void CustomPeehatLarvaDestroy(Actor* thisx, PlayState* play) { void RegisterEnemyRandomizer() { COND_ID_HOOK(OnActorInit, ACTOR_EN_MB, ENEMY_RANDOMIZER_ENABLED, FixClubMoblinScale); - // prevent dark link from triggering a voidout - COND_VB_SHOULD(VB_TRIGGER_VOIDOUT, ENEMY_RANDOMIZER_ENABLED, { - Actor* actor = va_arg(args, Actor*); - - if (*should == true && actor->category != ACTORCAT_PLAYER) { - // Improvement opportunity: Play sfx - *should = false; - Actor_Kill(actor); - } - }); - - // prevent dark link dealing fall damage to the player - COND_VB_SHOULD(VB_RECIEVE_FALL_DAMAGE, ENEMY_RANDOMIZER_ENABLED, { - Actor* actor = va_arg(args, Actor*); - - if (actor->category != ACTORCAT_PLAYER) { - *should = false; - } - }); - - // prevent dark link from interfering with HESS/recoil/etc when at more than 100 away from him - COND_VB_SHOULD(VB_TORCH2_HANDLE_CLANKING, ENEMY_RANDOMIZER_ENABLED, { - Actor* darkLink = va_arg(args, Actor*); - - if (darkLink->xzDistToPlayer > 100.0f) { - *should = false; - } - }); - - // prevent dark link from interfering with ice floors - COND_VB_SHOULD(VB_SET_STATIC_PREV_FLOOR_TYPE, ENEMY_RANDOMIZER_ENABLED, { - Player* playerOrDarkLink = va_arg(args, Player*); - - if (playerOrDarkLink->actor.id != ACTOR_PLAYER) { - *should = false; - } - }); - - // prevent dark link from interfering with ice floors - COND_VB_SHOULD(VB_SET_STATIC_FLOOR_TYPE, ENEMY_RANDOMIZER_ENABLED, { - Player* playerOrDarkLink = va_arg(args, Player*); - - if (playerOrDarkLink->actor.id != ACTOR_PLAYER) { - *should = false; - } - }); - - // prevent dark link from being grabbed by like likes and therefore grabbing the player - COND_VB_SHOULD(VB_LIKE_LIKE_GRAB_PLAYER, ENEMY_RANDOMIZER_ENABLED, { - EnRr* likeLike = va_arg(args, EnRr*); - - if (!(likeLike->collider1.base.oc != NULL && likeLike->collider1.base.oc->category == ACTORCAT_PLAYER) && - !(likeLike->collider2.base.oc != NULL && likeLike->collider2.base.oc->category == ACTORCAT_PLAYER)) { - *should = false; - } - }); - // Allow Random Gerudo Fighters (contain no keys) to spawn without any switch flags COND_VB_SHOULD(VB_GERUDO_FIGHTER_CONTINUE_WAITING, ENEMY_RANDOMIZER_ENABLED, { EnGeldB* enGeldB = va_arg(args, EnGeldB*); diff --git a/soh/soh/Enhancements/Fixes/DarkLinkFixes.cpp b/soh/soh/Enhancements/Fixes/DarkLinkFixes.cpp new file mode 100644 index 0000000000..4c458d0de4 --- /dev/null +++ b/soh/soh/Enhancements/Fixes/DarkLinkFixes.cpp @@ -0,0 +1,77 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/enhancementTypes.h" +#include "soh/ShipInit.hpp" +#include "soh/cvar_prefixes.h" + +extern "C" { +#include "functions.h" +#include "src/overlays/actors/ovl_En_Rr/z_en_rr.h" +} + +// Dark Link runs the player update function, so anything he does that has a global effect (voiding +// out, fall damage, the shared floor type statics) happens to Link instead. +static void RegisterDarkLinkFixes() { + bool required = + CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), ENEMY_RANDOMIZER_OFF) != ENEMY_RANDOMIZER_OFF || + CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("Enabled"), 0) || CVarGetInteger(CVAR_REMOTE_SAIL("Enabled"), 0); + // prevent dark link from triggering a voidout + COND_VB_SHOULD(VB_TRIGGER_VOIDOUT, required, { + Actor* actor = va_arg(args, Actor*); + + if (*should == true && actor->category != ACTORCAT_PLAYER) { + // Improvement opportunity: Play sfx + *should = false; + Actor_Kill(actor); + } + }); + + // prevent dark link dealing fall damage to the player + COND_VB_SHOULD(VB_RECIEVE_FALL_DAMAGE, required, { + Actor* actor = va_arg(args, Actor*); + + if (actor->category != ACTORCAT_PLAYER) { + *should = false; + } + }); + + // prevent dark link from interfering with HESS/recoil/etc when at more than 100 away from him + COND_VB_SHOULD(VB_TORCH2_HANDLE_CLANKING, required, { + Actor* darkLink = va_arg(args, Actor*); + + if (darkLink->xzDistToPlayer > 100.0f) { + *should = false; + } + }); + + // prevent dark link from interfering with ice floors + COND_VB_SHOULD(VB_SET_STATIC_PREV_FLOOR_TYPE, required, { + Player* playerOrDarkLink = va_arg(args, Player*); + + if (playerOrDarkLink->actor.id != ACTOR_PLAYER) { + *should = false; + } + }); + + // prevent dark link from interfering with ice floors + COND_VB_SHOULD(VB_SET_STATIC_FLOOR_TYPE, required, { + Player* playerOrDarkLink = va_arg(args, Player*); + + if (playerOrDarkLink->actor.id != ACTOR_PLAYER) { + *should = false; + } + }); + + // prevent dark link from being grabbed by like likes and therefore grabbing the player + COND_VB_SHOULD(VB_LIKE_LIKE_GRAB_PLAYER, required, { + EnRr* likeLike = va_arg(args, EnRr*); + + if (!(likeLike->collider1.base.oc != NULL && likeLike->collider1.base.oc->category == ACTORCAT_PLAYER) && + !(likeLike->collider2.base.oc != NULL && likeLike->collider2.base.oc->category == ACTORCAT_PLAYER)) { + *should = false; + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterDarkLinkFixes, + { CVAR_ENHANCEMENT("RandomizedEnemies"), CVAR_REMOTE_CROWD_CONTROL("Enabled"), + CVAR_REMOTE_SAIL("Enabled") }); diff --git a/soh/soh/Network/CrowdControl/CrowdControl.cpp b/soh/soh/Network/CrowdControl/CrowdControl.cpp index 1537d5d6dd..94ce46ec15 100644 --- a/soh/soh/Network/CrowdControl/CrowdControl.cpp +++ b/soh/soh/Network/CrowdControl/CrowdControl.cpp @@ -13,6 +13,12 @@ extern PlayState* gPlayState; void CrowdControl::Enable() { Network::Enable(CVarGetString(CVAR_REMOTE_CROWD_CONTROL("Host"), "127.0.0.1"), CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("Port"), 43384)); + ShipInit::Init(CVAR_REMOTE_CROWD_CONTROL("Enabled")); +} + +void CrowdControl::Disable() { + Network::Disable(); + ShipInit::Init(CVAR_REMOTE_CROWD_CONTROL("Enabled")); } void CrowdControl::OnConnected() { diff --git a/soh/soh/Network/CrowdControl/CrowdControl.h b/soh/soh/Network/CrowdControl/CrowdControl.h index b9f76f1c04..627f436165 100644 --- a/soh/soh/Network/CrowdControl/CrowdControl.h +++ b/soh/soh/Network/CrowdControl/CrowdControl.h @@ -80,6 +80,7 @@ class CrowdControl : public Network { public: static CrowdControl* Instance; void Enable(); + void Disable(); void OnIncomingJson(nlohmann::json payload); void OnConnected(); void OnDisconnected(); diff --git a/soh/soh/Network/Sail/Sail.cpp b/soh/soh/Network/Sail/Sail.cpp index 8cc5e7001a..4da34f1373 100644 --- a/soh/soh/Network/Sail/Sail.cpp +++ b/soh/soh/Network/Sail/Sail.cpp @@ -4,6 +4,7 @@ #include #include #include +#include "soh/ShipInit.hpp" #include "soh/ShipUtils.h" #include "soh/cvar_prefixes.h" @@ -14,6 +15,12 @@ template bool IsType(const SrcType* src) { void Sail::Enable() { Network::Enable(CVarGetString(CVAR_REMOTE_SAIL("Host"), "127.0.0.1"), CVarGetInteger(CVAR_REMOTE_SAIL("Port"), 43384)); + ShipInit::Init(CVAR_REMOTE_SAIL("Enabled")); +} + +void Sail::Disable() { + Network::Disable(); + ShipInit::Init(CVAR_REMOTE_SAIL("Enabled")); } void Sail::OnConnected() { diff --git a/soh/soh/Network/Sail/Sail.h b/soh/soh/Network/Sail/Sail.h index 418606e66c..c04bf897fc 100644 --- a/soh/soh/Network/Sail/Sail.h +++ b/soh/soh/Network/Sail/Sail.h @@ -16,6 +16,7 @@ class Sail : public Network { static Sail* Instance; void Enable(); + void Disable(); void OnIncomingJson(nlohmann::json payload); void OnConnected(); void OnDisconnected();