Save enderchest block entities to storage
+ Add EnderChest saving, as Vanilla does - Remove CreateBlockEntities. Storage should save & load everything so looping over chunk data is not needed
This commit is contained in:
parent
da9158937d
commit
be121f9e80
@ -322,9 +322,6 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData)
|
|||||||
KeyPair.second->SetWorld(m_World);
|
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)
|
// Set the chunk data as valid. This may be needed for some simulators that perform actions upon block adding (Vaporize)
|
||||||
SetPresence(cpPresent);
|
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});
|
auto clone = be->Clone({posX, posY, posZ});
|
||||||
clone->SetWorld(m_World);
|
clone->SetWorld(m_World);
|
||||||
AddBlockEntityClean(std::move(clone));
|
AddBlockEntity(std::move(clone));
|
||||||
m_World->BroadcastBlockEntity({posX, posY, posZ});
|
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<int>(SectionIdx * cChunkData::SectionHeight);
|
|
||||||
const auto AbsPos = RelativeToAbsolute(RelPos);
|
|
||||||
|
|
||||||
if (!HasBlockEntityAt(AbsPos))
|
|
||||||
{
|
|
||||||
AddBlockEntityClean(cBlockEntity::CreateByBlockType(
|
|
||||||
BlockType, GetMeta(RelPos), AbsPos, m_World
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::WakeUpSimulators(void)
|
void cChunk::WakeUpSimulators(void)
|
||||||
{
|
{
|
||||||
auto * WaterSimulator = m_World->GetWaterSimulator();
|
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 the new block is a block entity, create the entity object:
|
||||||
if (cBlockEntity::IsBlockEntityBlockType(a_BlockType))
|
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)
|
void cChunk::AddBlockEntity(OwnedBlockEntity a_BlockEntity)
|
||||||
{
|
{
|
||||||
MarkDirty();
|
[[maybe_unused]] const auto Result = m_BlockEntities.emplace(
|
||||||
AddBlockEntityClean(std::move(a_BlockEntity));
|
MakeIndex(a_BlockEntity->GetRelX(), a_BlockEntity->GetPosY(), a_BlockEntity->GetRelZ()),
|
||||||
}
|
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);
|
|
||||||
ASSERT(Result.second); // No block entity already at this position
|
ASSERT(Result.second); // No block entity already at this position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
src/Chunk.h
16
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
|
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
|
||||||
std::vector<cClientHandle *> m_LoadedByClient;
|
std::vector<cClientHandle *> m_LoadedByClient;
|
||||||
std::vector<OwnedEntity> m_Entities;
|
std::vector<OwnedEntity> 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 */
|
/** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */
|
||||||
unsigned m_StayCount;
|
unsigned m_StayCount;
|
||||||
@ -623,12 +623,6 @@ private:
|
|||||||
void RemoveBlockEntity(cBlockEntity * a_BlockEntity);
|
void RemoveBlockEntity(cBlockEntity * a_BlockEntity);
|
||||||
void AddBlockEntity (OwnedBlockEntity 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 */
|
/** Wakes up each simulator for its specific blocks; through all the blocks in the chunk */
|
||||||
void WakeUpSimulators(void);
|
void WakeUpSimulators(void);
|
||||||
|
|
||||||
@ -659,11 +653,3 @@ private:
|
|||||||
/** Check m_Entities for cPlayer objects. */
|
/** Check m_Entities for cPlayer objects. */
|
||||||
bool HasPlayerEntities() const;
|
bool HasPlayerEntities() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef cChunk * cChunkPtr;
|
|
||||||
|
|
||||||
typedef std::list<cChunkPtr> cChunkPtrList;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "../BlockEntities/CommandBlockEntity.h"
|
#include "../BlockEntities/CommandBlockEntity.h"
|
||||||
#include "../BlockEntities/DispenserEntity.h"
|
#include "../BlockEntities/DispenserEntity.h"
|
||||||
#include "../BlockEntities/DropperEntity.h"
|
#include "../BlockEntities/DropperEntity.h"
|
||||||
|
#include "../BlockEntities/EnderChestEntity.h"
|
||||||
#include "../BlockEntities/FurnaceEntity.h"
|
#include "../BlockEntities/FurnaceEntity.h"
|
||||||
#include "../BlockEntities/HopperEntity.h"
|
#include "../BlockEntities/HopperEntity.h"
|
||||||
#include "../BlockEntities/JukeboxEntity.h"
|
#include "../BlockEntities/JukeboxEntity.h"
|
||||||
@ -214,7 +215,7 @@ public:
|
|||||||
case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity(static_cast<cCommandBlockEntity *>(a_Entity)); break;
|
case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity(static_cast<cCommandBlockEntity *>(a_Entity)); break;
|
||||||
case E_BLOCK_DISPENSER: AddDispenserEntity (static_cast<cDispenserEntity *> (a_Entity)); break;
|
case E_BLOCK_DISPENSER: AddDispenserEntity (static_cast<cDispenserEntity *> (a_Entity)); break;
|
||||||
case E_BLOCK_DROPPER: AddDropperEntity (static_cast<cDropperEntity *> (a_Entity)); break;
|
case E_BLOCK_DROPPER: AddDropperEntity (static_cast<cDropperEntity *> (a_Entity)); break;
|
||||||
case E_BLOCK_ENDER_CHEST: /* No data to be saved */ break;
|
case E_BLOCK_ENDER_CHEST: AddEnderchestEntity (static_cast<cEnderChestEntity *> (a_Entity)); break;
|
||||||
case E_BLOCK_FLOWER_POT: AddFlowerPotEntity (static_cast<cFlowerPotEntity *> (a_Entity)); break;
|
case E_BLOCK_FLOWER_POT: AddFlowerPotEntity (static_cast<cFlowerPotEntity *> (a_Entity)); break;
|
||||||
case E_BLOCK_FURNACE: AddFurnaceEntity (static_cast<cFurnaceEntity *> (a_Entity)); break;
|
case E_BLOCK_FURNACE: AddFurnaceEntity (static_cast<cFurnaceEntity *> (a_Entity)); break;
|
||||||
case E_BLOCK_HEAD: AddMobHeadEntity (static_cast<cMobHeadEntity *> (a_Entity)); break;
|
case E_BLOCK_HEAD: AddMobHeadEntity (static_cast<cMobHeadEntity *> (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)
|
void AddFurnaceEntity(cFurnaceEntity * a_Furnace)
|
||||||
{
|
{
|
||||||
mWriter.BeginCompound("");
|
mWriter.BeginCompound("");
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "../BlockEntities/CommandBlockEntity.h"
|
#include "../BlockEntities/CommandBlockEntity.h"
|
||||||
#include "../BlockEntities/DispenserEntity.h"
|
#include "../BlockEntities/DispenserEntity.h"
|
||||||
#include "../BlockEntities/DropperEntity.h"
|
#include "../BlockEntities/DropperEntity.h"
|
||||||
|
#include "../BlockEntities/EnderChestEntity.h"
|
||||||
#include "../BlockEntities/FurnaceEntity.h"
|
#include "../BlockEntities/FurnaceEntity.h"
|
||||||
#include "../BlockEntities/HopperEntity.h"
|
#include "../BlockEntities/HopperEntity.h"
|
||||||
#include "../BlockEntities/JukeboxEntity.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_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_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_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_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_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);
|
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_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);
|
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:
|
default:
|
||||||
{
|
{
|
||||||
// All the other blocktypes should have no entities assigned to them. Report an error:
|
// 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<cEnderChestEntity>(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)
|
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:
|
// Check if the data has a proper type:
|
||||||
|
@ -163,6 +163,7 @@ protected:
|
|||||||
OwnedBlockEntity LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos);
|
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 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 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 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 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);
|
OwnedBlockEntity LoadHopperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos);
|
||||||
|
Loading…
Reference in New Issue
Block a user