1
0

Merge pull request #1427 from mc-server/chestcarts

Implemented Chest Minecarts
This commit is contained in:
Mattes D 2014-09-30 17:16:15 +02:00
commit 1531511bbe
15 changed files with 196 additions and 78 deletions

View File

@ -20,12 +20,9 @@
// tolua_begin
class cBlockEntityWithItems :
public cBlockEntity
// tolua_end
// tolua doesn't seem to support multiple inheritance?
, public cItemGrid::cListener
, public cBlockEntityWindowOwner
// tolua_begin
public cBlockEntity,
public cItemGrid::cListener,
public cBlockEntityWindowOwner
{
typedef cBlockEntity super;
@ -39,6 +36,7 @@ public:
cWorld * a_World // Optional world to assign to the entity
) :
super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World),
cBlockEntityWindowOwner(this),
m_Contents(a_ItemGridWidth, a_ItemGridHeight)
{
m_Contents.AddListener(*this);

View File

@ -14,7 +14,6 @@ cChestEntity::cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_
super(a_Type, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
m_NumActivePlayers(0)
{
cBlockEntityWindowOwner::SetBlockEntity(this);
}

View File

@ -14,7 +14,6 @@
cDispenserEntity::cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
super(E_BLOCK_DISPENSER, a_BlockX, a_BlockY, a_BlockZ, a_World)
{
SetBlockEntity(this); // cBlockEntityWindowOwner
}

View File

@ -18,7 +18,6 @@ cDropSpenserEntity::cDropSpenserEntity(BLOCKTYPE a_BlockType, int a_BlockX, int
m_ShouldDropSpense(false),
m_IsPowered(false)
{
SetBlockEntity(this); // cBlockEntityWindowOwner
}

View File

@ -13,7 +13,6 @@
cDropperEntity::cDropperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
super(E_BLOCK_DROPPER, a_BlockX, a_BlockY, a_BlockZ, a_World)
{
SetBlockEntity(this); // cBlockEntityWindowOwner
}

View File

@ -11,7 +11,8 @@
cEnderChestEntity::cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
super(E_BLOCK_ENDER_CHEST, a_BlockX, a_BlockY, a_BlockZ, a_World)
super(E_BLOCK_ENDER_CHEST, a_BlockX, a_BlockY, a_BlockZ, a_World),
cBlockEntityWindowOwner(this)
{
}

View File

@ -34,7 +34,6 @@ cFurnaceEntity::cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY
m_LastProgressFuel(0),
m_LastProgressCook(0)
{
cBlockEntityWindowOwner::SetBlockEntity(this);
m_Contents.AddListener(*this);
}

View File

@ -7,7 +7,6 @@
#include "Globals.h"
#include "Minecart.h"
#include "../World.h"
#include "../ClientHandle.h"
#include "../Chunk.h"
#include "Player.h"
@ -1106,19 +1105,11 @@ void cRideableMinecart::OnRightClicked(cPlayer & a_Player)
// cMinecartWithChest:
cMinecartWithChest::cMinecartWithChest(double a_X, double a_Y, double a_Z) :
super(mpChest, a_X, a_Y, a_Z)
super(mpChest, a_X, a_Y, a_Z),
cEntityWindowOwner(this),
m_Contents(ContentsWidth, ContentsHeight)
{
}
void cMinecartWithChest::SetSlot(size_t a_Idx, const cItem & a_Item)
{
ASSERT(a_Idx < ARRAYCOUNT(m_Items));
m_Items[a_Idx] = a_Item;
m_Contents.AddListener(*this);
}
@ -1127,7 +1118,42 @@ void cMinecartWithChest::SetSlot(size_t a_Idx, const cItem & a_Item)
void cMinecartWithChest::OnRightClicked(cPlayer & a_Player)
{
// TODO: Show the chest UI window to the 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);
}
}
}
void cMinecartWithChest::OpenNewWindow()
{
OpenWindow(new cMinecartWithChestWindow(this));
}
void cMinecartWithChest::Destroyed()
{
cItems Pickups;
m_Contents.CopyToItems(Pickups);
GetWorld()->SpawnItemPickups(Pickups, GetPosX(), GetPosY() + 1, GetPosZ(), 4);
}

View File

@ -10,6 +10,8 @@
#pragma once
#include "Entity.h"
#include "World.h"
#include "../UI/WindowOwner.h"
@ -108,27 +110,46 @@ protected:
class cMinecartWithChest :
public cMinecart
public cMinecart,
public cItemGrid::cListener,
public cEntityWindowOwner
{
typedef cMinecart super;
public:
CLASS_PROTODEF(cMinecartWithChest)
/// Number of item slots in the chest
static const int NumSlots = 9 * 3;
cMinecartWithChest(double a_X, double a_Y, double a_Z);
enum
{
ContentsHeight = 3,
ContentsWidth = 9,
};
const cItem & GetSlot(int a_Idx) const { return m_Items[a_Idx]; }
cItem & GetSlot(int a_Idx) { return m_Items[a_Idx]; }
void SetSlot(size_t a_Idx, const cItem & a_Item);
const cItem & GetSlot(int a_Idx) const { return m_Contents.GetSlot(a_Idx); }
void SetSlot(size_t a_Idx, const cItem & a_Item) { m_Contents.SetSlot(a_Idx, a_Item); }
protected:
cItemGrid m_Contents;
void OpenNewWindow(void);
virtual void Destroyed() override;
/// The chest contents:
cItem m_Items[NumSlots];
// cItemGrid::cListener overrides:
virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum)
{
UNUSED(a_SlotNum);
ASSERT(a_Grid == &m_Contents);
if (m_World != NULL)
{
if (GetWindow() != NULL)
{
GetWindow()->BroadcastWholeWindow();
}
m_World->MarkChunkDirty(GetChunkX(), GetChunkZ());
}
}
// cEntity overrides:
virtual void OnRightClicked(cPlayer & a_Player) override;

View File

@ -10,6 +10,7 @@
#include "../BlockEntities/DropSpenserEntity.h"
#include "../BlockEntities/EnderChestEntity.h"
#include "../BlockEntities/FurnaceEntity.h"
#include "../Entities/Minecart.h"
#include "../Items/ItemHandler.h"
#include "Window.h"
#include "../CraftingRecipes.h"
@ -1919,6 +1920,40 @@ void cSlotAreaFurnace::HandleSmeltItem(const cItem & a_Result, cPlayer & a_Playe
////////////////////////////////////////////////////////////////////////////////
// cSlotAreaMinecartWithChest:
cSlotAreaMinecartWithChest::cSlotAreaMinecartWithChest(cMinecartWithChest * a_Chest, cWindow & a_ParentWindow) :
cSlotArea(27, a_ParentWindow),
m_Chest(a_Chest)
{
}
const cItem * cSlotAreaMinecartWithChest::GetSlot(int a_SlotNum, cPlayer & a_Player) const
{
// a_SlotNum ranges from 0 to 26, use that to index the minecart chest entity's inventory directly:
UNUSED(a_Player);
return &(m_Chest->GetSlot(a_SlotNum));
}
void cSlotAreaMinecartWithChest::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item)
{
UNUSED(a_Player);
m_Chest->SetSlot(a_SlotNum, a_Item);
}
////////////////////////////////////////////////////////////////////////////////
// cSlotAreaInventoryBase:

View File

@ -20,6 +20,7 @@ class cChestEntity;
class cDropSpenserEntity;
class cEnderChestEntity;
class cFurnaceEntity;
class cMinecartWithChest;
class cCraftingRecipe;
class cEnchantingWindow;
class cWorld;
@ -448,10 +449,27 @@ protected:
// cItemGrid::cListener overrides:
virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override;
/// Called after an item has been smelted to handle statistics e.t.c.
/// Called after an item has been smelted to handle statistics etc.
void HandleSmeltItem(const cItem & a_Result, cPlayer & a_Player);
} ;
class cSlotAreaMinecartWithChest :
public cSlotArea
{
public:
cSlotAreaMinecartWithChest(cMinecartWithChest * a_ChestCart, cWindow & a_ParentWindow);
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
protected:
cMinecartWithChest * m_Chest;
};

View File

@ -14,6 +14,7 @@
#include "../BlockEntities/DropSpenserEntity.h"
#include "../BlockEntities/EnderChestEntity.h"
#include "../BlockEntities/HopperEntity.h"
#include "../Entities/Minecart.h"
#include "../Root.h"
#include "../Bindings/PluginManager.h"
@ -1075,6 +1076,34 @@ cChestWindow::~cChestWindow()
////////////////////////////////////////////////////////////////////////////////
// cMinecartWithChestWindow:
cMinecartWithChestWindow::cMinecartWithChestWindow(cMinecartWithChest * a_ChestCart) :
cWindow(wtChest, "Minecart with Chest"),
m_ChestCart(a_ChestCart)
{
m_ShouldDistributeToHotbarFirst = false;
m_SlotAreas.push_back(new cSlotAreaMinecartWithChest(a_ChestCart, *this));
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
a_ChestCart->GetWorld()->BroadcastSoundEffect("random.chestopen", a_ChestCart->GetPosX(), a_ChestCart->GetPosY(), a_ChestCart->GetPosZ(), 1, 1);
}
cMinecartWithChestWindow::~cMinecartWithChestWindow()
{
m_ChestCart->GetWorld()->BroadcastSoundEffect("random.chestclosed", m_ChestCart->GetPosX(), m_ChestCart->GetPosY(), m_ChestCart->GetPosZ(), 1, 1);
}
////////////////////////////////////////////////////////////////////////////////
// cDropSpenserWindow:
@ -1101,6 +1130,7 @@ cEnderChestWindow::cEnderChestWindow(cEnderChestEntity * a_EnderChest) :
m_BlockY(a_EnderChest->GetPosY()),
m_BlockZ(a_EnderChest->GetPosZ())
{
m_ShouldDistributeToHotbarFirst = false;
m_SlotAreas.push_back(new cSlotAreaEnderChest(a_EnderChest, *this));
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));

View File

@ -23,6 +23,7 @@ class cDropSpenserEntity;
class cEnderChestEntity;
class cFurnaceEntity;
class cHopperEntity;
class cMinecartWithChest;
class cBeaconEntity;
class cSlotArea;
class cSlotAreaAnvil;
@ -361,6 +362,20 @@ protected:
class cMinecartWithChestWindow :
public cWindow
{
public:
cMinecartWithChestWindow(cMinecartWithChest * a_ChestCart);
~cMinecartWithChestWindow();
private:
cMinecartWithChest * m_ChestCart;
};
class cEnderChestWindow :
public cWindow
{

View File

@ -1,4 +1,3 @@
#pragma once
#include "../BlockEntities/BlockEntity.h"
@ -16,12 +15,6 @@ for entities / players in motion to close their windows when they get too far aw
// class cWindow;
/**
Base class for the window owning
*/
@ -32,16 +25,16 @@ public:
m_Window(NULL)
{
}
virtual ~cWindowOwner()
{
}
void CloseWindow(void)
{
m_Window = NULL;
}
void OpenWindow(cWindow * a_Window)
{
m_Window = a_Window;
@ -54,11 +47,11 @@ public:
}
/// Returns the block position at which the element owning the window is
virtual void GetBlockPos(int & a_BlockX, int & a_BlockY, int & a_BlockZ) = 0;
virtual Vector3i GetBlockPos(void) = 0;
private:
cWindow * m_Window;
} ;
};
@ -71,26 +64,19 @@ class cBlockEntityWindowOwner :
public cWindowOwner
{
public:
cBlockEntityWindowOwner(void) :
m_BlockEntity(NULL)
cBlockEntityWindowOwner(cBlockEntity * a_BlockEntity) :
m_BlockEntity(a_BlockEntity)
{
}
void SetBlockEntity(cBlockEntity * a_BlockEntity)
virtual Vector3i GetBlockPos(void) override
{
m_BlockEntity = a_BlockEntity;
return Vector3i(m_BlockEntity->GetPosX(), m_BlockEntity->GetPosY(), m_BlockEntity->GetPosZ());
}
virtual void GetBlockPos(int & a_BlockX, int & a_BlockY, int & a_BlockZ) override
{
a_BlockX = m_BlockEntity->GetPosX();
a_BlockY = m_BlockEntity->GetPosY();
a_BlockZ = m_BlockEntity->GetPosZ();
}
private:
cBlockEntity * m_BlockEntity;
} ;
};
@ -103,26 +89,19 @@ class cEntityWindowOwner :
public cWindowOwner
{
public:
cEntityWindowOwner(void) :
m_Entity(NULL)
cEntityWindowOwner(cEntity * a_Entity) :
m_Entity(a_Entity)
{
}
void SetEntity(cEntity * a_Entity)
{
m_Entity = a_Entity;
}
virtual void GetBlockPos(int & a_BlockX, int & a_BlockY, int & a_BlockZ) override
virtual Vector3i GetBlockPos(void) override
{
a_BlockX = (int)floor(m_Entity->GetPosX() + 0.5);
a_BlockY = (int)floor(m_Entity->GetPosY() + 0.5);
a_BlockZ = (int)floor(m_Entity->GetPosZ() + 0.5);
return m_Entity->GetPosition().Floor();
}
private:
cEntity * m_Entity;
} ;
};

View File

@ -752,7 +752,7 @@ void cNBTChunkSerializer::AddItemFrameEntity(cItemFrame * a_ItemFrame)
void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart)
{
m_Writer.BeginList("Items", TAG_Compound);
for (int i = 0; i < cMinecartWithChest::NumSlots; i++)
for (int i = 0; i < cMinecartWithChest::ContentsHeight * cMinecartWithChest::ContentsWidth; i++)
{
const cItem & Item = a_Minecart->GetSlot(i);
if (Item.IsEmpty())