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-c427514a06d6master
parent
a10c4774f5
commit
05d71675f6
|
@ -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"
|
||||
>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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) );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() )
|
||||
|
|
Loading…
Reference in New Issue