mirror of
https://github.com/DarkflameUniverse/DarkflameServer
synced 2024-08-30 18:43:58 +00:00
Refactor UpdateEntities to not lose items if we add them while processing (#664)
* if we are deleting entities, and we add an entity to delete, dont throw it out * made it all uniform * change update back to how it was since it's an unordere map and wouldn't be guaranteed to update even in this secnario
This commit is contained in:
parent
40a9aefb5b
commit
5523b6aafc
@ -74,7 +74,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE
|
|||||||
|
|
||||||
// For non player entites, we'll generate a new ID or set the appropiate flags
|
// For non player entites, we'll generate a new ID or set the appropiate flags
|
||||||
else if (user == nullptr || info.lot != 1) {
|
else if (user == nullptr || info.lot != 1) {
|
||||||
|
|
||||||
// Entities with no ID already set, often spawned entities, we'll generate a new sequencial ID
|
// Entities with no ID already set, often spawned entities, we'll generate a new sequencial ID
|
||||||
if (info.id == 0) {
|
if (info.id == 0) {
|
||||||
id = ObjectIDManager::Instance()->GenerateObjectID();
|
id = ObjectIDManager::Instance()->GenerateObjectID();
|
||||||
@ -104,7 +104,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE
|
|||||||
}
|
}
|
||||||
|
|
||||||
info.id = id;
|
info.id = id;
|
||||||
|
|
||||||
Entity* entity;
|
Entity* entity;
|
||||||
|
|
||||||
// Check if the entitty if a player, in case use the extended player entity class
|
// Check if the entitty if a player, in case use the extended player entity class
|
||||||
@ -117,7 +117,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE
|
|||||||
|
|
||||||
// Initialize the entity
|
// Initialize the entity
|
||||||
entity->Initialize();
|
entity->Initialize();
|
||||||
|
|
||||||
// Add the entity to the entity map
|
// Add the entity to the entity map
|
||||||
m_Entities.insert_or_assign(id, entity);
|
m_Entities.insert_or_assign(id, entity);
|
||||||
|
|
||||||
@ -162,110 +162,81 @@ void EntityManager::DestroyEntity(Entity* entity) {
|
|||||||
|
|
||||||
void EntityManager::UpdateEntities(const float deltaTime) {
|
void EntityManager::UpdateEntities(const float deltaTime) {
|
||||||
for (const auto& e : m_Entities) {
|
for (const auto& e : m_Entities) {
|
||||||
e.second->Update(deltaTime);
|
e.second->Update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto entityId : m_EntitiesToSerialize)
|
for (auto entry = m_EntitiesToSerialize.begin(); entry != m_EntitiesToSerialize.end(); entry++) {
|
||||||
{
|
auto* entity = GetEntity(*entry);
|
||||||
auto* entity = GetEntity(entityId);
|
|
||||||
|
|
||||||
if (entity == nullptr) continue;
|
if (entity == nullptr) continue;
|
||||||
|
|
||||||
m_SerializationCounter++;
|
m_SerializationCounter++;
|
||||||
|
|
||||||
RakNet::BitStream stream;
|
RakNet::BitStream stream;
|
||||||
|
|
||||||
stream.Write(static_cast<char>(ID_REPLICA_MANAGER_SERIALIZE));
|
stream.Write(static_cast<char>(ID_REPLICA_MANAGER_SERIALIZE));
|
||||||
stream.Write(static_cast<unsigned short>(entity->GetNetworkId()));
|
stream.Write(static_cast<unsigned short>(entity->GetNetworkId()));
|
||||||
|
|
||||||
entity->WriteBaseReplicaData(&stream, PACKET_TYPE_SERIALIZATION);
|
entity->WriteBaseReplicaData(&stream, PACKET_TYPE_SERIALIZATION);
|
||||||
entity->WriteComponents(&stream, PACKET_TYPE_SERIALIZATION);
|
entity->WriteComponents(&stream, PACKET_TYPE_SERIALIZATION);
|
||||||
|
|
||||||
if (entity->GetIsGhostingCandidate())
|
if (entity->GetIsGhostingCandidate()) {
|
||||||
{
|
for (auto* player : Player::GetAllPlayers()) {
|
||||||
for (auto* player : Player::GetAllPlayers())
|
if (player->IsObserved(*entry)) {
|
||||||
{
|
|
||||||
if (player->IsObserved(entityId))
|
|
||||||
{
|
|
||||||
Game::server->Send(&stream, player->GetSystemAddress(), false);
|
Game::server->Send(&stream, player->GetSystemAddress(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Game::server->Send(&stream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
Game::server->Send(&stream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_EntitiesToSerialize.clear();
|
m_EntitiesToSerialize.clear();
|
||||||
|
|
||||||
for (const auto& entry : m_EntitiesToKill)
|
for (auto entry = m_EntitiesToKill.begin(); entry != m_EntitiesToKill.end(); entry++) {
|
||||||
{
|
auto* entity = GetEntity(*entry);
|
||||||
auto* entity = GetEntity(entry);
|
|
||||||
|
|
||||||
if (!entity) continue;
|
if (!entity) continue;
|
||||||
|
|
||||||
if (entity->GetScheduledKiller())
|
if (entity->GetScheduledKiller()) {
|
||||||
{
|
|
||||||
entity->Smash(entity->GetScheduledKiller()->GetObjectID(), SILENT);
|
entity->Smash(entity->GetScheduledKiller()->GetObjectID(), SILENT);
|
||||||
}
|
} else {
|
||||||
else
|
entity->Smash(LWOOBJID_EMPTY, SILENT);
|
||||||
{
|
|
||||||
entity->Smash(LWOOBJID_EMPTY, SILENT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_EntitiesToKill.clear();
|
m_EntitiesToKill.clear();
|
||||||
|
|
||||||
for (const auto entry : m_EntitiesToDelete)
|
for (auto entry = m_EntitiesToDelete.begin(); entry != m_EntitiesToDelete.end(); entry++) {
|
||||||
{
|
|
||||||
// Get all this info first before we delete the player.
|
// Get all this info first before we delete the player.
|
||||||
auto entityToDelete = GetEntity(entry);
|
auto entityToDelete = GetEntity(*entry);
|
||||||
|
|
||||||
auto networkIdToErase = entityToDelete->GetNetworkId();
|
auto networkIdToErase = entityToDelete->GetNetworkId();
|
||||||
|
|
||||||
const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete);
|
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.
|
// If we are a player run through the player destructor.
|
||||||
if (entityToDelete->IsPlayer())
|
if (entityToDelete->IsPlayer()) {
|
||||||
{
|
|
||||||
delete dynamic_cast<Player*>(entityToDelete);
|
delete dynamic_cast<Player*>(entityToDelete);
|
||||||
}
|
} else {
|
||||||
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())
|
if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete);
|
||||||
{
|
|
||||||
m_EntitiesToGhost.erase(ghostingToDelete);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Entities.erase(entry);
|
m_Entities.erase(*entry);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_EntitiesToDelete.clear();
|
m_EntitiesToDelete.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
if (index == m_Entities.end())
|
if (index == m_Entities.end())
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return index->second;
|
return index->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,7 +257,7 @@ std::vector<Entity*> EntityManager::GetEntitiesByComponent(const int componentTy
|
|||||||
std::vector<Entity*> withComp;
|
std::vector<Entity*> withComp;
|
||||||
for (const auto& entity : m_Entities) {
|
for (const auto& entity : m_Entities) {
|
||||||
if (componentType != -1 && !entity.second->HasComponent(componentType)) continue;
|
if (componentType != -1 && !entity.second->HasComponent(componentType)) continue;
|
||||||
|
|
||||||
withComp.push_back(entity.second);
|
withComp.push_back(entity.second);
|
||||||
}
|
}
|
||||||
return withComp;
|
return withComp;
|
||||||
@ -331,7 +302,7 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
|
|||||||
if (entity->GetNetworkId() == 0)
|
if (entity->GetNetworkId() == 0)
|
||||||
{
|
{
|
||||||
uint16_t networkId;
|
uint16_t networkId;
|
||||||
|
|
||||||
if (!m_LostNetworkIds.empty())
|
if (!m_LostNetworkIds.empty())
|
||||||
{
|
{
|
||||||
networkId = m_LostNetworkIds.top();
|
networkId = m_LostNetworkIds.top();
|
||||||
@ -344,7 +315,7 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
|
|||||||
|
|
||||||
entity->SetNetworkId(networkId);
|
entity->SetNetworkId(networkId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto checkGhosting = entity->GetIsGhostingCandidate();
|
const auto checkGhosting = entity->GetIsGhostingCandidate();
|
||||||
|
|
||||||
if (checkGhosting)
|
if (checkGhosting)
|
||||||
@ -365,13 +336,13 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_SerializationCounter++;
|
m_SerializationCounter++;
|
||||||
|
|
||||||
RakNet::BitStream stream;
|
RakNet::BitStream stream;
|
||||||
|
|
||||||
stream.Write(static_cast<char>(ID_REPLICA_MANAGER_CONSTRUCTION));
|
stream.Write(static_cast<char>(ID_REPLICA_MANAGER_CONSTRUCTION));
|
||||||
stream.Write(true);
|
stream.Write(true);
|
||||||
stream.Write(static_cast<unsigned short>(entity->GetNetworkId()));
|
stream.Write(static_cast<unsigned short>(entity->GetNetworkId()));
|
||||||
|
|
||||||
entity->WriteBaseReplicaData(&stream, PACKET_TYPE_CONSTRUCTION);
|
entity->WriteBaseReplicaData(&stream, PACKET_TYPE_CONSTRUCTION);
|
||||||
entity->WriteComponents(&stream, PACKET_TYPE_CONSTRUCTION);
|
entity->WriteComponents(&stream, PACKET_TYPE_CONSTRUCTION);
|
||||||
|
|
||||||
@ -430,7 +401,7 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RakNet::BitStream stream;
|
RakNet::BitStream stream;
|
||||||
|
|
||||||
stream.Write(static_cast<char>(ID_REPLICA_MANAGER_DESTRUCTION));
|
stream.Write(static_cast<char>(ID_REPLICA_MANAGER_DESTRUCTION));
|
||||||
@ -467,7 +438,7 @@ void EntityManager::DestructAllEntities(const SystemAddress& sysAddr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityManager::SetGhostDistanceMax(float value)
|
void EntityManager::SetGhostDistanceMax(float value)
|
||||||
{
|
{
|
||||||
m_GhostDistanceMaxSquared = value * value;
|
m_GhostDistanceMaxSquared = value * value;
|
||||||
}
|
}
|
||||||
@ -477,7 +448,7 @@ float EntityManager::GetGhostDistanceMax() const
|
|||||||
return std::sqrt(m_GhostDistanceMaxSquared);
|
return std::sqrt(m_GhostDistanceMaxSquared);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityManager::SetGhostDistanceMin(float value)
|
void EntityManager::SetGhostDistanceMin(float value)
|
||||||
{
|
{
|
||||||
m_GhostDistanceMinSqaured = value * value;
|
m_GhostDistanceMinSqaured = value * value;
|
||||||
}
|
}
|
||||||
@ -487,7 +458,7 @@ float EntityManager::GetGhostDistanceMin() const
|
|||||||
return std::sqrt(m_GhostDistanceMinSqaured);
|
return std::sqrt(m_GhostDistanceMinSqaured);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityManager::QueueGhostUpdate(LWOOBJID playerID)
|
void EntityManager::QueueGhostUpdate(LWOOBJID playerID)
|
||||||
{
|
{
|
||||||
const auto& iter = std::find(m_PlayersToUpdateGhosting.begin(), m_PlayersToUpdateGhosting.end(), playerID);
|
const auto& iter = std::find(m_PlayersToUpdateGhosting.begin(), m_PlayersToUpdateGhosting.end(), playerID);
|
||||||
|
|
||||||
@ -497,7 +468,7 @@ void EntityManager::QueueGhostUpdate(LWOOBJID playerID)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityManager::UpdateGhosting()
|
void EntityManager::UpdateGhosting()
|
||||||
{
|
{
|
||||||
for (const auto playerID : m_PlayersToUpdateGhosting)
|
for (const auto playerID : m_PlayersToUpdateGhosting)
|
||||||
{
|
{
|
||||||
@ -514,7 +485,7 @@ void EntityManager::UpdateGhosting()
|
|||||||
m_PlayersToUpdateGhosting.clear();
|
m_PlayersToUpdateGhosting.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityManager::UpdateGhosting(Player* player)
|
void EntityManager::UpdateGhosting(Player* player)
|
||||||
{
|
{
|
||||||
if (player == nullptr)
|
if (player == nullptr)
|
||||||
{
|
{
|
||||||
@ -575,15 +546,15 @@ void EntityManager::UpdateGhosting(Player* player)
|
|||||||
}
|
}
|
||||||
|
|
||||||
player->ObserveEntity(id);
|
player->ObserveEntity(id);
|
||||||
|
|
||||||
ConstructEntity(entity, player->GetSystemAddress());
|
ConstructEntity(entity, player->GetSystemAddress());
|
||||||
|
|
||||||
entity->SetObservers(entity->GetObservers() + 1);
|
entity->SetObservers(entity->GetObservers() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityManager::CheckGhosting(Entity* entity)
|
void EntityManager::CheckGhosting(Entity* entity)
|
||||||
{
|
{
|
||||||
if (entity == nullptr)
|
if (entity == nullptr)
|
||||||
{
|
{
|
||||||
@ -591,7 +562,7 @@ void EntityManager::CheckGhosting(Entity* entity)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto& referencePoint = entity->GetPosition();
|
const auto& referencePoint = entity->GetPosition();
|
||||||
|
|
||||||
auto ghostingDistanceMax = m_GhostDistanceMaxSquared;
|
auto ghostingDistanceMax = m_GhostDistanceMaxSquared;
|
||||||
auto ghostingDistanceMin = m_GhostDistanceMinSqaured;
|
auto ghostingDistanceMin = m_GhostDistanceMinSqaured;
|
||||||
|
|
||||||
@ -618,15 +589,15 @@ void EntityManager::CheckGhosting(Entity* entity)
|
|||||||
else if (!observed && ghostingDistanceMin > distance)
|
else if (!observed && ghostingDistanceMin > distance)
|
||||||
{
|
{
|
||||||
player->ObserveEntity(id);
|
player->ObserveEntity(id);
|
||||||
|
|
||||||
ConstructEntity(entity, player->GetSystemAddress());
|
ConstructEntity(entity, player->GetSystemAddress());
|
||||||
|
|
||||||
entity->SetObservers(entity->GetObservers() + 1);
|
entity->SetObservers(entity->GetObservers() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity* EntityManager::GetGhostCandidate(int32_t id)
|
Entity* EntityManager::GetGhostCandidate(int32_t id)
|
||||||
{
|
{
|
||||||
for (auto* entity : m_EntitiesToGhost)
|
for (auto* entity : m_EntitiesToGhost)
|
||||||
{
|
{
|
||||||
@ -635,7 +606,7 @@ Entity* EntityManager::GetGhostCandidate(int32_t id)
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -654,7 +625,7 @@ void EntityManager::ScheduleForKill(Entity* entity) {
|
|||||||
// Deactivate switches if they die
|
// Deactivate switches if they die
|
||||||
if (!entity)
|
if (!entity)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>();
|
SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>();
|
||||||
if (switchComp) {
|
if (switchComp) {
|
||||||
entity->TriggerEvent("OnDectivated");
|
entity->TriggerEvent("OnDectivated");
|
||||||
@ -670,7 +641,7 @@ void EntityManager::ScheduleForKill(Entity* entity) {
|
|||||||
m_EntitiesToKill.push_back(objectId);
|
m_EntitiesToKill.push_back(objectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityManager::ScheduleForDeletion(LWOOBJID entity)
|
void EntityManager::ScheduleForDeletion(LWOOBJID entity)
|
||||||
{
|
{
|
||||||
if (std::count(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), entity))
|
if (std::count(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), entity))
|
||||||
{
|
{
|
||||||
@ -689,7 +660,7 @@ void EntityManager::FireEventServerSide(Entity* origin, std::string args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityManager::IsExcludedFromGhosting(LOT lot)
|
bool EntityManager::IsExcludedFromGhosting(LOT lot)
|
||||||
{
|
{
|
||||||
return std::find(m_GhostingExcludedLOTs.begin(), m_GhostingExcludedLOTs.end(), lot) != m_GhostingExcludedLOTs.end();
|
return std::find(m_GhostingExcludedLOTs.begin(), m_GhostingExcludedLOTs.end(), lot) != m_GhostingExcludedLOTs.end();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user