summaryrefslogtreecommitdiffstats
path: root/src/BlockEntities
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/BlockEntities/BlockEntity.cpp22
-rw-r--r--src/BlockEntities/BlockEntityWithItems.h2
-rw-r--r--src/BlockEntities/EnderChestEntity.cpp130
-rw-r--r--src/BlockEntities/EnderChestEntity.h59
4 files changed, 202 insertions, 11 deletions
diff --git a/src/BlockEntities/BlockEntity.cpp b/src/BlockEntities/BlockEntity.cpp
index 41a488717..5d7e4a37a 100644
--- a/src/BlockEntities/BlockEntity.cpp
+++ b/src/BlockEntities/BlockEntity.cpp
@@ -8,6 +8,7 @@
#include "ChestEntity.h"
#include "DispenserEntity.h"
#include "DropperEntity.h"
+#include "EnderChestEntity.h"
#include "FurnaceEntity.h"
#include "HopperEntity.h"
#include "JukeboxEntity.h"
@@ -22,16 +23,17 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
{
switch (a_BlockType)
{
- case E_BLOCK_CHEST: return new cChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_DISPENSER: return new cDispenserEntity(a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
- case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
- case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_WALLSIGN: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_NOTE_BLOCK: return new cNoteEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
- case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_CHEST: return new cChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
+ case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
+ case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_WALLSIGN: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_NOTE_BLOCK: return new cNoteEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
+ case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
}
LOGD("%s: Requesting creation of an unknown block entity - block type %d (%s)",
__FUNCTION__, a_BlockType, ItemTypeToString(a_BlockType).c_str()
diff --git a/src/BlockEntities/BlockEntityWithItems.h b/src/BlockEntities/BlockEntityWithItems.h
index 0846ae17e..f35412e03 100644
--- a/src/BlockEntities/BlockEntityWithItems.h
+++ b/src/BlockEntities/BlockEntityWithItems.h
@@ -48,7 +48,7 @@ public:
cItems Pickups;
m_Contents.CopyToItems(Pickups);
m_Contents.Clear();
- m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ);
+ m_World->SpawnItemPickups(Pickups, m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); // Spawn in centre of block
}
// tolua_begin
diff --git a/src/BlockEntities/EnderChestEntity.cpp b/src/BlockEntities/EnderChestEntity.cpp
new file mode 100644
index 000000000..e53930798
--- /dev/null
+++ b/src/BlockEntities/EnderChestEntity.cpp
@@ -0,0 +1,130 @@
+
+#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
+
+#include "EnderChestEntity.h"
+#include "../Item.h"
+#include "../Entities/Player.h"
+#include "../UI/Window.h"
+#include "json/json.h"
+
+
+
+
+
+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, ContentsWidth, ContentsHeight, a_World)
+{
+ cBlockEntityWindowOwner::SetBlockEntity(this);
+}
+
+
+
+
+
+cEnderChestEntity::~cEnderChestEntity()
+{
+ cWindow * Window = GetWindow();
+ if (Window != NULL)
+ {
+ Window->OwnerDestroyed();
+ }
+}
+
+
+
+
+
+bool cEnderChestEntity::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)
+ {
+ cItem Item;
+ Item.FromJson(*itr);
+ SetSlot(SlotIdx, Item);
+ SlotIdx++;
+ }
+ return true;
+}
+
+
+
+
+
+void cEnderChestEntity::SaveToJson(Json::Value & a_Value)
+{
+ a_Value["x"] = m_PosX;
+ a_Value["y"] = m_PosY;
+ a_Value["z"] = m_PosZ;
+
+ Json::Value AllSlots;
+ for (int i = m_Contents.GetNumSlots() - 1; i >= 0; i--)
+ {
+ Json::Value Slot;
+ m_Contents.GetSlot(i).GetJson(Slot);
+ AllSlots.append(Slot);
+ }
+ a_Value["Slots"] = AllSlots;
+}
+
+
+
+
+
+void cEnderChestEntity::SendTo(cClientHandle & a_Client)
+{
+ // The chest 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 chest is rclked
+
+ UNUSED(a_Client);
+}
+
+
+
+
+
+void cEnderChestEntity::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_PosZ, ChunkX, ChunkZ);
+ m_World->MarkChunkDirty(ChunkX, ChunkZ);
+}
+
+
+
+
+
+void cEnderChestEntity::OpenNewWindow(void)
+{
+ OpenWindow(new cEnderChestWindow(this));
+}
+
+
+
+
diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h
new file mode 100644
index 000000000..683b652b2
--- /dev/null
+++ b/src/BlockEntities/EnderChestEntity.h
@@ -0,0 +1,59 @@
+
+#pragma once
+
+#include "BlockEntityWithItems.h"
+#include "../UI/WindowOwner.h"
+
+
+
+
+
+namespace Json
+{
+ class Value;
+};
+
+class cClientHandle;
+class cServer;
+class cNBTData;
+
+
+
+
+
+class cEnderChestEntity : // tolua_export
+ public cBlockEntityWindowOwner,
+ // tolua_begin
+ public cBlockEntityWithItems
+{
+ typedef cBlockEntityWithItems super;
+
+public:
+ enum {
+ ContentsHeight = 3,
+ ContentsWidth = 9,
+ } ;
+
+ // tolua_end
+
+ /// Constructor used for normal operation
+ cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+
+ virtual ~cEnderChestEntity();
+
+ static const char * GetClassStatic(void) { return "cEnderChestEntity"; }
+
+ bool LoadFromJson(const Json::Value & a_Value);
+
+ // cBlockEntity overrides:
+ 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);
+} ; // tolua_export
+
+
+
+