rearranged core files
--HG-- branch : trunk
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "Corpse.h"
|
||||
#include "Player.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Opcodes.h"
|
||||
#include "GossipDef.h"
|
||||
#include "World.h"
|
||||
|
||||
Corpse::Corpse(CorpseType type) : WorldObject()
|
||||
, m_type(type)
|
||||
{
|
||||
m_objectType |= TYPEMASK_CORPSE;
|
||||
m_objectTypeId = TYPEID_CORPSE;
|
||||
|
||||
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
|
||||
|
||||
m_valuesCount = CORPSE_END;
|
||||
|
||||
m_time = time(NULL);
|
||||
|
||||
lootForBody = false;
|
||||
|
||||
if (type != CORPSE_BONES)
|
||||
m_isWorldObject = true;
|
||||
}
|
||||
|
||||
Corpse::~Corpse()
|
||||
{
|
||||
}
|
||||
|
||||
void Corpse::AddToWorld()
|
||||
{
|
||||
///- Register the corpse for guid lookup
|
||||
if (!IsInWorld())
|
||||
ObjectAccessor::Instance().AddObject(this);
|
||||
|
||||
Object::AddToWorld();
|
||||
}
|
||||
|
||||
void Corpse::RemoveFromWorld()
|
||||
{
|
||||
///- Remove the corpse from the accessor
|
||||
if (IsInWorld())
|
||||
ObjectAccessor::Instance().RemoveObject(this);
|
||||
|
||||
Object::RemoveFromWorld();
|
||||
}
|
||||
|
||||
bool Corpse::Create(uint32 guidlow, Map *map)
|
||||
{
|
||||
SetMap(map);
|
||||
Object::_Create(guidlow, 0, HIGHGUID_CORPSE);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Corpse::Create(uint32 guidlow, Player *owner)
|
||||
{
|
||||
ASSERT(owner);
|
||||
|
||||
Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
|
||||
|
||||
if (!IsPositionValid())
|
||||
{
|
||||
sLog.outError("Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
|
||||
guidlow, owner->GetName(), owner->GetPositionX(), owner->GetPositionY());
|
||||
return false;
|
||||
}
|
||||
|
||||
//we need to assign owner's map for corpse
|
||||
//in other way we will get a crash in Corpse::SaveToDB()
|
||||
SetMap(owner->GetMap());
|
||||
|
||||
WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetPhaseMask());
|
||||
|
||||
SetFloatValue(OBJECT_FIELD_SCALE_X, 1);
|
||||
SetUInt64Value(CORPSE_FIELD_OWNER, owner->GetGUID());
|
||||
|
||||
m_grid = Trinity::ComputeGridPair(GetPositionX(), GetPositionY());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Corpse::SaveToDB()
|
||||
{
|
||||
// prevent DB data inconsistence problems and duplicates
|
||||
CharacterDatabase.BeginTransaction();
|
||||
DeleteFromDB();
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance,phaseMask) VALUES ("
|
||||
<< GetGUIDLow() << ", "
|
||||
<< GUID_LOPART(GetOwnerGUID()) << ", "
|
||||
<< GetPositionX() << ", "
|
||||
<< GetPositionY() << ", "
|
||||
<< GetPositionZ() << ", "
|
||||
<< GetOrientation() << ", "
|
||||
<< GetZoneId() << ", "
|
||||
<< GetMapId() << ", '";
|
||||
for (uint16 i = 0; i < m_valuesCount; ++i)
|
||||
ss << GetUInt32Value(i) << " ";
|
||||
ss << "',"
|
||||
<< uint64(m_time) <<", "
|
||||
<< uint32(GetType()) << ", "
|
||||
<< int(GetInstanceId()) << ", "
|
||||
<< uint16(GetPhaseMask()) << ")"; // prevent out of range error
|
||||
CharacterDatabase.Execute(ss.str().c_str());
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
|
||||
void Corpse::DeleteBonesFromWorld()
|
||||
{
|
||||
assert(GetType() == CORPSE_BONES);
|
||||
Corpse* corpse = ObjectAccessor::GetCorpse(*this, GetGUID());
|
||||
|
||||
if (!corpse)
|
||||
{
|
||||
sLog.outError("Bones %u not found in world.", GetGUIDLow());
|
||||
return;
|
||||
}
|
||||
|
||||
AddObjectToRemoveList();
|
||||
}
|
||||
|
||||
void Corpse::DeleteFromDB()
|
||||
{
|
||||
if (GetType() == CORPSE_BONES)
|
||||
// only specific bones
|
||||
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%d'", GetGUIDLow());
|
||||
else
|
||||
// all corpses (not bones)
|
||||
CharacterDatabase.PExecute("DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'", GUID_LOPART(GetOwnerGUID()));
|
||||
}
|
||||
|
||||
/*
|
||||
bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId)
|
||||
{
|
||||
bool external = (result != NULL);
|
||||
if (!external)
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sLog.outError("Corpse (GUID: %u) not found in table `corpse`, can't load. ",guid);
|
||||
return false;
|
||||
}
|
||||
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
if (!LoadFromDB(guid, fields))
|
||||
{
|
||||
if (!external)
|
||||
delete result;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!external)
|
||||
delete result;
|
||||
|
||||
return true;
|
||||
}*/
|
||||
|
||||
bool Corpse::LoadFromDB(uint32 guid, Field *fields)
|
||||
{
|
||||
float positionX = fields[0].GetFloat();
|
||||
float positionY = fields[1].GetFloat();
|
||||
float positionZ = fields[2].GetFloat();
|
||||
float ort = fields[3].GetFloat();
|
||||
uint32 mapid = fields[4].GetUInt32();
|
||||
|
||||
Object::_Create(guid, 0, HIGHGUID_CORPSE);
|
||||
|
||||
if (!LoadValues(fields[5].GetString()))
|
||||
{
|
||||
sLog.outError("Corpse #%d have broken data in `data` field. Can't be loaded.",guid);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_time = time_t(fields[6].GetUInt64());
|
||||
m_type = CorpseType(fields[7].GetUInt32());
|
||||
|
||||
if (m_type >= MAX_CORPSE_TYPE)
|
||||
{
|
||||
sLog.outError("Corpse (guidlow %d, owner %d) have wrong corpse type, not load.",GetGUIDLow(),GUID_LOPART(GetOwnerGUID()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_type != CORPSE_BONES)
|
||||
m_isWorldObject = true;
|
||||
|
||||
uint32 instanceid = fields[8].GetUInt32();
|
||||
|
||||
uint32 phaseMask = fields[9].GetUInt32();
|
||||
|
||||
// overwrite possible wrong/corrupted guid
|
||||
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE));
|
||||
|
||||
// place
|
||||
SetLocationInstanceId(instanceid);
|
||||
SetLocationMapId(mapid);
|
||||
SetPhaseMask(phaseMask, false);
|
||||
Relocate(positionX, positionY, positionZ, ort);
|
||||
|
||||
if (!IsPositionValid())
|
||||
{
|
||||
sLog.outError("Corpse (guidlow %d, owner %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
|
||||
GetGUIDLow(), GUID_LOPART(GetOwnerGUID()), GetPositionX(), GetPositionY());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_grid = Trinity::ComputeGridPair(GetPositionX(), GetPositionY());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Corpse::isVisibleForInState(Player const* u, bool inVisibleList) const
|
||||
{
|
||||
return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u->m_seer, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITYCORE_CORPSE_H
|
||||
#define TRINITYCORE_CORPSE_H
|
||||
|
||||
#include "Object.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "GridDefines.h"
|
||||
#include "LootMgr.h"
|
||||
|
||||
enum CorpseType
|
||||
{
|
||||
CORPSE_BONES = 0,
|
||||
CORPSE_RESURRECTABLE_PVE = 1,
|
||||
CORPSE_RESURRECTABLE_PVP = 2
|
||||
};
|
||||
#define MAX_CORPSE_TYPE 3
|
||||
|
||||
// Value equal client resurrection dialog show radius.
|
||||
#define CORPSE_RECLAIM_RADIUS 39
|
||||
|
||||
enum CorpseFlags
|
||||
{
|
||||
CORPSE_FLAG_NONE = 0x00,
|
||||
CORPSE_FLAG_BONES = 0x01,
|
||||
CORPSE_FLAG_UNK1 = 0x02,
|
||||
CORPSE_FLAG_UNK2 = 0x04,
|
||||
CORPSE_FLAG_HIDE_HELM = 0x08,
|
||||
CORPSE_FLAG_HIDE_CLOAK = 0x10,
|
||||
CORPSE_FLAG_LOOTABLE = 0x20
|
||||
};
|
||||
|
||||
class Corpse : public WorldObject, public GridObject<Corpse>
|
||||
{
|
||||
public:
|
||||
explicit Corpse(CorpseType type = CORPSE_BONES);
|
||||
~Corpse();
|
||||
|
||||
void AddToWorld();
|
||||
void RemoveFromWorld();
|
||||
|
||||
bool Create(uint32 guidlow, Map *map);
|
||||
bool Create(uint32 guidlow, Player *owner);
|
||||
|
||||
void SaveToDB();
|
||||
//bool LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId);
|
||||
bool LoadFromDB(uint32 guid, Field *fields);
|
||||
|
||||
void DeleteBonesFromWorld();
|
||||
void DeleteFromDB();
|
||||
|
||||
uint64 const& GetOwnerGUID() const { return GetUInt64Value(CORPSE_FIELD_OWNER); }
|
||||
|
||||
time_t const& GetGhostTime() const { return m_time; }
|
||||
void ResetGhostTime() { m_time = time(NULL); }
|
||||
CorpseType GetType() const { return m_type; }
|
||||
|
||||
GridPair const& GetGrid() const { return m_grid; }
|
||||
void SetGrid(GridPair const& grid) { m_grid = grid; }
|
||||
|
||||
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
|
||||
|
||||
Loot loot; // remove insignia ONLY at BG
|
||||
Player* lootRecipient;
|
||||
bool lootForBody;
|
||||
|
||||
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
|
||||
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
|
||||
void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); }
|
||||
void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); }
|
||||
void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
|
||||
|
||||
private:
|
||||
CorpseType m_type;
|
||||
time_t m_time;
|
||||
GridPair m_grid; // gride for corpse position for fast search
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "Opcodes.h"
|
||||
#include "World.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
||||
DynamicObject::DynamicObject() : WorldObject()
|
||||
{
|
||||
m_objectType |= TYPEMASK_DYNAMICOBJECT;
|
||||
m_objectTypeId = TYPEID_DYNAMICOBJECT;
|
||||
|
||||
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
|
||||
|
||||
m_valuesCount = DYNAMICOBJECT_END;
|
||||
|
||||
m_aura = 0;
|
||||
m_duration = 0;
|
||||
}
|
||||
|
||||
void DynamicObject::AddToWorld()
|
||||
{
|
||||
///- Register the dynamicObject for guid lookup
|
||||
if (!IsInWorld())
|
||||
{
|
||||
ObjectAccessor::Instance().AddObject(this);
|
||||
WorldObject::AddToWorld();
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicObject::RemoveFromWorld()
|
||||
{
|
||||
///- Remove the dynamicObject from the accessor
|
||||
if (IsInWorld())
|
||||
{
|
||||
if (m_isWorldObject)
|
||||
{
|
||||
if (Unit *caster = GetCaster())
|
||||
{
|
||||
if (caster->GetTypeId() == TYPEID_PLAYER)
|
||||
caster->ToPlayer()->SetViewpoint(this, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outCrash("DynamicObject::RemoveFromWorld cannot find viewpoint owner");
|
||||
}
|
||||
}
|
||||
WorldObject::RemoveFromWorld();
|
||||
ObjectAccessor::Instance().RemoveObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, const Position &pos, float radius, bool active)
|
||||
{
|
||||
SetMap(caster->GetMap());
|
||||
Relocate(pos);
|
||||
if (!IsPositionValid())
|
||||
{
|
||||
sLog.outError("DynamicObject (spell %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,GetPositionX(),GetPositionY());
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetPhaseMask());
|
||||
|
||||
SetEntry(spellId);
|
||||
SetFloatValue(OBJECT_FIELD_SCALE_X, 1);
|
||||
SetUInt64Value(DYNAMICOBJECT_CASTER, caster->GetGUID());
|
||||
|
||||
// The lower word of DYNAMICOBJECT_BYTES must be 0x0001. This value means that the visual radius will be overriden
|
||||
// by client for most of the "ground patch" visual effect spells and a few "skyfall" ones like Hurricane.
|
||||
// If any other value is used, the client will _always_ use the radius provided in DYNAMICOBJECT_RADIUS, but
|
||||
// precompensation is necessary (eg radius *= 2) for many spells. Anyway, blizz sends 0x0001 for all the spells
|
||||
// I saw sniffed...
|
||||
SetUInt32Value(DYNAMICOBJECT_BYTES, 0x00000001);
|
||||
SetUInt32Value(DYNAMICOBJECT_SPELLID, spellId);
|
||||
SetFloatValue(DYNAMICOBJECT_RADIUS, radius);
|
||||
SetUInt32Value(DYNAMICOBJECT_CASTTIME, getMSTime());
|
||||
|
||||
m_isWorldObject = active;
|
||||
return true;
|
||||
}
|
||||
|
||||
Unit* DynamicObject::GetCaster() const
|
||||
{
|
||||
// can be not found in some cases
|
||||
return ObjectAccessor::GetUnit(*this, GetCasterGUID());
|
||||
}
|
||||
|
||||
void DynamicObject::Update(uint32 p_time)
|
||||
{
|
||||
// caster can be not in world at time dynamic object update, but dynamic object not yet deleted in Unit destructor
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster)
|
||||
{
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
bool expired = false;
|
||||
|
||||
if (m_aura)
|
||||
{
|
||||
if (!m_aura->IsRemoved())
|
||||
m_aura->UpdateOwner(p_time, this);
|
||||
|
||||
// m_aura may be set to null in Unit::RemoveGameObject call
|
||||
if (m_aura && (m_aura->IsRemoved() || m_aura->IsExpired()))
|
||||
expired = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetDuration() > int32(p_time))
|
||||
m_duration -= p_time;
|
||||
else
|
||||
expired = true;
|
||||
}
|
||||
|
||||
if (expired)
|
||||
{
|
||||
caster->RemoveDynObjectWithGUID(GetGUID());
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicObject::Delete()
|
||||
{
|
||||
if (m_aura)
|
||||
{
|
||||
// dynObj may be removed in Aura::Remove - we cannot delete there
|
||||
// so recheck aura here
|
||||
if (!m_aura->IsRemoved())
|
||||
m_aura->_Remove(AURA_REMOVE_BY_DEFAULT);
|
||||
delete m_aura;
|
||||
m_aura = NULL;
|
||||
}
|
||||
SendObjectDeSpawnAnim(GetGUID());
|
||||
RemoveFromWorld();
|
||||
AddObjectToRemoveList();
|
||||
}
|
||||
|
||||
int32 DynamicObject::GetDuration() const
|
||||
{
|
||||
if (!m_aura)
|
||||
return m_duration;
|
||||
else
|
||||
return m_aura->GetDuration();
|
||||
}
|
||||
|
||||
void DynamicObject::SetDuration(int32 newDuration)
|
||||
{
|
||||
if (!m_aura)
|
||||
m_duration = newDuration;
|
||||
else
|
||||
m_aura->SetDuration(newDuration);
|
||||
}
|
||||
|
||||
void DynamicObject::Delay(int32 delaytime)
|
||||
{
|
||||
SetDuration(GetDuration() - delaytime);
|
||||
}
|
||||
|
||||
bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const
|
||||
{
|
||||
return IsInWorld() && u->IsInWorld()
|
||||
&& (IsWithinDistInMap(u->m_seer,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false));
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITYCORE_DYNAMICOBJECT_H
|
||||
#define TRINITYCORE_DYNAMICOBJECT_H
|
||||
|
||||
#include "Object.h"
|
||||
|
||||
class Unit;
|
||||
class Aura;
|
||||
struct SpellEntry;
|
||||
|
||||
class DynamicObject : public WorldObject, public GridObject<DynamicObject>
|
||||
{
|
||||
public:
|
||||
explicit DynamicObject();
|
||||
|
||||
void AddToWorld();
|
||||
void RemoveFromWorld();
|
||||
|
||||
bool Create(uint32 guidlow, Unit *caster, uint32 spellId, const Position &pos, float radius, bool active);
|
||||
void Update(uint32 p_time);
|
||||
void Delete();
|
||||
void SetDuration(int32 newDuration);
|
||||
int32 GetDuration() const;
|
||||
void SetAura(Aura * aura) {assert (!m_aura && aura); m_aura = aura;}
|
||||
void Delay(int32 delaytime);
|
||||
uint32 GetSpellId() const { return GetUInt32Value(DYNAMICOBJECT_SPELLID); }
|
||||
uint64 GetCasterGUID() const { return GetUInt64Value(DYNAMICOBJECT_CASTER); }
|
||||
float GetRadius() const { return GetFloatValue(DYNAMICOBJECT_RADIUS); }
|
||||
Unit* GetCaster() const;
|
||||
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
|
||||
|
||||
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
|
||||
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
|
||||
void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); }
|
||||
void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); }
|
||||
void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
|
||||
|
||||
protected:
|
||||
int32 m_duration; // for non-aura dynobjects
|
||||
Aura * m_aura;
|
||||
};
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,743 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _OBJECT_H
|
||||
#define _OBJECT_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "UpdateFields.h"
|
||||
#include "UpdateData.h"
|
||||
#include "GameSystem/GridReference.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "GridDefines.h"
|
||||
#include "Map.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#define CONTACT_DISTANCE 0.5f
|
||||
#define INTERACTION_DISTANCE 5.0f
|
||||
#define ATTACK_DISTANCE 5.0f
|
||||
#define MAX_VISIBILITY_DISTANCE 333.0f // max distance for visible object show, limited in 333 yards
|
||||
#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
|
||||
#define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards
|
||||
#define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards
|
||||
|
||||
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
|
||||
#define DEFAULT_COMBAT_REACH 1.5f
|
||||
#define MIN_MELEE_REACH 2.0f
|
||||
#define NOMINAL_MELEE_RANGE 5.0f
|
||||
#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
|
||||
|
||||
enum TypeMask
|
||||
{
|
||||
TYPEMASK_OBJECT = 0x0001,
|
||||
TYPEMASK_ITEM = 0x0002,
|
||||
TYPEMASK_CONTAINER = 0x0006, // TYPEMASK_ITEM | 0x0004
|
||||
TYPEMASK_UNIT = 0x0008, //creature or player
|
||||
TYPEMASK_PLAYER = 0x0010,
|
||||
TYPEMASK_GAMEOBJECT = 0x0020,
|
||||
TYPEMASK_DYNAMICOBJECT = 0x0040,
|
||||
TYPEMASK_CORPSE = 0x0080,
|
||||
TYPEMASK_SEER = 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
|
||||
TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN = 2, // despawns after a specified time OR when the creature dies
|
||||
TEMPSUMMON_TIMED_DESPAWN = 3, // despawns after a specified time
|
||||
TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT = 4, // despawns after a specified time after the creature is out of combat
|
||||
TEMPSUMMON_CORPSE_DESPAWN = 5, // despawns instantly after death
|
||||
TEMPSUMMON_CORPSE_TIMED_DESPAWN = 6, // despawns after a specified time after death
|
||||
TEMPSUMMON_DEAD_DESPAWN = 7, // despawns when the creature disappears
|
||||
TEMPSUMMON_MANUAL_DESPAWN = 8 // despawns when UnSummon() is called
|
||||
};
|
||||
|
||||
enum PhaseMasks
|
||||
{
|
||||
PHASEMASK_NORMAL = 0x00000001,
|
||||
PHASEMASK_ANYWHERE = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
enum NotifyFlags
|
||||
{
|
||||
NOTIFY_NONE = 0x00,
|
||||
NOTIFY_AI_RELOCATION = 0x01,
|
||||
NOTIFY_VISIBILITY_CHANGED = 0x02,
|
||||
NOTIFY_ALL = 0xFF
|
||||
};
|
||||
|
||||
class WorldPacket;
|
||||
class UpdateData;
|
||||
class ByteBuffer;
|
||||
class WorldSession;
|
||||
class Creature;
|
||||
class Player;
|
||||
class UpdateMask;
|
||||
class InstanceData;
|
||||
class GameObject;
|
||||
class TempSummon;
|
||||
class Vehicle;
|
||||
class CreatureAI;
|
||||
class ZoneScript;
|
||||
class Unit;
|
||||
|
||||
typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType;
|
||||
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
virtual ~Object ();
|
||||
|
||||
const bool IsInWorld() const { return m_inWorld; }
|
||||
virtual void AddToWorld()
|
||||
{
|
||||
if (m_inWorld)
|
||||
return;
|
||||
|
||||
assert(m_uint32Values);
|
||||
|
||||
m_inWorld = true;
|
||||
|
||||
// synchronize values mirror with values array (changes will send in updatecreate opcode any way
|
||||
ClearUpdateMask(true);
|
||||
}
|
||||
virtual void RemoveFromWorld()
|
||||
{
|
||||
if (!m_inWorld)
|
||||
return;
|
||||
|
||||
m_inWorld = false;
|
||||
|
||||
// if we remove from world then sending changes not required
|
||||
ClearUpdateMask(true);
|
||||
}
|
||||
|
||||
const uint64& GetGUID() const { return GetUInt64Value(0); }
|
||||
uint32 GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(0)); }
|
||||
uint32 GetGUIDMid() const { return GUID_ENPART(GetUInt64Value(0)); }
|
||||
uint32 GetGUIDHigh() const { return GUID_HIPART(GetUInt64Value(0)); }
|
||||
const ByteBuffer& GetPackGUID() const { return m_PackGUID; }
|
||||
uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
|
||||
void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); }
|
||||
|
||||
TypeID GetTypeId() const { return m_objectTypeId; }
|
||||
bool isType(uint16 mask) const { return (mask & m_objectType); }
|
||||
|
||||
virtual void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const;
|
||||
void SendUpdateToPlayer(Player* player);
|
||||
|
||||
void BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) const;
|
||||
void BuildOutOfRangeUpdateBlock(UpdateData *data) const;
|
||||
void BuildMovementUpdateBlock(UpdateData * data, uint32 flags = 0) const;
|
||||
|
||||
virtual void DestroyForPlayer(Player *target, bool anim = false) const;
|
||||
|
||||
const int32& GetInt32Value(uint16 index) const
|
||||
{
|
||||
ASSERT(index < m_valuesCount || PrintIndexError(index , false));
|
||||
return m_int32Values[ index ];
|
||||
}
|
||||
|
||||
const uint32& GetUInt32Value(uint16 index) const
|
||||
{
|
||||
ASSERT(index < m_valuesCount || PrintIndexError(index , false));
|
||||
return m_uint32Values[ index ];
|
||||
}
|
||||
|
||||
const uint64& GetUInt64Value(uint16 index) const
|
||||
{
|
||||
ASSERT(index + 1 < m_valuesCount || PrintIndexError(index , false));
|
||||
return *((uint64*)&(m_uint32Values[ index ]));
|
||||
}
|
||||
|
||||
const float& GetFloatValue(uint16 index) const
|
||||
{
|
||||
ASSERT(index < m_valuesCount || PrintIndexError(index , false));
|
||||
return m_floatValues[ index ];
|
||||
}
|
||||
|
||||
uint8 GetByteValue(uint16 index, uint8 offset) const
|
||||
{
|
||||
ASSERT(index < m_valuesCount || PrintIndexError(index , false));
|
||||
ASSERT(offset < 4);
|
||||
return *(((uint8*)&m_uint32Values[ index ])+offset);
|
||||
}
|
||||
|
||||
uint16 GetUInt16Value(uint16 index, uint8 offset) const
|
||||
{
|
||||
ASSERT(index < m_valuesCount || PrintIndexError(index , false));
|
||||
ASSERT(offset < 2);
|
||||
return *(((uint16*)&m_uint32Values[ index ])+offset);
|
||||
}
|
||||
|
||||
void SetInt32Value(uint16 index, int32 value);
|
||||
void SetUInt32Value(uint16 index, uint32 value);
|
||||
void UpdateUInt32Value(uint16 index, uint32 value);
|
||||
void SetUInt64Value(uint16 index, const uint64 &value);
|
||||
void SetFloatValue(uint16 index, float value);
|
||||
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 SetStatFloatValue(uint16 index, float value);
|
||||
void SetStatInt32Value(uint16 index, int32 value);
|
||||
|
||||
bool AddUInt64Value(uint16 index, const uint64 &value);
|
||||
bool RemoveUInt64Value(uint16 index, const uint64 &value);
|
||||
|
||||
void ApplyModUInt32Value(uint16 index, int32 val, bool apply);
|
||||
void ApplyModInt32Value(uint16 index, int32 val, bool apply);
|
||||
void ApplyModUInt64Value(uint16 index, int32 val, bool apply);
|
||||
void ApplyModPositiveFloatValue(uint16 index, float val, bool apply);
|
||||
void ApplyModSignedFloatValue(uint16 index, float val, bool apply);
|
||||
|
||||
void ApplyPercentModFloatValue(uint16 index, float val, bool apply)
|
||||
{
|
||||
val = val != -100.0f ? val : -99.9f ;
|
||||
SetFloatValue(index, GetFloatValue(index) * (apply?(100.0f+val)/100.0f : 100.0f / (100.0f+val)));
|
||||
}
|
||||
|
||||
void SetFlag(uint16 index, uint32 newFlag);
|
||||
void RemoveFlag(uint16 index, uint32 oldFlag);
|
||||
|
||||
void ToggleFlag(uint16 index, uint32 flag)
|
||||
{
|
||||
if (HasFlag(index, flag))
|
||||
RemoveFlag(index, flag);
|
||||
else
|
||||
SetFlag(index, flag);
|
||||
}
|
||||
|
||||
bool HasFlag(uint16 index, uint32 flag) const
|
||||
{
|
||||
if (index >= m_valuesCount && !PrintIndexError(index , false)) return false;
|
||||
return (m_uint32Values[ index ] & flag) != 0;
|
||||
}
|
||||
|
||||
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag);
|
||||
void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag);
|
||||
|
||||
void ToggleFlag(uint16 index, uint8 offset, uint8 flag)
|
||||
{
|
||||
if (HasByteFlag(index, offset, flag))
|
||||
RemoveByteFlag(index, offset, flag);
|
||||
else
|
||||
SetByteFlag(index, offset, flag);
|
||||
}
|
||||
|
||||
bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
|
||||
{
|
||||
ASSERT(index < m_valuesCount || PrintIndexError(index , false));
|
||||
ASSERT(offset < 4);
|
||||
return (((uint8*)&m_uint32Values[index])[offset] & flag) != 0;
|
||||
}
|
||||
|
||||
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
|
||||
{
|
||||
if (apply) SetFlag(index,flag); else RemoveFlag(index,flag);
|
||||
}
|
||||
|
||||
void SetFlag64(uint16 index, uint64 newFlag)
|
||||
{
|
||||
uint64 oldval = GetUInt64Value(index);
|
||||
uint64 newval = oldval | newFlag;
|
||||
SetUInt64Value(index,newval);
|
||||
}
|
||||
|
||||
void RemoveFlag64(uint16 index, uint64 oldFlag)
|
||||
{
|
||||
uint64 oldval = GetUInt64Value(index);
|
||||
uint64 newval = oldval & ~oldFlag;
|
||||
SetUInt64Value(index,newval);
|
||||
}
|
||||
|
||||
void ToggleFlag64(uint16 index, uint64 flag)
|
||||
{
|
||||
if (HasFlag64(index, flag))
|
||||
RemoveFlag64(index, flag);
|
||||
else
|
||||
SetFlag64(index, flag);
|
||||
}
|
||||
|
||||
bool HasFlag64(uint16 index, uint64 flag) const
|
||||
{
|
||||
ASSERT(index < m_valuesCount || PrintIndexError(index , false));
|
||||
return (GetUInt64Value(index) & flag) != 0;
|
||||
}
|
||||
|
||||
void ApplyModFlag64(uint16 index, uint64 flag, bool apply)
|
||||
{
|
||||
if (apply) SetFlag64(index,flag); else RemoveFlag64(index,flag);
|
||||
}
|
||||
|
||||
void ClearUpdateMask(bool remove);
|
||||
|
||||
bool LoadValues(const char* data);
|
||||
|
||||
uint16 GetValuesCount() const { return m_valuesCount; }
|
||||
|
||||
virtual bool hasQuest(uint32 /* quest_id */) const { return false; }
|
||||
virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; }
|
||||
virtual void BuildUpdate(UpdateDataMapType&) {}
|
||||
void BuildFieldsUpdate(Player *, UpdateDataMapType &) const;
|
||||
|
||||
// FG: some hacky helpers
|
||||
void ForceValuesUpdateAtIndex(uint32);
|
||||
|
||||
Player* ToPlayer(){ if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player*>(this); else return NULL; }
|
||||
const Player* ToPlayer() const { if (GetTypeId() == TYPEID_PLAYER) return (const Player*)((Player*)this); else return NULL; }
|
||||
Creature* ToCreature(){ if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature*>(this); else return NULL; }
|
||||
const Creature* ToCreature() const {if (GetTypeId() == TYPEID_UNIT) return (const Creature*)((Creature*)this); else return NULL; }
|
||||
|
||||
protected:
|
||||
|
||||
Object ();
|
||||
|
||||
void _InitValues();
|
||||
void _Create (uint32 guidlow, uint32 entry, HighGuid guidhigh);
|
||||
|
||||
virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;
|
||||
|
||||
virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
|
||||
void _BuildMovementUpdate(ByteBuffer * data, uint16 flags) const;
|
||||
void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target) const;
|
||||
|
||||
uint16 m_objectType;
|
||||
|
||||
TypeID m_objectTypeId;
|
||||
uint16 m_updateFlag;
|
||||
|
||||
union
|
||||
{
|
||||
int32 *m_int32Values;
|
||||
uint32 *m_uint32Values;
|
||||
float *m_floatValues;
|
||||
};
|
||||
|
||||
uint32 *m_uint32Values_mirror;
|
||||
|
||||
uint16 m_valuesCount;
|
||||
|
||||
bool m_objectUpdated;
|
||||
|
||||
private:
|
||||
bool m_inWorld;
|
||||
|
||||
ByteBuffer m_PackGUID;
|
||||
|
||||
// for output helpfull error messages from asserts
|
||||
bool PrintIndexError(uint32 index, bool set) const;
|
||||
Object(const Object&); // prevent generation copy constructor
|
||||
Object& operator=(Object const&); // prevent generation assigment operator
|
||||
};
|
||||
|
||||
struct Position
|
||||
{
|
||||
float m_positionX;
|
||||
float m_positionY;
|
||||
float m_positionZ;
|
||||
float m_orientation;
|
||||
|
||||
void Relocate(float x, float y)
|
||||
{ m_positionX = x; m_positionY = y;}
|
||||
void Relocate(float x, float y, float z)
|
||||
{ m_positionX = x; m_positionY = y; m_positionZ = z; }
|
||||
void Relocate(float x, float y, float z, float orientation)
|
||||
{ m_positionX = x; m_positionY = y; m_positionZ = z; m_orientation = orientation; }
|
||||
void Relocate(const Position &pos)
|
||||
{ m_positionX = pos.m_positionX; m_positionY = pos.m_positionY; m_positionZ = pos.m_positionZ; m_orientation = pos.m_orientation; }
|
||||
void Relocate(const Position *pos)
|
||||
{ m_positionX = pos->m_positionX; m_positionY = pos->m_positionY; m_positionZ = pos->m_positionZ; m_orientation = pos->m_orientation; }
|
||||
void SetOrientation(float orientation)
|
||||
{ m_orientation = orientation; }
|
||||
|
||||
float GetPositionX() const { return m_positionX; }
|
||||
float GetPositionY() const { return m_positionY; }
|
||||
float GetPositionZ() const { return m_positionZ; }
|
||||
float GetOrientation() const { return m_orientation; }
|
||||
|
||||
void GetPosition(float &x, float &y) const
|
||||
{ x = m_positionX; y = m_positionY; }
|
||||
void GetPosition(float &x, float &y, float &z) const
|
||||
{ x = m_positionX; y = m_positionY; z = m_positionZ; }
|
||||
void GetPosition(float &x, float &y, float &z, float &o) const
|
||||
{ x = m_positionX; y = m_positionY; z = m_positionZ; o = m_orientation; }
|
||||
void GetPosition(Position *pos) const
|
||||
{
|
||||
if (pos)
|
||||
pos->Relocate(m_positionX, m_positionY, m_positionZ, m_orientation);
|
||||
}
|
||||
|
||||
bool IsPositionValid() const;
|
||||
|
||||
float GetExactDist2dSq(float x, float y) const
|
||||
{ float dx = m_positionX - x; float dy = m_positionY - y; return dx*dx + dy*dy; }
|
||||
float GetExactDist2d(const float x, const float y) const
|
||||
{ return sqrt(GetExactDist2dSq(x, y)); }
|
||||
float GetExactDist2dSq(const Position *pos) const
|
||||
{ float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; return dx*dx + dy*dy; }
|
||||
float GetExactDist2d(const Position *pos) const
|
||||
{ return sqrt(GetExactDist2dSq(pos)); }
|
||||
float GetExactDistSq(float x, float y, float z) const
|
||||
{ float dz = m_positionZ - z; return GetExactDist2dSq(x, y) + dz*dz; }
|
||||
float GetExactDist(float x, float y, float z) const
|
||||
{ return sqrt(GetExactDistSq(x, y, z)); }
|
||||
float GetExactDistSq(const Position *pos) const
|
||||
{ float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; float dz = m_positionZ - pos->m_positionZ; return dx*dx + dy*dy + dz*dz; }
|
||||
float GetExactDist(const Position *pos) const
|
||||
{ return sqrt(GetExactDistSq(pos)); }
|
||||
|
||||
float GetAngle(const Position *pos) const;
|
||||
float GetAngle(float x, float y) const;
|
||||
float GetRelativeAngle(const Position *pos) const
|
||||
{ return GetAngle(pos) - m_orientation; }
|
||||
float GetRelativeAngle(float x, float y) const { return GetAngle(x, y) - m_orientation; }
|
||||
void GetSinCos(float x, float y, float &vsin, float &vcos) const;
|
||||
|
||||
bool IsInDist2d(float x, float y, float dist) const
|
||||
{ return GetExactDist2dSq(x, y) < dist * dist; }
|
||||
bool IsInDist2d(const Position *pos, float dist) const
|
||||
{ return GetExactDist2dSq(pos) < dist * dist; }
|
||||
bool IsInDist(float x, float y, float z, float dist) const
|
||||
{ return GetExactDistSq(x, y, z) < dist * dist; }
|
||||
bool IsInDist(const Position *pos, float dist) const
|
||||
{ return GetExactDistSq(pos) < dist * dist; }
|
||||
bool HasInArc(float arcangle, const Position *pos) const;
|
||||
bool HasInLine(const Unit *target, float distance, float width) const;
|
||||
};
|
||||
|
||||
#define MAPID_INVALID 0xFFFFFFFF
|
||||
|
||||
class WorldLocation : public Position
|
||||
{
|
||||
public:
|
||||
explicit WorldLocation(uint32 _mapid = MAPID_INVALID, float _x = 0, float _y = 0, float _z = 0, float _o = 0)
|
||||
: m_mapId(_mapid) { Relocate(_x, _y, _z, _o); }
|
||||
WorldLocation(const WorldLocation &loc) { WorldRelocate(loc); }
|
||||
|
||||
void WorldRelocate(const WorldLocation &loc)
|
||||
{ m_mapId = loc.GetMapId(); Relocate(loc); }
|
||||
uint32 GetMapId() const { return m_mapId; }
|
||||
|
||||
uint32 m_mapId;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class GridObject
|
||||
{
|
||||
public:
|
||||
GridReference<T> &GetGridRef() { return m_gridRef; }
|
||||
protected:
|
||||
GridReference<T> m_gridRef;
|
||||
};
|
||||
|
||||
class WorldObject : public Object, public WorldLocation
|
||||
{
|
||||
public:
|
||||
virtual ~WorldObject();
|
||||
|
||||
virtual void Update (uint32 /*time_diff*/) { }
|
||||
|
||||
void _Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask);
|
||||
|
||||
void GetNearPoint2D(float &x, float &y, float distance, float absAngle) const;
|
||||
void GetNearPoint(WorldObject const* searcher, float &x, float &y, float &z, float searcher_size, float distance2d,float absAngle) const;
|
||||
void GetClosePoint(float &x, float &y, float &z, float size, float distance2d = 0, float angle = 0) const
|
||||
{
|
||||
// angle calculated from current orientation
|
||||
GetNearPoint(NULL,x,y,z,size,distance2d,GetOrientation() + angle);
|
||||
}
|
||||
void MovePosition(Position &pos, float dist, float angle);
|
||||
void GetNearPosition(Position &pos, float dist, float angle)
|
||||
{
|
||||
GetPosition(&pos);
|
||||
MovePosition(pos, dist, angle);
|
||||
}
|
||||
void GetRandomNearPosition(Position &pos, float radius)
|
||||
{
|
||||
GetPosition(&pos);
|
||||
MovePosition(pos, radius * rand_norm(), rand_norm() * 2 * M_PI);
|
||||
}
|
||||
|
||||
void GetContactPoint(const WorldObject* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const
|
||||
{
|
||||
// angle to face `obj` to `this` using distance includes size of `obj`
|
||||
GetNearPoint(obj,x,y,z,obj->GetObjectSize(),distance2d,GetAngle(obj));
|
||||
}
|
||||
|
||||
float GetObjectSize() const
|
||||
{
|
||||
return (m_valuesCount > UNIT_FIELD_COMBATREACH) ? m_floatValues[UNIT_FIELD_COMBATREACH] : DEFAULT_WORLD_OBJECT_SIZE;
|
||||
}
|
||||
void UpdateGroundPositionZ(float x, float y, float &z) const;
|
||||
|
||||
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const;
|
||||
void GetRandomPoint(const Position &srcPos, float distance, Position &pos) const
|
||||
{
|
||||
float x, y, z;
|
||||
GetRandomPoint(srcPos, distance, x, y, z);
|
||||
pos.Relocate(x, y, z, GetOrientation());
|
||||
}
|
||||
|
||||
uint32 GetInstanceId() const { return m_InstanceId; }
|
||||
|
||||
virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
|
||||
uint32 GetPhaseMask() const { return m_phaseMask; }
|
||||
bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); }
|
||||
bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask); }
|
||||
|
||||
uint32 GetZoneId() const;
|
||||
uint32 GetAreaId() const;
|
||||
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const;
|
||||
|
||||
InstanceData* GetInstanceData();
|
||||
|
||||
const char* GetName() const { return m_name.c_str(); }
|
||||
void SetName(const std::string& newname) { m_name=newname; }
|
||||
|
||||
virtual const char* GetNameForLocaleIdx(int32 /*locale_idx*/) const { return GetName(); }
|
||||
|
||||
float GetDistance(const WorldObject *obj) const
|
||||
{
|
||||
float d = GetExactDist(obj) - GetObjectSize() - obj->GetObjectSize();
|
||||
return d > 0.0f ? d : 0.0f;
|
||||
}
|
||||
float GetDistance(const Position &pos) const
|
||||
{
|
||||
float d = GetExactDist(&pos) - GetObjectSize();
|
||||
return d > 0.0f ? d : 0.0f;
|
||||
}
|
||||
float GetDistance(float x, float y, float z) const
|
||||
{
|
||||
float d = GetExactDist(x, y, z) - GetObjectSize();
|
||||
return d > 0.0f ? d : 0.0f;
|
||||
}
|
||||
float GetDistance2d(const WorldObject* obj) const
|
||||
{
|
||||
float d = GetExactDist2d(obj) - GetObjectSize() - obj->GetObjectSize();
|
||||
return d > 0.0f ? d : 0.0f;
|
||||
}
|
||||
float GetDistance2d(float x, float y) const
|
||||
{
|
||||
float d = GetExactDist2d(x, y) - GetObjectSize();
|
||||
return d > 0.0f ? d : 0.0f;
|
||||
}
|
||||
float GetDistanceZ(const WorldObject* obj) const;
|
||||
|
||||
bool IsInMap(const WorldObject* obj) const
|
||||
{
|
||||
if (obj)
|
||||
return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap()) && InSamePhase(obj);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
bool IsWithinDist3d(float x, float y, float z, float dist) const
|
||||
{ return IsInDist(x, y, z, dist + GetObjectSize()); }
|
||||
bool IsWithinDist3d(const Position *pos, float dist) const
|
||||
{ return IsInDist(pos, dist + GetObjectSize()); }
|
||||
bool IsWithinDist2d(float x, float y, float dist) const
|
||||
{ return IsInDist2d(x, y, dist + GetObjectSize()); }
|
||||
bool IsWithinDist2d(const Position *pos, float dist) const
|
||||
{ return IsInDist2d(pos, dist + GetObjectSize()); }
|
||||
bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const;
|
||||
// use only if you will sure about placing both object at same map
|
||||
bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const
|
||||
{
|
||||
return obj && _IsWithinDist(obj,dist2compare,is3D);
|
||||
}
|
||||
bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const
|
||||
{
|
||||
return obj && IsInMap(obj) && _IsWithinDist(obj,dist2compare,is3D);
|
||||
}
|
||||
bool IsWithinLOS(float x, float y, float z) const;
|
||||
bool IsWithinLOSInMap(const WorldObject* obj) const;
|
||||
bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const;
|
||||
bool IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D = true) const;
|
||||
bool IsInRange2d(float x, float y, float minRange, float maxRange) const;
|
||||
bool IsInRange3d(float x, float y, float z, float minRange, float maxRange) const;
|
||||
bool isInFront(WorldObject const* target,float distance, float arc = M_PI) const;
|
||||
bool isInBack(WorldObject const* target, float distance, float arc = M_PI) const;
|
||||
|
||||
bool IsInBetween(const WorldObject *obj1, const WorldObject *obj2, float size = 0) const;
|
||||
|
||||
virtual void CleanupsBeforeDelete(bool finalCleanup = true); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
|
||||
|
||||
virtual void SendMessageToSet(WorldPacket *data, bool self);
|
||||
virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self);
|
||||
virtual void SendMessageToSet(WorldPacket *data, Player const* skipped_rcvr);
|
||||
|
||||
void MonsterSay(const char* text, uint32 language, uint64 TargetGuid);
|
||||
void MonsterYell(const char* text, uint32 language, uint64 TargetGuid);
|
||||
void MonsterTextEmote(const char* text, uint64 TargetGuid, bool IsBossEmote = false);
|
||||
void MonsterWhisper(const char* text, uint64 receiver, bool IsBossWhisper = false);
|
||||
void MonsterSay(int32 textId, uint32 language, uint64 TargetGuid);
|
||||
void MonsterYell(int32 textId, uint32 language, uint64 TargetGuid);
|
||||
void MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false);
|
||||
void MonsterWhisper(int32 textId, uint64 receiver, bool IsBossWhisper = false);
|
||||
void MonsterYellToZone(int32 textId, uint32 language, uint64 TargetGuid);
|
||||
void BuildMonsterChat(WorldPacket *data, uint8 msgtype, char const* text, uint32 language, char const* name, uint64 TargetGuid) const;
|
||||
|
||||
void PlayDistanceSound(uint32 sound_id, Player* target = NULL);
|
||||
void PlayDirectSound(uint32 sound_id, Player* target = NULL);
|
||||
|
||||
void SendObjectDeSpawnAnim(uint64 guid);
|
||||
|
||||
virtual void SaveRespawnTime() {}
|
||||
void AddObjectToRemoveList();
|
||||
|
||||
// main visibility check function in normal case (ignore grey zone distance check)
|
||||
bool isVisibleFor(Player const* u) const { return isVisibleForInState(u,false); }
|
||||
|
||||
// low level function for visibility change code, must be define in all main world object subclasses
|
||||
virtual bool isVisibleForInState(Player const* u, bool inVisibleList) const = 0;
|
||||
|
||||
// Low Level Packets
|
||||
void SendPlaySound(uint32 Sound, bool OnlySelf);
|
||||
|
||||
virtual void SetMap(Map * map);
|
||||
virtual void ResetMap();
|
||||
Map * GetMap() const { ASSERT(m_currMap); return m_currMap; }
|
||||
Map * FindMap() const { return m_currMap; }
|
||||
//used to check all object's GetMap() calls when object is not in world!
|
||||
|
||||
//this function should be removed in nearest time...
|
||||
Map const* GetBaseMap() const;
|
||||
|
||||
void SetZoneScript();
|
||||
ZoneScript * GetZoneScript() const { return m_zoneScript; }
|
||||
|
||||
TempSummon* SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0, uint32 vehId = 0) const;
|
||||
TempSummon* SummonCreature(uint32 id, float x, float y, float z, float ang = 0, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0)
|
||||
{
|
||||
if (!x && !y && !z)
|
||||
{
|
||||
GetClosePoint(x, y, z, GetObjectSize());
|
||||
ang = GetOrientation();
|
||||
}
|
||||
Position pos = {x, y, z, ang};
|
||||
return SummonCreature(id, pos, spwtype, despwtime, 0);
|
||||
}
|
||||
GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime);
|
||||
Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL);
|
||||
|
||||
Creature* FindNearestCreature(uint32 entry, float range, bool alive = true);
|
||||
GameObject* FindNearestGameObject(uint32 entry, float range);
|
||||
|
||||
void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& lList, uint32 uiEntry, float fMaxSearchRange);
|
||||
void GetCreatureListWithEntryInGrid(std::list<Creature*>& lList, uint32 uiEntry, float fMaxSearchRange);
|
||||
|
||||
void DestroyForNearbyPlayers();
|
||||
virtual void UpdateObjectVisibility(bool forced = true);
|
||||
void BuildUpdate(UpdateDataMapType&);
|
||||
|
||||
//relocation and visibility system functions
|
||||
void AddToNotify(uint16 f) { m_notifyflags |= f;}
|
||||
bool isNeedNotify(uint16 f) const { return m_notifyflags & f;}
|
||||
uint16 GetNotifyFlags() const { return m_notifyflags; }
|
||||
bool NotifyExecuted(uint16 f) const { return m_executed_notifies & f;}
|
||||
void SetNotified(uint16 f) { m_executed_notifies |= f;}
|
||||
void ResetAllNotifies() { m_notifyflags = 0; m_executed_notifies = 0; }
|
||||
|
||||
bool isActiveObject() const { return m_isActive; }
|
||||
void setActive(bool isActiveObject);
|
||||
void SetWorldObject(bool apply);
|
||||
template<class NOTIFIER> void VisitNearbyObject(const float &radius, NOTIFIER ¬ifier) const { GetMap()->VisitAll(GetPositionX(), GetPositionY(), radius, notifier); }
|
||||
template<class NOTIFIER> void VisitNearbyGridObject(const float &radius, NOTIFIER ¬ifier) const { GetMap()->VisitGrid(GetPositionX(), GetPositionY(), radius, notifier); }
|
||||
template<class NOTIFIER> void VisitNearbyWorldObject(const float &radius, NOTIFIER ¬ifier) const { GetMap()->VisitWorld(GetPositionX(), GetPositionY(), radius, notifier); }
|
||||
|
||||
#ifdef MAP_BASED_RAND_GEN
|
||||
int32 irand(int32 min, int32 max) const { return int32 (GetMap()->mtRand.randInt(max - min)) + min; }
|
||||
uint32 urand(uint32 min, uint32 max) const { return GetMap()->mtRand.randInt(max - min) + min;}
|
||||
int32 rand32() const { return GetMap()->mtRand.randInt();}
|
||||
double rand_norm() const { return GetMap()->mtRand.randExc();}
|
||||
double rand_chance() const { return GetMap()->mtRand.randExc(100.0);}
|
||||
#endif
|
||||
|
||||
bool m_isWorldObject;
|
||||
uint32 LastUsedScriptID;
|
||||
protected:
|
||||
explicit WorldObject();
|
||||
std::string m_name;
|
||||
bool m_isActive;
|
||||
ZoneScript *m_zoneScript;
|
||||
|
||||
//these functions are used mostly for Relocate() and Corpse/Player specific stuff...
|
||||
//use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
|
||||
//mapId/instanceId should be set in SetMap() function!
|
||||
void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
|
||||
void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }
|
||||
|
||||
private:
|
||||
Map * m_currMap; //current object's Map location
|
||||
|
||||
//uint32 m_mapId; // object at map with map_id
|
||||
uint32 m_InstanceId; // in map copy with instance id
|
||||
uint32 m_phaseMask; // in area phase state
|
||||
|
||||
uint16 m_notifyflags;
|
||||
uint16 m_executed_notifies;
|
||||
};
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
template<class T>
|
||||
void RandomResizeList(std::list<T> &_list, uint32 _size)
|
||||
{
|
||||
while (_list.size() > _size)
|
||||
{
|
||||
typename std::list<T>::iterator itr = _list.begin();
|
||||
advance(itr, urand(0, _list.size() - 1));
|
||||
_list.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
// Binary predicate to sort WorldObjects based on the distance to a reference WorldObject
|
||||
class ObjectDistanceOrderPred
|
||||
{
|
||||
public:
|
||||
ObjectDistanceOrderPred(const WorldObject *pRefObj, bool ascending = true) : m_refObj(pRefObj), m_ascending(ascending) {}
|
||||
bool operator()(const WorldObject *pLeft, const WorldObject *pRight) const
|
||||
{
|
||||
return m_ascending ? m_refObj->GetDistanceOrder(pLeft, pRight) : !m_refObj->GetDistanceOrder(pLeft, pRight);
|
||||
}
|
||||
private:
|
||||
const WorldObject *m_refObj;
|
||||
const bool m_ascending;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Player.h"
|
||||
#include "Creature.h"
|
||||
#include "GameObject.h"
|
||||
#include "DynamicObject.h"
|
||||
#include "Vehicle.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Item.h"
|
||||
#include "Corpse.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "MapManager.h"
|
||||
#include "Map.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "Opcodes.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "MapInstanced.h"
|
||||
#include "World.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#define CLASS_LOCK Trinity::ClassLevelLockable<ObjectAccessor, ACE_Thread_Mutex>
|
||||
INSTANTIATE_SINGLETON_2(ObjectAccessor, CLASS_LOCK);
|
||||
INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ACE_Thread_Mutex);
|
||||
|
||||
ObjectAccessor::ObjectAccessor()
|
||||
{
|
||||
}
|
||||
|
||||
ObjectAccessor::~ObjectAccessor()
|
||||
{
|
||||
for (Player2CorpsesMapType::const_iterator itr = i_player2corpse.begin(); itr != i_player2corpse.end(); ++itr)
|
||||
{
|
||||
itr->second->RemoveFromWorld();
|
||||
delete itr->second;
|
||||
}
|
||||
}
|
||||
|
||||
Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, uint64 guid)
|
||||
{
|
||||
if (IS_PLAYER_GUID(guid))
|
||||
return NULL;
|
||||
|
||||
if (IS_PET_GUID(guid))
|
||||
return GetPet(guid);
|
||||
|
||||
return u.IsInWorld() ? u.GetMap()->GetCreature(guid) : NULL;
|
||||
}
|
||||
|
||||
Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, uint64 guid)
|
||||
{
|
||||
Corpse* ret = GetObjectInWorld(guid, (Corpse*)NULL);
|
||||
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
if (ret->GetMapId() != u.GetMapId())
|
||||
return NULL;
|
||||
|
||||
if (ret->GetInstanceId() != u.GetInstanceId())
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, uint64 guid)
|
||||
{
|
||||
switch (GUID_HIPART(guid))
|
||||
{
|
||||
case HIGHGUID_PLAYER: return FindPlayer(guid);
|
||||
case HIGHGUID_GAMEOBJECT: return p.GetMap()->GetGameObject(guid);
|
||||
case HIGHGUID_VEHICLE:
|
||||
case HIGHGUID_UNIT: return p.GetMap()->GetCreature(guid);
|
||||
case HIGHGUID_PET: return GetPet(guid);
|
||||
case HIGHGUID_DYNAMICOBJECT: return p.GetMap()->GetDynamicObject(guid);
|
||||
case HIGHGUID_TRANSPORT: return NULL;
|
||||
case HIGHGUID_CORPSE: return GetCorpse(p,guid);
|
||||
case HIGHGUID_MO_TRANSPORT: return NULL;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, uint64 guid, uint32 typemask)
|
||||
{
|
||||
switch (GUID_HIPART(guid))
|
||||
{
|
||||
case HIGHGUID_ITEM:
|
||||
if (typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER)
|
||||
return ((Player const&)p).GetItemByGuid(guid);
|
||||
break;
|
||||
case HIGHGUID_PLAYER:
|
||||
if (typemask & TYPEMASK_PLAYER)
|
||||
return FindPlayer(guid);
|
||||
break;
|
||||
case HIGHGUID_GAMEOBJECT:
|
||||
if (typemask & TYPEMASK_GAMEOBJECT)
|
||||
return p.GetMap()->GetGameObject(guid);
|
||||
break;
|
||||
case HIGHGUID_UNIT:
|
||||
case HIGHGUID_VEHICLE:
|
||||
if (typemask & TYPEMASK_UNIT)
|
||||
return p.GetMap()->GetCreature(guid);
|
||||
break;
|
||||
case HIGHGUID_PET:
|
||||
if (typemask & TYPEMASK_UNIT)
|
||||
return GetPet(guid);
|
||||
break;
|
||||
case HIGHGUID_DYNAMICOBJECT:
|
||||
if (typemask & TYPEMASK_DYNAMICOBJECT)
|
||||
return p.GetMap()->GetDynamicObject(guid);
|
||||
break;
|
||||
case HIGHGUID_TRANSPORT:
|
||||
case HIGHGUID_CORPSE:
|
||||
case HIGHGUID_MO_TRANSPORT:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Player* ObjectAccessor::FindPlayer(uint64 guid)
|
||||
{
|
||||
Player* plr = GetObjectInWorld(guid, (Player*)NULL);
|
||||
if (!plr || !plr->IsInWorld())
|
||||
return NULL;
|
||||
|
||||
return plr;
|
||||
}
|
||||
|
||||
Player* ObjectAccessor::FindPlayerByName(const char* name)
|
||||
{
|
||||
Guard guard(*HashMapHolder<Player>::GetLock());
|
||||
HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer();
|
||||
for (HashMapHolder<Player>::MapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
if (iter->second->IsInWorld() && strcmp(name, iter->second->GetName()) == 0)
|
||||
return iter->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ObjectAccessor::SaveAllPlayers()
|
||||
{
|
||||
Guard guard(*HashMapHolder<Player>::GetLock());
|
||||
HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer();
|
||||
for (HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
itr->second->SaveToDB();
|
||||
}
|
||||
|
||||
Pet* ObjectAccessor::GetPet(uint64 guid)
|
||||
{
|
||||
return GetObjectInWorld(guid, (Pet*)NULL);
|
||||
}
|
||||
|
||||
Corpse* ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)
|
||||
{
|
||||
Guard guard(i_corpseGuard);
|
||||
|
||||
Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid);
|
||||
if (iter == i_player2corpse.end())
|
||||
return NULL;
|
||||
|
||||
assert(iter->second->GetType() != CORPSE_BONES);
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void ObjectAccessor::RemoveCorpse(Corpse* corpse)
|
||||
{
|
||||
assert(corpse && corpse->GetType() != CORPSE_BONES);
|
||||
|
||||
if (corpse->FindMap())
|
||||
corpse->FindMap()->Remove(corpse, false);
|
||||
else
|
||||
corpse->RemoveFromWorld();
|
||||
|
||||
// Critical section
|
||||
{
|
||||
Guard guard(i_corpseGuard);
|
||||
|
||||
Player2CorpsesMapType::iterator iter = i_player2corpse.find(corpse->GetOwnerGUID());
|
||||
if (iter == i_player2corpse.end()) // TODO: Fix this
|
||||
return;
|
||||
|
||||
// build mapid*cellid -> guid_set map
|
||||
CellPair cell_pair = Trinity::ComputeCellPair(corpse->GetPositionX(), corpse->GetPositionY());
|
||||
uint32 cell_id = (cell_pair.y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
|
||||
|
||||
objmgr.DeleteCorpseCellData(corpse->GetMapId(), cell_id, corpse->GetOwnerGUID());
|
||||
|
||||
i_player2corpse.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectAccessor::AddCorpse(Corpse* corpse)
|
||||
{
|
||||
assert(corpse && corpse->GetType() != CORPSE_BONES);
|
||||
|
||||
// Critical section
|
||||
{
|
||||
Guard guard(i_corpseGuard);
|
||||
|
||||
assert(i_player2corpse.find(corpse->GetOwnerGUID()) == i_player2corpse.end());
|
||||
i_player2corpse[corpse->GetOwnerGUID()] = corpse;
|
||||
|
||||
// build mapid*cellid -> guid_set map
|
||||
CellPair cell_pair = Trinity::ComputeCellPair(corpse->GetPositionX(), corpse->GetPositionY());
|
||||
uint32 cell_id = (cell_pair.y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
|
||||
|
||||
objmgr.AddCorpseCellData(corpse->GetMapId(), cell_id, corpse->GetOwnerGUID(), corpse->GetInstanceId());
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectAccessor::AddCorpsesToGrid(GridPair const& gridpair, GridType& grid, Map* map)
|
||||
{
|
||||
Guard guard(i_corpseGuard);
|
||||
|
||||
for (Player2CorpsesMapType::iterator iter = i_player2corpse.begin(); iter != i_player2corpse.end(); ++iter)
|
||||
{
|
||||
if (iter->second->GetGrid() == gridpair)
|
||||
{
|
||||
// verify, if the corpse in our instance (add only corpses which are)
|
||||
if (map->Instanceable())
|
||||
{
|
||||
if (iter->second->GetInstanceId() == map->GetInstanceId())
|
||||
grid.AddWorldObject(iter->second);
|
||||
}
|
||||
else
|
||||
grid.AddWorldObject(iter->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Corpse* ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool /*insignia*/)
|
||||
{
|
||||
Corpse* corpse = GetCorpseForPlayerGUID(player_guid);
|
||||
if (!corpse)
|
||||
{
|
||||
//in fact this function is called from several places
|
||||
//even when player doesn't have a corpse, not an error
|
||||
// TODO: really, now...
|
||||
//sLog.outError("Try remove corpse that not in map for GUID %ul", player_guid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEBUG_LOG("Deleting Corpse and spawned bones.");
|
||||
|
||||
//Map* map = corpse->FindMap();
|
||||
|
||||
// remove corpse from player_guid -> corpse map
|
||||
RemoveCorpse(corpse);
|
||||
|
||||
// done in removecorpse
|
||||
// remove resurrectable corpse from grid object registry (loaded state checked into call)
|
||||
// do not load the map if it's not loaded
|
||||
//Map *map = MapManager::Instance().FindMap(corpse->GetMapId(), corpse->GetInstanceId());
|
||||
//if (map)
|
||||
// map->Remove(corpse, false);
|
||||
|
||||
// remove corpse from DB
|
||||
corpse->DeleteFromDB();
|
||||
|
||||
// we don't want bones to save some cpu.. :)
|
||||
delete corpse;
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
Corpse* bones = NULL;
|
||||
// create the bones only if the map and the grid is loaded at the corpse's location
|
||||
// ignore bones creating option in case insignia
|
||||
if (map && (insignia ||
|
||||
(map->IsBattleGroundOrArena() ? sWorld.getConfig(CONFIG_DEATH_BONES_BG_OR_ARENA) : sWorld.getConfig(CONFIG_DEATH_BONES_WORLD))) &&
|
||||
!map->IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY()))
|
||||
{
|
||||
// Create bones, don't change Corpse
|
||||
bones = new Corpse;
|
||||
bones->Create(corpse->GetGUIDLow(), map);
|
||||
|
||||
for (int i = 3; i < CORPSE_END; ++i) // don't overwrite guid and object type
|
||||
bones->SetUInt32Value(i, corpse->GetUInt32Value(i));
|
||||
|
||||
bones->SetGrid(corpse->GetGrid());
|
||||
// bones->m_time = m_time; // don't overwrite time
|
||||
// bones->m_inWorld = m_inWorld; // don't overwrite in-world state
|
||||
// bones->m_type = m_type; // don't overwrite type
|
||||
bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
|
||||
bones->SetPhaseMask(corpse->GetPhaseMask(), false);
|
||||
|
||||
bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
|
||||
bones->SetUInt64Value(CORPSE_FIELD_OWNER, 0);
|
||||
|
||||
for (int i = 0; i < EQUIPMENT_SLOT_END; ++i)
|
||||
{
|
||||
if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i))
|
||||
bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0);
|
||||
}
|
||||
|
||||
// add bones in grid store if grid loaded where corpse placed
|
||||
map->Add(bones);
|
||||
}
|
||||
|
||||
// all references to the corpse should be removed at this point
|
||||
delete corpse;
|
||||
|
||||
return bones;
|
||||
*/
|
||||
}
|
||||
|
||||
void ObjectAccessor::Update(uint32 /*diff*/)
|
||||
{
|
||||
UpdateDataMapType update_players;
|
||||
|
||||
// Critical section
|
||||
{
|
||||
Guard guard(i_updateGuard);
|
||||
|
||||
while (!i_objects.empty())
|
||||
{
|
||||
Object* obj = *i_objects.begin();
|
||||
assert(obj && obj->IsInWorld());
|
||||
i_objects.erase(i_objects.begin());
|
||||
obj->BuildUpdate(update_players);
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket packet; // here we allocate a std::vector with a size of 0x10000
|
||||
for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
|
||||
{
|
||||
iter->second.BuildPacket(&packet);
|
||||
iter->first->GetSession()->SendPacket(&packet);
|
||||
packet.clear(); // clean the string
|
||||
}
|
||||
}
|
||||
|
||||
/// Define the static members of HashMapHolder
|
||||
|
||||
template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;
|
||||
template <class T> ACE_Thread_Mutex HashMapHolder<T>::i_lock;
|
||||
|
||||
/// Global definitions for the hashmap storage
|
||||
|
||||
template class HashMapHolder<Player>;
|
||||
template class HashMapHolder<Pet>;
|
||||
template class HashMapHolder<GameObject>;
|
||||
template class HashMapHolder<DynamicObject>;
|
||||
template class HashMapHolder<Creature>;
|
||||
template class HashMapHolder<Corpse>;
|
||||
|
||||
template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/);
|
||||
template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/);
|
||||
template Creature* ObjectAccessor::GetObjectInWorld<Creature>(uint32 mapid, float x, float y, uint64 guid, Creature* /*fake*/);
|
||||
template Corpse* ObjectAccessor::GetObjectInWorld<Corpse>(uint32 mapid, float x, float y, uint64 guid, Corpse* /*fake*/);
|
||||
template GameObject* ObjectAccessor::GetObjectInWorld<GameObject>(uint32 mapid, float x, float y, uint64 guid, GameObject* /*fake*/);
|
||||
template DynamicObject* ObjectAccessor::GetObjectInWorld<DynamicObject>(uint32 mapid, float x, float y, uint64 guid, DynamicObject* /*fake*/);
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_OBJECTACCESSOR_H
|
||||
#define TRINITY_OBJECTACCESSOR_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
#include "Policies/Singleton.h"
|
||||
#include <ace/Thread_Mutex.h>
|
||||
#include "Utilities/UnorderedMap.h"
|
||||
#include "Policies/ThreadingModel.h"
|
||||
|
||||
#include "UpdateData.h"
|
||||
|
||||
#include "GridDefines.h"
|
||||
#include "Object.h"
|
||||
#include "Player.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
class Creature;
|
||||
class Corpse;
|
||||
class Unit;
|
||||
class GameObject;
|
||||
class DynamicObject;
|
||||
class WorldObject;
|
||||
class Map;
|
||||
|
||||
template <class T>
|
||||
class HashMapHolder
|
||||
{
|
||||
public:
|
||||
|
||||
typedef UNORDERED_MAP<uint64, T*> MapType;
|
||||
typedef ACE_Thread_Mutex LockType;
|
||||
typedef Trinity::GeneralLock<LockType> Guard;
|
||||
|
||||
static void Insert(T* o)
|
||||
{
|
||||
Guard guard(i_lock);
|
||||
m_objectMap[o->GetGUID()] = o;
|
||||
}
|
||||
|
||||
static void Remove(T* o)
|
||||
{
|
||||
Guard guard(i_lock);
|
||||
m_objectMap.erase(o->GetGUID());
|
||||
}
|
||||
|
||||
static T* Find(uint64 guid)
|
||||
{
|
||||
Guard guard(i_lock);
|
||||
typename MapType::iterator itr = m_objectMap.find(guid);
|
||||
return (itr != m_objectMap.end()) ? itr->second : NULL;
|
||||
}
|
||||
|
||||
static MapType& GetContainer() { return m_objectMap; }
|
||||
|
||||
static LockType* GetLock() { return &i_lock; }
|
||||
|
||||
private:
|
||||
|
||||
//Non instanceable only static
|
||||
HashMapHolder() {}
|
||||
|
||||
static LockType i_lock;
|
||||
static MapType m_objectMap;
|
||||
};
|
||||
|
||||
class ObjectAccessor : public Trinity::Singleton<ObjectAccessor, Trinity::ClassLevelLockable<ObjectAccessor, ACE_Thread_Mutex> >
|
||||
{
|
||||
friend class Trinity::OperatorNew<ObjectAccessor>;
|
||||
ObjectAccessor();
|
||||
~ObjectAccessor();
|
||||
ObjectAccessor(const ObjectAccessor&);
|
||||
ObjectAccessor& operator=(const ObjectAccessor&);
|
||||
|
||||
public:
|
||||
|
||||
typedef UNORDERED_MAP<uint64, Corpse*> Player2CorpsesMapType;
|
||||
typedef UNORDERED_MAP<Player*, UpdateData>::value_type UpdateDataValueType;
|
||||
|
||||
template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/)
|
||||
{
|
||||
return HashMapHolder<T>::Find(guid);
|
||||
}
|
||||
|
||||
static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/)
|
||||
{
|
||||
if (!guid)
|
||||
return NULL;
|
||||
|
||||
if (IS_PLAYER_GUID(guid))
|
||||
{
|
||||
Unit* u = (Unit*)HashMapHolder<Player>::Find(guid);
|
||||
if (!u || !u->IsInWorld())
|
||||
return NULL;
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
if (IS_PET_GUID(guid))
|
||||
return (Unit*)HashMapHolder<Pet>::Find(guid);
|
||||
|
||||
return (Unit*)HashMapHolder<Creature>::Find(guid);
|
||||
}
|
||||
|
||||
static Unit* GetUnitInOrOutOfWorld(uint64 guid, Unit* /*fake*/)
|
||||
{
|
||||
if (!guid)
|
||||
return NULL;
|
||||
|
||||
if (IS_PLAYER_GUID(guid))
|
||||
{
|
||||
Unit* u = (Unit*)HashMapHolder<Player>::Find(guid);
|
||||
if (!u)
|
||||
return NULL;
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
// Other object types than player are unloaded while out of world
|
||||
return GetObjectInWorld(guid, (Unit*)NULL);
|
||||
}
|
||||
|
||||
template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/)
|
||||
{
|
||||
T* obj = HashMapHolder<T>::Find(guid);
|
||||
if (!obj || obj->GetMapId() != mapid)
|
||||
return NULL;
|
||||
|
||||
CellPair p = Trinity::ComputeCellPair(x, y);
|
||||
if (p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||
{
|
||||
sLog.outError("ObjectAccessor::GetObjectInWorld: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x, y, p.x_coord, p.y_coord);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CellPair q = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
|
||||
if (q.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || q.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||
{
|
||||
sLog.outError("ObjectAccessor::GetObjecInWorld: object (GUID: %u TypeId: %u) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), q.x_coord, q.y_coord);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32 dx = int32(p.x_coord) - int32(q.x_coord);
|
||||
int32 dy = int32(p.y_coord) - int32(q.y_coord);
|
||||
|
||||
if (dx > -2 && dx < 2 && dy > -2 && dy < 2)
|
||||
return obj;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static WorldObject* GetWorldObject(WorldObject const&, uint64);
|
||||
static Object* GetObjectByTypeMask(WorldObject const&, uint64, uint32 typemask);
|
||||
static Creature* GetCreatureOrPetOrVehicle(WorldObject const&, uint64);
|
||||
static Unit* GetUnit(WorldObject const&, uint64 guid) { return GetObjectInWorld(guid, (Unit*)NULL); }
|
||||
static Unit* GetUnitInOrOutOfWorld(WorldObject const&, uint64 guid) { return GetUnitInOrOutOfWorld(guid, (Unit*)NULL); }
|
||||
static Pet* GetPet(Unit const&, uint64 guid) { return GetPet(guid); }
|
||||
static Player* GetPlayer(Unit const&, uint64 guid) { return FindPlayer(guid); }
|
||||
static Corpse* GetCorpse(WorldObject const& u, uint64 guid);
|
||||
static Pet* GetPet(uint64 guid);
|
||||
static Player* FindPlayer(uint64);
|
||||
|
||||
Player* FindPlayerByName(const char* name) ;
|
||||
|
||||
// when using this, you must use the hashmapholder's lock
|
||||
HashMapHolder<Player>::MapType& GetPlayers()
|
||||
{
|
||||
return HashMapHolder<Player>::GetContainer();
|
||||
}
|
||||
|
||||
// when using this, you must use the hashmapholder's lock
|
||||
HashMapHolder<Creature>::MapType& GetCreatures()
|
||||
{
|
||||
return HashMapHolder<Creature>::GetContainer();
|
||||
}
|
||||
|
||||
// when using this, you must use the hashmapholder's lock
|
||||
HashMapHolder<GameObject>::MapType& GetGameObjects()
|
||||
{
|
||||
return HashMapHolder<GameObject>::GetContainer();
|
||||
}
|
||||
|
||||
template<class T> void AddObject(T* object)
|
||||
{
|
||||
HashMapHolder<T>::Insert(object);
|
||||
}
|
||||
|
||||
template<class T> void RemoveObject(T* object)
|
||||
{
|
||||
HashMapHolder<T>::Remove(object);
|
||||
}
|
||||
|
||||
void RemoveObject(Player* pl)
|
||||
{
|
||||
HashMapHolder<Player>::Remove(pl);
|
||||
RemoveUpdateObject((Object*)pl);
|
||||
}
|
||||
|
||||
void SaveAllPlayers();
|
||||
|
||||
void AddUpdateObject(Object* obj)
|
||||
{
|
||||
Guard guard(i_updateGuard);
|
||||
i_objects.insert(obj);
|
||||
}
|
||||
|
||||
void RemoveUpdateObject(Object* obj)
|
||||
{
|
||||
Guard guard(i_updateGuard);
|
||||
i_objects.erase(obj);
|
||||
}
|
||||
|
||||
void Update(uint32 diff);
|
||||
|
||||
Corpse* GetCorpseForPlayerGUID(uint64 guid);
|
||||
void RemoveCorpse(Corpse* corpse);
|
||||
void AddCorpse(Corpse* corpse);
|
||||
void AddCorpsesToGrid(GridPair const& gridpair, GridType& grid, Map* map);
|
||||
Corpse* ConvertCorpseForPlayer(uint64 player_guid, bool insignia = false);
|
||||
|
||||
typedef ACE_Thread_Mutex LockType;
|
||||
typedef Trinity::GeneralLock<LockType> Guard;
|
||||
|
||||
private:
|
||||
|
||||
Player2CorpsesMapType i_player2corpse;
|
||||
|
||||
static void _buildChangeObjectForPlayer(WorldObject*, UpdateDataMapType&);
|
||||
static void _buildPacket(Player*, Object*, UpdateDataMapType&);
|
||||
void _update();
|
||||
|
||||
std::set<Object*> i_objects;
|
||||
|
||||
LockType i_updateGuard;
|
||||
LockType i_corpseGuard;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_OBJECTDEFINES_H
|
||||
#define TRINITY_OBJECTDEFINES_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
|
||||
// used for creating values for respawn for example
|
||||
#define MAKE_PAIR64(l, h) uint64(uint32(l) | (uint64(h) << 32))
|
||||
#define PAIR64_HIPART(x) (uint32)((uint64(x) >> 32) & UI64LIT(0x00000000FFFFFFFF))
|
||||
#define PAIR64_LOPART(x) (uint32)(uint64(x) & UI64LIT(0x00000000FFFFFFFF))
|
||||
|
||||
#define MAKE_PAIR16(l, h) uint16(uint8(l) | (uint16(h) << 8))
|
||||
#define MAKE_PAIR32(l, h) uint32(uint16(l) | (uint32(h) << 16))
|
||||
#define PAIR32_HIPART(x) (uint16)((uint32(x) >> 16) & 0x0000FFFF)
|
||||
#define PAIR32_LOPART(x) (uint16)(uint32(x) & 0x0000FFFF)
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
#define IS_EMPTY_GUID(Guid) (Guid == 0)
|
||||
|
||||
#define IS_CREATURE_GUID(Guid) (GUID_HIPART(Guid) == HIGHGUID_UNIT)
|
||||
#define IS_PET_GUID(Guid) (GUID_HIPART(Guid) == HIGHGUID_PET)
|
||||
#define IS_VEHICLE_GUID(Guid) (GUID_HIPART(Guid) == HIGHGUID_VEHICLE)
|
||||
#define IS_CRE_OR_VEH_GUID(Guid) (IS_CREATURE_GUID(Guid) || IS_VEHICLE_GUID(Guid))
|
||||
#define IS_CRE_OR_VEH_OR_PET_GUID(Guid)(IS_CRE_OR_VEH_GUID(Guid) || IS_PET_GUID(Guid))
|
||||
#define IS_PLAYER_GUID(Guid) (GUID_HIPART(Guid) == HIGHGUID_PLAYER && Guid != 0)
|
||||
#define IS_UNIT_GUID(Guid) (IS_CRE_OR_VEH_OR_PET_GUID(Guid) || IS_PLAYER_GUID(Guid))
|
||||
// special case for empty guid need check
|
||||
#define IS_ITEM_GUID(Guid) (GUID_HIPART(Guid) == HIGHGUID_ITEM)
|
||||
#define IS_GAMEOBJECT_GUID(Guid) (GUID_HIPART(Guid) == HIGHGUID_GAMEOBJECT)
|
||||
#define IS_DYNAMICOBJECT_GUID(Guid) (GUID_HIPART(Guid) == HIGHGUID_DYNAMICOBJECT)
|
||||
#define IS_CORPSE_GUID(Guid) (GUID_HIPART(Guid) == HIGHGUID_CORPSE)
|
||||
#define IS_TRANSPORT(Guid) (GUID_HIPART(Guid) == HIGHGUID_TRANSPORT)
|
||||
#define IS_MO_TRANSPORT(Guid) (GUID_HIPART(Guid) == HIGHGUID_MO_TRANSPORT)
|
||||
#define IS_GROUP(Guid) (GUID_HIPART(Guid) == HIGHGUID_GROUP)
|
||||
|
||||
// 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
|
||||
#define MAKE_NEW_GUID(l, e, h) uint64(uint64(l) | (uint64(e) << 24) | (uint64(h) << 48))
|
||||
|
||||
#define GUID_HIPART(x) (uint32)((uint64(x) >> 48) & 0x0000FFFF)
|
||||
|
||||
// We have different low and middle part size for different guid types
|
||||
#define _GUID_ENPART_2(x) 0
|
||||
#define _GUID_ENPART_3(x) (uint32)((uint64(x) >> 24) & UI64LIT(0x0000000000FFFFFF))
|
||||
#define _GUID_LOPART_2(x) (uint32)(uint64(x) & UI64LIT(0x00000000FFFFFFFF))
|
||||
#define _GUID_LOPART_3(x) (uint32)(uint64(x) & UI64LIT(0x0000000000FFFFFF))
|
||||
|
||||
inline bool IsGuidHaveEnPart(uint64 const& 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;
|
||||
}
|
||||
}
|
||||
|
||||
#define GUID_ENPART(x) (IsGuidHaveEnPart(x) ? _GUID_ENPART_3(x) : _GUID_ENPART_2(x))
|
||||
#define GUID_LOPART(x) (IsGuidHaveEnPart(x) ? _GUID_LOPART_3(x) : _GUID_LOPART_2(x))
|
||||
|
||||
inline 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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "ByteBuffer.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "UpdateData.h"
|
||||
#include "Log.h"
|
||||
#include "Opcodes.h"
|
||||
#include "World.h"
|
||||
#include <zlib/zlib.h>
|
||||
|
||||
UpdateData::UpdateData() : m_blockCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateData::AddOutOfRangeGUID(std::set<uint64>& guids)
|
||||
{
|
||||
m_outOfRangeGUIDs.insert(guids.begin(),guids.end());
|
||||
}
|
||||
|
||||
void UpdateData::AddOutOfRangeGUID(const uint64 &guid)
|
||||
{
|
||||
m_outOfRangeGUIDs.insert(guid);
|
||||
}
|
||||
|
||||
void UpdateData::AddUpdateBlock(const ByteBuffer &block)
|
||||
{
|
||||
m_data.append(block);
|
||||
++m_blockCount;
|
||||
}
|
||||
|
||||
void UpdateData::Compress(void* dst, uint32 *dst_size, void* src, int src_size)
|
||||
{
|
||||
z_stream c_stream;
|
||||
|
||||
c_stream.zalloc = (alloc_func)0;
|
||||
c_stream.zfree = (free_func)0;
|
||||
c_stream.opaque = (voidpf)0;
|
||||
|
||||
// default Z_BEST_SPEED (1)
|
||||
int z_res = deflateInit(&c_stream, sWorld.getConfig(CONFIG_COMPRESSION));
|
||||
if (z_res != Z_OK)
|
||||
{
|
||||
sLog.outError("Can't compress update packet (zlib: deflateInit) Error code: %i (%s)",z_res,zError(z_res));
|
||||
*dst_size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
c_stream.next_out = (Bytef*)dst;
|
||||
c_stream.avail_out = *dst_size;
|
||||
c_stream.next_in = (Bytef*)src;
|
||||
c_stream.avail_in = (uInt)src_size;
|
||||
|
||||
z_res = deflate(&c_stream, Z_NO_FLUSH);
|
||||
if (z_res != Z_OK)
|
||||
{
|
||||
sLog.outError("Can't compress update packet (zlib: deflate) Error code: %i (%s)",z_res,zError(z_res));
|
||||
*dst_size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (c_stream.avail_in != 0)
|
||||
{
|
||||
sLog.outError("Can't compress update packet (zlib: deflate not greedy)");
|
||||
*dst_size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
z_res = deflate(&c_stream, Z_FINISH);
|
||||
if (z_res != Z_STREAM_END)
|
||||
{
|
||||
sLog.outError("Can't compress update packet (zlib: deflate should report Z_STREAM_END instead %i (%s)",z_res,zError(z_res));
|
||||
*dst_size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
z_res = deflateEnd(&c_stream);
|
||||
if (z_res != Z_OK)
|
||||
{
|
||||
sLog.outError("Can't compress update packet (zlib: deflateEnd) Error code: %i (%s)",z_res,zError(z_res));
|
||||
*dst_size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*dst_size = c_stream.total_out;
|
||||
}
|
||||
|
||||
bool UpdateData::BuildPacket(WorldPacket *packet)
|
||||
{
|
||||
ASSERT(packet->empty()); // shouldn't happen
|
||||
|
||||
ByteBuffer buf(4 + (m_outOfRangeGUIDs.empty() ? 0 : 1 + 4 + 9 * m_outOfRangeGUIDs.size()) + m_data.wpos());
|
||||
|
||||
buf << (uint32) (!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount);
|
||||
|
||||
if (!m_outOfRangeGUIDs.empty())
|
||||
{
|
||||
buf << (uint8) UPDATETYPE_OUT_OF_RANGE_OBJECTS;
|
||||
buf << (uint32) m_outOfRangeGUIDs.size();
|
||||
|
||||
for (std::set<uint64>::const_iterator i = m_outOfRangeGUIDs.begin(); i != m_outOfRangeGUIDs.end(); ++i)
|
||||
{
|
||||
buf.appendPackGUID(*i);
|
||||
}
|
||||
}
|
||||
|
||||
buf.append(m_data);
|
||||
|
||||
size_t pSize = buf.wpos(); // use real used data size
|
||||
|
||||
if (pSize > 100) // compress large packets
|
||||
{
|
||||
uint32 destsize = compressBound(pSize);
|
||||
packet->resize(destsize + sizeof(uint32));
|
||||
|
||||
packet->put<uint32>(0, pSize);
|
||||
Compress(const_cast<uint8*>(packet->contents()) + sizeof(uint32), &destsize, (void*)buf.contents(), pSize);
|
||||
if (destsize == 0)
|
||||
return false;
|
||||
|
||||
packet->resize(destsize + sizeof(uint32));
|
||||
packet->SetOpcode(SMSG_COMPRESSED_UPDATE_OBJECT);
|
||||
}
|
||||
else // send small packets without compression
|
||||
{
|
||||
packet->append(buf);
|
||||
packet->SetOpcode(SMSG_UPDATE_OBJECT);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UpdateData::Clear()
|
||||
{
|
||||
m_data.clear();
|
||||
m_outOfRangeGUIDs.clear();
|
||||
m_blockCount = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __UPDATEDATA_H
|
||||
#define __UPDATEDATA_H
|
||||
|
||||
#include "ByteBuffer.h"
|
||||
class WorldPacket;
|
||||
|
||||
enum OBJECT_UPDATE_TYPE
|
||||
{
|
||||
UPDATETYPE_VALUES = 0,
|
||||
UPDATETYPE_MOVEMENT = 1,
|
||||
UPDATETYPE_CREATE_OBJECT = 2,
|
||||
UPDATETYPE_CREATE_OBJECT2 = 3,
|
||||
UPDATETYPE_OUT_OF_RANGE_OBJECTS = 4,
|
||||
UPDATETYPE_NEAR_OBJECTS = 5
|
||||
};
|
||||
|
||||
enum OBJECT_UPDATE_FLAGS
|
||||
{
|
||||
UPDATEFLAG_NONE = 0x0000,
|
||||
UPDATEFLAG_SELF = 0x0001,
|
||||
UPDATEFLAG_TRANSPORT = 0x0002,
|
||||
UPDATEFLAG_HAS_TARGET = 0x0004,
|
||||
UPDATEFLAG_LOWGUID = 0x0008,
|
||||
UPDATEFLAG_HIGHGUID = 0x0010,
|
||||
UPDATEFLAG_LIVING = 0x0020,
|
||||
UPDATEFLAG_HAS_POSITION = 0x0040,
|
||||
UPDATEFLAG_VEHICLE = 0x0080,
|
||||
UPDATEFLAG_POSITION = 0x0100,
|
||||
UPDATEFLAG_ROTATION = 0x0200
|
||||
};
|
||||
|
||||
class UpdateData
|
||||
{
|
||||
public:
|
||||
UpdateData();
|
||||
|
||||
void AddOutOfRangeGUID(std::set<uint64>& guids);
|
||||
void AddOutOfRangeGUID(const uint64 &guid);
|
||||
void AddUpdateBlock(const ByteBuffer &block);
|
||||
bool BuildPacket(WorldPacket *packet);
|
||||
bool HasData() { return m_blockCount > 0 || !m_outOfRangeGUIDs.empty(); }
|
||||
void Clear();
|
||||
|
||||
std::set<uint64> const& GetOutOfRangeGUIDs() const { return m_outOfRangeGUIDs; }
|
||||
|
||||
protected:
|
||||
uint32 m_blockCount;
|
||||
std::set<uint64> m_outOfRangeGUIDs;
|
||||
ByteBuffer m_data;
|
||||
|
||||
void Compress(void* dst, uint32 *dst_size, void* src, int src_size);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,435 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _UPDATEFIELDS_AUTO_H
|
||||
#define _UPDATEFIELDS_AUTO_H
|
||||
|
||||
// Auto generated for version 3, 3, 3, 11723
|
||||
|
||||
enum EObjectFields
|
||||
{
|
||||
OBJECT_FIELD_GUID = 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
OBJECT_FIELD_TYPE = 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
OBJECT_FIELD_ENTRY = 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
OBJECT_FIELD_SCALE_X = 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
OBJECT_FIELD_PADDING = 0x0005, // Size: 1, Type: INT, Flags: NONE
|
||||
OBJECT_END = 0x0006,
|
||||
};
|
||||
|
||||
enum EItemFields
|
||||
{
|
||||
ITEM_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
ITEM_FIELD_CONTAINED = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
ITEM_FIELD_CREATOR = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
ITEM_FIELD_GIFTCREATOR = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
ITEM_FIELD_STACK_COUNT = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
|
||||
ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
|
||||
ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER, ITEM_OWNER
|
||||
ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_1_1 = OBJECT_END + 0x0010, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_1_3 = OBJECT_END + 0x0012, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_2_1 = OBJECT_END + 0x0013, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_2_3 = OBJECT_END + 0x0015, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_3_1 = OBJECT_END + 0x0016, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_3_3 = OBJECT_END + 0x0018, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_4_1 = OBJECT_END + 0x0019, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_4_3 = OBJECT_END + 0x001B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_5_1 = OBJECT_END + 0x001C, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_5_3 = OBJECT_END + 0x001E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_6_1 = OBJECT_END + 0x001F, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_6_3 = OBJECT_END + 0x0021, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_7_1 = OBJECT_END + 0x0022, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_7_3 = OBJECT_END + 0x0024, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_8_1 = OBJECT_END + 0x0025, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_8_3 = OBJECT_END + 0x0027, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_9_1 = OBJECT_END + 0x0028, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_9_3 = OBJECT_END + 0x002A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_10_1 = OBJECT_END + 0x002B, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_10_3 = OBJECT_END + 0x002D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_11_1 = OBJECT_END + 0x002E, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_11_3 = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_12_1 = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_12_3 = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_DURABILITY = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
|
||||
ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
|
||||
ITEM_FIELD_CREATE_PLAYED_TIME = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_PAD = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: NONE
|
||||
ITEM_END = OBJECT_END + 0x003A,
|
||||
};
|
||||
|
||||
enum EContainerFields
|
||||
{
|
||||
CONTAINER_FIELD_NUM_SLOTS = ITEM_END + 0x0000, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
CONTAINER_ALIGN_PAD = ITEM_END + 0x0001, // Size: 1, Type: BYTES, Flags: NONE
|
||||
CONTAINER_FIELD_SLOT_1 = ITEM_END + 0x0002, // Size: 72, Type: LONG, Flags: PUBLIC
|
||||
CONTAINER_END = ITEM_END + 0x004A,
|
||||
};
|
||||
|
||||
enum EUnitFields
|
||||
{
|
||||
UNIT_FIELD_CHARM = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_SUMMON = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_CRITTER = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_CREATEDBY = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_TARGET = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_CHANNEL_OBJECT = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_CHANNEL_SPELL = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_BYTES_0 = OBJECT_END + 0x0011, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_HEALTH = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER1 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER2 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER3 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER4 = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER5 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER6 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER7 = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER6 = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER7 = OBJECT_END + 0x0021, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x0022, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0029, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_LEVEL = OBJECT_END + 0x0030, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0031, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x0032, // Size: 3, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_FLAGS = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_AURASTATE = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0038, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x003A, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
UNIT_FIELD_COMBATREACH = OBJECT_END + 0x003C, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
UNIT_FIELD_DISPLAYID = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x003F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0040, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
|
||||
UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0041, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
|
||||
UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
|
||||
UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0043, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
|
||||
UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0044, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_PETNUMBER = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: OWNER
|
||||
UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: OWNER
|
||||
UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: DYNAMIC
|
||||
UNIT_MOD_CAST_SPEED = OBJECT_END + 0x004A, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
UNIT_CREATED_BY_SPELL = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_NPC_FLAGS = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: DYNAMIC
|
||||
UNIT_NPC_EMOTESTATE = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_STAT0 = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_STAT1 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_STAT2 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_STAT3 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_STAT4 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x005A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_RESISTANCES = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER, PARTY_LEADER
|
||||
UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x006B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_BASE_MANA = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_BYTES_2 = OBJECT_END + 0x0074, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x0075, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x0076, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0078, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x007A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x007B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x007C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x007D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0084, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x008B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
|
||||
UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x008C, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
UNIT_FIELD_PADDING = OBJECT_END + 0x008D, // Size: 1, Type: INT, Flags: NONE
|
||||
UNIT_END = OBJECT_END + 0x008E,
|
||||
|
||||
PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_GUILDID = UNIT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_GUILDRANK = UNIT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_BYTES = UNIT_END + 0x0005, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
PLAYER_BYTES_2 = UNIT_END + 0x0006, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
PLAYER_BYTES_3 = UNIT_END + 0x0007, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
PLAYER_DUEL_TEAM = UNIT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_GUILD_TIMESTAMP = UNIT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_QUEST_LOG_1_1 = UNIT_END + 0x000A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000B, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_1_3 = UNIT_END + 0x000C, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_1_4 = UNIT_END + 0x000E, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x000F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x0010, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_2_3 = UNIT_END + 0x0011, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_2_5 = UNIT_END + 0x0013, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0014, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0015, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_3_3 = UNIT_END + 0x0016, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_3_5 = UNIT_END + 0x0018, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x001A, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_4_3 = UNIT_END + 0x001B, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_4_5 = UNIT_END + 0x001D, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x001E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_5_3 = UNIT_END + 0x0020, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_5_5 = UNIT_END + 0x0022, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x0023, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x0024, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_6_3 = UNIT_END + 0x0025, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_6_5 = UNIT_END + 0x0027, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x0028, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x0029, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_7_3 = UNIT_END + 0x002A, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_7_5 = UNIT_END + 0x002C, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x002D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_8_3 = UNIT_END + 0x002F, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_8_5 = UNIT_END + 0x0031, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x0032, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x0033, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_9_3 = UNIT_END + 0x0034, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_9_5 = UNIT_END + 0x0036, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x0038, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_10_3 = UNIT_END + 0x0039, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_10_5 = UNIT_END + 0x003B, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x003C, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_11_3 = UNIT_END + 0x003E, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_11_5 = UNIT_END + 0x0040, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x0041, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x0042, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_12_3 = UNIT_END + 0x0043, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_12_5 = UNIT_END + 0x0045, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x0047, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_13_3 = UNIT_END + 0x0048, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_13_5 = UNIT_END + 0x004A, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x004B, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x004C, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_14_3 = UNIT_END + 0x004D, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_14_5 = UNIT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0050, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_15_3 = UNIT_END + 0x0052, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_15_5 = UNIT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0055, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_16_3 = UNIT_END + 0x0057, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_16_5 = UNIT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x005A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_17_3 = UNIT_END + 0x005C, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_17_5 = UNIT_END + 0x005E, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x005F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x0060, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_18_3 = UNIT_END + 0x0061, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_18_5 = UNIT_END + 0x0063, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0064, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0065, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_19_3 = UNIT_END + 0x0066, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_19_5 = UNIT_END + 0x0068, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x0069, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x006A, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_20_3 = UNIT_END + 0x006B, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_20_5 = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x006E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x006F, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_21_3 = UNIT_END + 0x0070, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_21_5 = UNIT_END + 0x0072, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x0073, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x0074, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_22_3 = UNIT_END + 0x0075, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_22_5 = UNIT_END + 0x0077, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x0078, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x0079, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_23_3 = UNIT_END + 0x007A, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_23_5 = UNIT_END + 0x007C, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_24_3 = UNIT_END + 0x007F, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_24_5 = UNIT_END + 0x0081, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x0082, // Size: 1, Type: INT, Flags: PARTY_MEMBER
|
||||
PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x0083, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x0084, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_25_5 = UNIT_END + 0x0086, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_VISIBLE_ITEM_1_ENTRYID = UNIT_END + 0x0087, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_1_ENCHANTMENT = UNIT_END + 0x0088, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_2_ENTRYID = UNIT_END + 0x0089, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_2_ENCHANTMENT = UNIT_END + 0x008A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_3_ENTRYID = UNIT_END + 0x008B, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_3_ENCHANTMENT = UNIT_END + 0x008C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_4_ENTRYID = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_4_ENCHANTMENT = UNIT_END + 0x008E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_5_ENTRYID = UNIT_END + 0x008F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_5_ENCHANTMENT = UNIT_END + 0x0090, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_6_ENTRYID = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_6_ENCHANTMENT = UNIT_END + 0x0092, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_7_ENTRYID = UNIT_END + 0x0093, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_7_ENCHANTMENT = UNIT_END + 0x0094, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_8_ENTRYID = UNIT_END + 0x0095, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_8_ENCHANTMENT = UNIT_END + 0x0096, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_9_ENTRYID = UNIT_END + 0x0097, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_9_ENCHANTMENT = UNIT_END + 0x0098, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_10_ENTRYID = UNIT_END + 0x0099, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_10_ENCHANTMENT = UNIT_END + 0x009A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_11_ENTRYID = UNIT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_11_ENCHANTMENT = UNIT_END + 0x009C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_12_ENTRYID = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_12_ENCHANTMENT = UNIT_END + 0x009E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_13_ENTRYID = UNIT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_13_ENCHANTMENT = UNIT_END + 0x00A0, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_14_ENTRYID = UNIT_END + 0x00A1, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_14_ENCHANTMENT = UNIT_END + 0x00A2, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_15_ENTRYID = UNIT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_15_ENCHANTMENT = UNIT_END + 0x00A4, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_16_ENTRYID = UNIT_END + 0x00A5, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_16_ENCHANTMENT = UNIT_END + 0x00A6, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_17_ENTRYID = UNIT_END + 0x00A7, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_17_ENCHANTMENT = UNIT_END + 0x00A8, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_18_ENTRYID = UNIT_END + 0x00A9, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_18_ENCHANTMENT = UNIT_END + 0x00AA, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_19_ENTRYID = UNIT_END + 0x00AB, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_19_ENCHANTMENT = UNIT_END + 0x00AC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_CHOSEN_TITLE = UNIT_END + 0x00AD, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_FAKE_INEBRIATION = UNIT_END + 0x00AE, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_FIELD_PAD_0 = UNIT_END + 0x00AF, // Size: 1, Type: INT, Flags: NONE
|
||||
PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x00B0, // Size: 46, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x00DE, // Size: 32, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x00FE, // Size: 56, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x0136, // Size: 14, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x0144, // Size: 24, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x015C, // Size: 64, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 = UNIT_END + 0x019C, // Size: 64, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FARSIGHT = UNIT_END + 0x01DC, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x01DE, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x01E0, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
PLAYER__FIELD_KNOWN_TITLES2 = UNIT_END + 0x01E2, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_KNOWN_CURRENCIES = UNIT_END + 0x01E4, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_XP = UNIT_END + 0x01E6, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x01E7, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x01E8, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x0368, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x0369, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_TRACK_CREATURES = UNIT_END + 0x036A, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_TRACK_RESOURCES = UNIT_END + 0x036B, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x036C, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x036D, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x036E, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_EXPERTISE = UNIT_END + 0x036F, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x0370, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x0371, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0372, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0373, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0374, // Size: 7, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_SHIELD_BLOCK = UNIT_END + 0x037B, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x037C, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x037D, // Size: 128, Type: BYTES, Flags: PRIVATE
|
||||
PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x03FD, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_COINAGE = UNIT_END + 0x03FE, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x03FF, // Size: 7, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x0406, // Size: 7, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x040D, // Size: 7, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x0414, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x0415, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x0416, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x0417, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x0418, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BYTES = UNIT_END + 0x0419, // Size: 1, Type: BYTES, Flags: PRIVATE
|
||||
PLAYER_AMMO_ID = UNIT_END + 0x041A, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_SELF_RES_SPELL = UNIT_END + 0x041B, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x041C, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x041D, // Size: 12, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x0429, // Size: 12, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_KILLS = UNIT_END + 0x0435, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x0436, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_LIFETIME_HONORABLE_KILLS = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BYTES2 = UNIT_END + 0x0439, // Size: 1, Type: 6, Flags: PRIVATE
|
||||
PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x043A, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x043B, // Size: 25, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x0454, // Size: 21, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x0469, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x046A, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x046B, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x046C, // Size: 25, Type: INT, Flags: PRIVATE
|
||||
PLAYER_RUNE_REGEN_1 = UNIT_END + 0x0485, // Size: 4, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x0489, // Size: 3, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x048C, // Size: 6, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0492, // Size: 6, Type: INT, Flags: PRIVATE
|
||||
PLAYER_GLYPHS_ENABLED = UNIT_END + 0x0498, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_PET_SPELL_POWER = UNIT_END + 0x0499, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_END = UNIT_END + 0x049A,
|
||||
};
|
||||
|
||||
enum EGameObjectFields
|
||||
{
|
||||
OBJECT_FIELD_CREATED_BY = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
GAMEOBJECT_DISPLAYID = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC
|
||||
GAMEOBJECT_DYNAMIC = OBJECT_END + 0x0008, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC
|
||||
GAMEOBJECT_FACTION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_LEVEL = OBJECT_END + 0x000A, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_BYTES_1 = OBJECT_END + 0x000B, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
GAMEOBJECT_END = OBJECT_END + 0x000C,
|
||||
};
|
||||
|
||||
enum EDynamicObjectFields
|
||||
{
|
||||
DYNAMICOBJECT_CASTER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
DYNAMICOBJECT_BYTES = OBJECT_END + 0x0002, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
DYNAMICOBJECT_SPELLID = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
DYNAMICOBJECT_RADIUS = OBJECT_END + 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
DYNAMICOBJECT_END = OBJECT_END + 0x0006,
|
||||
};
|
||||
|
||||
enum ECorpseFields
|
||||
{
|
||||
CORPSE_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
CORPSE_FIELD_PARTY = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
CORPSE_FIELD_DISPLAY_ID = OBJECT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
CORPSE_FIELD_ITEM = OBJECT_END + 0x0005, // Size: 19, Type: INT, Flags: PUBLIC
|
||||
CORPSE_FIELD_BYTES_1 = OBJECT_END + 0x0018, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
CORPSE_FIELD_BYTES_2 = OBJECT_END + 0x0019, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
CORPSE_FIELD_GUILD = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
CORPSE_FIELD_FLAGS = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
CORPSE_FIELD_DYNAMIC_FLAGS = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: DYNAMIC
|
||||
CORPSE_FIELD_PAD = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: NONE
|
||||
CORPSE_END = OBJECT_END + 0x001E,
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __UPDATEMASK_H
|
||||
#define __UPDATEMASK_H
|
||||
|
||||
#include "UpdateFields.h"
|
||||
#include "Errors.h"
|
||||
|
||||
class UpdateMask
|
||||
{
|
||||
public:
|
||||
UpdateMask() : mCount(0), mBlocks(0), mUpdateMask(0) { }
|
||||
UpdateMask(const UpdateMask& mask) : mUpdateMask(0) { *this = mask; }
|
||||
|
||||
~UpdateMask()
|
||||
{
|
||||
if (mUpdateMask)
|
||||
delete [] mUpdateMask;
|
||||
}
|
||||
|
||||
void SetBit (uint32 index)
|
||||
{
|
||||
((uint8 *)mUpdateMask)[ index >> 3 ] |= 1 << (index & 0x7);
|
||||
}
|
||||
|
||||
void UnsetBit (uint32 index)
|
||||
{
|
||||
((uint8 *)mUpdateMask)[ index >> 3 ] &= (0xff ^ (1 << (index & 0x7)));
|
||||
}
|
||||
|
||||
bool GetBit (uint32 index) const
|
||||
{
|
||||
return (((uint8 *)mUpdateMask)[ index >> 3 ] & (1 << (index & 0x7))) != 0;
|
||||
}
|
||||
|
||||
uint32 GetBlockCount() const { return mBlocks; }
|
||||
uint32 GetLength() const { return mBlocks << 2; }
|
||||
uint32 GetCount() const { return mCount; }
|
||||
uint8* GetMask() { return (uint8*)mUpdateMask; }
|
||||
|
||||
void SetCount (uint32 valuesCount)
|
||||
{
|
||||
if (mUpdateMask)
|
||||
delete [] mUpdateMask;
|
||||
|
||||
mCount = valuesCount;
|
||||
mBlocks = (valuesCount + 31) / 32;
|
||||
|
||||
mUpdateMask = new uint32[mBlocks];
|
||||
memset(mUpdateMask, 0, mBlocks << 2);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if (mUpdateMask)
|
||||
memset(mUpdateMask, 0, mBlocks << 2);
|
||||
}
|
||||
|
||||
UpdateMask& operator = (const UpdateMask& mask)
|
||||
{
|
||||
SetCount(mask.mCount);
|
||||
memcpy(mUpdateMask, mask.mUpdateMask, mBlocks << 2);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void operator &= (const UpdateMask& mask)
|
||||
{
|
||||
ASSERT(mask.mCount <= mCount);
|
||||
for (uint32 i = 0; i < mBlocks; ++i)
|
||||
mUpdateMask[i] &= mask.mUpdateMask[i];
|
||||
}
|
||||
|
||||
void operator |= (const UpdateMask& mask)
|
||||
{
|
||||
ASSERT(mask.mCount <= mCount);
|
||||
for (uint32 i = 0; i < mBlocks; ++i)
|
||||
mUpdateMask[i] |= mask.mUpdateMask[i];
|
||||
}
|
||||
|
||||
UpdateMask operator & (const UpdateMask& mask) const
|
||||
{
|
||||
ASSERT(mask.mCount <= mCount);
|
||||
|
||||
UpdateMask newmask;
|
||||
newmask = *this;
|
||||
newmask &= mask;
|
||||
|
||||
return newmask;
|
||||
}
|
||||
|
||||
UpdateMask operator | (const UpdateMask& mask) const
|
||||
{
|
||||
ASSERT(mask.mCount <= mCount);
|
||||
|
||||
UpdateMask newmask;
|
||||
newmask = *this;
|
||||
newmask |= mask;
|
||||
|
||||
return newmask;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 mCount;
|
||||
uint32 mBlocks;
|
||||
uint32 *mUpdateMask;
|
||||
};
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user