Fixes for boat entities (#3265)
protocol for vehicles now properly handled, protocol for boat paddles now properly handled, boats can no longer spawn underwater, boats now properly float, boat metadata now properly broadcasted.
This commit is contained in:
parent
8ee662c1fa
commit
db65e11d57
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user