From f0235c1de16fb546024442e6d0a3682546e1e2f7 Mon Sep 17 00:00:00 2001 From: Henrique Gemignani Passos Lima Date: Wed, 9 Nov 2022 02:12:27 +0200 Subject: [PATCH] Add CScriptRandomRelay --- .../ScriptObjects/CScriptRandomRelay.s | 12 +-- configure.py | 2 +- include/MetroidPrime/CAnimRes.hpp | 2 +- .../Player/CWorldTransManager.hpp | 4 +- .../ScriptObjects/CScriptRandomRelay.hpp | 22 +++++ .../ScriptObjects/CScriptRandomRelay.cpp | 90 +++++++++++++++++++ 6 files changed, 122 insertions(+), 10 deletions(-) create mode 100644 include/MetroidPrime/ScriptObjects/CScriptRandomRelay.hpp create mode 100644 src/MetroidPrime/ScriptObjects/CScriptRandomRelay.cpp diff --git a/asm/MetroidPrime/ScriptObjects/CScriptRandomRelay.s b/asm/MetroidPrime/ScriptObjects/CScriptRandomRelay.s index e444a9bd..8084a28f 100644 --- a/asm/MetroidPrime/ScriptObjects/CScriptRandomRelay.s +++ b/asm/MetroidPrime/ScriptObjects/CScriptRandomRelay.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803DF870 -lbl_803DF870: +.global __vt__18CScriptRandomRelay +__vt__18CScriptRandomRelay: # ROM: 0x3DC870 .4byte 0 .4byte 0 @@ -461,9 +461,9 @@ __dt__18CScriptRandomRelayFv: /* 800E2CF8 000DFC58 93 C1 00 08 */ stw r30, 8(r1) /* 800E2CFC 000DFC5C 7C 7E 1B 79 */ or. r30, r3, r3 /* 800E2D00 000DFC60 41 82 00 28 */ beq lbl_800E2D28 -/* 800E2D04 000DFC64 3C A0 80 3E */ lis r5, lbl_803DF870@ha +/* 800E2D04 000DFC64 3C A0 80 3E */ lis r5, __vt__18CScriptRandomRelay@ha /* 800E2D08 000DFC68 38 80 00 00 */ li r4, 0 -/* 800E2D0C 000DFC6C 38 05 F8 70 */ addi r0, r5, lbl_803DF870@l +/* 800E2D0C 000DFC6C 38 05 F8 70 */ addi r0, r5, __vt__18CScriptRandomRelay@l /* 800E2D10 000DFC70 90 1E 00 00 */ stw r0, 0(r30) /* 800E2D14 000DFC74 4B F6 E5 61 */ bl __dt__7CEntityFv /* 800E2D18 000DFC78 7F E0 07 35 */ extsh. r0, r31 @@ -500,9 +500,9 @@ lbl_800E2D28: /* 800E2D84 000DFCE4 7C 87 23 78 */ mr r7, r4 /* 800E2D88 000DFCE8 38 81 00 08 */ addi r4, r1, 8 /* 800E2D8C 000DFCEC 4B F6 E5 99 */ bl "__ct__7CEntityF9TUniqueIdRC11CEntityInfobRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>" -/* 800E2D90 000DFCF0 3C 60 80 3E */ lis r3, lbl_803DF870@ha +/* 800E2D90 000DFCF0 3C 60 80 3E */ lis r3, __vt__18CScriptRandomRelay@ha /* 800E2D94 000DFCF4 57 E0 06 3F */ clrlwi. r0, r31, 0x18 -/* 800E2D98 000DFCF8 38 63 F8 70 */ addi r3, r3, lbl_803DF870@l +/* 800E2D98 000DFCF8 38 63 F8 70 */ addi r3, r3, __vt__18CScriptRandomRelay@l /* 800E2D9C 000DFCFC 90 7C 00 00 */ stw r3, 0(r28) /* 800E2DA0 000DFD00 93 BC 00 34 */ stw r29, 0x34(r28) /* 800E2DA4 000DFD04 93 DC 00 38 */ stw r30, 0x38(r28) diff --git a/configure.py b/configure.py index aebf9f24..5e187ea5 100755 --- a/configure.py +++ b/configure.py @@ -136,7 +136,7 @@ LIBS = [ ["MetroidPrime/CScriptMailbox", False], ["MetroidPrime/ScriptObjects/CScriptRelay", True], ["MetroidPrime/ScriptObjects/CScriptSpawnPoint", False], - "MetroidPrime/ScriptObjects/CScriptRandomRelay", + ["MetroidPrime/ScriptObjects/CScriptRandomRelay", False], "MetroidPrime/Enemies/CBeetle", ["MetroidPrime/HUD/CHUDMemoParms", True], ["MetroidPrime/ScriptObjects/CScriptHUDMemo", True], diff --git a/include/MetroidPrime/CAnimRes.hpp b/include/MetroidPrime/CAnimRes.hpp index a922413b..14b0c658 100644 --- a/include/MetroidPrime/CAnimRes.hpp +++ b/include/MetroidPrime/CAnimRes.hpp @@ -20,7 +20,7 @@ public: // CAnimRes() // : x4_charIdx(-1), x14_canLoop(false), x8_scale(????), x18_defaultAnim(-1) {} - CAnimRes(CAssetId ancs, int charIdx, const CVector3f& scale, const int defaultAnim, bool loop) + CAnimRes(CAssetId ancs, const int charIdx, const CVector3f& scale, const int defaultAnim, const bool loop) : x0_ancsId(ancs) , x4_charIdx(charIdx) , x8_scale(scale) diff --git a/include/MetroidPrime/Player/CWorldTransManager.hpp b/include/MetroidPrime/Player/CWorldTransManager.hpp index 13c1b47f..141586b8 100644 --- a/include/MetroidPrime/Player/CWorldTransManager.hpp +++ b/include/MetroidPrime/Player/CWorldTransManager.hpp @@ -1,7 +1,7 @@ #ifndef _CWORLDTRANSMANAGER #define _CWORLDTRANSMANAGER -#include "types.h" +#include "Kyoto/SObjectTag.hpp" class CAnimRes; class CVector3f; @@ -14,7 +14,7 @@ public: void SfxStart(); void SfxStop(); - void EnableTransition(const CAnimRes&, unsigned int, const CVector3f&, unsigned int, const CVector3f&, bool); + void EnableTransition(const CAnimRes&, const CAssetId, const CVector3f&, const CAssetId, const CVector3f&, bool); void EnableTransition(int fontId, int stringId, int stringIdx, bool fadeWhite, float chFadeTime, float chFadeRate, float textStartTime); void DisableTransition(); diff --git a/include/MetroidPrime/ScriptObjects/CScriptRandomRelay.hpp b/include/MetroidPrime/ScriptObjects/CScriptRandomRelay.hpp new file mode 100644 index 00000000..b5e98a7c --- /dev/null +++ b/include/MetroidPrime/ScriptObjects/CScriptRandomRelay.hpp @@ -0,0 +1,22 @@ +#ifndef _CSCRIPTRANDOMRELAY +#define _CSCRIPTRANDOMRELAY + +#include "MetroidPrime/CEntity.hpp" + +class CScriptRandomRelay : public CEntity { +public: + CScriptRandomRelay(TUniqueId uid, const rstl::string& name, const CEntityInfo& info, + int sendSetSize, int sendSetVariance, bool percentSize, bool active); + ~CScriptRandomRelay(); + + void Accept(IVisitor& visitor) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) override; + void SendLocalScriptMsgs(EScriptObjectState state, CStateManager& stateMgr); + +private: + int x34_sendSetSize; + int x38_sendSetVariance; + bool x3c_percentSize; +}; + +#endif // _CSCRIPTRANDOMRELAY diff --git a/src/MetroidPrime/ScriptObjects/CScriptRandomRelay.cpp b/src/MetroidPrime/ScriptObjects/CScriptRandomRelay.cpp new file mode 100644 index 00000000..1f0a541f --- /dev/null +++ b/src/MetroidPrime/ScriptObjects/CScriptRandomRelay.cpp @@ -0,0 +1,90 @@ +#include "MetroidPrime/ScriptObjects/CScriptRandomRelay.hpp" + +#include "MetroidPrime/CStateManager.hpp" + +#include "rstl/math.hpp" + +CScriptRandomRelay::CScriptRandomRelay(TUniqueId uid, const rstl::string& name, + const CEntityInfo& info, int sendSetSize, + int sendSetVariance, bool percentSize, bool active) +: CEntity(uid, info, active, name) +, x34_sendSetSize(sendSetSize) +, x38_sendSetVariance(sendSetVariance) +, x3c_percentSize(percentSize) { + if (percentSize && x34_sendSetSize > 100) { + x34_sendSetSize = 100; + } +} + +CScriptRandomRelay::~CScriptRandomRelay() {} + +void CScriptRandomRelay::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, + CStateManager& stateMgr) { + CEntity::AcceptScriptMsg(msg, objId, stateMgr); + switch (msg) { + case kSM_SetToZero: + if (GetActive()) { + SendLocalScriptMsgs(kSS_Zero, stateMgr); + } + break; + default: + break; + } +} + +void CScriptRandomRelay::SendLocalScriptMsgs(EScriptObjectState state, CStateManager& stateMgr) { + switch (state) { + case kSS_Zero: { + rstl::vector< rstl::pair< CEntity*, EScriptObjectMessage > > objs; + objs.reserve(10); + + rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin(); + for (; conn != GetConnectionList().end(); ++conn) { + if (conn->x0_state == kSS_Zero) { + CObjectList& objList = stateMgr.GetObjectListById(kOL_All); + CStateManager::TIdListResult list = stateMgr.GetIdListForScript(conn->x8_objId); + if (!(list.first == list.second)) { + for (CStateManager::TIdList::const_iterator it = list.first; it != list.second; ++it) { + CEntity* ent = objList.GetObjectById(it->second); + if (ent && ent->GetActive()) { + objs.push_back(rstl::pair< CEntity*, EScriptObjectMessage >(ent, conn->x4_msg)); + } + } + } + } + } + + int targetSetSize = x3c_percentSize ? int(0.5f + (float(x34_sendSetSize * objs.size()) / 100.f)) + : x34_sendSetSize; + targetSetSize += + int(float(x38_sendSetVariance) * (stateMgr.Random()->Float() * 2.0f)) - x38_sendSetVariance; + + targetSetSize = rstl::min_val(rstl::max_val(0, targetSetSize), 64); + + while (objs.size() > targetSetSize) { + const int randomRemoveIdx = int(stateMgr.Random()->Float() * float(objs.size()) * 0.99f); + rstl::vector< rstl::pair< CEntity*, EScriptObjectMessage > >::iterator it = objs.begin(); + for (int i = 0; i < randomRemoveIdx; ++i) { + ++it; + if (it == objs.end()) { + break; + } + } + if (it != objs.end()) { + objs.erase(it); + } + } + + for (rstl::vector< rstl::pair< CEntity*, EScriptObjectMessage > >::iterator it = objs.begin(); + it != objs.end(); ++it) { + stateMgr.SendScriptMsg(it->first, GetUniqueId(), it->second); + } + break; + } + default: + SendScriptMsgs(state, stateMgr, kSM_None); + break; + } +} + +void CScriptRandomRelay::Accept(IVisitor& visitor) { visitor.Visit(*this); }