Add more null checks and split out code

Makes crash logs more apparent for what stage they crashed in for the engine updating.
This commit is contained in:
David Markowitz 2023-05-05 23:31:30 -07:00
parent e297aacc68
commit df3265c82e
3 changed files with 67 additions and 51 deletions

View File

@ -161,9 +161,7 @@ void EntityManager::DestroyEntity(const LWOOBJID& objectID) {
} }
void EntityManager::DestroyEntity(Entity* entity) { void EntityManager::DestroyEntity(Entity* entity) {
if (entity == nullptr) { if (!entity) return;
return;
}
entity->TriggerEvent(eTriggerEventType::DESTROY, entity); entity->TriggerEvent(eTriggerEventType::DESTROY, entity);
@ -182,15 +180,11 @@ void EntityManager::DestroyEntity(Entity* entity) {
ScheduleForDeletion(id); ScheduleForDeletion(id);
} }
void EntityManager::UpdateEntities(const float deltaTime) { void EntityManager::SerializeEntities() {
for (const auto& e : m_Entities) {
e.second->Update(deltaTime);
}
for (auto entry = m_EntitiesToSerialize.begin(); entry != m_EntitiesToSerialize.end(); entry++) { for (auto entry = m_EntitiesToSerialize.begin(); entry != m_EntitiesToSerialize.end(); entry++) {
auto* entity = GetEntity(*entry); auto* entity = GetEntity(*entry);
if (entity == nullptr) continue; if (!entity) continue;
m_SerializationCounter++; m_SerializationCounter++;
@ -212,11 +206,16 @@ void EntityManager::UpdateEntities(const float deltaTime) {
} }
} }
m_EntitiesToSerialize.clear(); m_EntitiesToSerialize.clear();
}
void EntityManager::KillEntities() {
for (auto entry = m_EntitiesToKill.begin(); entry != m_EntitiesToKill.end(); entry++) { for (auto entry = m_EntitiesToKill.begin(); entry != m_EntitiesToKill.end(); entry++) {
auto* entity = GetEntity(*entry); auto* entity = GetEntity(*entry);
if (!entity) continue; if (!entity) {
Game::logger->Log("EntityManager", "Attempting to kill null entity %llu", *entry);
continue;
}
if (entity->GetScheduledKiller()) { if (entity->GetScheduledKiller()) {
entity->Smash(entity->GetScheduledKiller()->GetObjectID(), eKillType::SILENT); entity->Smash(entity->GetScheduledKiller()->GetObjectID(), eKillType::SILENT);
@ -225,32 +224,41 @@ void EntityManager::UpdateEntities(const float deltaTime) {
} }
} }
m_EntitiesToKill.clear(); m_EntitiesToKill.clear();
}
void EntityManager::DeleteEntities() {
for (auto entry = m_EntitiesToDelete.begin(); entry != m_EntitiesToDelete.end(); entry++) { for (auto entry = m_EntitiesToDelete.begin(); entry != m_EntitiesToDelete.end(); entry++) {
// Get all this info first before we delete the player.
auto entityToDelete = GetEntity(*entry); auto entityToDelete = GetEntity(*entry);
auto networkIdToErase = entityToDelete->GetNetworkId();
const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete);
if (entityToDelete) { if (entityToDelete) {
// If we are a player run through the player destructor. // Get all this info first before we delete the player.
if (entityToDelete->IsPlayer()) { auto networkIdToErase = entityToDelete->GetNetworkId();
delete dynamic_cast<Player*>(entityToDelete); const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete);
} else {
delete entityToDelete; delete entityToDelete;
}
entityToDelete = nullptr; entityToDelete = nullptr;
if (networkIdToErase != 0) m_LostNetworkIds.push(networkIdToErase); if (networkIdToErase != 0) m_LostNetworkIds.push(networkIdToErase);
if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete);
} else {
Game::logger->Log("EntityManager", "Attempted to delete non-existent entity %llu", *entry);
} }
if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete);
m_Entities.erase(*entry); m_Entities.erase(*entry);
} }
m_EntitiesToDelete.clear(); m_EntitiesToDelete.clear();
} }
void EntityManager::UpdateEntities(const float deltaTime) {
for (const auto& e : m_Entities) {
e.second->Update(deltaTime);
}
SerializeEntities();
KillEntities();
DeleteEntities();
}
Entity* EntityManager::GetEntity(const LWOOBJID& objectId) const { Entity* EntityManager::GetEntity(const LWOOBJID& objectId) const {
const auto& index = m_Entities.find(objectId); const auto& index = m_Entities.find(objectId);
@ -316,6 +324,11 @@ const std::unordered_map<std::string, LWOOBJID>& EntityManager::GetSpawnPointEnt
} }
void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr, const bool skipChecks) { void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr, const bool skipChecks) {
if (!entity) {
Game::logger->Log("EntityManager", "Attempted to construct null entity");
return;
}
if (entity->GetNetworkId() == 0) { if (entity->GetNetworkId() == 0) {
uint16_t networkId; uint16_t networkId;
@ -395,9 +408,7 @@ void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) {
} }
void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) { void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) {
if (entity->GetNetworkId() == 0) { if (!entity || entity->GetNetworkId() == 0) return;
return;
}
RakNet::BitStream stream; RakNet::BitStream stream;
@ -414,9 +425,7 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr)
} }
void EntityManager::SerializeEntity(Entity* entity) { void EntityManager::SerializeEntity(Entity* entity) {
if (entity->GetNetworkId() == 0) { if (!entity || entity->GetNetworkId() == 0) return;
return;
}
if (std::find(m_EntitiesToSerialize.begin(), m_EntitiesToSerialize.end(), entity->GetObjectID()) == m_EntitiesToSerialize.end()) { if (std::find(m_EntitiesToSerialize.begin(), m_EntitiesToSerialize.end(), entity->GetObjectID()) == m_EntitiesToSerialize.end()) {
m_EntitiesToSerialize.push_back(entity->GetObjectID()); m_EntitiesToSerialize.push_back(entity->GetObjectID());

View File

@ -85,6 +85,10 @@ public:
const uint32_t GetHardcoreUscoreEnemiesMultiplier() { return m_HardcoreUscoreEnemiesMultiplier; }; const uint32_t GetHardcoreUscoreEnemiesMultiplier() { return m_HardcoreUscoreEnemiesMultiplier; };
private: private:
void SerializeEntities();
void KillEntities();
void DeleteEntities();
static EntityManager* m_Address; //For singleton method static EntityManager* m_Address; //For singleton method
static std::vector<LWOMAPID> m_GhostingExcludedZones; static std::vector<LWOMAPID> m_GhostingExcludedZones;
static std::vector<LOT> m_GhostingExcludedLOTs; static std::vector<LOT> m_GhostingExcludedLOTs;

View File

@ -275,6 +275,11 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) {
toSpawn.spawnPaths.at(pathIndex) toSpawn.spawnPaths.at(pathIndex)
); );
if (!path) {
Game::logger->Log("SGCannon", "Path %s at index %i is null", toSpawn.spawnPaths.at(pathIndex).c_str(), pathIndex);
return;
}
auto info = EntityInfo{}; auto info = EntityInfo{};
info.lot = toSpawn.lot; info.lot = toSpawn.lot;
info.spawnerID = self->GetObjectID(); info.spawnerID = self->GetObjectID();
@ -294,32 +299,30 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) {
auto* enemy = EntityManager::Instance()->CreateEntity(info, nullptr, self); auto* enemy = EntityManager::Instance()->CreateEntity(info, nullptr, self);
EntityManager::Instance()->ConstructEntity(enemy); EntityManager::Instance()->ConstructEntity(enemy);
if (true) { auto* movementAI = new MovementAIComponent(enemy, {});
auto* movementAI = new MovementAIComponent(enemy, {});
enemy->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAI); enemy->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAI);
movementAI->SetSpeed(toSpawn.initialSpeed); movementAI->SetSpeed(toSpawn.initialSpeed);
movementAI->SetCurrentSpeed(toSpawn.initialSpeed); movementAI->SetCurrentSpeed(toSpawn.initialSpeed);
movementAI->SetHaltDistance(0.0f); movementAI->SetHaltDistance(0.0f);
std::vector<NiPoint3> pathWaypoints; std::vector<NiPoint3> pathWaypoints;
for (const auto& waypoint : path->pathWaypoints) { for (const auto& waypoint : path->pathWaypoints) {
pathWaypoints.push_back(waypoint.position); pathWaypoints.push_back(waypoint.position);
}
if (GeneralUtils::GenerateRandomNumber<float_t>(0, 1) < 0.5f) {
std::reverse(pathWaypoints.begin(), pathWaypoints.end());
}
movementAI->SetPath(pathWaypoints);
enemy->AddDieCallback([this, self, enemy, name]() {
RegisterHit(self, enemy, name);
});
} }
if (GeneralUtils::GenerateRandomNumber<float_t>(0, 1) < 0.5f) {
std::reverse(pathWaypoints.begin(), pathWaypoints.end());
}
movementAI->SetPath(pathWaypoints);
enemy->AddDieCallback([this, self, enemy, name]() {
RegisterHit(self, enemy, name);
});
// Save the enemy and tell it to start pathing // Save the enemy and tell it to start pathing
if (enemy != nullptr) { if (enemy != nullptr) {
const_cast<std::vector<LWOOBJID>&>(self->GetVar<std::vector<LWOOBJID>>(SpawnedObjects)).push_back(enemy->GetObjectID()); const_cast<std::vector<LWOOBJID>&>(self->GetVar<std::vector<LWOOBJID>>(SpawnedObjects)).push_back(enemy->GetObjectID());
@ -577,7 +580,7 @@ void SGCannon::StopGame(Entity* self, bool cancel) {
self->SetNetworkVar<std::u16string>(u"UI_Rewards", self->SetNetworkVar<std::u16string>(u"UI_Rewards",
GeneralUtils::to_u16string(self->GetVar<uint32_t>(TotalScoreVariable)) + u"_0_0_0_0_0_0" GeneralUtils::to_u16string(self->GetVar<uint32_t>(TotalScoreVariable)) + u"_0_0_0_0_0_0"
); );
GameMessages::SendRequestActivitySummaryLeaderboardData( GameMessages::SendRequestActivitySummaryLeaderboardData(
player->GetObjectID(), player->GetObjectID(),