summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Blocks/BlockFarmland.h24
-rw-r--r--src/ClientHandle.cpp9
-rw-r--r--src/ClientHandle.h1
-rw-r--r--src/Protocol/Protocol.h1
-rw-r--r--src/Protocol/Protocol_1_8.cpp33
-rw-r--r--src/Protocol/Protocol_1_8.h1
-rw-r--r--src/Protocol/Protocol_1_9.cpp36
-rw-r--r--src/Protocol/Protocol_1_9.h1
8 files changed, 82 insertions, 24 deletions
diff --git a/src/Blocks/BlockFarmland.h b/src/Blocks/BlockFarmland.h
index 61ac872c8..3da27de43 100644
--- a/src/Blocks/BlockFarmland.h
+++ b/src/Blocks/BlockFarmland.h
@@ -44,7 +44,7 @@ public:
/** Turns farmland into dirt.
Will first check for any colliding entities and teleport them to a higher position.
*/
- static void TurnToDirt(cChunk & a_Chunk, Vector3i a_AbsPos, Vector3i a_RelPos)
+ static void TurnToDirt(cChunk & a_Chunk, const Vector3i a_AbsPos, const Vector3i a_RelPos)
{
static const auto FarmlandHeight = cBlockInfo::GetBlockHeight(E_BLOCK_FARMLAND);
static const auto FullHeightDelta = 1 - FarmlandHeight;
@@ -53,23 +53,29 @@ public:
cBoundingBox(Vector3d(0.5, FarmlandHeight, 0.5) + a_AbsPos, 0.5, FullHeightDelta),
[&](cEntity & Entity)
{
- if (!Entity.IsOnGround())
+ const auto GroundHeight = a_AbsPos.y + 1;
+
+ // A simple IsOnGround isn't enough. It will return true when
+ // e.g. a piston pushes a farmland block into an entity's head.
+ // Maybe it's also possible than an entity is falling, it's
+ // still not on the ground, but it's less than 0.0625 blocks
+ // higher than the farmland block
+ if ((Entity.GetPosY() < a_AbsPos.y + FarmlandHeight) || (Entity.GetPosY() >= GroundHeight))
{
return false;
}
- Entity.AddPosY(FullHeightDelta);
// Players need a packet that will update their position
if (Entity.IsPlayer())
{
- auto Player = static_cast<cPlayer *>(&Entity);
- // This works, but it's much worse than Vanilla.
- // This can be easily improved by implementing relative
- // "Player Position And Look" packets! See
- // https://wiki.vg/Protocol#Player_Position_And_Look_.28clientbound.29
- Player->GetClientHandle()->SendPlayerMoveLook();
+ const auto HeightIncrease = GroundHeight - Entity.GetPosY();
+ const auto Player = static_cast<const cPlayer *>(&Entity);
+
+ Player->GetClientHandle()->SendPlayerMoveLook(Vector3d(0.0, HeightIncrease, 0.0), 0.0f, 0.0f, true);
}
+ Entity.SetPosY(GroundHeight);
+
return false;
});
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index db54cc77b..ef596baf0 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -2852,6 +2852,15 @@ void cClientHandle::SendPlayerListUpdatePing()
+void cClientHandle::SendPlayerMoveLook (const Vector3d a_Pos, const float a_Yaw, const float a_Pitch, const bool a_IsRelative)
+{
+ m_Protocol->SendPlayerMoveLook(a_Pos, a_Yaw, a_Pitch, a_IsRelative);
+}
+
+
+
+
+
void cClientHandle::SendPlayerMoveLook(void)
{
/*
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 66ae7f20e..9f3cbb18d 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -204,6 +204,7 @@ public: // tolua_export
void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName);
void SendPlayerListUpdateGameMode (const cPlayer & a_Player);
void SendPlayerListUpdatePing ();
+ void SendPlayerMoveLook (Vector3d a_Pos, float a_Yaw, float a_Pitch, bool a_IsRelative);
void SendPlayerMoveLook (void);
void SendPlayerPermissionLevel (void);
void SendPlayerPosition (void);
diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h
index 4f7590c2c..f1d85f014 100644
--- a/src/Protocol/Protocol.h
+++ b/src/Protocol/Protocol.h
@@ -422,6 +422,7 @@ public:
virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) = 0;
virtual void SendPlayerListUpdatePing () = 0;
virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) = 0;
+ virtual void SendPlayerMoveLook (Vector3d a_Pos, float a_Yaw, float a_Pitch, bool a_IsRelative) = 0;
virtual void SendPlayerMoveLook (void) = 0;
virtual void SendPlayerPermissionLevel (void) = 0;
virtual void SendPlayerPosition (void) = 0;
diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp
index 7a3cd3b90..cbb13e68e 100644
--- a/src/Protocol/Protocol_1_8.cpp
+++ b/src/Protocol/Protocol_1_8.cpp
@@ -1136,18 +1136,37 @@ void cProtocol_1_8_0::SendPlayerListUpdatePing()
-void cProtocol_1_8_0::SendPlayerMoveLook(void)
+void cProtocol_1_8_0::SendPlayerMoveLook (const Vector3d a_Pos, const float a_Yaw, const float a_Pitch, const bool a_IsRelative)
{
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, pktPlayerMoveLook);
+ Pkt.WriteBEDouble(a_Pos.x);
+ Pkt.WriteBEDouble(a_Pos.y);
+ Pkt.WriteBEDouble(a_Pos.z);
+ Pkt.WriteBEFloat(a_Yaw);
+ Pkt.WriteBEFloat(a_Pitch);
+
+ if (a_IsRelative)
+ {
+ // Set all bits to 1 - makes everything relative
+ Pkt.WriteBEUInt8(static_cast<UInt8>(-1));
+ }
+ else
+ {
+ // Set all bits to 0 - make everything absolute
+ Pkt.WriteBEUInt8(0);
+ }
+}
+
+
+
+
+
+void cProtocol_1_8_0::SendPlayerMoveLook(void)
+{
cPlayer * Player = m_Client->GetPlayer();
- Pkt.WriteBEDouble(Player->GetPosX());
- Pkt.WriteBEDouble(Player->GetPosY());
- Pkt.WriteBEDouble(Player->GetPosZ());
- Pkt.WriteBEFloat(static_cast<float>(Player->GetYaw()));
- Pkt.WriteBEFloat(static_cast<float>(Player->GetPitch()));
- Pkt.WriteBEUInt8(0);
+ SendPlayerMoveLook(Player->GetPosition(), static_cast<float>(Player->GetYaw()), static_cast<float>(Player->GetPitch()), false);
}
diff --git a/src/Protocol/Protocol_1_8.h b/src/Protocol/Protocol_1_8.h
index 59dacbca0..eaa8813be 100644
--- a/src/Protocol/Protocol_1_8.h
+++ b/src/Protocol/Protocol_1_8.h
@@ -93,6 +93,7 @@ public:
virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) override;
virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override;
virtual void SendPlayerListUpdatePing () override;
+ virtual void SendPlayerMoveLook (Vector3d a_Pos, float a_Yaw, float a_Pitch, bool a_IsRelative) override;
virtual void SendPlayerMoveLook (void) override;
virtual void SendPlayerPermissionLevel (void) override;
virtual void SendPlayerPosition (void) override;
diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp
index 07ab4caf7..dd2133f77 100644
--- a/src/Protocol/Protocol_1_9.cpp
+++ b/src/Protocol/Protocol_1_9.cpp
@@ -466,18 +466,28 @@ void cProtocol_1_9_0::SendMapData(const cMap & a_Map, int a_DataStartX, int a_Da
-void cProtocol_1_9_0::SendPlayerMoveLook(void)
+void cProtocol_1_9_0::SendPlayerMoveLook (const Vector3d a_Pos, const float a_Yaw, const float a_Pitch, const bool a_IsRelative)
{
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, pktPlayerMoveLook);
- cPlayer * Player = m_Client->GetPlayer();
- Pkt.WriteBEDouble(Player->GetPosX());
- Pkt.WriteBEDouble(Player->GetPosY());
- Pkt.WriteBEDouble(Player->GetPosZ());
- Pkt.WriteBEFloat(static_cast<float>(Player->GetYaw()));
- Pkt.WriteBEFloat(static_cast<float>(Player->GetPitch()));
- Pkt.WriteBEUInt8(0);
+ Pkt.WriteBEDouble(a_Pos.x);
+ Pkt.WriteBEDouble(a_Pos.y);
+ Pkt.WriteBEDouble(a_Pos.z);
+ Pkt.WriteBEFloat(a_Yaw);
+ Pkt.WriteBEFloat(a_Pitch);
+
+ if (a_IsRelative)
+ {
+ // Set all bits to 1 - makes everything relative
+ Pkt.WriteBEUInt8(static_cast<UInt8>(-1));
+ }
+ else
+ {
+ // Set all bits to 0 - make everything absolute
+ Pkt.WriteBEUInt8(0);
+ }
+
Pkt.WriteVarInt32(++m_OutstandingTeleportId);
// This teleport ID hasn't been confirmed yet
@@ -488,6 +498,16 @@ void cProtocol_1_9_0::SendPlayerMoveLook(void)
+void cProtocol_1_9_0::SendPlayerMoveLook(void)
+{
+ cPlayer * Player = m_Client->GetPlayer();
+ SendPlayerMoveLook(Player->GetPosition(), static_cast<float>(Player->GetYaw()), static_cast<float>(Player->GetPitch()), false);
+}
+
+
+
+
+
void cProtocol_1_9_0::SendPlayerPermissionLevel()
{
const cPlayer & Player = *m_Client->GetPlayer();
diff --git a/src/Protocol/Protocol_1_9.h b/src/Protocol/Protocol_1_9.h
index 5f4bbed59..e56d7e2d2 100644
--- a/src/Protocol/Protocol_1_9.h
+++ b/src/Protocol/Protocol_1_9.h
@@ -51,6 +51,7 @@ public:
virtual void SendLeashEntity (const cEntity & a_Entity, const cEntity & a_EntityLeashedTo) override;
virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) override;
virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
+ virtual void SendPlayerMoveLook (Vector3d a_Pos, float a_Yaw, float a_Pitch, bool a_IsRelative) override;
virtual void SendPlayerMoveLook (void) override;
virtual void SendPlayerPermissionLevel() override;
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;