summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Entities/Boat.cpp38
-rw-r--r--src/Entities/Boat.h23
-rw-r--r--src/Entities/Entity.cpp22
-rw-r--r--src/Entities/Entity.h3
-rw-r--r--src/Items/ItemBoat.h17
-rw-r--r--src/Protocol/Protocol19x.cpp88
-rw-r--r--src/Protocol/Protocol19x.h2
7 files changed, 186 insertions, 7 deletions
diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp
index e81e57529..330e54740 100644
--- a/src/Entities/Boat.cpp
+++ b/src/Entities/Boat.cpp
@@ -14,7 +14,10 @@
cBoat::cBoat(double a_X, double a_Y, double a_Z) :
- super(etBoat, a_X, a_Y, a_Z, 0.98, 0.7)
+ super(etBoat, a_X, a_Y, a_Z, 0.98, 0.7),
+ m_LastDamage(0), m_ForwardDirection(0),
+ m_DamageTaken(0.0f), m_Type(0),
+ m_RightPaddleUsed(false), m_LeftPaddleUsed(false)
{
SetMass(20.0f);
SetGravity(-16.0f);
@@ -37,12 +40,15 @@ void cBoat::SpawnOn(cClientHandle & a_ClientHandle)
bool cBoat::DoTakeDamage(TakeDamageInfo & TDI)
{
+ m_LastDamage = 10;
if (!super::DoTakeDamage(TDI))
{
return false;
}
- if (GetHealth() == 0)
+ m_World->BroadcastEntityMetadata(*this);
+
+ if (GetHealth() <= 0)
{
if (TDI.Attacker != nullptr)
{
@@ -112,6 +118,14 @@ void cBoat::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
AddSpeedY(0.2);
}
}
+
+ if (GetLastDamage() > 0)
+ {
+ SetLastDamage(GetLastDamage() - 1);
+ }
+
+ // Broadcast any changes in position
+ m_World->BroadcastEntityMetadata(*this);
}
@@ -130,3 +144,23 @@ void cBoat::HandleSpeedFromAttachee(float a_Forward, float a_Sideways)
AddSpeed(ToAddSpeed);
}
+
+
+
+
+void cBoat::SetLastDamage(int TimeSinceLastHit)
+{
+ m_LastDamage = TimeSinceLastHit;
+}
+
+
+
+
+
+void cBoat::UpdatePaddles(bool a_RightPaddleUsed, bool a_LeftPaddleUsed)
+{
+ m_RightPaddleUsed = a_RightPaddleUsed;
+ m_LeftPaddleUsed = a_LeftPaddleUsed;
+
+ m_World->BroadcastEntityMetadata(*this);
+}
diff --git a/src/Entities/Boat.h b/src/Entities/Boat.h
index d168f5072..5815ff88c 100644
--- a/src/Entities/Boat.h
+++ b/src/Entities/Boat.h
@@ -31,8 +31,29 @@ public:
virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways) override;
cBoat(double a_X, double a_Y, double a_Z);
-} ;
+ int GetLastDamage(void) const { return m_LastDamage; }
+ int GetForwardDirection(void) const { return m_ForwardDirection; }
+
+ float GetDamageTaken(void) const { return m_DamageTaken; }
+
+ int GetType(void) const { return m_Type; }
+
+ bool IsRightPaddleUsed(void) const { return m_RightPaddleUsed; }
+ bool IsLeftPaddleUsed(void) const { return m_LeftPaddleUsed; }
+ void SetLastDamage(int TimeSinceLastHit);
+ void UpdatePaddles(bool rightPaddleUsed, bool leftPaddleUsed);
+private:
+ int m_LastDamage;
+ int m_ForwardDirection;
+
+ float m_DamageTaken;
+
+ int m_Type;
+
+ bool m_RightPaddleUsed;
+ bool m_LeftPaddleUsed;
+} ;
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 6e1dec957..98be99a27 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -1038,6 +1038,20 @@ void cEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
NextSpeed -= NextSpeed * (m_AirDrag * 20.0f) * DtSec.count();
}
NextSpeed.y += static_cast<float>(fallspeed);
+
+ // A real boat floats
+ if (IsBoat())
+ {
+ // Find top water block and sit there
+ int NextBlockY = BlockY;
+ BLOCKTYPE NextBlock = NextChunk->GetBlock(RelBlockX, NextBlockY, RelBlockZ);
+ while (IsBlockWater(NextBlock))
+ {
+ NextBlock = NextChunk->GetBlock(RelBlockX, ++NextBlockY, RelBlockZ);
+ }
+ NextPos.y = NextBlockY - 0.5;
+ NextSpeed.y = 0;
+ }
}
else
{
@@ -1913,6 +1927,14 @@ void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude)
+cEntity * cEntity::GetAttached()
+{
+ return m_AttachedTo;
+}
+
+
+
+
void cEntity::AttachTo(cEntity * a_AttachTo)
{
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index b00201f3a..6923795db 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -421,6 +421,9 @@ public:
/** Updates clients of changes in the entity. */
virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = nullptr);
+ /** Gets entity (vehicle) attached to this entity */
+ cEntity * GetAttached();
+
/** Attaches to the specified entity; detaches from any previous one first */
void AttachTo(cEntity * a_AttachTo);
diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h
index 208904130..de16c70dc 100644
--- a/src/Items/ItemBoat.h
+++ b/src/Items/ItemBoat.h
@@ -77,7 +77,22 @@ public:
double y = Callbacks.m_Pos.y;
double z = Callbacks.m_Pos.z;
- cBoat * Boat = new cBoat(x + 0.5, y + 1, z + 0.5);
+ // Verify that block type for spawn point is water
+ BLOCKTYPE SpawnBlock = a_World->GetBlock(x, y, z);
+ if (!IsBlockWater(SpawnBlock))
+ {
+ return false;
+ }
+
+ // Block above must be air to spawn a boat (prevents spawning a boat underwater)
+ BLOCKTYPE BlockAbove = a_World->GetBlock(x, y + 1, z);
+ if (BlockAbove != E_BLOCK_AIR)
+ {
+ return false;
+ }
+
+ // Spawn block at water level
+ cBoat * Boat = new cBoat(x + 0.5, y + 0.5, z + 0.5);
Boat->Initialize(*a_World);
return true;
diff --git a/src/Protocol/Protocol19x.cpp b/src/Protocol/Protocol19x.cpp
index 4a9732fb0..c11e05565 100644
--- a/src/Protocol/Protocol19x.cpp
+++ b/src/Protocol/Protocol19x.cpp
@@ -33,6 +33,7 @@ Implements the 1.9.x protocol classes:
#include "../WorldStorage/FastNBT.h"
#include "../WorldStorage/EnchantmentSerializer.h"
+#include "../Entities/Boat.h"
#include "../Entities/ExpOrb.h"
#include "../Entities/Minecart.h"
#include "../Entities/FallingBlock.h"
@@ -2067,8 +2068,8 @@ bool cProtocol190::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
case 0x0d: HandlePacketPlayerPosLook (a_ByteBuffer); return true;
case 0x0e: HandlePacketPlayerLook (a_ByteBuffer); return true;
case 0x0f: HandlePacketPlayer (a_ByteBuffer); return true;
- case 0x10: break; // Vehicle move - not yet implemented
- case 0x11: break; // Steer boat - not yet implemented
+ case 0x10: HandlePacketVehicleMove (a_ByteBuffer); return true;
+ case 0x11: HandlePacketBoatSteer (a_ByteBuffer); return true;
case 0x12: HandlePacketPlayerAbilities (a_ByteBuffer); return true;
case 0x13: HandlePacketBlockDig (a_ByteBuffer); return true;
case 0x14: HandlePacketEntityAction (a_ByteBuffer); return true;
@@ -2318,6 +2319,29 @@ void cProtocol190::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
+void cProtocol190::HandlePacketBoatSteer(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadBool, bool, RightPaddle);
+ HANDLE_READ(a_ByteBuffer, ReadBool, bool, LeftPaddle);
+
+ // Get the players vehicle
+ cPlayer * Player = m_Client->GetPlayer();
+ cEntity * Vehicle = Player->GetAttached();
+
+ if (Vehicle)
+ {
+ if (Vehicle->GetEntityType() == cEntity::etBoat)
+ {
+ auto * Boat = reinterpret_cast<cBoat *>(Vehicle);
+ Boat->UpdatePaddles(RightPaddle, LeftPaddle);
+ }
+ }
+}
+
+
+
+
+
void cProtocol190::HandlePacketChatMessage(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Message);
@@ -2560,7 +2584,7 @@ void cProtocol190::HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer)
}
else if ((Flags & 0x1) != 0)
{
- // jump
+ // TODO: Handle vehicle jump (for animals)
}
else
{
@@ -2676,6 +2700,32 @@ void cProtocol190::HandlePacketEnchantItem(cByteBuffer & a_ByteBuffer)
+void cProtocol190::HandlePacketVehicleMove(cByteBuffer & a_ByteBuffer)
+{
+ // This handles updating the vehicles location server side
+ HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, xPos);
+ HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, yPos);
+ HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, zPos);
+ HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, yaw);
+ HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, pitch);
+
+ // Get the players vehicle
+ cEntity * Vehicle = m_Client->GetPlayer()->GetAttached();
+
+ if (Vehicle)
+ {
+ Vehicle->SetPosX(xPos);
+ Vehicle->SetPosY(yPos);
+ Vehicle->SetPosZ(zPos);
+ Vehicle->SetYaw(yaw);
+ Vehicle->SetPitch(pitch);
+ }
+}
+
+
+
+
+
void cProtocol190::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, WindowID);
@@ -3579,6 +3629,37 @@ void cProtocol190::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_En
break;
}
+ case cEntity::etBoat:
+ {
+ auto & Boat = reinterpret_cast<const cBoat &>(a_Entity);
+
+ a_Pkt.WriteBEInt8(5); // Index 6: Time since last hit
+ a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
+ a_Pkt.WriteBEInt32(Boat.GetLastDamage());
+
+ a_Pkt.WriteBEInt8(6); // Index 7: Forward direction
+ a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
+ a_Pkt.WriteBEInt32(Boat.GetForwardDirection());
+
+ a_Pkt.WriteBEInt8(7); // Index 8: Damage taken
+ a_Pkt.WriteBEInt8(METADATA_TYPE_FLOAT);
+ a_Pkt.WriteBEFloat(Boat.GetDamageTaken());
+
+ a_Pkt.WriteBEInt8(8); // Index 9: Type
+ a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
+ a_Pkt.WriteBEInt32(Boat.GetType());
+
+ a_Pkt.WriteBEInt8(9); // Index 10: Right paddle turning
+ a_Pkt.WriteBEInt8(METADATA_TYPE_BOOL);
+ a_Pkt.WriteBool(Boat.IsRightPaddleUsed());
+
+ a_Pkt.WriteBEInt8(10); // Index 11: Left paddle turning
+ a_Pkt.WriteBEInt8(METADATA_TYPE_BOOL);
+ a_Pkt.WriteBool(Boat.IsLeftPaddleUsed());
+
+ break;
+ } // case etBoat
+
case cEntity::etItemFrame:
{
auto & Frame = reinterpret_cast<const cItemFrame &>(a_Entity);
@@ -3777,6 +3858,7 @@ void cProtocol190::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(12); // Index 12: Is saddled
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(Pig.IsSaddled());
+
break;
} // case mtPig
diff --git a/src/Protocol/Protocol19x.h b/src/Protocol/Protocol19x.h
index e40e3aac2..d23653702 100644
--- a/src/Protocol/Protocol19x.h
+++ b/src/Protocol/Protocol19x.h
@@ -208,6 +208,7 @@ protected:
void HandlePacketAnimation (cByteBuffer & a_ByteBuffer);
void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer);
void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer);
+ void HandlePacketBoatSteer (cByteBuffer & a_ByteBuffer);
void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer);
void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer);
void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer);
@@ -228,6 +229,7 @@ protected:
void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer);
void HandlePacketUseItem (cByteBuffer & a_ByteBuffer);
void HandlePacketEnchantItem (cByteBuffer & a_ByteBuffer);
+ void HandlePacketVehicleMove (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);