diff --git a/source/game/StarEntityMap.cpp b/source/game/StarEntityMap.cpp index 2232099..6a22a67 100644 --- a/source/game/StarEntityMap.cpp +++ b/source/game/StarEntityMap.cpp @@ -31,13 +31,15 @@ Maybe EntityMap::maybeReserveEntityId(EntityId entityId) { if (m_spatialMap.size() >= (size_t)(m_endIdSpace - m_beginIdSpace)) throw EntityMapException("No more entity id space in EntityMap::reserveEntityId"); - if (m_spatialMap.contains(entityId)) + if (entityId == NullEntityId || m_spatialMap.contains(entityId)) return {}; else return entityId; } EntityId EntityMap::reserveEntityId(EntityId entityId) { + if (entityId == NullEntityId) + return reserveEntityId(); if (auto reserved = maybeReserveEntityId(entityId)) return *reserved; diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp index 4f1dc27..f12ae28 100644 --- a/source/game/StarUniverseClient.cpp +++ b/source/game/StarUniverseClient.cpp @@ -479,16 +479,19 @@ void UniverseClient::stopLua() { bool UniverseClient::reloadPlayer(Json const& data, Uuid const& uuid) { auto player = mainPlayer(); - auto world = worldClient(); - bool inWorld = player->inWorld(); - EntityId entityId = player->entityId(); + bool playerInWorld = player->inWorld(); + auto world = as(player->world()); + + EntityId entityId = (playerInWorld || !world->inWorld()) + ? player->entityId() + : connectionEntitySpace(world->connection()).first; if (m_playerReloadPreCallback) m_playerReloadPreCallback(); - if (inWorld) - world->removeEntity(entityId, false); - else { + if (playerInWorld) { + world->removeEntity(player->entityId(), false); + } else { m_respawning = false; m_respawnTimer.reset(); } @@ -505,7 +508,7 @@ bool UniverseClient::reloadPlayer(Json const& data, Uuid const& uuid) { exception = std::current_exception(); } - world->addEntity(player); + world->addEntity(player, entityId); CelestialCoordinate coordinate = m_systemWorldClient->location(); player->universeMap()->addMappedCoordinate(coordinate); diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index 3f80682..ee16a91 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -1203,7 +1203,7 @@ EntityPtr WorldClient::entity(EntityId entityId) const { return m_entityMap->entity(entityId); } -void WorldClient::addEntity(EntityPtr const& entity) { +void WorldClient::addEntity(EntityPtr const& entity, EntityId entityId) { if (!entity) return; @@ -1211,7 +1211,7 @@ void WorldClient::addEntity(EntityPtr const& entity) { return; if (entity->clientEntityMode() != ClientEntityMode::ClientSlaveOnly) { - entity->init(this, m_entityMap->reserveEntityId(), EntityMode::Master); + entity->init(this, m_entityMap->reserveEntityId(entityId), EntityMode::Master); m_entityMap->addEntity(entity); } else { auto entityFactory = Root::singleton().entityFactory(); diff --git a/source/game/StarWorldClient.hpp b/source/game/StarWorldClient.hpp index 6a241ae..3f9c0bb 100644 --- a/source/game/StarWorldClient.hpp +++ b/source/game/StarWorldClient.hpp @@ -54,7 +54,7 @@ public: TileModificationList validTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) const override; TileModificationList applyTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) override; EntityPtr entity(EntityId entityId) const override; - void addEntity(EntityPtr const& entity) override; + void addEntity(EntityPtr const& entity, EntityId entityId = NullEntityId) override; EntityPtr closestEntity(Vec2F const& center, float radius, EntityFilter selector = EntityFilter()) const override; void forAllEntities(EntityCallback entityCallback) const override; void forEachEntity(RectF const& boundBox, EntityCallback callback) const override; diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp index 87b9ba3..fe0c431 100644 --- a/source/game/StarWorldServer.cpp +++ b/source/game/StarWorldServer.cpp @@ -713,11 +713,11 @@ EntityPtr WorldServer::entity(EntityId entityId) const { return m_entityMap->entity(entityId); } -void WorldServer::addEntity(EntityPtr const& entity) { +void WorldServer::addEntity(EntityPtr const& entity, EntityId entityId) { if (!entity) return; - entity->init(this, m_entityMap->reserveEntityId(), EntityMode::Master); + entity->init(this, m_entityMap->reserveEntityId(entityId), EntityMode::Master); m_entityMap->addEntity(entity); if (auto tileEntity = as(entity)) diff --git a/source/game/StarWorldServer.hpp b/source/game/StarWorldServer.hpp index 163cc1b..896bb40 100644 --- a/source/game/StarWorldServer.hpp +++ b/source/game/StarWorldServer.hpp @@ -135,7 +135,7 @@ public: TileModificationList validTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) const override; TileModificationList applyTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) override; EntityPtr entity(EntityId entityId) const override; - void addEntity(EntityPtr const& entity) override; + void addEntity(EntityPtr const& entity, EntityId entityId = NullEntityId) override; EntityPtr closestEntity(Vec2F const& center, float radius, EntityFilter selector = EntityFilter()) const override; void forAllEntities(EntityCallback entityCallback) const override; void forEachEntity(RectF const& boundBox, EntityCallback callback) const override; diff --git a/source/game/interfaces/StarWorld.hpp b/source/game/interfaces/StarWorld.hpp index dc673e1..f2af197 100644 --- a/source/game/interfaces/StarWorld.hpp +++ b/source/game/interfaces/StarWorld.hpp @@ -55,7 +55,7 @@ public: // passed in pointer directly and initialize it, and entity will have a valid // id in this world and be ready for use. This is always the case on the // server, but not *always* the case on the client. - virtual void addEntity(EntityPtr const& entity) = 0; + virtual void addEntity(EntityPtr const& entity, EntityId entityId = NullEntityId) = 0; virtual EntityPtr closestEntity(Vec2F const& center, float radius, EntityFilter selector = {}) const = 0;