diff --git a/src/Chunk.cpp b/src/Chunk.cpp index eb44828e2..fc128b31c 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -262,6 +262,9 @@ void cChunk::MarkLoadFailed(void) { ASSERT(m_Presence == cpQueued); + // Mark dirty before generating, so that we get saved and don't have to later generate again: + MarkDirty(); + // The chunk is always needed, generate it: m_World->GetGenerator().QueueGenerateChunk({m_PosX, m_PosZ}, false); } @@ -307,6 +310,25 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData) m_ChunkData.Assign(std::move(a_SetChunkData.GetChunkData())); m_IsLightValid = a_SetChunkData.IsLightValid(); + // Entities need some extra steps to destroy, so here we're keeping the old ones. + // Move the entities already in the chunk, including player entities, so that we don't lose any: + a_SetChunkData.GetEntities().insert( + a_SetChunkData.GetEntities().end(), + std::make_move_iterator(m_Entities.begin()), + std::make_move_iterator(m_Entities.end()) + ); + + // Store the augmented result: + m_Entities = std::move(a_SetChunkData.GetEntities()); + + // Set all the entity variables again: + for (const auto & Entity : m_Entities) + { + Entity->SetWorld(m_World); + Entity->SetParentChunk(this); + Entity->SetIsTicking(true); + } + // Clear the block entities present - either the loader / saver has better, or we'll create empty ones: m_BlockEntities = std::move(a_SetChunkData.GetBlockEntities()); diff --git a/src/World.cpp b/src/World.cpp index 02de985c6..aea963257 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2310,13 +2310,6 @@ void cWorld::SetChunkData(cSetChunkData & a_SetChunkData) m_ChunkMap.SetChunkData(a_SetChunkData); - // Initialize the entities (outside the m_ChunkMap's CS, to fix FS #347): - for (auto & Entity : a_SetChunkData.GetEntities()) - { - auto EntityPtr = Entity.get(); - EntityPtr->Initialize(std::move(Entity), *this); - } - // If a client is requesting this chunk, send it to them: int ChunkX = a_SetChunkData.GetChunkX(); int ChunkZ = a_SetChunkData.GetChunkZ(); @@ -2337,14 +2330,6 @@ void cWorld::SetChunkData(cSetChunkData & a_SetChunkData) return true; } ); - - // Save the chunk right after generating, so that we don't have to generate it again on next run - // If saving is disabled, then the chunk was marked dirty so it will get - // saved if saving is later enabled. - if (a_SetChunkData.ShouldMarkDirty() && IsSavingEnabled()) - { - m_Storage.QueueSaveChunk(ChunkX, ChunkZ); - } }