feat(Core/Misc): implement ObjectGuid class (port from TC) (#4885)

This commit is contained in:
UltraNix
2021-04-25 22:18:03 +02:00
committed by GitHub
parent 91081f4ad8
commit f4c226423d
568 changed files with 10655 additions and 11019 deletions

View File

@@ -47,33 +47,6 @@
#include "LuaEngine.h"
#endif
uint32 GuidHigh2TypeId(uint32 guid_hi)
{
switch (guid_hi)
{
case HIGHGUID_ITEM:
return TYPEID_ITEM;
//case HIGHGUID_CONTAINER: return TYPEID_CONTAINER; HIGHGUID_CONTAINER == HIGHGUID_ITEM currently
case HIGHGUID_UNIT:
return TYPEID_UNIT;
case HIGHGUID_PET:
return TYPEID_UNIT;
case HIGHGUID_PLAYER:
return TYPEID_PLAYER;
case HIGHGUID_GAMEOBJECT:
return TYPEID_GAMEOBJECT;
case HIGHGUID_DYNAMICOBJECT:
return TYPEID_DYNAMICOBJECT;
case HIGHGUID_CORPSE:
return TYPEID_CORPSE;
case HIGHGUID_MO_TRANSPORT:
return TYPEID_GAMEOBJECT;
case HIGHGUID_VEHICLE:
return TYPEID_UNIT;
}
return NUM_CLIENT_OBJECT_TYPES; // unknown
}
Object::Object() : m_PackGUID(sizeof(uint64) + 1)
{
m_objectTypeId = TYPEID_OBJECT;
@@ -86,8 +59,6 @@ Object::Object() : m_PackGUID(sizeof(uint64) + 1)
m_inWorld = false;
m_objectUpdated = false;
m_PackGUID.appendPackGUID(0);
sScriptMgr->OnConstructObject(this);
}
@@ -103,7 +74,7 @@ WorldObject::~WorldObject()
{
if (GetTypeId() == TYPEID_CORPSE)
{
LOG_FATAL("server", "Object::~Object Corpse guid=" UI64FMTD ", type=%d, entry=%u deleted but still in map!!", GetGUID(), ((Corpse*)this)->GetType(), GetEntry());
LOG_FATAL("server", "Object::~Object Corpse %s, type=%d deleted but still in map!!", GetGUID().ToString().c_str(), ((Corpse*)this)->GetType());
ABORT();
}
ResetMap();
@@ -116,18 +87,16 @@ Object::~Object()
if (IsInWorld())
{
LOG_FATAL("server", "Object::~Object - guid=" UI64FMTD ", typeid=%d, entry=%u deleted but still in world!!", GetGUID(), GetTypeId(), GetEntry());
LOG_FATAL("server", "Object::~Object - %s deleted but still in world!!", GetGUID().ToString().c_str());
if (isType(TYPEMASK_ITEM))
LOG_FATAL("server", "Item slot %u", ((Item*)this)->GetSlot());
ABORT();
RemoveFromWorld();
}
if (m_objectUpdated)
{
LOG_FATAL("server", "Object::~Object - guid=" UI64FMTD ", typeid=%d, entry=%u deleted but still in update list!!", GetGUID(), GetTypeId(), GetEntry());
LOG_FATAL("server", "Object::~Object - %s deleted but still in update list!!", GetGUID().ToString().c_str());
ABORT();
sObjectAccessor->RemoveUpdateObject(this);
}
delete [] m_uint32Values;
@@ -144,15 +113,14 @@ void Object::_InitValues()
m_objectUpdated = false;
}
void Object::_Create(uint32 guidlow, uint32 entry, HighGuid guidhigh)
void Object::_Create(ObjectGuid::LowType guidlow, uint32 entry, HighGuid guidhigh)
{
if (!m_uint32Values) _InitValues();
uint64 guid = MAKE_NEW_GUID(guidlow, entry, guidhigh);
SetUInt64Value(OBJECT_FIELD_GUID, guid);
ObjectGuid guid(guidhigh, entry, guidlow);
SetGuidValue(OBJECT_FIELD_GUID, guid);
SetUInt32Value(OBJECT_FIELD_TYPE, m_objectType);
m_PackGUID.wpos(0);
m_PackGUID.appendPackGUID(GetGUID());
m_PackGUID.Set(guid);
}
std::string Object::_ConcatFields(uint16 startIndex, uint16 size) const
@@ -173,7 +141,8 @@ void Object::AddToWorld()
m_inWorld = true;
// synchronize values mirror with values array (changes will send in updatecreate opcode any way
ClearUpdateMask(true);
ASSERT(!m_objectUpdated);
ClearUpdateMask(false);
}
void Object::RemoveFromWorld()
@@ -192,7 +161,7 @@ void Object::BuildMovementUpdateBlock(UpdateData* data, uint32 flags) const
ByteBuffer buf(500);
buf << uint8(UPDATETYPE_MOVEMENT);
buf.append(GetPackGUID());
buf << GetPackGUID();
BuildMovementUpdate(&buf, flags);
@@ -248,7 +217,7 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
ByteBuffer buf(500);
buf << (uint8)updatetype;
buf.append(GetPackGUID());
buf << GetPackGUID();
buf << (uint8)m_objectTypeId;
BuildMovementUpdate(&buf, flags);
@@ -272,7 +241,7 @@ void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) c
ByteBuffer buf(500);
buf << (uint8) UPDATETYPE_VALUES;
buf.append(GetPackGUID());
buf << GetPackGUID();
BuildValuesUpdate(UPDATETYPE_VALUES, &buf, target);
@@ -295,14 +264,14 @@ void Object::DestroyForPlayer(Player* target, bool onDeath) const
if (bg->isArena())
{
WorldPacket data(SMSG_ARENA_UNIT_DESTROYED, 8);
data << uint64(GetGUID());
data << GetGUID();
target->GetSession()->SendPacket(&data);
}
}
}
WorldPacket data(SMSG_DESTROY_OBJECT, 8 + 1);
data << uint64(GetGUID());
data << GetGUID();
//! If the following bool is true, the client will call "void CGUnit_C::OnDeath()" for this object.
//! OnDeath() does for eg trigger death animation and interrupts certain spells/missiles/auras/sounds...
data << uint8(onDeath ? 1 : 0);
@@ -353,7 +322,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
Transport* transport = object->GetTransport();
if (transport)
data->append(transport->GetPackGUID());
*data << transport->GetPackGUID();
else
*data << uint8(0);
@@ -411,7 +380,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
case TYPEID_GAMEOBJECT:
case TYPEID_DYNAMICOBJECT:
case TYPEID_CORPSE:
*data << uint32(GetGUIDLow()); // GetGUIDLow()
*data << uint32(GetGUID().GetCounter());
break;
//! Unit, Player and default here are sending wrong values.
/// @todo Research the proper formula
@@ -434,7 +403,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
if (flags & UPDATEFLAG_HAS_TARGET)
{
if (Unit* victim = unit->GetVictim())
data->append(victim->GetPackGUID());
*data << victim->GetPackGUID();
else
*data << uint8(0);
}
@@ -492,6 +461,15 @@ void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* targe
data->append(fieldBuffer);
}
void Object::AddToObjectUpdateIfNeeded()
{
if (m_inWorld && !m_objectUpdated)
{
AddToObjectUpdate();
m_objectUpdated = true;
}
}
void Object::ClearUpdateMask(bool remove)
{
_changesMask.Clear();
@@ -499,7 +477,7 @@ void Object::ClearUpdateMask(bool remove)
if (m_objectUpdated)
{
if (remove)
sObjectAccessor->RemoveUpdateObject(this);
RemoveFromObjectUpdate();
m_objectUpdated = false;
}
}
@@ -597,11 +575,7 @@ void Object::SetInt32Value(uint16 index, int32 value)
m_int32Values[index] = value;
_changesMask.SetBit(index);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
}
}
@@ -614,11 +588,7 @@ void Object::SetUInt32Value(uint16 index, uint32 value)
m_uint32Values[index] = value;
_changesMask.SetBit(index);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
}
}
@@ -633,6 +603,7 @@ void Object::UpdateUInt32Value(uint16 index, uint32 value)
void Object::SetUInt64Value(uint16 index, uint64 value)
{
ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true));
if (*((uint64*) & (m_uint32Values[index])) != value)
{
m_uint32Values[index] = PAIR64_LOPART(value);
@@ -640,29 +611,21 @@ void Object::SetUInt64Value(uint16 index, uint64 value)
_changesMask.SetBit(index);
_changesMask.SetBit(index + 1);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
}
}
bool Object::AddUInt64Value(uint16 index, uint64 value)
bool Object::AddGuidValue(uint16 index, ObjectGuid value)
{
ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true));
if (value && !*((uint64*) & (m_uint32Values[index])))
if (value && !*((ObjectGuid*)&(m_uint32Values[index])))
{
m_uint32Values[index] = PAIR64_LOPART(value);
m_uint32Values[index + 1] = PAIR64_HIPART(value);
*((ObjectGuid*)&(m_uint32Values[index])) = value;
_changesMask.SetBit(index);
_changesMask.SetBit(index + 1);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
return true;
}
@@ -670,21 +633,18 @@ bool Object::AddUInt64Value(uint16 index, uint64 value)
return false;
}
bool Object::RemoveUInt64Value(uint16 index, uint64 value)
bool Object::RemoveGuidValue(uint16 index, ObjectGuid value)
{
ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true));
if (value && *((uint64*) & (m_uint32Values[index])) == value)
if (value && *((ObjectGuid*)&(m_uint32Values[index])) == value)
{
m_uint32Values[index] = 0;
m_uint32Values[index + 1] = 0;
_changesMask.SetBit(index);
_changesMask.SetBit(index + 1);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
return true;
}
@@ -692,6 +652,20 @@ bool Object::RemoveUInt64Value(uint16 index, uint64 value)
return false;
}
void Object::SetGuidValue(uint16 index, ObjectGuid value)
{
ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true));
if (*((ObjectGuid*)&(m_uint32Values[index])) != value)
{
*((ObjectGuid*)&(m_uint32Values[index])) = value;
_changesMask.SetBit(index);
_changesMask.SetBit(index + 1);
AddToObjectUpdateIfNeeded();
}
}
void Object::SetFloatValue(uint16 index, float value)
{
ASSERT(index < m_valuesCount || PrintIndexError(index, true));
@@ -701,11 +675,7 @@ void Object::SetFloatValue(uint16 index, float value)
m_floatValues[index] = value;
_changesMask.SetBit(index);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
}
}
@@ -725,11 +695,7 @@ void Object::SetByteValue(uint16 index, uint8 offset, uint8 value)
m_uint32Values[index] |= uint32(uint32(value) << (offset * 8));
_changesMask.SetBit(index);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
}
}
@@ -749,11 +715,7 @@ void Object::SetUInt16Value(uint16 index, uint8 offset, uint16 value)
m_uint32Values[index] |= uint32(uint32(value) << (offset * 16));
_changesMask.SetBit(index);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
}
}
@@ -816,11 +778,7 @@ void Object::SetFlag(uint16 index, uint32 newFlag)
m_uint32Values[index] = newval;
_changesMask.SetBit(index);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
}
}
@@ -837,11 +795,7 @@ void Object::RemoveFlag(uint16 index, uint32 oldFlag)
m_uint32Values[index] = newval;
_changesMask.SetBit(index);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
}
}
@@ -860,11 +814,7 @@ void Object::SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
m_uint32Values[index] |= uint32(uint32(newFlag) << (offset * 8));
_changesMask.SetBit(index);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
}
}
@@ -883,11 +833,7 @@ void Object::RemoveByteFlag(uint16 index, uint8 offset, uint8 oldFlag)
m_uint32Values[index] &= ~uint32(uint32(oldFlag) << (offset * 8));
_changesMask.SetBit(index);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
}
}
@@ -966,7 +912,7 @@ ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& st
void MovementInfo::OutDebug()
{
LOG_INFO("server", "MOVEMENT INFO");
LOG_INFO("server", "guid " UI64FMTD, guid);
LOG_INFO("server", "guid %s", guid.ToString().c_str());
LOG_INFO("server", "flags %u", flags);
LOG_INFO("server", "flags2 %u", flags2);
LOG_INFO("server", "time %u current time " UI64FMTD "", flags2, uint64(::time(nullptr)));
@@ -974,7 +920,7 @@ void MovementInfo::OutDebug()
if (flags & MOVEMENTFLAG_ONTRANSPORT)
{
LOG_INFO("server", "TRANSPORT:");
LOG_INFO("server", "guid: " UI64FMTD, transport.guid);
LOG_INFO("server", "guid: %s", transport.guid.ToString().c_str());
LOG_INFO("server", "position: `%s`", transport.pos.ToString().c_str());
LOG_INFO("server", "seat: %i", transport.seat);
LOG_INFO("server", "time: %u", transport.time);
@@ -1082,7 +1028,7 @@ void WorldObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
RemoveFromWorld();
}
void WorldObject::_Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask)
void WorldObject::_Create(ObjectGuid::LowType guidlow, HighGuid guidhigh, uint32 phaseMask)
{
Object::_Create(guidlow, 0, guidhigh);
SetPhaseMask(phaseMask, false);
@@ -1122,7 +1068,7 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool
float sizefactor = GetObjectSize() + obj->GetObjectSize();
float maxdist = dist2compare + sizefactor;
if (m_transport && obj->GetTransport() && obj->GetTransport()->GetGUIDLow() == m_transport->GetGUIDLow())
if (m_transport && obj->GetTransport() && obj->GetTransport()->GetGUID() == m_transport->GetGUID())
{
float dtx = m_movementInfo.transport.pos.m_positionX - obj->m_movementInfo.transport.pos.m_positionX;
float dty = m_movementInfo.transport.pos.m_positionY - obj->m_movementInfo.transport.pos.m_positionY;
@@ -1951,11 +1897,7 @@ void WorldObject::SendPlayMusic(uint32 Music, bool OnlySelf)
void Object::ForceValuesUpdateAtIndex(uint32 i)
{
_changesMask.SetBit(i);
if (m_inWorld && !m_objectUpdated)
{
sObjectAccessor->AddUpdateObject(this);
m_objectUpdated = true;
}
AddToObjectUpdateIfNeeded();
}
namespace acore
@@ -2120,7 +2062,7 @@ void WorldObject::MonsterWhisper(int32 textId, Player const* target, bool IsBoss
void Unit::BuildHeartBeatMsg(WorldPacket* data) const
{
data->Initialize(MSG_MOVE_HEARTBEAT, 32);
data->append(GetPackGUID());
*data << GetPackGUID();
BuildMovementPacket(data);
}
@@ -2134,17 +2076,17 @@ void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*
VisitNearbyWorldObject(dist, notifier);
}
void WorldObject::SendObjectDeSpawnAnim(uint64 guid)
void WorldObject::SendObjectDeSpawnAnim(ObjectGuid guid)
{
WorldPacket data(SMSG_GAMEOBJECT_DESPAWN_ANIM, 8);
data << uint64(guid);
data << guid;
SendMessageToSet(&data, true);
}
void WorldObject::SetMap(Map* map)
{
ASSERT(map);
ASSERT(!IsInWorld() || GetTypeId() == TYPEID_CORPSE);
ASSERT(!IsInWorld());
if (m_currMap == map) // command add npc: first create, than loadfromdb
return;
if (m_currMap)
@@ -2197,7 +2139,7 @@ void WorldObject::AddObjectToRemoveList()
Map* map = FindMap();
if (!map)
{
LOG_ERROR("server", "Object (TypeId: %u Entry: %u GUID: %u) at attempt add to move list not have valid map (Id: %u).", GetTypeId(), GetEntry(), GetGUIDLow(), GetMapId());
LOG_ERROR("server", "Object %s at attempt add to move list not have valid map (Id: %u).", GetGUID().ToString().c_str(), GetMapId());
return;
}
@@ -2263,26 +2205,26 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
switch (mask)
{
case UNIT_MASK_SUMMON:
summon = new TempSummon(properties, summoner ? summoner->GetGUID() : 0, false);
summon = new TempSummon(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty, false);
break;
case UNIT_MASK_GUARDIAN:
summon = new Guardian(properties, summoner ? summoner->GetGUID() : 0, false);
summon = new Guardian(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty, false);
break;
case UNIT_MASK_PUPPET:
summon = new Puppet(properties, summoner ? summoner->GetGUID() : 0);
summon = new Puppet(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty);
break;
case UNIT_MASK_TOTEM:
summon = new Totem(properties, summoner ? summoner->GetGUID() : 0);
summon = new Totem(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty);
break;
case UNIT_MASK_MINION:
summon = new Minion(properties, summoner ? summoner->GetGUID() : 0, false);
summon = new Minion(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty, false);
break;
default:
return nullptr;
}
EnsureGridLoaded(Cell(pos.GetPositionX(), pos.GetPositionY()));
if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, vehId, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()))
if (!summon->Create(GenerateLowGuid<HighGuid::Unit>(), this, phase, entry, vehId, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()))
{
delete summon;
return nullptr;
@@ -2293,7 +2235,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
summon->SetHomePosition(pos);
summon->InitStats(duration);
AddToMap(summon->ToCreature(), (IS_PLAYER_GUID(summon->GetOwnerGUID()) || (summoner && summoner->GetTransport())));
AddToMap(summon->ToCreature(), summon->GetOwnerGUID().IsPlayer() || (summoner && summoner->GetTransport()));
summon->InitSummon();
//ObjectAccessor::UpdateObjectVisibility(summon);
@@ -2330,7 +2272,7 @@ GameObject* Map::SummonGameObject(uint32 entry, float x, float y, float z, float
}
GameObject* go = sObjectMgr->IsGameObjectStaticTransport(entry) ? new StaticTransport() : new GameObject();
if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, this, PHASEMASK_NORMAL, x, y, z, ang, G3D::Quat(rotation0, rotation1, rotation2, rotation3), 100, GO_STATE_READY))
if (!go->Create(GenerateLowGuid<HighGuid::GameObject>(), entry, this, PHASEMASK_NORMAL, x, y, z, ang, G3D::Quat(rotation0, rotation1, rotation2, rotation3), 100, GO_STATE_READY))
{
delete go;
return nullptr;
@@ -2363,6 +2305,11 @@ void WorldObject::SetZoneScript()
}
}
void WorldObject::ClearZoneScript()
{
m_zoneScript = nullptr;
}
TempSummon* WorldObject::SummonCreature(uint32 entry, const Position& pos, TempSummonType spwtype, uint32 duration, uint32 /*vehId*/, SummonPropertiesEntry const* properties) const
{
if (Map* map = FindMap())
@@ -2391,7 +2338,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float
Map* map = GetMap();
GameObject* go = sObjectMgr->IsGameObjectStaticTransport(entry) ? new StaticTransport() : new GameObject();
if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, map, GetPhaseMask(), x, y, z, ang, G3D::Quat(rotation0, rotation1, rotation2, rotation3), 100, GO_STATE_READY))
if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, GetPhaseMask(), x, y, z, ang, G3D::Quat(rotation0, rotation1, rotation2, rotation3), 100, GO_STATE_READY))
{
delete go;
return nullptr;
@@ -2857,7 +2804,7 @@ void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= nullptr*
{
WorldPacket data(SMSG_PLAY_OBJECT_SOUND, 4 + 8);
data << uint32(sound_id);
data << uint64(GetGUID());
data << GetGUID();
if (target)
target->SendDirectMessage(&data);
else
@@ -2996,13 +2943,13 @@ struct WorldObjectChangeAccumulator
for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
source = iter->GetSource();
uint64 guid = source->GetCasterGUID();
ObjectGuid guid = source->GetCasterGUID();
if (IS_PLAYER_GUID(guid))
if (guid)
{
//Caster may be nullptr if DynObj is in removelist
if (Player* caster = ObjectAccessor::FindPlayer(guid))
if (caster->GetUInt64Value(PLAYER_FARSIGHT) == source->GetGUID())
if (caster->GetGuidValue(PLAYER_FARSIGHT) == source->GetGUID())
BuildPacket(caster);
}
}
@@ -3011,10 +2958,10 @@ struct WorldObjectChangeAccumulator
void BuildPacket(Player* player)
{
// Only send update once to a player
if (i_playerSet.find(player->GetGUIDLow()) == i_playerSet.end() && player->HaveAtClient(&i_object))
if (i_playerSet.find(player->GetGUID()) == i_playerSet.end() && player->HaveAtClient(&i_object))
{
i_object.BuildFieldsUpdate(player, i_updateDatas);
i_playerSet.insert(player->GetGUIDLow());
i_playerSet.insert(player->GetGUID());
}
}
@@ -3051,11 +2998,22 @@ void WorldObject::GetCreaturesWithEntryInRange(std::list<Creature*>& creatureLis
cell.Visit(pair, grid_visitor, *(this->GetMap()), *this, radius);
}
uint64 WorldObject::GetTransGUID() const
void WorldObject::AddToObjectUpdate()
{
GetMap()->AddUpdateObject(this);
}
void WorldObject::RemoveFromObjectUpdate()
{
GetMap()->RemoveUpdateObject(this);
}
ObjectGuid WorldObject::GetTransGUID() const
{
if (GetTransport())
return GetTransport()->GetGUID();
return 0;
return ObjectGuid::Empty;
}
float WorldObject::GetMapHeight(float x, float y, float z, bool vmap/* = true*/, float distanceToSearch/* = DEFAULT_HEIGHT_SEARCH*/) const

View File

@@ -13,6 +13,7 @@
#include "GridReference.h"
#include "Map.h"
#include "ObjectDefines.h"
#include "ObjectGuid.h"
#include "UpdateData.h"
#include "UpdateMask.h"
#include <set>
@@ -23,35 +24,6 @@
class ElunaEventProcessor;
#endif
enum TypeMask
{
TYPEMASK_OBJECT = 0x0001,
TYPEMASK_ITEM = 0x0002,
TYPEMASK_CONTAINER = 0x0006, // TYPEMASK_ITEM | 0x0004
TYPEMASK_UNIT = 0x0008, // creature
TYPEMASK_PLAYER = 0x0010,
TYPEMASK_GAMEOBJECT = 0x0020,
TYPEMASK_DYNAMICOBJECT = 0x0040,
TYPEMASK_CORPSE = 0x0080,
TYPEMASK_SEER = TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT
};
enum TypeID
{
TYPEID_OBJECT = 0,
TYPEID_ITEM = 1,
TYPEID_CONTAINER = 2,
TYPEID_UNIT = 3,
TYPEID_PLAYER = 4,
TYPEID_GAMEOBJECT = 5,
TYPEID_DYNAMICOBJECT = 6,
TYPEID_CORPSE = 7
};
#define NUM_CLIENT_OBJECT_TYPES 8
uint32 GuidHigh2TypeId(uint32 guid_hi);
enum TempSummonType
{
TEMPSUMMON_TIMED_OR_DEAD_DESPAWN = 1, // despawns after a specified time OR when the creature disappears
@@ -97,7 +69,7 @@ class StaticTransport;
class MotionTransport;
typedef std::unordered_map<Player*, UpdateData> UpdateDataMapType;
typedef std::unordered_set<uint32> UpdatePlayerSet;
typedef GuidUnorderedSet UpdatePlayerSet;
class Object
{
@@ -109,11 +81,9 @@ public:
virtual void AddToWorld();
virtual void RemoveFromWorld();
[[nodiscard]] uint64 GetGUID() const { return GetUInt64Value(0); }
[[nodiscard]] uint32 GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(0)); }
[[nodiscard]] uint32 GetGUIDMid() const { return GUID_ENPART(GetUInt64Value(0)); }
[[nodiscard]] uint32 GetGUIDHigh() const { return GUID_HIPART(GetUInt64Value(0)); }
[[nodiscard]] const ByteBuffer& GetPackGUID() const { return m_PackGUID; }
[[nodiscard]] static ObjectGuid GetGUID(Object const* o) { return o ? o->GetGUID() : ObjectGuid::Empty; }
[[nodiscard]] ObjectGuid GetGUID() const { return GetGuidValue(OBJECT_FIELD_GUID); }
[[nodiscard]] PackedGuid const& GetPackGUID() const { return m_PackGUID; }
[[nodiscard]] uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); }
@@ -170,6 +140,12 @@ public:
return *(((uint16*)&m_uint32Values[index]) + offset);
}
[[nodiscard]] ObjectGuid GetGuidValue(uint16 index) const
{
ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, false));
return *((ObjectGuid*)&(m_uint32Values[index]));
}
void SetInt32Value(uint16 index, int32 value);
void SetUInt32Value(uint16 index, uint32 value);
void UpdateUInt32Value(uint16 index, uint32 value);
@@ -178,11 +154,12 @@ public:
void SetByteValue(uint16 index, uint8 offset, uint8 value);
void SetUInt16Value(uint16 index, uint8 offset, uint16 value);
void SetInt16Value(uint16 index, uint8 offset, int16 value) { SetUInt16Value(index, offset, (uint16)value); }
void SetGuidValue(uint16 index, ObjectGuid value);
void SetStatFloatValue(uint16 index, float value);
void SetStatInt32Value(uint16 index, int32 value);
bool AddUInt64Value(uint16 index, uint64 value);
bool RemoveUInt64Value(uint16 index, uint64 value);
bool AddGuidValue(uint16 index, ObjectGuid value);
bool RemoveGuidValue(uint16 index, ObjectGuid value);
void ApplyModUInt32Value(uint16 index, int32 val, bool apply);
void ApplyModInt32Value(uint16 index, int32 val, bool apply);
@@ -311,7 +288,7 @@ protected:
Object();
void _InitValues();
void _Create(uint32 guidlow, uint32 entry, HighGuid guidhigh);
void _Create(ObjectGuid::LowType guidlow, uint32 entry, HighGuid guidhigh);
[[nodiscard]] std::string _ConcatFields(uint16 startIndex, uint16 size) const;
void _LoadIntoDataField(std::string const& data, uint32 startOffset, uint32 count);
@@ -338,12 +315,16 @@ protected:
uint16 _fieldNotifyFlags;
virtual void AddToObjectUpdate() = 0;
virtual void RemoveFromObjectUpdate() = 0;
void AddToObjectUpdateIfNeeded();
bool m_objectUpdated;
private:
bool m_inWorld;
ByteBuffer m_PackGUID;
PackedGuid m_PackGUID;
// for output helpfull error messages from asserts
[[nodiscard]] bool PrintIndexError(uint32 index, bool set) const;
@@ -586,7 +567,7 @@ ByteBuffer& operator >> (ByteBuffer& buf, Position::PositionXYZOStreamer const&
struct MovementInfo
{
// common
uint64 guid{0};
ObjectGuid guid;
uint32 flags{0};
uint16 flags2{0};
Position pos;
@@ -597,14 +578,14 @@ struct MovementInfo
{
void Reset()
{
guid = 0;
guid.Clear();
pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
seat = -1;
time = 0;
time2 = 0;
}
uint64 guid;
ObjectGuid guid;
Position pos;
int8 seat;
uint32 time;
@@ -674,6 +655,12 @@ public:
Relocate(loc);
}
void WorldRelocate(uint32 mapId = MAPID_INVALID, float x = 0.f, float y = 0.f, float z = 0.f, float o = 0.f)
{
m_mapId = mapId;
Relocate(x, y, z, o);
}
[[nodiscard]] uint32 GetMapId() const
{
return m_mapId;
@@ -758,7 +745,7 @@ public:
#else
virtual void Update(uint32 /*time_diff*/) { };
#endif
void _Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask);
void _Create(ObjectGuid::LowType guidlow, HighGuid guidhigh, uint32 phaseMask);
void RemoveFromWorld() override
{
@@ -928,7 +915,7 @@ public:
void PlayDirectSound(uint32 sound_id, Player* target = nullptr);
void PlayDirectMusic(uint32 music_id, Player* target = nullptr);
void SendObjectDeSpawnAnim(uint64 guid);
void SendObjectDeSpawnAnim(ObjectGuid guid);
virtual void SaveRespawnTime() {}
void AddObjectToRemoveList();
@@ -962,6 +949,7 @@ public:
[[nodiscard]] Map const* GetBaseMap() const;
void SetZoneScript();
void ClearZoneScript();
[[nodiscard]] ZoneScript* GetZoneScript() const { return m_zoneScript; }
TempSummon* SummonCreature(uint32 id, const Position& pos, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0, uint32 vehId = 0, SummonPropertiesEntry const* properties = nullptr) const;
@@ -993,6 +981,9 @@ public:
void BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet& player_set) override;
void GetCreaturesWithEntryInRange(std::list<Creature*>& creatureList, float radius, uint32 entry);
void AddToObjectUpdate() override;
void RemoveFromObjectUpdate() override;
//relocation and visibility system functions
void AddToNotify(uint16 f);
void RemoveFromNotify(uint16 f) { m_notifyflags &= ~f; }
@@ -1037,7 +1028,7 @@ public:
[[nodiscard]] float GetTransOffsetO() const { return m_movementInfo.transport.pos.GetOrientation(); }
[[nodiscard]] uint32 GetTransTime() const { return m_movementInfo.transport.time; }
[[nodiscard]] int8 GetTransSeat() const { return m_movementInfo.transport.seat; }
[[nodiscard]] virtual uint64 GetTransGUID() const;
[[nodiscard]] virtual ObjectGuid GetTransGUID() const;
void SetTransport(Transport* t) { m_transport = t; }
MovementInfo m_movementInfo;

View File

@@ -30,25 +30,7 @@
#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
#define DEFAULT_COLLISION_HEIGHT 2.03128f // Most common value in dbc
enum HighGuid
{
HIGHGUID_ITEM = 0x4000, // blizz 4000
HIGHGUID_CONTAINER = 0x4000, // blizz 4000
HIGHGUID_PLAYER = 0x0000, // blizz 0000
HIGHGUID_GAMEOBJECT = 0xF110, // blizz F110
HIGHGUID_TRANSPORT = 0xF120, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT)
HIGHGUID_UNIT = 0xF130, // blizz F130
HIGHGUID_PET = 0xF140, // blizz F140
HIGHGUID_VEHICLE = 0xF150, // blizz F550
HIGHGUID_DYNAMICOBJECT = 0xF100, // blizz F100
HIGHGUID_CORPSE = 0xF101, // blizz F100
HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT)
HIGHGUID_GROUP = 0x1F50,
HIGHGUID_INSTANCE = 0x1F42, // blizz 1F42/1F44/1F44/1F47
};
// used for creating values for respawn for example
inline uint64 MAKE_PAIR64(uint32 l, uint32 h);
inline uint32 PAIR64_HIPART(uint64 x);
inline uint32 PAIR64_LOPART(uint64 x);
inline uint16 MAKE_PAIR16(uint8 l, uint8 h);
@@ -56,40 +38,6 @@ inline uint32 MAKE_PAIR32(uint16 l, uint16 h);
inline uint16 PAIR32_HIPART(uint32 x);
inline uint16 PAIR32_LOPART(uint32 x);
inline bool IS_EMPTY_GUID(uint64 guid);
inline bool IS_CREATURE_GUID(uint64 guid);
inline bool IS_PET_GUID(uint64 guid);
inline bool IS_VEHICLE_GUID(uint64 guid);
inline bool IS_CRE_OR_VEH_GUID(uint64 guid);
inline bool IS_CRE_OR_VEH_OR_PET_GUID(uint64 guid);
inline bool IS_PLAYER_GUID(uint64 guid);
inline bool IS_UNIT_GUID(uint64 guid);
inline bool IS_ITEM_GUID(uint64 guid);
inline bool IS_GAMEOBJECT_GUID(uint64 guid);
inline bool IS_DYNAMICOBJECT_GUID(uint64 guid);
inline bool IS_CORPSE_GUID(uint64 guid);
inline bool IS_TRANSPORT_GUID(uint64 guid);
inline bool IS_MO_TRANSPORT_GUID(uint64 guid);
inline bool IS_GROUP_GUID(uint64 guid);
// l - OBJECT_FIELD_GUID
// e - OBJECT_FIELD_ENTRY for GO (except GAMEOBJECT_TYPE_MO_TRANSPORT) and creatures or UNIT_FIELD_PETNUMBER for pets
// h - OBJECT_FIELD_GUID + 1
inline uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h);
//#define GUID_HIPART(x) (uint32)((uint64(x) >> 52)) & 0x0000FFFF)
inline uint32 GUID_HIPART(uint64 guid);
inline uint32 GUID_ENPART(uint64 x);
inline uint32 GUID_LOPART(uint64 x);
inline bool IsGuidHaveEnPart(uint64 guid);
inline char const* GetLogNameForGuid(uint64 guid);
uint64 MAKE_PAIR64(uint32 l, uint32 h)
{
return uint64(l | (uint64(h) << 32));
}
uint32 PAIR64_HIPART(uint64 x)
{
return (uint32)((x >> 32) & UI64LIT(0x00000000FFFFFFFF));
@@ -120,155 +68,4 @@ uint16 PAIR32_LOPART(uint32 x)
return (uint16)(x & 0x0000FFFF);
}
bool IS_EMPTY_GUID(uint64 guid)
{
return guid == 0;
}
bool IS_CREATURE_GUID(uint64 guid)
{
return GUID_HIPART(guid) == HIGHGUID_UNIT;
}
bool IS_PET_GUID(uint64 guid)
{
return GUID_HIPART(guid) == HIGHGUID_PET;
}
bool IS_VEHICLE_GUID(uint64 guid)
{
return GUID_HIPART(guid) == HIGHGUID_VEHICLE;
}
bool IS_CRE_OR_VEH_GUID(uint64 guid)
{
return IS_CREATURE_GUID(guid) || IS_VEHICLE_GUID(guid);
}
bool IS_CRE_OR_VEH_OR_PET_GUID(uint64 guid)
{
return IS_CRE_OR_VEH_GUID(guid) || IS_PET_GUID(guid);
}
bool IS_PLAYER_GUID(uint64 guid)
{
return guid != 0 && GUID_HIPART(guid) == HIGHGUID_PLAYER;
}
bool IS_UNIT_GUID(uint64 guid)
{
return IS_CRE_OR_VEH_OR_PET_GUID(guid) || IS_PLAYER_GUID(guid);
}
bool IS_ITEM_GUID(uint64 guid)
{
return GUID_HIPART(guid) == HIGHGUID_ITEM;
}
bool IS_GAMEOBJECT_GUID(uint64 guid)
{
return GUID_HIPART(guid) == HIGHGUID_GAMEOBJECT;
}
bool IS_DYNAMICOBJECT_GUID(uint64 guid)
{
return GUID_HIPART(guid) == HIGHGUID_DYNAMICOBJECT;
}
bool IS_CORPSE_GUID(uint64 guid)
{
return GUID_HIPART(guid) == HIGHGUID_CORPSE;
}
bool IS_TRANSPORT_GUID(uint64 guid)
{
return GUID_HIPART(guid) == HIGHGUID_TRANSPORT;
}
bool IS_MO_TRANSPORT_GUID(uint64 guid)
{
return GUID_HIPART(guid) == HIGHGUID_MO_TRANSPORT;
}
bool IS_GROUP_GUID(uint64 guid)
{
return GUID_HIPART(guid) == HIGHGUID_GROUP;
}
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
{
return uint64(uint64(l) | (uint64(e) << 24) | (uint64(h) << 48));
}
uint32 GUID_HIPART(uint64 guid)
{
return (uint32)((uint64(guid) >> 48) & 0x0000FFFF);
}
uint32 GUID_ENPART(uint64 x)
{
return IsGuidHaveEnPart(x)
? (uint32)((x >> 24) & UI64LIT(0x0000000000FFFFFF))
: 0;
}
uint32 GUID_LOPART(uint64 x)
{
return IsGuidHaveEnPart(x)
? (uint32)(x & UI64LIT(0x0000000000FFFFFF))
: (uint32)(x & UI64LIT(0x00000000FFFFFFFF));
}
bool IsGuidHaveEnPart(uint64 guid)
{
switch (GUID_HIPART(guid))
{
case HIGHGUID_ITEM:
case HIGHGUID_PLAYER:
case HIGHGUID_DYNAMICOBJECT:
case HIGHGUID_CORPSE:
case HIGHGUID_GROUP:
return false;
case HIGHGUID_GAMEOBJECT:
case HIGHGUID_TRANSPORT:
case HIGHGUID_UNIT:
case HIGHGUID_PET:
case HIGHGUID_VEHICLE:
case HIGHGUID_MO_TRANSPORT:
default:
return true;
}
}
char const* GetLogNameForGuid(uint64 guid)
{
switch (GUID_HIPART(guid))
{
case HIGHGUID_ITEM:
return "item";
case HIGHGUID_PLAYER:
return guid ? "player" : "none";
case HIGHGUID_GAMEOBJECT:
return "gameobject";
case HIGHGUID_TRANSPORT:
return "transport";
case HIGHGUID_UNIT:
return "creature";
case HIGHGUID_PET:
return "pet";
case HIGHGUID_VEHICLE:
return "vehicle";
case HIGHGUID_DYNAMICOBJECT:
return "dynobject";
case HIGHGUID_CORPSE:
return "corpse";
case HIGHGUID_MO_TRANSPORT:
return "mo_transport";
case HIGHGUID_GROUP:
return "group";
default:
return "<unknown>";
}
}
#endif

View File

@@ -0,0 +1,100 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
* Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
*/
#include "ObjectGuid.h"
#include "Log.h"
#include "World.h"
#include <sstream>
#include <iomanip>
ObjectGuid const ObjectGuid::Empty = ObjectGuid();
char const* ObjectGuid::GetTypeName(HighGuid high)
{
switch (high)
{
case HighGuid::Item: return "Item";
case HighGuid::Player: return "Player";
case HighGuid::GameObject: return "Gameobject";
case HighGuid::Transport: return "Transport";
case HighGuid::Unit: return "Creature";
case HighGuid::Pet: return "Pet";
case HighGuid::Vehicle: return "Vehicle";
case HighGuid::DynamicObject: return "DynObject";
case HighGuid::Corpse: return "Corpse";
case HighGuid::Mo_Transport: return "MoTransport";
case HighGuid::Instance: return "InstanceID";
case HighGuid::Group: return "Group";
default:
return "<unknown>";
}
}
std::string ObjectGuid::ToString() const
{
std::ostringstream str;
str << "GUID Full: 0x" << std::hex << std::setw(16) << std::setfill('0') << _guid << std::dec;
str << " Type: " << GetTypeName();
if (HasEntry())
str << (IsPet() ? " Pet number: " : " Entry: ") << GetEntry() << " ";
str << " Low: " << GetCounter();
return str.str();
}
ObjectGuid ObjectGuid::Global(HighGuid type, LowType counter)
{
return ObjectGuid(type, counter);
}
ObjectGuid ObjectGuid::MapSpecific(HighGuid type, uint32 entry, LowType counter)
{
return ObjectGuid(type, entry, counter);
}
ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid)
{
buf << uint64(guid.GetRawValue());
return buf;
}
ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid)
{
guid.Set(buf.read<uint64>());
return buf;
}
ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid)
{
buf.append(guid._packedGuid);
return buf;
}
ByteBuffer& operator>>(ByteBuffer& buf, PackedGuidReader const& guid)
{
buf.readPackGUID(reinterpret_cast<uint64&>(guid.Guid));
return buf;
}
void ObjectGuidGeneratorBase::HandleCounterOverflow(HighGuid high)
{
LOG_ERROR("server", "%s guid overflow!! Can't continue, shutting down server. ", ObjectGuid::GetTypeName(high));
World::StopNow(ERROR_EXIT_CODE);
}
#define GUID_TRAIT_INSTANTIATE_GUID( HIGH_GUID ) \
template class ObjectGuidGenerator< HIGH_GUID >;
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Container)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Player)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::GameObject)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Transport)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Unit)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Pet)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Vehicle)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::DynamicObject)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Mo_Transport)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Instance)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Group)

View File

@@ -0,0 +1,323 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
* Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
*/
#ifndef ObjectGuid_h__
#define ObjectGuid_h__
#include "ByteBuffer.h"
#include "Define.h"
#include <deque>
#include <functional>
#include <list>
#include <memory>
#include <set>
#include <type_traits>
#include <vector>
#include <unordered_set>
enum TypeID
{
TYPEID_OBJECT = 0,
TYPEID_ITEM = 1,
TYPEID_CONTAINER = 2,
TYPEID_UNIT = 3,
TYPEID_PLAYER = 4,
TYPEID_GAMEOBJECT = 5,
TYPEID_DYNAMICOBJECT = 6,
TYPEID_CORPSE = 7
};
#define NUM_CLIENT_OBJECT_TYPES 8
enum TypeMask
{
TYPEMASK_OBJECT = 0x0001,
TYPEMASK_ITEM = 0x0002,
TYPEMASK_CONTAINER = 0x0006, // TYPEMASK_ITEM | 0x0004
TYPEMASK_UNIT = 0x0008, // creature
TYPEMASK_PLAYER = 0x0010,
TYPEMASK_GAMEOBJECT = 0x0020,
TYPEMASK_DYNAMICOBJECT = 0x0040,
TYPEMASK_CORPSE = 0x0080,
TYPEMASK_SEER = TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT
};
enum class HighGuid
{
Item = 0x4000, // blizz 4000
Container = 0x4000, // blizz 4000
Player = 0x0000, // blizz 0000
GameObject = 0xF110, // blizz F110
Transport = 0xF120, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT)
Unit = 0xF130, // blizz F130
Pet = 0xF140, // blizz F140
Vehicle = 0xF150, // blizz F550
DynamicObject = 0xF100, // blizz F100
Corpse = 0xF101, // blizz F100
Mo_Transport = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT)
Instance = 0x1F40, // blizz 1F40
Group = 0x1F50,
};
template<HighGuid high>
struct ObjectGuidTraits
{
static bool const Global = false;
static bool const MapSpecific = false;
};
#define GUID_TRAIT_GLOBAL(highguid) \
template<> struct ObjectGuidTraits<highguid> \
{ \
static bool const Global = true; \
static bool const MapSpecific = false; \
};
#define GUID_TRAIT_MAP_SPECIFIC(highguid) \
template<> struct ObjectGuidTraits<highguid> \
{ \
static bool const Global = false; \
static bool const MapSpecific = true; \
};
GUID_TRAIT_GLOBAL(HighGuid::Player)
GUID_TRAIT_GLOBAL(HighGuid::Item)
GUID_TRAIT_GLOBAL(HighGuid::Mo_Transport)
GUID_TRAIT_GLOBAL(HighGuid::Group)
GUID_TRAIT_GLOBAL(HighGuid::Instance)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Transport)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Unit)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Vehicle)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Pet)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::GameObject)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::DynamicObject)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Corpse)
class ObjectGuid;
class PackedGuid;
struct PackedGuidReader
{
explicit PackedGuidReader(ObjectGuid& guid) : Guid(guid) { }
ObjectGuid& Guid;
};
class ObjectGuid
{
public:
static ObjectGuid const Empty;
typedef uint32 LowType;
template<HighGuid type>
static typename std::enable_if<ObjectGuidTraits<type>::Global, ObjectGuid>::type Create(LowType counter) { return Global(type, counter); }
template<HighGuid type>
static typename std::enable_if<ObjectGuidTraits<type>::MapSpecific, ObjectGuid>::type Create(uint32 entry, LowType counter) { return MapSpecific(type, entry, counter); }
ObjectGuid() : _guid(0) { }
explicit ObjectGuid(uint64 guid) : _guid(guid) { }
ObjectGuid(HighGuid hi, uint32 entry, LowType counter) : _guid(counter ? uint64(counter) | (uint64(entry) << 24) | (uint64(hi) << 48) : 0) { }
ObjectGuid(HighGuid hi, LowType counter) : _guid(counter ? uint64(counter) | (uint64(hi) << 48) : 0) { }
PackedGuidReader ReadAsPacked() { return PackedGuidReader(*this); }
void Set(uint64 guid) { _guid = guid; }
void Clear() { _guid = 0; }
PackedGuid WriteAsPacked() const;
uint64 GetRawValue() const { return _guid; }
HighGuid GetHigh() const { return HighGuid((_guid >> 48) & 0x0000FFFF); }
uint32 GetEntry() const { return HasEntry() ? uint32((_guid >> 24) & UI64LIT(0x0000000000FFFFFF)) : 0; }
LowType GetCounter() const
{
return HasEntry()
? LowType(_guid & UI64LIT(0x0000000000FFFFFF))
: LowType(_guid & UI64LIT(0x00000000FFFFFFFF));
}
static LowType GetMaxCounter(HighGuid high)
{
return HasEntry(high)
? LowType(0x00FFFFFF)
: LowType(0xFFFFFFFF);
}
ObjectGuid::LowType GetMaxCounter() const { return GetMaxCounter(GetHigh()); }
bool IsEmpty() const { return _guid == 0; }
bool IsCreature() const { return GetHigh() == HighGuid::Unit; }
bool IsPet() const { return GetHigh() == HighGuid::Pet; }
bool IsVehicle() const { return GetHigh() == HighGuid::Vehicle; }
bool IsCreatureOrPet() const { return IsCreature() || IsPet(); }
bool IsCreatureOrVehicle() const { return IsCreature() || IsVehicle(); }
bool IsAnyTypeCreature() const { return IsCreature() || IsPet() || IsVehicle(); }
bool IsPlayer() const { return !IsEmpty() && GetHigh() == HighGuid::Player; }
bool IsUnit() const { return IsAnyTypeCreature() || IsPlayer(); }
bool IsItem() const { return GetHigh() == HighGuid::Item; }
bool IsGameObject() const { return GetHigh() == HighGuid::GameObject; }
bool IsDynamicObject() const { return GetHigh() == HighGuid::DynamicObject; }
bool IsCorpse() const { return GetHigh() == HighGuid::Corpse; }
bool IsTransport() const { return GetHigh() == HighGuid::Transport; }
bool IsMOTransport() const { return GetHigh() == HighGuid::Mo_Transport; }
bool IsAnyTypeGameObject() const { return IsGameObject() || IsTransport() || IsMOTransport(); }
bool IsInstance() const { return GetHigh() == HighGuid::Instance; }
bool IsGroup() const { return GetHigh() == HighGuid::Group; }
static TypeID GetTypeId(HighGuid high)
{
switch (high)
{
case HighGuid::Item: return TYPEID_ITEM;
//case HighGuid::Container: return TYPEID_CONTAINER; HighGuid::Container == HighGuid::Item currently
case HighGuid::Unit: return TYPEID_UNIT;
case HighGuid::Pet: return TYPEID_UNIT;
case HighGuid::Player: return TYPEID_PLAYER;
case HighGuid::GameObject: return TYPEID_GAMEOBJECT;
case HighGuid::DynamicObject: return TYPEID_DYNAMICOBJECT;
case HighGuid::Corpse: return TYPEID_CORPSE;
case HighGuid::Mo_Transport: return TYPEID_GAMEOBJECT;
case HighGuid::Vehicle: return TYPEID_UNIT;
// unknown
case HighGuid::Instance:
case HighGuid::Group:
default: return TYPEID_OBJECT;
}
}
TypeID GetTypeId() const { return GetTypeId(GetHigh()); }
operator bool() const { return !IsEmpty(); }
bool operator!() const { return !(bool(*this)); }
bool operator==(ObjectGuid const& guid) const { return GetRawValue() == guid.GetRawValue(); }
bool operator!=(ObjectGuid const& guid) const { return GetRawValue() != guid.GetRawValue(); }
bool operator< (ObjectGuid const& guid) const { return GetRawValue() < guid.GetRawValue(); }
bool operator<= (ObjectGuid const& guid) const { return GetRawValue() <= guid.GetRawValue(); }
static char const* GetTypeName(HighGuid high);
char const* GetTypeName() const { return !IsEmpty() ? GetTypeName(GetHigh()) : "None"; }
std::string ToString() const;
private:
static bool HasEntry(HighGuid high)
{
switch (high)
{
case HighGuid::Item:
case HighGuid::Player:
case HighGuid::DynamicObject:
case HighGuid::Corpse:
case HighGuid::Mo_Transport:
case HighGuid::Instance:
case HighGuid::Group:
return false;
case HighGuid::GameObject:
case HighGuid::Transport:
case HighGuid::Unit:
case HighGuid::Pet:
case HighGuid::Vehicle:
default:
return true;
}
}
bool HasEntry() const { return HasEntry(GetHigh()); }
static ObjectGuid Global(HighGuid type, LowType counter);
static ObjectGuid MapSpecific(HighGuid type, uint32 entry, LowType counter);
explicit ObjectGuid(uint32 const&) = delete; // no implementation, used to catch wrong type assignment
ObjectGuid(HighGuid, uint32, uint64 counter) = delete; // no implementation, used to catch wrong type assignment
ObjectGuid(HighGuid, uint64 counter) = delete; // no implementation, used to catch wrong type assignment
// used to catch wrong type assignment
operator int64() const = delete;
uint64 _guid;
};
// Some Shared defines
typedef std::set<ObjectGuid> GuidSet;
typedef std::list<ObjectGuid> GuidList;
typedef std::deque<ObjectGuid> GuidDeque;
typedef std::vector<ObjectGuid> GuidVector;
typedef std::unordered_set<ObjectGuid> GuidUnorderedSet;
// minimum buffer size for packed guid is 9 bytes
#define PACKED_GUID_MIN_BUFFER_SIZE 9
class PackedGuid
{
friend ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid);
public:
explicit PackedGuid() : _packedGuid(PACKED_GUID_MIN_BUFFER_SIZE) { _packedGuid.appendPackGUID(0); }
explicit PackedGuid(uint64 guid) : _packedGuid(PACKED_GUID_MIN_BUFFER_SIZE) { _packedGuid.appendPackGUID(guid); }
explicit PackedGuid(ObjectGuid guid) : _packedGuid(PACKED_GUID_MIN_BUFFER_SIZE) { _packedGuid.appendPackGUID(guid.GetRawValue()); }
void Set(uint64 guid) { _packedGuid.wpos(0); _packedGuid.appendPackGUID(guid); }
void Set(ObjectGuid guid) { _packedGuid.wpos(0); _packedGuid.appendPackGUID(guid.GetRawValue()); }
std::size_t size() const { return _packedGuid.size(); }
private:
ByteBuffer _packedGuid;
};
class ObjectGuidGeneratorBase
{
public:
ObjectGuidGeneratorBase(ObjectGuid::LowType start = 1) : _nextGuid(start) { }
virtual void Set(ObjectGuid::LowType val) { _nextGuid = val; }
virtual ObjectGuid::LowType Generate() = 0;
ObjectGuid::LowType GetNextAfterMaxUsed() const { return _nextGuid; }
virtual ~ObjectGuidGeneratorBase() { }
protected:
static void HandleCounterOverflow(HighGuid high);
ObjectGuid::LowType _nextGuid;
};
template<HighGuid high>
class ObjectGuidGenerator : public ObjectGuidGeneratorBase
{
public:
explicit ObjectGuidGenerator(ObjectGuid::LowType start = 1) : ObjectGuidGeneratorBase(start) { }
ObjectGuid::LowType Generate() override
{
if (_nextGuid >= ObjectGuid::GetMaxCounter(high) - 1)
HandleCounterOverflow(high);
return _nextGuid++;
}
};
ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid);
ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid);
ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid);
ByteBuffer& operator>>(ByteBuffer& buf, PackedGuidReader const& guid);
inline PackedGuid ObjectGuid::WriteAsPacked() const { return PackedGuid(*this); }
namespace std
{
template<>
struct hash<ObjectGuid>
{
public:
size_t operator()(ObjectGuid const& key) const
{
return std::hash<uint64>()(key.GetRawValue());
}
};
}
#endif // ObjectGuid_h__

View File

@@ -18,7 +18,7 @@ UpdateData::UpdateData() : m_blockCount(0)
m_outOfRangeGUIDs.reserve(15);
}
void UpdateData::AddOutOfRangeGUID(uint64 guid)
void UpdateData::AddOutOfRangeGUID(ObjectGuid guid)
{
m_outOfRangeGUIDs.push_back(guid);
}
@@ -104,9 +104,9 @@ bool UpdateData::BuildPacket(WorldPacket* packet)
buf << (uint8) UPDATETYPE_OUT_OF_RANGE_OBJECTS;
buf << (uint32) m_outOfRangeGUIDs.size();
for (std::vector<uint64>::const_iterator i = m_outOfRangeGUIDs.begin(); i != m_outOfRangeGUIDs.end(); ++i)
for (ObjectGuid const guid : m_outOfRangeGUIDs)
{
buf.appendPackGUID(*i);
buf << guid.WriteAsPacked();
}
}

View File

@@ -8,6 +8,7 @@
#define __UPDATEDATA_H
#include "ByteBuffer.h"
#include "ObjectGuid.h"
class WorldPacket;
@@ -41,7 +42,7 @@ class UpdateData
public:
UpdateData();
void AddOutOfRangeGUID(uint64 guid);
void AddOutOfRangeGUID(ObjectGuid guid);
void AddUpdateBlock(const ByteBuffer& block);
void AddUpdateBlock(const UpdateData& block);
bool BuildPacket(WorldPacket* packet);
@@ -50,7 +51,7 @@ public:
protected:
uint32 m_blockCount;
std::vector<uint64> m_outOfRangeGUIDs;
GuidVector m_outOfRangeGUIDs;
ByteBuffer m_data;
void Compress(void* dst, uint32* dst_size, void* src, int src_size);