1
0

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:
keyboard.osh@gmail.com 2013-04-02 06:48:31 +00:00
parent b661b26138
commit 8f047b0704
5 changed files with 84 additions and 40 deletions

View File

@ -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();

View File

@ -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)
@ -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
@ -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);
//LOGD("Sending (rot,yaw,roll) = (%f,%f,%f)",m_Rot.x,m_Rot.y,m_Rot.z); int DiffZ = (int)((GetPosZ() - m_LastPosZ) * 32.0);
m_World->BroadcastEntLook(*this,a_Exclude); Int64 DiffTeleportPacket = m_World->GetWorldAge() - m_TimeLastTeleportPacket;
m_World->BroadcastEntHeadLook(*this,a_Exclude);
m_bDirtyOrientation = false;
}
if (m_bDirtyPosition) //Have to process this every two ticks
if (m_World->GetWorldAge() % 2 == 0)
{ {
float DiffX = (float)(GetPosX() - m_LastPosX); // 4 blocks is max Relative So if the Diff is greater than 127 or. Send an absolute position every 20 seconds
float DiffY = (float)(GetPosY() - m_LastPosY); if (DiffTeleportPacket >= 400 ||
float DiffZ = (float)(GetPosZ() - m_LastPosZ); ((DiffX > 127) || (DiffX < -128) ||
float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ; (DiffY > 127) || (DiffY < -128) ||
(DiffZ > 127) || (DiffZ < -128)))
// 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;
} }
} }
} }
//We need to keep updating the clients when there is movement or if there was a change in speed and after 1 tick if (m_bDirtyHead)
if( (m_Speed.SqrLength() > 0.0004f || m_bDirtySpeed) && (m_World->GetWorldAge() - m_TimeLastSpeedPacket >= 1)) {
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 2 ticks
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;
@ -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;

View File

@ -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;

View File

@ -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 );
} }

View File

@ -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();
} }