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(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(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(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(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(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(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(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(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(); - } - - if (Window != nullptr) - { - if (a_Player->GetWindow() != Window) - { - a_Player->OpenWindow(*Window); - } - } - - UpdateProgressBars(true); - return true; + m_IsDestroyed = true; + Super::Destroy(); } -bool cFurnaceEntity::ContinueCooking(void) +void cFurnaceEntity::CopyFrom(const cBlockEntity & a_Src) { - UpdateInput(); - UpdateFuel(); - return m_IsCooking; + Super::CopyFrom(a_Src); + auto & src = reinterpret_cast(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; +} + + + + + +void cFurnaceEntity::SendTo(cClientHandle & a_Client) +{ + // 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(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(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(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(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(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(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(a_NBT.GetDataLength(TagID))).c_str() + AString(a_NBT.GetData(TagID), static_cast(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 Beacon = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, m_World); + auto Beacon = cpp14::make_unique(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 Brewingstand(new cBrewingstandEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World)); + auto Brewingstand = cpp14::make_unique(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 Chest = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, m_World, a_ChestBlockType); + auto Chest = cpp14::make_unique(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 CmdBlock = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, m_World); + auto CmdBlock = cpp14::make_unique(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 Dispenser = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, m_World); + auto Dispenser = cpp14::make_unique(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 Dropper = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, m_World); + auto Dropper = cpp14::make_unique(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 FlowerPot = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, m_World); + auto FlowerPot = cpp14::make_unique(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 Furnace = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World); + auto Furnace = cpp14::make_unique(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 MobSpawner = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, m_World); + auto MobSpawner = cpp14::make_unique(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 Hopper = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, m_World); + auto Hopper = cpp14::make_unique(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 Jukebox = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, m_World); + auto Jukebox = cpp14::make_unique(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 MobHead = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, m_World); + auto MobHead = cpp14::make_unique(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 NoteBlock = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, m_World); + auto NoteBlock = cpp14::make_unique(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 Sign = cpp14::make_unique(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, m_World); + auto Sign = cpp14::make_unique(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); + /** 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, 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); + 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);