diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 17e403452..f32b6bec7 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -1416,6 +1416,15 @@ void cClientHandle::SendPickupSpawn(const cPickup & a_Pickup) +void cClientHandle::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) +{ + m_Protocol->SendSpawnFallingBlock(a_FallingBlock); +} + + + + + void cClientHandle::SendSpawnMob(const cMonster & a_Mob) { m_Protocol->SendSpawnMob(a_Mob); diff --git a/source/ClientHandle.h b/source/ClientHandle.h index 03367ebac..cf02bd107 100644 --- a/source/ClientHandle.h +++ b/source/ClientHandle.h @@ -30,6 +30,7 @@ class cPlayer; class cProtocol; class cRedstone; class cWindow; +class cFallingBlock; @@ -109,7 +110,9 @@ public: void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch); // a_Src coords are Block * 8 void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data); void SendBlockBreakAnim (int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage); + void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock); void SendSpawnMob (const cMonster & a_Mob); + void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch); void SendTeleportEntity (const cEntity & a_Entity); void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay); @@ -121,7 +124,6 @@ public: void SendWindowClose (char a_WindowID); void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots); void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ); - void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch); const AString & GetUsername(void) const; //tolua_export void SetUsername( const AString & a_Username ); //tolua_export diff --git a/source/FallingBlock.cpp b/source/FallingBlock.cpp index 13342cdef..7b0fa69fb 100644 --- a/source/FallingBlock.cpp +++ b/source/FallingBlock.cpp @@ -32,7 +32,7 @@ void cFallingBlock::Initialize(cWorld * a_World) void cFallingBlock::SpawnOn(cClientHandle & a_ClientHandle) { - a_ClientHandle.SendSpawnObject(*this, 70, m_BlockType, 0, 0, 0, 0, 0); + a_ClientHandle.SendSpawnFallingBlock(*this); } diff --git a/source/FallingBlock.h b/source/FallingBlock.h index cdf1e1f04..e40b342fe 100644 --- a/source/FallingBlock.h +++ b/source/FallingBlock.h @@ -25,6 +25,9 @@ public: cFallingBlock(const Vector3i & a_BlockPosition, BLOCKTYPE a_BlockType); + BLOCKTYPE GetBlockType(void) const { return m_BlockType; } + + // cEntity overrides: virtual void Initialize(cWorld * a_World) override; virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void Tick(float a_Dt, MTRand & a_TickRandom) override; diff --git a/source/Protocol/Protocol.h b/source/Protocol/Protocol.h index 956d31955..52f3f2e3f 100644 --- a/source/Protocol/Protocol.h +++ b/source/Protocol/Protocol.h @@ -25,6 +25,7 @@ class cPickup; class cMonster; class cChunkDataSerializer; class cWorld; +class cFallingBlock; @@ -80,6 +81,7 @@ public: virtual void SendRespawn (void) = 0; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) = 0; // a_Src coords are Block * 8 virtual void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0; + virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) = 0; virtual void SendSpawnMob (const cMonster & a_Mob) = 0; virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) = 0; virtual void SendTeleportEntity (const cEntity & a_Entity) = 0; diff --git a/source/Protocol/Protocol125.cpp b/source/Protocol/Protocol125.cpp index 821cebfa1..cb1e46193 100644 --- a/source/Protocol/Protocol125.cpp +++ b/source/Protocol/Protocol125.cpp @@ -23,6 +23,7 @@ Documentation: #include "../UI/Window.h" #include "../Root.h" #include "../Server.h" +#include "../FallingBlock.h" @@ -614,6 +615,16 @@ void cProtocol125::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_Src +void cProtocol125::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) +{ + // This protocol version implements falling blocks using the spawn object / vehicle packet: + SendSpawnObject(a_FallingBlock, 70, a_FallingBlock.GetBlockType(), 0, 0, 0, 0, 0); +} + + + + + void cProtocol125::SendSpawnMob(const cMonster & a_Mob) { cCSLock Lock(m_CSPacket); diff --git a/source/Protocol/Protocol125.h b/source/Protocol/Protocol125.h index 84d4f7f41..ec0d976e5 100644 --- a/source/Protocol/Protocol125.h +++ b/source/Protocol/Protocol125.h @@ -58,6 +58,7 @@ public: virtual void SendRespawn (void) override; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8 virtual void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; + virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; diff --git a/source/Protocol/Protocol14x.cpp b/source/Protocol/Protocol14x.cpp index 5c517cd7f..d9be4948c 100644 --- a/source/Protocol/Protocol14x.cpp +++ b/source/Protocol/Protocol14x.cpp @@ -23,6 +23,7 @@ Implements the 1.4.x protocol classes representing these protocols: #include "../Mobs/Monster.h" #include "../UI/Window.h" #include "../Pickup.h" +#include "../FallingBlock.h" @@ -152,6 +153,71 @@ cProtocol146::cProtocol146(cClientHandle * a_Client) : +void cProtocol146::SendPickupSpawn(const cPickup & a_Pickup) +{ + ASSERT(!a_Pickup.GetItem()->IsEmpty()); + + cCSLock Lock(m_CSPacket); + + // Send a SPAWN_OBJECT packet for the base entity: + WriteByte(PACKET_SPAWN_OBJECT); + WriteInt (a_Pickup.GetUniqueID()); + WriteByte(0x02); + WriteInt ((int)(a_Pickup.GetPosX() * 32)); + WriteInt ((int)(a_Pickup.GetPosY() * 32)); + WriteInt ((int)(a_Pickup.GetPosZ() * 32)); + WriteInt (1); + WriteShort((short)(a_Pickup.GetSpeed().x * 32)); + WriteShort((short)(a_Pickup.GetSpeed().y * 32)); + WriteShort((short)(a_Pickup.GetSpeed().z * 32)); + WriteByte(0); + WriteByte(0); + + // Send a ENTITY_METADATA packet with the slot info: + WriteByte(PACKET_ENTITY_METADATA); + WriteInt(a_Pickup.GetUniqueID()); + WriteByte(0xaa); // a slot value at index 10 + WriteItem(*a_Pickup.GetItem()); + WriteByte(0x7f); // End of metadata + Flush(); +} + + + + + +void cProtocol146::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) +{ + // Send two packets - spawn object, then entity metadata + cCSLock Lock(m_CSPacket); + + WriteByte(PACKET_SPAWN_OBJECT); + WriteInt (a_FallingBlock.GetUniqueID()); + WriteByte(70); + WriteInt ((int)(a_FallingBlock.GetPosX() * 32)); + WriteInt ((int)(a_FallingBlock.GetPosY() * 32)); + WriteInt ((int)(a_FallingBlock.GetPosZ() * 32)); + WriteInt (0x800000); + WriteShort(0); + WriteShort(0); + WriteShort(0); + WriteByte (0); + WriteByte (0); + + // TODO: This still doesn't work, although it is exactly the same that the vanilla server sends. WTF? + WriteByte(PACKET_ENTITY_METADATA); + WriteInt(a_FallingBlock.GetUniqueID()); + WriteByte(0xaa); // a slot value at index 10 + cItem Item(a_FallingBlock.GetBlockType(), 1); + WriteItem(Item); + WriteByte(0x7f); // End of metadata + Flush(); +} + + + + + void cProtocol146::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) { cCSLock Lock(m_CSPacket); @@ -177,35 +243,3 @@ void cProtocol146::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, -void cProtocol146::SendPickupSpawn(const cPickup & a_Pickup) -{ - ASSERT(!a_Pickup.GetItem()->IsEmpty()); - - cCSLock Lock(m_CSPacket); - - // Send a SPAWN_OBJECT packet for the base entity: - WriteByte(PACKET_SPAWN_OBJECT); - WriteInt (a_Pickup.GetUniqueID()); - WriteByte(0x02); - WriteInt ((int)(a_Pickup.GetPosX() * 32)); - WriteInt ((int)(a_Pickup.GetPosY() * 32)); - WriteInt ((int)(a_Pickup.GetPosZ() * 32)); - WriteInt (1); - WriteShort((short)(a_Pickup.GetSpeed().x * 32)); - WriteShort((short)(a_Pickup.GetSpeed().y * 32)); - WriteShort((short)(a_Pickup.GetSpeed().z * 32)); - WriteByte(0); - WriteByte(0); - - // Send a ENTITY_METADATA packet with the slot info: - WriteByte(PACKET_ENTITY_METADATA); - WriteInt(a_Pickup.GetUniqueID()); - WriteByte(0xaa); // a slot value at index 10 - WriteItem(*a_Pickup.GetItem()); // TODO: Still not good, needs GZIP! - WriteByte(0x7f); // End of metadata - Flush(); -} - - - - diff --git a/source/Protocol/Protocol14x.h b/source/Protocol/Protocol14x.h index bd8706f40..02888e61f 100644 --- a/source/Protocol/Protocol14x.h +++ b/source/Protocol/Protocol14x.h @@ -52,8 +52,9 @@ class cProtocol146 : public: cProtocol146(cClientHandle * a_Client); - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) override; + virtual void SendPickupSpawn (const cPickup & a_Pickup) override; + virtual void SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) override; + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) override; } ; diff --git a/source/Protocol/ProtocolRecognizer.cpp b/source/Protocol/ProtocolRecognizer.cpp index 43ed82a36..4ab163783 100644 --- a/source/Protocol/ProtocolRecognizer.cpp +++ b/source/Protocol/ProtocolRecognizer.cpp @@ -406,6 +406,16 @@ void cProtocolRecognizer::SendSoundParticleEffect(int a_EffectID, int a_SrcX, in +void cProtocolRecognizer::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendSpawnFallingBlock(a_FallingBlock); +} + + + + + void cProtocolRecognizer::SendSpawnMob(const cMonster & a_Mob) { ASSERT(m_Protocol != NULL); diff --git a/source/Protocol/ProtocolRecognizer.h b/source/Protocol/ProtocolRecognizer.h index fce5c0ba4..e7505fe3c 100644 --- a/source/Protocol/ProtocolRecognizer.h +++ b/source/Protocol/ProtocolRecognizer.h @@ -83,6 +83,7 @@ public: virtual void SendRespawn (void) override; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; virtual void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; + virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override;