mirror of
https://github.com/PrimeDecomp/prime.git
synced 2025-12-09 22:27:40 +00:00
Add CScriptGenerator
What is even that AcceptScriptMsg
This commit is contained in:
175
src/MetroidPrime/ScriptObjects/CScriptGenerator.cpp
Normal file
175
src/MetroidPrime/ScriptObjects/CScriptGenerator.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
#include "MetroidPrime/ScriptObjects/CScriptGenerator.hpp"
|
||||
|
||||
#include "MetroidPrime/CActor.hpp"
|
||||
#include "MetroidPrime/CStateManager.hpp"
|
||||
#include "MetroidPrime/Enemies/CWallCrawlerSwarm.hpp"
|
||||
|
||||
#include "rstl/algorithm.hpp"
|
||||
|
||||
CScriptGenerator::CScriptGenerator(TUniqueId uid, const rstl::string& name, const CEntityInfo& info,
|
||||
int spawnCount, bool noReuseFollowers, const CVector3f& vec1,
|
||||
bool noInheritXf, bool active, float minScale, float maxScale)
|
||||
: CEntity(uid, info, active, name)
|
||||
, x34_spawnCount(spawnCount)
|
||||
, x38_24_noReuseFollowers(noReuseFollowers)
|
||||
, x38_25_noInheritTransform(noInheritXf)
|
||||
, x3c_offset(vec1)
|
||||
, x48_minScale(minScale)
|
||||
, x4c_maxScale(maxScale) {}
|
||||
|
||||
CScriptGenerator::~CScriptGenerator() {}
|
||||
|
||||
void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender,
|
||||
CStateManager& stateMgr) {
|
||||
switch (msg) {
|
||||
case kSM_SetToZero: {
|
||||
if (!GetActive()) {
|
||||
break;
|
||||
}
|
||||
|
||||
rstl::vector< TUniqueId > follows;
|
||||
int connectionsCount = GetConnectionList().size();
|
||||
int reseveSize = 1;
|
||||
if (connectionsCount != 0) {
|
||||
reseveSize = connectionsCount;
|
||||
}
|
||||
follows.reserve(reseveSize);
|
||||
rstl::vector< SConnection >::const_iterator iter = GetConnectionList().begin();
|
||||
for (; iter != GetConnectionList().end(); ++iter) {
|
||||
if (iter->x0_state != kSS_Zero || iter->x4_msg != kSM_Follow) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const TUniqueId uid = stateMgr.GetIdForScript(iter->x8_objId);
|
||||
if (uid != kInvalidUniqueId) {
|
||||
const CEntity* entity = stateMgr.GetObjectById(uid);
|
||||
if (entity && entity->GetActive()) {
|
||||
follows.push_back(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (follows.empty()) {
|
||||
follows.push_back(sender);
|
||||
}
|
||||
|
||||
rstl::vector< rstl::pair< TUniqueId, TEditorId > > activates;
|
||||
activates.reserve(GetConnectionList().size());
|
||||
|
||||
for (iter = GetConnectionList().begin(); iter != GetConnectionList().end(); ++iter) {
|
||||
if (iter->x0_state != kSS_Zero) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TUniqueId uid = stateMgr.GetIdForScript(iter->x8_objId);
|
||||
if (uid == kInvalidUniqueId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (iter->x4_msg == kSM_Activate) {
|
||||
if (!stateMgr.GetObjectById(uid)) {
|
||||
continue;
|
||||
}
|
||||
activates.push_back(rstl::pair< TUniqueId, TEditorId >(uid, iter->x8_objId));
|
||||
} else {
|
||||
stateMgr.SendScriptMsgAlways(uid, GetUniqueId(), iter->x4_msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (activates.empty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < x34_spawnCount; ++i) {
|
||||
if (activates.size() == 0 || follows.size() == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
int activatesRand = 0.99f * (stateMgr.Random()->Float() * activates.size());
|
||||
const int followsRand = 0.99f * (stateMgr.Random()->Float() * follows.size());
|
||||
|
||||
for (int j = 0; j < activates.size(); ++j) {
|
||||
if (TCastToConstPtr< CScriptSound >(stateMgr.GetObjectById(activates[j].first))) {
|
||||
activatesRand = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const rstl::pair< TUniqueId, TEditorId > idPair = activates[activatesRand];
|
||||
CEntity* activate = stateMgr.ObjectById(idPair.first);
|
||||
CEntity* follow = stateMgr.ObjectById(follows[followsRand]);
|
||||
|
||||
if (!activate || !follow) {
|
||||
break;
|
||||
}
|
||||
|
||||
const bool oldGeneratingObject = stateMgr.IsGeneratingObject();
|
||||
stateMgr.SetIsGeneratingObject(true);
|
||||
TUniqueId objId = stateMgr.GenerateObject(idPair.second).second;
|
||||
stateMgr.SetIsGeneratingObject(oldGeneratingObject);
|
||||
|
||||
if (objId != kInvalidUniqueId) {
|
||||
CEntity* genObj = stateMgr.ObjectById(objId);
|
||||
{
|
||||
CActor* activateActor = TCastToPtr< CActor >(genObj);
|
||||
const CActor* followActor = TCastToConstPtr< CActor >(follow);
|
||||
const CWallCrawlerSwarm* wallCrawlerSwarm = TCastToConstPtr< CWallCrawlerSwarm >(follow);
|
||||
|
||||
if (activateActor && wallCrawlerSwarm) {
|
||||
if (!x38_25_noInheritTransform) {
|
||||
activateActor->SetTransform(wallCrawlerSwarm->GetTransform());
|
||||
}
|
||||
activateActor->SetTranslation(wallCrawlerSwarm->GetLastKilledOffset() + x3c_offset);
|
||||
} else if (activateActor && followActor) {
|
||||
if (!x38_25_noInheritTransform) {
|
||||
activateActor->SetTransform(followActor->GetTransform());
|
||||
}
|
||||
activateActor->SetTranslation(followActor->GetTranslation() + x3c_offset);
|
||||
}
|
||||
}
|
||||
if (genObj) {
|
||||
CEntity* genObj = stateMgr.ObjectById(objId);
|
||||
CActor* activateActor = TCastToPtr< CActor >(genObj);
|
||||
const CActor* followActor = TCastToConstPtr< CActor >(follow);
|
||||
const CWallCrawlerSwarm* wallCrawlerSwarm = TCastToConstPtr< CWallCrawlerSwarm >(follow);
|
||||
|
||||
if (activateActor) {
|
||||
if (activateActor && wallCrawlerSwarm) {
|
||||
if (!x38_25_noInheritTransform) {
|
||||
activateActor->SetTransform(wallCrawlerSwarm->GetTransform());
|
||||
}
|
||||
activateActor->SetTranslation(wallCrawlerSwarm->GetLastKilledOffset() + x3c_offset);
|
||||
} else if (activateActor && followActor) {
|
||||
if (!x38_25_noInheritTransform) {
|
||||
activateActor->SetTransform(followActor->GetTransform());
|
||||
}
|
||||
activateActor->SetTranslation(followActor->GetTranslation() + x3c_offset);
|
||||
}
|
||||
}
|
||||
|
||||
const float rnd = stateMgr.Random()->Range(x48_minScale, x4c_maxScale);
|
||||
CModelData* mData = activateActor->ModelData();
|
||||
bool valid = mData && !mData->IsNull();
|
||||
if (valid) {
|
||||
mData->SetScale(rnd * mData->GetScale());
|
||||
}
|
||||
|
||||
stateMgr.SendScriptMsg(genObj, GetUniqueId(), kSM_Activate);
|
||||
}
|
||||
}
|
||||
|
||||
activates.erase(activates.begin() + activatesRand);
|
||||
if (x38_24_noReuseFollowers) {
|
||||
follows.erase(follows.begin() + followsRand);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CEntity::AcceptScriptMsg(msg, sender, stateMgr);
|
||||
}
|
||||
|
||||
void CScriptGenerator::Accept(IVisitor& visitor) { visitor.Visit(*this); }
|
||||
Reference in New Issue
Block a user