I havent checked if this compiled

This commit is contained in:
EmosewaMC 2023-06-14 19:01:31 -07:00
parent fdd98ab825
commit 83065dfb6f
4 changed files with 116 additions and 157 deletions

View File

@ -541,6 +541,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 +573,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 +602,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 +611,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 +625,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 +666,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 +716,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 +750,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;
@ -808,7 +802,7 @@ void Entity::Update(const float deltaTime) {
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](EntityCallbackTimer* timer) {
timer->Update(deltaTime); timer->Update(deltaTime);
if (timer->GetTime() <= 0) { if (timer->GetTime() <= 0) {
timer->GetCallback()(); timer->ExecuteCallback();
delete timer; delete timer;
return true; return true;
} }
@ -818,9 +812,7 @@ void Entity::Update(const float deltaTime) {
// 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.size() > 0) {
for (auto namedTimer : m_PendingTimers) { m_Timers.insert(m_Timers.end(), m_PendingTimers.begin(), m_PendingTimers.end());
m_Timers.push_back(namedTimer);
}
m_PendingTimers.clear(); m_PendingTimers.clear();
} }
@ -828,33 +820,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 +850,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 +895,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 +933,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 +995,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 +1013,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 +1021,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 +1033,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 +1068,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) {
auto* characterComponent = GetComponent<CharacterComponent>(); if (lootObjId != objectID) continue;
if (characterComponent != nullptr) { auto* characterComponent = GetComponent<CharacterComponent>();
characterComponent->TrackLOTCollection(p.second.lot); if (characterComponent) characterComponent->TrackLOTCollection(loot.lot);
}
const CDObjects& object = objectsTable->GetByID(loot.lot);
const CDObjects& object = objectsTable->GetByID(p.second.lot); if (object.id != 0 && object.type == "Powerup") {
if (object.id != 0 && object.type == "Powerup") { const auto lootLot = loot.lot;
CDObjectSkillsTable* skillsTable = CDClientManager::Instance().GetTable<CDObjectSkillsTable>(); auto skills = skillsTable->Query([lootLot](CDObjectSkills entry) {return (entry.objectTemplate == lootLot); });
std::vector<CDObjectSkills> skills = skillsTable->Query([=](CDObjectSkills entry) {return (entry.objectTemplate == p.second.lot); }); for (const auto& skill : skills) {
for (CDObjectSkills skill : skills) { auto* skillBehaviorTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>();
CDSkillBehaviorTable* skillBehTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>(); auto behaviorData = skillBehaviorTable->GetSkillByID(skill.skillID);
CDSkillBehavior behaviorData = skillBehTable->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) missionComponent->Progress(eMissionTaskType::POWERUP, skill.skillID);
if (missionComponent != nullptr) {
missionComponent->Progress(eMissionTaskType::POWERUP, skill.skillID);
}
}
} else {
inv->AddItem(p.second.lot, p.second.count, eLootSourceType::PICKUP, eInventoryType::INVALID, {}, LWOOBJID_EMPTY, true, false, LWOOBJID_EMPTY, eInventoryType::INVALID, 1);
} }
} else {
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,81 +1136,71 @@ 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.push_back(new 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.push_back(new 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](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) { std::for_each(m_CallbackTimers.begin(), m_CallbackTimers.end(), [](EntityCallbackTimer* timer) {
delete callback; delete timer;
} });
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](EntityTimer* timer) {
if (m_Timers[i]->GetName() == name) { if (timer->GetName() == name) {
delete m_Timers[i]; delete timer;
m_Timers.erase(m_Timers.begin() + i); return true;
return;
} }
} return false;
});
m_Timers.erase(m_Timers.begin(), toErase);
} }
// ### LEFT OFF HERE ###
void Entity::CancelAllTimers() { void Entity::CancelAllTimers() {
for (auto* timer : m_Timers) { for (auto* timer : m_Timers) {
delete timer; delete timer;

View File

@ -145,8 +145,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);

View File

@ -9,6 +9,10 @@ EntityCallbackTimer::~EntityCallbackTimer() {
} }
void EntityCallbackTimer::ExecuteCallback() {
m_Callback();
}
std::function<void()> EntityCallbackTimer::GetCallback() { std::function<void()> EntityCallbackTimer::GetCallback() {
return m_Callback; return m_Callback;
} }

View File

@ -8,6 +8,7 @@ public:
EntityCallbackTimer(float time, std::function<void()> callback); EntityCallbackTimer(float time, std::function<void()> callback);
~EntityCallbackTimer(); ~EntityCallbackTimer();
void ExecuteCallback();
std::function<void()> GetCallback(); std::function<void()> GetCallback();
float GetTime(); float GetTime();