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-c427514a06d6
This commit is contained in:
parent
732190e9f9
commit
03c6bb9f85
@ -2356,6 +2356,14 @@
|
|||||||
RelativePath="..\source\BlockEntities\FurnaceEntity.h"
|
RelativePath="..\source\BlockEntities\FurnaceEntity.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\source\BlockEntities\HopperEntity.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\source\BlockEntities\HopperEntity.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\source\BlockEntities\JukeboxEntity.cpp"
|
RelativePath="..\source\BlockEntities\JukeboxEntity.cpp"
|
||||||
>
|
>
|
||||||
|
291
source/BlockEntities/HopperEntity.cpp
Normal file
291
source/BlockEntities/HopperEntity.cpp
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
81
source/BlockEntities/HopperEntity.h
Normal file
81
source/BlockEntities/HopperEntity.h
Normal file
@ -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/DispenserEntity.h"
|
||||||
#include "BlockEntities/DropperEntity.h"
|
#include "BlockEntities/DropperEntity.h"
|
||||||
#include "BlockEntities/FurnaceEntity.h"
|
#include "BlockEntities/FurnaceEntity.h"
|
||||||
|
#include "BlockEntities/HopperEntity.h"
|
||||||
#include "BlockEntities/JukeboxEntity.h"
|
#include "BlockEntities/JukeboxEntity.h"
|
||||||
#include "BlockEntities/NoteEntity.h"
|
#include "BlockEntities/NoteEntity.h"
|
||||||
#include "BlockEntities/SignEntity.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))
|
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;
|
break;
|
||||||
}
|
}
|
||||||
@ -1231,7 +1232,7 @@ void cChunk::CreateBlockEntities(void)
|
|||||||
{
|
{
|
||||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
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;
|
break;
|
||||||
}
|
}
|
||||||
@ -1249,17 +1250,25 @@ void cChunk::CreateBlockEntities(void)
|
|||||||
{
|
{
|
||||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
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;
|
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_SIGN_POST:
|
||||||
case E_BLOCK_WALLSIGN:
|
case E_BLOCK_WALLSIGN:
|
||||||
{
|
{
|
||||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
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;
|
break;
|
||||||
}
|
}
|
||||||
@ -1268,7 +1277,7 @@ void cChunk::CreateBlockEntities(void)
|
|||||||
{
|
{
|
||||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
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;
|
break;
|
||||||
}
|
}
|
||||||
@ -1277,7 +1286,7 @@ void cChunk::CreateBlockEntities(void)
|
|||||||
{
|
{
|
||||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
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;
|
break;
|
||||||
}
|
}
|
||||||
@ -1434,28 +1443,33 @@ void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType
|
|||||||
{
|
{
|
||||||
case E_BLOCK_CHEST:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case E_BLOCK_DISPENSER:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case E_BLOCK_DROPPER:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case E_BLOCK_FURNACE:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case E_BLOCK_SIGN_POST:
|
case E_BLOCK_SIGN_POST:
|
||||||
case E_BLOCK_WALLSIGN:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case E_BLOCK_NOTE_BLOCK:
|
case E_BLOCK_NOTE_BLOCK:
|
||||||
|
@ -310,6 +310,9 @@ public:
|
|||||||
cFluidSimulatorData * GetLavaSimulatorData (void) { return m_LavaSimulatorData; }
|
cFluidSimulatorData * GetLavaSimulatorData (void) { return m_LavaSimulatorData; }
|
||||||
cSandSimulatorChunkData & GetSandSimulatorData (void) { return m_SandSimulatorData; }
|
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:
|
private:
|
||||||
|
|
||||||
friend class cChunkMap;
|
friend class cChunkMap;
|
||||||
@ -362,8 +365,6 @@ private:
|
|||||||
|
|
||||||
void RemoveBlockEntity(cBlockEntity * a_BlockEntity);
|
void RemoveBlockEntity(cBlockEntity * a_BlockEntity);
|
||||||
void AddBlockEntity (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);
|
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)
|
void cItemGrid::TriggerListeners(int a_SlotNum)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSListeners);
|
cListeners Listeners;
|
||||||
m_IsInTriggerListeners = true;
|
{
|
||||||
for (cListeners::iterator itr = m_Listeners.begin(), end = m_Listeners.end(); itr != end; ++itr)
|
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);
|
(*itr)->OnSlotChanged(this, a_SlotNum);
|
||||||
} // for itr - m_Listeners[]
|
} // for itr - m_Listeners[]
|
||||||
|
@ -665,6 +665,16 @@ cSlotAreaItemGrid::cSlotAreaItemGrid(cItemGrid & a_ItemGrid, cWindow & a_ParentW
|
|||||||
super(a_ItemGrid.GetNumSlots(), a_ParentWindow),
|
super(a_ItemGrid.GetNumSlots(), a_ParentWindow),
|
||||||
m_ItemGrid(a_ItemGrid)
|
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:
|
// cSlotAreaTemporary:
|
||||||
|
|
||||||
|
@ -143,18 +143,24 @@ public:
|
|||||||
|
|
||||||
/// Handles any slot area that is representing a cItemGrid; same items for all the players
|
/// Handles any slot area that is representing a cItemGrid; same items for all the players
|
||||||
class cSlotAreaItemGrid :
|
class cSlotAreaItemGrid :
|
||||||
public cSlotArea
|
public cSlotArea,
|
||||||
|
public cItemGrid::cListener
|
||||||
{
|
{
|
||||||
typedef cSlotArea super;
|
typedef cSlotArea super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cSlotAreaItemGrid(cItemGrid & a_ItemGrid, cWindow & a_ParentWindow);
|
cSlotAreaItemGrid(cItemGrid & a_ItemGrid, cWindow & a_ParentWindow);
|
||||||
|
|
||||||
|
virtual ~cSlotAreaItemGrid();
|
||||||
|
|
||||||
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
|
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;
|
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
cItemGrid & m_ItemGrid;
|
cItemGrid & m_ItemGrid;
|
||||||
|
|
||||||
|
// cItemGrid::cListener overrides:
|
||||||
|
virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "../Inventory.h"
|
#include "../Inventory.h"
|
||||||
#include "../Items/ItemHandler.h"
|
#include "../Items/ItemHandler.h"
|
||||||
#include "../BlockEntities/ChestEntity.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)
|
void cWindow::SendWholeWindow(cClientHandle & a_Client)
|
||||||
{
|
{
|
||||||
a_Client.SendWholeInventory(*this);
|
a_Client.SendWholeInventory(*this);
|
||||||
@ -741,6 +776,7 @@ cChestWindow::~cChestWindow()
|
|||||||
cDropSpenserWindow::cDropSpenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserEntity * a_DropSpenser) :
|
cDropSpenserWindow::cDropSpenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserEntity * a_DropSpenser) :
|
||||||
cWindow(cWindow::DropSpenser, "MCS-DropSpenser")
|
cWindow(cWindow::DropSpenser, "MCS-DropSpenser")
|
||||||
{
|
{
|
||||||
|
m_ShouldDistributeToHotbarFirst = false;
|
||||||
m_SlotAreas.push_back(new cSlotAreaDropSpenser(a_DropSpenser, *this));
|
m_SlotAreas.push_back(new cSlotAreaDropSpenser(a_DropSpenser, *this));
|
||||||
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
||||||
m_SlotAreas.push_back(new cSlotAreaHotBar(*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::cFurnaceWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceEntity * a_Furnace) :
|
cFurnaceWindow::cFurnaceWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceEntity * a_Furnace) :
|
||||||
cWindow(cWindow::Furnace, "MCS-Furnace")
|
cWindow(cWindow::Furnace, "MCS-Furnace")
|
||||||
{
|
{
|
||||||
|
m_ShouldDistributeToHotbarFirst = false;
|
||||||
m_SlotAreas.push_back(new cSlotAreaFurnace(a_Furnace, *this));
|
m_SlotAreas.push_back(new cSlotAreaFurnace(a_Furnace, *this));
|
||||||
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
||||||
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
|
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
|
||||||
|
@ -21,6 +21,7 @@ class cClientHandle;
|
|||||||
class cChestEntity;
|
class cChestEntity;
|
||||||
class cDropSpenserEntity;
|
class cDropSpenserEntity;
|
||||||
class cFurnaceEntity;
|
class cFurnaceEntity;
|
||||||
|
class cHopperEntity;
|
||||||
class cSlotArea;
|
class cSlotArea;
|
||||||
class cWorld;
|
class cWorld;
|
||||||
|
|
||||||
@ -110,8 +111,16 @@ public:
|
|||||||
/// Called when a player closes this window; notifies all slot areas. Returns true if close accepted
|
/// 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);
|
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);
|
void SendWholeWindow(cClientHandle & a_Client);
|
||||||
|
|
||||||
|
/// Sends the contents of the whole window to all clients of this window.
|
||||||
void BroadcastWholeWindow(void);
|
void BroadcastWholeWindow(void);
|
||||||
|
|
||||||
|
/// Sends the progressbar to all clients of this window
|
||||||
void BroadcastInventoryProgress(short a_Progressbar, short a_Value);
|
void BroadcastInventoryProgress(short a_Progressbar, short a_Value);
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
@ -194,6 +203,7 @@ protected:
|
|||||||
class cCraftingWindow :
|
class cCraftingWindow :
|
||||||
public cWindow
|
public cWindow
|
||||||
{
|
{
|
||||||
|
typedef cWindow super;
|
||||||
public:
|
public:
|
||||||
cCraftingWindow(int a_BlockX, int a_BlockY, int a_BlockZ);
|
cCraftingWindow(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
} ;
|
} ;
|
||||||
@ -205,6 +215,7 @@ public:
|
|||||||
class cFurnaceWindow :
|
class cFurnaceWindow :
|
||||||
public cWindow
|
public cWindow
|
||||||
{
|
{
|
||||||
|
typedef cWindow super;
|
||||||
public:
|
public:
|
||||||
cFurnaceWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceEntity * a_Furnace);
|
cFurnaceWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceEntity * a_Furnace);
|
||||||
} ;
|
} ;
|
||||||
@ -216,6 +227,7 @@ public:
|
|||||||
class cDropSpenserWindow :
|
class cDropSpenserWindow :
|
||||||
public cWindow
|
public cWindow
|
||||||
{
|
{
|
||||||
|
typedef cWindow super;
|
||||||
public:
|
public:
|
||||||
cDropSpenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserEntity * a_Dispenser);
|
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 :
|
class cChestWindow :
|
||||||
public cWindow
|
public cWindow
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "../BlockEntities/DispenserEntity.h"
|
#include "../BlockEntities/DispenserEntity.h"
|
||||||
#include "../BlockEntities/DropperEntity.h"
|
#include "../BlockEntities/DropperEntity.h"
|
||||||
#include "../BlockEntities/FurnaceEntity.h"
|
#include "../BlockEntities/FurnaceEntity.h"
|
||||||
|
#include "../BlockEntities/HopperEntity.h"
|
||||||
#include "../BlockEntities/JukeboxEntity.h"
|
#include "../BlockEntities/JukeboxEntity.h"
|
||||||
#include "../BlockEntities/NoteEntity.h"
|
#include "../BlockEntities/NoteEntity.h"
|
||||||
#include "../BlockEntities/SignEntity.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("");
|
m_Writer.BeginCompound("");
|
||||||
AddBasicTileEntity(a_Sign, "Sign");
|
AddBasicTileEntity(a_Entity, "Hopper");
|
||||||
m_Writer.AddString("Text1", a_Sign->GetLine(0));
|
m_Writer.BeginList("Items", TAG_Compound);
|
||||||
m_Writer.AddString("Text2", a_Sign->GetLine(1));
|
AddItemGrid(a_Entity->GetContents());
|
||||||
m_Writer.AddString("Text3", a_Sign->GetLine(2));
|
m_Writer.EndList();
|
||||||
m_Writer.AddString("Text4", a_Sign->GetLine(3));
|
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();
|
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("");
|
m_Writer.BeginCompound("");
|
||||||
AddBasicTileEntity(a_Jukebox, "RecordPlayer");
|
AddBasicTileEntity(a_Sign, "Sign");
|
||||||
m_Writer.AddInt("Record", a_Jukebox->GetRecord());
|
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();
|
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_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break;
|
||||||
case E_BLOCK_DROPPER: AddDropperEntity ((cDropperEntity *) a_Entity); break;
|
case E_BLOCK_DROPPER: AddDropperEntity ((cDropperEntity *) a_Entity); break;
|
||||||
case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) 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_SIGN_POST:
|
||||||
case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break;
|
case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break;
|
||||||
case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break;
|
case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break;
|
||||||
|
@ -20,12 +20,13 @@ class cFastNBTWriter;
|
|||||||
class cEntity;
|
class cEntity;
|
||||||
class cBlockEntity;
|
class cBlockEntity;
|
||||||
class cChestEntity;
|
class cChestEntity;
|
||||||
class cFurnaceEntity;
|
|
||||||
class cDispenserEntity;
|
class cDispenserEntity;
|
||||||
class cDropperEntity;
|
class cDropperEntity;
|
||||||
class cSignEntity;
|
class cFurnaceEntity;
|
||||||
class cNoteEntity;
|
class cHopperEntity;
|
||||||
class cJukeboxEntity;
|
class cJukeboxEntity;
|
||||||
|
class cNoteEntity;
|
||||||
|
class cSignEntity;
|
||||||
class cFallingBlock;
|
class cFallingBlock;
|
||||||
class cMinecart;
|
class cMinecart;
|
||||||
class cMinecartWithChest;
|
class cMinecartWithChest;
|
||||||
@ -78,17 +79,18 @@ protected:
|
|||||||
void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0);
|
void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0);
|
||||||
|
|
||||||
// Block entities:
|
// Block entities:
|
||||||
void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID);
|
void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID);
|
||||||
void AddChestEntity(cChestEntity * a_Entity);
|
void AddChestEntity (cChestEntity * a_Entity);
|
||||||
void AddDispenserEntity(cDispenserEntity * a_Entity);
|
void AddDispenserEntity(cDispenserEntity * a_Entity);
|
||||||
void AddDropperEntity(cDropperEntity * a_Entity);
|
void AddDropperEntity (cDropperEntity * a_Entity);
|
||||||
void AddFurnaceEntity(cFurnaceEntity * a_Furnace);
|
void AddFurnaceEntity (cFurnaceEntity * a_Furnace);
|
||||||
void AddSignEntity(cSignEntity * a_Sign);
|
void AddHopperEntity (cHopperEntity * a_Entity);
|
||||||
void AddNoteEntity(cNoteEntity * a_Note);
|
void AddJukeboxEntity (cJukeboxEntity * a_Jukebox);
|
||||||
void AddJukeboxEntity(cJukeboxEntity * a_Jukebox);
|
void AddNoteEntity (cNoteEntity * a_Note);
|
||||||
void AddBasicEntity(cEntity * a_Entity, const AString & a_ClassName);
|
void AddSignEntity (cSignEntity * a_Sign);
|
||||||
|
|
||||||
// Entities:
|
// Entities:
|
||||||
|
void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName);
|
||||||
void AddFallingBlockEntity(cFallingBlock * a_FallingBlock);
|
void AddFallingBlockEntity(cFallingBlock * a_FallingBlock);
|
||||||
void AddMinecartEntity (cMinecart * a_Minecart);
|
void AddMinecartEntity (cMinecart * a_Minecart);
|
||||||
void AddMonsterEntity (cMonster * a_Monster);
|
void AddMonsterEntity (cMonster * a_Monster);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "../BlockEntities/DispenserEntity.h"
|
#include "../BlockEntities/DispenserEntity.h"
|
||||||
#include "../BlockEntities/DropperEntity.h"
|
#include "../BlockEntities/DropperEntity.h"
|
||||||
#include "../BlockEntities/FurnaceEntity.h"
|
#include "../BlockEntities/FurnaceEntity.h"
|
||||||
|
#include "../BlockEntities/HopperEntity.h"
|
||||||
#include "../BlockEntities/JukeboxEntity.h"
|
#include "../BlockEntities/JukeboxEntity.h"
|
||||||
#include "../BlockEntities/NoteEntity.h"
|
#include "../BlockEntities/NoteEntity.h"
|
||||||
#include "../BlockEntities/SignEntity.h"
|
#include "../BlockEntities/SignEntity.h"
|
||||||
@ -568,6 +569,10 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
|
|||||||
{
|
{
|
||||||
LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child);
|
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)
|
else if (strncmp(a_NBT.GetData(sID), "Music", a_NBT.GetDataLength(sID)) == 0)
|
||||||
{
|
{
|
||||||
LoadNoteFromNBT(a_BlockEntities, a_NBT, Child);
|
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");
|
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
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));
|
std::auto_ptr<cDropperEntity> Dropper(new cDropperEntity(x, y, z, m_World));
|
||||||
LoadItemGridFromNBT(Dropper->GetContents(), a_NBT, Items);
|
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)
|
void cWSSAnvil::LoadSignFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
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)
|
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 LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
void LoadDropperFromNBT (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 LoadFurnaceFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
void LoadHopperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
|
||||||
void LoadJukeboxFromNBT (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);
|
void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user