Almost match CScriptMailbox

This commit is contained in:
Henrique Gemignani Passos Lima 2022-11-03 16:21:47 +02:00
parent 9e400ca7cd
commit 99f27bda6e
No known key found for this signature in database
GPG Key ID: E224F951761145F8
6 changed files with 131 additions and 14 deletions

View File

@ -5,12 +5,7 @@
#include "Kyoto/CObjectReference.hpp" #include "Kyoto/CObjectReference.hpp"
#include "MetroidPrime/TGameTypes.hpp" #include "MetroidPrime/TGameTypes.hpp"
#include "MetroidPrime/Player/CWorldSaveGameInfo.hpp"
class CWorldSaveGameInfo {
// TODO: move to it's own file
public:
enum EScanCategory { kSC_None, kSC_Data, kSC_Lore, kSC_Creature, kSC_Research, kSC_Artifact };
};
class CMemoryCard { class CMemoryCard {
public: public:

View File

@ -6,8 +6,8 @@
#include "MetroidPrime/CGameArea.hpp" #include "MetroidPrime/CGameArea.hpp"
#include "MetroidPrime/TGameTypes.hpp" #include "MetroidPrime/TGameTypes.hpp"
#include "Kyoto/IObjectStore.hpp"
#include "Kyoto/Audio/CSfxHandle.hpp" #include "Kyoto/Audio/CSfxHandle.hpp"
#include "Kyoto/IObjectStore.hpp"
#include "rstl/string.hpp" #include "rstl/string.hpp"
@ -37,6 +37,20 @@ class CSoundGroupData;
class IDvdRequest; class IDvdRequest;
class IFactory; class IFactory;
class CRelay {
public:
const TEditorId& GetRelayId() const { return x0_relay; }
const TEditorId& GetTargetId() const { return x4_target; }
ushort GetMessage() const { return x8_msg; }
bool GetActive() const { return xa_active; }
private:
TEditorId x0_relay;
TEditorId x4_target;
ushort x8_msg;
bool xa_active;
};
// TODO move? // TODO move?
enum EEnvFxType { enum EEnvFxType {
kEFX_None, kEFX_None,
@ -66,8 +80,10 @@ public:
bool IsAreaValid(TAreaId id) const { return GetArea(id)->IsLoaded(); } bool IsAreaValid(TAreaId id) const { return GetArea(id)->IsLoaded(); }
CAssetId GetWorldAssetId() const { return x8_mlvlId; } CAssetId GetWorldAssetId() const { return x8_mlvlId; }
TAreaId GetAreaIdForSaveId(int saveId) const; TAreaId GetAreaIdForSaveId(int saveId) const;
const rstl::vector< CRelay >& GetRelays() const { return x2c_relays; }
static void PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGameArea* area, CWorld* world); static void PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGameArea* area,
CWorld* world);
private: private:
enum Phase { enum Phase {

View File

@ -0,0 +1,22 @@
#ifndef _CWORLDSAVEGAMEINFO
#define _CWORLDSAVEGAMEINFO
#include "MetroidPrime/TGameTypes.hpp"
#include "rstl/vector.hpp"
class CWorldSaveGameInfo {
public:
enum EScanCategory { kSC_None, kSC_Data, kSC_Lore, kSC_Creature, kSC_Research, kSC_Artifact };
int GetRelayIndex(const TEditorId&) const;
const rstl::vector<TEditorId>& GetRelays() const { return x14_relays; }
private:
uint x0_areaCount;
rstl::vector<TEditorId> x4_cinematics;
rstl::vector<TEditorId> x14_relays;
};
#endif // _CWORLDSAVEGAMEINFO

View File

@ -33,8 +33,8 @@ struct TEditorId {
TEditorId(CInputStream& in); TEditorId(CInputStream& in);
// TODO // TODO
uint Value() const { return value & 0x3FFFFFF; } uint Value() const { return value & 0x3FFFFFF; }
uint Id() const { return value; } uint Id() const { return value & 0xffff; }
uint AreaNum() const { return value; } int AreaNum() const { return (value >> 16) & 0x3ff; }
void PutTo(COutputStream&) const; void PutTo(COutputStream&) const;

View File

@ -70,7 +70,17 @@ public:
inline const T& back() const { return data()[x0_count - 1]; } inline const T& back() const { return data()[x0_count - 1]; }
inline T& operator[](int idx) { return data()[idx]; } inline T& operator[](int idx) { return data()[idx]; }
inline const T& operator[](int idx) const { return data()[idx]; } inline const T& operator[](int idx) const { return data()[idx]; }
iterator erase(iterator it) {} void erase(iterator it) {
if (it < begin()) {
return;
}
if (it < end()) {
for (iterator j = it; j < end() - 1; ++j) {
*j = *(j + 1);
}
--x0_count;
}
}
}; };
} // namespace rstl } // namespace rstl

View File

@ -1,18 +1,84 @@
#include "MetroidPrime/CScriptMailbox.hpp" #include "MetroidPrime/CScriptMailbox.hpp"
#include "MetroidPrime/CStateManager.hpp"
#include "MetroidPrime/CWorld.hpp"
#include "MetroidPrime/Player/CWorldSaveGameInfo.hpp"
#include "Kyoto/Streams/CInputStream.hpp" #include "Kyoto/Streams/CInputStream.hpp"
#include "Kyoto/Streams/COutputStream.hpp"
CScriptMailbox::CScriptMailbox() { CMemory::OffsetFakeStatics(sizeof(*this)); } CScriptMailbox::CScriptMailbox() { CMemory::OffsetFakeStatics(sizeof(*this)); }
CScriptMailbox::CScriptMailbox(CInputStream& in, const CWorldSaveGameInfo& world) { CScriptMailbox::CScriptMailbox(CInputStream& in, const CWorldSaveGameInfo& world) {
rstl::vector< bool > relayStates(world.GetRelays().size(), false);
for (int i = 0; i < relayStates.size(); ++i) {
relayStates[i] = in.ReadBits(1);
}
for (int i = 0; i < relayStates.size(); ++i) {
if (relayStates[i]) {
TEditorId it = world.GetRelays()[i];
x0_relays.push_back(it);
}
}
CMemory::OffsetFakeStatics(sizeof(*this)); CMemory::OffsetFakeStatics(sizeof(*this));
} }
CScriptMailbox::~CScriptMailbox() { CMemory::OffsetFakeStatics(-sizeof(*this)); } CScriptMailbox::~CScriptMailbox() { CMemory::OffsetFakeStatics(-sizeof(*this)); }
void CScriptMailbox::PutTo(COutputStream& out, CWorldSaveGameInfo& world) const {} void CScriptMailbox::PutTo(COutputStream& out, CWorldSaveGameInfo& world) const {
rstl::vector< bool > relayStates(world.GetRelays().size(), false);
void CScriptMailbox::SendMsgs(const TAreaId& area, CStateManager& mgr) {} for (rstl::reserved_vector< TEditorId, 512 >::const_iterator it = x0_relays.begin();
it != x0_relays.end(); ++it) {
TEditorId id = *it;
relayStates[world.GetRelayIndex(id)] = true;
}
for (int i = 0; i < relayStates.size(); ++i) {
out.WriteBits(relayStates[i] ? 1 : 0, 1);
}
}
void CScriptMailbox::SendMsgs(const TAreaId& areaId, CStateManager& mgr) {
CWorld* world = mgr.World();
if (world->GetRelays().size() <= 0) {
return;
}
bool hasActiveRelays = false;
for (rstl::vector< CRelay >::const_iterator it = world->GetRelays().begin();
it != world->GetRelays().end(); ++it) {
TEditorId targetId = it->GetTargetId();
if (targetId.AreaNum() != areaId.Value())
continue;
TEditorId relayId = it->GetRelayId();
if (HasMsg(relayId)) {
mgr.SendScriptMsg(kInvalidUniqueId, targetId, EScriptObjectMessage(it->GetMessage()), kSS_Any);
if (it->GetActive()) {
hasActiveRelays = true;
}
}
}
if (!hasActiveRelays)
return;
for (rstl::vector< CRelay >::const_iterator it = world->GetRelays().begin();
it != world->GetRelays().end(); ++it) {
if (it->GetTargetId().AreaNum() != areaId.Value())
continue;
TEditorId relayId = it->GetRelayId();
if (HasMsg(relayId) && it->GetActive()) {
RemoveMsg(relayId);
}
}
}
void CScriptMailbox::AddMsg(TEditorId id) { void CScriptMailbox::AddMsg(TEditorId id) {
rstl::reserved_vector< TEditorId, 512 >::iterator iter = x0_relays.begin(); rstl::reserved_vector< TEditorId, 512 >::iterator iter = x0_relays.begin();
@ -25,7 +91,15 @@ void CScriptMailbox::AddMsg(TEditorId id) {
x0_relays.push_back(id); x0_relays.push_back(id);
} }
void CScriptMailbox::RemoveMsg(TEditorId id) {} void CScriptMailbox::RemoveMsg(TEditorId id) {
rstl::reserved_vector< TEditorId, 512 >::iterator iter = x0_relays.begin();
for (; iter != x0_relays.end(); ++iter) {
if (*iter == id) {
x0_relays.erase(iter);
return;
}
}
}
bool CScriptMailbox::HasMsg(TEditorId id) const { bool CScriptMailbox::HasMsg(TEditorId id) const {
rstl::reserved_vector< TEditorId, 512 >::const_iterator iter = x0_relays.begin(); rstl::reserved_vector< TEditorId, 512 >::const_iterator iter = x0_relays.begin();