From db02870a05461a09159a6b9e302056211f1ac625 Mon Sep 17 00:00:00 2001
From: inspectredc <78732756+inspectredc@users.noreply.github.com>
Date: Mon, 15 Jan 2024 15:30:20 +0000
Subject: [PATCH] Restore Original Scene Command Object List Behaviour
 (MacReady) (#3827)

* Restore Original Scene_CommandObjectList Behaviour

* remove some vrom stuff

* add some comments
---
 soh/soh/z_scene_otr.cpp | 50 ++++++++++++++++-------------------------
 soh/src/code/z_actor.c  |  6 +++--
 soh/src/code/z_scene.c  |  7 ++++--
 3 files changed, 28 insertions(+), 35 deletions(-)

diff --git a/soh/soh/z_scene_otr.cpp b/soh/soh/z_scene_otr.cpp
index ef98a4b3a..54065e27e 100644
--- a/soh/soh/z_scene_otr.cpp
+++ b/soh/soh/z_scene_otr.cpp
@@ -149,6 +149,13 @@ bool Scene_CommandMeshHeader(PlayState* play, LUS::ISceneCommand* cmd) {
 
 extern "C" void* func_800982FC(ObjectContext* objectCtx, s32 bankIndex, s16 objectId);
 
+bool OTRfunc_800982FC(ObjectContext* objectCtx, s32 bankIndex, s16 objectId) {
+
+    objectCtx->status[bankIndex].id = -objectId;
+
+    return false;
+}
+
 bool Scene_CommandObjectList(PlayState* play, LUS::ISceneCommand* cmd) {
     // LUS::SetObjectList* cmdObj = static_pointer_cast<LUS::SetObjectList>(cmd);
     LUS::SetObjectList* cmdObj = (LUS::SetObjectList*)cmd;
@@ -164,49 +171,30 @@ bool Scene_CommandObjectList(PlayState* play, LUS::ISceneCommand* cmd) {
     void* nextPtr;
 
     k = 0;
-    // i = play->objectCtx.unk_09;
-    i = 0;
+    i = play->objectCtx.unk_09;
     firstStatus = &play->objectCtx.status[0];
     status = &play->objectCtx.status[i];
 
-    for (int i = 0; i < cmdObj->objects.size(); i++) {
-        bool alreadyIncluded = false;
-
-        for (int j = 0; j < play->objectCtx.num; j++) {
-            if (play->objectCtx.status[j].id == cmdObj->objects[i]) {
-                alreadyIncluded = true;
-                break;
+    // Loop until a mismatch in the object lists
+    // Then clear all object ids past that in the context object list and kill actors for those objects
+    for (i = play->objectCtx.unk_09, k = 0; i < play->objectCtx.num; i++, k++) {
+        if (play->objectCtx.status[i].id != cmdObj->objects[k]) {
+            for (j = i; j < play->objectCtx.num; j++) {
+                play->objectCtx.status[j].id = OBJECT_INVALID;
             }
-        }
-
-        if (!alreadyIncluded) {
-            play->objectCtx.status[play->objectCtx.num++].id = cmdObj->objects[i];
             func_80031A28(play, &play->actorCtx);
+            break;
         }
     }
 
-    /*
-    while (i < play->objectCtx.num) {
-        if (status->id != *objectEntry) {
-            status2 = &play->objectCtx.status[i];
-            for (j = i; j < play->objectCtx.num; j++) {
-                status2->id = OBJECT_INVALID;
-                status2++;
-            }
-            play->objectCtx.num = i;
-            func_80031A28(play, &play->actorCtx);
-
-            continue;
+    // Continuing from the last index, add the remaining object ids from the command object list
+    for (; k < cmdObj->objects.size(); k++, i++) {
+        if (i < OBJECT_EXCHANGE_BANK_MAX - 1) {
+            OTRfunc_800982FC(&play->objectCtx, i, cmdObj->objects[k]);
         }
-
-        i++;
-        k++;
-        objectEntry++;
-        status++;
     }
 
     play->objectCtx.num = i;
-    */
 
     return false;
 }
diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c
index 79a3c8ace..dfb3e4407 100644
--- a/soh/src/code/z_actor.c
+++ b/soh/src/code/z_actor.c
@@ -1219,8 +1219,7 @@ void Actor_Init(Actor* actor, PlayState* play) {
     CollisionCheck_InitInfo(&actor->colChkInfo);
     actor->floorBgId = BGCHECK_SCENE;
     ActorShape_Init(&actor->shape, 0.0f, NULL, 0.0f);
-    //if (Object_IsLoaded(&play->objectCtx, actor->objBankIndex))
-    {
+    if (Object_IsLoaded(&play->objectCtx, actor->objBankIndex)) {
         //Actor_SetObjectDependency(play, actor);
         actor->init(actor, play);
         actor->init = NULL;
@@ -3129,6 +3128,9 @@ void Actor_FreeOverlay(ActorDBEntry* dbEntry) {
     osSyncPrintf(VT_RST);
 }
 
+// SoH: Flag to check if actors are being spawned from the actor entry list
+//      This flag is checked against to allow actors which dont have an objectBankIndex in the objectCtx slot/status array to spawn
+//      An example of what this fixes, is that it allows hookshot to be used as child
 int gMapLoading = 0;
 
 Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 posX, f32 posY, f32 posZ,
diff --git a/soh/src/code/z_scene.c b/soh/src/code/z_scene.c
index 2a0a5d5d7..579e84eda 100644
--- a/soh/src/code/z_scene.c
+++ b/soh/src/code/z_scene.c
@@ -83,9 +83,10 @@ void Object_UpdateBank(ObjectContext* objectCtx) {
     RomFile* objectFile;
     size_t size;
 
-    /*
+
     for (i = 0; i < objectCtx->num; i++) {
         if (status->id < 0) {
+            /*
             if (status->dmaRequest.vromAddr == 0) {
                 osCreateMesgQueue(&status->loadQueue, &status->loadMsg, 1);
                 objectFile = &gObjectTable[-status->id];
@@ -96,10 +97,12 @@ void Object_UpdateBank(ObjectContext* objectCtx) {
             } else if (!osRecvMesg(&status->loadQueue, NULL, OS_MESG_NOBLOCK)) {
                 status->id = -status->id;
             }
+            */
+           status->id = -status->id;
         }
         status++;
     }
-    */
+
 }
 
 s32 Object_GetIndex(ObjectContext* objectCtx, s16 objectId) {