mirror of https://github.com/PrimeDecomp/prime.git
91 lines
3.1 KiB
C++
91 lines
3.1 KiB
C++
#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.ObjectListById(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.DeliverScriptMsg(it->first, GetUniqueId(), it->second);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
SendScriptMsgs(state, stateMgr, kSM_None);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CScriptRandomRelay::Accept(IVisitor& visitor) { visitor.Visit(*this); }
|