I hope this works

This commit is contained in:
David Markowitz 2023-06-06 20:48:30 -07:00
parent 716a5fcf37
commit ea9d0d8592
25 changed files with 1024 additions and 1014 deletions

View File

@ -121,6 +121,7 @@ enum class eReplicaComponentType : uint32_t {
BUILD_BORDER,
UNKNOWN_115,
CULLING_PLANE,
NUMBER_OF_COMPONENTS,
DESTROYABLE = 1000 // Actually 7
};

View File

@ -90,4 +90,11 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponent
return defaultValue;
#endif
}
std::vector<std::pair<eReplicaComponentType, uint32_t>> CDComponentsRegistryTable::GetTemplateComponents(LOT templateId) {
std::vector<std::pair<eReplicaComponentType, uint32_t>> components;
for (int8_t i = 0; static_cast<eReplicaComponentType>(i) < eReplicaComponentType::NUMBER_OF_COMPONENTS; i++) {
auto compId = GetByIDAndType(templateId, static_cast<eReplicaComponentType>(i), -1);
if (compId != -1) components.push_back(std::make_pair(static_cast<eReplicaComponentType>(i), compId));
}
return components;
}

View File

@ -2,6 +2,7 @@
// Custom Classes
#include "CDTable.h"
#include "dCommonVars.h"
enum class eReplicaComponentType : uint32_t;
struct CDComponentsRegistry {
@ -18,4 +19,5 @@ private:
public:
CDComponentsRegistryTable();
int32_t GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue = 0);
std::vector<std::pair<eReplicaComponentType, uint32_t>> GetTemplateComponents(LOT templateId);
};

View File

@ -427,7 +427,7 @@ void Character::SetPlayerFlag(const int32_t flagId, const bool value) {
auto* player = EntityManager::Instance()->GetEntity(m_ObjectID);
if (player != nullptr) {
auto* missionComponent = player->GetComponent<MissionComponent>();
auto missionComponent = player->GetComponent<MissionComponent>();
if (missionComponent != nullptr) {
missionComponent->Progress(eMissionTaskType::PLAYER_FLAG, flagId);
@ -538,7 +538,7 @@ void Character::OnZoneLoad() {
return;
}
auto* missionComponent = m_OurEntity->GetComponent<MissionComponent>();
auto missionComponent = m_OurEntity->GetComponent<MissionComponent>();
if (missionComponent != nullptr) {
// Fix the monument race flag
@ -563,7 +563,7 @@ void Character::OnZoneLoad() {
}
}
auto* inventoryComponent = m_OurEntity->GetComponent<InventoryComponent>();
auto inventoryComponent = m_OurEntity->GetComponent<InventoryComponent>();
if (inventoryComponent == nullptr) {
return;

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
#include <type_traits>
#include <unordered_map>
#include <vector>
#include <memory>
#include "NiPoint3.h"
#include "NiQuaternion.h"
@ -44,6 +45,8 @@ namespace CppScripts {
/**
* An entity in the world. Has multiple components.
*/
using ComponentPtr = std::shared_ptr<Component>;
class Entity {
public:
explicit Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity = nullptr);
@ -136,19 +139,17 @@ public:
* Component management
*/
Component* GetComponent(eReplicaComponentType componentID) const;
const ComponentPtr GetComponent(eReplicaComponentType componentID) const;
template<typename T>
T* GetComponent() const;
template<typename T>
bool TryGetComponent(eReplicaComponentType componentId, T*& component) const;
std::shared_ptr<T> GetComponent() const;
bool HasComponent(eReplicaComponentType componentId) const;
void AddComponent(eReplicaComponentType componentId, Component* component);
template<typename ComponentType, typename...ConstructorValues>
std::shared_ptr<ComponentType> AddComponent(ConstructorValues... arguments);
std::vector<ScriptComponent*> GetScriptComponents();
std::vector<std::shared_ptr<ScriptComponent>> GetScriptComponents();
void Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName);
void Unsubscribe(LWOOBJID scriptObjId, const std::string& notificationName);
@ -169,8 +170,6 @@ public:
void AddToGroup(const std::string& group);
bool IsPlayer() const;
std::unordered_map<eReplicaComponentType, Component*>& GetComponents() { return m_Components; } // TODO: Remove
void WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacketType packetType);
void WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType packetType);
void ResetFlags();
@ -320,7 +319,7 @@ protected:
std::vector<std::function<void()>> m_DieCallbacks;
std::vector<std::function<void(Entity* target)>> m_PhantomCollisionCallbacks;
std::unordered_map<eReplicaComponentType, Component*> m_Components;
std::unordered_map<eReplicaComponentType, ComponentPtr> m_Components;
std::vector<EntityTimer*> m_Timers;
std::vector<EntityTimer*> m_PendingTimers;
std::vector<EntityCallbackTimer*> m_CallbackTimers;
@ -345,31 +344,11 @@ protected:
std::vector<LWOOBJID> m_TargetsInPhantom;
};
/**
* Template definitions.
*/
template<typename T>
bool Entity::TryGetComponent(const eReplicaComponentType componentId, T*& component) const {
const auto& index = m_Components.find(componentId);
if (index == m_Components.end()) {
component = nullptr;
return false;
}
component = dynamic_cast<T*>(index->second);
return true;
}
template <typename T>
T* Entity::GetComponent() const {
return dynamic_cast<T*>(GetComponent(T::ComponentType));
std::shared_ptr<T> Entity::GetComponent() const {
return std::dynamic_pointer_cast<T>(GetComponent(T::ComponentType));
}
template<typename T>
const T& Entity::GetVar(const std::u16string& name) const {
auto* data = GetVarData(name);
@ -501,3 +480,10 @@ T Entity::GetNetworkVar(const std::u16string& name) {
return LDFData<T>::Default;
}
template<typename ComponentType, typename...ConstructorValues>
std::shared_ptr<ComponentType> Entity::AddComponent(ConstructorValues...arguments) {
if (GetComponent<ComponentType>()) return nullptr;
m_Components.insert_or_assign(ComponentType::ComponentType, std::make_shared<ComponentType>(arguments...));
}

View File

@ -0,0 +1,640 @@
Entity::Initialize() {
/**
* Setup trigger
*/
const auto triggerInfo = GetVarAsString(u"trigger_id");
if (!triggerInfo.empty()) m_Components.emplace(eReplicaComponentType::TRIGGER, new TriggerComponent(this, triggerInfo));
/**
* Setup groups
*/
const auto groupIDs = GetVarAsString(u"groupID");
if (!groupIDs.empty()) {
m_Groups = GeneralUtils::SplitString(groupIDs, ';');
m_Groups.erase(m_Groups.end() - 1);
}
/**
* Set ourselves as a child of our parent
*/
if (m_ParentEntity != nullptr) {
m_ParentEntity->AddChild(this);
}
// Get the registry table
CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
/**
* Special case for BBB models. They have components not corresponding to the registry.
*/
if (m_TemplateID == 14) {
const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SIMPLE_PHYSICS);
SimplePhysicsComponent* comp = new SimplePhysicsComponent(simplePhysicsComponentID, this);
m_Components.insert(std::make_pair(eReplicaComponentType::SIMPLE_PHYSICS, comp));
ModelComponent* modelcomp = new ModelComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::MODEL, modelcomp));
RenderComponent* render = new RenderComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render));
auto destroyableComponent = new DestroyableComponent(this);
destroyableComponent->SetHealth(1);
destroyableComponent->SetMaxHealth(1.0f);
destroyableComponent->SetFaction(-1, true);
destroyableComponent->SetIsSmashable(true);
m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, destroyableComponent));
// We have all our components.
return;
}
/**
* Go through all the components and check if this entity has them.
*
* Not all components are implemented. Some are represented by a nullptr, as they hold no data.
*/
if (GetParentUser()) {
auto missions = new MissionComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::MISSION, missions));
missions->LoadFromXml(m_Character->GetXMLDoc());
}
uint32_t petComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PET);
if (petComponentId > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::PET, new PetComponent(this, petComponentId)));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ZONE_CONTROL) > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::ZONE_CONTROL, nullptr));
}
uint32_t possessableComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::POSSESSABLE);
if (possessableComponentId > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::POSSESSABLE, new PossessableComponent(this, possessableComponentId)));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MODULE_ASSEMBLY) > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::MODULE_ASSEMBLY, new ModuleAssemblyComponent(this)));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_STATS) > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::RACING_STATS, nullptr));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::LUP_EXHIBIT, -1) >= 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::LUP_EXHIBIT, new LUPExhibitComponent(this)));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_CONTROL) > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::RACING_CONTROL, new RacingControlComponent(this)));
}
const auto propertyEntranceComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_ENTRANCE);
if (propertyEntranceComponentID > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::PROPERTY_ENTRANCE,
new PropertyEntranceComponent(propertyEntranceComponentID, this)));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CONTROLLABLE_PHYSICS) > 0) {
ControllablePhysicsComponent* controllablePhysics = new ControllablePhysicsComponent(this);
if (m_Character) {
controllablePhysics->LoadFromXml(m_Character->GetXMLDoc());
const auto mapID = Game::server->GetZoneID();
//If we came from another zone, put us in the starting loc
if (m_Character->GetZoneID() != Game::server->GetZoneID() || mapID == 1603) { // Exception for Moon Base as you tend to spawn on the roof.
NiPoint3 pos;
NiQuaternion rot;
const auto& targetSceneName = m_Character->GetTargetScene();
auto* targetScene = EntityManager::Instance()->GetSpawnPointEntity(targetSceneName);
if (m_Character->HasBeenToWorld(mapID) && targetSceneName.empty()) {
pos = m_Character->GetRespawnPoint(mapID);
rot = dZoneManager::Instance()->GetZone()->GetSpawnRot();
} else if (targetScene != nullptr) {
pos = targetScene->GetPosition();
rot = targetScene->GetRotation();
} else {
pos = dZoneManager::Instance()->GetZone()->GetSpawnPos();
rot = dZoneManager::Instance()->GetZone()->GetSpawnRot();
}
controllablePhysics->SetPosition(pos);
controllablePhysics->SetRotation(rot);
}
} else {
controllablePhysics->SetPosition(m_DefaultPosition);
controllablePhysics->SetRotation(m_DefaultRotation);
}
m_Components.insert(std::make_pair(eReplicaComponentType::CONTROLLABLE_PHYSICS, controllablePhysics));
}
// If an entity is marked a phantom, simple physics is made into phantom phyics.
bool markedAsPhantom = GetVar<bool>(u"markedAsPhantom");
const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SIMPLE_PHYSICS);
if (!markedAsPhantom && simplePhysicsComponentID > 0) {
SimplePhysicsComponent* comp = new SimplePhysicsComponent(simplePhysicsComponentID, this);
m_Components.insert(std::make_pair(eReplicaComponentType::SIMPLE_PHYSICS, comp));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS) > 0) {
RigidbodyPhantomPhysicsComponent* comp = new RigidbodyPhantomPhysicsComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS, comp));
}
if (markedAsPhantom || compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PHANTOM_PHYSICS) > 0) {
PhantomPhysicsComponent* phantomPhysics = new PhantomPhysicsComponent(this);
phantomPhysics->SetPhysicsEffectActive(false);
m_Components.insert(std::make_pair(eReplicaComponentType::PHANTOM_PHYSICS, phantomPhysics));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VEHICLE_PHYSICS) > 0) {
VehiclePhysicsComponent* vehiclePhysicsComponent = new VehiclePhysicsComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::VEHICLE_PHYSICS, vehiclePhysicsComponent));
vehiclePhysicsComponent->SetPosition(m_DefaultPosition);
vehiclePhysicsComponent->SetRotation(m_DefaultRotation);
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SOUND_TRIGGER, -1) != -1) {
auto* comp = new SoundTriggerComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::SOUND_TRIGGER, comp));
}
//Also check for the collectible id:
m_CollectibleID = GetVarAs<int32_t>(u"collectible_id");
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF) > 0) {
BuffComponent* comp = new BuffComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::BUFF, comp));
}
int collectibleComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::COLLECTIBLE);
if (collectibleComponentID > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::COLLECTIBLE, nullptr));
}
/**
* Multiple components require the destructible component.
*/
int buffComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF);
int rebuildComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD);
int componentID = 0;
if (collectibleComponentID > 0) componentID = collectibleComponentID;
if (rebuildComponentID > 0) componentID = rebuildComponentID;
if (buffComponentID > 0) componentID = buffComponentID;
CDDestructibleComponentTable* destCompTable = CDClientManager::Instance().GetTable<CDDestructibleComponentTable>();
std::vector<CDDestructibleComponent> destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); });
if (buffComponentID > 0 || collectibleComponentID > 0) {
DestroyableComponent* comp = new DestroyableComponent(this);
if (m_Character) {
comp->LoadFromXml(m_Character->GetXMLDoc());
} else {
if (componentID > 0) {
std::vector<CDDestructibleComponent> destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); });
if (destCompData.size() > 0) {
if (HasComponent(eReplicaComponentType::RACING_STATS)) {
destCompData[0].imagination = 60;
}
comp->SetHealth(destCompData[0].life);
comp->SetImagination(destCompData[0].imagination);
comp->SetArmor(destCompData[0].armor);
comp->SetMaxHealth(destCompData[0].life);
comp->SetMaxImagination(destCompData[0].imagination);
comp->SetMaxArmor(destCompData[0].armor);
comp->SetIsSmashable(destCompData[0].isSmashable);
comp->SetLootMatrixID(destCompData[0].LootMatrixIndex);
// Now get currency information
uint32_t npcMinLevel = destCompData[0].level;
uint32_t currencyIndex = destCompData[0].CurrencyIndex;
CDCurrencyTableTable* currencyTable = CDClientManager::Instance().GetTable<CDCurrencyTableTable>();
std::vector<CDCurrencyTable> currencyValues = currencyTable->Query([=](CDCurrencyTable entry) { return (entry.currencyIndex == currencyIndex && entry.npcminlevel == npcMinLevel); });
if (currencyValues.size() > 0) {
// Set the coins
comp->SetMinCoins(currencyValues[0].minvalue);
comp->SetMaxCoins(currencyValues[0].maxvalue);
}
// extraInfo overrides
comp->SetIsSmashable(GetVarAs<int32_t>(u"is_smashable") != 0);
}
} else {
comp->SetHealth(1);
comp->SetArmor(0);
comp->SetMaxHealth(1);
comp->SetMaxArmor(0);
comp->SetIsSmashable(true);
comp->AddFaction(-1);
comp->AddFaction(6); //Smashables
// A race car has 60 imagination, other entities defaults to 0.
comp->SetImagination(HasComponent(eReplicaComponentType::RACING_STATS) ? 60 : 0);
comp->SetMaxImagination(HasComponent(eReplicaComponentType::RACING_STATS) ? 60 : 0);
}
}
if (destCompData.size() > 0) {
comp->AddFaction(destCompData[0].faction);
std::stringstream ss(destCompData[0].factionList);
std::string token;
while (std::getline(ss, token, ',')) {
if (std::stoi(token) == destCompData[0].faction) continue;
if (token != "") {
comp->AddFaction(std::stoi(token));
}
}
}
m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, comp));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CHARACTER) > 0 || m_Character) {
// Character Component always has a possessor, level, and forced movement components
m_Components.insert(std::make_pair(eReplicaComponentType::POSSESSOR, new PossessorComponent(this)));
// load in the xml for the level
auto* levelComp = new LevelProgressionComponent(this);
levelComp->LoadFromXml(m_Character->GetXMLDoc());
m_Components.insert(std::make_pair(eReplicaComponentType::LEVEL_PROGRESSION, levelComp));
m_Components.insert(std::make_pair(eReplicaComponentType::PLAYER_FORCED_MOVEMENT, new PlayerForcedMovementComponent(this)));
CharacterComponent* charComp = new CharacterComponent(this, m_Character);
charComp->LoadFromXml(m_Character->GetXMLDoc());
m_Components.insert(std::make_pair(eReplicaComponentType::CHARACTER, charComp));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::INVENTORY) > 0 || m_Character) {
InventoryComponent* comp = nullptr;
if (m_Character) comp = new InventoryComponent(this, m_Character->GetXMLDoc());
else comp = new InventoryComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::INVENTORY, comp));
}
// if this component exists, then we initialize it. it's value is always 0
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ROCKET_LAUNCH_LUP, -1) != -1) {
auto comp = new RocketLaunchLupComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::ROCKET_LAUNCH_LUP, comp));
}
/**
* This is a bit of a mess
*/
CDScriptComponentTable* scriptCompTable = CDClientManager::Instance().GetTable<CDScriptComponentTable>();
int32_t scriptComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SCRIPT, -1);
std::string scriptName = "";
bool client = false;
if (scriptComponentID > 0 || m_Character) {
std::string clientScriptName;
if (!m_Character) {
CDScriptComponent scriptCompData = scriptCompTable->GetByID(scriptComponentID);
scriptName = scriptCompData.script_name;
clientScriptName = scriptCompData.client_script_name;
} else {
scriptName = "";
}
if (scriptName != "" || (scriptName == "" && m_Character)) {
} else if (clientScriptName != "") {
client = true;
} else if (!m_Character) {
client = true;
}
}
std::string customScriptServer;
bool hasCustomServerScript = false;
const auto customScriptServerName = GetVarAsString(u"custom_script_server");
const auto customScriptClientName = GetVarAsString(u"custom_script_client");
if (!customScriptServerName.empty()) {
customScriptServer = customScriptServerName;
hasCustomServerScript = true;
}
if (!customScriptClientName.empty()) {
client = true;
}
if (hasCustomServerScript && scriptName.empty()) {
scriptName = customScriptServer;
}
if (!scriptName.empty() || client || m_Character || scriptComponentID >= 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::SCRIPT, new ScriptComponent(this, scriptName, true, client && scriptName.empty())));
}
// ZoneControl script
if (m_TemplateID == 2365) {
CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable<CDZoneTableTable>();
const auto zoneID = dZoneManager::Instance()->GetZoneID();
const CDZoneTable* zoneData = zoneTable->Query(zoneID.GetMapID());
if (zoneData != nullptr) {
int zoneScriptID = zoneData->scriptID;
CDScriptComponent zoneScriptData = scriptCompTable->GetByID(zoneScriptID);
ScriptComponent* comp = new ScriptComponent(this, zoneScriptData.script_name, true);
m_Components.insert(std::make_pair(eReplicaComponentType::SCRIPT, comp));
}
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SKILL, -1) != -1 || m_Character) {
SkillComponent* comp = new SkillComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::SKILL, comp));
}
const auto combatAiId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BASE_COMBAT_AI);
if (combatAiId > 0) {
BaseCombatAIComponent* comp = new BaseCombatAIComponent(this, combatAiId);
m_Components.insert(std::make_pair(eReplicaComponentType::BASE_COMBAT_AI, comp));
}
if (int componentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD) > 0) {
RebuildComponent* comp = new RebuildComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::QUICK_BUILD, comp));
CDRebuildComponentTable* rebCompTable = CDClientManager::Instance().GetTable<CDRebuildComponentTable>();
std::vector<CDRebuildComponent> rebCompData = rebCompTable->Query([=](CDRebuildComponent entry) { return (entry.id == rebuildComponentID); });
if (rebCompData.size() > 0) {
comp->SetResetTime(rebCompData[0].reset_time);
comp->SetCompleteTime(rebCompData[0].complete_time);
comp->SetTakeImagination(rebCompData[0].take_imagination);
comp->SetInterruptible(rebCompData[0].interruptible);
comp->SetSelfActivator(rebCompData[0].self_activator);
comp->SetActivityId(rebCompData[0].activityID);
comp->SetPostImaginationCost(rebCompData[0].post_imagination_cost);
comp->SetTimeBeforeSmash(rebCompData[0].time_before_smash);
const auto rebuildResetTime = GetVar<float>(u"rebuild_reset_time");
if (rebuildResetTime != 0.0f) {
comp->SetResetTime(rebuildResetTime);
if (m_TemplateID == 9483) // Look away!
{
comp->SetResetTime(comp->GetResetTime() + 25);
}
}
const auto activityID = GetVar<int32_t>(u"activityID");
if (activityID > 0) {
comp->SetActivityId(activityID);
}
const auto compTime = GetVar<float>(u"compTime");
if (compTime > 0) {
comp->SetCompleteTime(compTime);
}
}
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SWITCH, -1) != -1) {
SwitchComponent* comp = new SwitchComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::SWITCH, comp));
}
if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VENDOR) > 0)) {
VendorComponent* comp = new VendorComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::VENDOR, comp));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_VENDOR, -1) != -1) {
auto* component = new PropertyVendorComponent(this);
m_Components.insert_or_assign(eReplicaComponentType::PROPERTY_VENDOR, component);
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_MANAGEMENT, -1) != -1) {
auto* component = new PropertyManagementComponent(this);
m_Components.insert_or_assign(eReplicaComponentType::PROPERTY_MANAGEMENT, component);
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BOUNCER, -1) != -1) { // you have to determine it like this because all bouncers have a componentID of 0
BouncerComponent* comp = new BouncerComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::BOUNCER, comp));
}
int32_t renderComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RENDER);
if ((renderComponentId > 0 && m_TemplateID != 2365) || m_Character) {
RenderComponent* render = new RenderComponent(this, renderComponentId);
m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render));
}
if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MISSION_OFFER) > 0) || m_Character) {
m_Components.insert(std::make_pair(eReplicaComponentType::MISSION_OFFER, new MissionOfferComponent(this, m_TemplateID)));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUILD_BORDER, -1) != -1) {
m_Components.insert(std::make_pair(eReplicaComponentType::BUILD_BORDER, new BuildBorderComponent(this)));
}
// Scripted activity component
int scriptedActivityID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SCRIPTED_ACTIVITY);
if ((scriptedActivityID > 0)) {
m_Components.insert(std::make_pair(eReplicaComponentType::SCRIPTED_ACTIVITY, new ScriptedActivityComponent(this, scriptedActivityID)));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MODEL, -1) != -1 && !GetComponent<PetComponent>()) {
m_Components.insert(std::make_pair(eReplicaComponentType::MODEL, new ModelComponent(this)));
if (m_Components.find(eReplicaComponentType::DESTROYABLE) == m_Components.end()) {
auto destroyableComponent = new DestroyableComponent(this);
destroyableComponent->SetHealth(1);
destroyableComponent->SetMaxHealth(1.0f);
destroyableComponent->SetFaction(-1, true);
destroyableComponent->SetIsSmashable(true);
m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, destroyableComponent));
}
}
PetComponent* petComponent;
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ITEM) > 0 && !TryGetComponent(eReplicaComponentType::PET, petComponent) && !HasComponent(eReplicaComponentType::MODEL)) {
m_Components.insert(std::make_pair(eReplicaComponentType::ITEM, nullptr));
}
// Shooting gallery component
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SHOOTING_GALLERY) > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::SHOOTING_GALLERY, new ShootingGalleryComponent(this)));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY, -1) != -1) {
m_Components.insert(std::make_pair(eReplicaComponentType::PROPERTY, new PropertyComponent(this)));
}
const int rocketId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ROCKET_LAUNCH);
if ((rocketId > 0)) {
m_Components.insert(std::make_pair(eReplicaComponentType::ROCKET_LAUNCH, new RocketLaunchpadControlComponent(this, rocketId)));
}
const int32_t railComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RAIL_ACTIVATOR);
if (railComponentID > 0) {
m_Components.insert(std::make_pair(eReplicaComponentType::RAIL_ACTIVATOR, new RailActivatorComponent(this, railComponentID)));
}
int movementAIID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVEMENT_AI);
if (movementAIID > 0) {
CDMovementAIComponentTable* moveAITable = CDClientManager::Instance().GetTable<CDMovementAIComponentTable>();
std::vector<CDMovementAIComponent> moveAIComp = moveAITable->Query([=](CDMovementAIComponent entry) {return (entry.id == movementAIID); });
if (moveAIComp.size() > 0) {
MovementAIInfo moveInfo = MovementAIInfo();
moveInfo.movementType = moveAIComp[0].MovementType;
moveInfo.wanderChance = moveAIComp[0].WanderChance;
moveInfo.wanderRadius = moveAIComp[0].WanderRadius;
moveInfo.wanderSpeed = moveAIComp[0].WanderSpeed;
moveInfo.wanderDelayMax = moveAIComp[0].WanderDelayMax;
moveInfo.wanderDelayMin = moveAIComp[0].WanderDelayMin;
bool useWanderDB = GetVar<bool>(u"usewanderdb");
if (!useWanderDB) {
const auto wanderOverride = GetVarAs<float>(u"wanderRadius");
if (wanderOverride != 0.0f) {
moveInfo.wanderRadius = wanderOverride;
}
}
m_Components.insert(std::make_pair(eReplicaComponentType::MOVEMENT_AI, new MovementAIComponent(this, moveInfo)));
}
} else if (petComponentId > 0 || combatAiId > 0 && GetComponent<BaseCombatAIComponent>()->GetTetherSpeed() > 0) {
MovementAIInfo moveInfo = MovementAIInfo();
moveInfo.movementType = "";
moveInfo.wanderChance = 0;
moveInfo.wanderRadius = 16;
moveInfo.wanderSpeed = 2.5f;
moveInfo.wanderDelayMax = 5;
moveInfo.wanderDelayMin = 2;
m_Components.insert(std::make_pair(eReplicaComponentType::MOVEMENT_AI, new MovementAIComponent(this, moveInfo)));
}
std::string pathName = GetVarAsString(u"attached_path");
const Path* path = dZoneManager::Instance()->GetZone()->GetPath(pathName);
//Check to see if we have an attached path and add the appropiate component to handle it:
if (path){
// if we have a moving platform path, then we need a moving platform component
if (path->pathType == PathType::MovingPlatform) {
MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName);
m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat));
// else if we are a movement path
} /*else if (path->pathType == PathType::Movement) {
auto movementAIcomp = GetComponent<MovementAIComponent>();
if (movementAIcomp){
// TODO: set path in existing movementAIComp
} else {
// TODO: create movementAIcomp and set path
}
}*/
} else {
// else we still need to setup moving platform if it has a moving platform comp but no path
int32_t movingPlatformComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVING_PLATFORM, -1);
if (movingPlatformComponentId >= 0) {
MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName);
m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat));
}
}
int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROXIMITY_MONITOR);
if (proximityMonitorID > 0) {
CDProximityMonitorComponentTable* proxCompTable = CDClientManager::Instance().GetTable<CDProximityMonitorComponentTable>();
std::vector<CDProximityMonitorComponent> proxCompData = proxCompTable->Query([=](CDProximityMonitorComponent entry) { return (entry.id == proximityMonitorID); });
if (proxCompData.size() > 0) {
std::vector<std::string> proximityStr = GeneralUtils::SplitString(proxCompData[0].Proximities, ',');
ProximityMonitorComponent* comp = new ProximityMonitorComponent(this, std::stoi(proximityStr[0]), std::stoi(proximityStr[1]));
m_Components.insert(std::make_pair(eReplicaComponentType::PROXIMITY_MONITOR, comp));
}
}
// Hacky way to trigger these when the object has had a chance to get constructed
AddCallbackTimer(0, [this]() {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) {
script->OnStartup(this);
}
});
if (!m_Character && EntityManager::Instance()->GetGhostingEnabled()) {
// Don't ghost what is likely large scene elements
if (HasComponent(eReplicaComponentType::SIMPLE_PHYSICS) && HasComponent(eReplicaComponentType::RENDER) && (m_Components.size() == 2 || (HasComponent(eReplicaComponentType::TRIGGER) && m_Components.size() == 3))) {
goto no_ghosting;
}
/* Filter for ghosting candidates.
*
* Don't ghost moving platforms, until we've got proper syncing for those.
* Don't ghost big phantom physics triggers, as putting those to sleep might prevent interactions.
* Don't ghost property related objects, as the client expects those to always be loaded.
*/
if (
!EntityManager::IsExcludedFromGhosting(GetLOT()) &&
!HasComponent(eReplicaComponentType::SCRIPTED_ACTIVITY) &&
!HasComponent(eReplicaComponentType::MOVING_PLATFORM) &&
!HasComponent(eReplicaComponentType::PHANTOM_PHYSICS) &&
!HasComponent(eReplicaComponentType::PROPERTY) &&
!HasComponent(eReplicaComponentType::RACING_CONTROL) &&
!HasComponent(eReplicaComponentType::VEHICLE_PHYSICS)
)
//if (HasComponent(eReplicaComponentType::BASE_COMBAT_AI))
{
m_IsGhostingCandidate = true;
}
if (GetLOT() == 6368) {
m_IsGhostingCandidate = true;
}
// Special case for collectibles in Ninjago
if (HasComponent(eReplicaComponentType::COLLECTIBLE) && Game::server->GetZoneID() == 2000) {
m_IsGhostingCandidate = true;
}
}
no_ghosting:
TriggerEvent(eTriggerEventType::CREATE, this);
if (m_Character) {
auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>();
auto* levelComponent = GetComponent<LevelProgressionComponent>();
if (controllablePhysicsComponent && levelComponent) {
controllablePhysicsComponent->SetSpeedMultiplier(levelComponent->GetSpeedBase() / 500.0f);
}
}
}

View File

@ -483,7 +483,7 @@ void EntityManager::UpdateGhosting(Player* player) {
return;
}
auto* missionComponent = player->GetComponent<MissionComponent>();
auto missionComponent = player->GetComponent<MissionComponent>();
if (missionComponent == nullptr) {
return;
@ -599,7 +599,7 @@ void EntityManager::ScheduleForKill(Entity* entity) {
if (!entity)
return;
SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>();
auto switchComp = entity->GetComponent<SwitchComponent>();
if (switchComp) {
entity->TriggerEvent(eTriggerEventType::DEACTIVATED, entity);
}

View File

@ -94,7 +94,7 @@ void Player::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) {
const auto sysAddr = entity->GetSystemAddress();
auto* character = entity->GetCharacter();
auto* characterComponent = entity->GetComponent<CharacterComponent>();
auto characterComponent = entity->GetComponent<CharacterComponent>();
if (character != nullptr && characterComponent != nullptr) {
character->SetZoneID(zoneID);

View File

@ -114,10 +114,10 @@ void Trade::Complete() {
if (entityA == nullptr || entityB == nullptr) return;
auto* inventoryA = entityA->GetComponent<InventoryComponent>();
auto* inventoryB = entityB->GetComponent<InventoryComponent>();
auto* missionsA = entityA->GetComponent<MissionComponent>();
auto* missionsB = entityB->GetComponent<MissionComponent>();
auto inventoryA = entityA->GetComponent<InventoryComponent>();
auto inventoryB = entityB->GetComponent<InventoryComponent>();
auto missionsA = entityA->GetComponent<MissionComponent>();
auto missionsB = entityB->GetComponent<MissionComponent>();
auto* characterA = entityA->GetCharacter();
auto* characterB = entityB->GetCharacter();
@ -214,12 +214,12 @@ void Trade::SendUpdateToOther(LWOOBJID participant) {
std::vector<TradeItem> items{};
auto* inventoryComponent = self->GetComponent<InventoryComponent>();
auto inventoryComponent = self->GetComponent<InventoryComponent>();
if (inventoryComponent == nullptr) return;
for (const auto tradeItem : itemIds) {
auto* item = inventoryComponent->FindItemById(tradeItem.itemId);
auto item = inventoryComponent->FindItemById(tradeItem.itemId);
if (item == nullptr) return;

View File

@ -214,7 +214,7 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) {
continue;
}
auto* skillComponent = chars[i]->GetEntity()->GetComponent<SkillComponent>();
auto skillComponent = chars[i]->GetEntity()->GetComponent<SkillComponent>();
if (skillComponent != nullptr) {
skillComponent->Reset();

View File

@ -4,13 +4,12 @@
#include "BehaviorBranchContext.h"
#include "BuffComponent.h"
void ApplyBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target == LWOOBJID_EMPTY ? context->originator : branch.target);
if (entity == nullptr) return;
auto* buffComponent = entity->GetComponent<BuffComponent>();
auto buffComponent = entity->GetComponent<BuffComponent>();
if (buffComponent == nullptr) return;
@ -23,7 +22,7 @@ void ApplyBuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext b
if (entity == nullptr) return;
auto* buffComponent = entity->GetComponent<BuffComponent>();
auto buffComponent = entity->GetComponent<BuffComponent>();
if (buffComponent == nullptr) return;

View File

@ -87,7 +87,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream
continue;
}
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
auto destroyableComponent = entity->GetComponent<DestroyableComponent>();
if (destroyableComponent == nullptr) {
continue;

View File

@ -11,7 +11,7 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi
if (context->unmanaged) {
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
auto destroyableComponent = entity->GetComponent<DestroyableComponent>();
if (destroyableComponent != nullptr) {
PlayFx(u"onhit", entity->GetObjectID());
destroyableComponent->Damage(this->m_MaxDamage, context->originator, context->skillID);
@ -44,7 +44,7 @@ void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::Bit
return;
}
auto* destroyableComponent = targetEntity->GetComponent<DestroyableComponent>();
auto destroyableComponent = targetEntity->GetComponent<DestroyableComponent>();
if (!destroyableComponent) {
Game::logger->Log("BasicAttackBehavior", "No destroyable found on the obj/lot %llu/%i", branch.target, targetEntity->GetLOT());
return;
@ -161,7 +161,7 @@ void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet
return;
}
auto* destroyableComponent = targetEntity->GetComponent<DestroyableComponent>();
auto destroyableComponent = targetEntity->GetComponent<DestroyableComponent>();
if (!destroyableComponent || !destroyableComponent->GetOwningEntity()) {
Game::logger->Log("BasicAttackBehavior", "No destroyable component on %llu", branch.target);
return;

View File

@ -328,7 +328,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID
return;
}
auto* renderComponent = targetEntity->GetComponent<RenderComponent>();
auto renderComponent = targetEntity->GetComponent<RenderComponent>();
const auto typeString = GeneralUtils::UTF16ToWTF8(type);

View File

@ -35,7 +35,7 @@ uint32_t BehaviorContext::GetUniqueSkillId() const {
return 0;
}
auto* component = entity->GetComponent<SkillComponent>();
auto component = entity->GetComponent<SkillComponent>();
if (component == nullptr) {
Game::logger->Log("BehaviorContext", "No skill component attached to (%llu)!", this->originator);;
@ -331,8 +331,8 @@ std::vector<LWOOBJID> BehaviorContext::GetValidTargets(int32_t ignoreFaction, in
}
if (ignoreFaction || includeFaction || (!entity->HasComponent(eReplicaComponentType::PHANTOM_PHYSICS) && targets.empty())) {
DestroyableComponent* destroyableComponent;
if (!entity->TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent)) {
auto destroyableComponent = entity->GetComponent<DestroyableComponent>();
if (!destroyableComponent) {
return targets;
}

View File

@ -18,7 +18,7 @@ void BlockBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea
return;
}
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
auto destroyableComponent = entity->GetComponent<DestroyableComponent>();
if (destroyableComponent == nullptr) {
return;
@ -48,7 +48,7 @@ void BlockBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branc
return;
}
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
auto destroyableComponent = entity->GetComponent<DestroyableComponent>();
destroyableComponent->SetAttacksToBlock(this->m_numAttacksCanBlock);

View File

@ -18,7 +18,7 @@ void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream
return;
}
auto* component = entity->GetComponent<DestroyableComponent>();
auto component = entity->GetComponent<DestroyableComponent>();
if (component == nullptr) {
Game::logger->Log("BuffBehavior", "Invalid target, no destroyable component (%llu)!", target);
@ -52,7 +52,7 @@ void BuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch
return;
}
auto* component = entity->GetComponent<DestroyableComponent>();
auto component = entity->GetComponent<DestroyableComponent>();
if (component == nullptr) {
Game::logger->Log("BuffBehavior", "Invalid target, no destroyable component (%llu)!", target);

View File

@ -19,13 +19,13 @@ void CarBoostBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitSt
Game::logger->Log("Car boost", "Activating car boost!");
auto* possessableComponent = entity->GetComponent<PossessableComponent>();
auto possessableComponent = entity->GetComponent<PossessableComponent>();
if (possessableComponent != nullptr) {
auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor());
if (possessor != nullptr) {
auto* characterComponent = possessor->GetComponent<CharacterComponent>();
auto characterComponent = possessor->GetComponent<CharacterComponent>();
if (characterComponent != nullptr) {
Game::logger->Log("Car boost", "Tracking car boost!");
characterComponent->UpdatePlayerStatistic(RacingCarBoostsActivated);

View File

@ -16,7 +16,7 @@ void DamageAbsorptionBehavior::Handle(BehaviorContext* context, RakNet::BitStrea
return;
}
auto* destroyable = target->GetComponent<DestroyableComponent>();
auto destroyable = target->GetComponent<DestroyableComponent>();
if (destroyable == nullptr) {
return;

View File

@ -37,3 +37,7 @@ void Component::LoadConfigData() {
void Component::LoadTemplateData() {
}
void Component::Serialize(RakNet::BitStream* bitStream, bool isConstruction = false) {
}

View File

@ -4,6 +4,10 @@
class Entity;
namespace RakNet {
class BitStream;
}
/**
* Component base class, provides methods for game loop updates, usage events and loading and saving to XML.
*/
@ -56,6 +60,11 @@ public:
* Loads the data of this component from the cdclient database
*/
virtual void LoadTemplateData();
/**
* Serializes the component for delivery to the client(s)
*/
virtual void Serialize(RakNet::BitStream* bitStream, bool isConstruction = false);
protected:
/**

View File

@ -85,7 +85,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac
Entity* entity = EntityManager::Instance()->GetEntity(user->GetLastUsedChar()->GetObjectID());
if (!entity) return;
ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS));
auto comp = entity->GetComponent<ControllablePhysicsComponent>();
if (!comp) return;
/*
@ -100,7 +100,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac
}
*/
auto* possessorComponent = entity->GetComponent<PossessorComponent>();
auto possessorComponent = entity->GetComponent<PossessorComponent>();
NiPoint3 position;
inStream.Read(position.x);
@ -142,13 +142,13 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac
auto* possassableEntity = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable());
if (possassableEntity != nullptr) {
auto* possessableComponent = possassableEntity->GetComponent<PossessableComponent>();
auto possessableComponent = possassableEntity->GetComponent<PossessableComponent>();
if (possessableComponent) {
// While possessing something, only update char if we are attached to the thing we are possessing
if (possessableComponent->GetPossessionType() != ePossessionType::ATTACHED_VISIBLE) updateChar = false;
}
auto* vehiclePhysicsComponent = possassableEntity->GetComponent<VehiclePhysicsComponent>();
auto vehiclePhysicsComponent = possassableEntity->GetComponent<VehiclePhysicsComponent>();
if (vehiclePhysicsComponent != nullptr) {
// This is flipped for whatever reason
rotation = NiQuaternion(rotation.z, rotation.y, rotation.x, rotation.w);
@ -163,7 +163,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac
vehiclePhysicsComponent->SetDirtyAngularVelocity(angVelocityFlag);
} else {
// Need to get the mount's controllable physics
auto* controllablePhysicsComponent = possassableEntity->GetComponent<ControllablePhysicsComponent>();
auto controllablePhysicsComponent = possassableEntity->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
controllablePhysicsComponent->SetPosition(position);
controllablePhysicsComponent->SetRotation(rotation);
@ -186,7 +186,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac
// Handle statistics
auto* characterComponent = entity->GetComponent<CharacterComponent>();
auto characterComponent = entity->GetComponent<CharacterComponent>();
if (characterComponent != nullptr) {
characterComponent->TrackPositionUpdate(position);
}

View File

@ -13,13 +13,7 @@ void NtFactionSpyServer::OnStartup(Entity* self) {
SetVariables(self);
// Set the proximity to sense later
auto* proximityMonitor = self->GetComponent<ProximityMonitorComponent>();
if (proximityMonitor == nullptr) {
proximityMonitor = new ProximityMonitorComponent(self, -1, -1);
self->AddComponent(eReplicaComponentType::PROXIMITY_MONITOR, proximityMonitor);
}
proximityMonitor->SetProximityRadius(self->GetVar<float_t>(m_SpyProximityVariable), m_ProximityName);
self->SetProximityRadius(self->GetVar<float_t>(m_SpyProximityVariable), m_ProximityName);
}
void NtFactionSpyServer::SetVariables(Entity* self) {

View File

@ -12,6 +12,5 @@ void AgStromlingProperty::OnStartup(Entity* self) {
4
};
auto* movementAIComponent = new MovementAIComponent(self, movementInfo);
self->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAIComponent);
self->AddComponent<MovementAIComponent>(movementInfo);
}