metaforce/Runtime/World/CScriptGenerator.cpp

140 lines
5.0 KiB
C++
Raw Normal View History

2016-04-20 21:44:18 +00:00
#include "CScriptGenerator.hpp"
2016-12-22 02:48:22 +00:00
#include "CStateManager.hpp"
2017-01-24 17:23:10 +00:00
#include "CWallCrawlerSwarm.hpp"
2017-01-15 03:07:01 +00:00
#include "TCastTo.hpp"
2016-04-20 21:44:18 +00:00
namespace urde
{
2017-11-13 06:19:18 +00:00
CScriptGenerator::CScriptGenerator(TUniqueId uid, std::string_view name, const CEntityInfo& info, u32 spawnCount,
bool noReuseFollowers, const zeus::CVector3f& vec1, bool noInheritXf, bool active,
float minScale, float maxScale)
2017-01-24 17:23:10 +00:00
: CEntity(uid, info, active, name)
, x34_spawnCount(spawnCount)
, x38_24_noReuseFollowers(noReuseFollowers)
, x38_25_noInheritTransform(noInheritXf)
2017-01-24 17:23:10 +00:00
, x3c_offset(vec1)
, x48_minScale(minScale)
, x4c_maxScale(maxScale)
2016-04-20 21:44:18 +00:00
{
}
2016-05-03 08:27:28 +00:00
2017-01-24 17:23:10 +00:00
void CScriptGenerator::Accept(IVisitor& visitor) { visitor.Visit(this); }
2017-01-15 03:07:01 +00:00
void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& stateMgr)
2016-05-03 08:27:28 +00:00
{
switch (msg)
2016-05-03 08:27:28 +00:00
{
case EScriptObjectMessage::SetToZero:
{
if (!GetActive())
break;
2017-01-31 11:21:45 +00:00
std::vector<TUniqueId> follows;
follows.reserve(x20_conns.size());
for (const SConnection& conn : x20_conns)
2017-01-24 17:23:10 +00:00
{
2017-01-31 11:21:45 +00:00
if (conn.x0_state != EScriptObjectState::Zero || conn.x4_msg != EScriptObjectMessage::Follow)
continue;
2017-01-24 17:23:10 +00:00
2017-01-31 11:21:45 +00:00
TUniqueId uid = stateMgr.GetIdForScript(conn.x8_objId);
if (stateMgr.GetObjectById(uid) != nullptr)
follows.push_back(uid);
}
2017-01-24 17:23:10 +00:00
if (follows.empty())
follows.push_back(sender);
2017-01-31 11:21:45 +00:00
std::vector<std::pair<TUniqueId, TEditorId>> activates;
activates.reserve(x20_conns.size());
2017-01-24 17:23:10 +00:00
2017-01-31 11:21:45 +00:00
for (const SConnection& conn : x20_conns)
{
if (conn.x0_state != EScriptObjectState::Zero)
continue;
2017-01-24 17:23:10 +00:00
2017-01-31 11:21:45 +00:00
TUniqueId uid = stateMgr.GetIdForScript(conn.x8_objId);
if (uid == kInvalidUniqueId)
continue;
2017-01-24 17:23:10 +00:00
if (conn.x4_msg == EScriptObjectMessage::Activate)
2017-01-31 11:21:45 +00:00
{
if (!stateMgr.GetObjectById(uid))
continue;
activates.emplace_back(uid, conn.x8_objId);
2017-01-24 17:23:10 +00:00
}
stateMgr.SendScriptMsgAlways(GetUniqueId(), uid, conn.x4_msg);
2017-01-31 11:21:45 +00:00
}
if (activates.empty())
break;
2017-01-31 11:21:45 +00:00
for (u32 i = 0; i < x34_spawnCount; ++i)
{
if (activates.size() == 0 || follows.size() == 0)
break;
2017-01-31 11:21:45 +00:00
u32 activatesRand = 0.99f * (stateMgr.GetActiveRandom()->Float() * activates.size());
u32 followsRand = 0.99f * (stateMgr.GetActiveRandom()->Float() * follows.size());
2017-01-24 17:23:10 +00:00
2017-01-31 11:21:45 +00:00
for (u32 j = 0; j < activates.size(); ++j)
if (TCastToConstPtr<CScriptSound>(stateMgr.GetObjectById(activates[j].first)))
activatesRand = j;
2017-01-24 17:23:10 +00:00
2017-01-31 11:21:45 +00:00
std::pair<TUniqueId, TEditorId> idPair = activates[activatesRand];
CEntity* activate = stateMgr.ObjectById(idPair.first);
CEntity* follow = stateMgr.ObjectById(follows[followsRand]);
2017-01-24 17:23:10 +00:00
2017-01-31 11:21:45 +00:00
if (!activate || !follow)
break;
2017-01-24 17:23:10 +00:00
2017-01-31 11:21:45 +00:00
bool oldGeneratingObject = stateMgr.GetIsGeneratingObject();
stateMgr.SetIsGeneratingObject(true);
std::pair<TEditorId, TUniqueId> objId = stateMgr.GenerateObject(idPair.second);
stateMgr.SetIsGeneratingObject(oldGeneratingObject);
2017-01-24 17:23:10 +00:00
2017-01-31 11:21:45 +00:00
if (objId.second != kInvalidUniqueId)
{
if (CEntity* genObj = stateMgr.ObjectById(objId.second))
2017-01-24 17:23:10 +00:00
{
TCastToPtr<CActor> activateActor(genObj);
TCastToPtr<CActor> followActor(follow);
TCastToPtr<CWallCrawlerSwarm> wallCrawlerSwarm(follow);
2017-01-24 17:23:10 +00:00
if (activateActor && wallCrawlerSwarm)
{
if (!x38_25_noInheritTransform)
2017-01-24 17:23:10 +00:00
activateActor->SetTransform(wallCrawlerSwarm->GetTransform());
activateActor->SetTranslation(wallCrawlerSwarm->GetLastKilledOffset() + x3c_offset);
}
else if (activateActor && followActor)
{
if (!x38_25_noInheritTransform)
2017-01-24 17:23:10 +00:00
activateActor->SetTransform(followActor->GetTransform());
activateActor->SetTranslation(followActor->GetTranslation() + x3c_offset);
2017-01-24 17:23:10 +00:00
}
2017-01-31 11:21:45 +00:00
float rnd = stateMgr.GetActiveRandom()->Range(x48_minScale, x4c_maxScale);
CModelData* mData = activateActor->ModelData();
if (mData && !mData->IsNull())
2017-01-31 11:21:45 +00:00
mData->SetScale(rnd * mData->GetScale());
stateMgr.SendScriptMsg(genObj, GetUniqueId(), EScriptObjectMessage::Activate);
}
2017-01-24 17:23:10 +00:00
}
activates.erase(std::find(activates.begin(), activates.end(), idPair));
if (x38_24_noReuseFollowers)
follows.erase(std::find(follows.begin(), follows.end(), follows[followsRand]));
2017-01-24 17:23:10 +00:00
}
break;
}
default:
break;
2016-05-03 08:27:28 +00:00
}
CEntity::AcceptScriptMsg(msg, sender, stateMgr);
2016-05-03 08:27:28 +00:00
}
} // namespace urde