diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 497205667..eeeff3e8b 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -322,9 +322,6 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData) KeyPair.second->SetWorld(m_World); } - // Create block entities that the loader didn't load; fill them with defaults - CreateBlockEntities(); - // Set the chunk data as valid. This may be needed for some simulators that perform actions upon block adding (Vaporize) SetPresence(cpPresent); @@ -455,7 +452,7 @@ void cChunk::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlock } auto clone = be->Clone({posX, posY, posZ}); clone->SetWorld(m_World); - AddBlockEntityClean(std::move(clone)); + AddBlockEntity(std::move(clone)); m_World->BroadcastBlockEntity({posX, posY, posZ}); } } @@ -1152,40 +1149,6 @@ int cChunk::GetHeight(int a_X, int a_Z) -void cChunk::CreateBlockEntities(void) -{ - for (size_t SectionIdx = 0; SectionIdx != cChunkData::NumSections; ++SectionIdx) - { - const auto * Section = m_ChunkData.GetSection(SectionIdx); - if (Section == nullptr) - { - continue; - } - - for (size_t BlockIdx = 0; BlockIdx != cChunkData::SectionBlockCount; ++BlockIdx) - { - auto BlockType = Section->m_BlockTypes[BlockIdx]; - if (cBlockEntity::IsBlockEntityBlockType(BlockType)) - { - auto RelPos = IndexToCoordinate(BlockIdx); - RelPos.y += static_cast(SectionIdx * cChunkData::SectionHeight); - const auto AbsPos = RelativeToAbsolute(RelPos); - - if (!HasBlockEntityAt(AbsPos)) - { - AddBlockEntityClean(cBlockEntity::CreateByBlockType( - BlockType, GetMeta(RelPos), AbsPos, m_World - )); - } - } - } - } -} - - - - - void cChunk::WakeUpSimulators(void) { auto * WaterSimulator = m_World->GetWaterSimulator(); @@ -1261,7 +1224,7 @@ void cChunk::SetBlock(Vector3i a_RelPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_Blo // If the new block is a block entity, create the entity object: if (cBlockEntity::IsBlockEntityBlockType(a_BlockType)) { - AddBlockEntityClean(cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, RelativeToAbsolute(a_RelPos), m_World)); + AddBlockEntity(cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, RelativeToAbsolute(a_RelPos), m_World)); } } @@ -1374,19 +1337,10 @@ void cChunk::SendBlockTo(int a_RelX, int a_RelY, int a_RelZ, cClientHandle * a_C void cChunk::AddBlockEntity(OwnedBlockEntity a_BlockEntity) { - MarkDirty(); - AddBlockEntityClean(std::move(a_BlockEntity)); -} - - - - - -void cChunk::AddBlockEntityClean(OwnedBlockEntity a_BlockEntity) -{ - int Idx = MakeIndex(a_BlockEntity->GetRelX(), a_BlockEntity->GetPosY(), a_BlockEntity->GetRelZ()); - auto Result = m_BlockEntities.emplace(Idx, std::move(a_BlockEntity)); - UNUSED(Result); + [[maybe_unused]] const auto Result = m_BlockEntities.emplace( + MakeIndex(a_BlockEntity->GetRelX(), a_BlockEntity->GetPosY(), a_BlockEntity->GetRelZ()), + std::move(a_BlockEntity) + ); ASSERT(Result.second); // No block entity already at this position } diff --git a/src/Chunk.h b/src/Chunk.h index fa4e9ad19..8aa73cde5 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -581,7 +581,7 @@ private: // A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers std::vector m_LoadedByClient; std::vector m_Entities; - cBlockEntities m_BlockEntities; + cBlockEntities m_BlockEntities; /** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */ unsigned m_StayCount; @@ -623,12 +623,6 @@ private: void RemoveBlockEntity(cBlockEntity * a_BlockEntity); void AddBlockEntity (OwnedBlockEntity a_BlockEntity); - /** Add a block entity to the chunk without marking the chunk dirty */ - void AddBlockEntityClean(OwnedBlockEntity a_BlockEntity); - - /** Creates a block entity for each block that needs a block entity and doesn't have one already */ - void CreateBlockEntities(void); - /** Wakes up each simulator for its specific blocks; through all the blocks in the chunk */ void WakeUpSimulators(void); @@ -659,11 +653,3 @@ private: /** Check m_Entities for cPlayer objects. */ bool HasPlayerEntities() const; }; - -typedef cChunk * cChunkPtr; - -typedef std::list cChunkPtrList; - - - - diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 19936add2..51ca81663 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -18,6 +18,7 @@ #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/DispenserEntity.h" #include "../BlockEntities/DropperEntity.h" +#include "../BlockEntities/EnderChestEntity.h" #include "../BlockEntities/FurnaceEntity.h" #include "../BlockEntities/HopperEntity.h" #include "../BlockEntities/JukeboxEntity.h" @@ -214,7 +215,7 @@ public: case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity(static_cast(a_Entity)); break; case E_BLOCK_DISPENSER: AddDispenserEntity (static_cast (a_Entity)); break; case E_BLOCK_DROPPER: AddDropperEntity (static_cast (a_Entity)); break; - case E_BLOCK_ENDER_CHEST: /* No data to be saved */ break; + case E_BLOCK_ENDER_CHEST: AddEnderchestEntity (static_cast (a_Entity)); break; case E_BLOCK_FLOWER_POT: AddFlowerPotEntity (static_cast (a_Entity)); break; case E_BLOCK_FURNACE: AddFurnaceEntity (static_cast (a_Entity)); break; case E_BLOCK_HEAD: AddMobHeadEntity (static_cast (a_Entity)); break; @@ -460,6 +461,17 @@ public: + void AddEnderchestEntity(cEnderChestEntity * a_Entity) + { + mWriter.BeginCompound(""); + AddBasicTileEntity(a_Entity, "EnderChest"); + mWriter.EndCompound(); + } + + + + + void AddFurnaceEntity(cFurnaceEntity * a_Furnace) { mWriter.BeginCompound(""); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 5e4d48eeb..ebeb198b1 100755 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -25,6 +25,7 @@ #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/DispenserEntity.h" #include "../BlockEntities/DropperEntity.h" +#include "../BlockEntities/EnderChestEntity.h" #include "../BlockEntities/FurnaceEntity.h" #include "../BlockEntities/HopperEntity.h" #include "../BlockEntities/JukeboxEntity.h" @@ -645,6 +646,7 @@ OwnedBlockEntity cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int case E_BLOCK_COMMAND_BLOCK: return LoadCommandBlockFromNBT(a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos); case E_BLOCK_DISPENSER: return LoadDispenserFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos); case E_BLOCK_DROPPER: return LoadDropperFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos); + case E_BLOCK_ENDER_CHEST: return LoadEnderChestFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos); case E_BLOCK_FLOWER_POT: return LoadFlowerPotFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos); case E_BLOCK_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos); case E_BLOCK_HEAD: return LoadMobHeadFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos); @@ -657,9 +659,6 @@ OwnedBlockEntity cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int case E_BLOCK_TRAPPED_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos); case E_BLOCK_WALLSIGN: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos); - // Blocktypes that have block entities but don't load their contents from disk: - case E_BLOCK_ENDER_CHEST: return nullptr; - default: { // All the other blocktypes should have no entities assigned to them. Report an error: @@ -1125,6 +1124,21 @@ OwnedBlockEntity cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_T +OwnedBlockEntity cWSSAnvil::LoadEnderChestFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos) +{ + // Check if the data has a proper type: + static const AStringVector expectedTypes({ "EnderChest", "minecraft:ender_chest" }); + if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_Pos)) + { + return nullptr; + } + return std::make_unique(a_BlockType, a_BlockMeta, a_Pos, m_World); +} + + + + + OwnedBlockEntity cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos) { // Check if the data has a proper type: diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 8c3fda2d7..7684fd81b 100755 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -163,6 +163,7 @@ protected: OwnedBlockEntity LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos); OwnedBlockEntity LoadDispenserFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos); OwnedBlockEntity LoadDropperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos); + OwnedBlockEntity LoadEnderChestFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos); OwnedBlockEntity LoadFlowerPotFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos); OwnedBlockEntity LoadFurnaceFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos); OwnedBlockEntity LoadHopperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos);