diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 3f87dec56..6dc24097d 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -76,6 +76,10 @@ #include "eGameMasterLevel.h" #include "eReplicaComponentType.h" #include "eReplicaPacketType.h" +#include "ZoneControlComponent.h" +#include "RacingStatsComponent.h" +#include "CollectibleComponent.h" +#include "ItemComponent.h" // Table includes #include "CDComponentsRegistryTable.h" @@ -95,7 +99,6 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) m_ParentEntity = parentEntity; m_Character = nullptr; m_GMLevel = eGameMasterLevel::CIVILIAN; - m_CollectibleID = 0; m_NetworkID = 0; m_Groups = {}; m_OwnerOverride = LWOOBJID_EMPTY; @@ -153,7 +156,7 @@ void Entity::Initialize() { const auto triggerInfo = GetVarAsString(u"trigger_id"); - if (!triggerInfo.empty()) m_Components.emplace(eReplicaComponentType::TRIGGER, new TriggerComponent(this, triggerInfo)); + if (!triggerInfo.empty()) AddComponent(triggerInfo); /** * Setup groups @@ -184,21 +187,17 @@ void Entity::Initialize() { 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)); + AddComponent(simplePhysicsComponentID); - ModelComponent* modelcomp = new ModelComponent(this); - m_Components.insert(std::make_pair(eReplicaComponentType::MODEL, modelcomp)); + AddComponent(); - RenderComponent* render = new RenderComponent(this); - m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render)); + AddComponent(); - auto destroyableComponent = new DestroyableComponent(this); + auto* destroyableComponent = AddComponent(); 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; } @@ -210,49 +209,46 @@ void Entity::Initialize() { */ if (GetParentUser()) { - auto missions = new MissionComponent(this); - m_Components.insert(std::make_pair(eReplicaComponentType::MISSION, missions)); - missions->LoadFromXml(m_Character->GetXMLDoc()); + AddComponent()->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))); + AddComponent(petComponentId); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ZONE_CONTROL) > 0) { - m_Components.insert(std::make_pair(eReplicaComponentType::ZONE_CONTROL, nullptr)); + AddComponent(); } uint32_t possessableComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::POSSESSABLE); if (possessableComponentId > 0) { - m_Components.insert(std::make_pair(eReplicaComponentType::POSSESSABLE, new PossessableComponent(this, possessableComponentId))); + AddComponent(possessableComponentId); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MODULE_ASSEMBLY) > 0) { - m_Components.insert(std::make_pair(eReplicaComponentType::MODULE_ASSEMBLY, new ModuleAssemblyComponent(this))); + AddComponent(); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_STATS) > 0) { - m_Components.insert(std::make_pair(eReplicaComponentType::RACING_STATS, nullptr)); + AddComponent(); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::LUP_EXHIBIT, -1) >= 0) { - m_Components.insert(std::make_pair(eReplicaComponentType::LUP_EXHIBIT, new LUPExhibitComponent(this))); + AddComponent(); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_CONTROL) > 0) { - m_Components.insert(std::make_pair(eReplicaComponentType::RACING_CONTROL, new RacingControlComponent(this))); + AddComponent(); } 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))); + AddComponent(propertyEntranceComponentID); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CONTROLLABLE_PHYSICS) > 0) { - ControllablePhysicsComponent* controllablePhysics = new ControllablePhysicsComponent(this); + auto* controllablePhysics = AddComponent(); if (m_Character) { controllablePhysics->LoadFromXml(m_Character->GetXMLDoc()); @@ -285,8 +281,6 @@ void Entity::Initialize() { 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. @@ -294,54 +288,42 @@ void Entity::Initialize() { 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)); + AddComponent(simplePhysicsComponentID); } 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)); + AddComponent(); } 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)); + AddComponent()->SetPhysicsEffectActive(false); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VEHICLE_PHYSICS) > 0) { - VehiclePhysicsComponent* vehiclePhysicsComponent = new VehiclePhysicsComponent(this); - m_Components.insert(std::make_pair(eReplicaComponentType::VEHICLE_PHYSICS, vehiclePhysicsComponent)); + auto* vehiclePhysicsComponent = AddComponent(); 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)); + AddComponent(); } else if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_SOUND_TRIGGER, -1) != -1) { - auto* comp = new RacingSoundTriggerComponent(this); - m_Components.insert(std::make_pair(eReplicaComponentType::RACING_SOUND_TRIGGER, comp)); + AddComponent(); } - //Also check for the collectible id: - m_CollectibleID = GetVarAs(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)); + AddComponent(); } int collectibleComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::COLLECTIBLE); if (collectibleComponentID > 0) { - m_Components.insert(std::make_pair(eReplicaComponentType::COLLECTIBLE, nullptr)); + AddComponent(GetVarAs(u"collectible_id")); } /** * Multiple components require the destructible component. */ - int buffComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF); int rebuildComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD); @@ -352,10 +334,10 @@ void Entity::Initialize() { CDDestructibleComponentTable* destCompTable = CDClientManager::Instance().GetTable(); std::vector destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); }); - + bool isSmashable = GetVarAs(u"is_smashable") != 0; if (buffComponentID > 0 || collectibleComponentID > 0 || isSmashable) { - DestroyableComponent* comp = new DestroyableComponent(this); + DestroyableComponent* comp = AddComponent(); if (m_Character) { comp->LoadFromXml(m_Character->GetXMLDoc()); } else { @@ -440,36 +422,27 @@ void Entity::Initialize() { } } } - - 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))); + AddComponent(); // 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)); + AddComponent()->LoadFromXml(m_Character->GetXMLDoc()); - m_Components.insert(std::make_pair(eReplicaComponentType::PLAYER_FORCED_MOVEMENT, new PlayerForcedMovementComponent(this))); + AddComponent(); - CharacterComponent* charComp = new CharacterComponent(this, m_Character); - charComp->LoadFromXml(m_Character->GetXMLDoc()); - m_Components.insert(std::make_pair(eReplicaComponentType::CHARACTER, charComp)); + AddComponent(m_Character)->LoadFromXml(m_Character->GetXMLDoc()); } 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)); + auto* xmlDoc = m_Character ? m_Character->GetXMLDoc() : nullptr; + AddComponent(xmlDoc); } // if this component exists, then we initialize it. it's value is always 0 if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MULTI_ZONE_ENTRANCE, -1) != -1) { - auto comp = new MultiZoneEntranceComponent(this); - m_Components.insert(std::make_pair(eReplicaComponentType::MULTI_ZONE_ENTRANCE, comp)); + AddComponent(); } /** @@ -520,7 +493,7 @@ void Entity::Initialize() { } if (!scriptName.empty() || client || m_Character || scriptComponentID >= 0) { - m_Components.insert(std::make_pair(eReplicaComponentType::SCRIPT, new ScriptComponent(this, scriptName, true, client && scriptName.empty()))); + AddComponent(scriptName, true, client && scriptName.empty()); } // ZoneControl script @@ -532,148 +505,137 @@ void Entity::Initialize() { 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)); + AddComponent(zoneScriptData.script_name, true); } } 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)); + AddComponent(); } 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)); + AddComponent(combatAiId); } 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)); + auto* rebuildComponent = AddComponent(); CDRebuildComponentTable* rebCompTable = CDClientManager::Instance().GetTable(); std::vector 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); + rebuildComponent->SetResetTime(rebCompData[0].reset_time); + rebuildComponent->SetCompleteTime(rebCompData[0].complete_time); + rebuildComponent->SetTakeImagination(rebCompData[0].take_imagination); + rebuildComponent->SetInterruptible(rebCompData[0].interruptible); + rebuildComponent->SetSelfActivator(rebCompData[0].self_activator); + rebuildComponent->SetActivityId(rebCompData[0].activityID); + rebuildComponent->SetPostImaginationCost(rebCompData[0].post_imagination_cost); + rebuildComponent->SetTimeBeforeSmash(rebCompData[0].time_before_smash); const auto rebuildResetTime = GetVar(u"rebuild_reset_time"); if (rebuildResetTime != 0.0f) { - comp->SetResetTime(rebuildResetTime); + rebuildComponent->SetResetTime(rebuildResetTime); - if (m_TemplateID == 9483) // Look away! + // Known bug with moving platform in FV that casues it to build at the end instead of the start. + // This extends the smash time so players can ride up the lift. + if (m_TemplateID == 9483) { - comp->SetResetTime(comp->GetResetTime() + 25); + rebuildComponent->SetResetTime(rebuildComponent->GetResetTime() + 25); } } const auto activityID = GetVar(u"activityID"); if (activityID > 0) { - comp->SetActivityId(activityID); + rebuildComponent->SetActivityId(activityID); Loot::CacheMatrix(activityID); } const auto compTime = GetVar(u"compTime"); if (compTime > 0) { - comp->SetCompleteTime(compTime); + rebuildComponent->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)); + AddComponent(); } if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VENDOR) > 0)) { - VendorComponent* comp = new VendorComponent(this); - m_Components.insert(std::make_pair(eReplicaComponentType::VENDOR, comp)); + AddComponent(); } else if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::DONATION_VENDOR, -1) != -1)) { - DonationVendorComponent* comp = new DonationVendorComponent(this); - m_Components.insert(std::make_pair(eReplicaComponentType::DONATION_VENDOR, comp)); + AddComponent(); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_VENDOR, -1) != -1) { - auto* component = new PropertyVendorComponent(this); - m_Components.insert_or_assign(eReplicaComponentType::PROPERTY_VENDOR, component); + AddComponent(); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_MANAGEMENT, -1) != -1) { - auto* component = new PropertyManagementComponent(this); - m_Components.insert_or_assign(eReplicaComponentType::PROPERTY_MANAGEMENT, component); + AddComponent(); } 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)); + AddComponent(); } 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)); + AddComponent(renderComponentId); } 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))); + AddComponent(m_TemplateID); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUILD_BORDER, -1) != -1) { - m_Components.insert(std::make_pair(eReplicaComponentType::BUILD_BORDER, new BuildBorderComponent(this))); + AddComponent(); } // 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))); + AddComponent(scriptedActivityID); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MODEL, -1) != -1 && !GetComponent()) { - 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); + AddComponent(); + if (!HasComponent(eReplicaComponentType::DESTROYABLE)) { + auto* destroyableComponent = AddComponent(); 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)); + AddComponent(); } // Shooting gallery component if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SHOOTING_GALLERY) > 0) { - m_Components.insert(std::make_pair(eReplicaComponentType::SHOOTING_GALLERY, new ShootingGalleryComponent(this))); + AddComponent(); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY, -1) != -1) { - m_Components.insert(std::make_pair(eReplicaComponentType::PROPERTY, new PropertyComponent(this))); + AddComponent(); } 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))); + AddComponent(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))); + AddComponent(railComponentID); } int movementAIID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVEMENT_AI); @@ -701,7 +663,7 @@ void Entity::Initialize() { } } - m_Components.insert(std::make_pair(eReplicaComponentType::MOVEMENT_AI, new MovementAIComponent(this, moveInfo))); + AddComponent(moveInfo); } } else if (petComponentId > 0 || combatAiId > 0 && GetComponent()->GetTetherSpeed() > 0) { MovementAIInfo moveInfo = MovementAIInfo(); @@ -712,7 +674,7 @@ void Entity::Initialize() { moveInfo.wanderDelayMax = 5; moveInfo.wanderDelayMin = 2; - m_Components.insert(std::make_pair(eReplicaComponentType::MOVEMENT_AI, new MovementAIComponent(this, moveInfo))); + AddComponent(moveInfo); } std::string pathName = GetVarAsString(u"attached_path"); @@ -722,8 +684,7 @@ void Entity::Initialize() { 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)); + AddComponent(pathName); // else if we are a movement path } /*else if (path->pathType == PathType::Movement) { auto movementAIcomp = GetComponent(); @@ -737,8 +698,7 @@ void Entity::Initialize() { // 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)); + AddComponent(pathName); } } @@ -748,8 +708,7 @@ void Entity::Initialize() { std::vector proxCompData = proxCompTable->Query([=](CDProximityMonitorComponent entry) { return (entry.id == proximityMonitorID); }); if (proxCompData.size() > 0) { std::vector 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)); + AddComponent(std::stoi(proximityStr[0]), std::stoi(proximityStr[1])); } } @@ -840,14 +799,6 @@ bool Entity::HasComponent(const eReplicaComponentType componentId) const { return m_Components.find(componentId) != m_Components.end(); } -void Entity::AddComponent(const eReplicaComponentType componentId, Component* component) { - if (HasComponent(componentId)) { - return; - } - - m_Components.insert_or_assign(componentId, component); -} - std::vector Entity::GetScriptComponents() { std::vector comps; for (std::pair p : m_Components) { @@ -876,20 +827,12 @@ void Entity::Unsubscribe(LWOOBJID scriptObjId, const std::string& notificationNa } void Entity::SetProximityRadius(float proxRadius, std::string name) { - ProximityMonitorComponent* proxMon = GetComponent(); - if (!proxMon) { - proxMon = new ProximityMonitorComponent(this); - m_Components.insert_or_assign(eReplicaComponentType::PROXIMITY_MONITOR, proxMon); - } + ProximityMonitorComponent* proxMon = AddComponent(); proxMon->SetProximityRadius(proxRadius, name); } void Entity::SetProximityRadius(dpEntity* entity, std::string name) { - ProximityMonitorComponent* proxMon = GetComponent(); - if (!proxMon) { - proxMon = new ProximityMonitorComponent(this); - m_Components.insert_or_assign(eReplicaComponentType::PROXIMITY_MONITOR, proxMon); - } + ProximityMonitorComponent* proxMon = AddComponent(); proxMon->SetProximityRadius(entity, name); } @@ -1104,13 +1047,14 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType destroyableSerialized = true; } - if (HasComponent(eReplicaComponentType::COLLECTIBLE)) { + CollectibleComponent* collectibleComponent; + if (TryGetComponent(eReplicaComponentType::COLLECTIBLE, collectibleComponent)) { DestroyableComponent* destroyableComponent; if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent) && !destroyableSerialized) { destroyableComponent->Serialize(outBitStream, bIsInitialUpdate); } destroyableSerialized = true; - outBitStream->Write(m_CollectibleID); // Collectable component + collectibleComponent->Serialize(outBitStream, bIsInitialUpdate); } PetComponent* petComponent; @@ -1148,8 +1092,9 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType characterComponent->Serialize(outBitStream, bIsInitialUpdate); } - if (HasComponent(eReplicaComponentType::ITEM)) { - outBitStream->Write0(); + ItemComponent* itemComponent; + if (TryGetComponent(eReplicaComponentType::ITEM, itemComponent)) { + itemComponent->Serialize(outBitStream, bIsInitialUpdate); } InventoryComponent* inventoryComponent; @@ -1245,8 +1190,9 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType } } - if (HasComponent(eReplicaComponentType::ZONE_CONTROL)) { - outBitStream->Write(0x40000000); + ZoneControlComponent* zoneControlComponent; + if (TryGetComponent(eReplicaComponentType::ZONE_CONTROL, zoneControlComponent)) { + zoneControlComponent->Serialize(outBitStream, bIsInitialUpdate); } // BBB Component, unused currently @@ -2102,3 +2048,8 @@ void Entity::RetroactiveVaultSize() { modelVault->SetSize(itemsVault->GetSize()); } + +uint8_t Entity::GetCollectibleID() const { + auto* collectible = GetComponent(); + return collectible ? collectible->GetCollectibleId() : 0; +} diff --git a/dGame/Entity.h b/dGame/Entity.h index 8680653fb..a5588c3e6 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -66,7 +66,7 @@ class Entity { eGameMasterLevel GetGMLevel() const { return m_GMLevel; } - uint8_t GetCollectibleID() const { return uint8_t(m_CollectibleID); } + uint8_t GetCollectibleID() const; Entity* GetParentEntity() const { return m_ParentEntity; } @@ -274,6 +274,9 @@ class Entity { template T GetVarAs(const std::u16string& name) const; + template + ComponentType* AddComponent(VaArgs... args); + /** * Get the LDF data. */ @@ -501,3 +504,36 @@ T Entity::GetNetworkVar(const std::u16string& name) { return LDFData::Default; } + +/** + * @brief Adds a component of type ComponentType to this entity and forwards the arguments to the constructor. + * + * @tparam ComponentType The component class type to add. Must derive from Component. + * @tparam VaArgs The argument types to forward to the constructor. + * @param args The arguments to forward to the constructor. The first argument passed to the ComponentType constructor will be this entity. + * @return ComponentType* The added component. Will never return null. + */ +template +inline ComponentType* Entity::AddComponent(VaArgs... args) { + static_assert(std::is_base_of_v, "ComponentType must be a Component"); + + // Get the component if it already exists, or default construct a nullptr + auto*& componentToReturn = m_Components[ComponentType::ComponentType]; + + // If it doesn't exist, create it and forward the arguments to the constructor + if (!componentToReturn) { + componentToReturn = new ComponentType(this, std::forward(args)...); + } else { + // In this case the block is already allocated and ready for use + // so we use a placement new to construct the component again as was requested by the caller. + // Placement new means we already have memory allocated for the object, so this just calls its constructor again. + // This is useful for when we want to create a new object in the same memory location as an old one. + componentToReturn->~Component(); + new(componentToReturn) ComponentType(this, std::forward(args)...); + } + + // Finally return the created or already existing component. + // Because of the assert above, this should always be a ComponentType* but I need a way to guarantee the map cannot be modifed outside this function + // To allow a static cast here instead of a dynamic one. + return dynamic_cast(componentToReturn); +} diff --git a/dGame/dComponents/BaseCombatAIComponent.h b/dGame/dComponents/BaseCombatAIComponent.h index 17b74e9cc..a08b008e4 100644 --- a/dGame/dComponents/BaseCombatAIComponent.h +++ b/dGame/dComponents/BaseCombatAIComponent.h @@ -47,7 +47,7 @@ struct AiSkillEntry */ class BaseCombatAIComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::BASE_COMBAT_AI; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BASE_COMBAT_AI; BaseCombatAIComponent(Entity* parentEntity, uint32_t id); ~BaseCombatAIComponent() override; diff --git a/dGame/dComponents/BouncerComponent.h b/dGame/dComponents/BouncerComponent.h index d372f5c74..cb3d8df36 100644 --- a/dGame/dComponents/BouncerComponent.h +++ b/dGame/dComponents/BouncerComponent.h @@ -12,7 +12,7 @@ */ class BouncerComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::BOUNCER; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BOUNCER; BouncerComponent(Entity* parentEntity); ~BouncerComponent() override; diff --git a/dGame/dComponents/BuffComponent.h b/dGame/dComponents/BuffComponent.h index 61e7be5d6..5b6f8fd6c 100644 --- a/dGame/dComponents/BuffComponent.h +++ b/dGame/dComponents/BuffComponent.h @@ -42,7 +42,7 @@ struct Buff */ class BuffComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::BUFF; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BUFF; explicit BuffComponent(Entity* parent); diff --git a/dGame/dComponents/BuildBorderComponent.h b/dGame/dComponents/BuildBorderComponent.h index dc5afc8ad..985c03885 100644 --- a/dGame/dComponents/BuildBorderComponent.h +++ b/dGame/dComponents/BuildBorderComponent.h @@ -16,7 +16,7 @@ */ class BuildBorderComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::BUILD_BORDER; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BUILD_BORDER; BuildBorderComponent(Entity* parent); ~BuildBorderComponent() override; diff --git a/dGame/dComponents/CMakeLists.txt b/dGame/dComponents/CMakeLists.txt index 229de5870..b1550f378 100644 --- a/dGame/dComponents/CMakeLists.txt +++ b/dGame/dComponents/CMakeLists.txt @@ -3,11 +3,13 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp" "BuffComponent.cpp" "BuildBorderComponent.cpp" "CharacterComponent.cpp" + "CollectibleComponent.cpp" "Component.cpp" "ControllablePhysicsComponent.cpp" "DestroyableComponent.cpp" "DonationVendorComponent.cpp" "InventoryComponent.cpp" + "ItemComponent.cpp" "LevelProgressionComponent.cpp" "LUPExhibitComponent.cpp" "MissionComponent.cpp" @@ -42,4 +44,7 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp" "SwitchComponent.cpp" "TriggerComponent.cpp" "VehiclePhysicsComponent.cpp" - "VendorComponent.cpp" PARENT_SCOPE) + "VendorComponent.cpp" + "ZoneControlComponent.cpp" + PARENT_SCOPE +) diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h index 3a5c033b7..5bafb3dfc 100644 --- a/dGame/dComponents/CharacterComponent.h +++ b/dGame/dComponents/CharacterComponent.h @@ -62,7 +62,7 @@ enum StatisticID { */ class CharacterComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER; CharacterComponent(Entity* parent, Character* character); ~CharacterComponent() override; diff --git a/dGame/dComponents/CollectibleComponent.cpp b/dGame/dComponents/CollectibleComponent.cpp new file mode 100644 index 000000000..99fcc6818 --- /dev/null +++ b/dGame/dComponents/CollectibleComponent.cpp @@ -0,0 +1,5 @@ +#include "CollectibleComponent.h" + +void CollectibleComponent::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) { + outBitStream->Write(GetCollectibleId()); +} diff --git a/dGame/dComponents/CollectibleComponent.h b/dGame/dComponents/CollectibleComponent.h new file mode 100644 index 000000000..3ff71c6fe --- /dev/null +++ b/dGame/dComponents/CollectibleComponent.h @@ -0,0 +1,18 @@ +#ifndef __COLLECTIBLECOMPONENT__H__ +#define __COLLECTIBLECOMPONENT__H__ + +#include "Component.h" +#include "eReplicaComponentType.h" + +class CollectibleComponent : public Component { +public: + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::COLLECTIBLE; + CollectibleComponent(Entity* parentEntity, int32_t collectibleId) : Component(parentEntity), m_CollectibleId(collectibleId) {} + + int16_t GetCollectibleId() const { return m_CollectibleId; } + void Serialize(RakNet::BitStream* outBitStream, bool isConstruction) override; +private: + int16_t m_CollectibleId = 0; +}; + +#endif //!__COLLECTIBLECOMPONENT__H__ diff --git a/dGame/dComponents/ControllablePhysicsComponent.h b/dGame/dComponents/ControllablePhysicsComponent.h index 897ced1c9..e5c3f890d 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.h +++ b/dGame/dComponents/ControllablePhysicsComponent.h @@ -21,7 +21,7 @@ enum class eStateChangeType : uint32_t; */ class ControllablePhysicsComponent : public PhysicsComponent { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::CONTROLLABLE_PHYSICS; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::CONTROLLABLE_PHYSICS; ControllablePhysicsComponent(Entity* entity); ~ControllablePhysicsComponent() override; diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index 46af39227..52d4be5a2 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -19,7 +19,7 @@ enum class eStateChangeType : uint32_t; */ class DestroyableComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::DESTROYABLE; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::DESTROYABLE; DestroyableComponent(Entity* parentEntity); ~DestroyableComponent() override; diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index ab9de3e64..e818d2cb6 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -38,7 +38,7 @@ enum class eItemType : int32_t; class InventoryComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY; explicit InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document = nullptr); void Update(float deltaTime) override; diff --git a/dGame/dComponents/ItemComponent.cpp b/dGame/dComponents/ItemComponent.cpp new file mode 100644 index 000000000..dc413b172 --- /dev/null +++ b/dGame/dComponents/ItemComponent.cpp @@ -0,0 +1,5 @@ +#include "ItemComponent.h" + +void ItemComponent::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) { + outBitStream->Write0(); +} diff --git a/dGame/dComponents/ItemComponent.h b/dGame/dComponents/ItemComponent.h new file mode 100644 index 000000000..3af6a91e1 --- /dev/null +++ b/dGame/dComponents/ItemComponent.h @@ -0,0 +1,16 @@ +#ifndef __ITEMCOMPONENT__H__ +#define __ITEMCOMPONENT__H__ + +#include "Component.h" +#include "eReplicaComponentType.h" + +class ItemComponent : public Component { +public: + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::ITEM; + + ItemComponent(Entity* entity) : Component(entity) {} + + void Serialize(RakNet::BitStream* bitStream, bool isConstruction) override; +}; + +#endif //!__ITEMCOMPONENT__H__ diff --git a/dGame/dComponents/LUPExhibitComponent.h b/dGame/dComponents/LUPExhibitComponent.h index 510c42fe1..646d361c9 100644 --- a/dGame/dComponents/LUPExhibitComponent.h +++ b/dGame/dComponents/LUPExhibitComponent.h @@ -11,7 +11,7 @@ class LUPExhibitComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::EXHIBIT; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::EXHIBIT; LUPExhibitComponent(Entity* parent); ~LUPExhibitComponent(); diff --git a/dGame/dComponents/LevelProgressionComponent.h b/dGame/dComponents/LevelProgressionComponent.h index 17ca81173..09ccec34c 100644 --- a/dGame/dComponents/LevelProgressionComponent.h +++ b/dGame/dComponents/LevelProgressionComponent.h @@ -13,7 +13,7 @@ class LevelProgressionComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::LEVEL_PROGRESSION; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::LEVEL_PROGRESSION; /** * Constructor for this component diff --git a/dGame/dComponents/MissionComponent.h b/dGame/dComponents/MissionComponent.h index eeaaa7260..e82b5b677 100644 --- a/dGame/dComponents/MissionComponent.h +++ b/dGame/dComponents/MissionComponent.h @@ -27,7 +27,7 @@ class AchievementCacheKey; class MissionComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION; explicit MissionComponent(Entity* parent); ~MissionComponent() override; diff --git a/dGame/dComponents/MissionOfferComponent.h b/dGame/dComponents/MissionOfferComponent.h index 6e22ca059..ad5f83bcb 100644 --- a/dGame/dComponents/MissionOfferComponent.h +++ b/dGame/dComponents/MissionOfferComponent.h @@ -61,7 +61,7 @@ struct OfferedMission { */ class MissionOfferComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION_OFFER; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION_OFFER; MissionOfferComponent(Entity* parent, LOT parentLot); ~MissionOfferComponent() override; diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index c961bff04..dd9984e72 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -13,7 +13,7 @@ class Entity; */ class ModelComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::MODEL; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MODEL; ModelComponent(Entity* parent); diff --git a/dGame/dComponents/ModuleAssemblyComponent.h b/dGame/dComponents/ModuleAssemblyComponent.h index 6ee5f5052..9e7301fed 100644 --- a/dGame/dComponents/ModuleAssemblyComponent.h +++ b/dGame/dComponents/ModuleAssemblyComponent.h @@ -12,7 +12,7 @@ */ class ModuleAssemblyComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::MODULE_ASSEMBLY; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MODULE_ASSEMBLY; ModuleAssemblyComponent(Entity* parent); ~ModuleAssemblyComponent() override; diff --git a/dGame/dComponents/MovementAIComponent.h b/dGame/dComponents/MovementAIComponent.h index 4a4e4c0a9..574241aa1 100644 --- a/dGame/dComponents/MovementAIComponent.h +++ b/dGame/dComponents/MovementAIComponent.h @@ -57,7 +57,7 @@ struct MovementAIInfo { */ class MovementAIComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI; MovementAIComponent(Entity* parentEntity, MovementAIInfo info); diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index bb83a5381..e8e1dac78 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -106,7 +106,7 @@ class MoverSubComponent { */ class MovingPlatformComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVING_PLATFORM; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVING_PLATFORM; MovingPlatformComponent(Entity* parent, const std::string& pathName); ~MovingPlatformComponent() override; diff --git a/dGame/dComponents/MultiZoneEntranceComponent.h b/dGame/dComponents/MultiZoneEntranceComponent.h index 9c1f4360b..c65dc0fe3 100644 --- a/dGame/dComponents/MultiZoneEntranceComponent.h +++ b/dGame/dComponents/MultiZoneEntranceComponent.h @@ -10,7 +10,7 @@ */ class MultiZoneEntranceComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::MULTI_ZONE_ENTRANCE; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MULTI_ZONE_ENTRANCE; /** * Constructor for this component, builds the m_LUPWorlds vector diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index 4ca6a49ef..980bb1462 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -21,7 +21,7 @@ enum class PetAbilityType class PetComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::PET; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PET; explicit PetComponent(Entity* parentEntity, uint32_t componentId); ~PetComponent() override; diff --git a/dGame/dComponents/PhantomPhysicsComponent.h b/dGame/dComponents/PhantomPhysicsComponent.h index 3387c9cfc..5fcee004f 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.h +++ b/dGame/dComponents/PhantomPhysicsComponent.h @@ -27,7 +27,7 @@ enum class ePhysicsEffectType : uint32_t ; */ class PhantomPhysicsComponent : public PhysicsComponent { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::PHANTOM_PHYSICS; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PHANTOM_PHYSICS; PhantomPhysicsComponent(Entity* parent); ~PhantomPhysicsComponent() override; diff --git a/dGame/dComponents/PlayerForcedMovementComponent.h b/dGame/dComponents/PlayerForcedMovementComponent.h index 43781baba..810b727c5 100644 --- a/dGame/dComponents/PlayerForcedMovementComponent.h +++ b/dGame/dComponents/PlayerForcedMovementComponent.h @@ -10,7 +10,7 @@ */ class PlayerForcedMovementComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::PLAYER_FORCED_MOVEMENT; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PLAYER_FORCED_MOVEMENT; /** * Constructor for this component diff --git a/dGame/dComponents/PossessableComponent.h b/dGame/dComponents/PossessableComponent.h index be60bb778..9a767ba9a 100644 --- a/dGame/dComponents/PossessableComponent.h +++ b/dGame/dComponents/PossessableComponent.h @@ -14,7 +14,7 @@ */ class PossessableComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSABLE; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSABLE; PossessableComponent(Entity* parentEntity, uint32_t componentId); diff --git a/dGame/dComponents/PossessorComponent.h b/dGame/dComponents/PossessorComponent.h index d21695f06..c225766b4 100644 --- a/dGame/dComponents/PossessorComponent.h +++ b/dGame/dComponents/PossessorComponent.h @@ -18,7 +18,7 @@ enum class ePossessionType : uint8_t { */ class PossessorComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSOR; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSOR; PossessorComponent(Entity* parent); ~PossessorComponent() override; diff --git a/dGame/dComponents/PropertyComponent.h b/dGame/dComponents/PropertyComponent.h index 41f93677a..135a1d26e 100644 --- a/dGame/dComponents/PropertyComponent.h +++ b/dGame/dComponents/PropertyComponent.h @@ -22,7 +22,7 @@ struct PropertyState { */ class PropertyComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY; explicit PropertyComponent(Entity* parentEntity); ~PropertyComponent() override; [[nodiscard]] PropertyState* GetPropertyState() const { return m_PropertyState; }; diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index bff917d8a..90c07a167 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -15,7 +15,7 @@ #include "eObjectBits.h" #include "eGameMasterLevel.h" -PropertyEntranceComponent::PropertyEntranceComponent(uint32_t componentID, Entity* parent) : Component(parent) { +PropertyEntranceComponent::PropertyEntranceComponent(Entity* parent, uint32_t componentID) : Component(parent) { this->propertyQueries = {}; auto table = CDClientManager::Instance().GetTable(); diff --git a/dGame/dComponents/PropertyEntranceComponent.h b/dGame/dComponents/PropertyEntranceComponent.h index e37d1daa4..ef8f98103 100644 --- a/dGame/dComponents/PropertyEntranceComponent.h +++ b/dGame/dComponents/PropertyEntranceComponent.h @@ -13,8 +13,8 @@ */ class PropertyEntranceComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_ENTRANCE; - explicit PropertyEntranceComponent(uint32_t componentID, Entity* parent); + explicit PropertyEntranceComponent(Entity* parent, uint32_t componentID); + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_ENTRANCE; /** * Handles an OnUse request for some other entity, rendering the property browse menu diff --git a/dGame/dComponents/PropertyManagementComponent.h b/dGame/dComponents/PropertyManagementComponent.h index 2ee010a8c..2f2deea48 100644 --- a/dGame/dComponents/PropertyManagementComponent.h +++ b/dGame/dComponents/PropertyManagementComponent.h @@ -32,7 +32,7 @@ enum class PropertyPrivacyOption class PropertyManagementComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_MANAGEMENT; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_MANAGEMENT; PropertyManagementComponent(Entity* parent); static PropertyManagementComponent* Instance(); diff --git a/dGame/dComponents/PropertyVendorComponent.h b/dGame/dComponents/PropertyVendorComponent.h index 5055b445a..0e6c6521c 100644 --- a/dGame/dComponents/PropertyVendorComponent.h +++ b/dGame/dComponents/PropertyVendorComponent.h @@ -10,7 +10,7 @@ class PropertyVendorComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_VENDOR; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_VENDOR; explicit PropertyVendorComponent(Entity* parent); /** diff --git a/dGame/dComponents/ProximityMonitorComponent.h b/dGame/dComponents/ProximityMonitorComponent.h index 2f51917d0..90ba7d544 100644 --- a/dGame/dComponents/ProximityMonitorComponent.h +++ b/dGame/dComponents/ProximityMonitorComponent.h @@ -19,7 +19,7 @@ */ class ProximityMonitorComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::PROXIMITY_MONITOR; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROXIMITY_MONITOR; ProximityMonitorComponent(Entity* parentEntity, int smallRadius = -1, int largeRadius = -1); ~ProximityMonitorComponent() override; diff --git a/dGame/dComponents/RacingControlComponent.h b/dGame/dComponents/RacingControlComponent.h index c713a7597..3dcb730eb 100644 --- a/dGame/dComponents/RacingControlComponent.h +++ b/dGame/dComponents/RacingControlComponent.h @@ -105,7 +105,7 @@ struct RacingPlayerInfo { */ class RacingControlComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_CONTROL; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_CONTROL; RacingControlComponent(Entity* parentEntity); ~RacingControlComponent(); diff --git a/dGame/dComponents/RacingStatsComponent.h b/dGame/dComponents/RacingStatsComponent.h new file mode 100644 index 000000000..9349ce491 --- /dev/null +++ b/dGame/dComponents/RacingStatsComponent.h @@ -0,0 +1,14 @@ +#ifndef __RACINGSTATSCOMPONENT__H__ +#define __RACINGSTATSCOMPONENT__H__ + +#include "Component.h" +#include "eReplicaComponentType.h" + +class RacingStatsComponent final : public Component { +public: + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_STATS; + + RacingStatsComponent(Entity* parent) : Component(parent) {} +}; + +#endif //!__RACINGSTATSCOMPONENT__H__ diff --git a/dGame/dComponents/RailActivatorComponent.h b/dGame/dComponents/RailActivatorComponent.h index 5d625d2ad..28b250734 100644 --- a/dGame/dComponents/RailActivatorComponent.h +++ b/dGame/dComponents/RailActivatorComponent.h @@ -15,7 +15,7 @@ class RailActivatorComponent final : public Component { explicit RailActivatorComponent(Entity* parent, int32_t componentID); ~RailActivatorComponent() override; - static const eReplicaComponentType ComponentType = eReplicaComponentType::RAIL_ACTIVATOR; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RAIL_ACTIVATOR; /** * Handles the OnUse event from some entity, initiates the rail movement diff --git a/dGame/dComponents/RebuildComponent.h b/dGame/dComponents/RebuildComponent.h index cd266c1f8..bb097eddd 100644 --- a/dGame/dComponents/RebuildComponent.h +++ b/dGame/dComponents/RebuildComponent.h @@ -22,7 +22,7 @@ enum class eQuickBuildFailReason : uint32_t; */ class RebuildComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::QUICK_BUILD; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::QUICK_BUILD; RebuildComponent(Entity* entity); ~RebuildComponent() override; diff --git a/dGame/dComponents/RenderComponent.h b/dGame/dComponents/RenderComponent.h index 54c0da25a..d4d1e5c3c 100644 --- a/dGame/dComponents/RenderComponent.h +++ b/dGame/dComponents/RenderComponent.h @@ -56,7 +56,7 @@ struct Effect { */ class RenderComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::RENDER; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RENDER; RenderComponent(Entity* entity, int32_t componentId = -1); ~RenderComponent() override; diff --git a/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h b/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h index 66e87f4ad..bc60c38e9 100644 --- a/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h +++ b/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h @@ -19,7 +19,7 @@ */ class RigidbodyPhantomPhysicsComponent : public PhysicsComponent { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS; RigidbodyPhantomPhysicsComponent(Entity* parent); diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.h b/dGame/dComponents/RocketLaunchpadControlComponent.h index 84cff22dc..06d97cd33 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.h +++ b/dGame/dComponents/RocketLaunchpadControlComponent.h @@ -18,7 +18,7 @@ class PreconditionExpression; */ class RocketLaunchpadControlComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::ROCKET_LAUNCH; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::ROCKET_LAUNCH; RocketLaunchpadControlComponent(Entity* parent, int rocketId); ~RocketLaunchpadControlComponent() override; diff --git a/dGame/dComponents/ScriptedActivityComponent.h b/dGame/dComponents/ScriptedActivityComponent.h index 455ac6677..3bc8114f3 100644 --- a/dGame/dComponents/ScriptedActivityComponent.h +++ b/dGame/dComponents/ScriptedActivityComponent.h @@ -156,7 +156,7 @@ struct ActivityPlayer { */ class ScriptedActivityComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPTED_ACTIVITY; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPTED_ACTIVITY; ScriptedActivityComponent(Entity* parent, int activityID); ~ScriptedActivityComponent() override; diff --git a/dGame/dComponents/ShootingGalleryComponent.h b/dGame/dComponents/ShootingGalleryComponent.h index bc1aa090d..4024e99af 100644 --- a/dGame/dComponents/ShootingGalleryComponent.h +++ b/dGame/dComponents/ShootingGalleryComponent.h @@ -73,7 +73,7 @@ struct StaticShootingGalleryParams { */ class ShootingGalleryComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::SHOOTING_GALLERY; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SHOOTING_GALLERY; explicit ShootingGalleryComponent(Entity* parent); ~ShootingGalleryComponent(); diff --git a/dGame/dComponents/SimplePhysicsComponent.cpp b/dGame/dComponents/SimplePhysicsComponent.cpp index 9a9553040..37281c57e 100644 --- a/dGame/dComponents/SimplePhysicsComponent.cpp +++ b/dGame/dComponents/SimplePhysicsComponent.cpp @@ -13,7 +13,7 @@ #include "Entity.h" -SimplePhysicsComponent::SimplePhysicsComponent(uint32_t componentID, Entity* parent) : PhysicsComponent(parent) { +SimplePhysicsComponent::SimplePhysicsComponent(Entity* parent, uint32_t componentID) : PhysicsComponent(parent) { m_Position = m_Parent->GetDefaultPosition(); m_Rotation = m_Parent->GetDefaultRotation(); diff --git a/dGame/dComponents/SimplePhysicsComponent.h b/dGame/dComponents/SimplePhysicsComponent.h index 581e5be4d..752fef0ba 100644 --- a/dGame/dComponents/SimplePhysicsComponent.h +++ b/dGame/dComponents/SimplePhysicsComponent.h @@ -28,9 +28,9 @@ enum class eClimbableType : int32_t { */ class SimplePhysicsComponent : public PhysicsComponent { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::SIMPLE_PHYSICS; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SIMPLE_PHYSICS; - SimplePhysicsComponent(uint32_t componentID, Entity* parent); + SimplePhysicsComponent(Entity* parent, uint32_t componentID); ~SimplePhysicsComponent() override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; diff --git a/dGame/dComponents/SkillComponent.h b/dGame/dComponents/SkillComponent.h index b157ad3dd..963c2d698 100644 --- a/dGame/dComponents/SkillComponent.h +++ b/dGame/dComponents/SkillComponent.h @@ -59,7 +59,7 @@ struct SkillExecutionResult { */ class SkillComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::SKILL; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SKILL; explicit SkillComponent(Entity* parent); ~SkillComponent() override; diff --git a/dGame/dComponents/SoundTriggerComponent.h b/dGame/dComponents/SoundTriggerComponent.h index 3873d6ed2..56c71770b 100644 --- a/dGame/dComponents/SoundTriggerComponent.h +++ b/dGame/dComponents/SoundTriggerComponent.h @@ -58,7 +58,7 @@ struct MixerProgram{ class SoundTriggerComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::SOUND_TRIGGER; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SOUND_TRIGGER; explicit SoundTriggerComponent(Entity* parent); void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void ActivateMusicCue(const std::string& name, float bordemTime = -1.0); diff --git a/dGame/dComponents/SwitchComponent.h b/dGame/dComponents/SwitchComponent.h index f262f44c8..25f694ba9 100644 --- a/dGame/dComponents/SwitchComponent.h +++ b/dGame/dComponents/SwitchComponent.h @@ -16,7 +16,7 @@ */ class SwitchComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::SWITCH; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SWITCH; SwitchComponent(Entity* parent); ~SwitchComponent() override; diff --git a/dGame/dComponents/TriggerComponent.h b/dGame/dComponents/TriggerComponent.h index df65707f3..90ecc52c7 100644 --- a/dGame/dComponents/TriggerComponent.h +++ b/dGame/dComponents/TriggerComponent.h @@ -7,7 +7,7 @@ class TriggerComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER; explicit TriggerComponent(Entity* parent, const std::string triggerInfo); diff --git a/dGame/dComponents/VehiclePhysicsComponent.h b/dGame/dComponents/VehiclePhysicsComponent.h index 86d9af43d..69f8579c6 100644 --- a/dGame/dComponents/VehiclePhysicsComponent.h +++ b/dGame/dComponents/VehiclePhysicsComponent.h @@ -28,7 +28,7 @@ struct RemoteInputInfo { */ class VehiclePhysicsComponent : public PhysicsComponent { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::VEHICLE_PHYSICS; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::VEHICLE_PHYSICS; VehiclePhysicsComponent(Entity* parentEntity); diff --git a/dGame/dComponents/ZoneControlComponent.cpp b/dGame/dComponents/ZoneControlComponent.cpp new file mode 100644 index 000000000..ca9c6626a --- /dev/null +++ b/dGame/dComponents/ZoneControlComponent.cpp @@ -0,0 +1,5 @@ +#include "ZoneControlComponent.h" + +void ZoneControlComponent::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) { + outBitStream->Write(0x40000000); +} diff --git a/dGame/dComponents/ZoneControlComponent.h b/dGame/dComponents/ZoneControlComponent.h new file mode 100644 index 000000000..ba235a808 --- /dev/null +++ b/dGame/dComponents/ZoneControlComponent.h @@ -0,0 +1,15 @@ +#ifndef __ZONECONTROLCOMPONENT__H__ +#define __ZONECONTROLCOMPONENT__H__ + +#include "Component.h" +#include "eReplicaComponentType.h" + +class ZoneControlComponent final : public Component { +public: + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::ZONE_CONTROL; + + ZoneControlComponent(Entity* parent) : Component(parent) {} + void Serialize(RakNet::BitStream* outBitStream, bool isConstruction); +}; + +#endif //!__ZONECONTROLCOMPONENT__H__ diff --git a/dScripts/NtFactionSpyServer.cpp b/dScripts/NtFactionSpyServer.cpp index a11618802..56e2f6020 100644 --- a/dScripts/NtFactionSpyServer.cpp +++ b/dScripts/NtFactionSpyServer.cpp @@ -15,8 +15,7 @@ void NtFactionSpyServer::OnStartup(Entity* self) { // Set the proximity to sense later auto* proximityMonitor = self->GetComponent(); if (proximityMonitor == nullptr) { - proximityMonitor = new ProximityMonitorComponent(self, -1, -1); - self->AddComponent(eReplicaComponentType::PROXIMITY_MONITOR, proximityMonitor); + self->AddComponent(-1, -1); } proximityMonitor->SetProximityRadius(self->GetVar(m_SpyProximityVariable), m_ProximityName); diff --git a/dScripts/ScriptComponent.h b/dScripts/ScriptComponent.h index 98925eb44..cabbf8bf0 100644 --- a/dScripts/ScriptComponent.h +++ b/dScripts/ScriptComponent.h @@ -19,7 +19,7 @@ class Entity; */ class ScriptComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPT; + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPT; ScriptComponent(Entity* parent, std::string scriptName, bool serialized, bool client = false); ~ScriptComponent() override; diff --git a/dScripts/ai/AG/AgStromlingProperty.cpp b/dScripts/ai/AG/AgStromlingProperty.cpp index 9a9ae33b7..83f5ab7a7 100644 --- a/dScripts/ai/AG/AgStromlingProperty.cpp +++ b/dScripts/ai/AG/AgStromlingProperty.cpp @@ -12,6 +12,5 @@ void AgStromlingProperty::OnStartup(Entity* self) { 4 }; - auto* movementAIComponent = new MovementAIComponent(self, movementInfo); - self->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAIComponent); + self->AddComponent(movementInfo); } diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 2208d5d74..3b9dd71e5 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -302,9 +302,7 @@ void SGCannon::DoSpawnTimerFunc(Entity* self, const std::string& name) { auto* enemy = Game::entityManager->CreateEntity(info, nullptr, self); Game::entityManager->ConstructEntity(enemy); - auto* movementAI = new MovementAIComponent(enemy, {}); - - enemy->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAI); + auto* movementAI = enemy->AddComponent(MovementAIInfo{}); movementAI->SetMaxSpeed(toSpawn.initialSpeed); movementAI->SetCurrentSpeed(toSpawn.initialSpeed); diff --git a/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp b/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp index 85507b4ee..acb903520 100644 --- a/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp @@ -16,8 +16,7 @@ class DestroyableTest : public GameDependenciesTest { void SetUp() override { SetUpDependencies(); baseEntity = new Entity(15, GameDependenciesTest::info); - destroyableComponent = new DestroyableComponent(baseEntity); - baseEntity->AddComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent); + destroyableComponent = baseEntity->AddComponent(); // Initialize some values to be not default destroyableComponent->SetMaxHealth(12345.0f); destroyableComponent->SetHealth(23); @@ -37,6 +36,14 @@ class DestroyableTest : public GameDependenciesTest { } }; +TEST_F(DestroyableTest, PlacementNewAddComponentTest) { + ASSERT_NE(destroyableComponent, nullptr); + ASSERT_EQ(destroyableComponent->GetArmor(), 7); + baseEntity->AddComponent(); + ASSERT_NE(baseEntity->GetComponent(), nullptr); + ASSERT_EQ(destroyableComponent->GetArmor(), 0); +} + /** * Test Construction of a DestroyableComponent */ @@ -318,9 +325,7 @@ TEST_F(DestroyableTest, DestroyableComponentFactionTest) { TEST_F(DestroyableTest, DestroyableComponentValiditiyTest) { auto* enemyEntity = new Entity(19, info); - auto* enemyDestroyableComponent = new DestroyableComponent(enemyEntity); - enemyEntity->AddComponent(eReplicaComponentType::DESTROYABLE, enemyDestroyableComponent); - enemyDestroyableComponent->AddFactionNoLookup(16); + enemyEntity->AddComponent()->AddFactionNoLookup(16); destroyableComponent->AddEnemyFaction(16); EXPECT_TRUE(destroyableComponent->IsEnemy(enemyEntity)); EXPECT_FALSE(destroyableComponent->IsFriend(enemyEntity)); diff --git a/tests/dGameTests/dComponentsTests/SimplePhysicsComponentTests.cpp b/tests/dGameTests/dComponentsTests/SimplePhysicsComponentTests.cpp index eb906e7f5..896dcf5af 100644 --- a/tests/dGameTests/dComponentsTests/SimplePhysicsComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/SimplePhysicsComponentTests.cpp @@ -15,8 +15,7 @@ class SimplePhysicsTest : public GameDependenciesTest { void SetUp() override { SetUpDependencies(); baseEntity = std::make_unique(15, GameDependenciesTest::info); - simplePhysicsComponent = new SimplePhysicsComponent(1, baseEntity.get()); - baseEntity->AddComponent(SimplePhysicsComponent::ComponentType, simplePhysicsComponent); + simplePhysicsComponent = baseEntity->AddComponent(1); simplePhysicsComponent->SetClimbableType(eClimbableType::CLIMBABLE_TYPE_WALL); simplePhysicsComponent->SetPosition(NiPoint3(1.0f, 2.0f, 3.0f)); simplePhysicsComponent->SetRotation(NiQuaternion(1.0f, 2.0f, 3.0f, 4.0f));