summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/BlockEntities/BeaconEntity.cpp38
-rw-r--r--src/BlockEntities/BeaconEntity.h5
-rw-r--r--src/BlockEntities/BlockEntity.cpp58
-rw-r--r--src/BlockEntities/BlockEntity.h22
-rw-r--r--src/BlockEntities/BlockEntityWithItems.cpp72
-rw-r--r--src/BlockEntities/BlockEntityWithItems.h41
-rw-r--r--src/BlockEntities/BrewingstandEntity.cpp88
-rw-r--r--src/BlockEntities/BrewingstandEntity.h18
-rw-r--r--src/BlockEntities/CMakeLists.txt1
-rw-r--r--src/BlockEntities/ChestEntity.cpp19
-rw-r--r--src/BlockEntities/ChestEntity.h5
-rw-r--r--src/BlockEntities/CommandBlockEntity.cpp22
-rw-r--r--src/BlockEntities/CommandBlockEntity.h6
-rw-r--r--src/BlockEntities/DispenserEntity.cpp9
-rw-r--r--src/BlockEntities/DispenserEntity.h6
-rw-r--r--src/BlockEntities/DropSpenserEntity.cpp16
-rw-r--r--src/BlockEntities/DropSpenserEntity.h5
-rw-r--r--src/BlockEntities/DropperEntity.cpp5
-rw-r--r--src/BlockEntities/DropperEntity.h4
-rw-r--r--src/BlockEntities/EnderChestEntity.cpp5
-rw-r--r--src/BlockEntities/EnderChestEntity.h4
-rw-r--r--src/BlockEntities/FlowerPotEntity.cpp53
-rw-r--r--src/BlockEntities/FlowerPotEntity.h9
-rw-r--r--src/BlockEntities/FurnaceEntity.cpp83
-rw-r--r--src/BlockEntities/FurnaceEntity.h15
-rw-r--r--src/BlockEntities/HopperEntity.cpp27
-rw-r--r--src/BlockEntities/HopperEntity.h5
-rw-r--r--src/BlockEntities/JukeboxEntity.cpp16
-rw-r--r--src/BlockEntities/JukeboxEntity.h7
-rw-r--r--src/BlockEntities/MobHeadEntity.cpp20
-rw-r--r--src/BlockEntities/MobHeadEntity.h6
-rw-r--r--src/BlockEntities/MobSpawnerEntity.cpp24
-rw-r--r--src/BlockEntities/MobSpawnerEntity.h6
-rw-r--r--src/BlockEntities/NoteEntity.cpp16
-rw-r--r--src/BlockEntities/NoteEntity.h6
-rw-r--r--src/BlockEntities/SignEntity.cpp21
-rw-r--r--src/BlockEntities/SignEntity.h6
-rw-r--r--src/ItemGrid.cpp16
-rw-r--r--src/ItemGrid.h5
-rwxr-xr-xsrc/WorldStorage/WSSAnvil.cpp123
-rwxr-xr-xsrc/WorldStorage/WSSAnvil.h36
41 files changed, 640 insertions, 309 deletions
diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp
index f7728600a..24de9e25c 100644
--- a/src/BlockEntities/BeaconEntity.cpp
+++ b/src/BlockEntities/BeaconEntity.cpp
@@ -11,13 +11,14 @@
-cBeaconEntity::cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
- super(E_BLOCK_BEACON, a_BlockX, a_BlockY, a_BlockZ, 1, 1, a_World),
+cBeaconEntity::cBeaconEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, 1, 1, a_World),
m_IsActive(false),
m_BeaconLevel(0),
m_PrimaryEffect(cEntityEffect::effNoEffect),
m_SecondaryEffect(cEntityEffect::effNoEffect)
{
+ ASSERT(a_BlockType == E_BLOCK_BEACON);
UpdateBeacon();
}
@@ -268,6 +269,30 @@ void cBeaconEntity::GiveEffects(void)
+void cBeaconEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cBeaconEntity &>(a_Src);
+ m_BeaconLevel = src.m_BeaconLevel;
+ m_Contents.CopyFrom(src.m_Contents);
+ m_IsActive = src.m_IsActive;
+ m_PrimaryEffect = src.m_PrimaryEffect;
+ m_SecondaryEffect = src.m_SecondaryEffect;
+}
+
+
+
+
+
+void cBeaconEntity::SendTo(cClientHandle & a_Client)
+{
+ a_Client.SendUpdateBlockEntity(*this);
+}
+
+
+
+
+
bool cBeaconEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
// Update the beacon every 4 seconds
@@ -306,12 +331,3 @@ bool cBeaconEntity::UsedBy(cPlayer * a_Player)
-
-void cBeaconEntity::SendTo(cClientHandle & a_Client)
-{
- a_Client.SendUpdateBlockEntity(*this);
-}
-
-
-
-
diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h
index 6ec00fd1a..23912c1a8 100644
--- a/src/BlockEntities/BeaconEntity.h
+++ b/src/BlockEntities/BeaconEntity.h
@@ -19,16 +19,17 @@
class cBeaconEntity :
public cBlockEntityWithItems
{
- typedef cBlockEntityWithItems super;
+ typedef cBlockEntityWithItems Super;
public:
// tolua_end
BLOCKENTITY_PROTODEF(cBeaconEntity)
- cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ cBeaconEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
// cBlockEntity overrides:
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual bool UsedBy(cPlayer * a_Player) override;
diff --git a/src/BlockEntities/BlockEntity.cpp b/src/BlockEntities/BlockEntity.cpp
index 0b69830f6..f0716dd08 100644
--- a/src/BlockEntities/BlockEntity.cpp
+++ b/src/BlockEntities/BlockEntity.cpp
@@ -29,24 +29,24 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
{
switch (a_BlockType)
{
- case E_BLOCK_BEACON: return new cBeaconEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_CHEST: return new cChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World, a_BlockType);
- case E_BLOCK_COMMAND_BLOCK: return new cCommandBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_FLOWER_POT: return new cFlowerPotEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
- case E_BLOCK_BREWING_STAND: return new cBrewingstandEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
- case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_MOB_SPAWNER: return new cMobSpawnerEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
- case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_TRAPPED_CHEST: return new cChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World, a_BlockType);
- case E_BLOCK_WALLSIGN: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_NOTE_BLOCK: return new cNoteEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_BEACON: return new cBeaconEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_CHEST: return new cChestEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_COMMAND_BLOCK: return new cCommandBlockEntity(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_FLOWER_POT: return new cFlowerPotEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_BREWING_STAND: return new cBrewingstandEntity(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_MOB_SPAWNER: return new cMobSpawnerEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_TRAPPED_CHEST: return new cChestEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_WALLSIGN: return new cSignEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_NOTE_BLOCK: return new cNoteEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
}
LOGD("%s: Requesting creation of an unknown block entity - block type %d (%s)",
__FUNCTION__, a_BlockType, ItemTypeToString(a_BlockType).c_str()
@@ -58,3 +58,25 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
+
+cBlockEntity * cBlockEntity::Clone(int a_BlockX, int a_BlockY, int a_BlockZ)
+{
+ auto res = std::unique_ptr<cBlockEntity>(CreateByBlockType(m_BlockType, m_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, nullptr));
+ res->CopyFrom(*this);
+ return res.release();
+}
+
+
+
+
+
+void cBlockEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ // Nothing to copy, but check that we're copying the right entity:
+ ASSERT(m_BlockType == a_Src.m_BlockType);
+ ASSERT(m_BlockMeta == a_Src.m_BlockMeta);
+}
+
+
+
+
diff --git a/src/BlockEntities/BlockEntity.h b/src/BlockEntities/BlockEntity.h
index 17c0677ec..6c69e8260 100644
--- a/src/BlockEntities/BlockEntity.h
+++ b/src/BlockEntities/BlockEntity.h
@@ -9,7 +9,7 @@
#define BLOCKENTITY_PROTODEF(classname) \
virtual bool IsA(const char * a_ClassName) const override \
{ \
- return ((a_ClassName != nullptr) && ((strcmp(a_ClassName, #classname) == 0) || super::IsA(a_ClassName))); \
+ return ((a_ClassName != nullptr) && ((strcmp(a_ClassName, #classname) == 0) || Super::IsA(a_ClassName))); \
} \
virtual const char * GetClass(void) const override \
{ \
@@ -21,7 +21,7 @@
} \
virtual const char * GetParentClass(void) const override \
{ \
- return super::GetClass(); \
+ return Super::GetClass(); \
}
@@ -40,13 +40,14 @@ class cWorld;
class cBlockEntity
{
protected:
- cBlockEntity(BLOCKTYPE a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
+ cBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
m_PosX(a_BlockX),
m_PosY(a_BlockY),
m_PosZ(a_BlockZ),
m_RelX(a_BlockX - cChunkDef::Width * FAST_FLOOR_DIV(a_BlockX, cChunkDef::Width)),
m_RelZ(a_BlockZ - cChunkDef::Width * FAST_FLOOR_DIV(a_BlockZ, cChunkDef::Width)),
m_BlockType(a_BlockType),
+ m_BlockMeta(a_BlockMeta),
m_World(a_World)
{
}
@@ -68,6 +69,15 @@ public:
Returns nullptr for unknown block types. */
static cBlockEntity * CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World = nullptr);
+ /** Makes an exact copy of this block entity, except for its m_World (set to nullptr), and at a new position.
+ Uses CopyFrom() to copy the properties. */
+ cBlockEntity * Clone(int a_BlockX, int a_BlockY, int a_BlockZ);
+
+ /** Copies all properties of a_Src into this entity, except for its m_World and location.
+ Each non-abstract descendant should override to copy its specific properties, and call
+ Super::CopyFrom(a_Src) to copy the common ones. */
+ virtual void CopyFrom(const cBlockEntity & a_Src);
+
static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates
{
return "cBlockEntity";
@@ -124,8 +134,14 @@ protected:
/** Position relative to the chunk, used to speed up ticking */
int m_RelX, m_RelZ;
+ /** The blocktype representing this particular instance in the world.
+ Mainly used for multi-block-type entities, such as furnaces / lit furnaces. */
BLOCKTYPE m_BlockType;
+ /** The block meta representing this particular instance in the world
+ Mainly used for directional entities, such as dispensers. */
+ NIBBLETYPE m_BlockMeta;
+
cWorld * m_World;
} ; // tolua_export
diff --git a/src/BlockEntities/BlockEntityWithItems.cpp b/src/BlockEntities/BlockEntityWithItems.cpp
new file mode 100644
index 000000000..de223041d
--- /dev/null
+++ b/src/BlockEntities/BlockEntityWithItems.cpp
@@ -0,0 +1,72 @@
+// BlockEntityWithItems.cpp
+
+// Implements the cBlockEntityWithItems class representing a common ancestor for all block entities that have an ItemGrid
+
+
+
+
+
+#include "Globals.h"
+#include "BlockEntityWithItems.h"
+
+
+
+
+
+cBlockEntityWithItems::cBlockEntityWithItems(
+ BLOCKTYPE a_BlockType,
+ NIBBLETYPE a_BlockMeta,
+ int a_BlockX, int a_BlockY, int a_BlockZ,
+ int a_ItemGridWidth, int a_ItemGridHeight,
+ cWorld * a_World
+):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
+ cBlockEntityWindowOwner(this),
+ m_Contents(a_ItemGridWidth, a_ItemGridHeight)
+{
+ m_Contents.AddListener(*this);
+}
+
+
+
+
+
+void cBlockEntityWithItems::Destroy(void)
+{
+ // Drop the contents as pickups:
+ ASSERT(m_World != nullptr);
+ cItems Pickups;
+ m_Contents.CopyToItems(Pickups);
+ m_Contents.Clear();
+ m_World->SpawnItemPickups(Pickups, m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); // Spawn in centre of block
+}
+
+
+
+
+
+void cBlockEntityWithItems::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cBlockEntityWithItems &>(a_Src);
+ m_Contents.CopyFrom(src.m_Contents);
+}
+
+
+
+
+
+void cBlockEntityWithItems::OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum)
+{
+ UNUSED(a_SlotNum);
+ ASSERT(a_Grid == &m_Contents);
+ if (m_World != nullptr)
+ {
+ if (GetWindow() != nullptr)
+ {
+ GetWindow()->BroadcastWholeWindow();
+ }
+
+ m_World->MarkChunkDirty(GetChunkX(), GetChunkZ());
+ }
+}
diff --git a/src/BlockEntities/BlockEntityWithItems.h b/src/BlockEntities/BlockEntityWithItems.h
index 39540d630..65fdf3c0d 100644
--- a/src/BlockEntities/BlockEntityWithItems.h
+++ b/src/BlockEntities/BlockEntityWithItems.h
@@ -26,35 +26,25 @@ class cBlockEntityWithItems :
// tolua_begin
public cBlockEntityWindowOwner
{
- typedef cBlockEntity super;
+ typedef cBlockEntity Super;
public:
// tolua_end
BLOCKENTITY_PROTODEF(cBlockEntityWithItems)
+
cBlockEntityWithItems(
BLOCKTYPE a_BlockType, // Type of the block that the entity represents
+ NIBBLETYPE a_BlockMeta, // Meta of the block that the entity represents
int a_BlockX, int a_BlockY, int a_BlockZ, // Position of the block entity
int a_ItemGridWidth, int a_ItemGridHeight, // Dimensions of the ItemGrid
cWorld * a_World // Optional world to assign to the entity
- ) :
- super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World),
- cBlockEntityWindowOwner(this),
- m_Contents(a_ItemGridWidth, a_ItemGridHeight)
- {
- m_Contents.AddListener(*this);
- }
-
- virtual void Destroy(void) override
- {
- // Drop the contents as pickups:
- ASSERT(m_World != nullptr);
- cItems Pickups;
- m_Contents.CopyToItems(Pickups);
- m_Contents.Clear();
- m_World->SpawnItemPickups(Pickups, m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); // Spawn in centre of block
- }
+ );
+
+ // cBlockEntity overrides:
+ virtual void Destroy(void) override;
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
// tolua_begin
@@ -76,20 +66,7 @@ protected:
cItemGrid m_Contents;
// cItemGrid::cListener overrides:
- virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) override
- {
- UNUSED(a_SlotNum);
- ASSERT(a_Grid == &m_Contents);
- if (m_World != nullptr)
- {
- if (GetWindow() != nullptr)
- {
- GetWindow()->BroadcastWholeWindow();
- }
-
- m_World->MarkChunkDirty(GetChunkX(), GetChunkZ());
- }
- }
+ virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) override;
} ; // tolua_export
diff --git a/src/BlockEntities/BrewingstandEntity.cpp b/src/BlockEntities/BrewingstandEntity.cpp
index 464d175c9..28c6e2f43 100644
--- a/src/BlockEntities/BrewingstandEntity.cpp
+++ b/src/BlockEntities/BrewingstandEntity.cpp
@@ -19,19 +19,14 @@
-cBrewingstandEntity::cBrewingstandEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World) :
- super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
- m_BlockMeta(a_BlockMeta),
+cBrewingstandEntity::cBrewingstandEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
m_IsDestroyed(false),
m_IsBrewing(false),
m_TimeBrewed(0),
m_RemainingFuel(0)
{
m_Contents.AddListener(*this);
- for (int i = 0; i < 3; i++)
- {
- m_Results[i] = cItem{};
- }
}
@@ -52,33 +47,41 @@ cBrewingstandEntity::~cBrewingstandEntity()
-bool cBrewingstandEntity::UsedBy(cPlayer * a_Player)
+void cBrewingstandEntity::Destroy()
{
- cWindow * Window = GetWindow();
- if (Window == nullptr)
- {
- OpenWindow(new cBrewingstandWindow(m_PosX, m_PosY, m_PosZ, this));
- Window = GetWindow();
- }
+ m_IsDestroyed = true;
+ Super::Destroy();
+}
- if (Window != nullptr)
- {
- if (a_Player->GetWindow() != Window)
- {
- a_Player->OpenWindow(*Window);
- }
- }
- if (m_IsBrewing)
+
+
+
+void cBrewingstandEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cBrewingstandEntity &>(a_Src);
+ m_IsBrewing = src.m_IsBrewing;
+ for (size_t i = 0; i < ARRAYCOUNT(m_CurrentBrewingRecipes); ++i)
{
- BroadcastProgress(0, m_NeedBrewingTime - m_TimeBrewed);
+ m_CurrentBrewingRecipes[i] = src.m_CurrentBrewingRecipes[i];
}
- else
+ for (size_t i = 0; i < ARRAYCOUNT(m_Results); ++i)
{
- BroadcastProgress(0, 0);
+ m_Results[i] = src.m_Results[i];
}
- BroadcastProgress(1, m_RemainingFuel);
- return true;
+ m_TimeBrewed = src.m_TimeBrewed;
+ m_RemainingFuel = src.m_RemainingFuel;
+}
+
+
+
+
+
+void cBrewingstandEntity::SendTo(cClientHandle & a_Client)
+{
+ // Nothing needs to be sent
+ UNUSED(a_Client);
}
@@ -159,10 +162,33 @@ bool cBrewingstandEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
-void cBrewingstandEntity::SendTo(cClientHandle & a_Client)
+bool cBrewingstandEntity::UsedBy(cPlayer * a_Player)
{
- // Nothing needs to be sent
- UNUSED(a_Client);
+ cWindow * Window = GetWindow();
+ if (Window == nullptr)
+ {
+ OpenWindow(new cBrewingstandWindow(m_PosX, m_PosY, m_PosZ, this));
+ Window = GetWindow();
+ }
+
+ if (Window != nullptr)
+ {
+ if (a_Player->GetWindow() != Window)
+ {
+ a_Player->OpenWindow(*Window);
+ }
+ }
+
+ if (m_IsBrewing)
+ {
+ BroadcastProgress(0, m_NeedBrewingTime - m_TimeBrewed);
+ }
+ else
+ {
+ BroadcastProgress(0, 0);
+ }
+ BroadcastProgress(1, m_RemainingFuel);
+ return true;
}
@@ -185,7 +211,7 @@ void cBrewingstandEntity::BroadcastProgress(short a_ProgressbarID, short a_Value
void cBrewingstandEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
{
- super::OnSlotChanged(a_ItemGrid, a_SlotNum);
+ Super::OnSlotChanged(a_ItemGrid, a_SlotNum);
if (m_IsDestroyed)
{
diff --git a/src/BlockEntities/BrewingstandEntity.h b/src/BlockEntities/BrewingstandEntity.h
index a8891968a..cda77d21a 100644
--- a/src/BlockEntities/BrewingstandEntity.h
+++ b/src/BlockEntities/BrewingstandEntity.h
@@ -18,7 +18,7 @@ class cClientHandle;
class cBrewingstandEntity :
public cBlockEntityWithItems
{
- typedef cBlockEntityWithItems super;
+ typedef cBlockEntityWithItems Super;
public:
enum
@@ -38,19 +38,16 @@ public:
BLOCKENTITY_PROTODEF(cBrewingstandEntity)
/** Constructor used for normal operation */
- cBrewingstandEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World);
+ cBrewingstandEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
virtual ~cBrewingstandEntity() override;
// cBlockEntity overrides:
+ virtual void Destroy() override;
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual bool UsedBy(cPlayer * a_Player) override;
- virtual void Destroy() override
- {
- m_IsDestroyed = true;
- super::Destroy();
- }
// tolua_begin
@@ -109,10 +106,9 @@ public:
/** Gets the recipes. Will be called if the brewing stand gets loaded from the world. */
void LoadRecipes(void);
-protected:
- /** Block meta of the block currently represented by this entity */
- NIBBLETYPE m_BlockMeta;
+
+protected:
/** Set to true when the brewing stand entity has been destroyed to prevent the block being set again */
bool m_IsDestroyed;
@@ -127,7 +123,7 @@ protected:
const cBrewingRecipes::cRecipe * m_CurrentBrewingRecipes[3] = {};
/** Result items for the bottle inputs */
- cItem m_Results[3] = {};
+ cItem m_Results[3];
/** Amount of ticks that the current item has been brewed */
short m_TimeBrewed;
diff --git a/src/BlockEntities/CMakeLists.txt b/src/BlockEntities/CMakeLists.txt
index 96dfa8d85..d6bf6355c 100644
--- a/src/BlockEntities/CMakeLists.txt
+++ b/src/BlockEntities/CMakeLists.txt
@@ -5,6 +5,7 @@ include_directories ("${PROJECT_SOURCE_DIR}/../")
SET (SRCS
BeaconEntity.cpp
BlockEntity.cpp
+ BlockEntityWithItems.cpp
BrewingstandEntity.cpp
ChestEntity.cpp
CommandBlockEntity.cpp
diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp
index 9aeb50d5b..a4576b66d 100644
--- a/src/BlockEntities/ChestEntity.cpp
+++ b/src/BlockEntities/ChestEntity.cpp
@@ -11,8 +11,8 @@
-cChestEntity::cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, BLOCKTYPE a_Type) :
- super(a_Type, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
+cChestEntity::cChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
m_NumActivePlayers(0),
m_Neighbour(nullptr)
{
@@ -46,6 +46,21 @@ cChestEntity::~cChestEntity()
+void cChestEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cChestEntity &>(a_Src);
+ m_Contents.CopyFrom(src.m_Contents);
+
+ // Reset the neighbor and player count, there's no sense in copying these:
+ m_Neighbour = nullptr;
+ m_NumActivePlayers = 0;
+}
+
+
+
+
+
void cChestEntity::SendTo(cClientHandle & a_Client)
{
// Send a dummy "number of players with chest open" packet to make the chest visible:
diff --git a/src/BlockEntities/ChestEntity.h b/src/BlockEntities/ChestEntity.h
index 96d904248..dc26e0895 100644
--- a/src/BlockEntities/ChestEntity.h
+++ b/src/BlockEntities/ChestEntity.h
@@ -17,7 +17,7 @@ class cClientHandle;
class cChestEntity :
public cBlockEntityWithItems
{
- typedef cBlockEntityWithItems super;
+ typedef cBlockEntityWithItems Super;
public:
enum
@@ -31,11 +31,12 @@ public:
BLOCKENTITY_PROTODEF(cChestEntity)
/** Constructor used for normal operation */
- cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, BLOCKTYPE a_Type);
+ cChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
virtual ~cChestEntity() override;
// cBlockEntity overrides:
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual bool UsedBy(cPlayer * a_Player) override;
diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp
index 5a273d56f..43e9316c5 100644
--- a/src/BlockEntities/CommandBlockEntity.cpp
+++ b/src/BlockEntities/CommandBlockEntity.cpp
@@ -17,11 +17,13 @@
-cCommandBlockEntity::cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World) :
- super(E_BLOCK_COMMAND_BLOCK, a_X, a_Y, a_Z, a_World),
+cCommandBlockEntity::cCommandBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
m_ShouldExecute(false),
m_Result(0)
-{}
+{
+ ASSERT(a_BlockType == E_BLOCK_COMMAND_BLOCK);
+}
@@ -112,6 +114,20 @@ void cCommandBlockEntity::Activate(void)
+void cCommandBlockEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cCommandBlockEntity &>(a_Src);
+ m_Command = src.m_Command;
+ m_LastOutput = src.m_LastOutput;
+ m_Result = src.m_Result;
+ m_ShouldExecute = src.m_ShouldExecute;
+}
+
+
+
+
+
bool cCommandBlockEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
diff --git a/src/BlockEntities/CommandBlockEntity.h b/src/BlockEntities/CommandBlockEntity.h
index 716cb3b79..55f34a000 100644
--- a/src/BlockEntities/CommandBlockEntity.h
+++ b/src/BlockEntities/CommandBlockEntity.h
@@ -20,7 +20,7 @@
class cCommandBlockEntity :
public cBlockEntity
{
- typedef cBlockEntity super;
+ typedef cBlockEntity Super;
public:
@@ -29,8 +29,10 @@ public:
BLOCKENTITY_PROTODEF(cCommandBlockEntity)
/** Creates a new empty command block entity */
- cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World);
+ cCommandBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ // cBlockEntity overrides:
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual bool UsedBy(cPlayer * a_Player) override;
diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp
index 78ce81e5b..66311a518 100644
--- a/src/BlockEntities/DispenserEntity.cpp
+++ b/src/BlockEntities/DispenserEntity.cpp
@@ -13,9 +13,10 @@
-cDispenserEntity::cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
- super(E_BLOCK_DISPENSER, a_BlockX, a_BlockY, a_BlockZ, a_World)
+cDispenserEntity::cDispenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World)
{
+ ASSERT(a_BlockType == E_BLOCK_DISPENSER);
}
@@ -309,9 +310,9 @@ Vector3d cDispenserEntity::GetShootVector(NIBBLETYPE a_Meta)
-bool cDispenserEntity::ScoopUpLiquid(int a_SlotNum, short a_BucketItemType)
+bool cDispenserEntity::ScoopUpLiquid(int a_SlotNum, short a_ResultingBucketItemType)
{
- cItem LiquidBucket(a_BucketItemType, 1);
+ cItem LiquidBucket(a_ResultingBucketItemType, 1);
if (m_Contents.GetSlot(a_SlotNum).m_ItemCount == 1)
{
// Special case: replacing one empty bucket with one full bucket
diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h
index 4e81b455a..bb4178079 100644
--- a/src/BlockEntities/DispenserEntity.h
+++ b/src/BlockEntities/DispenserEntity.h
@@ -11,7 +11,7 @@
class cDispenserEntity :
public cDropSpenserEntity
{
- typedef cDropSpenserEntity super;
+ typedef cDropSpenserEntity Super;
public:
@@ -20,7 +20,7 @@ public:
BLOCKENTITY_PROTODEF(cDispenserEntity)
/** Constructor used for normal operation */
- cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ cDispenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
// tolua_begin
@@ -38,7 +38,7 @@ private:
virtual void DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) override;
/** If such a bucket can fit, adds it to m_Contents and returns true */
- bool ScoopUpLiquid(int a_SlotNum, short a_BucketItemType);
+ bool ScoopUpLiquid(int a_SlotNum, short a_ResultingBucketItemType);
/** If the a_BlockInFront can be washed away by liquid and the empty bucket can fit,
does the m_Contents processing and returns true. Returns false otherwise. */
diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp
index 032c5cf12..34c7857b0 100644
--- a/src/BlockEntities/DropSpenserEntity.cpp
+++ b/src/BlockEntities/DropSpenserEntity.cpp
@@ -15,8 +15,8 @@
-cDropSpenserEntity::cDropSpenserEntity(BLOCKTYPE a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
- super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
+cDropSpenserEntity::cDropSpenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
m_ShouldDropSpense(false)
{
}
@@ -113,6 +113,18 @@ void cDropSpenserEntity::Activate(void)
+void cDropSpenserEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cDropSpenserEntity &>(a_Src);
+ m_Contents.CopyFrom(src.m_Contents);
+ m_ShouldDropSpense = src.m_ShouldDropSpense;
+}
+
+
+
+
+
bool cDropSpenserEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h
index 8efd7acf8..72ab4246e 100644
--- a/src/BlockEntities/DropSpenserEntity.h
+++ b/src/BlockEntities/DropSpenserEntity.h
@@ -26,7 +26,7 @@ class cClientHandle;
class cDropSpenserEntity :
public cBlockEntityWithItems
{
- typedef cBlockEntityWithItems super;
+ typedef cBlockEntityWithItems Super;
public:
enum
@@ -39,10 +39,11 @@ public:
BLOCKENTITY_PROTODEF(cDropSpenserEntity)
- cDropSpenserEntity(BLOCKTYPE a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ cDropSpenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
virtual ~cDropSpenserEntity() override;
// cBlockEntity overrides:
+ virtual void CopyFrom(const cBlockEntity & a_Src);
virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual bool UsedBy(cPlayer * a_Player) override;
diff --git a/src/BlockEntities/DropperEntity.cpp b/src/BlockEntities/DropperEntity.cpp
index 38d1aa988..29f77d2df 100644
--- a/src/BlockEntities/DropperEntity.cpp
+++ b/src/BlockEntities/DropperEntity.cpp
@@ -10,9 +10,10 @@
-cDropperEntity::cDropperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
- super(E_BLOCK_DROPPER, a_BlockX, a_BlockY, a_BlockZ, a_World)
+cDropperEntity::cDropperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World)
{
+ ASSERT(a_BlockType == E_BLOCK_DROPPER);
}
diff --git a/src/BlockEntities/DropperEntity.h b/src/BlockEntities/DropperEntity.h
index e6ce34f0d..eb1d79a97 100644
--- a/src/BlockEntities/DropperEntity.h
+++ b/src/BlockEntities/DropperEntity.h
@@ -19,7 +19,7 @@
class cDropperEntity :
public cDropSpenserEntity
{
- typedef cDropSpenserEntity super;
+ typedef cDropSpenserEntity Super;
public:
@@ -28,7 +28,7 @@ public:
BLOCKENTITY_PROTODEF(cDropperEntity)
/** Constructor used for normal operation */
- cDropperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ cDropperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
protected:
// cDropSpenserEntity overrides:
diff --git a/src/BlockEntities/EnderChestEntity.cpp b/src/BlockEntities/EnderChestEntity.cpp
index d6ee9e016..9030a0172 100644
--- a/src/BlockEntities/EnderChestEntity.cpp
+++ b/src/BlockEntities/EnderChestEntity.cpp
@@ -12,10 +12,11 @@
-cEnderChestEntity::cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
- super(E_BLOCK_ENDER_CHEST, a_BlockX, a_BlockY, a_BlockZ, a_World),
+cEnderChestEntity::cEnderChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
cBlockEntityWindowOwner(this)
{
+ ASSERT(a_BlockType == E_BLOCK_ENDER_CHEST);
}
diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h
index cb45f44b7..acd7bbdec 100644
--- a/src/BlockEntities/EnderChestEntity.h
+++ b/src/BlockEntities/EnderChestEntity.h
@@ -13,14 +13,14 @@ class cEnderChestEntity :
public cBlockEntity,
public cBlockEntityWindowOwner
{
- typedef cBlockEntity super;
+ typedef cBlockEntity Super;
public:
// tolua_end
BLOCKENTITY_PROTODEF(cEnderChestEntity)
- cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ cEnderChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
virtual ~cEnderChestEntity() override;
// cBlockEntity overrides:
diff --git a/src/BlockEntities/FlowerPotEntity.cpp b/src/BlockEntities/FlowerPotEntity.cpp
index 125b0d173..dbbbefff2 100644
--- a/src/BlockEntities/FlowerPotEntity.cpp
+++ b/src/BlockEntities/FlowerPotEntity.cpp
@@ -13,16 +13,45 @@
-cFlowerPotEntity::cFlowerPotEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
- super(E_BLOCK_FLOWER_POT, a_BlockX, a_BlockY, a_BlockZ, a_World)
+cFlowerPotEntity::cFlowerPotEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World)
{
+ ASSERT(a_BlockType == E_BLOCK_FLOWER_POT);
+}
+
+
+
+
+
+void cFlowerPotEntity::Destroy(void)
+{
+ // Drop the contents as pickups:
+ if (!m_Item.IsEmpty())
+ {
+ ASSERT(m_World != nullptr);
+ cItems Pickups;
+ Pickups.Add(m_Item);
+ m_World->SpawnItemPickups(Pickups, m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5);
+
+ m_Item.Empty();
+ }
+}
+
+
+
+
+
+void cFlowerPotEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cFlowerPotEntity &>(a_Src);
+ m_Item = src.m_Item;
}
-// It don't do anything when 'used'
bool cFlowerPotEntity::UsedBy(cPlayer * a_Player)
{
if (IsItemInPot())
@@ -56,24 +85,6 @@ void cFlowerPotEntity::SendTo(cClientHandle & a_Client)
-void cFlowerPotEntity::Destroy(void)
-{
- // Drop the contents as pickups:
- if (!m_Item.IsEmpty())
- {
- ASSERT(m_World != nullptr);
- cItems Pickups;
- Pickups.Add(m_Item);
- m_World->SpawnItemPickups(Pickups, m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5);
-
- m_Item.Empty();
- }
-}
-
-
-
-
-
bool cFlowerPotEntity::IsFlower(short m_ItemType, short m_ItemData)
{
switch (m_ItemType)
diff --git a/src/BlockEntities/FlowerPotEntity.h b/src/BlockEntities/FlowerPotEntity.h
index c9d330673..00ddc1442 100644
--- a/src/BlockEntities/FlowerPotEntity.h
+++ b/src/BlockEntities/FlowerPotEntity.h
@@ -20,7 +20,7 @@
class cFlowerPotEntity :
public cBlockEntity
{
- typedef cBlockEntity super;
+ typedef cBlockEntity Super;
public:
@@ -29,9 +29,8 @@ public:
BLOCKENTITY_PROTODEF(cFlowerPotEntity)
/** Creates a new flowerpot entity at the specified block coords. a_World may be nullptr */
- cFlowerPotEntity(int a_BlocX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ cFlowerPotEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
- virtual void Destroy(void) override;
// tolua_begin
@@ -46,7 +45,9 @@ public:
// tolua_end
- /** Called when the player is using the entity; returns true if it was a successful use, return false if it should be treated as a normal block */
+ // cBlockEntity overrides:
+ virtual void Destroy(void) override;
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual bool UsedBy(cPlayer * a_Player) override;
virtual void SendTo(cClientHandle & a_Client) override;
diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp
index bdbecfb79..1f7f6e023 100644
--- a/src/BlockEntities/FurnaceEntity.cpp
+++ b/src/BlockEntities/FurnaceEntity.cpp
@@ -23,9 +23,8 @@ enum
-cFurnaceEntity::cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World) :
- super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
- m_BlockMeta(a_BlockMeta),
+cFurnaceEntity::cFurnaceEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
m_CurrentRecipe(nullptr),
m_IsDestroyed(false),
m_IsCooking(a_BlockType == E_BLOCK_LIT_FURNACE),
@@ -56,36 +55,40 @@ cFurnaceEntity::~cFurnaceEntity()
-bool cFurnaceEntity::UsedBy(cPlayer * a_Player)
+void cFurnaceEntity::Destroy()
{
- cWindow * Window = GetWindow();
- if (Window == nullptr)
- {
- OpenWindow(new cFurnaceWindow(m_PosX, m_PosY, m_PosZ, this));
- Window = GetWindow();
- }
+ m_IsDestroyed = true;
+ Super::Destroy();
+}
- if (Window != nullptr)
- {
- if (a_Player->GetWindow() != Window)
- {
- a_Player->OpenWindow(*Window);
- }
- }
- UpdateProgressBars(true);
- return true;
+
+
+
+void cFurnaceEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cFurnaceEntity &>(a_Src);
+ m_Contents.CopyFrom(src.m_Contents);
+ m_CurrentRecipe = src.m_CurrentRecipe;
+ m_FuelBurnTime = src.m_FuelBurnTime;
+ m_IsCooking = src.m_IsCooking;
+ m_IsDestroyed = src.m_IsDestroyed;
+ m_IsLoading = src.m_IsLoading;
+ m_LastInput = src.m_LastInput;
+ m_NeedCookTime = src.m_NeedCookTime;
+ m_TimeBurned = src.m_TimeBurned;
+ m_TimeCooked = src.m_TimeCooked;
}
-bool cFurnaceEntity::ContinueCooking(void)
+void cFurnaceEntity::SendTo(cClientHandle & a_Client)
{
- UpdateInput();
- UpdateFuel();
- return m_IsCooking;
+ // Nothing needs to be sent
+ UNUSED(a_Client);
}
@@ -134,10 +137,36 @@ bool cFurnaceEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
-void cFurnaceEntity::SendTo(cClientHandle & a_Client)
+bool cFurnaceEntity::UsedBy(cPlayer * a_Player)
{
- // Nothing needs to be sent
- UNUSED(a_Client);
+ cWindow * Window = GetWindow();
+ if (Window == nullptr)
+ {
+ OpenWindow(new cFurnaceWindow(m_PosX, m_PosY, m_PosZ, this));
+ Window = GetWindow();
+ }
+
+ if (Window != nullptr)
+ {
+ if (a_Player->GetWindow() != Window)
+ {
+ a_Player->OpenWindow(*Window);
+ }
+ }
+
+ UpdateProgressBars(true);
+ return true;
+}
+
+
+
+
+
+bool cFurnaceEntity::ContinueCooking(void)
+{
+ UpdateInput();
+ UpdateFuel();
+ return m_IsCooking;
}
@@ -208,7 +237,7 @@ void cFurnaceEntity::BurnNewFuel(void)
void cFurnaceEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
{
- super::OnSlotChanged(a_ItemGrid, a_SlotNum);
+ Super::OnSlotChanged(a_ItemGrid, a_SlotNum);
if (m_IsDestroyed)
{
diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h
index c9252c39f..7b189be85 100644
--- a/src/BlockEntities/FurnaceEntity.h
+++ b/src/BlockEntities/FurnaceEntity.h
@@ -18,7 +18,7 @@ class cClientHandle;
class cFurnaceEntity :
public cBlockEntityWithItems
{
- typedef cBlockEntityWithItems super;
+ typedef cBlockEntityWithItems Super;
public:
enum
@@ -36,19 +36,16 @@ public:
BLOCKENTITY_PROTODEF(cFurnaceEntity)
/** Constructor used for normal operation */
- cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World);
+ cFurnaceEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
virtual ~cFurnaceEntity() override;
// cBlockEntity overrides:
+ virtual void Destroy() override;
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual bool UsedBy(cPlayer * a_Player) override;
- virtual void Destroy() override
- {
- m_IsDestroyed = true;
- super::Destroy();
- }
/** Restarts cooking
Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active
@@ -106,10 +103,8 @@ public:
m_IsLoading = a_IsLoading;
}
-protected:
- /** Block meta of the block currently represented by this entity */
- NIBBLETYPE m_BlockMeta;
+protected:
/** The recipe for the current input slot */
const cFurnaceRecipe::cRecipe * m_CurrentRecipe;
diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp
index c6cab90cd..0467685af 100644
--- a/src/BlockEntities/HopperEntity.cpp
+++ b/src/BlockEntities/HopperEntity.cpp
@@ -17,11 +17,12 @@
-cHopperEntity::cHopperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
- super(E_BLOCK_HOPPER, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
+cHopperEntity::cHopperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
m_LastMoveItemsInTick(0),
m_LastMoveItemsOutTick(0)
{
+ ASSERT(a_BlockType == E_BLOCK_HOPPER);
}
@@ -52,16 +53,28 @@ bool cHopperEntity::GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, i
+void cHopperEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cHopperEntity &>(a_Src);
+ m_LastMoveItemsInTick = src.m_LastMoveItemsInTick;
+ m_LastMoveItemsOutTick = src.m_LastMoveItemsOutTick;
+}
+
+
+
+
+
bool cHopperEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
Int64 CurrentTick = a_Chunk.GetWorld()->GetWorldAge();
- bool res = false;
- res = MoveItemsIn (a_Chunk, CurrentTick) || res;
- res = MovePickupsIn(a_Chunk, CurrentTick) || res;
- res = MoveItemsOut (a_Chunk, CurrentTick) || res;
- return res;
+ bool isDirty = false;
+ isDirty = MoveItemsIn (a_Chunk, CurrentTick) || isDirty;
+ isDirty = MovePickupsIn(a_Chunk, CurrentTick) || isDirty;
+ isDirty = MoveItemsOut (a_Chunk, CurrentTick) || isDirty;
+ return isDirty;
}
diff --git a/src/BlockEntities/HopperEntity.h b/src/BlockEntities/HopperEntity.h
index 5c0ef139d..e11b2cc4d 100644
--- a/src/BlockEntities/HopperEntity.h
+++ b/src/BlockEntities/HopperEntity.h
@@ -19,7 +19,7 @@
class cHopperEntity :
public cBlockEntityWithItems
{
- typedef cBlockEntityWithItems super;
+ typedef cBlockEntityWithItems Super;
public:
enum
@@ -34,7 +34,7 @@ public:
BLOCKENTITY_PROTODEF(cHopperEntity)
/** Constructor used for normal operation */
- cHopperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ cHopperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
/** Returns the block coords of the block receiving the output items, based on the meta
Returns false if unattached.
@@ -47,6 +47,7 @@ protected:
Int64 m_LastMoveItemsOutTick;
// cBlockEntity overrides:
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual bool UsedBy(cPlayer * a_Player) override;
diff --git a/src/BlockEntities/JukeboxEntity.cpp b/src/BlockEntities/JukeboxEntity.cpp
index f505a3030..ef2069d72 100644
--- a/src/BlockEntities/JukeboxEntity.cpp
+++ b/src/BlockEntities/JukeboxEntity.cpp
@@ -10,10 +10,11 @@
-cJukeboxEntity::cJukeboxEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
- super(E_BLOCK_JUKEBOX, a_BlockX, a_BlockY, a_BlockZ, a_World),
+cJukeboxEntity::cJukeboxEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
m_Record(0)
{
+ ASSERT(a_BlockType == E_BLOCK_JUKEBOX);
}
@@ -28,6 +29,17 @@ cJukeboxEntity::~cJukeboxEntity()
+void cJukeboxEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cJukeboxEntity &>(a_Src);
+ m_Record = src.m_Record;
+}
+
+
+
+
+
bool cJukeboxEntity::UsedBy(cPlayer * a_Player)
{
if (IsPlayingRecord())
diff --git a/src/BlockEntities/JukeboxEntity.h b/src/BlockEntities/JukeboxEntity.h
index c76aa6507..6e02d111d 100644
--- a/src/BlockEntities/JukeboxEntity.h
+++ b/src/BlockEntities/JukeboxEntity.h
@@ -12,14 +12,15 @@
class cJukeboxEntity :
public cBlockEntity
{
- typedef cBlockEntity super;
+ typedef cBlockEntity Super;
+
public:
// tolua_end
BLOCKENTITY_PROTODEF(cJukeboxEntity)
- cJukeboxEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ cJukeboxEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
virtual ~cJukeboxEntity() override;
// tolua_begin
@@ -44,6 +45,8 @@ public:
// tolua_end
+ // cBlockEntity overrides:
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual bool UsedBy(cPlayer * a_Player) override;
virtual void SendTo(cClientHandle &) override {}
diff --git a/src/BlockEntities/MobHeadEntity.cpp b/src/BlockEntities/MobHeadEntity.cpp
index 01529f4d0..3bc7839b7 100644
--- a/src/BlockEntities/MobHeadEntity.cpp
+++ b/src/BlockEntities/MobHeadEntity.cpp
@@ -13,17 +13,33 @@
-cMobHeadEntity::cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
- super(E_BLOCK_HEAD, a_BlockX, a_BlockY, a_BlockZ, a_World),
+cMobHeadEntity::cMobHeadEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
m_Type(SKULL_TYPE_SKELETON),
m_Rotation(SKULL_ROTATION_NORTH)
{
+ ASSERT(a_BlockType == E_BLOCK_HEAD);
}
+void cMobHeadEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cMobHeadEntity &>(a_Src);
+ m_OwnerName = src.m_OwnerName;
+ m_OwnerTexture = src.m_OwnerTexture;
+ m_OwnerTextureSignature = src.m_OwnerTextureSignature;
+ m_OwnerUUID = src.m_OwnerUUID;
+ m_Rotation = src.m_Rotation;
+ m_Type = src.m_Type;
+}
+
+
+
+
bool cMobHeadEntity::UsedBy(cPlayer * a_Player)
{
UNUSED(a_Player);
diff --git a/src/BlockEntities/MobHeadEntity.h b/src/BlockEntities/MobHeadEntity.h
index eef88a201..c8bfeb357 100644
--- a/src/BlockEntities/MobHeadEntity.h
+++ b/src/BlockEntities/MobHeadEntity.h
@@ -20,7 +20,7 @@
class cMobHeadEntity :
public cBlockEntity
{
- typedef cBlockEntity super;
+ typedef cBlockEntity Super;
public:
@@ -29,7 +29,7 @@ public:
BLOCKENTITY_PROTODEF(cMobHeadEntity)
/** Creates a new mob head entity at the specified block coords. a_World may be nullptr */
- cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ cMobHeadEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
// tolua_begin
@@ -65,6 +65,8 @@ public:
// tolua_end
+ // cBlockEntity overrides:
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual bool UsedBy(cPlayer * a_Player) override;
virtual void SendTo(cClientHandle & a_Client) override;
diff --git a/src/BlockEntities/MobSpawnerEntity.cpp b/src/BlockEntities/MobSpawnerEntity.cpp
index 3bb04682a..9cc6f20c6 100644
--- a/src/BlockEntities/MobSpawnerEntity.cpp
+++ b/src/BlockEntities/MobSpawnerEntity.cpp
@@ -13,12 +13,26 @@
-cMobSpawnerEntity::cMobSpawnerEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World)
- : super(E_BLOCK_MOB_SPAWNER, a_BlockX, a_BlockY, a_BlockZ, a_World)
- , m_Entity(mtPig)
- , m_SpawnDelay(100)
- , m_IsActive(false)
+cMobSpawnerEntity::cMobSpawnerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
+ m_Entity(mtPig),
+ m_SpawnDelay(100),
+ m_IsActive(false)
{
+ ASSERT(a_BlockType == E_BLOCK_MOB_SPAWNER);
+}
+
+
+
+
+
+void cMobSpawnerEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cMobSpawnerEntity &>(a_Src);
+ m_Entity = src.m_Entity;
+ m_IsActive = src.m_IsActive;
+ m_SpawnDelay = src.m_SpawnDelay;
}
diff --git a/src/BlockEntities/MobSpawnerEntity.h b/src/BlockEntities/MobSpawnerEntity.h
index 66cfff2db..356265d31 100644
--- a/src/BlockEntities/MobSpawnerEntity.h
+++ b/src/BlockEntities/MobSpawnerEntity.h
@@ -20,13 +20,15 @@
class cMobSpawnerEntity :
public cBlockEntity
{
- typedef cBlockEntity super;
+ typedef cBlockEntity Super;
public:
// tolua_end
- cMobSpawnerEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ cMobSpawnerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ // cBlockEntity overrides:
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual bool UsedBy(cPlayer * a_Player) override;
virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
diff --git a/src/BlockEntities/NoteEntity.cpp b/src/BlockEntities/NoteEntity.cpp
index 41559a8ad..54b04e15a 100644
--- a/src/BlockEntities/NoteEntity.cpp
+++ b/src/BlockEntities/NoteEntity.cpp
@@ -9,10 +9,22 @@
-cNoteEntity::cNoteEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
- super(E_BLOCK_NOTE_BLOCK, a_BlockX, a_BlockY, a_BlockZ, a_World),
+cNoteEntity::cNoteEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
m_Pitch(0)
{
+ ASSERT(a_BlockType == E_BLOCK_NOTE_BLOCK);
+}
+
+
+
+
+
+void cNoteEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cNoteEntity &>(a_Src);
+ m_Pitch = src.m_Pitch;
}
diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h
index 7e92a7f06..87305b087 100644
--- a/src/BlockEntities/NoteEntity.h
+++ b/src/BlockEntities/NoteEntity.h
@@ -25,7 +25,7 @@ enum ENUM_NOTE_INSTRUMENTS
class cNoteEntity :
public cBlockEntity
{
- typedef cBlockEntity super;
+ typedef cBlockEntity Super;
public:
// tolua_end
@@ -33,7 +33,7 @@ public:
BLOCKENTITY_PROTODEF(cNoteEntity)
/** Creates a new note entity. a_World may be nullptr */
- cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World);
+ cNoteEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
virtual ~cNoteEntity() override {}
// tolua_begin
@@ -45,6 +45,8 @@ public:
// tolua_end
+ // cBlockEntity overrides:
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual bool UsedBy(cPlayer * a_Player) override;
virtual void SendTo(cClientHandle &) override {}
diff --git a/src/BlockEntities/SignEntity.cpp b/src/BlockEntities/SignEntity.cpp
index 64f42e425..61f200ed5 100644
--- a/src/BlockEntities/SignEntity.cpp
+++ b/src/BlockEntities/SignEntity.cpp
@@ -12,10 +12,25 @@
-cSignEntity::cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World) :
- super(a_BlockType, a_X, a_Y, a_Z, a_World)
+cSignEntity::cSignEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World):
+ Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World)
{
- ASSERT((a_Y >= 0) && (a_Y < cChunkDef::Height));
+ ASSERT((a_BlockType == E_BLOCK_WALLSIGN) || (a_BlockType == E_BLOCK_SIGN_POST));
+ ASSERT(cChunkDef::IsValidHeight(a_BlockY));
+}
+
+
+
+
+
+void cSignEntity::CopyFrom(const cBlockEntity & a_Src)
+{
+ Super::CopyFrom(a_Src);
+ auto & src = reinterpret_cast<const cSignEntity &>(a_Src);
+ for (size_t i = 0; i < ARRAYCOUNT(m_Line); ++i)
+ {
+ m_Line[i] = src.m_Line[i];
+ }
}
diff --git a/src/BlockEntities/SignEntity.h b/src/BlockEntities/SignEntity.h
index c7a2de154..666c290db 100644
--- a/src/BlockEntities/SignEntity.h
+++ b/src/BlockEntities/SignEntity.h
@@ -19,7 +19,7 @@
class cSignEntity :
public cBlockEntity
{
- typedef cBlockEntity super;
+ typedef cBlockEntity Super;
public:
@@ -28,7 +28,7 @@ public:
BLOCKENTITY_PROTODEF(cSignEntity)
/** Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be nullptr */
- cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World);
+ cSignEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
// tolua_begin
@@ -43,6 +43,8 @@ public:
// tolua_end
+ // cBlockEntity overrides:
+ virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual bool UsedBy(cPlayer * a_Player) override;
virtual void SendTo(cClientHandle & a_Client) override;
diff --git a/src/ItemGrid.cpp b/src/ItemGrid.cpp
index e97a53f68..39757e198 100644
--- a/src/ItemGrid.cpp
+++ b/src/ItemGrid.cpp
@@ -73,6 +73,22 @@ void cItemGrid::GetSlotCoords(int a_SlotNum, int & a_X, int & a_Y) const
+void cItemGrid::CopyFrom(const cItemGrid & a_Src)
+{
+ ASSERT(m_Width == a_Src.m_Width);
+ ASSERT(m_Height == a_Src.m_Height);
+ for (int i = m_NumSlots - 1; i >= 0; --i)
+ {
+ m_Slots[i] = a_Src.m_Slots[i];
+ }
+
+ // The listeners are not copied
+}
+
+
+
+
+
const cItem & cItemGrid::GetSlot(int a_X, int a_Y) const
{
return GetSlot(GetSlotNum(a_X, a_Y));
diff --git a/src/ItemGrid.h b/src/ItemGrid.h
index 46e200b9c..a346c9c8d 100644
--- a/src/ItemGrid.h
+++ b/src/ItemGrid.h
@@ -48,6 +48,11 @@ public:
/** Converts slot number into XY coords; sets coords to -1 on invalid slot number. Exported in ManualBindings.cpp */
void GetSlotCoords(int a_SlotNum, int & a_X, int & a_Y) const;
+ /** Copies all items from a_Src to this grid.
+ Both grids must be the same size (asserts).
+ Doesn't copy the listeners. */
+ void CopyFrom(const cItemGrid & a_Src);
+
// tolua_begin
// Retrieve slots by coords or slot number; Logs warning and returns the first slot on invalid coords / slotnum
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index 1d7cedaa6..03cec9c58 100755
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -692,23 +692,23 @@ cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a
switch (a_BlockType)
{
// Specific entity loaders:
- case E_BLOCK_BEACON: return LoadBeaconFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
- case E_BLOCK_BREWING_STAND: return LoadBrewingstandFromNBT(a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BREWING_STAND, a_BlockMeta);
- case E_BLOCK_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_CHEST);
- case E_BLOCK_COMMAND_BLOCK: return LoadCommandBlockFromNBT(a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
- case E_BLOCK_DISPENSER: return LoadDispenserFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
- case E_BLOCK_DROPPER: return LoadDropperFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
- case E_BLOCK_FLOWER_POT: return LoadFlowerPotFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
- case E_BLOCK_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FURNACE, a_BlockMeta);
- case E_BLOCK_HEAD: return LoadMobHeadFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
- case E_BLOCK_HOPPER: return LoadHopperFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
- case E_BLOCK_JUKEBOX: return LoadJukeboxFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
- case E_BLOCK_LIT_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LIT_FURNACE, a_BlockMeta);
- case E_BLOCK_MOB_SPAWNER: return LoadMobSpawnerFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
- case E_BLOCK_NOTE_BLOCK: return LoadNoteBlockFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
- case E_BLOCK_SIGN_POST: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SIGN_POST);
- case E_BLOCK_TRAPPED_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_TRAPPED_CHEST);
- case E_BLOCK_WALLSIGN: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WALLSIGN);
+ case E_BLOCK_BEACON: return LoadBeaconFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_BREWING_STAND: return LoadBrewingstandFromNBT(a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_COMMAND_BLOCK: return LoadCommandBlockFromNBT(a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_DISPENSER: return LoadDispenserFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_DROPPER: return LoadDropperFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_FLOWER_POT: return LoadFlowerPotFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_HEAD: return LoadMobHeadFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_HOPPER: return LoadHopperFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_JUKEBOX: return LoadJukeboxFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_LIT_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_MOB_SPAWNER: return LoadMobSpawnerFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_NOTE_BLOCK: return LoadNoteBlockFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_SIGN_POST: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_TRAPPED_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_WALLSIGN: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ);
// Blocktypes that have block entities but don't load their contents from disk:
case E_BLOCK_ENDER_CHEST: return nullptr;
@@ -858,7 +858,7 @@ void cWSSAnvil::LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a
-bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType)
+bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the given tag is a compound:
if (a_NBT.GetType(a_TagIdx) != TAG_Compound)
@@ -878,9 +878,10 @@ bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, con
{
return true;
}
- LOGWARNING("Block entity type mismatch: exp \"%s\", got \"%s\".",
+ LOGWARNING("Block entity type mismatch: exp \"%s\", got \"%s\". The block entity at {%d, %d, %d} will lose all its properties.",
a_ExpectedType,
- AString(a_NBT.GetData(TagID), static_cast<size_t>(a_NBT.GetDataLength(TagID))).c_str()
+ AString(a_NBT.GetData(TagID), static_cast<size_t>(a_NBT.GetDataLength(TagID))).c_str(),
+ a_BlockX, a_BlockY, a_BlockZ
);
return false;
}
@@ -889,15 +890,15 @@ bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, con
-cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
+cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Beacon"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Beacon", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
- std::unique_ptr<cBeaconEntity> Beacon = cpp14::make_unique<cBeaconEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World);
+ auto Beacon = cpp14::make_unique<cBeaconEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
int CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Levels");
if (CurrentLine >= 0)
@@ -931,10 +932,10 @@ cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagI
-cBlockEntity * cWSSAnvil::LoadBrewingstandFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+cBlockEntity * cWSSAnvil::LoadBrewingstandFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Brewingstand"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Brewingstand", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
@@ -945,7 +946,7 @@ cBlockEntity * cWSSAnvil::LoadBrewingstandFromNBT(const cParsedNBT & a_NBT, int
return nullptr; // Make it an empty brewingstand - the chunk loader will provide an empty cBrewingstandEntity for this
}
- std::unique_ptr<cBrewingstandEntity> Brewingstand(new cBrewingstandEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World));
+ auto Brewingstand = cpp14::make_unique<cBrewingstandEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
// Fuel has to be loaded at first, because of slot events:
int Fuel = a_NBT.FindChildByName(a_TagIdx, "Fuel");
@@ -988,7 +989,7 @@ cBlockEntity * cWSSAnvil::LoadBrewingstandFromNBT(const cParsedNBT & a_NBT, int
-cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_ChestBlockType)
+cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
// Note that older Cuberite code used "TrappedChest" for trapped chests; new code mimics vanilla and uses "Chest" throughout, but we allow migration here:
@@ -1015,7 +1016,7 @@ cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagId
{
return nullptr; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this
}
- std::unique_ptr<cChestEntity> Chest = cpp14::make_unique<cChestEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World, a_ChestBlockType);
+ auto Chest = cpp14::make_unique<cChestEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
LoadItemGridFromNBT(Chest->GetContents(), a_NBT, Items);
return Chest.release();
}
@@ -1024,15 +1025,15 @@ cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagId
-cBlockEntity * cWSSAnvil::LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
+cBlockEntity * cWSSAnvil::LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Control"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Control", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
- std::unique_ptr<cCommandBlockEntity> CmdBlock = cpp14::make_unique<cCommandBlockEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World);
+ auto CmdBlock = cpp14::make_unique<cCommandBlockEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
int currentLine = a_NBT.FindChildByName(a_TagIdx, "Command");
if (currentLine >= 0)
@@ -1061,10 +1062,10 @@ cBlockEntity * cWSSAnvil::LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int
-cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
+cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Trap"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Trap", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
@@ -1074,7 +1075,7 @@ cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_T
{
return nullptr; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this
}
- std::unique_ptr<cDispenserEntity> Dispenser = cpp14::make_unique<cDispenserEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World);
+ auto Dispenser = cpp14::make_unique<cDispenserEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
LoadItemGridFromNBT(Dispenser->GetContents(), a_NBT, Items);
return Dispenser.release();
}
@@ -1083,10 +1084,10 @@ cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_T
-cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
+cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Dropper"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Dropper", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
@@ -1096,7 +1097,7 @@ cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_Tag
{
return nullptr; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this
}
- std::unique_ptr<cDropperEntity> Dropper = cpp14::make_unique<cDropperEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World);
+ auto Dropper = cpp14::make_unique<cDropperEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
LoadItemGridFromNBT(Dropper->GetContents(), a_NBT, Items);
return Dropper.release();
}
@@ -1105,15 +1106,15 @@ cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_Tag
-cBlockEntity * cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
+cBlockEntity * cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "FlowerPot"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "FlowerPot", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
- std::unique_ptr<cFlowerPotEntity> FlowerPot = cpp14::make_unique<cFlowerPotEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World);
+ auto FlowerPot = cpp14::make_unique<cFlowerPotEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
cItem Item;
int currentLine = a_NBT.FindChildByName(a_TagIdx, "Item");
@@ -1143,10 +1144,10 @@ cBlockEntity * cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_T
-cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Furnace"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Furnace", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
@@ -1157,7 +1158,7 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag
return nullptr; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this
}
- std::unique_ptr<cFurnaceEntity> Furnace = cpp14::make_unique<cFurnaceEntity>(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World);
+ auto Furnace = cpp14::make_unique<cFurnaceEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
Furnace->SetLoading(true);
// Load slots:
@@ -1202,15 +1203,15 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag
-cBlockEntity * cWSSAnvil::LoadMobSpawnerFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
+cBlockEntity * cWSSAnvil::LoadMobSpawnerFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "MobSpawner"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "MobSpawner", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
- std::unique_ptr<cMobSpawnerEntity> MobSpawner = cpp14::make_unique<cMobSpawnerEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World);
+ auto MobSpawner = cpp14::make_unique<cMobSpawnerEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
// Load entity (Cuberite worlds):
int Type = a_NBT.FindChildByName(a_TagIdx, "Entity");
@@ -1250,10 +1251,10 @@ cBlockEntity * cWSSAnvil::LoadMobSpawnerFromNBT(const cParsedNBT & a_NBT, int a_
-cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
+cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Hopper"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Hopper", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
@@ -1263,7 +1264,7 @@ cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagI
{
return nullptr; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this
}
- std::unique_ptr<cHopperEntity> Hopper = cpp14::make_unique<cHopperEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World);
+ auto Hopper = cpp14::make_unique<cHopperEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
LoadItemGridFromNBT(Hopper->GetContents(), a_NBT, Items);
return Hopper.release();
}
@@ -1272,15 +1273,15 @@ cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagI
-cBlockEntity * cWSSAnvil::LoadJukeboxFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
+cBlockEntity * cWSSAnvil::LoadJukeboxFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "RecordPlayer"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "RecordPlayer", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
- std::unique_ptr<cJukeboxEntity> Jukebox = cpp14::make_unique<cJukeboxEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World);
+ auto Jukebox = cpp14::make_unique<cJukeboxEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
int Record = a_NBT.FindChildByName(a_TagIdx, "Record");
if (Record >= 0)
{
@@ -1293,15 +1294,15 @@ cBlockEntity * cWSSAnvil::LoadJukeboxFromNBT(const cParsedNBT & a_NBT, int a_Tag
-cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
+cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Skull"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Skull", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
- std::unique_ptr<cMobHeadEntity> MobHead = cpp14::make_unique<cMobHeadEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World);
+ auto MobHead = cpp14::make_unique<cMobHeadEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
int currentLine = a_NBT.FindChildByName(a_TagIdx, "SkullType");
if (currentLine >= 0)
@@ -1365,15 +1366,15 @@ cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_Tag
-cBlockEntity * cWSSAnvil::LoadNoteBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
+cBlockEntity * cWSSAnvil::LoadNoteBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Music"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Music", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
- std::unique_ptr<cNoteEntity> NoteBlock = cpp14::make_unique<cNoteEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World);
+ auto NoteBlock = cpp14::make_unique<cNoteEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
int note = a_NBT.FindChildByName(a_TagIdx, "note");
if (note >= 0)
{
@@ -1386,15 +1387,15 @@ cBlockEntity * cWSSAnvil::LoadNoteBlockFromNBT(const cParsedNBT & a_NBT, int a_T
-cBlockEntity * cWSSAnvil::LoadSignFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType)
+cBlockEntity * cWSSAnvil::LoadSignFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Check if the data has a proper type:
- if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Sign"))
+ if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Sign", a_BlockX, a_BlockY, a_BlockZ))
{
return nullptr;
}
- std::unique_ptr<cSignEntity> Sign = cpp14::make_unique<cSignEntity>(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, m_World);
+ auto Sign = cpp14::make_unique<cSignEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
int currentLine = a_NBT.FindChildByName(a_TagIdx, "Text1");
if (currentLine >= 0)
diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h
index 86fdc8189..f9f43305b 100755
--- a/src/WorldStorage/WSSAnvil.h
+++ b/src/WorldStorage/WSSAnvil.h
@@ -145,23 +145,25 @@ protected:
Slots outside the ItemGrid range are ignored */
void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0);
- /** Returns true iff the "id" child tag inside the specified tag equals the specified expected type. */
- bool CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType);
-
- cBlockEntity * LoadBeaconFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
- cBlockEntity * LoadBrewingstandFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
- cBlockEntity * LoadChestFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_ChestBlockType);
- cBlockEntity * LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
- cBlockEntity * LoadDispenserFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
- cBlockEntity * LoadDropperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
- cBlockEntity * LoadFlowerPotFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
- cBlockEntity * LoadFurnaceFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
- cBlockEntity * LoadMobSpawnerFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
- cBlockEntity * LoadHopperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
- cBlockEntity * LoadJukeboxFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
- cBlockEntity * LoadMobHeadFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
- cBlockEntity * LoadNoteBlockFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
- cBlockEntity * LoadSignFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SignBlockType);
+ /** Returns true iff the "id" child tag inside the specified tag equals the specified expected type.
+ Logs a warning to the console on mismatch.
+ The coordinates are used only for the log message. */
+ bool CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType, int a_BlockX, int a_BlockY, int a_BlockZ);
+
+ cBlockEntity * LoadBeaconFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadBrewingstandFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadChestFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadDispenserFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadDropperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadFlowerPotFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadFurnaceFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadMobSpawnerFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadHopperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadJukeboxFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadMobHeadFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadNoteBlockFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
+ cBlockEntity * LoadSignFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, size_t a_IDTagLength);