Added support for head yaw tracking and packet sending and fixed bug in BroadcastMovementUpdate
git-svn-id: http://mc-server.googlecode.com/svn/trunk@1350 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
b661b26138
commit
8f047b0704
@ -918,6 +918,7 @@ void cClientHandle::HandleChat(const AString & a_Message)
|
|||||||
void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsOnGround)
|
void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsOnGround)
|
||||||
{
|
{
|
||||||
m_Player->SetRotation (a_Rotation);
|
m_Player->SetRotation (a_Rotation);
|
||||||
|
m_Player->SetHeadYaw (a_Rotation);
|
||||||
m_Player->SetPitch (a_Pitch);
|
m_Player->SetPitch (a_Pitch);
|
||||||
m_Player->SetTouchGround(a_IsOnGround);
|
m_Player->SetTouchGround(a_IsOnGround);
|
||||||
m_Player->WrapRotation();
|
m_Player->WrapRotation();
|
||||||
@ -945,6 +946,7 @@ void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_
|
|||||||
m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ));
|
m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ));
|
||||||
m_Player->SetStance (a_Stance);
|
m_Player->SetStance (a_Stance);
|
||||||
m_Player->SetTouchGround(a_IsOnGround);
|
m_Player->SetTouchGround(a_IsOnGround);
|
||||||
|
m_Player->SetHeadYaw (a_Rotation);
|
||||||
m_Player->SetRotation (a_Rotation);
|
m_Player->SetRotation (a_Rotation);
|
||||||
m_Player->SetPitch (a_Pitch);
|
m_Player->SetPitch (a_Pitch);
|
||||||
m_Player->WrapRotation();
|
m_Player->WrapRotation();
|
||||||
|
@ -30,7 +30,9 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z)
|
|||||||
, m_ChunkX(0)
|
, m_ChunkX(0)
|
||||||
, m_ChunkY(0)
|
, m_ChunkY(0)
|
||||||
, m_ChunkZ(0)
|
, m_ChunkZ(0)
|
||||||
|
, m_HeadYaw( 0.0 )
|
||||||
, m_Pos(a_X, a_Y, a_Z)
|
, m_Pos(a_X, a_Y, a_Z)
|
||||||
|
, m_bDirtyHead(true)
|
||||||
, m_bDirtyOrientation(true)
|
, m_bDirtyOrientation(true)
|
||||||
, m_bDirtyPosition(true)
|
, m_bDirtyPosition(true)
|
||||||
, m_bDirtySpeed(true)
|
, m_bDirtySpeed(true)
|
||||||
@ -63,8 +65,8 @@ cEntity::~cEntity()
|
|||||||
m_Pos.x, m_Pos.y, m_Pos.z,
|
m_Pos.x, m_Pos.y, m_Pos.z,
|
||||||
(int)(m_Pos.x / cChunkDef::Width), (int)(m_Pos.z / cChunkDef::Width),
|
(int)(m_Pos.x / cChunkDef::Width), (int)(m_Pos.z / cChunkDef::Width),
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
|
|
||||||
if (m_AttachedTo != NULL)
|
if (m_AttachedTo != NULL)
|
||||||
{
|
{
|
||||||
Detach();
|
Detach();
|
||||||
@ -73,7 +75,7 @@ cEntity::~cEntity()
|
|||||||
{
|
{
|
||||||
m_Attachee->Detach();
|
m_Attachee->Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_bDestroyed || !m_bRemovedFromChunk)
|
if (!m_bDestroyed || !m_bRemovedFromChunk)
|
||||||
{
|
{
|
||||||
LOGERROR("ERROR: Entity deallocated without being destroyed %i or unlinked %i", m_bDestroyed, m_bRemovedFromChunk);
|
LOGERROR("ERROR: Entity deallocated without being destroyed %i or unlinked %i", m_bDestroyed, m_bRemovedFromChunk);
|
||||||
@ -126,6 +128,16 @@ void cEntity::Initialize(cWorld * a_World)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cEntity::WrapHeadYaw()
|
||||||
|
{
|
||||||
|
while (m_HeadYaw > 180.f) m_HeadYaw -=360.f; // Wrap it
|
||||||
|
while (m_HeadYaw < -180.f) m_HeadYaw +=360.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::WrapRotation()
|
void cEntity::WrapRotation()
|
||||||
{
|
{
|
||||||
while (m_Rot.x > 180.f) m_Rot.x-=360.f; // Wrap it
|
while (m_Rot.x > 180.f) m_Rot.x-=360.f; // Wrap it
|
||||||
@ -164,7 +176,7 @@ void cEntity::MoveToCorrectChunk(bool a_bIgnoreOldChunk)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
class cMover :
|
class cMover :
|
||||||
public cClientDiffCallback
|
public cClientDiffCallback
|
||||||
{
|
{
|
||||||
@ -176,7 +188,7 @@ void cEntity::MoveToCorrectChunk(bool a_bIgnoreOldChunk)
|
|||||||
}
|
}
|
||||||
a_Client->SendDestroyEntity(*m_Entity);
|
a_Client->SendDestroyEntity(*m_Entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Added(cClientHandle * a_Client) override
|
virtual void Added(cClientHandle * a_Client) override
|
||||||
{
|
{
|
||||||
m_Entity->SpawnOn(*a_Client);
|
m_Entity->SpawnOn(*a_Client);
|
||||||
@ -184,17 +196,17 @@ void cEntity::MoveToCorrectChunk(bool a_bIgnoreOldChunk)
|
|||||||
|
|
||||||
bool m_IgnoreOldChunk;
|
bool m_IgnoreOldChunk;
|
||||||
cEntity * m_Entity;
|
cEntity * m_Entity;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cMover(cEntity * a_Entity, bool a_IgnoreOldChunk) :
|
cMover(cEntity * a_Entity, bool a_IgnoreOldChunk) :
|
||||||
m_IgnoreOldChunk(a_IgnoreOldChunk),
|
m_IgnoreOldChunk(a_IgnoreOldChunk),
|
||||||
m_Entity(a_Entity)
|
m_Entity(a_Entity)
|
||||||
{}
|
{}
|
||||||
} Mover(this, a_bIgnoreOldChunk);
|
} Mover(this, a_bIgnoreOldChunk);
|
||||||
|
|
||||||
m_World->CompareChunkClients(m_ChunkX, m_ChunkY, m_ChunkZ, ChunkX, ChunkY, ChunkZ, Mover);
|
m_World->CompareChunkClients(m_ChunkX, m_ChunkY, m_ChunkZ, ChunkX, ChunkY, ChunkZ, Mover);
|
||||||
m_World->MoveEntityToChunk(this, ChunkX, ChunkY, ChunkZ);
|
m_World->MoveEntityToChunk(this, ChunkX, ChunkY, ChunkZ);
|
||||||
|
|
||||||
m_ChunkX = ChunkX;
|
m_ChunkX = ChunkX;
|
||||||
m_ChunkY = ChunkY;
|
m_ChunkY = ChunkY;
|
||||||
m_ChunkZ = ChunkZ;
|
m_ChunkZ = ChunkZ;
|
||||||
@ -214,9 +226,9 @@ void cEntity::Destroy()
|
|||||||
{
|
{
|
||||||
RemoveFromChunk();
|
RemoveFromChunk();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_World->BroadcastDestroyEntity(*this);
|
m_World->BroadcastDestroyEntity(*this);
|
||||||
|
|
||||||
m_bDestroyed = true;
|
m_bDestroyed = true;
|
||||||
|
|
||||||
Destroyed();
|
Destroyed();
|
||||||
@ -232,7 +244,7 @@ void cEntity::RemoveFromChunk(void)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ);
|
m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ);
|
||||||
m_bRemovedFromChunk = true;
|
m_bRemovedFromChunk = true;
|
||||||
}
|
}
|
||||||
@ -244,7 +256,7 @@ void cEntity::RemoveFromChunk(void)
|
|||||||
void cEntity::Tick(float a_Dt, MTRand & a_TickRandom)
|
void cEntity::Tick(float a_Dt, MTRand & a_TickRandom)
|
||||||
{
|
{
|
||||||
UNUSED(a_TickRandom);
|
UNUSED(a_TickRandom);
|
||||||
|
|
||||||
if (m_AttachedTo != NULL)
|
if (m_AttachedTo != NULL)
|
||||||
{
|
{
|
||||||
if ((m_Pos - m_AttachedTo->GetPosition()).Length() > 0.5)
|
if ((m_Pos - m_AttachedTo->GetPosition()).Length() > 0.5)
|
||||||
@ -264,57 +276,68 @@ void cEntity::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
|
|
||||||
void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude)
|
void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
if (m_bDirtyOrientation && !m_bDirtyPosition)
|
int DiffX = (int)((GetPosX() - m_LastPosX) * 32.0);
|
||||||
|
int DiffY = (int)((GetPosY() - m_LastPosY) * 32.0);
|
||||||
|
int DiffZ = (int)((GetPosZ() - m_LastPosZ) * 32.0);
|
||||||
|
Int64 DiffTeleportPacket = m_World->GetWorldAge() - m_TimeLastTeleportPacket;
|
||||||
|
|
||||||
|
//Have to process this every two ticks
|
||||||
|
if (m_World->GetWorldAge() % 2 == 0)
|
||||||
{
|
{
|
||||||
//LOGD("Sending (rot,yaw,roll) = (%f,%f,%f)",m_Rot.x,m_Rot.y,m_Rot.z);
|
// 4 blocks is max Relative So if the Diff is greater than 127 or. Send an absolute position every 20 seconds
|
||||||
m_World->BroadcastEntLook(*this,a_Exclude);
|
if (DiffTeleportPacket >= 400 ||
|
||||||
m_World->BroadcastEntHeadLook(*this,a_Exclude);
|
((DiffX > 127) || (DiffX < -128) ||
|
||||||
m_bDirtyOrientation = false;
|
(DiffY > 127) || (DiffY < -128) ||
|
||||||
}
|
(DiffZ > 127) || (DiffZ < -128)))
|
||||||
|
|
||||||
if (m_bDirtyPosition)
|
|
||||||
{
|
|
||||||
float DiffX = (float)(GetPosX() - m_LastPosX);
|
|
||||||
float DiffY = (float)(GetPosY() - m_LastPosY);
|
|
||||||
float DiffZ = (float)(GetPosZ() - m_LastPosZ);
|
|
||||||
float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ;
|
|
||||||
|
|
||||||
// 4 blocks is max Relative Move. 16 = 4 ^ 2. Send an absolute position every 20 seconds
|
|
||||||
if ((SqrDist > 16) || (m_World->GetWorldAge() - m_TimeLastTeleportPacket > 400))
|
|
||||||
{
|
{
|
||||||
m_World->BroadcastEntHeadLook(*this,a_Exclude);
|
//
|
||||||
m_World->BroadcastTeleportEntity(*this,a_Exclude);
|
m_World->BroadcastTeleportEntity(*this,a_Exclude);
|
||||||
m_TimeLastTeleportPacket = m_World->GetWorldAge();
|
m_TimeLastTeleportPacket = m_World->GetWorldAge();
|
||||||
|
m_TimeLastMoveReltPacket = m_TimeLastTeleportPacket; //Must synchronize.
|
||||||
m_LastPosX = GetPosX();
|
m_LastPosX = GetPosX();
|
||||||
m_LastPosY = GetPosY();
|
m_LastPosY = GetPosY();
|
||||||
m_LastPosZ = GetPosZ();
|
m_LastPosZ = GetPosZ();
|
||||||
m_bDirtyPosition = false;
|
m_bDirtyPosition = false;
|
||||||
|
m_bDirtyOrientation = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Send relative movement every 3 seconds
|
Int64 DiffMoveRelPacket = m_World->GetWorldAge() - m_TimeLastMoveReltPacket;
|
||||||
if ((m_World->GetWorldAge() - m_TimeLastMoveReltPacket > 60))
|
//if the change is big enough.
|
||||||
|
if ((abs(DiffX) >= 4 || abs(DiffY) >= 4 || abs(DiffZ) >= 4 || DiffMoveRelPacket >= 60) && m_bDirtyPosition)
|
||||||
{
|
{
|
||||||
if (m_bDirtyOrientation)
|
if (m_bDirtyOrientation)
|
||||||
{
|
{
|
||||||
m_World->BroadcastEntHeadLook(*this,a_Exclude);
|
m_World->BroadcastEntRelMoveLook(*this, (char)DiffX, (char)DiffY, (char)DiffZ,a_Exclude);
|
||||||
m_World->BroadcastEntRelMoveLook(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32),a_Exclude);
|
|
||||||
m_bDirtyOrientation = false;
|
m_bDirtyOrientation = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_World->BroadcastEntRelMove(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32),a_Exclude);
|
m_World->BroadcastEntRelMove(*this, (char)DiffX, (char)DiffY, (char)DiffZ,a_Exclude);
|
||||||
}
|
}
|
||||||
m_TimeLastMoveReltPacket = m_World->GetWorldAge();
|
|
||||||
m_LastPosX = GetPosX();
|
m_LastPosX = GetPosX();
|
||||||
m_LastPosY = GetPosY();
|
m_LastPosY = GetPosY();
|
||||||
m_LastPosZ = GetPosZ();
|
m_LastPosZ = GetPosZ();
|
||||||
m_bDirtyPosition = false;
|
m_bDirtyPosition = false;
|
||||||
|
m_TimeLastMoveReltPacket = m_World->GetWorldAge();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_bDirtyOrientation)
|
||||||
|
{
|
||||||
|
m_World->BroadcastEntLook(*this,a_Exclude);
|
||||||
|
m_bDirtyOrientation = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_bDirtyHead)
|
||||||
|
{
|
||||||
|
m_World->BroadcastEntHeadLook(*this,a_Exclude);
|
||||||
|
m_bDirtyHead = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//We need to keep updating the clients when there is movement or if there was a change in speed and after 1 tick
|
//We need to keep updating the clients when there is movement or if there was a change in speed and after 2 ticks
|
||||||
if( (m_Speed.SqrLength() > 0.0004f || m_bDirtySpeed) && (m_World->GetWorldAge() - m_TimeLastSpeedPacket >= 1))
|
if( (m_Speed.SqrLength() > 0.0004f || m_bDirtySpeed) && (m_World->GetWorldAge() - m_TimeLastSpeedPacket >= 2))
|
||||||
{
|
{
|
||||||
m_World->BroadcastEntVelocity(*this,a_Exclude);
|
m_World->BroadcastEntVelocity(*this,a_Exclude);
|
||||||
m_bDirtySpeed = false;
|
m_bDirtySpeed = false;
|
||||||
@ -333,10 +356,10 @@ void cEntity::AttachTo(cEntity * a_AttachTo)
|
|||||||
// Already attached to that entity, nothing to do here
|
// Already attached to that entity, nothing to do here
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detach from any previous entity:
|
// Detach from any previous entity:
|
||||||
Detach();
|
Detach();
|
||||||
|
|
||||||
// Attach to the new entity:
|
// Attach to the new entity:
|
||||||
m_AttachedTo = a_AttachTo;
|
m_AttachedTo = a_AttachTo;
|
||||||
a_AttachTo->m_Attachee = this;
|
a_AttachTo->m_Attachee = this;
|
||||||
@ -384,6 +407,17 @@ void cEntity::SetRot(const Vector3f & a_Rot)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cEntity::SetHeadYaw(double a_HeadYaw)
|
||||||
|
{
|
||||||
|
m_HeadYaw = a_HeadYaw;
|
||||||
|
m_bDirtyHead = true;
|
||||||
|
WrapHeadYaw();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::SetRotation(double a_Rotation)
|
void cEntity::SetRotation(double a_Rotation)
|
||||||
{
|
{
|
||||||
m_Rot.x = a_Rotation;
|
m_Rot.x = a_Rotation;
|
||||||
|
@ -105,6 +105,7 @@ public:
|
|||||||
|
|
||||||
cWorld * GetWorld(void) const { return m_World; }
|
cWorld * GetWorld(void) const { return m_World; }
|
||||||
|
|
||||||
|
double GetHeadYaw (void) const {return m_HeadYaw; }
|
||||||
const Vector3d & GetPosition (void) const {return m_Pos; }
|
const Vector3d & GetPosition (void) const {return m_Pos; }
|
||||||
double GetPosX (void) const {return m_Pos.x; }
|
double GetPosX (void) const {return m_Pos.x; }
|
||||||
double GetPosY (void) const {return m_Pos.y; }
|
double GetPosY (void) const {return m_Pos.y; }
|
||||||
@ -123,6 +124,7 @@ public:
|
|||||||
int GetChunkY(void) const {return m_ChunkY; }
|
int GetChunkY(void) const {return m_ChunkY; }
|
||||||
int GetChunkZ(void) const {return m_ChunkZ; }
|
int GetChunkZ(void) const {return m_ChunkZ; }
|
||||||
|
|
||||||
|
void SetHeadYaw (double a_HeadYaw);
|
||||||
void SetPosX (double a_PosX);
|
void SetPosX (double a_PosX);
|
||||||
void SetPosY (double a_PosY);
|
void SetPosY (double a_PosY);
|
||||||
void SetPosZ (double a_PosZ);
|
void SetPosZ (double a_PosZ);
|
||||||
@ -175,6 +177,9 @@ public:
|
|||||||
/// Detaches from the currently attached entity, if any
|
/// Detaches from the currently attached entity, if any
|
||||||
void Detach(void);
|
void Detach(void);
|
||||||
|
|
||||||
|
//Makes sure head yaw is not over the specified range.
|
||||||
|
void WrapHeadYaw();
|
||||||
|
|
||||||
//Makes sure rotation is not over the specified range.
|
//Makes sure rotation is not over the specified range.
|
||||||
void WrapRotation();
|
void WrapRotation();
|
||||||
|
|
||||||
@ -213,6 +218,7 @@ protected:
|
|||||||
int m_ChunkX, m_ChunkY, m_ChunkZ;
|
int m_ChunkX, m_ChunkY, m_ChunkZ;
|
||||||
|
|
||||||
//Flags that signal that we haven't updated the clients with the latest.
|
//Flags that signal that we haven't updated the clients with the latest.
|
||||||
|
bool m_bDirtyHead;
|
||||||
bool m_bDirtyOrientation;
|
bool m_bDirtyOrientation;
|
||||||
bool m_bDirtyPosition;
|
bool m_bDirtyPosition;
|
||||||
bool m_bDirtySpeed;
|
bool m_bDirtySpeed;
|
||||||
@ -243,6 +249,7 @@ protected:
|
|||||||
void ReferencedBy( cEntity*& a_EntityPtr );
|
void ReferencedBy( cEntity*& a_EntityPtr );
|
||||||
void Dereference( cEntity*& a_EntityPtr );
|
void Dereference( cEntity*& a_EntityPtr );
|
||||||
private:
|
private:
|
||||||
|
double m_HeadYaw;
|
||||||
Vector3d m_Speed;
|
Vector3d m_Speed;
|
||||||
Vector3d m_Rot;
|
Vector3d m_Rot;
|
||||||
Vector3d m_Pos;
|
Vector3d m_Pos;
|
||||||
|
@ -153,6 +153,7 @@ void cMonster::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
double Rotation, Pitch;
|
double Rotation, Pitch;
|
||||||
Distance.Normalize();
|
Distance.Normalize();
|
||||||
VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch );
|
VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch );
|
||||||
|
SetHeadYaw (Rotation);
|
||||||
SetRotation( Rotation );
|
SetRotation( Rotation );
|
||||||
SetPitch( Pitch );
|
SetPitch( Pitch );
|
||||||
}
|
}
|
||||||
|
@ -300,7 +300,7 @@ void cProtocol125::SendEntHeadLook(const cEntity & a_Entity)
|
|||||||
cCSLock Lock(m_CSPacket);
|
cCSLock Lock(m_CSPacket);
|
||||||
WriteByte(PACKET_ENT_HEAD_LOOK);
|
WriteByte(PACKET_ENT_HEAD_LOOK);
|
||||||
WriteInt (a_Entity.GetUniqueID());
|
WriteInt (a_Entity.GetUniqueID());
|
||||||
WriteByte((char)((a_Entity.GetRotation() / 360.f) * 256));
|
WriteByte((char)((a_Entity.GetHeadYaw() / 360.f) * 256));
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user