1
0

Added dispensers (they can't dispense items yet)

Fixed crash when digging snow
Moved BlockPlace hook check, so Core plugin will no longer block item usage
Player chat messages are now visible in the console

git-svn-id: http://mc-server.googlecode.com/svn/trunk@1081 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
luksor111@gmail.com 2012-12-19 21:19:36 +00:00
parent a10c4774f5
commit 05d71675f6
19 changed files with 533 additions and 59 deletions

View File

@ -950,6 +950,14 @@
RelativePath="..\source\ChestEntity.h"
>
</File>
<File
RelativePath="..\source\DispenserEntity.cpp"
>
</File>
<File
RelativePath="..\source\DispenserEntity.h"
>
</File>
<File
RelativePath="..\source\Doors.h"
>

View File

@ -1,10 +1,17 @@
#pragma once
#include "BlockEntity.h"
#include "../World.h"
#include "../Piston.h"
#include "../Player.h"
class cBlockDispenserHandler : public cBlockEntityHandler
class cBlockDispenserHandler :
public cBlockEntityHandler
{
public:
cBlockDispenserHandler(BLOCKTYPE a_BlockType)

View File

@ -69,19 +69,10 @@ void cBlockDoorHandler::PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLET
{
a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation());
char a_TopBlockMeta = 8;
if((a_BlockMeta == 0) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) == m_BlockType))
{
a_TopBlockMeta = 9;
}
else if((a_BlockMeta == 1) && (a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) == m_BlockType))
{
a_TopBlockMeta = 9;
}
else if((a_BlockMeta == 2) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) == m_BlockType))
{
a_TopBlockMeta = 9;
}
else if((a_BlockMeta == 3) && (a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) == m_BlockType))
if( (a_BlockMeta == 0) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) == m_BlockType) ||
(a_BlockMeta == 1) && (a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) == m_BlockType) ||
(a_BlockMeta == 2) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) == m_BlockType) ||
(a_BlockMeta == 3) && (a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) == m_BlockType))
{
a_TopBlockMeta = 9;
}

View File

@ -34,7 +34,8 @@ public:
char OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
char NewMetaData = cDoors::RotationToMetaData(a_Player->GetRotation() + 270);
OldMetaData ^= 4; //Toggle the gate
if((OldMetaData & 1) == (NewMetaData & 1)){
if((OldMetaData & 1) == (NewMetaData & 1))
{
//Standing in front of the gate - apply new direction
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, (OldMetaData & 4) | (NewMetaData & 3));
}

View File

@ -25,7 +25,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
a_Pickups.push_back(cItem(E_ITEM_SNOWBALL, 4, 0));
a_Pickups.push_back(cItem(E_ITEM_SNOWBALL, 1, 0));
}

View File

@ -13,6 +13,7 @@
#include "zlib.h"
#include "Defines.h"
#include "ChestEntity.h"
#include "DispenserEntity.h"
#include "FurnaceEntity.h"
#include "SignEntity.h"
#include "NoteEntity.h"
@ -982,6 +983,15 @@ void cChunk::CreateBlockEntities(void)
}
break;
}
case E_BLOCK_DISPENSER:
{
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) );
}
break;
}
case E_BLOCK_FURNACE:
{
@ -1128,6 +1138,11 @@ void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType
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) );
break;
}
case E_BLOCK_FURNACE:
{
AddBlockEntity( new cFurnaceEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) );

View File

@ -38,6 +38,7 @@ class MTRand;
class cPlayer;
class cChunkMap;
class cChestEntity;
class cDispenserEntity;
class cFurnaceEntity;
class cBlockArea;
class cPawn;
@ -45,10 +46,11 @@ class cPickup;
class cChunkDataSerializer;
class cBlockArea;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback;
typedef cItemCallback<cDispenserEntity> cDispenserCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;

View File

@ -18,6 +18,7 @@ class cChunkStay;
class cChunk;
class cPlayer;
class cChestEntity;
class cDispenserEntity;
class cFurnaceEntity;
class cPawn;
class cPickup;
@ -26,9 +27,10 @@ class cBlockArea;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cChunk * cChunkPtr;
typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback;
typedef cItemCallback<cDispenserEntity> cDispenserCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;

View File

@ -578,11 +578,14 @@ void cClientHandle::HandleBlockDig(int a_BlockX, int a_BlockY, int a_BlockZ, cha
if (bBroken)
{
ItemHandler->OnBlockDestroyed(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ);
BlockHandler(OldBlock)->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
World->BroadcastSoundParticleEffect(2001, a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, OldBlock, this);
World->DigBlock(a_BlockX, a_BlockY, a_BlockZ);
if(World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_AIR)
{
ItemHandler->OnBlockDestroyed(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ);
BlockHandler(OldBlock)->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
World->BroadcastSoundParticleEffect(2001, a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, OldBlock, this);
World->DigBlock(a_BlockX, a_BlockY, a_BlockZ);
}
}
else
{
@ -643,20 +646,12 @@ void cClientHandle::HandleBlockPlace(int a_BlockX, int a_BlockY, int a_BlockZ, c
}
return;
}
if (cRoot::Get()->GetPluginManager()->CallHookBlockPlace(m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, Equipped))
{
if (a_BlockFace > -1)
{
AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
}
return;
}
cWorld * World = m_Player->GetWorld();
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(World->GetBlock(a_BlockX, a_BlockY, a_BlockZ));
// TODO: Wrap following if into another if which will call hook 'OnBlockUse' (or some nicer name)
if (Handler->IsUseable())
{
Handler->OnUse(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
@ -742,6 +737,16 @@ void cClientHandle::HandleBlockPlace(int a_BlockX, int a_BlockY, int a_BlockZ, c
}
}
}
if (cRoot::Get()->GetPluginManager()->CallHookBlockPlace(m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, Equipped))
{
if (a_BlockFace > -1)
{
AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
}
return;
}
}
@ -760,6 +765,7 @@ void cClientHandle::HandleChat(const AString & a_Message)
a_Message.c_str()
);
m_Player->GetWorld()->BroadcastChat(Msg);
LOG("<%s> %s", m_Player->GetName().c_str(), a_Message.c_str());
}
}

192
source/DispenserEntity.cpp Normal file
View File

@ -0,0 +1,192 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "DispenserEntity.h"
#include "BlockID.h"
#include "Item.h"
#include "UI/Window.h"
#include "Player.h"
#include "World.h"
#include "ClientHandle.h"
#include "Server.h"
#include "Pickup.h"
#include "Root.h"
#include <json/json.h>
cDispenserEntity::cDispenserEntity(int a_X, int a_Y, int a_Z, cWorld * a_World)
: cBlockEntity( E_BLOCK_DISPENSER, a_X, a_Y, a_Z, a_World )
, m_Items( new cItem[9] )
{
SetBlockEntity(this); // cBlockEntityWindowOwner
}
cDispenserEntity::~cDispenserEntity()
{
// Tell window its owner is destroyed
if( GetWindow() )
{
GetWindow()->OwnerDestroyed();
}
// Clean up items
if( m_Items )
{
delete [] m_Items;
}
}
void cDispenserEntity::Destroy()
{
// Drop items
cItems Pickups;
for( int i = 0; i < 3; i++)
{
if( !m_Items[i].IsEmpty() )
{
Pickups.push_back(m_Items[i]);
m_Items[i].Empty();
}
}
m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ);
}
void cDispenserEntity::UsedBy(cPlayer * a_Player)
{
if (GetWindow() == NULL)
{
OpenWindow(new cDispenserWindow(m_PosX, m_PosY, m_PosZ, this));
}
if (GetWindow() != NULL)
{
if (a_Player->GetWindow() != GetWindow())
{
a_Player->OpenWindow(GetWindow());
GetWindow()->SendWholeWindow(*a_Player->GetClientHandle());
}
}
}
bool cDispenserEntity::Tick( float a_Dt )
{
return true;
}
void cDispenserEntity::SetSlot(int a_Slot, const cItem & a_Item)
{
if ((a_Slot < 0) || (a_Slot >= 9))
{
ASSERT(!"Dispenser: slot number out of range");
return;
}
m_Items[a_Slot] = a_Item;
}
#define READ(File, Var) \
if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \
{ \
LOGERROR("ERROR READING cDispenserEntity %s FROM FILE (line %d)", #Var, __LINE__); \
return false; \
}
bool cDispenserEntity::LoadFromFile(cFile & f)
{
READ(f, m_PosX);
READ(f, m_PosY);
READ(f, m_PosZ);
unsigned int NumSlots = 0;
READ(f, NumSlots);
m_Items = new cItem[ NumSlots ];
for(unsigned int i = 0; i < NumSlots; i++)
{
cItem & Item = m_Items[i];
READ(f, Item.m_ItemID);
READ(f, Item.m_ItemCount);
READ(f, Item.m_ItemHealth);
}
return true;
}
bool cDispenserEntity::LoadFromJson( const Json::Value& a_Value )
{
m_PosX = a_Value.get("x", 0).asInt();
m_PosY = a_Value.get("y", 0).asInt();
m_PosZ = a_Value.get("z", 0).asInt();
Json::Value AllSlots = a_Value.get("Slots", 0);
int SlotIdx = 0;
for( Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr )
{
m_Items[ SlotIdx ].FromJson( *itr );
SlotIdx++;
}
return true;
}
void cDispenserEntity::SaveToJson( Json::Value& a_Value )
{
a_Value["x"] = m_PosX;
a_Value["y"] = m_PosY;
a_Value["z"] = m_PosZ;
Json::Value AllSlots;
for(unsigned int i = 0; i < 3; i++)
{
Json::Value Slot;
m_Items[ i ].GetJson( Slot );
AllSlots.append( Slot );
}
a_Value["Slots"] = AllSlots;
}
void cDispenserEntity::SendTo(cClientHandle & a_Client)
{
// Nothing needs to be sent
UNUSED(a_Client);
}

55
source/DispenserEntity.h Normal file
View File

@ -0,0 +1,55 @@
#pragma once
#include "BlockEntity.h"
#include "UI/WindowOwner.h"
#include "Item.h"
namespace Json
{
class Value;
}
class cClientHandle;
class cServer;
class cDispenserEntity :
public cBlockEntity,
public cBlockEntityWindowOwner
{
public:
cDispenserEntity(int a_X, int a_Y, int a_Z, cWorld * a_World);
virtual ~cDispenserEntity();
virtual void Destroy();
bool LoadFromFile(cFile & a_File); // deprecated format
bool LoadFromJson(const Json::Value& a_Value );
virtual void SaveToJson(Json::Value& a_Value ) override;
virtual void SendTo(cClientHandle & a_Client) override;
// Returns true if there's any change, forcing the chunk to go dirty.
bool Tick( float a_Dt );
virtual void UsedBy( cPlayer * a_Player ) override;
const cItem * GetSlot(int i) const { return &(m_Items[i]); }
void SetSlot(int a_Slot, const cItem & a_Item);
private:
cItem * m_Items;
};

View File

@ -7,6 +7,7 @@
#include "SlotArea.h"
#include "../Player.h"
#include "../ChestEntity.h"
#include "../DispenserEntity.h"
#include "../FurnaceEntity.h"
#include "../Items/ItemHandler.h"
#include "Window.h"
@ -414,6 +415,53 @@ cCraftingRecipe & cSlotAreaCrafting::GetRecipeForPlayer(cPlayer & a_Player)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cSlotAreaFurnace:
cSlotAreaDispenser::cSlotAreaDispenser(cDispenserEntity * a_Dispenser, cWindow & a_ParentWindow) :
cSlotArea(9, a_ParentWindow),
m_Dispenser(a_Dispenser)
{
}
void cSlotAreaDispenser::Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem)
{
super::Clicked(a_Player, a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_ClickedItem);
if (m_Dispenser == NULL)
{
LOGERROR("cSlotAreaDispenser::Clicked(): m_Dispenser == NULL");
ASSERT(!"cSlotAreaDispenser::Clicked(): m_Dispenser == NULL");
return;
}
}
const cItem * cSlotAreaDispenser::GetSlot(int a_SlotNum, cPlayer & a_Player)
{
return m_Dispenser->GetSlot(a_SlotNum);
}
void cSlotAreaDispenser::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item)
{
m_Dispenser->SetSlot(a_SlotNum, a_Item);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cSlotAreaFurnace:

View File

@ -15,6 +15,7 @@
class cWindow;
class cPlayer;
class cChestEntity;
class cDispenserEntity;
class cFurnaceEntity;
class cCraftingRecipe;
@ -231,6 +232,26 @@ protected:
class cSlotAreaDispenser :
public cSlotArea
{
typedef cSlotArea super;
public:
cSlotAreaDispenser(cDispenserEntity * a_Dispenser, cWindow & a_ParentWindow);
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem) override;
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
protected:
cDispenserEntity * m_Dispenser;
} ;
class cSlotAreaFurnace :
public cSlotArea
{

View File

@ -460,6 +460,21 @@ cChestWindow::~cChestWindow()
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cDispenserWindow:
cDispenserWindow::cDispenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserEntity * a_Dispenser) :
cWindow(cWindow::Dispenser, "MCS-Dispenser")
{
m_SlotAreas.push_back(new cSlotAreaDispenser(a_Dispenser, *this));
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cFurnaceWindow:

View File

@ -19,6 +19,7 @@ class cPlayer;
class cWindowOwner;
class cClientHandle;
class cChestEntity;
class cDispenserEntity;
class cFurnaceEntity;
class cSlotArea;
class cWorld;
@ -148,6 +149,17 @@ public:
class cDispenserWindow :
public cWindow
{
public:
cDispenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserEntity * a_Dispenser);
} ;
class cChestWindow :
public cWindow
{

View File

@ -38,14 +38,16 @@ class cBlockEntity;
class cWorldGenerator; // The generator that actually generates the chunks for a single world
class cChunkGenerator; // The thread responsible for generating chunks
class cChestEntity;
class cDispenserEntity;
class cFurnaceEntity;
typedef std::list< cPlayer * > cPlayerList;
typedef cItemCallback<cPlayer> cPlayerListCallback;
typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
typedef cItemCallback<cPlayer> cPlayerListCallback;
typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback;
typedef cItemCallback<cDispenserEntity> cDispenserCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;

View File

@ -9,6 +9,7 @@
#include "zlib.h"
#include "../BlockID.h"
#include "../ChestEntity.h"
#include "../DispenserEntity.h"
#include "../FurnaceEntity.h"
#include "../SignEntity.h"
#include "../NoteEntity.h"
@ -132,8 +133,27 @@ protected:
m_Writer.EndList();
m_Writer.EndCompound();
}
void AddDispenserEntity(cDispenserEntity * a_Entity)
{
m_Writer.BeginCompound("");
AddBasicTileEntity(a_Entity, "Trap");
m_Writer.BeginList("Items", TAG_Compound);
for (int i = 0; i < 9; i++)
{
const cItem * Item = a_Entity->GetSlot(i);
if ((Item == NULL) || Item->IsEmpty())
{
continue;
}
AddItem(Item, i);
}
m_Writer.EndList();
m_Writer.EndCompound();
}
void AddFurnaceEntity(cFurnaceEntity * a_Furnace)
{
m_Writer.BeginCompound("");
@ -229,12 +249,13 @@ protected:
// Add tile-entity into NBT:
switch (a_Entity->GetBlockType())
{
case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break;
case E_BLOCK_FURNACE: AddFurnaceEntity((cFurnaceEntity *)a_Entity); break;
case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break;
case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break;
case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) 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;
case E_BLOCK_JUKEBOX: AddJukeboxEntity((cJukeboxEntity *)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_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break;
default:
{
ASSERT(!"Unhandled block entity saved into Anvil");
@ -728,6 +749,10 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
{
LoadChestFromNBT(a_BlockEntities, a_NBT, Child);
}
else if (strncmp(a_NBT.GetData(sID), "Trap", a_NBT.GetDataLength(sID)) == 0)
{
LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child);
}
else if (strncmp(a_NBT.GetData(sID), "Furnace", a_NBT.GetDataLength(sID)) == 0)
{
LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child);
@ -801,6 +826,55 @@ void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cPars
void cWSSAnvil::LoadDispenserFromNBT(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 dispenser - the chunk loader will provide an empty cDispenserEntity for this
}
std::auto_ptr<cDispenserEntity> Dispenser(new cDispenserEntity(x, y, z, m_World));
for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child))
{
int Slot = a_NBT.FindChildByName(Child, "Slot");
if ((Slot < 0) || (a_NBT.GetType(Slot) != TAG_Byte))
{
continue;
}
cItem Item;
int ID = a_NBT.FindChildByName(Child, "id");
if ((ID < 0) || (a_NBT.GetType(ID) != TAG_Short))
{
continue;
}
Item.m_ItemID = (ENUM_ITEM_ID)(a_NBT.GetShort(ID));
int Damage = a_NBT.FindChildByName(Child, "Damage");
if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short))
{
continue;
}
Item.m_ItemHealth = a_NBT.GetShort(Damage);
int Count = a_NBT.FindChildByName(Child, "Count");
if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte))
{
continue;
}
Item.m_ItemCount = a_NBT.GetByte(Count);
Dispenser->SetSlot(a_NBT.GetByte(Slot), Item);
} // for itr - ItemDefs[]
a_BlockEntities.push_back(Dispenser.release());
}
void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
{
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);

View File

@ -111,11 +111,12 @@ protected:
/// Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1)
void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag);
void LoadChestFromNBT (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 LoadJukeboxFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadDispenserFromNBT (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 LoadJukeboxFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
/// Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if successful
bool GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z);

View File

@ -11,6 +11,7 @@
#include "../StringCompression.h"
#include "../ChestEntity.h"
#include "../SignEntity.h"
#include "../DispenserEntity.h"
#include "../FurnaceEntity.h"
#include "../NoteEntity.h"
#include "../JukeboxEntity.h"
@ -71,12 +72,13 @@ void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity)
const char * SaveInto = NULL;
switch (a_BlockEntity->GetBlockType())
{
case E_BLOCK_CHEST: SaveInto = "Chests"; break;
case E_BLOCK_FURNACE: SaveInto = "Furnaces"; break;
case E_BLOCK_SIGN_POST: SaveInto = "Signs"; break;
case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break;
case E_BLOCK_NOTE_BLOCK: SaveInto = "Notes"; break;
case E_BLOCK_JUKEBOX: SaveInto = "Jukeboxes"; break;
case E_BLOCK_CHEST: SaveInto = "Chests"; break;
case E_BLOCK_DISPENSER: SaveInto = "Dispensers"; break;
case E_BLOCK_FURNACE: SaveInto = "Furnaces"; break;
case E_BLOCK_SIGN_POST: SaveInto = "Signs"; break;
case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break;
case E_BLOCK_NOTE_BLOCK: SaveInto = "Notes"; break;
case E_BLOCK_JUKEBOX: SaveInto = "Jukeboxes"; break;
default:
{
@ -281,6 +283,26 @@ void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_En
} // for itr - AllChests[]
}
// Load dispensers
Json::Value AllDispensers = a_Value.get("Dispensers", Json::nullValue);
if( !AllDispensers.empty() )
{
for( Json::Value::iterator itr = AllDispensers.begin(); itr != AllDispensers.end(); ++itr )
{
Json::Value & Dispenser = *itr;
cDispenserEntity * DispenserEntity = new cDispenserEntity(0,0,0, a_World);
if( !DispenserEntity->LoadFromJson( Dispenser ) )
{
LOGERROR("ERROR READING DISPENSER FROM JSON!" );
delete DispenserEntity;
}
else
{
a_BlockEntities.push_back( DispenserEntity );
}
} // for itr - AllDispensers[]
}
// Load furnaces
Json::Value AllFurnaces = a_Value.get("Furnaces", Json::nullValue);
if( !AllFurnaces.empty() )