summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Entities/HangingEntity.cpp2
-rw-r--r--src/Entities/HangingEntity.h13
-rw-r--r--src/Entities/ItemFrame.cpp11
-rw-r--r--src/Entities/ItemFrame.h1
-rw-r--r--src/Entities/Painting.cpp18
-rw-r--r--src/Entities/Painting.h18
-rw-r--r--src/Items/ItemPainting.h19
-rw-r--r--src/Protocol/Protocol17x.cpp2
-rw-r--r--src/Protocol/Protocol18x.cpp10
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp30
-rw-r--r--src/WorldStorage/NBTChunkSerializer.h2
-rwxr-xr-xsrc/WorldStorage/WSSAnvil.cpp28
-rwxr-xr-xsrc/WorldStorage/WSSAnvil.h1
13 files changed, 83 insertions, 72 deletions
diff --git a/src/Entities/HangingEntity.cpp b/src/Entities/HangingEntity.cpp
index a3d05204a..a37d8702e 100644
--- a/src/Entities/HangingEntity.cpp
+++ b/src/Entities/HangingEntity.cpp
@@ -24,8 +24,6 @@ cHangingEntity::cHangingEntity(eEntityType a_EntityType, eBlockFace a_Facing, do
void cHangingEntity::SpawnOn(cClientHandle & a_ClientHandle)
{
SetYaw(GetProtocolFacing() * 90);
- a_ClientHandle.SendSpawnObject(*this, 71, GetProtocolFacing(), (Byte)GetYaw(), (Byte)GetPitch());
- a_ClientHandle.SendEntityMetadata(*this);
}
diff --git a/src/Entities/HangingEntity.h b/src/Entities/HangingEntity.h
index de93a73fe..8c9e93622 100644
--- a/src/Entities/HangingEntity.h
+++ b/src/Entities/HangingEntity.h
@@ -41,10 +41,14 @@ public:
m_Facing = a_Facing;
}
-private:
+protected:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
- virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override {}
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override
+ {
+ UNUSED(a_Dt);
+ UNUSED(a_Chunk);
+ }
/** Converts protocol hanging item facing to eBlockFace values */
inline static eBlockFace ProtocolFaceToBlockFace(Byte a_ProtocolFace)
@@ -84,8 +88,9 @@ private:
case BLOCK_FACE_XP: Dir = 3; break;
default:
{
- LOGINFO("Invalid facing (%d) in a cHangingEntity, adjusting to BLOCK_FACE_XP.", a_BlockFace);
- // Uncomment when entities are initialised with their real data, instead of dummy values: ASSERT(!"Tried to convert a bad facing!");
+ // Uncomment when entities are initialised with their real data, instead of dummy values:
+ // LOGINFO("Invalid facing (%d) in a cHangingEntity, adjusting to BLOCK_FACE_XP.", a_BlockFace);
+ // ASSERT(!"Tried to convert a bad facing!");
Dir = cHangingEntity::BlockFaceToProtocolFace(BLOCK_FACE_XP);
}
diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp
index dfffcd3ed..4e6e38f1f 100644
--- a/src/Entities/ItemFrame.cpp
+++ b/src/Entities/ItemFrame.cpp
@@ -92,3 +92,14 @@ void cItemFrame::GetDrops(cItems & a_Items, cEntity * a_Killer)
+
+void cItemFrame::SpawnOn(cClientHandle & a_ClientHandle)
+{
+ super::SpawnOn(a_ClientHandle);
+ a_ClientHandle.SendSpawnObject(*this, 71, GetProtocolFacing(), (Byte)GetYaw(), (Byte)GetPitch());
+ a_ClientHandle.SendEntityMetadata(*this);
+}
+
+
+
+
diff --git a/src/Entities/ItemFrame.h b/src/Entities/ItemFrame.h
index ced8c37af..2444b26a3 100644
--- a/src/Entities/ItemFrame.h
+++ b/src/Entities/ItemFrame.h
@@ -42,6 +42,7 @@ private:
virtual void OnRightClicked(cPlayer & a_Player) override;
virtual void KilledBy(TakeDamageInfo & a_TDI) override;
virtual void GetDrops(cItems & a_Items, cEntity * a_Killer) override;
+ virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
cItem m_Item;
Byte m_ItemRotation;
diff --git a/src/Entities/Painting.cpp b/src/Entities/Painting.cpp
index 6f6277f28..02a8f6ed0 100644
--- a/src/Entities/Painting.cpp
+++ b/src/Entities/Painting.cpp
@@ -10,10 +10,9 @@
-cPainting::cPainting(const AString & a_Name, int a_Direction, double a_X, double a_Y, double a_Z)
- : cEntity(etPainting, a_X, a_Y, a_Z, 1, 1),
- m_Name(a_Name),
- m_Direction(a_Direction)
+cPainting::cPainting(const AString & a_Name, eBlockFace a_Direction, double a_X, double a_Y, double a_Z)
+ : cHangingEntity(etPainting, a_Direction, a_X, a_Y, a_Z),
+ m_Name(a_Name)
{
}
@@ -24,6 +23,7 @@ cPainting::cPainting(const AString & a_Name, int a_Direction, double a_X, double
void cPainting::SpawnOn(cClientHandle & a_Client)
{
+ super::SpawnOn(a_Client);
a_Client.SendPaintingSpawn(*this);
}
@@ -31,16 +31,6 @@ void cPainting::SpawnOn(cClientHandle & a_Client)
-void cPainting::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
-{
- UNUSED(a_Dt);
- UNUSED(a_Chunk);
-}
-
-
-
-
-
void cPainting::GetDrops(cItems & a_Items, cEntity * a_Killer)
{
if ((a_Killer != nullptr) && a_Killer->IsPlayer() && !((cPlayer *)a_Killer)->IsGameModeCreative())
diff --git a/src/Entities/Painting.h b/src/Entities/Painting.h
index 6e8a382fc..20968d4f0 100644
--- a/src/Entities/Painting.h
+++ b/src/Entities/Painting.h
@@ -1,7 +1,7 @@
#pragma once
-#include "Entity.h"
+#include "HangingEntity.h"
@@ -9,9 +9,9 @@
// tolua_begin
class cPainting :
- public cEntity
+ public cHangingEntity
{
- typedef cEntity super;
+ typedef cHangingEntity super;
public:
@@ -19,19 +19,14 @@ public:
CLASS_PROTODEF(cPainting)
- cPainting(const AString & a_Name, int a_Direction, double a_X, double a_Y, double a_Z);
+ cPainting(const AString & a_Name, eBlockFace a_Direction, double a_X, double a_Y, double a_Z);
- // tolua_begin
-
- const AString & GetName(void) const { return m_Name; }
- int GetDirection(void) const { return m_Direction; }
-
- // tolua_end
+ /** Returns the protocol name of the painting */
+ const AString & GetName(void) const { return m_Name; } // tolua_export
private:
virtual void SpawnOn(cClientHandle & a_Client) override;
- virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void GetDrops(cItems & a_Items, cEntity * a_Killer) override;
virtual void KilledBy(TakeDamageInfo & a_TDI) override
{
@@ -40,7 +35,6 @@ private:
}
AString m_Name;
- int m_Direction;
}; // tolua_export
diff --git a/src/Items/ItemPainting.h b/src/Items/ItemPainting.h
index a2a77ce21..d6f2e24b4 100644
--- a/src/Items/ItemPainting.h
+++ b/src/Items/ItemPainting.h
@@ -21,30 +21,17 @@ public:
virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override
{
- if (a_Dir == BLOCK_FACE_NONE)
+ if ((a_Dir == BLOCK_FACE_NONE) || (a_Dir == BLOCK_FACE_YM) || (a_Dir == BLOCK_FACE_YP))
{
- // Client sends this if clicked on top or bottom face
+ // Paintings can't be flatly placed
return false;
}
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Dir); // Make sure block that will be occupied is free
BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Dir, true); // We want the clicked block, so go back again
if (Block == E_BLOCK_AIR)
{
- int Dir = 0;
-
- // The client uses different values for painting directions and block faces. Our constants are for the block faces, so we convert them here to painting faces
- switch (a_Dir)
- {
- case BLOCK_FACE_ZP: break; // Initialised to zero
- case BLOCK_FACE_ZM: Dir = 2; break;
- case BLOCK_FACE_XM: Dir = 1; break;
- case BLOCK_FACE_XP: Dir = 3; break;
- default: ASSERT(!"Unhandled block face when trying spawn painting!"); return false;
- }
-
static const struct // Define all the possible painting titles
{
AString Title;
@@ -78,7 +65,7 @@ public:
{ "BurningSkull" }
};
- cPainting * Painting = new cPainting(gPaintingTitlesList[a_World->GetTickRandomNumber(ARRAYCOUNT(gPaintingTitlesList) - 1)].Title, Dir, a_BlockX, a_BlockY, a_BlockZ);
+ cPainting * Painting = new cPainting(gPaintingTitlesList[a_World->GetTickRandomNumber(ARRAYCOUNT(gPaintingTitlesList) - 1)].Title, a_Dir, a_BlockX, a_BlockY, a_BlockZ);
Painting->Initialize(*a_World);
if (!a_Player->IsGameModeCreative())
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index f78c2e54b..9abe81238 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -637,7 +637,7 @@ void cProtocol172::SendPaintingSpawn(const cPainting & a_Painting)
Pkt.WriteInt(static_cast<int>(a_Painting.GetPosX()));
Pkt.WriteInt(static_cast<int>(a_Painting.GetPosY()));
Pkt.WriteInt(static_cast<int>(a_Painting.GetPosZ()));
- Pkt.WriteInt(a_Painting.GetDirection());
+ Pkt.WriteInt(a_Painting.GetProtocolFacing());
}
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 22280f800..52c369200 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -632,19 +632,11 @@ void cProtocol180::SendPaintingSpawn(const cPainting & a_Painting)
double PosY = a_Painting.GetPosY();
double PosZ = a_Painting.GetPosZ();
- switch (a_Painting.GetDirection())
- {
- case 0: PosZ += 1; break;
- case 1: PosX -= 1; break;
- case 2: PosZ -= 1; break;
- case 3: PosX += 1; break;
- }
-
cPacketizer Pkt(*this, 0x10); // Spawn Painting packet
Pkt.WriteVarInt(a_Painting.GetUniqueID());
Pkt.WriteString(a_Painting.GetName().c_str());
Pkt.WritePosition((int)PosX, (int)PosY, (int)PosZ);
- Pkt.WriteChar(a_Painting.GetDirection());
+ Pkt.WriteChar(a_Painting.GetProtocolFacing());
}
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index 4f78dd245..10231ae3b 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -36,20 +36,9 @@
#include "../Entities/ExpOrb.h"
#include "../Entities/HangingEntity.h"
#include "../Entities/ItemFrame.h"
+#include "../Entities/Painting.h"
-#include "../Mobs/Monster.h"
-#include "../Mobs/Bat.h"
-#include "../Mobs/Creeper.h"
-#include "../Mobs/Enderman.h"
-#include "../Mobs/Horse.h"
-#include "../Mobs/MagmaCube.h"
-#include "../Mobs/Sheep.h"
-#include "../Mobs/Slime.h"
-#include "../Mobs/Skeleton.h"
-#include "../Mobs/Villager.h"
-#include "../Mobs/Wither.h"
-#include "../Mobs/Wolf.h"
-#include "../Mobs/Zombie.h"
+#include "../Mobs/IncludeAllMonsters.h"
@@ -776,6 +765,19 @@ void cNBTChunkSerializer::AddItemFrameEntity(cItemFrame * a_ItemFrame)
+void cNBTChunkSerializer::AddPaintingEntity(cPainting * a_Painting)
+{
+ m_Writer.BeginCompound("");
+ AddBasicEntity(a_Painting, "Painting");
+ AddHangingEntity(a_Painting);
+ m_Writer.AddString("Motive", a_Painting->GetName());
+ m_Writer.EndCompound();
+}
+
+
+
+
+
void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart)
{
m_Writer.BeginList("Items", TAG_Compound);
@@ -874,7 +876,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity)
case cEntity::etTNT: AddTNTEntity ((cTNTEntity *) a_Entity); break;
case cEntity::etExpOrb: AddExpOrbEntity ((cExpOrb *) a_Entity); break;
case cEntity::etItemFrame: AddItemFrameEntity ((cItemFrame *) a_Entity); break;
- case cEntity::etPainting: /* TODO */ break;
+ case cEntity::etPainting: AddPaintingEntity (reinterpret_cast<cPainting *>(a_Entity)); break;
case cEntity::etPlayer: return; // Players aren't saved into the world
default:
{
diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h
index 4c066b9af..f30cd59d5 100644
--- a/src/WorldStorage/NBTChunkSerializer.h
+++ b/src/WorldStorage/NBTChunkSerializer.h
@@ -48,6 +48,7 @@ class cTNTEntity;
class cExpOrb;
class cHangingEntity;
class cItemFrame;
+class cPainting;
class cEntityEffect;
@@ -123,6 +124,7 @@ protected:
void AddTNTEntity (cTNTEntity * a_TNT);
void AddExpOrbEntity (cExpOrb * a_ExpOrb);
void AddItemFrameEntity (cItemFrame * a_ItemFrame);
+ void AddPaintingEntity (cPainting * a_Painting);
void AddMinecartChestContents(cMinecartWithChest * a_Minecart);
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index 0aa26834c..7244bcb73 100755
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -50,6 +50,7 @@
#include "../Entities/ExpOrb.h"
#include "../Entities/HangingEntity.h"
#include "../Entities/ItemFrame.h"
+#include "../Entities/Painting.h"
#include "../Protocol/MojangAPI.h"
#include "Server.h"
@@ -1337,6 +1338,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a
{
LoadPickupFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
}
+ else if (strncmp(a_IDTag, "Painting", a_IDTagLength) == 0)
+ {
+ LoadPaintingFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
+ }
else if (strncmp(a_IDTag, "PrimedTnt", a_IDTagLength) == 0)
{
LoadTNTFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
@@ -1808,6 +1813,29 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT
+void cWSSAnvil::LoadPaintingFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
+{
+ // Load painting name:
+ int MotiveTag = a_NBT.FindChildByName(a_TagIdx, "Motive");
+ if ((MotiveTag < 0) || (a_NBT.GetType(MotiveTag) != TAG_String))
+ {
+ return;
+ }
+
+ std::unique_ptr<cPainting> Painting(new cPainting(a_NBT.GetString(MotiveTag), BLOCK_FACE_NONE, 0.0, 0.0, 0.0));
+ if (!LoadEntityBaseFromNBT(*Painting.get(), a_NBT, a_TagIdx))
+ {
+ return;
+ }
+
+ LoadHangingFromNBT(*Painting.get(), a_NBT, a_TagIdx);
+ a_Entities.push_back(Painting.release());
+}
+
+
+
+
+
void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
{
std::unique_ptr<cArrowEntity> Arrow(new cArrowEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0)));
diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h
index 362796614..892645785 100755
--- a/src/WorldStorage/WSSAnvil.h
+++ b/src/WorldStorage/WSSAnvil.h
@@ -166,6 +166,7 @@ protected:
void LoadExpOrbFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadHangingFromNBT (cHangingEntity & a_Hanging, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadItemFrameFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
+ void LoadPaintingFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadMinecartRFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadMinecartCFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);