mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-05-25 16:22:26 +00:00
Merge branch 'components-wheeeee' of https://github.com/DarkflameUniverse/DarkflameServer into components-wheeeee
This commit is contained in:
commit
9a9b9aa813
@ -33,7 +33,7 @@ public:
|
|||||||
|
|
||||||
virtual void WriteToPacket(RakNet::BitStream* packet) = 0;
|
virtual void WriteToPacket(RakNet::BitStream* packet) = 0;
|
||||||
|
|
||||||
virtual const std::u16string& GetKey() = 0;
|
virtual const std::u16string& GetKey() const = 0;
|
||||||
|
|
||||||
virtual eLDFType GetValueType() = 0;
|
virtual eLDFType GetValueType() = 0;
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
\return The key
|
\return The key
|
||||||
*/
|
*/
|
||||||
const std::u16string& GetKey(void) override { return this->key; }
|
const std::u16string& GetKey(void) const override { return this->key; }
|
||||||
|
|
||||||
//! Gets the LDF Type
|
//! Gets the LDF Type
|
||||||
/*!
|
/*!
|
||||||
|
444
dGame/Entity.cpp
444
dGame/Entity.cpp
@ -3,19 +3,12 @@
|
|||||||
#include "CDClientManager.h"
|
#include "CDClientManager.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "dLogger.h"
|
#include "dLogger.h"
|
||||||
#include <PacketUtils.h>
|
|
||||||
#include <functional>
|
|
||||||
#include "CDDestructibleComponentTable.h"
|
|
||||||
#include "CDClientDatabase.h"
|
|
||||||
#include <sstream>
|
|
||||||
#include "dServer.h"
|
#include "dServer.h"
|
||||||
#include "GameMessages.h"
|
#include "GameMessages.h"
|
||||||
#include "EntityManager.h"
|
#include "EntityManager.h"
|
||||||
#include "dZoneManager.h"
|
#include "dZoneManager.h"
|
||||||
#include "Zone.h"
|
#include "Zone.h"
|
||||||
#include "Spawner.h"
|
#include "Spawner.h"
|
||||||
#include "UserManager.h"
|
|
||||||
#include "dpWorld.h"
|
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "LUTriggers.h"
|
#include "LUTriggers.h"
|
||||||
#include "User.h"
|
#include "User.h"
|
||||||
@ -60,7 +53,6 @@
|
|||||||
#include "ProximityMonitorComponent.h"
|
#include "ProximityMonitorComponent.h"
|
||||||
#include "PropertyEntranceComponent.h"
|
#include "PropertyEntranceComponent.h"
|
||||||
#include "ModelBehaviorComponent.h"
|
#include "ModelBehaviorComponent.h"
|
||||||
#include "ZCompression.h"
|
|
||||||
#include "PetComponent.h"
|
#include "PetComponent.h"
|
||||||
#include "HavokVehiclePhysicsComponent.h"
|
#include "HavokVehiclePhysicsComponent.h"
|
||||||
#include "PossessableComponent.h"
|
#include "PossessableComponent.h"
|
||||||
@ -81,15 +73,9 @@
|
|||||||
|
|
||||||
// Table includes
|
// Table includes
|
||||||
#include "CDComponentsRegistryTable.h"
|
#include "CDComponentsRegistryTable.h"
|
||||||
#include "CDCurrencyTableTable.h"
|
|
||||||
#include "CDMovementAIComponentTable.h"
|
|
||||||
#include "CDProximityMonitorComponentTable.h"
|
|
||||||
#include "CDRebuildComponentTable.h"
|
|
||||||
#include "CDObjectSkillsTable.h"
|
#include "CDObjectSkillsTable.h"
|
||||||
#include "CDObjectsTable.h"
|
#include "CDObjectsTable.h"
|
||||||
#include "CDScriptComponentTable.h"
|
|
||||||
#include "CDSkillBehaviorTable.h"
|
#include "CDSkillBehaviorTable.h"
|
||||||
#include "CDZoneTableTable.h"
|
|
||||||
|
|
||||||
const std::vector<ComponentWhitelist> Entity::m_ComponentWhitelists = {
|
const std::vector<ComponentWhitelist> Entity::m_ComponentWhitelists = {
|
||||||
{ // Unknown use case
|
{ // Unknown use case
|
||||||
@ -541,6 +527,8 @@ void Entity::Initialize() {
|
|||||||
if (!m_Character && EntityManager::Instance()->GetGhostingEnabled()) IsGhosted();
|
if (!m_Character && EntityManager::Instance()->GetGhostingEnabled()) IsGhosted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invert this check and build it into the component initialization. The ghosting property is an intrinsic property of which components the Entity has.
|
||||||
|
// Keep the first check since that is a special case for large scene elements like Brig Rock as a whole.
|
||||||
void Entity::IsGhosted() {
|
void Entity::IsGhosted() {
|
||||||
// Don't ghost what is likely large scene elements
|
// 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))) {
|
if (HasComponent(eReplicaComponentType::SIMPLE_PHYSICS) && HasComponent(eReplicaComponentType::RENDER) && (m_Components.size() == 2 || (HasComponent(eReplicaComponentType::TRIGGER) && m_Components.size() == 3))) {
|
||||||
@ -571,37 +559,27 @@ void Entity::IsGhosted() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to header
|
||||||
bool Entity::operator==(const Entity& other) const {
|
bool Entity::operator==(const Entity& other) const {
|
||||||
return other.m_ObjectID == m_ObjectID;
|
return other.m_ObjectID == m_ObjectID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to header
|
||||||
bool Entity::operator!=(const Entity& other) const {
|
bool Entity::operator!=(const Entity& other) const {
|
||||||
return !(other.m_ObjectID == m_ObjectID);
|
return !(other.m_ObjectID == m_ObjectID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to header
|
||||||
User* Entity::GetParentUser() const {
|
User* Entity::GetParentUser() const {
|
||||||
if (!IsPlayer()) {
|
return IsPlayer() ? static_cast<const Player*>(this)->GetParentUser() : nullptr;
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<const Player*>(this)->GetParentUser();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to header
|
||||||
bool Entity::HasComponent(const eReplicaComponentType componentId) const {
|
bool Entity::HasComponent(const eReplicaComponentType componentId) const {
|
||||||
return m_Components.find(componentId) != m_Components.end();
|
return m_Components.find(componentId) != m_Components.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ScriptComponent*> Entity::GetScriptComponents() {
|
// Fine
|
||||||
std::vector<ScriptComponent*> comps;
|
|
||||||
for (const auto& [componentType, component] : m_Components) {
|
|
||||||
if (componentType == eReplicaComponentType::SCRIPT) {
|
|
||||||
comps.push_back(dynamic_cast<ScriptComponent*>(component.get()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return comps;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Entity::Subscribe(const LWOOBJID& scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName) {
|
void Entity::Subscribe(const LWOOBJID& scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName) {
|
||||||
if (notificationName == "HitOrHealResult" || notificationName == "Hit") {
|
if (notificationName == "HitOrHealResult" || notificationName == "Hit") {
|
||||||
auto* destroyableComponent = GetComponent<DestroyableComponent>();
|
auto* destroyableComponent = GetComponent<DestroyableComponent>();
|
||||||
@ -610,6 +588,7 @@ void Entity::Subscribe(const LWOOBJID& scriptObjId, CppScripts::Script* scriptTo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fine
|
||||||
void Entity::Unsubscribe(const LWOOBJID& scriptObjId, const std::string& notificationName) {
|
void Entity::Unsubscribe(const LWOOBJID& scriptObjId, const std::string& notificationName) {
|
||||||
if (notificationName == "HitOrHealResult" || notificationName == "Hit") {
|
if (notificationName == "HitOrHealResult" || notificationName == "Hit") {
|
||||||
auto* destroyableComponent = GetComponent<DestroyableComponent>();
|
auto* destroyableComponent = GetComponent<DestroyableComponent>();
|
||||||
@ -618,11 +597,13 @@ void Entity::Unsubscribe(const LWOOBJID& scriptObjId, const std::string& notific
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fine
|
||||||
void Entity::SetProximityRadius(const float proxRadius, const std::string& name) {
|
void Entity::SetProximityRadius(const float proxRadius, const std::string& name) {
|
||||||
auto* proximityMonitorComponent = AddComponent<ProximityMonitorComponent>();
|
auto* proximityMonitorComponent = AddComponent<ProximityMonitorComponent>();
|
||||||
if (proximityMonitorComponent) proximityMonitorComponent->SetProximityRadius(proxRadius, name);
|
if (proximityMonitorComponent) proximityMonitorComponent->SetProximityRadius(proxRadius, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove in favor of a square constructor
|
||||||
void Entity::SetProximityRadius(dpEntity* entity, const std::string& name) {
|
void Entity::SetProximityRadius(dpEntity* entity, const std::string& name) {
|
||||||
auto* proximityMonitorComponent = AddComponent<ProximityMonitorComponent>();
|
auto* proximityMonitorComponent = AddComponent<ProximityMonitorComponent>();
|
||||||
if (proximityMonitorComponent) proximityMonitorComponent->SetProximityRadius(entity, name);
|
if (proximityMonitorComponent) proximityMonitorComponent->SetProximityRadius(entity, name);
|
||||||
@ -630,6 +611,7 @@ void Entity::SetProximityRadius(dpEntity* entity, const std::string& name) {
|
|||||||
|
|
||||||
void Entity::SetGMLevel(eGameMasterLevel value) {
|
void Entity::SetGMLevel(eGameMasterLevel value) {
|
||||||
m_GMLevel = value;
|
m_GMLevel = value;
|
||||||
|
// User m_Character?
|
||||||
if (GetParentUser()) {
|
if (GetParentUser()) {
|
||||||
Character* character = GetParentUser()->GetLastUsedChar();
|
Character* character = GetParentUser()->GetLastUsedChar();
|
||||||
|
|
||||||
@ -670,6 +652,7 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, const eReplic
|
|||||||
const auto& syncLDF = GetVar<std::vector<std::u16string>>(u"syncLDF");
|
const auto& syncLDF = GetVar<std::vector<std::u16string>>(u"syncLDF");
|
||||||
|
|
||||||
// Only sync for models.
|
// Only sync for models.
|
||||||
|
// PetComponent check un-needed since we should be removing the component during construction.
|
||||||
if (m_Settings.size() > 0 && (GetComponent<ModelBehaviorComponent>() && !GetComponent<PetComponent>())) {
|
if (m_Settings.size() > 0 && (GetComponent<ModelBehaviorComponent>() && !GetComponent<PetComponent>())) {
|
||||||
outBitStream->Write1(); //ldf data
|
outBitStream->Write1(); //ldf data
|
||||||
|
|
||||||
@ -719,31 +702,27 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, const eReplic
|
|||||||
outBitStream->Write0();
|
outBitStream->Write0();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outBitStream->Write<bool>(m_ParentEntity != nullptr || m_SpawnerID != 0);
|
||||||
if (m_ParentEntity != nullptr || m_SpawnerID != 0) {
|
if (m_ParentEntity != nullptr || m_SpawnerID != 0) {
|
||||||
outBitStream->Write1();
|
|
||||||
if (m_ParentEntity != nullptr) outBitStream->Write(GeneralUtils::SetBit(m_ParentEntity->GetObjectID(), static_cast<uint32_t>(eObjectBits::CLIENT)));
|
if (m_ParentEntity != nullptr) outBitStream->Write(GeneralUtils::SetBit(m_ParentEntity->GetObjectID(), static_cast<uint32_t>(eObjectBits::CLIENT)));
|
||||||
else if (m_Spawner != nullptr && m_Spawner->m_Info.isNetwork) outBitStream->Write(m_SpawnerID);
|
else if (m_Spawner != nullptr && m_Spawner->m_Info.isNetwork) outBitStream->Write(m_SpawnerID);
|
||||||
else outBitStream->Write(GeneralUtils::SetBit(m_SpawnerID, static_cast<uint32_t>(eObjectBits::CLIENT)));
|
else outBitStream->Write(GeneralUtils::SetBit(m_SpawnerID, static_cast<uint32_t>(eObjectBits::CLIENT)));
|
||||||
} else outBitStream->Write0();
|
}
|
||||||
|
|
||||||
outBitStream->Write(m_HasSpawnerNodeID);
|
outBitStream->Write(m_HasSpawnerNodeID);
|
||||||
if (m_HasSpawnerNodeID) outBitStream->Write(m_SpawnerNodeID);
|
if (m_HasSpawnerNodeID) outBitStream->Write(m_SpawnerNodeID);
|
||||||
|
|
||||||
//outBitStream->Write0(); //Spawner node id
|
//outBitStream->Write0(); //Spawner node id
|
||||||
|
|
||||||
if (m_Scale == 1.0f || m_Scale == 0.0f) outBitStream->Write0();
|
outBitStream->Write<bool>(m_Scale != 1.0f || m_Scale != 0.0f);
|
||||||
else {
|
if (m_Scale != 1.0f || m_Scale != 0.0f) outBitStream->Write(m_Scale);
|
||||||
outBitStream->Write1();
|
|
||||||
outBitStream->Write(m_Scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
outBitStream->Write0(); //ObjectWorldState
|
outBitStream->Write0(); //ObjectWorldState
|
||||||
|
|
||||||
|
outBitStream->Write(m_GMLevel != eGameMasterLevel::CIVILIAN);
|
||||||
if (m_GMLevel != eGameMasterLevel::CIVILIAN) {
|
if (m_GMLevel != eGameMasterLevel::CIVILIAN) {
|
||||||
outBitStream->Write1();
|
|
||||||
outBitStream->Write(m_GMLevel);
|
outBitStream->Write(m_GMLevel);
|
||||||
} else outBitStream->Write0(); //No GM Level
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only serialize parent / child info should the info be dirty (changed) or if this is the construction of the entity.
|
// Only serialize parent / child info should the info be dirty (changed) or if this is the construction of the entity.
|
||||||
@ -757,26 +736,27 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, const eReplic
|
|||||||
}
|
}
|
||||||
outBitStream->Write(m_ChildEntities.size() > 0);
|
outBitStream->Write(m_ChildEntities.size() > 0);
|
||||||
if (m_ChildEntities.size() > 0) {
|
if (m_ChildEntities.size() > 0) {
|
||||||
outBitStream->Write((uint16_t)m_ChildEntities.size());
|
outBitStream->Write<uint16_t>(m_ChildEntities.size());
|
||||||
for (Entity* child : m_ChildEntities) {
|
for (Entity* child : m_ChildEntities) {
|
||||||
outBitStream->Write((uint64_t)child->GetObjectID());
|
outBitStream->Write<LWOOBJID>(child->GetObjectID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// uh
|
||||||
void Entity::WriteComponents(RakNet::BitStream* outBitStream, const eReplicaPacketType packetType) {
|
void Entity::WriteComponents(RakNet::BitStream* outBitStream, const eReplicaPacketType packetType) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We should be able to use this at some point
|
||||||
void Entity::ResetFlags() {
|
void Entity::ResetFlags() {
|
||||||
// Unused
|
// Unused
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// std::for_each
|
||||||
void Entity::UpdateXMLDoc(tinyxml2::XMLDocument* doc) {
|
void Entity::UpdateXMLDoc(tinyxml2::XMLDocument* doc) {
|
||||||
//This function should only ever be called from within Character, meaning doc should always exist when this is called.
|
DluAssert(doc != nullptr);
|
||||||
//Naturally, we don't include any non-player components in this update function.
|
|
||||||
|
|
||||||
for (const auto& pair : m_Components) {
|
for (const auto& pair : m_Components) {
|
||||||
if (pair.second == nullptr) continue;
|
if (pair.second == nullptr) continue;
|
||||||
|
|
||||||
@ -793,23 +773,21 @@ CppScripts::Script* Entity::GetScript() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Entity::Update(const float deltaTime) {
|
void Entity::Update(const float deltaTime) {
|
||||||
auto namedTimerItr = std::remove_if(m_Timers.begin(), m_Timers.end(), [this, &deltaTime](EntityTimer* timer) {
|
auto namedTimerItr = std::remove_if(m_Timers.begin(), m_Timers.end(), [this, &deltaTime](const std::unique_ptr<EntityTimer>& timer) {
|
||||||
timer->Update(deltaTime);
|
timer->Update(deltaTime);
|
||||||
if (timer->GetTime() <= 0) {
|
if (timer->GetTime() <= 0) {
|
||||||
GetScript()->OnTimerDone(this, timer->GetName());
|
GetScript()->OnTimerDone(this, timer->GetName());
|
||||||
TriggerEvent(eTriggerEventType::TIMER_DONE, this);
|
TriggerEvent(eTriggerEventType::TIMER_DONE, this);
|
||||||
delete timer;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
m_Timers.erase(namedTimerItr, m_Timers.end());
|
m_Timers.erase(namedTimerItr, m_Timers.end());
|
||||||
|
|
||||||
auto callbackTimerItr = std::remove_if(m_CallbackTimers.begin(), m_CallbackTimers.end(), [this, &deltaTime](EntityCallbackTimer* timer) {
|
auto callbackTimerItr = std::remove_if(m_CallbackTimers.begin(), m_CallbackTimers.end(), [this, &deltaTime](const std::unique_ptr<EntityCallbackTimer>& timer) {
|
||||||
timer->Update(deltaTime);
|
timer->Update(deltaTime);
|
||||||
if (timer->GetTime() <= 0) {
|
if (timer->GetTime() <= 0) {
|
||||||
timer->GetCallback()();
|
timer->ExecuteCallback();
|
||||||
delete timer;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -817,9 +795,10 @@ void Entity::Update(const float deltaTime) {
|
|||||||
m_CallbackTimers.erase(callbackTimerItr, m_CallbackTimers.end());
|
m_CallbackTimers.erase(callbackTimerItr, m_CallbackTimers.end());
|
||||||
|
|
||||||
// Add pending timers to the list of timers so they start next tick.
|
// Add pending timers to the list of timers so they start next tick.
|
||||||
if (m_PendingTimers.size() > 0) {
|
if (!m_PendingTimers.empty()) {
|
||||||
for (auto namedTimer : m_PendingTimers) {
|
this->m_Timers.reserve(m_Timers.size() + m_PendingTimers.size());
|
||||||
m_Timers.push_back(namedTimer);
|
for (auto& timer : m_PendingTimers) {
|
||||||
|
this->m_Timers.push_back(std::move(timer));
|
||||||
}
|
}
|
||||||
m_PendingTimers.clear();
|
m_PendingTimers.clear();
|
||||||
}
|
}
|
||||||
@ -828,33 +807,28 @@ void Entity::Update(const float deltaTime) {
|
|||||||
Sleep();
|
Sleep();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
Wake();
|
|
||||||
}
|
}
|
||||||
|
Wake();
|
||||||
|
|
||||||
GetScript()->OnUpdate(this);
|
GetScript()->OnUpdate(this);
|
||||||
|
|
||||||
for (const auto& pair : m_Components) {
|
for (const auto& [componentId, component] : m_Components) {
|
||||||
if (pair.second == nullptr) continue;
|
if (component) component->Update(deltaTime);
|
||||||
|
|
||||||
pair.second->Update(deltaTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ShouldDestroyAfterUpdate) {
|
if (m_ShouldDestroyAfterUpdate) EntityManager::Instance()->DestroyEntity(this);
|
||||||
EntityManager::Instance()->DestroyEntity(this->GetObjectID());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::OnCollisionProximity(LWOOBJID otherEntity, const std::string& proxName, const std::string& status) {
|
void Entity::OnCollisionProximity(LWOOBJID otherEntity, const std::string& proxName, const std::string& status) {
|
||||||
Entity* other = EntityManager::Instance()->GetEntity(otherEntity);
|
auto* other = EntityManager::Instance()->GetEntity(otherEntity);
|
||||||
if (!other) return;
|
if (!other) return;
|
||||||
|
|
||||||
GetScript()->OnProximityUpdate(this, other, proxName, status);
|
GetScript()->OnProximityUpdate(this, other, proxName, status);
|
||||||
|
|
||||||
auto* rocketComp = GetComponent<RocketLaunchpadControlComponent>();
|
auto* rocketLaunchpadControlComponent = GetComponent<RocketLaunchpadControlComponent>();
|
||||||
if (!rocketComp) return;
|
if (!rocketLaunchpadControlComponent) return;
|
||||||
|
|
||||||
rocketComp->OnProximityUpdate(other, proxName, status);
|
rocketLaunchpadControlComponent->OnProximityUpdate(other, proxName, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) {
|
void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) {
|
||||||
@ -863,14 +837,12 @@ void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) {
|
|||||||
|
|
||||||
GetScript()->OnCollisionPhantom(this, other);
|
GetScript()->OnCollisionPhantom(this, other);
|
||||||
|
|
||||||
for (const auto& callback : m_PhantomCollisionCallbacks) {
|
std::for_each(m_PhantomCollisionCallbacks.begin(), m_PhantomCollisionCallbacks.end(), [other](const auto& callback) {
|
||||||
callback(other);
|
callback(other);
|
||||||
}
|
});
|
||||||
|
|
||||||
auto* switchComp = GetComponent<SwitchComponent>();
|
auto* switchComponent = GetComponent<SwitchComponent>();
|
||||||
if (switchComp) {
|
if (switchComponent) switchComponent->EntityEnter(other);
|
||||||
switchComp->EntityEnter(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
TriggerEvent(eTriggerEventType::ENTER, other);
|
TriggerEvent(eTriggerEventType::ENTER, other);
|
||||||
|
|
||||||
@ -910,10 +882,8 @@ void Entity::OnCollisionLeavePhantom(const LWOOBJID otherEntity) {
|
|||||||
|
|
||||||
TriggerEvent(eTriggerEventType::EXIT, other);
|
TriggerEvent(eTriggerEventType::EXIT, other);
|
||||||
|
|
||||||
auto* switchComp = GetComponent<SwitchComponent>();
|
auto* switchComponent = GetComponent<SwitchComponent>();
|
||||||
if (switchComp) {
|
if (switchComponent) switchComponent->EntityLeave(other);
|
||||||
switchComp->EntityLeave(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto index = std::find(m_TargetsInPhantom.begin(), m_TargetsInPhantom.end(), otherEntity);
|
const auto index = std::find(m_TargetsInPhantom.begin(), m_TargetsInPhantom.end(), otherEntity);
|
||||||
|
|
||||||
@ -950,12 +920,8 @@ void Entity::OnUse(Entity* originator) {
|
|||||||
|
|
||||||
GetScript()->OnUse(this, originator);
|
GetScript()->OnUse(this, originator);
|
||||||
|
|
||||||
// component base class when
|
for (const auto& [componentId, component] : m_Components) {
|
||||||
|
if (component) component->OnUse(originator);
|
||||||
for (const auto& pair : m_Components) {
|
|
||||||
if (pair.second == nullptr) continue;
|
|
||||||
|
|
||||||
pair.second->OnUse(originator);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1016,7 +982,7 @@ void Entity::Smash(const LWOOBJID source, const eKillType killType, const std::u
|
|||||||
if (!m_PlayerIsReadyForUpdates) return;
|
if (!m_PlayerIsReadyForUpdates) return;
|
||||||
|
|
||||||
auto* destroyableComponent = GetComponent<DestroyableComponent>();
|
auto* destroyableComponent = GetComponent<DestroyableComponent>();
|
||||||
if (destroyableComponent == nullptr) {
|
if (!destroyableComponent) {
|
||||||
Kill(EntityManager::Instance()->GetEntity(source));
|
Kill(EntityManager::Instance()->GetEntity(source));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1034,9 +1000,7 @@ void Entity::Smash(const LWOOBJID source, const eKillType killType, const std::u
|
|||||||
void Entity::Kill(Entity* murderer) {
|
void Entity::Kill(Entity* murderer) {
|
||||||
if (!m_PlayerIsReadyForUpdates) return;
|
if (!m_PlayerIsReadyForUpdates) return;
|
||||||
|
|
||||||
for (const auto& cb : m_DieCallbacks) {
|
for (const auto& cb : m_DieCallbacks) cb();
|
||||||
cb();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_DieCallbacks.clear();
|
m_DieCallbacks.clear();
|
||||||
|
|
||||||
@ -1044,13 +1008,9 @@ void Entity::Kill(Entity* murderer) {
|
|||||||
|
|
||||||
GetScript()->OnDie(this, murderer);
|
GetScript()->OnDie(this, murderer);
|
||||||
|
|
||||||
if (m_Spawner != nullptr) {
|
if (m_Spawner) m_Spawner->NotifyOfEntityDeath(m_ObjectID);
|
||||||
m_Spawner->NotifyOfEntityDeath(m_ObjectID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsPlayer()) {
|
if (!IsPlayer()) EntityManager::Instance()->DestroyEntity(this);
|
||||||
EntityManager::Instance()->DestroyEntity(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& grpNameQBShowBricks = GetVar<std::string>(u"grpNameQBShowBricks");
|
const auto& grpNameQBShowBricks = GetVar<std::string>(u"grpNameQBShowBricks");
|
||||||
|
|
||||||
@ -1060,30 +1020,26 @@ void Entity::Kill(Entity* murderer) {
|
|||||||
Spawner* spawner = nullptr;
|
Spawner* spawner = nullptr;
|
||||||
|
|
||||||
if (!spawners.empty()) {
|
if (!spawners.empty()) {
|
||||||
spawner = spawners[0];
|
spawner = spawners.front();
|
||||||
} else {
|
} else {
|
||||||
spawners = dZoneManager::Instance()->GetSpawnersInGroup(grpNameQBShowBricks);
|
spawners = dZoneManager::Instance()->GetSpawnersInGroup(grpNameQBShowBricks);
|
||||||
|
|
||||||
if (!spawners.empty()) {
|
if (!spawners.empty()) spawner = spawners.front();
|
||||||
spawner = spawners[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spawner != nullptr) {
|
if (spawner) spawner->Spawn();
|
||||||
spawner->Spawn();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track a player being smashed
|
// Track a player being smashed
|
||||||
auto* characterComponent = GetComponent<CharacterComponent>();
|
auto* characterComponent = GetComponent<CharacterComponent>();
|
||||||
if (characterComponent != nullptr) {
|
if (characterComponent) {
|
||||||
characterComponent->UpdatePlayerStatistic(TimesSmashed);
|
characterComponent->UpdatePlayerStatistic(TimesSmashed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track a player smashing something else
|
// Track a player smashing something else
|
||||||
if (murderer != nullptr) {
|
if (murderer) {
|
||||||
auto* murdererCharacterComponent = murderer->GetComponent<CharacterComponent>();
|
auto* murdererCharacterComponent = murderer->GetComponent<CharacterComponent>();
|
||||||
if (murdererCharacterComponent != nullptr) {
|
if (murdererCharacterComponent) {
|
||||||
murdererCharacterComponent->UpdatePlayerStatistic(SmashablesSmashed);
|
murdererCharacterComponent->UpdatePlayerStatistic(SmashablesSmashed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1099,65 +1055,62 @@ void Entity::AddCollisionPhantomCallback(const std::function<void(Entity* target
|
|||||||
|
|
||||||
void Entity::AddRebuildCompleteCallback(const std::function<void(Entity* user)>& callback) const {
|
void Entity::AddRebuildCompleteCallback(const std::function<void(Entity* user)>& callback) const {
|
||||||
auto* quickBuildComponent = GetComponent<QuickBuildComponent>();
|
auto* quickBuildComponent = GetComponent<QuickBuildComponent>();
|
||||||
if (quickBuildComponent != nullptr) {
|
if (quickBuildComponent) quickBuildComponent->AddRebuildCompleteCallback(callback);
|
||||||
quickBuildComponent->AddRebuildCompleteCallback(callback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entity::GetIsDead() const {
|
bool Entity::GetIsDead() const {
|
||||||
auto* dest = GetComponent<DestroyableComponent>();
|
auto* dest = GetComponent<DestroyableComponent>();
|
||||||
if (dest && dest->GetArmor() == 0 && dest->GetHealth() == 0) return true;
|
return dest && dest->GetArmor() == 0 && dest->GetHealth() == 0;
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace static_cast with dynamic_cast
|
||||||
void Entity::AddLootItem(const Loot::Info& info) {
|
void Entity::AddLootItem(const Loot::Info& info) {
|
||||||
if (!IsPlayer()) return;
|
if (!IsPlayer()) return;
|
||||||
auto& droppedLoot = static_cast<Player*>(this)->GetDroppedLoot();
|
auto& droppedLoot = static_cast<Player*>(this)->GetDroppedLoot();
|
||||||
droppedLoot.insert(std::make_pair(info.id, info));
|
droppedLoot.insert(std::make_pair(info.id, info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace static_cast with dynamic_cast
|
||||||
void Entity::PickupItem(const LWOOBJID& objectID) {
|
void Entity::PickupItem(const LWOOBJID& objectID) {
|
||||||
if (!IsPlayer()) return;
|
if (!IsPlayer()) return;
|
||||||
auto* inv = GetComponent<InventoryComponent>();
|
auto* inventoryComponent = GetComponent<InventoryComponent>();
|
||||||
if (!inv) return;
|
if (!inventoryComponent) return;
|
||||||
|
|
||||||
CDObjectsTable* objectsTable = CDClientManager::Instance().GetTable<CDObjectsTable>();
|
auto* objectsTable = CDClientManager::Instance().GetTable<CDObjectsTable>();
|
||||||
|
auto* skillsTable = CDClientManager::Instance().GetTable<CDObjectSkillsTable>();
|
||||||
|
|
||||||
auto& droppedLoot = static_cast<Player*>(this)->GetDroppedLoot();
|
auto& droppedLoot = static_cast<Player*>(this)->GetDroppedLoot();
|
||||||
|
|
||||||
for (const auto& p : droppedLoot) {
|
// See if there is some faster way to do this.
|
||||||
if (p.first == objectID) {
|
for (const auto& [lootObjId, loot] : droppedLoot) {
|
||||||
|
if (lootObjId != objectID) continue;
|
||||||
auto* characterComponent = GetComponent<CharacterComponent>();
|
auto* characterComponent = GetComponent<CharacterComponent>();
|
||||||
if (characterComponent != nullptr) {
|
if (characterComponent) characterComponent->TrackLOTCollection(loot.lot);
|
||||||
characterComponent->TrackLOTCollection(p.second.lot);
|
|
||||||
}
|
|
||||||
|
|
||||||
const CDObjects& object = objectsTable->GetByID(p.second.lot);
|
const CDObjects& object = objectsTable->GetByID(loot.lot);
|
||||||
if (object.id != 0 && object.type == "Powerup") {
|
if (object.id != 0 && object.type == "Powerup") {
|
||||||
CDObjectSkillsTable* skillsTable = CDClientManager::Instance().GetTable<CDObjectSkillsTable>();
|
const auto lootLot = loot.lot;
|
||||||
std::vector<CDObjectSkills> skills = skillsTable->Query([=](CDObjectSkills entry) {return (entry.objectTemplate == p.second.lot); });
|
auto skills = skillsTable->Query([lootLot](CDObjectSkills entry) {return (entry.objectTemplate == lootLot); });
|
||||||
for (CDObjectSkills skill : skills) {
|
for (const auto& skill : skills) {
|
||||||
CDSkillBehaviorTable* skillBehTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>();
|
auto* skillBehaviorTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>();
|
||||||
CDSkillBehavior behaviorData = skillBehTable->GetSkillByID(skill.skillID);
|
auto behaviorData = skillBehaviorTable->GetSkillByID(skill.skillID);
|
||||||
|
// This should take a skillID, not a behaviorID.
|
||||||
SkillComponent::HandleUnmanaged(behaviorData.behaviorID, GetObjectID());
|
SkillComponent::HandleUnmanaged(behaviorData.behaviorID, GetObjectID());
|
||||||
|
|
||||||
auto* missionComponent = GetComponent<MissionComponent>();
|
auto* missionComponent = GetComponent<MissionComponent>();
|
||||||
|
|
||||||
if (missionComponent != nullptr) {
|
if (missionComponent) missionComponent->Progress(eMissionTaskType::POWERUP, skill.skillID);
|
||||||
missionComponent->Progress(eMissionTaskType::POWERUP, skill.skillID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
inv->AddItem(p.second.lot, p.second.count, eLootSourceType::PICKUP, eInventoryType::INVALID, {}, LWOOBJID_EMPTY, true, false, LWOOBJID_EMPTY, eInventoryType::INVALID, 1);
|
inventoryComponent->AddItem(loot.lot, loot.count, eLootSourceType::PICKUP, eInventoryType::INVALID, {}, LWOOBJID_EMPTY, true, false, LWOOBJID_EMPTY, eInventoryType::INVALID, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
droppedLoot.erase(objectID);
|
droppedLoot.erase(objectID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This functions name is misleading and should not modify the number of dropped coins.
|
||||||
|
// A separate function, PickupCoins should modify that.
|
||||||
|
// Replace static_cast with dynamic_cast
|
||||||
bool Entity::CanPickupCoins(const uint64_t& count) {
|
bool Entity::CanPickupCoins(const uint64_t& count) {
|
||||||
if (!IsPlayer()) return false;
|
if (!IsPlayer()) return false;
|
||||||
auto* player = static_cast<Player*>(this);
|
auto* player = static_cast<Player*>(this);
|
||||||
@ -1170,92 +1123,66 @@ bool Entity::CanPickupCoins(const uint64_t& count) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::RegisterCoinDrop(const uint64_t& count) {
|
// Replace static_cast with dynamic_cast
|
||||||
|
void Entity::RegisterCoinDrop(const uint64_t& coinsDropped) {
|
||||||
if (!IsPlayer()) return;
|
if (!IsPlayer()) return;
|
||||||
auto* player = static_cast<Player*>(this);
|
auto* player = static_cast<Player*>(this);
|
||||||
auto droppedCoins = player->GetDroppedCoins();
|
player->SetDroppedCoins(player->GetDroppedCoins() + coinsDropped);
|
||||||
droppedCoins += count;
|
|
||||||
player->SetDroppedCoins(droppedCoins);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::AddChild(Entity* child) {
|
void Entity::AddChild(Entity* child) {
|
||||||
m_IsParentChildDirty = true;
|
m_IsParentChildDirty = true;
|
||||||
m_ChildEntities.push_back(child);
|
if (std::find(m_ChildEntities.begin(), m_ChildEntities.end(), child) == m_ChildEntities.end()) m_ChildEntities.push_back(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::RemoveChild(Entity* child) {
|
void Entity::RemoveChild(Entity* child) {
|
||||||
if (!child) return;
|
if (!child) return;
|
||||||
uint32_t entityPosition = 0;
|
uint32_t entityPosition = 0;
|
||||||
while (entityPosition < m_ChildEntities.size()) {
|
auto toRemove = std::remove(m_ChildEntities.begin(), m_ChildEntities.end(), child);
|
||||||
if (!m_ChildEntities[entityPosition] || (m_ChildEntities[entityPosition])->GetObjectID() == child->GetObjectID()) {
|
if (toRemove != m_ChildEntities.end()) m_IsParentChildDirty = true;
|
||||||
m_IsParentChildDirty = true;
|
m_ChildEntities.erase(toRemove, m_ChildEntities.end());
|
||||||
m_ChildEntities.erase(m_ChildEntities.begin() + entityPosition);
|
|
||||||
} else {
|
|
||||||
entityPosition++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::RemoveParent() {
|
void Entity::RemoveParent() {
|
||||||
|
if (m_ParentEntity) m_IsParentChildDirty = true;
|
||||||
|
else Game::logger->Log("Entity", "Attempted to remove parent from(objid:lot) (%llu:%i) when no parent existed", GetObjectID(), GetLOT());
|
||||||
this->m_ParentEntity = nullptr;
|
this->m_ParentEntity = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::AddTimer(const std::string& name, float time) {
|
void Entity::AddTimer(const std::string& name, float time) {
|
||||||
EntityTimer* timer = new EntityTimer(name, time);
|
m_PendingTimers.emplace_back(std::make_unique<EntityTimer>(name, time));
|
||||||
m_PendingTimers.push_back(timer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::AddCallbackTimer(const float time, const std::function<void()>& callback) {
|
void Entity::AddCallbackTimer(const float time, const std::function<void()>& callback) {
|
||||||
EntityCallbackTimer* timer = new EntityCallbackTimer(time, callback);
|
m_CallbackTimers.emplace_back(std::make_unique<EntityCallbackTimer>(time, callback));
|
||||||
m_CallbackTimers.push_back(timer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entity::HasTimer(const std::string& name) {
|
bool Entity::HasTimer(const std::string& name) {
|
||||||
for (auto* timer : m_Timers) {
|
auto possibleTimer = std::find_if(m_Timers.begin(), m_Timers.end(), [name](const std::unique_ptr<EntityTimer>& timer) {
|
||||||
if (timer->GetName() == name) {
|
return timer->GetName() == name;
|
||||||
return true;
|
});
|
||||||
}
|
return possibleTimer != m_Timers.end();
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::CancelCallbackTimers() {
|
void Entity::CancelCallbackTimers() {
|
||||||
for (auto* callback : m_CallbackTimers) {
|
|
||||||
delete callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_CallbackTimers.clear();
|
m_CallbackTimers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::ScheduleKillAfterUpdate(Entity* murderer) {
|
void Entity::ScheduleKillAfterUpdate(Entity* murderer) {
|
||||||
//if (m_Info.spawner) m_Info.spawner->ScheduleKill(this);
|
|
||||||
EntityManager::Instance()->ScheduleForKill(this);
|
EntityManager::Instance()->ScheduleForKill(this);
|
||||||
|
|
||||||
if (murderer) m_ScheduleKiller = murderer;
|
if (murderer) m_ScheduleKiller = murderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::CancelTimer(const std::string& name) {
|
void Entity::CancelTimer(const std::string& name) {
|
||||||
for (int i = 0; i < m_Timers.size(); i++) {
|
auto toErase = std::remove_if(m_Timers.begin(), m_Timers.end(), [&name](const std::unique_ptr<EntityTimer>& timer) {
|
||||||
if (m_Timers[i]->GetName() == name) {
|
return timer->GetName() == name;
|
||||||
delete m_Timers[i];
|
});
|
||||||
m_Timers.erase(m_Timers.begin() + i);
|
m_Timers.erase(m_Timers.begin(), toErase);
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// ### LEFT OFF HERE ###
|
||||||
void Entity::CancelAllTimers() {
|
void Entity::CancelAllTimers() {
|
||||||
for (auto* timer : m_Timers) {
|
|
||||||
delete timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Timers.clear();
|
m_Timers.clear();
|
||||||
|
|
||||||
for (auto* callBackTimer : m_CallbackTimers) {
|
|
||||||
delete callBackTimer;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_CallbackTimers.clear();
|
m_CallbackTimers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1302,18 +1229,12 @@ void Entity::SetObservers(int8_t value) {
|
|||||||
|
|
||||||
void Entity::Sleep() {
|
void Entity::Sleep() {
|
||||||
auto* baseCombatAIComponent = GetComponent<BaseCombatAIComponent>();
|
auto* baseCombatAIComponent = GetComponent<BaseCombatAIComponent>();
|
||||||
|
if (baseCombatAIComponent) baseCombatAIComponent->Sleep();
|
||||||
if (baseCombatAIComponent != nullptr) {
|
|
||||||
baseCombatAIComponent->Sleep();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::Wake() {
|
void Entity::Wake() {
|
||||||
auto* baseCombatAIComponent = GetComponent<BaseCombatAIComponent>();
|
auto* baseCombatAIComponent = GetComponent<BaseCombatAIComponent>();
|
||||||
|
if (baseCombatAIComponent) baseCombatAIComponent->Wake();
|
||||||
if (baseCombatAIComponent != nullptr) {
|
|
||||||
baseCombatAIComponent->Wake();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entity::IsSleeping() const {
|
bool Entity::IsSleeping() const {
|
||||||
@ -1322,173 +1243,164 @@ bool Entity::IsSleeping() const {
|
|||||||
|
|
||||||
|
|
||||||
const NiPoint3& Entity::GetPosition() const {
|
const NiPoint3& Entity::GetPosition() const {
|
||||||
auto* controllable = GetComponent<ControllablePhysicsComponent>();
|
auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>();
|
||||||
|
|
||||||
if (controllable != nullptr) {
|
if (controllablePhysicsComponent != nullptr) {
|
||||||
return controllable->GetPosition();
|
return controllablePhysicsComponent->GetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* phantom = GetComponent<PhantomPhysicsComponent>();
|
auto* phantomPhysicsComponent = GetComponent<PhantomPhysicsComponent>();
|
||||||
|
|
||||||
if (phantom != nullptr) {
|
if (phantomPhysicsComponent != nullptr) {
|
||||||
return phantom->GetPosition();
|
return phantomPhysicsComponent->GetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* simple = GetComponent<SimplePhysicsComponent>();
|
auto* simplePhysicsComponent = GetComponent<SimplePhysicsComponent>();
|
||||||
|
|
||||||
if (simple != nullptr) {
|
if (simplePhysicsComponent != nullptr) {
|
||||||
return simple->GetPosition();
|
return simplePhysicsComponent->GetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* vehicle = GetComponent<HavokVehiclePhysicsComponent>();
|
auto* vehiclePhysicsComponent = GetComponent<HavokVehiclePhysicsComponent>();
|
||||||
|
|
||||||
if (vehicle != nullptr) {
|
if (vehiclePhysicsComponent != nullptr) {
|
||||||
return vehicle->GetPosition();
|
return vehiclePhysicsComponent->GetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NiPoint3::ZERO;
|
return NiPoint3::ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NiQuaternion& Entity::GetRotation() const {
|
const NiQuaternion& Entity::GetRotation() const {
|
||||||
auto* controllable = GetComponent<ControllablePhysicsComponent>();
|
auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>();
|
||||||
|
|
||||||
if (controllable != nullptr) {
|
if (controllablePhysicsComponent != nullptr) {
|
||||||
return controllable->GetRotation();
|
return controllablePhysicsComponent->GetRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* phantom = GetComponent<PhantomPhysicsComponent>();
|
auto* phantomPhysicsComponent = GetComponent<PhantomPhysicsComponent>();
|
||||||
|
|
||||||
if (phantom != nullptr) {
|
if (phantomPhysicsComponent != nullptr) {
|
||||||
return phantom->GetRotation();
|
return phantomPhysicsComponent->GetRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* simple = GetComponent<SimplePhysicsComponent>();
|
auto* simplePhysicsComponent = GetComponent<SimplePhysicsComponent>();
|
||||||
|
|
||||||
if (simple != nullptr) {
|
if (simplePhysicsComponent != nullptr) {
|
||||||
return simple->GetRotation();
|
return simplePhysicsComponent->GetRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* vehicle = GetComponent<HavokVehiclePhysicsComponent>();
|
auto* vehiclePhysicsComponent = GetComponent<HavokVehiclePhysicsComponent>();
|
||||||
|
|
||||||
if (vehicle != nullptr) {
|
if (vehiclePhysicsComponent != nullptr) {
|
||||||
return vehicle->GetRotation();
|
return vehiclePhysicsComponent->GetRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NiQuaternion::IDENTITY;
|
return NiQuaternion::IDENTITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::SetPosition(const NiPoint3& position) {
|
void Entity::SetPosition(const NiPoint3& position) {
|
||||||
auto* controllable = GetComponent<ControllablePhysicsComponent>();
|
auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>();
|
||||||
|
|
||||||
if (controllable != nullptr) {
|
if (controllablePhysicsComponent != nullptr) {
|
||||||
controllable->SetPosition(position);
|
controllablePhysicsComponent->SetPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* phantom = GetComponent<PhantomPhysicsComponent>();
|
auto* phantomPhysicsComponent = GetComponent<PhantomPhysicsComponent>();
|
||||||
|
|
||||||
if (phantom != nullptr) {
|
if (phantomPhysicsComponent != nullptr) {
|
||||||
phantom->SetPosition(position);
|
phantomPhysicsComponent->SetPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* simple = GetComponent<SimplePhysicsComponent>();
|
auto* simplePhysicsComponent = GetComponent<SimplePhysicsComponent>();
|
||||||
|
|
||||||
if (simple != nullptr) {
|
if (simplePhysicsComponent != nullptr) {
|
||||||
simple->SetPosition(position);
|
simplePhysicsComponent->SetPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* vehicle = GetComponent<HavokVehiclePhysicsComponent>();
|
auto* vehiclePhysicsComponent = GetComponent<HavokVehiclePhysicsComponent>();
|
||||||
|
|
||||||
if (vehicle != nullptr) {
|
if (vehiclePhysicsComponent != nullptr) {
|
||||||
vehicle->SetPosition(position);
|
vehiclePhysicsComponent->SetPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityManager::Instance()->SerializeEntity(this);
|
EntityManager::Instance()->SerializeEntity(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::SetRotation(const NiQuaternion& rotation) {
|
void Entity::SetRotation(const NiQuaternion& rotation) {
|
||||||
auto* controllable = GetComponent<ControllablePhysicsComponent>();
|
auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>();
|
||||||
|
|
||||||
if (controllable != nullptr) {
|
if (controllablePhysicsComponent != nullptr) {
|
||||||
controllable->SetRotation(rotation);
|
controllablePhysicsComponent->SetRotation(rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* phantom = GetComponent<PhantomPhysicsComponent>();
|
auto* phantomPhysicsComponent = GetComponent<PhantomPhysicsComponent>();
|
||||||
|
|
||||||
if (phantom != nullptr) {
|
if (phantomPhysicsComponent != nullptr) {
|
||||||
phantom->SetRotation(rotation);
|
phantomPhysicsComponent->SetRotation(rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* simple = GetComponent<SimplePhysicsComponent>();
|
auto* simplePhysicsComponent = GetComponent<SimplePhysicsComponent>();
|
||||||
|
|
||||||
if (simple != nullptr) {
|
if (simplePhysicsComponent != nullptr) {
|
||||||
simple->SetRotation(rotation);
|
simplePhysicsComponent->SetRotation(rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* vehicle = GetComponent<HavokVehiclePhysicsComponent>();
|
auto* vehiclePhysicsComponent = GetComponent<HavokVehiclePhysicsComponent>();
|
||||||
|
|
||||||
if (vehicle != nullptr) {
|
if (vehiclePhysicsComponent != nullptr) {
|
||||||
vehicle->SetRotation(rotation);
|
vehiclePhysicsComponent->SetRotation(rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityManager::Instance()->SerializeEntity(this);
|
EntityManager::Instance()->SerializeEntity(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to header
|
||||||
bool Entity::GetBoolean(const std::u16string& name) const {
|
bool Entity::GetBoolean(const std::u16string& name) const {
|
||||||
return GetVar<bool>(name);
|
return GetVar<bool>(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to header
|
||||||
int32_t Entity::GetI32(const std::u16string& name) const {
|
int32_t Entity::GetI32(const std::u16string& name) const {
|
||||||
return GetVar<int32_t>(name);
|
return GetVar<int32_t>(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to header
|
||||||
int64_t Entity::GetI64(const std::u16string& name) const {
|
int64_t Entity::GetI64(const std::u16string& name) const {
|
||||||
return GetVar<int64_t>(name);
|
return GetVar<int64_t>(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to header
|
||||||
void Entity::SetBoolean(const std::u16string& name, const bool value) {
|
void Entity::SetBoolean(const std::u16string& name, const bool value) {
|
||||||
SetVar(name, value);
|
SetVar(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to header
|
||||||
void Entity::SetI32(const std::u16string& name, const int32_t value) {
|
void Entity::SetI32(const std::u16string& name, const int32_t value) {
|
||||||
SetVar(name, value);
|
SetVar(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to header
|
||||||
void Entity::SetI64(const std::u16string& name, const int64_t value) {
|
void Entity::SetI64(const std::u16string& name, const int64_t value) {
|
||||||
SetVar(name, value);
|
SetVar(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entity::HasVar(const std::u16string& name) const {
|
bool Entity::HasVar(const std::u16string& name) const {
|
||||||
for (auto* data : m_Settings) {
|
auto hasVar = std::find_if(m_Settings.begin(), m_Settings.end(), [&name](const LDFBaseData* data) {
|
||||||
if (data->GetKey() == name) {
|
return data->GetKey() == name;
|
||||||
return true;
|
});
|
||||||
}
|
return hasVar != m_Settings.end();
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to header
|
||||||
void Entity::SetNetworkId(const uint16_t id) {
|
void Entity::SetNetworkId(const uint16_t id) {
|
||||||
m_NetworkID = id;
|
m_NetworkID = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<LWOOBJID>& Entity::GetTargetsInPhantom() {
|
std::vector<LWOOBJID>& Entity::GetTargetsInPhantom() {
|
||||||
std::vector<LWOOBJID> valid;
|
auto toRemove = std::remove_if(m_TargetsInPhantom.begin(), m_TargetsInPhantom.end(), [this](const LWOOBJID& id) {
|
||||||
|
return EntityManager::Instance()->GetEntity(id) == nullptr;
|
||||||
// Clean up invalid targets, like disconnected players
|
});
|
||||||
for (auto i = 0u; i < m_TargetsInPhantom.size(); ++i) {
|
m_TargetsInPhantom.erase(toRemove, m_TargetsInPhantom.end());
|
||||||
const auto id = m_TargetsInPhantom.at(i);
|
|
||||||
|
|
||||||
auto* entity = EntityManager::Instance()->GetEntity(id);
|
|
||||||
|
|
||||||
if (entity == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
valid.push_back(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_TargetsInPhantom = valid;
|
|
||||||
|
|
||||||
return m_TargetsInPhantom;
|
return m_TargetsInPhantom;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1498,34 +1410,18 @@ void Entity::SendNetworkVar(const std::string& data, const SystemAddress& sysAdd
|
|||||||
|
|
||||||
LDFBaseData* Entity::GetVarData(const std::u16string& name) const {
|
LDFBaseData* Entity::GetVarData(const std::u16string& name) const {
|
||||||
for (auto* data : m_Settings) {
|
for (auto* data : m_Settings) {
|
||||||
if (data == nullptr) {
|
if (data && data->GetKey() == name) return data;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->GetKey() != name) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Entity::GetVarAsString(const std::u16string& name) const {
|
std::string Entity::GetVarAsString(const std::u16string& name) const {
|
||||||
auto* data = GetVarData(name);
|
auto* data = GetVarData(name);
|
||||||
|
return data ? data->GetValueAsString() : "";
|
||||||
if (data == nullptr) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return data->GetValueAsString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::Resurrect() {
|
void Entity::Resurrect() {
|
||||||
if (IsPlayer()) {
|
if (IsPlayer()) GameMessages::SendResurrect(this);
|
||||||
GameMessages::SendResurrect(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::AddToGroups(const std::string& group) {
|
void Entity::AddToGroups(const std::string& group) {
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
#ifndef __ENTITY__H__
|
#ifndef __ENTITY__H__
|
||||||
#define __ENTITY__H__
|
#define __ENTITY__H__
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <functional>
|
|
||||||
#include <typeinfo>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "dCommonVars.h"
|
||||||
#include "NiPoint3.h"
|
#include "NiPoint3.h"
|
||||||
#include "NiQuaternion.h"
|
#include "NiQuaternion.h"
|
||||||
#include "LDFFormat.h"
|
|
||||||
#include "eKillType.h"
|
#include "eKillType.h"
|
||||||
|
|
||||||
namespace Loot {
|
namespace Loot {
|
||||||
@ -33,6 +29,7 @@ class Component;
|
|||||||
class Item;
|
class Item;
|
||||||
class Character;
|
class Character;
|
||||||
class EntityCallbackTimer;
|
class EntityCallbackTimer;
|
||||||
|
class LDFBaseData;
|
||||||
enum class eTriggerEventType;
|
enum class eTriggerEventType;
|
||||||
enum class eGameMasterLevel : uint8_t;
|
enum class eGameMasterLevel : uint8_t;
|
||||||
enum class eReplicaComponentType : uint32_t;
|
enum class eReplicaComponentType : uint32_t;
|
||||||
@ -145,8 +142,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool HasComponent(const eReplicaComponentType componentId) const;
|
bool HasComponent(const eReplicaComponentType componentId) const;
|
||||||
|
|
||||||
std::vector<ScriptComponent*> GetScriptComponents();
|
|
||||||
|
|
||||||
void Subscribe(const LWOOBJID& scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName);
|
void Subscribe(const LWOOBJID& scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName);
|
||||||
void Unsubscribe(const LWOOBJID& scriptObjId, const std::string& notificationName);
|
void Unsubscribe(const LWOOBJID& scriptObjId, const std::string& notificationName);
|
||||||
|
|
||||||
@ -340,9 +335,9 @@ protected:
|
|||||||
std::vector<std::function<void(Entity*)>> m_PhantomCollisionCallbacks;
|
std::vector<std::function<void(Entity*)>> m_PhantomCollisionCallbacks;
|
||||||
|
|
||||||
std::unordered_map<eReplicaComponentType, ComponentPtr> m_Components;
|
std::unordered_map<eReplicaComponentType, ComponentPtr> m_Components;
|
||||||
std::vector<EntityTimer*> m_Timers;
|
std::vector<std::unique_ptr<EntityTimer>> m_Timers;
|
||||||
std::vector<EntityTimer*> m_PendingTimers;
|
std::vector<std::unique_ptr<EntityTimer>> m_PendingTimers;
|
||||||
std::vector<EntityCallbackTimer*> m_CallbackTimers;
|
std::vector<std::unique_ptr<EntityCallbackTimer>> m_CallbackTimers;
|
||||||
|
|
||||||
bool m_ShouldDestroyAfterUpdate;
|
bool m_ShouldDestroyAfterUpdate;
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#error "Include Entity.h instead of Entity.tpp"
|
#error "Include Entity.h instead of Entity.tpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "LDFFormat.h"
|
||||||
|
|
||||||
// Access definitions
|
// Access definitions
|
||||||
template <typename Cmpt>
|
template <typename Cmpt>
|
||||||
Cmpt* Entity::GetComponent() const {
|
Cmpt* Entity::GetComponent() const {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#include "EntityCallbackTimer.h"
|
#include "EntityCallbackTimer.h"
|
||||||
|
|
||||||
EntityCallbackTimer::EntityCallbackTimer(float time, std::function<void()> callback) {
|
EntityCallbackTimer::EntityCallbackTimer(const float& time, const std::function<void()>& callback) {
|
||||||
m_Time = time;
|
m_Time = time;
|
||||||
m_Callback = callback;
|
m_Callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityCallbackTimer::~EntityCallbackTimer() {
|
void EntityCallbackTimer::ExecuteCallback() {
|
||||||
|
m_Callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void()> EntityCallbackTimer::GetCallback() {
|
std::function<void()> EntityCallbackTimer::GetCallback() {
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
class EntityCallbackTimer {
|
class EntityCallbackTimer {
|
||||||
public:
|
public:
|
||||||
EntityCallbackTimer(float time, std::function<void()> callback);
|
EntityCallbackTimer(const float& time, const std::function<void()>& callback);
|
||||||
~EntityCallbackTimer();
|
|
||||||
|
|
||||||
|
void ExecuteCallback();
|
||||||
std::function<void()> GetCallback();
|
std::function<void()> GetCallback();
|
||||||
float GetTime();
|
float GetTime();
|
||||||
|
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
#include "EntityTimer.h"
|
#include "EntityTimer.h"
|
||||||
|
|
||||||
EntityTimer::EntityTimer(std::string name, float time) {
|
EntityTimer::EntityTimer(const std::string& name, const float& time) {
|
||||||
m_Name = name;
|
m_Name = name;
|
||||||
m_Time = time;
|
m_Time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityTimer::~EntityTimer() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EntityTimer::GetName() {
|
std::string EntityTimer::GetName() {
|
||||||
return m_Name;
|
return m_Name;
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
|
|
||||||
class EntityTimer {
|
class EntityTimer {
|
||||||
public:
|
public:
|
||||||
EntityTimer(std::string name, float time);
|
EntityTimer(const std::string& name, const float& time);
|
||||||
~EntityTimer();
|
|
||||||
|
|
||||||
std::string GetName();
|
std::string GetName();
|
||||||
float GetTime();
|
float GetTime();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user