1
0
Fork 0

Map decorators; Map clients

This commit is contained in:
andrew 2014-02-18 20:50:08 +02:00
parent 3b24bc870b
commit 393ca0221d
12 changed files with 354 additions and 48 deletions

View File

@ -1190,19 +1190,6 @@ void cClientHandle::HandleSlotSelected(short a_SlotNum)
{
m_Player->GetInventory().SetEquippedSlotNum(a_SlotNum);
m_Player->GetWorld()->BroadcastEntityEquipment(*m_Player, 0, m_Player->GetInventory().GetEquippedItem(), this);
const cItem & Item = m_Player->GetInventory().GetEquippedItem();
if (Item.m_ItemType == E_ITEM_MAP)
{
// TODO 2014-02-14 xdot: Do not hardcode this.
cMap * Map = m_Player->GetWorld()->GetMapData(Item.m_ItemDamage);
if (Map != NULL)
{
// TODO 2014-02-14 xdot: Optimization - Do not send the whole map.
Map->SendTo(*this);
}
}
}
@ -2079,6 +2066,15 @@ void cClientHandle::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Col
void cClientHandle::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators)
{
m_Protocol->SendMapDecorators(a_ID, a_Decorators);
}
void cClientHandle::SendMapInfo(int a_ID, unsigned int a_Scale)
{
m_Protocol->SendMapInfo(a_ID, a_Scale);

View File

@ -17,6 +17,7 @@
#include "ChunkDef.h"
#include "ByteBuffer.h"
#include "Scoreboard.h"
#include "Map.h"
@ -110,6 +111,7 @@ public:
void SendHealth (void);
void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item);
void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length);
void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators);
void SendMapInfo (int a_ID, unsigned int a_Scale);
void SendPickupSpawn (const cPickup & a_Pickup);
void SendEntityAnimation (const cEntity & a_Entity, char a_Animation);

View File

@ -36,8 +36,8 @@ public:
return;
}
// Map->AddTrackedPlayer(a_Player);
Map->UpdateRadius(*a_Player, DEFAULT_RADIUS);
Map->UpdateClient(a_Player);
}
} ;

View File

@ -14,6 +14,111 @@
cMapDecorator::cMapDecorator(cMap * a_Map, eType a_Type, int a_X, int a_Z, unsigned int a_Rot)
: m_Map(a_Map)
, m_Type(a_Type)
, m_PixelX(a_X)
, m_PixelZ(a_Z)
, m_Rot(a_Rot)
, m_Player(NULL)
{
}
cMapDecorator::cMapDecorator(cMap * a_Map, cPlayer * a_Player)
: m_Map(a_Map)
, m_Type(E_TYPE_PLAYER)
, m_Player(a_Player)
{
Update();
}
template <typename T>
T Clamp(T a_X, T a_Min, T a_Max)
{
return std::min(std::max(a_X, a_Min), a_Max);
}
void cMapDecorator::Update(void)
{
ASSERT(m_Map != NULL);
unsigned int PixelWidth = m_Map->GetPixelWidth();
int InsideWidth = (m_Map->GetWidth() / 2) - 1;
int InsideHeight = (m_Map->GetHeight() / 2) - 1;
if (m_Player)
{
int PixelX = (m_Player->GetPosX() - m_Map->GetCenterX()) / PixelWidth;
int PixelZ = (m_Player->GetPosZ() - m_Map->GetCenterZ()) / PixelWidth;
// Center of pixel
m_PixelX = (2 * PixelX) + 1;
m_PixelZ = (2 * PixelZ) + 1;
// 1px border
if ((PixelX > -InsideWidth) && (PixelX <= InsideWidth) && (PixelZ > -InsideHeight) && (PixelZ <= InsideHeight))
{
double Yaw = m_Player->GetYaw();
m_Rot = (Yaw * 16) / 360;
if (m_Map->GetDimension() == dimNether)
{
Int64 WorldAge = m_Player->GetWorld()->GetWorldAge();
// TODO 2014-02-18 xdot: Random rotations
}
m_Type = E_TYPE_PLAYER;
}
else
{
if ((abs(PixelX) > 320.0) || (abs(PixelZ) > 320.0))
{
// TODO 2014-02-18 xdot: Remove decorator
}
m_Rot = 0;
m_Type = E_TYPE_PLAYER_OUTSIDE;
// Move to border
if (PixelX <= -InsideWidth)
{
m_PixelX = (2 * -InsideWidth) + 1;
}
if (PixelZ <= -InsideHeight)
{
m_PixelZ = (2 * -InsideHeight) + 1;
}
if (PixelX > InsideWidth)
{
m_PixelX = (2 * InsideWidth) + 1;
}
if (PixelZ > InsideHeight)
{
m_PixelZ = (2 * InsideHeight) + 1;
}
}
}
}
cMap::cMap(unsigned int a_ID, cWorld * a_World)
: m_ID(a_ID)
, m_Width(cChunkDef::Width * 8)
@ -50,16 +155,6 @@ cMap::cMap(unsigned int a_ID, int a_CenterX, int a_CenterZ, cWorld * a_World, un
template <typename T>
T Clamp(T a_X, T a_Min, T a_Max)
{
return std::min(std::max(a_X, a_Min), a_Max);
}
void cMap::UpdateRadius(int a_PixelX, int a_PixelZ, unsigned int a_Radius)
{
int PixelRadius = a_Radius / GetPixelWidth();
@ -174,33 +269,117 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z)
void cMap::UpdateTrackedPlayers(void)
void cMap::UpdateDecorators(void)
{
cTrackedPlayerList NewList;
for (cTrackedPlayerList::iterator it = m_TrackedPlayers.begin(); it != m_TrackedPlayers.end(); ++it)
for (cMapDecoratorList::iterator it = m_Decorators.begin(); it != m_Decorators.end(); ++it)
{
cPlayer * Player = *it;
UpdateRadius(*Player, DEFAULT_RADIUS);
if (true)
{
NewList.insert(Player);
}
it->Update();
}
std::swap(m_TrackedPlayers, NewList);
}
void cMap::AddTrackedPlayer(cPlayer * a_Player)
void cMap::UpdateClient(cPlayer * a_Player)
{
ASSERT(a_Player != NULL);
m_TrackedPlayers.insert(a_Player);
cClientHandle * Handle = a_Player->GetClientHandle();
if (Handle == NULL)
{
return;
}
Int64 WorldAge = a_Player->GetWorld()->GetWorldAge();
// Remove invalid clients
for (cMapClientList::iterator it = m_Clients.begin(); it != m_Clients.end();)
{
// Check if client is active
if (it->m_LastUpdate < WorldAge - 5)
{
// Remove associated decorators
for (cMapDecoratorList::iterator it2 = m_Decorators.begin(); it2 != m_Decorators.end();)
{
if (it2->GetPlayer()->GetClientHandle() == Handle)
{
// Erase decorator
cMapDecoratorList::iterator temp = it2;
++it2;
m_Decorators.erase(temp);
}
else
{
++it2;
}
}
// Erase client
cMapClientList::iterator temp = it;
++it;
m_Clients.erase(temp);
}
else
{
++it;
}
}
// Linear search for client state
for (cMapClientList::iterator it = m_Clients.begin(); it != m_Clients.end(); ++it)
{
if (it->m_Handle == Handle)
{
it->m_LastUpdate = WorldAge;
if (it->m_SendInfo)
{
Handle->SendMapInfo(m_ID, m_Scale);
it->m_SendInfo = false;
return;
}
++it->m_NextDecoratorUpdate;
if (it->m_NextDecoratorUpdate >= 4)
{
UpdateDecorators();
Handle->SendMapDecorators(m_ID, m_Decorators);
it->m_NextDecoratorUpdate = 0;
}
else
{
++it->m_DataUpdate;
unsigned int Y = (it->m_DataUpdate * 11) % m_Width;
const Byte * Colors = &m_Data[Y * m_Height];
Handle->SendMapColumn(m_ID, Y, 0, Colors, m_Height);
}
return;
}
}
// New player, construct a new client state
cMapClient MapClient;
MapClient.m_LastUpdate = WorldAge;
MapClient.m_SendInfo = true;
MapClient.m_Handle = a_Player->GetClientHandle();
m_Clients.push_back(MapClient);
// Insert new decorator
cMapDecorator PlayerDecorator(this, a_Player);
m_Decorators.push_back(PlayerDecorator);
}
@ -267,6 +446,11 @@ void cMap::SetScale(unsigned int a_Scale)
}
m_Scale = a_Scale;
for (cMapClientList::iterator it = m_Clients.begin(); it != m_Clients.end(); ++it)
{
it->m_SendInfo = true;
}
}
@ -283,6 +467,8 @@ void cMap::SendTo(cClientHandle & a_Client)
a_Client.SendMapColumn(m_ID, i, 0, Colors, m_Height);
}
a_Client.SendMapDecorators(m_ID, m_Decorators);
}

View File

@ -22,6 +22,55 @@
class cClientHandle;
class cWorld;
class cPlayer;
class cMap;
class cMapDecorator
{
public:
enum eType
{
E_TYPE_PLAYER = 0x00,
E_TYPE_ITEM_FRAME = 0x01,
E_TYPE_PLAYER_OUTSIDE = 0x06
};
public:
cMapDecorator(cMap * a_Map, eType a_Type, int a_X, int a_Z, unsigned int a_Rot);
cMapDecorator(cMap * a_Map, cPlayer * a_Player);
void Update(void);
unsigned int GetPixelX(void) const { return m_PixelX; }
unsigned int GetPixelZ(void) const { return m_PixelZ; }
unsigned int GetRot(void) const { return m_Rot; }
eType GetType(void) const { return m_Type; }
cPlayer * GetPlayer(void) { return m_Player; }
protected:
cMap * m_Map;
eType m_Type;
unsigned int m_PixelX;
unsigned int m_PixelZ;
unsigned int m_Rot;
cPlayer * m_Player;
};
typedef std::list<cMapDecorator> cMapDecoratorList;
@ -38,7 +87,19 @@ public:
typedef std::vector<ColorID> cColorList;
static const unsigned int DEFAULT_RADIUS = 128;
struct cMapClient
{
cClientHandle * m_Handle;
bool m_SendInfo;
unsigned int m_NextDecoratorUpdate;
Int64 m_DataUpdate;
Int64 m_LastUpdate;
};
typedef std::list<cMapClient> cMapClientList;
public:
@ -56,9 +117,8 @@ public:
void UpdateRadius(cPlayer & a_Player, unsigned int a_Radius);
void UpdateTrackedPlayers(void);
void AddTrackedPlayer(cPlayer * a_Player);
/** Send next update packet and remove invalid decorators */
void UpdateClient(cPlayer * a_Player);
// tolua_begin
@ -98,6 +158,9 @@ public:
private:
/** Update the associated decorators. */
void UpdateDecorators(void);
/** Update the specified pixel. */
bool UpdatePixel(unsigned int a_X, unsigned int a_Z);
@ -117,9 +180,9 @@ private:
cWorld * m_World;
typedef std::set<cPlayer*> cTrackedPlayerList;
cMapDecoratorList m_Decorators;
cTrackedPlayerList m_TrackedPlayers;
cMapClientList m_Clients;
AString m_Name;

View File

@ -13,6 +13,7 @@
#include "../Defines.h"
#include "../Endianness.h"
#include "../Scoreboard.h"
#include "../Map.h"
@ -28,7 +29,6 @@ class cWorld;
class cMonster;
class cChunkDataSerializer;
class cFallingBlock;
class cMap;
@ -81,6 +81,7 @@ public:
virtual void SendKeepAlive (int a_PingID) = 0;
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) = 0;
virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) = 0;
virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) = 0;
virtual void SendMapInfo (int a_ID, unsigned int a_Scale) = 0;
virtual void SendPickupSpawn (const cPickup & a_Pickup) = 0;
virtual void SendPlayerAbilities (void) = 0;

View File

@ -602,6 +602,31 @@ void cProtocol125::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colo
void cProtocol125::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators)
{
cCSLock Lock(m_CSPacket);
WriteByte (PACKET_ITEM_DATA);
WriteShort(E_ITEM_MAP);
WriteShort(a_ID);
WriteShort(1 + (3 * a_Decorators.size()));
WriteByte(1);
for (cMapDecoratorList::const_iterator it = a_Decorators.begin(); it != a_Decorators.end(); ++it)
{
WriteByte((it->GetType() << 4) | (it->GetRot() & 0xf));
WriteByte(it->GetPixelX());
WriteByte(it->GetPixelZ());
}
Flush();
}
void cProtocol125::SendPickupSpawn(const cPickup & a_Pickup)
{

View File

@ -55,6 +55,7 @@ public:
virtual void SendKeepAlive (int a_PingID) override;
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override;
virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override;
virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override {} // This protocol doesn't support such message
virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override;
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;

View File

@ -516,6 +516,26 @@ void cProtocol172::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colo
void cProtocol172::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators)
{
cPacketizer Pkt(*this, 0x34);
Pkt.WriteVarInt(a_ID);
Pkt.WriteShort (1 + (3 * a_Decorators.size()));
Pkt.WriteByte(1);
for (cMapDecoratorList::const_iterator it = a_Decorators.begin(); it != a_Decorators.end(); ++it)
{
Pkt.WriteByte((it->GetType() << 4) | (it->GetRot() & 0xf));
Pkt.WriteByte(it->GetPixelX());
Pkt.WriteByte(it->GetPixelZ());
}
}
void cProtocol172::SendMapInfo(int a_ID, unsigned int a_Scale)
{
cPacketizer Pkt(*this, 0x34);

View File

@ -77,6 +77,7 @@ public:
virtual void SendKeepAlive (int a_PingID) override;
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override;
virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override;
virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override;
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
virtual void SendPlayerAbilities (void) override;

View File

@ -396,6 +396,16 @@ void cProtocolRecognizer::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte *
void cProtocolRecognizer::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators)
{
ASSERT(m_Protocol != NULL);
m_Protocol->SendMapDecorators(a_ID, a_Decorators);
}
void cProtocolRecognizer::SendMapInfo(int a_ID, unsigned int a_Scale)
{
ASSERT(m_Protocol != NULL);

View File

@ -90,6 +90,7 @@ public:
virtual void SendKeepAlive (int a_PingID) override;
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override;
virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override;
virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override;
virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override;
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;