From 36c44ecc83e3b70bd8c893947316e929bc0aa7c6 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 12 Jun 2023 01:29:43 -0700 Subject: [PATCH] Fully re-implemented initialize --- dCommon/dEnums/dCommonVars.h | 5 +- dGame/Entity.cpp | 112 +++++- dGame/Entity.h | 5 + dGame/EntityInitializeOld.cc | 319 +++++++++--------- dGame/dComponents/DestroyableComponent.cpp | 126 ++++--- dGame/dComponents/DestroyableComponent.h | 14 +- .../dComponents/LevelProgressionComponent.cpp | 8 +- dGame/dComponents/MovementAIComponent.cpp | 53 ++- dGame/dComponents/MovementAIComponent.h | 13 +- .../dComponents/ProximityMonitorComponent.cpp | 28 +- dGame/dComponents/ProximityMonitorComponent.h | 6 +- dScripts/ai/AG/AgStromlingProperty.cpp | 3 +- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 12 +- 13 files changed, 444 insertions(+), 260 deletions(-) diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index 7f80fc39..a071dff3 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -56,7 +56,10 @@ const uint32_t LWOCLONEID_INVALID = -1; //!< Invalid LWOCLONEID const uint16_t LWOINSTANCEID_INVALID = -1; //!< Invalid LWOINSTANCEID const uint16_t LWOMAPID_INVALID = -1; //!< Invalid LWOMAPID const uint64_t LWOZONEID_INVALID = 0; //!< Invalid LWOZONEID -const uint32_t ZONE_CONTROL_LOT = 2365; +const LOT LOT_ZONE_CONTROL = 2365; +const LOT LOT_3D_AMBIENT_SOUND = 6368; +const LOT LOT_MODEL_IN_WORLD = 14; + const float PI = 3.14159f; diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index c02414e2..150a04c0 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -205,6 +205,29 @@ void Entity::ApplyComponentConfig(TemplateComponents& components) const { } } +void Entity::AddPathComponent(TemplateComponents& components) const { + const Path* path = dZoneManager::Instance()->GetZone()->GetPath(GetVarAsString(u"attached_path")); + //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) { + bool hasMovingPlatform = std::count_if(components.begin(), components.end(), [](const auto& componentCandidate) { + return componentCandidate.first == eReplicaComponentType::MOVING_PLATFORM; + }) > 0; + if (!hasMovingPlatform) components.emplace_back(eReplicaComponentType::MOVING_PLATFORM, 0U); + } else if (path->pathType == PathType::Movement) { + bool hasMovementAi = std::count_if(components.begin(), components.end(), [](const auto& componentCandidate) { + return componentCandidate.first == eReplicaComponentType::MOVEMENT_AI; + }) > 0; + if (!hasMovementAi) { + components.emplace_back(eReplicaComponentType::MOVEMENT_AI, 0U); + } + } else { + Game::logger->Log("Entity", "Unsupported path type %i provided for lot %i.", path->pathType, GetLOT()); + } + } +} + void Entity::Initialize() { // A few edge cases to tackle first const auto triggerInfo = GetVarAsString(u"trigger_id"); @@ -222,11 +245,11 @@ void Entity::Initialize() { TemplateComponents components = componentsRegistry->GetTemplateComponents(m_TemplateID); ApplyComponentWhitelist(components); ApplyComponentBlacklist(components); + AddPathComponent(components); // Brick-by-Brick models use custom physics depending on _something_ but the client uses 4246 as the simple // physics component id and 4247 for phantom physics. We'll just use the simple physics component for now // since we dont know what the phantom physics are for at the moment. - if (GetLOT() == 14) components.emplace_back(eReplicaComponentType::SIMPLE_PHYSICS, 4246U); - + if (GetLOT() == LOT_MODEL_IN_WORLD) components.emplace_back(eReplicaComponentType::SIMPLE_PHYSICS, 4246U); for (const auto& [componentTemplate, componentId] : components) { switch (componentTemplate) { case eReplicaComponentType::CONTROLLABLE_PHYSICS: @@ -247,7 +270,7 @@ void Entity::Initialize() { break; case eReplicaComponentType::SCRIPT: { AddComponent(ScriptComponent::GetScriptName(this, componentId)); - if (m_TemplateID == ZONE_CONTROL_LOT) { + if (m_TemplateID == LOT_ZONE_CONTROL) { const auto zoneScript = ScriptComponent::GetZoneScriptName(componentId); if (!zoneScript.empty()) AddComponent(zoneScript); } @@ -257,7 +280,7 @@ void Entity::Initialize() { AddComponent(); break; case eReplicaComponentType::DESTROYABLE: - if (!HasComponent(eReplicaComponentType::DESTROYABLE)) AddComponent(); + if (!HasComponent(eReplicaComponentType::DESTROYABLE)) AddComponent(componentId); break; case eReplicaComponentType::SKILL: AddComponent(); @@ -279,13 +302,14 @@ void Entity::Initialize() { break; case eReplicaComponentType::COLLECTIBLE: AddComponent(); - if (!HasComponent(eReplicaComponentType::DESTROYABLE)) AddComponent(); + if (!HasComponent(eReplicaComponentType::DESTROYABLE)) AddComponent(componentId); break; case eReplicaComponentType::MOVING_PLATFORM: AddComponent(GetVarAsString(u"attached_path")); break; case eReplicaComponentType::PET: AddComponent(componentId); + AddComponent(); break; case eReplicaComponentType::HAVOK_VEHICLE_PHYSICS: { auto* havokVehiclePhysicsComponent = AddComponent(); @@ -295,6 +319,9 @@ void Entity::Initialize() { } break; } + case eReplicaComponentType::MOVEMENT_AI: + AddComponent(); + break; case eReplicaComponentType::PROPERTY: AddComponent(); break; @@ -309,7 +336,7 @@ void Entity::Initialize() { case eReplicaComponentType::MODEL_BEHAVIOR: { AddComponent(); if (!HasComponent(eReplicaComponentType::DESTROYABLE)) { - auto* destroyableComponent = AddComponent(); + auto* destroyableComponent = AddComponent(componentId); if (destroyableComponent) { destroyableComponent->SetHealth(1); destroyableComponent->SetMaxHealth(1.0f); @@ -327,7 +354,7 @@ void Entity::Initialize() { break; case eReplicaComponentType::QUICK_BUILD: AddComponent(componentId); - if (!HasComponent(eReplicaComponentType::DESTROYABLE)) AddComponent(); + if (!HasComponent(eReplicaComponentType::DESTROYABLE)) AddComponent(componentId); break; case eReplicaComponentType::SWITCH: AddComponent(); @@ -335,9 +362,22 @@ void Entity::Initialize() { case eReplicaComponentType::MINIGAME_CONTROL: AddComponent(); break; - case eReplicaComponentType::BASE_COMBAT_AI: - AddComponent(componentId); + case eReplicaComponentType::BASE_COMBAT_AI: { + auto* baseCombatAiComponent = AddComponent(componentId); + if (baseCombatAiComponent && baseCombatAiComponent->GetTetherSpeed() > 0.0f) { + auto* movementAiComponent = AddComponent(); + if (!movementAiComponent) break; + MovementAIInfo movementAiInfo{}; + movementAiInfo.movementType = ""; + movementAiInfo.wanderChance = 0; + movementAiInfo.wanderRadius = 16; + movementAiInfo.wanderSpeed = 2.5f; + movementAiInfo.wanderDelayMax = 5; + movementAiInfo.wanderDelayMin = 2; + movementAiComponent->SetMoveInfo(movementAiInfo); + } break; + } case eReplicaComponentType::MODULE_ASSEMBLY: AddComponent(); break; @@ -362,6 +402,9 @@ void Entity::Initialize() { case eReplicaComponentType::SOUND_TRIGGER: AddComponent(); break; + case eReplicaComponentType::PROXIMITY_MONITOR: + AddComponent(); + break; case eReplicaComponentType::MULTI_ZONE_ENTRANCE: AddComponent(); break; @@ -390,7 +433,6 @@ void Entity::Initialize() { case eReplicaComponentType::PLATFORM_BOUNDARY: case eReplicaComponentType::MODULE: case eReplicaComponentType::JETPACKPAD: - case eReplicaComponentType::MOVEMENT_AI: case eReplicaComponentType::EXHIBIT: case eReplicaComponentType::OVERHEAD_ICON: case eReplicaComponentType::PET_CONTROL: @@ -419,7 +461,6 @@ void Entity::Initialize() { case eReplicaComponentType::DROPPED_LOOT: case eReplicaComponentType::FACTION_TRIGGER: case eReplicaComponentType::BBB: - case eReplicaComponentType::PROXIMITY_MONITOR: case eReplicaComponentType::RACING_SOUND_TRIGGER: case eReplicaComponentType::CHAT_BUBBLE: case eReplicaComponentType::FRIENDS_LIST: @@ -460,6 +501,13 @@ void Entity::Initialize() { } } + AddCallbackTimer(0.0f, [this]() { + auto scripts = CppScripts::GetEntityScripts(this); + std::for_each(scripts.begin(), scripts.end(), [this](const auto& script) { + script->OnStartup(this); + }); + }); + std::for_each(m_Components.begin(), m_Components.end(), [this](auto& component) { component.second->LoadTemplateData(); }); @@ -471,11 +519,47 @@ void Entity::Initialize() { std::for_each(m_Components.begin(), m_Components.end(), [this](auto& component) { component.second->Startup(); }); - if (!IsPlayer()) return; // No save data to load for non players - - std::for_each(m_Components.begin(), m_Components.end(), [this](auto& component) { + // No save data to load for non players + if (!IsPlayer()) std::for_each(m_Components.begin(), m_Components.end(), [this](auto& component) { component.second->LoadFromXml(m_Character->GetXMLDoc()); }); + + TriggerEvent(eTriggerEventType::CREATE, this); + IsGhosted(); +} + +void Entity::IsGhosted() { + 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))) { + return; + } + + /* 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) + ) { + m_IsGhostingCandidate = true; + } + + if (GetLOT() == LOT_3D_AMBIENT_SOUND) m_IsGhostingCandidate = true; + + // Special case for collectibles in Ninjago + if (HasComponent(eReplicaComponentType::COLLECTIBLE) && Game::server->GetZoneID() == 2000) { + m_IsGhostingCandidate = true; + } + } } bool Entity::operator==(const Entity& other) const { diff --git a/dGame/Entity.h b/dGame/Entity.h index b2c2d7c9..ffbc38ee 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -66,6 +66,11 @@ public: // For adding and removing components based on LDF keys void ApplyComponentConfig(TemplateComponents& components) const; + + // Paths have several components they could add. This function will add them. + void AddPathComponent(TemplateComponents& components) const; + + void IsGhosted(); virtual void Initialize(); bool operator==(const Entity& other) const; diff --git a/dGame/EntityInitializeOld.cc b/dGame/EntityInitializeOld.cc index c56bd6a5..f09d5f3b 100644 --- a/dGame/EntityInitializeOld.cc +++ b/dGame/EntityInitializeOld.cc @@ -1,4 +1,4 @@ -Entity::Initialize() { +// Entity::Initialize() { /** * Setup trigger */ @@ -204,75 +204,75 @@ Entity::Initialize() { // if (destroyableComponentID > 0 || collectibleComponentID > 0) { // DestroyableComponent* comp = new DestroyableComponent(this); - if (m_Character) { - comp->LoadFromXml(m_Character->GetXMLDoc()); - } else { - if (componentID > 0) { - // std::vector destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); }); + // if (m_Character) { + // comp->LoadFromXml(m_Character->GetXMLDoc()); + // } else { + // if (componentID > 0) { + // // std::vector destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); }); - if (destCompData.size() > 0) { - if (HasComponent(eReplicaComponentType::RACING_STATS)) { - destCompData[0].imagination = 60; - } + // 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->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->SetMaxHealth(destCompData[0].life); + // comp->SetMaxImagination(destCompData[0].imagination); + // comp->SetMaxArmor(destCompData[0].armor); - comp->SetIsSmashable(destCompData[0].isSmashable); + // comp->SetIsSmashable(destCompData[0].isSmashable); - comp->SetLootMatrixID(destCompData[0].LootMatrixIndex); + // comp->SetLootMatrixID(destCompData[0].LootMatrixIndex); - // Now get currency information - uint32_t npcMinLevel = destCompData[0].level; - uint32_t currencyIndex = destCompData[0].CurrencyIndex; + // // Now get currency information + // uint32_t npcMinLevel = destCompData[0].level; + // uint32_t currencyIndex = destCompData[0].CurrencyIndex; - CDCurrencyTableTable* currencyTable = CDClientManager::Instance().GetTable(); - std::vector currencyValues = currencyTable->Query([=](CDCurrencyTable entry) { return (entry.currencyIndex == currencyIndex && entry.npcminlevel == npcMinLevel); }); + // CDCurrencyTableTable* currencyTable = CDClientManager::Instance().GetTable(); + // std::vector 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); - } + // if (currencyValues.size() > 0) { + // // Set the coins + // comp->SetMinCoins(currencyValues[0].minvalue); + // comp->SetMaxCoins(currencyValues[0].maxvalue); + // } - // extraInfo overrides - comp->SetIsSmashable(GetVarAs(u"is_smashable") != 0); - } - } else { - comp->SetHealth(1); - comp->SetArmor(0); + // // extraInfo overrides + // // comp->SetIsSmashable(GetVarAs(u"is_smashable") != 0); + // } + // } else { + // comp->SetHealth(1); + // comp->SetArmor(0); - comp->SetMaxHealth(1); - comp->SetMaxArmor(0); + // comp->SetMaxHealth(1); + // comp->SetMaxArmor(0); - comp->SetIsSmashable(true); - comp->AddFaction(-1); - comp->AddFaction(6); //Smashables + // 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); - } - } + // // 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; + // 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; + // while (std::getline(ss, token, ',')) { + // if (std::stoi(token) == destCompData[0].faction) continue; - if (token != "") { - comp->AddFaction(std::stoi(token)); - } - } - } + // if (token != "") { + // comp->AddFaction(std::stoi(token)); + // } + // } + // } // m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, comp)); } @@ -505,64 +505,64 @@ Entity::Initialize() { // 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(); - std::vector moveAIComp = moveAITable->Query([=](CDMovementAIComponent entry) {return (entry.id == movementAIID); }); + // int movementAIID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVEMENT_AI); + // if (movementAIID > 0) { + // CDMovementAIComponentTable* moveAITable = CDClientManager::Instance().GetTable(); + // std::vector moveAIComp = moveAITable->Query([=](CDMovementAIComponent entry) {return (entry.id == movementAIID); }); - if (moveAIComp.size() > 0) { - MovementAIInfo moveInfo = MovementAIInfo(); + // 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; + // 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(u"usewanderdb"); + // bool useWanderDB = GetVar(u"usewanderdb"); - if (!useWanderDB) { - const auto wanderOverride = GetVarAs(u"wanderRadius"); + // if (!useWanderDB) { + // const auto wanderOverride = GetVarAs(u"wanderRadius"); - if (wanderOverride != 0.0f) { - moveInfo.wanderRadius = wanderOverride; - } - } + // 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()->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))); + // } + // } else if (petComponentId > 0 || combatAiId > 0 && GetComponent()->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))); - } + // // 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); + // 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(); - if (movementAIcomp){ - // TODO: set path in existing movementAIComp - } else { - // TODO: create movementAIcomp and set path - } - }*/ - } + // //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(); + // 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); @@ -572,70 +572,67 @@ Entity::Initialize() { // } // } - int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROXIMITY_MONITOR); - if (proximityMonitorID > 0) { - CDProximityMonitorComponentTable* proxCompTable = CDClientManager::Instance().GetTable(); - 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)); - } - } + // int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROXIMITY_MONITOR); + // if (proximityMonitorID > 0) { + // CDProximityMonitorComponentTable* proxCompTable = CDClientManager::Instance().GetTable(); + // 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)); + // } + // } // 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); - } - }); + // 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; - } + // 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; - } + // /* 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) + // ) + // { + // m_IsGhostingCandidate = true; + // } - if (GetLOT() == 6368) { - 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; - } - } + // // Special case for collectibles in Ninjago + // if (HasComponent(eReplicaComponentType::COLLECTIBLE) && Game::server->GetZoneID() == 2000) { + // m_IsGhostingCandidate = true; + // } + // } -no_ghosting: +// no_ghosting: - TriggerEvent(eTriggerEventType::CREATE, this); + // TriggerEvent(eTriggerEventType::CREATE, this); - if (m_Character) { - auto controllablePhysicsComponent = GetComponent(); - auto levelComponent = GetComponent(); + // if (m_Character) { + // auto controllablePhysicsComponent = GetComponent(); + // auto levelComponent = GetComponent(); - if (controllablePhysicsComponent && levelComponent) { - controllablePhysicsComponent->SetSpeedMultiplier(levelComponent->GetSpeedBase() / 500.0f); - } - } -} + // if (controllablePhysicsComponent && levelComponent) { + // controllablePhysicsComponent->SetSpeedMultiplier(levelComponent->GetSpeedBase() / 500.0f); + // } + // } +// } diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index d1ba5133..3be0ce0c 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -37,8 +37,9 @@ #include "eGameActivity.h" #include "CDComponentsRegistryTable.h" +#include "CDCurrencyTableTable.h" -DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { +DestroyableComponent::DestroyableComponent(Entity* parent, int32_t componentId) : Component(parent) { m_iArmor = 0; m_fMaxArmor = 0.0f; m_iImagination = 0; @@ -62,6 +63,7 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { m_MinCoins = 0; m_MaxCoins = 0; m_DamageReduction = 0; + m_ComponentId = componentId; m_ImmuneToBasicAttackCount = 0; m_ImmuneToDamageOverTimeCount = 0; @@ -73,49 +75,71 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { m_ImmuneToQuickbuildInterruptCount = 0; m_ImmuneToPullToPointCount = 0; } +void DestroyableComponent::Startup() { -DestroyableComponent::~DestroyableComponent() { } - -void DestroyableComponent::Reinitialize(LOT templateID) { - CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable(); - - int32_t buffComponentID = compRegistryTable->GetByIDAndType(templateID, eReplicaComponentType::BUFF); - int32_t collectibleComponentID = compRegistryTable->GetByIDAndType(templateID, eReplicaComponentType::COLLECTIBLE); - int32_t quickBuildComponentID = compRegistryTable->GetByIDAndType(templateID, eReplicaComponentType::QUICK_BUILD); - - int32_t componentID = 0; - if (collectibleComponentID > 0) componentID = collectibleComponentID; - if (quickBuildComponentID > 0) componentID = quickBuildComponentID; - if (buffComponentID > 0) componentID = buffComponentID; - - CDDestructibleComponentTable* destCompTable = CDClientManager::Instance().GetTable(); - std::vector destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); }); - - if (componentID > 0) { - std::vector destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); }); - - if (destCompData.size() > 0) { - SetHealth(destCompData[0].life); - SetImagination(destCompData[0].imagination); - SetArmor(destCompData[0].armor); - - SetMaxHealth(destCompData[0].life); - SetMaxImagination(destCompData[0].imagination); - SetMaxArmor(destCompData[0].armor); - - SetIsSmashable(destCompData[0].isSmashable); - } - } else { +void DestroyableComponent::LoadConfigData() { + SetIsSmashable(m_ParentEntity->GetVarAs(u"is_smashable") != 0); +} +void DestroyableComponent::LoadTemplateData() { + [[unlikely]] if (m_ParentEntity->IsPlayer()) return; + auto* destroyableComponentTable = CDClientManager::Instance().GetTable(); + auto destroyableDataLookup = destroyableComponentTable->Query([this](CDDestructibleComponent entry) { return (entry.id == this->m_ComponentId); }); + if (m_ComponentId == -1 || destroyableDataLookup.empty()) { SetHealth(1); - SetImagination(0); SetArmor(0); SetMaxHealth(1); - SetMaxImagination(0); SetMaxArmor(0); SetIsSmashable(true); + AddFaction(-1); + AddFaction(6); //Smashables + + // A race car has 60 imagination, other entities defaults to 0. + SetImagination(m_ParentEntity->HasComponent(eReplicaComponentType::RACING_STATS) ? 60 : 0); + SetMaxImagination(m_ParentEntity->HasComponent(eReplicaComponentType::RACING_STATS) ? 60 : 0); + return; + } + + auto destroyableData = destroyableDataLookup.at(0); + if (m_ParentEntity->HasComponent(eReplicaComponentType::RACING_STATS)) { + destroyableData.imagination = 60; + } + + SetHealth(destroyableData.life); + SetImagination(destroyableData.imagination); + SetArmor(destroyableData.armor); + + SetMaxHealth(destroyableData.life); + SetMaxImagination(destroyableData.imagination); + SetMaxArmor(destroyableData.armor); + + SetIsSmashable(destroyableData.isSmashable); + + SetLootMatrixID(destroyableData.LootMatrixIndex); + + // Now get currency information + uint32_t npcMinLevel = destroyableData.level; + uint32_t currencyIndex = destroyableData.CurrencyIndex; + + auto* currencyTable = CDClientManager::Instance().GetTable(); + auto currencyValues = currencyTable->Query([=](CDCurrencyTable entry) { return (entry.currencyIndex == currencyIndex && entry.npcminlevel == npcMinLevel); }); + + if (currencyValues.size() > 0) { + // Set the coins + SetMinCoins(currencyValues.at(0).minvalue); + SetMaxCoins(currencyValues.at(0).maxvalue); + } + AddFaction(destroyableData.faction); + std::stringstream ss(destroyableData.factionList); + std::string tokenStr; + + while (std::getline(ss, tokenStr, ',')) { + int32_t factionToAdd = -2; + if (!GeneralUtils::TryParse(tokenStr, factionToAdd) || factionToAdd == -2 || factionToAdd == destroyableData.faction) continue; + + AddFaction(factionToAdd); } } @@ -661,9 +685,9 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 } //check if hardcore mode is enabled - if (EntityManager::Instance()->GetHardcoreMode()) { + if (EntityManager::Instance()->GetHardcoreMode()) { DoHardcoreModeDrops(source); - } + } Smash(source, eKillType::VIOLENT, u"", skillID); } @@ -823,16 +847,16 @@ void DestroyableComponent::SetFaction(int32_t factionID, bool ignoreChecks) { } void DestroyableComponent::SetStatusImmunity( - const eStateChangeType state, - const bool bImmuneToBasicAttack, - const bool bImmuneToDamageOverTime, - const bool bImmuneToKnockback, - const bool bImmuneToInterrupt, - const bool bImmuneToSpeed, - const bool bImmuneToImaginationGain, - const bool bImmuneToImaginationLoss, - const bool bImmuneToQuickbuildInterrupt, - const bool bImmuneToPullToPoint) { + const eStateChangeType state, + const bool bImmuneToBasicAttack, + const bool bImmuneToDamageOverTime, + const bool bImmuneToKnockback, + const bool bImmuneToInterrupt, + const bool bImmuneToSpeed, + const bool bImmuneToImaginationGain, + const bool bImmuneToImaginationLoss, + const bool bImmuneToQuickbuildInterrupt, + const bool bImmuneToPullToPoint) { if (state == eStateChangeType::POP) { if (bImmuneToBasicAttack && m_ImmuneToBasicAttackCount > 0) m_ImmuneToBasicAttackCount -= 1; @@ -845,7 +869,7 @@ void DestroyableComponent::SetStatusImmunity( if (bImmuneToQuickbuildInterrupt && m_ImmuneToQuickbuildInterruptCount > 0) m_ImmuneToQuickbuildInterruptCount -= 1; if (bImmuneToPullToPoint && m_ImmuneToPullToPointCount > 0) m_ImmuneToPullToPointCount -= 1; - } else if (state == eStateChangeType::PUSH){ + } else if (state == eStateChangeType::PUSH) { if (bImmuneToBasicAttack) m_ImmuneToBasicAttackCount += 1; if (bImmuneToDamageOverTime) m_ImmuneToDamageOverTimeCount += 1; if (bImmuneToKnockback) m_ImmuneToKnockbackCount += 1; @@ -972,7 +996,7 @@ void DestroyableComponent::AddOnHitCallback(const std::function& m_OnHitCallbacks.push_back(callback); } -void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){ +void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) { //check if this is a player: if (m_ParentEntity->IsPlayer()) { //remove hardcore_lose_uscore_on_death_percent from the player's uscore: @@ -990,9 +1014,9 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){ if (inventory) { //get the items inventory: auto items = inventory->GetInventory(eInventoryType::ITEMS); - if (items){ + if (items) { auto itemMap = items->GetItems(); - if (!itemMap.empty()){ + if (!itemMap.empty()) { for (const auto& item : itemMap) { //drop the item: if (!item.second) continue; diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index 1b6a7907..db482e9c 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -21,19 +21,15 @@ class DestroyableComponent : public Component { public: inline static const eReplicaComponentType ComponentType = eReplicaComponentType::DESTROYABLE; - DestroyableComponent(Entity* parentEntity); - ~DestroyableComponent() override; + DestroyableComponent(Entity* parentEntity, int32_t componentId = -1); + void Startup() override; + void LoadConfigData() override; + void LoadTemplateData() override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, uint32_t& flags); void LoadFromXml(tinyxml2::XMLDocument* doc) override; void UpdateXml(tinyxml2::XMLDocument* doc) override; - /** - * Initializes the component using a different LOT - * @param templateID the ID to use for initialization - */ - void Reinitialize(LOT templateID); - /** * Sets the health of this entity. Makes sure this is serialized on the next tick and if this is a character its * stats will also update. @@ -458,6 +454,8 @@ public: void DoHardcoreModeDrops(const LWOOBJID source); private: + // The ID of this component + int32_t m_ComponentId; /** * Whether or not the health should be serialized */ diff --git a/dGame/dComponents/LevelProgressionComponent.cpp b/dGame/dComponents/LevelProgressionComponent.cpp index a2a0dbcc..07fa9dca 100644 --- a/dGame/dComponents/LevelProgressionComponent.cpp +++ b/dGame/dComponents/LevelProgressionComponent.cpp @@ -35,6 +35,10 @@ void LevelProgressionComponent::LoadFromXml(tinyxml2::XMLDocument* doc) { uint32_t characterVersion; level->QueryAttribute("cv", &characterVersion); m_CharacterVersion = static_cast(characterVersion); + auto* controllablePhysicsComponent = m_ParentEntity->GetComponent(); + + if (!controllablePhysicsComponent) return; + controllablePhysicsComponent->SetSpeedMultiplier(GetSpeedBase() / 500.0f); } void LevelProgressionComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { @@ -68,7 +72,7 @@ void LevelProgressionComponent::HandleLevelUp() { } break; case 9: - SetSpeedBase(static_cast(reward->value) ); + SetSpeedBase(static_cast(reward->value)); controllablePhysicsComponent->SetSpeedMultiplier(GetSpeedBase() / 500.0f); break; case 11: @@ -82,7 +86,7 @@ void LevelProgressionComponent::HandleLevelUp() { if (rewardingItem) GameMessages::NotifyLevelRewards(m_ParentEntity->GetObjectID(), m_ParentEntity->GetSystemAddress(), m_Level, !rewardingItem); } -void LevelProgressionComponent::SetRetroactiveBaseSpeed(){ +void LevelProgressionComponent::SetRetroactiveBaseSpeed() { if (m_Level >= 20) m_SpeedBase = 525.0f; auto* controllablePhysicsComponent = m_ParentEntity->GetComponent(); if (controllablePhysicsComponent) controllablePhysicsComponent->SetSpeedMultiplier(m_SpeedBase / 500.0f); diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index 00938ece..f8a54068 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -13,22 +13,18 @@ #include "CDComponentsRegistryTable.h" #include "CDPhysicsComponentTable.h" +#include "CDMovementAIComponentTable.h" std::map MovementAIComponent::m_PhysicsSpeedCache = {}; -MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) : Component(parent) { - m_Info = std::move(info); +MovementAIComponent::MovementAIComponent(Entity* parent, int32_t componentId) : Component(parent) { + m_ComponentId = componentId; m_Done = true; m_BaseCombatAI = nullptr; m_BaseCombatAI = m_ParentEntity->GetComponent(); - //Try and fix the insane values: - if (m_Info.wanderRadius > 5.0f) m_Info.wanderRadius = m_Info.wanderRadius * 0.5f; - if (m_Info.wanderRadius > 8.0f) m_Info.wanderRadius = 8.0f; - if (m_Info.wanderSpeed > 0.5f) m_Info.wanderSpeed = m_Info.wanderSpeed * 0.5f; - m_BaseSpeed = GetBaseSpeed(m_ParentEntity->GetLOT()); m_NextWaypoint = GetCurrentPosition(); @@ -43,7 +39,48 @@ MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) : m_LockRotation = false; } -MovementAIComponent::~MovementAIComponent() = default; +void MovementAIComponent::Startup() { + +} + +void MovementAIComponent::LoadConfigData() { + bool useWanderDB = m_ParentEntity->GetVar(u"usewanderdb"); + + if (!useWanderDB) { + const auto wanderOverride = m_ParentEntity->GetVarAs(u"wanderRadius"); + + if (wanderOverride != 0.0f) { + m_Info.wanderRadius = wanderOverride; + } + } +} + +void MovementAIComponent::LoadTemplateData() { + if (m_ComponentId == -1) return; + auto* movementAiComponentTable = CDClientManager::Instance().GetTable(); + auto movementEntries = movementAiComponentTable->Query([this](CDMovementAIComponent entry) {return (entry.id == this->m_ComponentId); }); + if (movementEntries.empty()) return; + auto movementEntry = movementEntries.at(0); + MovementAIInfo moveInfo{}; + + moveInfo.movementType = movementEntry.MovementType; + moveInfo.wanderChance = movementEntry.WanderChance; + moveInfo.wanderRadius = movementEntry.WanderRadius; + moveInfo.wanderSpeed = movementEntry.WanderSpeed; + moveInfo.wanderDelayMax = movementEntry.WanderDelayMax; + moveInfo.wanderDelayMin = movementEntry.WanderDelayMin; + + this->SetMoveInfo(moveInfo); +} + +void MovementAIComponent::SetMoveInfo(const MovementAIInfo& info) { + m_Info = info; + + //Try and fix the insane values: + if (m_Info.wanderRadius > 5.0f) m_Info.wanderRadius *= 0.5f; + if (m_Info.wanderRadius > 8.0f) m_Info.wanderRadius = 8.0f; + if (m_Info.wanderSpeed > 0.5f) m_Info.wanderSpeed *= 0.5f; +} void MovementAIComponent::Update(const float deltaTime) { if (m_Interrupted) { diff --git a/dGame/dComponents/MovementAIComponent.h b/dGame/dComponents/MovementAIComponent.h index fdec2236..82689ba7 100644 --- a/dGame/dComponents/MovementAIComponent.h +++ b/dGame/dComponents/MovementAIComponent.h @@ -23,6 +23,10 @@ class BaseCombatAIComponent; * Information that describes the different variables used to make an entity move around */ struct MovementAIInfo { + + // copy assignment + MovementAIInfo& operator=(const MovementAIInfo& other) = default; + std::string movementType; /** @@ -59,8 +63,10 @@ class MovementAIComponent : public Component { public: inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI; - MovementAIComponent(Entity* parentEntity, MovementAIInfo info); - ~MovementAIComponent() override; + MovementAIComponent(Entity* parentEntity, int32_t componentId = -1); + void Startup() override; + void LoadTemplateData() override; + void LoadConfigData() override; void Update(float deltaTime) override; @@ -217,6 +223,7 @@ public: */ static float GetBaseSpeed(LOT lot); + void SetMoveInfo(const MovementAIInfo& value); private: /** @@ -326,6 +333,8 @@ private: * Cache of all lots and their respective speeds */ static std::map m_PhysicsSpeedCache; + + int32_t m_ComponentId; }; #endif // MOVEMENTAICOMPONENT_H diff --git a/dGame/dComponents/ProximityMonitorComponent.cpp b/dGame/dComponents/ProximityMonitorComponent.cpp index 8f63f884..2a345eca 100644 --- a/dGame/dComponents/ProximityMonitorComponent.cpp +++ b/dGame/dComponents/ProximityMonitorComponent.cpp @@ -4,14 +4,13 @@ #include "ControllablePhysicsComponent.h" #include "EntityManager.h" #include "SimplePhysicsComponent.h" +#include "CDClientManager.h" +#include "CDProximityMonitorComponentTable.h" const std::map ProximityMonitorComponent::m_EmptyObjectMap = {}; -ProximityMonitorComponent::ProximityMonitorComponent(Entity* parent, int radiusSmall, int radiusLarge) : Component(parent) { - if (radiusSmall != -1 && radiusLarge != -1) { - SetProximityRadius(radiusSmall, "rocketSmall"); - SetProximityRadius(radiusLarge, "rocketLarge"); - } +ProximityMonitorComponent::ProximityMonitorComponent(Entity* parent, int32_t componentId) : Component(parent) { + m_ComponentId = componentId; } ProximityMonitorComponent::~ProximityMonitorComponent() { @@ -24,6 +23,25 @@ ProximityMonitorComponent::~ProximityMonitorComponent() { m_ProximitiesData.clear(); } +void ProximityMonitorComponent::LoadTemplateData() { + if (m_ComponentId == -1) return; + auto* proxCompTable = CDClientManager::Instance().GetTable(); + auto proxCompData = proxCompTable->Query([this](CDProximityMonitorComponent entry) { return (entry.id == this->m_ComponentId); }); + + if (!proxCompData.empty()) { + float radiusSmall = -1.0f; + float radiusLarge = -1.0f; + auto proximitySplit = GeneralUtils::SplitString(proxCompData[0].Proximities, ','); + if (proximitySplit.size() < 2) return; + GeneralUtils::TryParse(proximitySplit.at(0), radiusSmall); + GeneralUtils::TryParse(proximitySplit.at(1), radiusLarge); + if (radiusSmall != -1.0f && radiusLarge != -1.0f) { + SetProximityRadius(radiusSmall, "rocketSmall"); + SetProximityRadius(radiusLarge, "rocketLarge"); + } + } +} + void ProximityMonitorComponent::SetProximityRadius(float proxRadius, const std::string& name) { dpEntity* en = new dpEntity(m_ParentEntity->GetObjectID(), proxRadius); en->SetPosition(m_ParentEntity->GetPosition()); diff --git a/dGame/dComponents/ProximityMonitorComponent.h b/dGame/dComponents/ProximityMonitorComponent.h index 90ba7d54..365eabe6 100644 --- a/dGame/dComponents/ProximityMonitorComponent.h +++ b/dGame/dComponents/ProximityMonitorComponent.h @@ -21,8 +21,10 @@ class ProximityMonitorComponent : public Component { public: inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROXIMITY_MONITOR; - ProximityMonitorComponent(Entity* parentEntity, int smallRadius = -1, int largeRadius = -1); + ProximityMonitorComponent(Entity* parentEntity, int32_t componentId = -1); ~ProximityMonitorComponent() override; + + void LoadTemplateData() override; void Update(float deltaTime) override; /** @@ -71,6 +73,8 @@ private: * Default value for the proximity data */ static const std::map m_EmptyObjectMap; + + int32_t m_ComponentId = 0; }; #endif // PROXIMITYMONITORCOMPONENT_H diff --git a/dScripts/ai/AG/AgStromlingProperty.cpp b/dScripts/ai/AG/AgStromlingProperty.cpp index 83f5ab7a..c776361d 100644 --- a/dScripts/ai/AG/AgStromlingProperty.cpp +++ b/dScripts/ai/AG/AgStromlingProperty.cpp @@ -12,5 +12,6 @@ void AgStromlingProperty::OnStartup(Entity* self) { 4 }; - self->AddComponent(movementInfo); + auto* movementAiComponent = self->AddComponent(0U); + if (movementAiComponent) movementAiComponent->SetMoveInfo(movementInfo); } diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index af2f4050..0eb33050 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -287,11 +287,11 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { auto* enemy = EntityManager::Instance()->CreateEntity(info, nullptr, self); EntityManager::Instance()->ConstructEntity(enemy); - auto movementAI = enemy->AddComponent({}); - - movementAI->SetSpeed(toSpawn.initialSpeed); - movementAI->SetCurrentSpeed(toSpawn.initialSpeed); - movementAI->SetHaltDistance(0.0f); + auto movementAiComponent = enemy->AddComponent(0U); + + movementAiComponent->SetSpeed(toSpawn.initialSpeed); + movementAiComponent->SetCurrentSpeed(toSpawn.initialSpeed); + movementAiComponent->SetHaltDistance(0.0f); std::vector pathWaypoints; @@ -303,7 +303,7 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { std::reverse(pathWaypoints.begin(), pathWaypoints.end()); } - movementAI->SetPath(pathWaypoints); + movementAiComponent->SetPath(pathWaypoints); enemy->AddDieCallback([this, self, enemy, name]() { RegisterHit(self, enemy, name);