summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@hotmail.co.uk>2014-09-13 00:18:02 +0200
committerTiger Wang <ziwei.tiger@hotmail.co.uk>2014-09-13 00:18:02 +0200
commit3e741134279e02d204a8d4638f2d46dfbf814d0c (patch)
treea6781315a66a2fb6f8c16ab21f9f36ea7741fb6d
parentFixed friction being applied whilst airborne (diff)
downloadcuberite-3e741134279e02d204a8d4638f2d46dfbf814d0c.tar
cuberite-3e741134279e02d204a8d4638f2d46dfbf814d0c.tar.gz
cuberite-3e741134279e02d204a8d4638f2d46dfbf814d0c.tar.bz2
cuberite-3e741134279e02d204a8d4638f2d46dfbf814d0c.tar.lz
cuberite-3e741134279e02d204a8d4638f2d46dfbf814d0c.tar.xz
cuberite-3e741134279e02d204a8d4638f2d46dfbf814d0c.tar.zst
cuberite-3e741134279e02d204a8d4638f2d46dfbf814d0c.zip
-rw-r--r--src/BlockEntities/BlockEntityWithItems.h2
-rw-r--r--src/BlockEntities/ChestEntity.cpp1
-rw-r--r--src/BlockEntities/DispenserEntity.cpp1
-rw-r--r--src/BlockEntities/DropSpenserEntity.cpp1
-rw-r--r--src/BlockEntities/DropperEntity.cpp1
-rw-r--r--src/BlockEntities/EnderChestEntity.h2
-rw-r--r--src/BlockEntities/FurnaceEntity.cpp1
-rw-r--r--src/Entities/Minecart.cpp41
-rw-r--r--src/Entities/Minecart.h40
-rw-r--r--src/UI/SlotArea.cpp35
-rw-r--r--src/UI/SlotArea.h14
-rw-r--r--src/UI/Window.cpp30
-rw-r--r--src/UI/Window.h15
-rw-r--r--src/UI/WindowOwner.h69
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp2
15 files changed, 161 insertions, 94 deletions
diff --git a/src/BlockEntities/BlockEntityWithItems.h b/src/BlockEntities/BlockEntityWithItems.h
index 5f1639d45..c19958e8d 100644
--- a/src/BlockEntities/BlockEntityWithItems.h
+++ b/src/BlockEntities/BlockEntityWithItems.h
@@ -23,7 +23,7 @@ class cBlockEntityWithItems :
// tolua_end
// tolua doesn't seem to support multiple inheritance?
, public cItemGrid::cListener
- , public cBlockEntityWindowOwner
+ , public cWindowOwner
// tolua_begin
{
typedef cBlockEntity super;
diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp
index 21e1f6ba2..13831b64a 100644
--- a/src/BlockEntities/ChestEntity.cpp
+++ b/src/BlockEntities/ChestEntity.cpp
@@ -15,7 +15,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);
}
diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp
index c02c68afa..649107dbb 100644
--- a/src/BlockEntities/DispenserEntity.cpp
+++ b/src/BlockEntities/DispenserEntity.cpp
@@ -17,7 +17,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
}
diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp
index dc38e3e9b..c11a8c796 100644
--- a/src/BlockEntities/DropSpenserEntity.cpp
+++ b/src/BlockEntities/DropSpenserEntity.cpp
@@ -19,7 +19,6 @@ cDropSpenserEntity::cDropSpenserEntity(BLOCKTYPE a_BlockType, int a_BlockX, int
m_ShouldDropSpense(false),
m_IsPowered(false)
{
- SetBlockEntity(this); // cBlockEntityWindowOwner
}
diff --git a/src/BlockEntities/DropperEntity.cpp b/src/BlockEntities/DropperEntity.cpp
index 5d4a8ad97..8f9ef210d 100644
--- a/src/BlockEntities/DropperEntity.cpp
+++ b/src/BlockEntities/DropperEntity.cpp
@@ -15,7 +15,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
}
diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h
index ed178f6fc..0715e9a29 100644
--- a/src/BlockEntities/EnderChestEntity.h
+++ b/src/BlockEntities/EnderChestEntity.h
@@ -12,7 +12,7 @@
// tolua_begin
class cEnderChestEntity :
public cBlockEntity,
- public cBlockEntityWindowOwner
+ public cWindowOwner
{
typedef cBlockEntity super;
diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp
index 72fd7f2b3..d2ffd643b 100644
--- a/src/BlockEntities/FurnaceEntity.cpp
+++ b/src/BlockEntities/FurnaceEntity.cpp
@@ -36,7 +36,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);
}
diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp
index 1501eea84..a3927298e 100644
--- a/src/Entities/Minecart.cpp
+++ b/src/Entities/Minecart.cpp
@@ -1103,29 +1103,54 @@ 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),
+ m_Contents(ContentsWidth, ContentsHeight)
{
+ m_Contents.AddListener(*this);
}
-void cMinecartWithChest::SetSlot(size_t a_Idx, const cItem & a_Item)
+void cMinecartWithChest::OnRightClicked(cPlayer & a_Player)
{
- ASSERT(a_Idx < ARRAYCOUNT(m_Items));
-
- m_Items[a_Idx] = a_Item;
+ // 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::OnRightClicked(cPlayer & a_Player)
+void cMinecartWithChest::OpenNewWindow()
+{
+ OpenWindow(new cMinecartWithChestWindow(this));
+}
+
+
+
+
+
+void cMinecartWithChest::Destroyed()
{
- // Show the chest UI window to the player
- // TODO
+ cItems Pickups;
+ m_Contents.CopyToItems(Pickups);
+ GetWorld()->SpawnItemPickups(Pickups, GetPosX(), GetPosY() + 1, GetPosZ(), 4);
}
diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h
index 410d3c77d..f77a171ba 100644
--- a/src/Entities/Minecart.h
+++ b/src/Entities/Minecart.h
@@ -10,6 +10,7 @@
#pragma once
#include "Entity.h"
+#include "../UI/WindowOwner.h"
@@ -108,27 +109,46 @@ protected:
class cMinecartWithChest :
- public cMinecart
+ public cMinecart,
+ public cItemGrid::cListener,
+ public cWindowOwner
{
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;
diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp
index b4facb2d3..999bed989 100644
--- a/src/UI/SlotArea.cpp
+++ b/src/UI/SlotArea.cpp
@@ -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"
@@ -1920,6 +1921,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:
cSlotAreaInventoryBase::cSlotAreaInventoryBase(int a_NumSlots, int a_SlotOffset, cWindow & a_ParentWindow) :
diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h
index 6bbc87b76..0a35527d1 100644
--- a/src/UI/SlotArea.h
+++ b/src/UI/SlotArea.h
@@ -20,6 +20,7 @@ class cChestEntity;
class cDropSpenserEntity;
class cEnderChestEntity;
class cFurnaceEntity;
+class cMinecartWithChest;
class cCraftingRecipe;
class cEnchantingWindow;
class cWorld;
@@ -455,3 +456,16 @@ protected:
+
+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;
+}; \ No newline at end of file
diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp
index 66900269f..fd80a017d 100644
--- a/src/UI/Window.cpp
+++ b/src/UI/Window.cpp
@@ -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"
@@ -1048,6 +1049,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:
cDropSpenserWindow::cDropSpenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserEntity * a_DropSpenser) :
@@ -1073,6 +1102,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));
diff --git a/src/UI/Window.h b/src/UI/Window.h
index 3d860407f..f47cf4b99 100644
--- a/src/UI/Window.h
+++ b/src/UI/Window.h
@@ -23,6 +23,7 @@ class cDropSpenserEntity;
class cEnderChestEntity;
class cFurnaceEntity;
class cHopperEntity;
+class cMinecartWithChest;
class cBeaconEntity;
class cSlotArea;
class cSlotAreaAnvil;
@@ -360,6 +361,20 @@ protected:
+class cMinecartWithChestWindow :
+ public cWindow
+{
+public:
+ cMinecartWithChestWindow(cMinecartWithChest * a_ChestCart);
+ ~cMinecartWithChestWindow();
+private:
+ cMinecartWithChest * m_ChestCart;
+};
+
+
+
+
+
class cEnderChestWindow :
public cWindow
{
diff --git a/src/UI/WindowOwner.h b/src/UI/WindowOwner.h
index 7a7941e37..a8be3e6cb 100644
--- a/src/UI/WindowOwner.h
+++ b/src/UI/WindowOwner.h
@@ -52,77 +52,10 @@ public:
{
return m_Window;
}
-
- /// 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;
private:
cWindow * m_Window;
-} ;
-
-
-
-
-
-/**
-Window owner that is associated with a block entity (chest, furnace, ...)
-*/
-class cBlockEntityWindowOwner :
- public cWindowOwner
-{
-public:
- cBlockEntityWindowOwner(void) :
- m_BlockEntity(NULL)
- {
- }
-
- void SetBlockEntity(cBlockEntity * a_BlockEntity)
- {
- m_BlockEntity = a_BlockEntity;
- }
-
- 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;
-} ;
-
-
-
-
-
-/**
-Window owner that is associated with an entity (chest minecart)
-*/
-class cEntityWindowOwner :
- public cWindowOwner
-{
-public:
- cEntityWindowOwner(void) :
- m_Entity(NULL)
- {
- }
-
- void SetEntity(cEntity * a_Entity)
- {
- m_Entity = a_Entity;
- }
-
- virtual void GetBlockPos(int & a_BlockX, int & a_BlockY, int & a_BlockZ) 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);
- }
-
-private:
- cEntity * m_Entity;
-} ;
+};
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index 68e541eba..963e016d6 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -738,7 +738,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())