BlockEntities: Support cloning self.
This commit is contained in:
parent
49e015b8de
commit
0dd1cd750b
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
72
src/BlockEntities/BlockEntityWithItems.cpp
Normal file
72
src/BlockEntities/BlockEntityWithItems.cpp
Normal file
@ -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());
|
||||
}
|
||||
}
|
@ -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
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -5,6 +5,7 @@ include_directories ("${PROJECT_SOURCE_DIR}/../")
|
||||
SET (SRCS
|
||||
BeaconEntity.cpp
|
||||
BlockEntity.cpp
|
||||
BlockEntityWithItems.cpp
|
||||
BrewingstandEntity.cpp
|
||||
ChestEntity.cpp
|
||||
CommandBlockEntity.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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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())
|
||||
|
@ -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 {}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 {}
|
||||
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user