#include "Runtime/CScriptMailbox.hpp" #include "Runtime/CWorldSaveGameInfo.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/World/CWorld.hpp" #include <algorithm> namespace metaforce { CScriptMailbox::CScriptMailbox(CInputStream& in, const CWorldSaveGameInfo& saveWorld) { const u32 relayCount = saveWorld.GetRelayCount(); if (saveWorld.GetRelayCount()) { std::vector<bool> relayStates(saveWorld.GetRelayCount()); for (u32 i = 0; i < relayCount; ++i) { relayStates[i] = in.ReadBits(1); } for (u32 i = 0; i < relayCount; ++i) { if (!relayStates[i]) { continue; } x0_relays.push_back(saveWorld.GetRelayEditorId(i)); } } } bool CScriptMailbox::HasMsg(TEditorId id) const { return std::find(x0_relays.cbegin(), x0_relays.cend(), id) != x0_relays.cend(); } void CScriptMailbox::AddMsg(TEditorId id) { if (HasMsg(id)) { return; } x0_relays.push_back(id); } void CScriptMailbox::RemoveMsg(TEditorId id) { if (!HasMsg(id)) { return; } std::erase(x0_relays, id); } void CScriptMailbox::SendMsgs(TAreaId areaId, CStateManager& stateMgr) { const CWorld* world = stateMgr.GetWorld(); u32 relayCount = world->GetRelayCount(); bool hasActiveRelays = false; for (u32 i = 0; i < relayCount; ++i) { const CWorld::CRelay& relay = world->GetRelay(i); if (relay.GetTargetId().AreaNum() != areaId) continue; if (!HasMsg(relay.GetRelayId())) continue; stateMgr.SendScriptMsg(kInvalidUniqueId, relay.GetTargetId(), EScriptObjectMessage(relay.GetMessage()), EScriptObjectState::Any); if (relay.GetActive()) hasActiveRelays = true; } if (!hasActiveRelays) return; for (u32 i = 0; i < relayCount; ++i) { const CWorld::CRelay& relay = world->GetRelay(i); if (relay.GetTargetId().AreaNum() != areaId) continue; if (!HasMsg(relay.GetRelayId()) || !relay.GetActive()) continue; RemoveMsg(relay.GetRelayId()); } } void CScriptMailbox::PutTo(COutputStream& out, const CWorldSaveGameInfo& saveWorld) { const u32 relayCount = saveWorld.GetRelayCount(); std::vector<bool> relays(relayCount); for (const TEditorId& id : x0_relays) { const s32 idx = saveWorld.GetRelayIndex(id); if (idx >= 0) { relays[idx] = true; } } for (u32 i = 0; i < relayCount; ++i) { out.WriteBits(u32(relays[i]), 1); } } } // namespace metaforce