Added hopper entity, it can suck items out of chests, dispensers, droppers and other hopppers above it.
git-svn-id: http://mc-server.googlecode.com/svn/trunk@1587 0a769ca7-a7f5-676a-18bf-c427514a06d6master
parent
732190e9f9
commit
03c6bb9f85
|
@ -2356,6 +2356,14 @@
|
|||
RelativePath="..\source\BlockEntities\FurnaceEntity.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\BlockEntities\HopperEntity.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\BlockEntities\HopperEntity.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\BlockEntities\JukeboxEntity.cpp"
|
||||
>
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
|
||||
// HopperEntity.cpp
|
||||
|
||||
// Implements the cHopperEntity representing a hopper block entity
|
||||
|
||||
#include "Globals.h"
|
||||
#include "HopperEntity.h"
|
||||
#include "../Chunk.h"
|
||||
#include "../Player.h"
|
||||
#include "ChestEntity.h"
|
||||
#include "DropSpenserEntity.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cHopperEntity::cHopperEntity(int a_BlockX, int a_BlockY, int a_BlockZ) :
|
||||
super(E_BLOCK_HOPPER, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cHopperEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cHopperEntity::SaveToJson(Json::Value & a_Value)
|
||||
{
|
||||
// TODO
|
||||
LOGWARNING("%s: Not implemented yet", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cHopperEntity::SendTo(cClientHandle & a_Client)
|
||||
{
|
||||
// The hopper entity doesn't need anything sent to the client when it's created / gets in the viewdistance
|
||||
// All the actual handling is in the cWindow UI code that gets called when the hopper is rclked
|
||||
|
||||
UNUSED(a_Client);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cHopperEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
// If the window is not created, open it anew:
|
||||
cWindow * Window = GetWindow();
|
||||
if (Window == NULL)
|
||||
{
|
||||
OpenNewWindow();
|
||||
Window = GetWindow();
|
||||
}
|
||||
|
||||
// Open the window for the player:
|
||||
if (Window != NULL)
|
||||
{
|
||||
if (a_Player->GetWindow() != Window)
|
||||
{
|
||||
a_Player->OpenWindow(Window);
|
||||
}
|
||||
}
|
||||
|
||||
// This is rather a hack
|
||||
// Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now
|
||||
// We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first.
|
||||
// The few false positives aren't much to worry about
|
||||
int ChunkX, ChunkZ;
|
||||
cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ);
|
||||
m_World->MarkChunkDirty(ChunkX, ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Opens a new window UI for this hopper
|
||||
void cHopperEntity::OpenNewWindow(void)
|
||||
{
|
||||
OpenWindow(new cHopperWindow(m_PosX, m_PosY, m_PosZ, this));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Moves items from the container above it into this hopper. Returns true if the contents have changed.
|
||||
bool cHopperEntity::MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
|
||||
{
|
||||
if (m_PosY >= cChunkDef::Height)
|
||||
{
|
||||
// This hopper is at the top of the world, no more blocks above
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a_CurrentTick - m_LastMoveItemsInTick < TICKS_PER_TRANSFER)
|
||||
{
|
||||
// Too early after the previous transfer
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try moving an item in:
|
||||
bool res = false;
|
||||
switch (a_Chunk.GetBlock(m_RelX, m_PosY + 1, m_RelZ))
|
||||
{
|
||||
case E_BLOCK_CHEST: res = MoveItemsFromChest(a_Chunk); break;
|
||||
case E_BLOCK_FURNACE: res = MoveItemsFromFurnace(a_Chunk); break;
|
||||
case E_BLOCK_DISPENSER:
|
||||
case E_BLOCK_DROPPER: res = MoveItemsFromGrid(((cDropSpenserEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ))->GetContents()); break;
|
||||
case E_BLOCK_HOPPER: res = MoveItemsFromGrid(((cHopperEntity *) a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ))->GetContents()); break;
|
||||
}
|
||||
|
||||
// If the item has been moved, reset the last tick:
|
||||
if (res)
|
||||
{
|
||||
m_LastMoveItemsInTick = a_CurrentTick;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Moves pickups from above this hopper into it. Returns true if the contents have changed.
|
||||
bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Moves items out from this hopper into the destination. Returns true if the contents have changed.
|
||||
bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
|
||||
{
|
||||
if (a_CurrentTick - m_LastMoveItemsOutTick < TICKS_PER_TRANSFER)
|
||||
{
|
||||
// Too early after the previous transfer
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Moves items from a chest (dblchest) above the hopper into this hopper. Returns true if contents have changed.
|
||||
bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
|
||||
{
|
||||
if (MoveItemsFromGrid(((cChestEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ))->GetContents()))
|
||||
{
|
||||
// Moved the item from the chest directly above the hopper
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the chest is a double-chest, if so, try to move from there:
|
||||
static const struct
|
||||
{
|
||||
int x, z;
|
||||
}
|
||||
Coords [] =
|
||||
{
|
||||
{1, 0},
|
||||
{-1, 0},
|
||||
{0, 1},
|
||||
{0, -1},
|
||||
} ;
|
||||
for (int i = 0; i < ARRAYCOUNT(Coords); i++)
|
||||
{
|
||||
int x = m_RelX + Coords[i].x;
|
||||
int z = m_RelZ + Coords[i].z;
|
||||
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z);
|
||||
if (
|
||||
(Neighbor == NULL) ||
|
||||
(Neighbor->GetBlock(x, m_PosY + 1, z) != E_BLOCK_CHEST)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (MoveItemsFromGrid(((cChestEntity *)Neighbor->GetBlockEntity(x, m_PosY, z))->GetContents()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// The chest was single and nothing could be moved
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Moves items from a furnace above the hopper into this hopper. Returns true if contents have changed.
|
||||
bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk)
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Moves items from the specified ItemGrid into this hopper. Returns true if contents have changed.
|
||||
bool cHopperEntity::MoveItemsFromGrid(cItemGrid & a_Grid)
|
||||
{
|
||||
int NumSlots = a_Grid.GetNumSlots();
|
||||
|
||||
// First try adding items of types already in the hopper:
|
||||
for (int i = 0; i < NumSlots; i++)
|
||||
{
|
||||
if (a_Grid.IsSlotEmpty(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (MoveItemsFromSlot(a_Grid.GetSlot(i), false))
|
||||
{
|
||||
a_Grid.ChangeSlotCount(i, -1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// No already existing stack can be topped up, try again with allowing new stacks:
|
||||
for (int i = 0; i < NumSlots; i++)
|
||||
{
|
||||
if (a_Grid.IsSlotEmpty(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (MoveItemsFromSlot(a_Grid.GetSlot(i), true))
|
||||
{
|
||||
a_Grid.ChangeSlotCount(i, -1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Moves one of the specified itemstack into this hopper. Returns true if contents have changed. Doesn't change the itemstack.
|
||||
bool cHopperEntity::MoveItemsFromSlot(const cItem & a_ItemStack, bool a_AllowNewStacks)
|
||||
{
|
||||
if (m_Contents.AddItem(a_ItemStack.CopyOne(), a_AllowNewStacks) > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
// HopperEntity.h
|
||||
|
||||
// Declares the cHopperEntity representing a hopper block entity
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockEntityWithItems.h"
|
||||
#include "../UI/WindowOwner.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cHopperEntity : // tolua_export
|
||||
public cBlockEntityWindowOwner,
|
||||
// tolua_begin
|
||||
public cBlockEntityWithItems
|
||||
{
|
||||
typedef cBlockEntityWithItems super;
|
||||
|
||||
public:
|
||||
enum {
|
||||
ContentsHeight = 1,
|
||||
ContentsWidth = 5,
|
||||
TICKS_PER_TRANSFER = 8, ///< How many ticks at minimum between two item transfers to or from the hopper
|
||||
} ;
|
||||
|
||||
/// Constructor used while generating a chunk; sets m_World to NULL
|
||||
cHopperEntity(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
// tolua_end
|
||||
|
||||
/// Constructor used for normal operation
|
||||
cHopperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
|
||||
|
||||
static const char * GetClassStatic(void) { return "cHopperEntity"; }
|
||||
|
||||
protected:
|
||||
|
||||
Int64 m_LastMoveItemsInTick;
|
||||
Int64 m_LastMoveItemsOutTick;
|
||||
|
||||
// cBlockEntity overrides:
|
||||
virtual bool Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void SaveToJson(Json::Value & a_Value) override;
|
||||
virtual void SendTo(cClientHandle & a_Client) override;
|
||||
virtual void UsedBy(cPlayer * a_Player) override;
|
||||
|
||||
/// Opens a new chest window for this chest. Scans for neighbors to open a double chest window, if appropriate.
|
||||
void OpenNewWindow(void);
|
||||
|
||||
/// Moves items from the container above it into this hopper. Returns true if the contents have changed.
|
||||
bool MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick);
|
||||
|
||||
/// Moves pickups from above this hopper into it. Returns true if the contents have changed.
|
||||
bool MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick);
|
||||
|
||||
/// Moves items out from this hopper into the destination. Returns true if the contents have changed.
|
||||
bool MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick);
|
||||
|
||||
/// Moves items from a chest (dblchest) above the hopper into this hopper. Returns true if contents have changed.
|
||||
bool MoveItemsFromChest(cChunk & a_Chunk);
|
||||
|
||||
/// Moves items from a furnace above the hopper into this hopper. Returns true if contents have changed.
|
||||
bool MoveItemsFromFurnace(cChunk & a_Chunk);
|
||||
|
||||
/// Moves items from the specified ItemGrid into this hopper. Returns true if contents have changed.
|
||||
bool MoveItemsFromGrid(cItemGrid & a_Grid);
|
||||
|
||||
/// Moves one of the specified itemstack into this hopper. Returns true if contents have changed. Doesn't change the itemstack.
|
||||
bool MoveItemsFromSlot(const cItem & a_ItemStack, bool a_AllowNewStacks);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
#include "BlockEntities/DispenserEntity.h"
|
||||
#include "BlockEntities/DropperEntity.h"
|
||||
#include "BlockEntities/FurnaceEntity.h"
|
||||
#include "BlockEntities/HopperEntity.h"
|
||||
#include "BlockEntities/JukeboxEntity.h"
|
||||
#include "BlockEntities/NoteEntity.h"
|
||||
#include "BlockEntities/SignEntity.h"
|
||||
|
@ -1222,7 +1223,7 @@ void cChunk::CreateBlockEntities(void)
|
|||
{
|
||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
||||
{
|
||||
m_BlockEntities.push_back( new cChestEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
|
||||
m_BlockEntities.push_back(new cChestEntity(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1231,7 +1232,7 @@ void cChunk::CreateBlockEntities(void)
|
|||
{
|
||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
||||
{
|
||||
m_BlockEntities.push_back( new cDispenserEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
|
||||
m_BlockEntities.push_back(new cDispenserEntity(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1249,17 +1250,25 @@ void cChunk::CreateBlockEntities(void)
|
|||
{
|
||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
||||
{
|
||||
m_BlockEntities.push_back( new cFurnaceEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
|
||||
m_BlockEntities.push_back(new cFurnaceEntity(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_BLOCK_HOPPER:
|
||||
{
|
||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
||||
{
|
||||
m_BlockEntities.push_back(new cHopperEntity(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World));
|
||||
}
|
||||
}
|
||||
|
||||
case E_BLOCK_SIGN_POST:
|
||||
case E_BLOCK_WALLSIGN:
|
||||
{
|
||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
||||
{
|
||||
m_BlockEntities.push_back( new cSignEntity( BlockType, x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
|
||||
m_BlockEntities.push_back( new cSignEntity(BlockType, x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1268,7 +1277,7 @@ void cChunk::CreateBlockEntities(void)
|
|||
{
|
||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
||||
{
|
||||
m_BlockEntities.push_back(new cNoteEntity(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
|
||||
m_BlockEntities.push_back(new cNoteEntity(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1277,7 +1286,7 @@ void cChunk::CreateBlockEntities(void)
|
|||
{
|
||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
||||
{
|
||||
m_BlockEntities.push_back(new cJukeboxEntity(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
|
||||
m_BlockEntities.push_back(new cJukeboxEntity(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1434,28 +1443,33 @@ void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType
|
|||
{
|
||||
case E_BLOCK_CHEST:
|
||||
{
|
||||
AddBlockEntity( new cChestEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) );
|
||||
AddBlockEntity(new cChestEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World));
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_DISPENSER:
|
||||
{
|
||||
AddBlockEntity( new cDispenserEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) );
|
||||
AddBlockEntity(new cDispenserEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World));
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_DROPPER:
|
||||
{
|
||||
AddBlockEntity( new cDropperEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) );
|
||||
AddBlockEntity(new cDropperEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World));
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_FURNACE:
|
||||
{
|
||||
AddBlockEntity( new cFurnaceEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) );
|
||||
AddBlockEntity(new cFurnaceEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World));
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_HOPPER:
|
||||
{
|
||||
AddBlockEntity(new cHopperEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World));
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_SIGN_POST:
|
||||
case E_BLOCK_WALLSIGN:
|
||||
{
|
||||
AddBlockEntity( new cSignEntity( (ENUM_BLOCK_ID)a_BlockType, WorldPos.x, WorldPos.y, WorldPos.z, m_World) );
|
||||
AddBlockEntity(new cSignEntity(a_BlockType, WorldPos.x, WorldPos.y, WorldPos.z, m_World));
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_NOTE_BLOCK:
|
||||
|
|
|
@ -310,6 +310,9 @@ public:
|
|||
cFluidSimulatorData * GetLavaSimulatorData (void) { return m_LavaSimulatorData; }
|
||||
cSandSimulatorChunkData & GetSandSimulatorData (void) { return m_SandSimulatorData; }
|
||||
|
||||
cBlockEntity * GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * GetBlockEntity(const Vector3i & a_BlockPos) { return GetBlockEntity(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); }
|
||||
|
||||
private:
|
||||
|
||||
friend class cChunkMap;
|
||||
|
@ -362,8 +365,6 @@ private:
|
|||
|
||||
void RemoveBlockEntity(cBlockEntity * a_BlockEntity);
|
||||
void AddBlockEntity (cBlockEntity * a_BlockEntity);
|
||||
cBlockEntity * GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * GetBlockEntity(const Vector3i & a_BlockPos) { return GetBlockEntity(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); }
|
||||
|
||||
void SpreadLightOfBlock(NIBBLETYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff);
|
||||
|
||||
|
|
|
@ -616,9 +616,13 @@ void cItemGrid::RemoveListener(cListener & a_Listener)
|
|||
|
||||
void cItemGrid::TriggerListeners(int a_SlotNum)
|
||||
{
|
||||
cCSLock Lock(m_CSListeners);
|
||||
m_IsInTriggerListeners = true;
|
||||
for (cListeners::iterator itr = m_Listeners.begin(), end = m_Listeners.end(); itr != end; ++itr)
|
||||
cListeners Listeners;
|
||||
{
|
||||
cCSLock Lock(m_CSListeners);
|
||||
m_IsInTriggerListeners = true;
|
||||
Listeners = m_Listeners;
|
||||
}
|
||||
for (cListeners::iterator itr = Listeners.begin(), end = Listeners.end(); itr != end; ++itr)
|
||||
{
|
||||
(*itr)->OnSlotChanged(this, a_SlotNum);
|
||||
} // for itr - m_Listeners[]
|
||||
|
|
|
@ -665,6 +665,16 @@ cSlotAreaItemGrid::cSlotAreaItemGrid(cItemGrid & a_ItemGrid, cWindow & a_ParentW
|
|||
super(a_ItemGrid.GetNumSlots(), a_ParentWindow),
|
||||
m_ItemGrid(a_ItemGrid)
|
||||
{
|
||||
m_ItemGrid.AddListener(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cSlotAreaItemGrid::~cSlotAreaItemGrid()
|
||||
{
|
||||
m_ItemGrid.RemoveListener(*this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -689,6 +699,16 @@ void cSlotAreaItemGrid::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem &
|
|||
|
||||
|
||||
|
||||
void cSlotAreaItemGrid::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
|
||||
{
|
||||
ASSERT(a_ItemGrid == &m_ItemGrid);
|
||||
m_ParentWindow.BroadcastSlot(this, a_SlotNum);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cSlotAreaTemporary:
|
||||
|
||||
|
|
|
@ -143,18 +143,24 @@ public:
|
|||
|
||||
/// Handles any slot area that is representing a cItemGrid; same items for all the players
|
||||
class cSlotAreaItemGrid :
|
||||
public cSlotArea
|
||||
public cSlotArea,
|
||||
public cItemGrid::cListener
|
||||
{
|
||||
typedef cSlotArea super;
|
||||
|
||||
public:
|
||||
cSlotAreaItemGrid(cItemGrid & a_ItemGrid, cWindow & a_ParentWindow);
|
||||
|
||||
virtual ~cSlotAreaItemGrid();
|
||||
|
||||
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
|
||||
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
|
||||
|
||||
protected:
|
||||
cItemGrid & m_ItemGrid;
|
||||
|
||||
// cItemGrid::cListener overrides:
|
||||
virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "../Inventory.h"
|
||||
#include "../Items/ItemHandler.h"
|
||||
#include "../BlockEntities/ChestEntity.h"
|
||||
#include "../BlockEntities/HopperEntity.h"
|
||||
|
||||
|
||||
|
||||
|
@ -607,6 +608,40 @@ int cWindow::DistributeItemToSlots(cPlayer & a_Player, const cItem & a_Item, int
|
|||
|
||||
|
||||
|
||||
void cWindow::BroadcastSlot(cSlotArea * a_Area, int a_LocalSlotNum)
|
||||
{
|
||||
// Translate local slot num into global slot num:
|
||||
int SlotNum = 0;
|
||||
bool HasFound = false;
|
||||
for (cSlotAreas::const_iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr)
|
||||
{
|
||||
if (a_Area == *itr)
|
||||
{
|
||||
SlotNum += a_LocalSlotNum;
|
||||
HasFound = true;
|
||||
break;
|
||||
}
|
||||
SlotNum += (*itr)->GetNumSlots();
|
||||
} // for itr - m_SlotAreas[]
|
||||
if (!HasFound)
|
||||
{
|
||||
LOGWARNING("%s: Invalid slot area parameter", __FUNCTION__);
|
||||
ASSERT(!"Invalid slot area");
|
||||
return;
|
||||
}
|
||||
|
||||
// Broadcast the update packet:
|
||||
cCSLock Lock(m_CS);
|
||||
for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr)
|
||||
{
|
||||
(*itr)->GetClientHandle()->SendInventorySlot(m_WindowID, SlotNum, *a_Area->GetSlot(a_LocalSlotNum, **itr));
|
||||
} // for itr - m_OpenedBy[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWindow::SendWholeWindow(cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendWholeInventory(*this);
|
||||
|
@ -741,6 +776,7 @@ cChestWindow::~cChestWindow()
|
|||
cDropSpenserWindow::cDropSpenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserEntity * a_DropSpenser) :
|
||||
cWindow(cWindow::DropSpenser, "MCS-DropSpenser")
|
||||
{
|
||||
m_ShouldDistributeToHotbarFirst = false;
|
||||
m_SlotAreas.push_back(new cSlotAreaDropSpenser(a_DropSpenser, *this));
|
||||
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
||||
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
|
||||
|
@ -750,12 +786,29 @@ cDropSpenserWindow::cDropSpenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ,
|
|||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cHopperWindow:
|
||||
|
||||
cHopperWindow::cHopperWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cHopperEntity * a_Hopper) :
|
||||
super(cWindow::Hopper, "MCS-Hopper")
|
||||
{
|
||||
m_ShouldDistributeToHotbarFirst = false;
|
||||
m_SlotAreas.push_back(new cSlotAreaItemGrid(a_Hopper->GetContents(), *this));
|
||||
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
||||
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cFurnaceWindow:
|
||||
|
||||
cFurnaceWindow::cFurnaceWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceEntity * a_Furnace) :
|
||||
cWindow(cWindow::Furnace, "MCS-Furnace")
|
||||
{
|
||||
m_ShouldDistributeToHotbarFirst = false;
|
||||
m_SlotAreas.push_back(new cSlotAreaFurnace(a_Furnace, *this));
|
||||
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
||||
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
|
||||
|
|
|
@ -21,6 +21,7 @@ class cClientHandle;
|
|||
class cChestEntity;
|
||||
class cDropSpenserEntity;
|
||||
class cFurnaceEntity;
|
||||
class cHopperEntity;
|
||||
class cSlotArea;
|
||||
class cWorld;
|
||||
|
||||
|
@ -110,8 +111,16 @@ public:
|
|||
/// Called when a player closes this window; notifies all slot areas. Returns true if close accepted
|
||||
virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse);
|
||||
|
||||
/// Sends the specified slot's contents to all clients of this window; the slot is specified as local in an area
|
||||
void BroadcastSlot(cSlotArea * a_Area, int a_LocalSlotNum);
|
||||
|
||||
/// Sends the contents of the whole window to the specified client
|
||||
void SendWholeWindow(cClientHandle & a_Client);
|
||||
|
||||
/// Sends the contents of the whole window to all clients of this window.
|
||||
void BroadcastWholeWindow(void);
|
||||
|
||||
/// Sends the progressbar to all clients of this window
|
||||
void BroadcastInventoryProgress(short a_Progressbar, short a_Value);
|
||||
|
||||
// tolua_begin
|
||||
|
@ -194,6 +203,7 @@ protected:
|
|||
class cCraftingWindow :
|
||||
public cWindow
|
||||
{
|
||||
typedef cWindow super;
|
||||
public:
|
||||
cCraftingWindow(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
} ;
|
||||
|
@ -205,6 +215,7 @@ public:
|
|||
class cFurnaceWindow :
|
||||
public cWindow
|
||||
{
|
||||
typedef cWindow super;
|
||||
public:
|
||||
cFurnaceWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceEntity * a_Furnace);
|
||||
} ;
|
||||
|
@ -216,6 +227,7 @@ public:
|
|||
class cDropSpenserWindow :
|
||||
public cWindow
|
||||
{
|
||||
typedef cWindow super;
|
||||
public:
|
||||
cDropSpenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserEntity * a_Dispenser);
|
||||
} ;
|
||||
|
@ -224,6 +236,18 @@ public:
|
|||
|
||||
|
||||
|
||||
class cHopperWindow :
|
||||
public cWindow
|
||||
{
|
||||
typedef cWindow super;
|
||||
public:
|
||||
cHopperWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cHopperEntity * a_Hopper);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cChestWindow :
|
||||
public cWindow
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "../BlockEntities/DispenserEntity.h"
|
||||
#include "../BlockEntities/DropperEntity.h"
|
||||
#include "../BlockEntities/FurnaceEntity.h"
|
||||
#include "../BlockEntities/HopperEntity.h"
|
||||
#include "../BlockEntities/JukeboxEntity.h"
|
||||
#include "../BlockEntities/NoteEntity.h"
|
||||
#include "../BlockEntities/SignEntity.h"
|
||||
|
@ -175,14 +176,25 @@ void cNBTChunkSerializer::AddFurnaceEntity(cFurnaceEntity * a_Furnace)
|
|||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddSignEntity(cSignEntity * a_Sign)
|
||||
void cNBTChunkSerializer::AddHopperEntity(cHopperEntity * a_Entity)
|
||||
{
|
||||
m_Writer.BeginCompound("");
|
||||
AddBasicTileEntity(a_Sign, "Sign");
|
||||
m_Writer.AddString("Text1", a_Sign->GetLine(0));
|
||||
m_Writer.AddString("Text2", a_Sign->GetLine(1));
|
||||
m_Writer.AddString("Text3", a_Sign->GetLine(2));
|
||||
m_Writer.AddString("Text4", a_Sign->GetLine(3));
|
||||
AddBasicTileEntity(a_Entity, "Hopper");
|
||||
m_Writer.BeginList("Items", TAG_Compound);
|
||||
AddItemGrid(a_Entity->GetContents());
|
||||
m_Writer.EndList();
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddJukeboxEntity(cJukeboxEntity * a_Jukebox)
|
||||
{
|
||||
m_Writer.BeginCompound("");
|
||||
AddBasicTileEntity(a_Jukebox, "RecordPlayer");
|
||||
m_Writer.AddInt("Record", a_Jukebox->GetRecord());
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
|
||||
|
@ -202,11 +214,14 @@ void cNBTChunkSerializer::AddNoteEntity(cNoteEntity * a_Note)
|
|||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddJukeboxEntity(cJukeboxEntity * a_Jukebox)
|
||||
void cNBTChunkSerializer::AddSignEntity(cSignEntity * a_Sign)
|
||||
{
|
||||
m_Writer.BeginCompound("");
|
||||
AddBasicTileEntity(a_Jukebox, "RecordPlayer");
|
||||
m_Writer.AddInt("Record", a_Jukebox->GetRecord());
|
||||
AddBasicTileEntity(a_Sign, "Sign");
|
||||
m_Writer.AddString("Text1", a_Sign->GetLine(0));
|
||||
m_Writer.AddString("Text2", a_Sign->GetLine(1));
|
||||
m_Writer.AddString("Text3", a_Sign->GetLine(2));
|
||||
m_Writer.AddString("Text4", a_Sign->GetLine(3));
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
|
||||
|
@ -428,6 +443,7 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity)
|
|||
case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break;
|
||||
case E_BLOCK_DROPPER: AddDropperEntity ((cDropperEntity *) a_Entity); break;
|
||||
case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break;
|
||||
case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break;
|
||||
case E_BLOCK_SIGN_POST:
|
||||
case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break;
|
||||
case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break;
|
||||
|
|
|
@ -20,12 +20,13 @@ class cFastNBTWriter;
|
|||
class cEntity;
|
||||
class cBlockEntity;
|
||||
class cChestEntity;
|
||||
class cFurnaceEntity;
|
||||
class cDispenserEntity;
|
||||
class cDropperEntity;
|
||||
class cSignEntity;
|
||||
class cNoteEntity;
|
||||
class cFurnaceEntity;
|
||||
class cHopperEntity;
|
||||
class cJukeboxEntity;
|
||||
class cNoteEntity;
|
||||
class cSignEntity;
|
||||
class cFallingBlock;
|
||||
class cMinecart;
|
||||
class cMinecartWithChest;
|
||||
|
@ -78,17 +79,18 @@ protected:
|
|||
void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0);
|
||||
|
||||
// Block entities:
|
||||
void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID);
|
||||
void AddChestEntity(cChestEntity * a_Entity);
|
||||
void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID);
|
||||
void AddChestEntity (cChestEntity * a_Entity);
|
||||
void AddDispenserEntity(cDispenserEntity * a_Entity);
|
||||
void AddDropperEntity(cDropperEntity * a_Entity);
|
||||
void AddFurnaceEntity(cFurnaceEntity * a_Furnace);
|
||||
void AddSignEntity(cSignEntity * a_Sign);
|
||||
void AddNoteEntity(cNoteEntity * a_Note);
|
||||
void AddJukeboxEntity(cJukeboxEntity * a_Jukebox);
|
||||
void AddBasicEntity(cEntity * a_Entity, const AString & a_ClassName);
|
||||
void AddDropperEntity (cDropperEntity * a_Entity);
|
||||
void AddFurnaceEntity (cFurnaceEntity * a_Furnace);
|
||||
void AddHopperEntity (cHopperEntity * a_Entity);
|
||||
void AddJukeboxEntity (cJukeboxEntity * a_Jukebox);
|
||||
void AddNoteEntity (cNoteEntity * a_Note);
|
||||
void AddSignEntity (cSignEntity * a_Sign);
|
||||
|
||||
// Entities:
|
||||
void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName);
|
||||
void AddFallingBlockEntity(cFallingBlock * a_FallingBlock);
|
||||
void AddMinecartEntity (cMinecart * a_Minecart);
|
||||
void AddMonsterEntity (cMonster * a_Monster);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "../BlockEntities/DispenserEntity.h"
|
||||
#include "../BlockEntities/DropperEntity.h"
|
||||
#include "../BlockEntities/FurnaceEntity.h"
|
||||
#include "../BlockEntities/HopperEntity.h"
|
||||
#include "../BlockEntities/JukeboxEntity.h"
|
||||
#include "../BlockEntities/NoteEntity.h"
|
||||
#include "../BlockEntities/SignEntity.h"
|
||||
|
@ -568,6 +569,10 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
|
|||
{
|
||||
LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child);
|
||||
}
|
||||
else if (strncmp(a_NBT.GetData(sID), "Hopper", a_NBT.GetDataLength(sID)) == 0)
|
||||
{
|
||||
LoadHopperFromNBT(a_BlockEntities, a_NBT, Child);
|
||||
}
|
||||
else if (strncmp(a_NBT.GetData(sID), "Music", a_NBT.GetDataLength(sID)) == 0)
|
||||
{
|
||||
LoadNoteFromNBT(a_BlockEntities, a_NBT, Child);
|
||||
|
@ -721,7 +726,7 @@ void cWSSAnvil::LoadDropperFromNBT(cBlockEntityList & a_BlockEntities, const cPa
|
|||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||
{
|
||||
return; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this
|
||||
return; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this
|
||||
}
|
||||
std::auto_ptr<cDropperEntity> Dropper(new cDropperEntity(x, y, z, m_World));
|
||||
LoadItemGridFromNBT(Dropper->GetContents(), a_NBT, Items);
|
||||
|
@ -781,6 +786,70 @@ void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cPa
|
|||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadHopperFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
||||
int x, y, z;
|
||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||
{
|
||||
return; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this
|
||||
}
|
||||
std::auto_ptr<cHopperEntity> Hopper(new cHopperEntity(x, y, z, m_World));
|
||||
LoadItemGridFromNBT(Hopper->GetContents(), a_NBT, Items);
|
||||
a_BlockEntities.push_back(Hopper.release());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadJukeboxFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
||||
int x, y, z;
|
||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::auto_ptr<cJukeboxEntity> Jukebox(new cJukeboxEntity(x, y, z, m_World));
|
||||
int Record = a_NBT.FindChildByName(a_TagIdx, "Record");
|
||||
if (Record >= 0)
|
||||
{
|
||||
Jukebox->SetRecord(a_NBT.GetInt(Record));
|
||||
}
|
||||
a_BlockEntities.push_back(Jukebox.release());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadNoteFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
||||
int x, y, z;
|
||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::auto_ptr<cNoteEntity> Note(new cNoteEntity(x, y, z, m_World));
|
||||
int note = a_NBT.FindChildByName(a_TagIdx, "note");
|
||||
if (note >= 0)
|
||||
{
|
||||
Note->SetPitch(a_NBT.GetByte(note));
|
||||
}
|
||||
a_BlockEntities.push_back(Note.release());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadSignFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
||||
|
@ -821,47 +890,6 @@ void cWSSAnvil::LoadSignFromNBT(cBlockEntityList & a_BlockEntities, const cParse
|
|||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadNoteFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
||||
int x, y, z;
|
||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::auto_ptr<cNoteEntity> Note(new cNoteEntity(x, y, z, m_World));
|
||||
int note = a_NBT.FindChildByName(a_TagIdx, "note");
|
||||
if (note >= 0)
|
||||
{
|
||||
Note->SetPitch(a_NBT.GetByte(note));
|
||||
}
|
||||
a_BlockEntities.push_back(Note.release());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadJukeboxFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
||||
int x, y, z;
|
||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::auto_ptr<cJukeboxEntity> Jukebox(new cJukeboxEntity(x, y, z, m_World));
|
||||
int Record = a_NBT.FindChildByName(a_TagIdx, "Record");
|
||||
if (Record >= 0)
|
||||
{
|
||||
Jukebox->SetRecord(a_NBT.GetInt(Record));
|
||||
}
|
||||
a_BlockEntities.push_back(Jukebox.release());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength)
|
||||
{
|
||||
|
|
|
@ -131,9 +131,10 @@ protected:
|
|||
void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadDropperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadFurnaceFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadHopperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadJukeboxFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength);
|
||||
|
||||
|
|
Loading…
Reference in New Issue