rendered paste bodyIndex: src/game/Object.cpp
===================================================================
--- src/game/Object.cpp (working copy)
+++ src/game/Object.cpp (working copy)
@@ -32,6 +32,7 @@
#include "ObjectAccessor.h"
#include "Log.h"
#include "Transports.h"
+#include "Chat.h"
using namespace std;
@@ -46,11 +47,13 @@
m_inWorld = false;
m_objectUpdated = false;
+
+ m_PackGUID.clear();
+ _SetPackGUID(&m_PackGUID,0);
}
Object::~Object( )
{
-
if(m_objectUpdated)
ObjectAccessor::Instance().RemoveUpdateObject(this);
@@ -99,69 +102,69 @@
void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const
{
- if(!target) return;
+ if(!target)
+ {
+ return;
+ }
- ByteBuffer buf(500);
- buf << uint8( UPDATETYPE_CREATE_OBJECT );
- buf << uint8( 0xFF );
- buf << GetGUID() ;
- buf << m_objectTypeId;
+ uint8 updatetype = UPDATETYPE_CREATE_OBJECT;
+ uint8 flags = m_updateFlag;
+ uint32 flags2 = 0;
- switch(m_objectTypeId)
+ /** lower flag1 **/
+ if(target == this) // building packet for oneself
+ flags |= UPDATEFLAG_SELF;
+
+ // flags2 only used at LIVING objects
+ if(flags & UPDATEFLAG_LIVING)
{
- case TYPEID_OBJECT: //do nothing
- break;
- case TYPEID_ITEM:
- case TYPEID_CONTAINER:
- _BuildMovementUpdate( &buf, 0x10, 0x0 );
- break;
- case TYPEID_UNIT:
- _BuildMovementUpdate( &buf, 0x70, 0x800000 );
- break;
- case TYPEID_PLAYER:
+ if(m_objectTypeId == TYPEID_PLAYER && ((Player*)this)->GetTransport() != 0)
+ flags2 |= 0x0200;
+
+ // UPDATETYPE_CREATE_OBJECT2 for pets, dynamic objects, corpses...
+ if(isType(TYPE_DYNAMICOBJECT) || isType(TYPE_CORPSE) || isType(TYPE_PLAYER))
+ updatetype = UPDATETYPE_CREATE_OBJECT2;
+
+ /*if(m_objectTypeId == TYPEID_PLAYER)
{
- if( target == this ) //build for self
+ updatetype = UPDATETYPE_CREATE_OBJECT2; // dunno when exactly this's used
+ //flags2 |= 0x00002000;
+ }*/
+
+ //if(m_objectTypeId == TYPEID_GAMEOBJECT)
+ if(isType(TYPE_GAMEOBJECT))
+ {
+ switch(m_uint32Values[GAMEOBJECT_TYPE_ID])
{
- buf.clear();
- buf << uint8( UPDATETYPE_CREATE_OBJECT2 );
- buf << uint8( 0xFF ); // must be packet GUID ?
- buf << GetGUID() ;
- buf << m_objectTypeId;
- _BuildMovementUpdate( &buf, 0x71, 0x2000 );
+ case GAMEOBJECT_TYPE_TRAP:
+ case GAMEOBJECT_TYPE_DUEL_ARBITER:
+ case GAMEOBJECT_TYPE_FLAGSTAND:
+ case GAMEOBJECT_TYPE_FLAGDROP:
+ // Duel flag will only animate if it's updatetype = UPDATETYPE_CREATE_OBJECT2.
+ updatetype = UPDATETYPE_CREATE_OBJECT2;
+ break;
}
- //build for other player
- else
- {
- _BuildMovementUpdate( &buf, 0x70, 0x0 );
- }
- }break;
- case TYPEID_CORPSE:
- case TYPEID_GAMEOBJECT:
- case TYPEID_DYNAMICOBJECT:
- {
- if ((GUID_HIPART(GetGUID())==HIGHGUID_PLAYER_CORPSE) || (GUID_HIPART(GetGUID()) == HIGHGUID_TRANSPORT))
- _BuildMovementUpdate( &buf, 0x52, 0x0 );
- else
- _BuildMovementUpdate( &buf, 0x50, 0x0 );
- }break;
- //case TYPEID_AIGROUP:
- //case TYPEID_AREATRIGGER:
- //break;
- default: //know type
- sLog.outDetail("Unknown Object Type %u Create Update Block.\n", m_objectTypeId);
- break;
+ }
}
+ sLog.outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updatetype, m_objectTypeId, flags, flags2);
+
+ ByteBuffer buf(500);
+ buf << updatetype;
+ //buf.append(GetPackGUID()); //client crashes when using this
+ buf << (uint8)0xFF << GetGUID();
+ buf << m_objectTypeId;
+
+ _BuildMovementUpdate(&buf, flags, flags2);
+
UpdateMask updateMask;
updateMask.SetCount( m_valuesCount );
_SetCreateBits( &updateMask, target );
- _BuildValuesUpdate( &buf, &updateMask );
+ _BuildValuesUpdate( &buf, &updateMask, target );
data->AddUpdateBlock(buf);
-
}
-void
-Object::BuildUpdate(UpdateDataMapType &update_players)
+void Object::BuildUpdate(UpdateDataMapType &update_players)
{
ObjectAccessor::_buildUpdateObject(this,update_players);
ClearUpdateMask(true);
@@ -189,14 +192,15 @@
ByteBuffer buf(500);
buf << (uint8) UPDATETYPE_VALUES;
- buf << (uint8) 0xFF; // must be packed GUID ?
+ //buf.append(GetPackGUID()); client crashes when using this
+ buf << (uint8)0xFF;
buf << GetGUID();
UpdateMask updateMask;
updateMask.SetCount( m_valuesCount );
_SetUpdateBits( &updateMask, target );
- _BuildValuesUpdate( &buf, &updateMask );
+ _BuildValuesUpdate( &buf, &updateMask, target );
data->AddUpdateBlock(buf);
}
@@ -219,118 +223,97 @@
void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const
{
*data << (uint8)flags;
- if( m_objectTypeId==TYPEID_PLAYER )
+
+ if (flags & UPDATEFLAG_LIVING) // 0x20
{
- if(((Player*)this)->GetTransport())
+ if(m_objectTypeId == TYPEID_UNIT)
{
- flags2 |= 0x02000000;
+ switch(GetEntry())
+ {
+ case 6491: // Spirit Healer
+ case 13116: // Alliance Spirit Guide
+ case 13117: // Horde Spirit Guide
+ flags2 |= 0x10000000;
+ break;
+ }
}
- *data << (uint32)flags2;
- *data << (uint32)getMSTime();
+ *data << flags2;
+ *data << getMSTime(); // this appears to be time in ms but can be any thing
+ }
- if (!((Player *)this)->GetTransport())
+ if (flags & UPDATEFLAG_HASPOSITION) // 0x40
+ {
+ if(flags & UPDATEFLAG_TRANSPORT) // 0x2
{
- *data << ((Player *)this)->GetPositionX();
- *data << ((Player *)this)->GetPositionY();
- *data << ((Player *)this)->GetPositionZ();
- *data << ((Player *)this)->GetOrientation();
+ *data << (float)0;
+ *data << (float)0;
+ *data << (float)0;
+ *data << ((WorldObject *)this)->GetOrientation();
}
else
{
- //*data << ((Player *)this)->m_transport->GetPositionX() + (float)((Player *)this)->m_transX;
- //*data << ((Player *)this)->m_transport->GetPositionY() + (float)((Player *)this)->m_transY;
- //*data << ((Player *)this)->m_transport->GetPositionZ() + (float)((Player *)this)->m_transZ;
+ *data << ((WorldObject *)this)->GetPositionX();
+ *data << ((WorldObject *)this)->GetPositionY();
+ *data << ((WorldObject *)this)->GetPositionZ();
+ *data << ((WorldObject *)this)->GetOrientation();
+ }
- *data << ((Player *)this)->GetTransport()->GetPositionX();
- *data << ((Player *)this)->GetTransport()->GetPositionY();
- *data << ((Player *)this)->GetTransport()->GetPositionZ();
- *data << ((Player *)this)->GetTransport()->GetOrientation();
-
- *data << (uint64)(((Player *)this)->GetTransport()->GetGUID());
- *data << ((Player *)this)->GetTransOffsetX();
- *data << ((Player *)this)->GetTransOffsetY();
- *data << ((Player *)this)->GetTransOffsetZ();
- *data << ((Player *)this)->GetTransOffsetO();
+ if(flags2 & 0x0200)
+ {
+ *data << (uint64)((Player*)this)->GetTransport()->GetGUID();
+ *data << (float)((Player*)this)->GetTransOffsetX();
+ *data << (float)((Player*)this)->GetTransOffsetY();
+ *data << (float)((Player*)this)->GetTransOffsetZ();
+ *data << (float)((Player*)this)->GetTransOffsetO();
+ *data << uint32(0x11); //unk, was added in 2.0.3
}
+ }
- *data << (float)0;
+ if (flags & UPDATEFLAG_LIVING) // 0x20
+ {
+ *data << (uint32)0; // unknown
- if(flags2 & 0x2000) //update self
+ if(flags2 & 0x2000) // unknown, unused now
{
*data << (float)0;
*data << (float)1.0;
+ *data << (float)0.0;
*data << (float)0;
- *data << (float)0;
}
- *data << ((Player*)this)->GetSpeed( MOVE_WALK );
- *data << ((Player*)this)->GetSpeed( MOVE_RUN );
- *data << ((Player*)this)->GetSpeed( MOVE_SWIMBACK );
- *data << ((Player*)this)->GetSpeed( MOVE_SWIM );
- *data << ((Player*)this)->GetSpeed( MOVE_WALKBACK );
- *data << ((Player*)this)->GetSpeed( MOVE_TURN );
+
+ *data << ((Unit*)this)->GetSpeed( MOVE_WALK );
+ *data << ((Unit*)this)->GetSpeed( MOVE_RUN );
+ *data << ((Unit*)this)->GetSpeed( MOVE_SWIMBACK );
+ *data << ((Unit*)this)->GetSpeed( MOVE_SWIM );
+ *data << ((Unit*)this)->GetSpeed( MOVE_WALKBACK );
+ *data << ((Unit*)this)->GetSpeed( MOVE_FLY );
+ *data << ((Unit*)this)->GetSpeed( MOVE_FLYBACK );
+ *data << ((Unit*)this)->GetSpeed( MOVE_TURN );
}
- if( m_objectTypeId==TYPEID_UNIT )
+
+ if(flags & UPDATEFLAG_ALL) // 0x10
{
- *data << (uint32)flags2;
- *data << (uint32)0xB5771D7F;
- *data << ((Unit *)this)->GetPositionX();
- *data << ((Unit *)this)->GetPositionY();
- *data << ((Unit *)this)->GetPositionZ();
- *data << ((Unit *)this)->GetOrientation();
- *data << (float)0;
- *data << ((Creature*)this)->GetSpeed( MOVE_WALK );
- *data << ((Creature*)this)->GetSpeed( MOVE_RUN );
- *data << ((Creature*)this)->GetSpeed( MOVE_SWIMBACK );
- *data << ((Creature*)this)->GetSpeed( MOVE_SWIM );
- *data << ((Creature*)this)->GetSpeed( MOVE_WALKBACK );
- *data << ((Creature*)this)->GetSpeed( MOVE_TURN );
- uint8 PosCount=0;
- if(flags2 & 0x400000)
- {
- *data << (uint32)0x0;
- *data << (uint32)0x659;
- *data << (uint32)0xB7B;
- *data << (uint32)0xFDA0B4;
- *data << (uint32)PosCount;
- for(int i=0;i<PosCount+1;i++)
- {
- *data << (float)0; //x
- *data << (float)0; //y
- *data << (float)0; //z
- }
- }
+ *data << uint32(1); // looks like flags (0x0, 0x1, 0x100, 0x20000, 0x40000)
}
- if( (m_objectTypeId==TYPEID_CORPSE) || (m_objectTypeId==TYPEID_GAMEOBJECT) || (m_objectTypeId==TYPEID_DYNAMICOBJECT))
+
+ if(flags & UPDATEFLAG_HIGHGUID) // 0x8
{
- if(GUID_HIPART(GetGUID()) != HIGHGUID_TRANSPORT)
- {
- *data << ((WorldObject *)this)->GetPositionX();
- *data << ((WorldObject *)this)->GetPositionY();
- *data << ((WorldObject *)this)->GetPositionZ();
- }
- else
- {
- *data << (uint32)0;
- *data << (uint32)0;
- *data << (uint32)0;
- }
- *data << ((WorldObject *)this)->GetOrientation();
+ *data << GetGUIDHigh(); // 2.0.6 - high guid was there...
}
- *data << (uint32)0x1;
-
- if ((GUID_HIPART(GetGUID()) == HIGHGUID_TRANSPORT))
+ if(flags & UPDATEFLAG_FULLGUID) // 0x4
{
- uint32 updT = (uint32)getMSTime();
- *data << (uint32)updT;
+ // unused in mangos
}
- if( GUID_HIPART(GetGUID()) == HIGHGUID_PLAYER_CORPSE)
- *data << (uint32)0xBD38BA14; //fix me
+ if(flags & UPDATEFLAG_TRANSPORT) // 0x2
+ {
+ *data << getMSTime();
+ }
}
-void Object::_BuildValuesUpdate(ByteBuffer * data, UpdateMask *updateMask) const
+void Object::_BuildValuesUpdate(ByteBuffer * data, UpdateMask *updateMask, Player *target) const
{
WPAssert(updateMask && updateMask->GetCount() == m_valuesCount);
@@ -344,13 +327,14 @@
{
if( updateMask->GetBit( index ) )
{
- // Some values at server stored in float format but must be send to client in uint32 format
- if( // unit fields
- index >= UNIT_FIELD_POWER1 && index <= UNIT_FIELD_MAXPOWER5 ||
- index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME ||
- index >= UNIT_FIELD_STR && index <= UNIT_FIELD_RESISTANCES + 6 ||
+ // Some values at server stored in float format but must be sended to client in uint32 format
+ if( // unit fields
+ (index >= UNIT_FIELD_POWER1 && index <= UNIT_FIELD_MAXPOWER5 ||
+ index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME ||
+ index >= UNIT_FIELD_STAT0 && index <= (UNIT_FIELD_RESISTANCES + 6) ||
+ index >= UNIT_FIELD_POSSTAT0 && index <= (UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 6) ) &&
//player fields (2 comparison preferred instead redundant isType(TYPE_PLAYER) check
- index >= PLAYER_FIELD_POSSTAT0 && index <= PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + 6 )
+ (m_objectTypeId == TYPEID_UNIT || m_objectTypeId == TYPEID_PLAYER) )
{
// convert from float to uint32 and send
*data << uint32(m_floatValues[ index ]);
Index: src/game/Transports.cpp
===================================================================
--- src/game/Transports.cpp (working copy)
+++ src/game/Transports.cpp (working copy)
@@ -110,6 +110,7 @@
Transport::Transport( WorldObject *instantiator ) : GameObject( instantiator )
{
+ m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_HIGHGUID | UPDATEFLAG_ALL | UPDATEFLAG_HASPOSITION);
}
bool Transport::Create(uint32 guidlow, uint32 displayId, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags)
Index: src/game/Object.h
===================================================================
--- src/game/Object.h (working copy)
+++ src/game/Object.h (working copy)
@@ -201,12 +201,13 @@
virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
void _BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const;
- void _BuildValuesUpdate( ByteBuffer *data, UpdateMask *updateMask ) const;
+ void _BuildValuesUpdate( ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
void _SetPackGUID(ByteBuffer *buffer, const uint64 &guid64) const;
uint16 m_objectType;
uint8 m_objectTypeId;
+ uint8 m_updateFlag;
union
{
Index: src/game/Corpse.cpp
===================================================================
--- src/game/Corpse.cpp (working copy)
+++ src/game/Corpse.cpp (working copy)
@@ -33,6 +33,7 @@
{
m_objectType |= TYPE_CORPSE;
m_objectTypeId = TYPEID_CORPSE;
+ m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_ALL | UPDATEFLAG_HASPOSITION); // 2.0.10 - 0x58
m_valuesCount = CORPSE_END;
Index: src/game/DynamicObject.cpp
===================================================================
--- src/game/DynamicObject.cpp (working copy)
+++ src/game/DynamicObject.cpp (working copy)
@@ -37,6 +37,7 @@
{
m_objectType |= TYPE_DYNAMICOBJECT;
m_objectTypeId = TYPEID_DYNAMICOBJECT;
+ m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_ALL | UPDATEFLAG_HASPOSITION); // 2.0.10 - 0x58
m_valuesCount = DYNAMICOBJECT_END;
}
Index: src/game/Item.cpp
===================================================================
--- src/game/Item.cpp (working copy)
+++ src/game/Item.cpp (working copy)
@@ -160,6 +160,7 @@
{
m_objectType |= TYPE_ITEM;
m_objectTypeId = TYPEID_ITEM;
+ m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_ALL);
m_valuesCount = ITEM_END;
m_slot = 0;
Index: src/game/GameObject.cpp
===================================================================
--- src/game/GameObject.cpp (working copy)
+++ src/game/GameObject.cpp (working copy)
@@ -37,6 +37,7 @@
{
m_objectType |= TYPE_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
+ m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_ALL | UPDATEFLAG_HASPOSITION); // 2.0.10 - 0x58
m_valuesCount = GAMEOBJECT_END;
m_respawnTime = 0;
@@ -310,7 +311,6 @@
void GameObject::Delete()
{
-
SendObjectDeSpawnAnim(GetGUID());
SetUInt32Value(GAMEOBJECT_STATE, 1);
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp (working copy)
+++ src/game/Unit.cpp (working copy)
@@ -57,6 +57,7 @@
{
m_objectType |= TYPE_UNIT;
m_objectTypeId = TYPEID_UNIT;
+ m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_ALL | UPDATEFLAG_LIVING | UPDATEFLAG_HASPOSITION);
m_attackTimer[BASE_ATTACK] = 0;
m_attackTimer[OFF_ATTACK] = 0;
Index: src/game/UpdateData.cpp
===================================================================
--- src/game/UpdateData.cpp (working copy)
+++ src/game/UpdateData.cpp (working copy)
@@ -97,7 +97,7 @@
ByteBuffer buf(m_data.size() + 10 + m_outOfRangeGUIDs.size()*8);
buf << (uint32) (m_outOfRangeGUIDs.size() > 0 ? m_blockCount + 1 : m_blockCount);
- buf << (uint8) 1;
+ buf << (uint8) 0;
if(m_outOfRangeGUIDs.size())
{
@@ -118,7 +118,6 @@
if (m_data.size() > 50 )
{
-
uint32 destsize = buf.size() + buf.size()/10 + 16;
packet->resize( destsize );