From 07ca09574072b303064eafb2751f8f83c865f083 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 4 May 2020 09:10:47 +0100 Subject: Improve entity position updates (#4701) * Make puking pickups fly nicer * Improve entity position updates * Move determination of whether a delta is too big for a packet into the protocol handlers + Less jittery movement + Generalise CollectEntity to take any entity --- src/Protocol/Protocol_1_9.cpp | 128 +++++++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 64 deletions(-) (limited to 'src/Protocol/Protocol_1_9.cpp') diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp index 10aed8cc1..150e81339 100644 --- a/src/Protocol/Protocol_1_9.cpp +++ b/src/Protocol/Protocol_1_9.cpp @@ -170,33 +170,50 @@ void cProtocol_1_9_0::SendEntityMetadata(const cEntity & a_Entity) -void cProtocol_1_9_0::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) +void cProtocol_1_9_0::SendEntityPosition(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, pktEntityRelMove); - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - // TODO: 1.9 changed these from chars to shorts, meaning that there can be more percision and data. Other code needs to be updated for that. - Pkt.WriteBEInt16(a_RelX * 128); - Pkt.WriteBEInt16(a_RelY * 128); - Pkt.WriteBEInt16(a_RelZ * 128); - Pkt.WriteBool(a_Entity.IsOnGround()); -} - + const auto Delta = (a_Entity.GetPosition() - a_Entity.GetLastSentPosition()) * 32 * 128; + // Limitations of a short + static const auto Max = std::numeric_limits::max(); + if ((std::abs(Delta.x) <= Max) && (std::abs(Delta.y) <= Max) && (std::abs(Delta.z) <= Max)) + { + const auto Move = static_cast>(Delta); + // Difference within limitations, use a relative move packet + if (a_Entity.IsOrientationDirty()) + { + cPacketizer Pkt(*this, pktEntityRelMoveLook); + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEInt16(Move.x); + Pkt.WriteBEInt16(Move.y); + Pkt.WriteBEInt16(Move.z); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteBool(a_Entity.IsOnGround()); + } + else + { + cPacketizer Pkt(*this, pktEntityRelMove); + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEInt16(Move.x); + Pkt.WriteBEInt16(Move.y); + Pkt.WriteBEInt16(Move.z); + Pkt.WriteBool(a_Entity.IsOnGround()); + } -void cProtocol_1_9_0::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) -{ - ASSERT(m_State == 3); // In game mode? + return; + } - cPacketizer Pkt(*this, pktEntityRelMoveLook); + // Too big a movement, do a teleport + cPacketizer Pkt(*this, pktTeleportEntity); Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - // TODO: 1.9 changed these from chars to shorts, meaning that there can be more percision and data. Other code needs to be updated for that. - Pkt.WriteBEInt16(a_RelX * 128); - Pkt.WriteBEInt16(a_RelY * 128); - Pkt.WriteBEInt16(a_RelZ * 128); + Pkt.WriteBEDouble(a_Entity.GetPosX()); + Pkt.WriteBEDouble(a_Entity.GetPosY()); + Pkt.WriteBEDouble(a_Entity.GetPosZ()); Pkt.WriteByteAngle(a_Entity.GetYaw()); Pkt.WriteByteAngle(a_Entity.GetPitch()); Pkt.WriteBool(a_Entity.IsOnGround()); @@ -386,7 +403,7 @@ void cProtocol_1_9_0::SendPlayerSpawn(const cPlayer & a_Player) cPacketizer Pkt(*this, pktSpawnOtherPlayer); Pkt.WriteVarInt32(a_Player.GetUniqueID()); Pkt.WriteUUID(a_Player.GetUUID()); - Vector3d LastSentPos = a_Player.GetLastSentPos(); + Vector3d LastSentPos = a_Player.GetLastSentPosition(); Pkt.WriteBEDouble(LastSentPos.x); Pkt.WriteBEDouble(LastSentPos.y + 0.001); // The "+ 0.001" is there because otherwise the player falls through the block they were standing on. Pkt.WriteBEDouble(LastSentPos.z); @@ -428,7 +445,7 @@ void cProtocol_1_9_0::SendSpawnMob(const cMonster & a_Mob) Pkt.WriteBEUInt64(0); Pkt.WriteBEUInt64(a_Mob.GetUniqueID()); Pkt.WriteBEUInt8(static_cast(GetProtocolMobType(a_Mob.GetMobType()))); - Vector3d LastSentPos = a_Mob.GetLastSentPos(); + Vector3d LastSentPos = a_Mob.GetLastSentPosition(); Pkt.WriteBEDouble(LastSentPos.x); Pkt.WriteBEDouble(LastSentPos.y); Pkt.WriteBEDouble(LastSentPos.z); @@ -446,24 +463,6 @@ void cProtocol_1_9_0::SendSpawnMob(const cMonster & a_Mob) -void cProtocol_1_9_0::SendTeleportEntity(const cEntity & a_Entity) -{ - ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, pktTeleportEntity); - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEDouble(a_Entity.GetPosX()); - Pkt.WriteBEDouble(a_Entity.GetPosY()); - Pkt.WriteBEDouble(a_Entity.GetPosZ()); - Pkt.WriteByteAngle(a_Entity.GetYaw()); - Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(a_Entity.IsOnGround()); -} - - - - - void cProtocol_1_9_0::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) { ASSERT(m_State == 3); // In game mode? @@ -1323,6 +1322,33 @@ eHand cProtocol_1_9_0::HandIntToEnum(Int32 a_Hand) +void cProtocol_1_9_0::SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, pktSpawnObject); + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + + // TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now. + Pkt.WriteBEUInt64(0); + Pkt.WriteBEUInt64(a_Entity.GetUniqueID()); + + Pkt.WriteBEUInt8(a_ObjectType); + Pkt.WriteBEDouble(a_Entity.GetPosX()); + Pkt.WriteBEDouble(a_Entity.GetPosY()); + Pkt.WriteBEDouble(a_Entity.GetPosZ()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteBEInt32(a_ObjectData); + Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedX() * 400)); + Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedY() * 400)); + Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedZ() * 400)); +} + + + + + void cProtocol_1_9_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) { short ItemType = a_Item.m_ItemType; @@ -2173,32 +2199,6 @@ void cProtocol_1_9_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & -void cProtocol_1_9_0::WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData) -{ - ASSERT(m_State == 3); // In game mode? - - a_Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - - // TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now. - a_Pkt.WriteBEUInt64(0); - a_Pkt.WriteBEUInt64(a_Entity.GetUniqueID()); - - a_Pkt.WriteBEUInt8(a_ObjectType); - a_Pkt.WriteBEDouble(a_Entity.GetPosX()); - a_Pkt.WriteBEDouble(a_Entity.GetPosY()); - a_Pkt.WriteBEDouble(a_Entity.GetPosZ()); - a_Pkt.WriteByteAngle(a_Entity.GetPitch()); - a_Pkt.WriteByteAngle(a_Entity.GetYaw()); - a_Pkt.WriteBEInt32(a_ObjectData); - a_Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedX() * 400)); - a_Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedY() * 400)); - a_Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedZ() * 400)); -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cProtocol_1_9_1: -- cgit v1.2.3