summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/BlockEntities/BlockEntity.cpp2
-rw-r--r--src/BlockEntities/SkullEntity.cpp110
-rw-r--r--src/BlockEntities/SkullEntity.h79
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/Chunk.cpp2
-rw-r--r--src/Defines.h37
-rw-r--r--src/Items/ItemHandler.cpp2
-rw-r--r--src/Items/ItemSkull.h43
-rw-r--r--src/Protocol/Protocol17x.cpp14
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp26
-rw-r--r--src/WorldStorage/NBTChunkSerializer.h2
-rw-r--r--src/WorldStorage/WSSAnvil.cpp40
-rw-r--r--src/WorldStorage/WSSAnvil.h1
13 files changed, 354 insertions, 5 deletions
diff --git a/src/BlockEntities/BlockEntity.cpp b/src/BlockEntities/BlockEntity.cpp
index 97b5c1a66..441f54a26 100644
--- a/src/BlockEntities/BlockEntity.cpp
+++ b/src/BlockEntities/BlockEntity.cpp
@@ -15,6 +15,7 @@
#include "JukeboxEntity.h"
#include "NoteEntity.h"
#include "SignEntity.h"
+#include "SkullEntity.h"
@@ -31,6 +32,7 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
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_HEAD: return new cSkullEntity (a_BlockX, a_BlockY, a_BlockZ, 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);
diff --git a/src/BlockEntities/SkullEntity.cpp b/src/BlockEntities/SkullEntity.cpp
new file mode 100644
index 000000000..3f3bc00ed
--- /dev/null
+++ b/src/BlockEntities/SkullEntity.cpp
@@ -0,0 +1,110 @@
+
+// SkullEntity.cpp
+
+// Implements the cSkullEntity class representing a single skull/head in the world
+
+#include "Globals.h"
+#include "json/json.h"
+#include "SkullEntity.h"
+#include "../Entities/Player.h"
+
+
+
+
+
+cSkullEntity::cSkullEntity(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta, cWorld * a_World) :
+ super(E_BLOCK_HEAD, a_BlockX, a_BlockY, a_BlockZ, a_World),
+ //m_SkullType(static_cast<eSkullType>(a_BlockMeta)),
+ m_Owner("")
+{
+
+}
+
+
+
+
+
+void cSkullEntity::UsedBy(cPlayer * a_Player)
+{
+ UNUSED(a_Player);
+}
+
+
+
+
+
+void cSkullEntity::SetSkullType(const eSkullType & a_SkullType)
+{
+ if ((!m_Owner.empty()) && (a_SkullType != SKULL_TYPE_PLAYER))
+ {
+ m_Owner = "";
+ }
+ m_SkullType = a_SkullType;
+}
+
+
+
+
+
+void cSkullEntity::SetRotation(eSkullRotation a_Rotation)
+{
+ m_Rotation = a_Rotation;
+}
+
+
+
+
+
+void cSkullEntity::SetOwner(const AString & a_Owner)
+{
+ if ((a_Owner.length() > 16) || (m_SkullType != SKULL_TYPE_PLAYER))
+ {
+ return;
+ }
+ m_Owner = a_Owner;
+}
+
+
+
+
+
+void cSkullEntity::SendTo(cClientHandle & a_Client)
+{
+ a_Client.SendUpdateBlockEntity(*this);
+}
+
+
+
+
+
+bool cSkullEntity::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();
+
+ m_SkullType = static_cast<eSkullType>(a_Value.get("SkullType", 0).asInt());
+ m_Rotation = static_cast<eSkullRotation>(a_Value.get("Rotation", 0).asInt());
+ m_Owner = a_Value.get("Owner", "").asString();
+
+ return true;
+}
+
+
+
+
+
+void cSkullEntity::SaveToJson(Json::Value & a_Value)
+{
+ a_Value["x"] = m_PosX;
+ a_Value["y"] = m_PosY;
+ a_Value["z"] = m_PosZ;
+
+ a_Value["SkullType"] = m_SkullType;
+ a_Value["Rotation"] = m_Rotation;
+ a_Value["Owner"] = m_Owner;
+}
+
+
+
+
diff --git a/src/BlockEntities/SkullEntity.h b/src/BlockEntities/SkullEntity.h
new file mode 100644
index 000000000..6f47c7d30
--- /dev/null
+++ b/src/BlockEntities/SkullEntity.h
@@ -0,0 +1,79 @@
+// SkullEntity.h
+
+// Declares the cSkullEntity class representing a single skull/head in the world
+
+
+
+
+
+#pragma once
+
+#include "BlockEntity.h"
+
+
+
+
+
+namespace Json
+{
+ class Value;
+}
+
+
+
+
+
+// tolua_begin
+
+class cSkullEntity :
+ public cBlockEntity
+{
+ typedef cBlockEntity super;
+
+public:
+
+ // tolua_end
+
+ /// Creates a new skull entity at the specified block coords. a_World may be NULL
+ cSkullEntity(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta, cWorld * a_World);
+
+ bool LoadFromJson( const Json::Value& a_Value );
+ virtual void SaveToJson(Json::Value& a_Value ) override;
+
+ // tolua_begin
+
+ /// Set the Skull Type
+ void SetSkullType(const eSkullType & a_SkullType);
+
+ /// Set the Rotation
+ void SetRotation(eSkullRotation a_Rotation);
+
+ // Set the Player Name for Player Skulls
+ void SetOwner(const AString & a_Owner);
+
+ /// Get the Skull Type
+ eSkullType GetSkullType(void) const { return m_SkullType; }
+
+ /// Get the Rotation
+ eSkullRotation GetRotation(void) const { return m_Rotation; }
+
+ /// Get the setted Player Name
+ AString GetOwner(void) const { return m_Owner; }
+
+ // tolua_end
+
+ virtual void UsedBy(cPlayer * a_Player) override;
+ virtual void SendTo(cClientHandle & a_Client) override;
+
+ static const char * GetClassStatic(void) { return "cSkullEntity"; }
+
+private:
+
+ eSkullType m_SkullType;
+ eSkullRotation m_Rotation;
+ AString m_Owner;
+} ; // tolua_export
+
+
+
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6ba952f92..e46aa3ee5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -39,6 +39,7 @@ if (NOT MSVC)
BlockEntities/JukeboxEntity.h
BlockEntities/NoteEntity.h
BlockEntities/SignEntity.h
+ BlockEntities/SkullEntity.h
BlockID.h
BoundingBox.h
ChatColor.h
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index 3028d24d0..c66dae7b4 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -1314,6 +1314,7 @@ void cChunk::CreateBlockEntities(void)
case E_BLOCK_HOPPER:
case E_BLOCK_SIGN_POST:
case E_BLOCK_WALLSIGN:
+ case E_BLOCK_HEAD:
case E_BLOCK_NOTE_BLOCK:
case E_BLOCK_JUKEBOX:
{
@@ -1442,6 +1443,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
case E_BLOCK_HOPPER:
case E_BLOCK_SIGN_POST:
case E_BLOCK_WALLSIGN:
+ case E_BLOCK_HEAD:
case E_BLOCK_NOTE_BLOCK:
case E_BLOCK_JUKEBOX:
{
diff --git a/src/Defines.h b/src/Defines.h
index f33d1ae56..7e22cbdc5 100644
--- a/src/Defines.h
+++ b/src/Defines.h
@@ -174,6 +174,43 @@ enum eWeather
+enum eSkullType
+{
+ SKULL_TYPE_SKELETON = 0,
+ SKULL_TYPE_WITHER = 1,
+ SKULL_TYPE_ZOMBIE = 2,
+ SKULL_TYPE_PLAYER = 3,
+ SKULL_TYPE_CREEPER = 4,
+} ;
+
+
+
+
+
+enum eSkullRotation
+{
+ SKULL_ROTATION_NORTH = 0,
+ SKULL_ROTATION_NORTH_NORTH_EAST = 1,
+ SKULL_ROTATION_NORTH_EAST = 2,
+ SKULL_ROTATION_EAST_NORTH_EAST = 3,
+ SKULL_ROTATION_EAST = 4,
+ SKULL_ROTATION_EAST_SOUTH_EAST = 5,
+ SKULL_ROTATION_SOUTH_EAST = 6,
+ SKULL_ROTATION_SOUTH_SOUTH_EAST = 7,
+ SKULL_ROTATION_SOUTH = 8,
+ SKULL_ROTATION_SOUTH_SOUTH_WEST = 9,
+ SKULL_ROTATION_SOUTH_WEST = 10,
+ SKULL_ROTATION_WEST_SOUTH_WEST = 11,
+ SKULL_ROTATION_WEST = 12,
+ SKULL_ROTATION_WEST_NORTH_WEST = 13,
+ SKULL_ROTATION_NORTH_WEST = 14,
+ SKULL_ROTATION_NORTH_NORTH_WEST = 15,
+} ;
+
+
+
+
+
inline const char * ClickActionToString(eClickAction a_ClickAction)
{
switch (a_ClickAction)
diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp
index 19913ab24..4ede75cf1 100644
--- a/src/Items/ItemHandler.cpp
+++ b/src/Items/ItemHandler.cpp
@@ -35,6 +35,7 @@
#include "ItemShears.h"
#include "ItemShovel.h"
#include "ItemSign.h"
+#include "ItemSkull.h"
#include "ItemSpawnEgg.h"
#include "ItemSugarcane.h"
#include "ItemSword.h"
@@ -110,6 +111,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
case E_ITEM_SHEARS: return new cItemShearsHandler(a_ItemType);
case E_ITEM_SIGN: return new cItemSignHandler(a_ItemType);
+ case E_ITEM_HEAD: return new cItemSkullHandler(a_ItemType);
case E_ITEM_SNOWBALL: return new cItemSnowballHandler();
case E_ITEM_SPAWN_EGG: return new cItemSpawnEggHandler(a_ItemType);
case E_ITEM_SUGARCANE: return new cItemSugarcaneHandler(a_ItemType);
diff --git a/src/Items/ItemSkull.h b/src/Items/ItemSkull.h
new file mode 100644
index 000000000..f511c8c4a
--- /dev/null
+++ b/src/Items/ItemSkull.h
@@ -0,0 +1,43 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+
+
+
+
+
+class cItemSkullHandler :
+ public cItemHandler
+{
+public:
+ cItemSkullHandler(int a_ItemType) :
+ cItemHandler(a_ItemType)
+ {
+ }
+
+
+ virtual bool IsPlaceable(void) override
+ {
+ return true;
+ }
+
+
+ virtual bool GetPlacementBlockTypeMeta(
+ cWorld * a_World, cPlayer * a_Player,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ,
+ BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
+ ) override
+ {
+ a_BlockType = E_BLOCK_HEAD;
+ a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x0f);
+
+ return true;
+ }
+} ;
+
+
+
+
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index f7d13774d..4d55822fb 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -26,6 +26,7 @@ Implements the 1.7.x protocol classes:
#include "../Mobs/IncludeAllMonsters.h"
#include "../UI/Window.h"
#include "../BlockEntities/CommandBlockEntity.h"
+#include "../BlockEntities/SkullEntity.h"
#include "../CompositeChat.h"
@@ -1042,6 +1043,7 @@ void cProtocol172::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity)
{
case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing
case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text
+ case E_BLOCK_HEAD: Action = 4; break; // Update Skull entity
default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break;
}
Pkt.WriteByte(Action);
@@ -2269,6 +2271,18 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt
}
break;
}
+ case E_BLOCK_HEAD:
+ {
+ cSkullEntity & SkullEntity = (cSkullEntity &)a_BlockEntity;
+
+ Writer.AddInt("x", SkullEntity.GetPosX());
+ Writer.AddInt("y", SkullEntity.GetPosY());
+ Writer.AddInt("z", SkullEntity.GetPosZ());
+ Writer.AddByte("SkullType", SkullEntity.GetSkullType() & 0xFF);
+ Writer.AddByte("Rot", SkullEntity.GetRotation() & 0xFF);
+ Writer.AddString("ExtraType", SkullEntity.GetOwner().c_str());
+ Writer.AddString("id", "Skull"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though
+ }
default: break;
}
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index 95b5e66d2..6da141728 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -19,6 +19,7 @@
#include "../BlockEntities/JukeboxEntity.h"
#include "../BlockEntities/NoteEntity.h"
#include "../BlockEntities/SignEntity.h"
+#include "../BlockEntities/SkullEntity.h"
#include "../Entities/Entity.h"
#include "../Entities/FallingBlock.h"
@@ -248,11 +249,25 @@ void cNBTChunkSerializer::AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock
void cNBTChunkSerializer::AddSignEntity(cSignEntity * a_Sign)
{
m_Writer.BeginCompound("");
- AddBasicTileEntity(a_Sign, "Sign");
- m_Writer.AddString("Text1", a_Sign->GetLine(0));
- m_Writer.AddString("Text2", a_Sign->GetLine(1));
- m_Writer.AddString("Text3", a_Sign->GetLine(2));
- m_Writer.AddString("Text4", a_Sign->GetLine(3));
+ AddBasicTileEntity(a_Sign, "Sign");
+ m_Writer.AddString("Text1", a_Sign->GetLine(0));
+ m_Writer.AddString("Text2", a_Sign->GetLine(1));
+ m_Writer.AddString("Text3", a_Sign->GetLine(2));
+ m_Writer.AddString("Text4", a_Sign->GetLine(3));
+ m_Writer.EndCompound();
+}
+
+
+
+
+
+void cNBTChunkSerializer::AddSkullEntity(cSkullEntity * a_Skull)
+{
+ m_Writer.BeginCompound("");
+ AddBasicTileEntity(a_Skull, "Skull");
+ m_Writer.AddByte ("SkullType", a_Skull->GetSkullType() & 0xFF);
+ m_Writer.AddByte ("Rot", a_Skull->GetRotation() & 0xFF);
+ m_Writer.AddString("ExtraType", a_Skull->GetOwner());
m_Writer.EndCompound();
}
@@ -666,6 +681,7 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity)
case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break;
case E_BLOCK_SIGN_POST:
case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break;
+ case E_BLOCK_HEAD: AddSkullEntity ((cSkullEntity *) 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_COMMAND_BLOCK: AddCommandBlockEntity((cCommandBlockEntity *) a_Entity); break;
diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h
index 245b68063..fd5601e47 100644
--- a/src/WorldStorage/NBTChunkSerializer.h
+++ b/src/WorldStorage/NBTChunkSerializer.h
@@ -29,6 +29,7 @@ class cHopperEntity;
class cJukeboxEntity;
class cNoteEntity;
class cSignEntity;
+class cSkullEntity;
class cFallingBlock;
class cMinecart;
class cMinecartWithChest;
@@ -93,6 +94,7 @@ protected:
void AddJukeboxEntity (cJukeboxEntity * a_Jukebox);
void AddNoteEntity (cNoteEntity * a_Note);
void AddSignEntity (cSignEntity * a_Sign);
+ void AddSkullEntity (cSkullEntity * a_Skull);
void AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock);
// Entities:
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index e95813a3c..89a236f07 100644
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -24,6 +24,7 @@
#include "../BlockEntities/JukeboxEntity.h"
#include "../BlockEntities/NoteEntity.h"
#include "../BlockEntities/SignEntity.h"
+#include "../BlockEntities/SkullEntity.h"
#include "../Mobs/Monster.h"
@@ -597,6 +598,10 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
{
LoadSignFromNBT(a_BlockEntities, a_NBT, Child);
}
+ else if (strncmp(a_NBT.GetData(sID), "Skull", a_NBT.GetDataLength(sID)) == 0)
+ {
+ LoadSkullFromNBT(a_BlockEntities, a_NBT, Child);
+ }
else if (strncmp(a_NBT.GetData(sID), "Trap", a_NBT.GetDataLength(sID)) == 0)
{
LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child);
@@ -927,6 +932,41 @@ void cWSSAnvil::LoadSignFromNBT(cBlockEntityList & a_BlockEntities, const cParse
+void cWSSAnvil::LoadSkullFromNBT(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;
+ }
+ std::auto_ptr<cSkullEntity> Skull(new cSkullEntity(E_BLOCK_HEAD, x, y, z, m_World));
+
+ int currentLine = a_NBT.FindChildByName(a_TagIdx, "SkullType");
+ if (currentLine >= 0)
+ {
+ Skull->SetSkullType(static_cast<eSkullType>(a_NBT.GetByte(currentLine)));
+ }
+
+ currentLine = a_NBT.FindChildByName(a_TagIdx, "Rot");
+ if (currentLine >= 0)
+ {
+ Skull->SetRotation(static_cast<eSkullRotation>(a_NBT.GetByte(currentLine)));
+ }
+
+ currentLine = a_NBT.FindChildByName(a_TagIdx, "ExtraType");
+ if (currentLine >= 0)
+ {
+ Skull->SetOwner(a_NBT.GetString(currentLine));
+ }
+
+ a_BlockEntities.push_back(Skull.release());
+}
+
+
+
+
+
void cWSSAnvil::LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
{
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h
index 5093ad083..9c9e17258 100644
--- a/src/WorldStorage/WSSAnvil.h
+++ b/src/WorldStorage/WSSAnvil.h
@@ -139,6 +139,7 @@ protected:
void LoadJukeboxFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
+ void LoadSkullFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength);