Clean up summon/remove gameobject code.
This commit is contained in:
@@ -91,27 +91,31 @@ void GameObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
|
|||||||
RemoveFromWorld();
|
RemoveFromWorld();
|
||||||
|
|
||||||
if (m_uint32Values) // field array can be not exist if GameOBject not loaded
|
if (m_uint32Values) // field array can be not exist if GameOBject not loaded
|
||||||
{
|
RemoveFromOwner();
|
||||||
// Possible crash at access to deleted GO in Unit::m_gameobj
|
}
|
||||||
if (uint64 owner_guid = GetOwnerGUID())
|
|
||||||
{
|
|
||||||
Unit* owner = ObjectAccessor::GetUnit(*this, owner_guid);
|
|
||||||
|
|
||||||
if (owner)
|
void GameObject::RemoveFromOwner()
|
||||||
owner->RemoveGameObject(this, false);
|
{
|
||||||
else
|
uint64 ownerGUID = GetOwnerGUID();
|
||||||
|
if (!ownerGUID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Unit* owner = ObjectAccessor::GetUnit(*this, ownerGUID))
|
||||||
{
|
{
|
||||||
|
owner->RemoveGameObject(this, false);
|
||||||
|
ASSERT(!GetOwnerGUID());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char * ownerType = "creature";
|
const char * ownerType = "creature";
|
||||||
if (IS_PLAYER_GUID(owner_guid))
|
if (IS_PLAYER_GUID(ownerGUID))
|
||||||
ownerType = "player";
|
ownerType = "player";
|
||||||
else if (IS_PET_GUID(owner_guid))
|
else if (IS_PET_GUID(ownerGUID))
|
||||||
ownerType = "pet";
|
ownerType = "pet";
|
||||||
|
|
||||||
sLog->outError("Delete GameObject (GUID: %u Entry: %u SpellId %u LinkedGO %u) that lost references to owner (GUID %u Type '%s') GO list. Crash possible later.",
|
sLog->outCrash("Delete GameObject (GUID: %u Entry: %u SpellId %u LinkedGO %u) that lost references to owner (GUID %u Type '%s') GO list. Crash possible later.",
|
||||||
GetGUIDLow(), GetGOInfo()->entry, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType);
|
GetGUIDLow(), GetGOInfo()->entry, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(ownerGUID), ownerType);
|
||||||
}
|
SetOwnerGUID(0);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameObject::AddToWorld()
|
void GameObject::AddToWorld()
|
||||||
@@ -135,14 +139,7 @@ void GameObject::RemoveFromWorld()
|
|||||||
if (m_zoneScript)
|
if (m_zoneScript)
|
||||||
m_zoneScript->OnGameObjectRemove(this);
|
m_zoneScript->OnGameObjectRemove(this);
|
||||||
|
|
||||||
// Possible crash at access to deleted GO in Unit::m_gameobj
|
RemoveFromOwner();
|
||||||
if (uint64 owner_guid = GetOwnerGUID())
|
|
||||||
{
|
|
||||||
if (Unit* owner = GetOwner())
|
|
||||||
owner->RemoveGameObject(this, false);
|
|
||||||
else
|
|
||||||
sLog->outError("Delete GameObject (GUID: %u Entry: %u, Name: %s) that have references in not found creature %u GO list. Crash possible later.", GetGUIDLow(), GetGOInfo()->entry, GetGOInfo()->name.c_str(), GUID_LOPART(owner_guid));
|
|
||||||
}
|
|
||||||
WorldObject::RemoveFromWorld();
|
WorldObject::RemoveFromWorld();
|
||||||
sObjectAccessor->RemoveObject(this);
|
sObjectAccessor->RemoveObject(this);
|
||||||
}
|
}
|
||||||
@@ -601,15 +598,8 @@ void GameObject::AddUniqueUse(Player* player)
|
|||||||
void GameObject::Delete()
|
void GameObject::Delete()
|
||||||
{
|
{
|
||||||
SetLootState(GO_NOT_READY);
|
SetLootState(GO_NOT_READY);
|
||||||
if (GetOwnerGUID())
|
RemoveFromOwner();
|
||||||
{
|
|
||||||
if (Unit* owner = GetOwner())
|
|
||||||
owner->RemoveGameObject(this, false);
|
|
||||||
else //! Owner not in world anymore
|
|
||||||
SetOwnerGUID(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT (!GetOwnerGUID());
|
|
||||||
SendObjectDeSpawnAnim(GetGUID());
|
SendObjectDeSpawnAnim(GetGUID());
|
||||||
|
|
||||||
SetGoState(GO_STATE_READY);
|
SetGoState(GO_STATE_READY);
|
||||||
@@ -1284,8 +1274,9 @@ void GameObject::Use(Unit* user)
|
|||||||
{
|
{
|
||||||
player->UpdateFishingSkill();
|
player->UpdateFishingSkill();
|
||||||
|
|
||||||
|
//TODO: I do not understand this hack. Need some explanation.
|
||||||
// prevent removing GO at spell cancel
|
// prevent removing GO at spell cancel
|
||||||
player->RemoveGameObject(this, false);
|
RemoveFromOwner();
|
||||||
SetOwnerGUID(player->GetGUID());
|
SetOwnerGUID(player->GetGUID());
|
||||||
|
|
||||||
//TODO: find reasonable value for fishing hole search
|
//TODO: find reasonable value for fishing hole search
|
||||||
|
|||||||
@@ -815,6 +815,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>
|
|||||||
|
|
||||||
uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable
|
uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable
|
||||||
private:
|
private:
|
||||||
|
void RemoveFromOwner();
|
||||||
void SwitchDoorOrButton(bool activate, bool alternative = false);
|
void SwitchDoorOrButton(bool activate, bool alternative = false);
|
||||||
|
|
||||||
//! Object distance/size - overridden from Object::_IsWithinDist. Needs to take in account proper GO size.
|
//! Object distance/size - overridden from Object::_IsWithinDist. Needs to take in account proper GO size.
|
||||||
|
|||||||
@@ -181,7 +181,8 @@ m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE), m_HostileRefManager(this)
|
|||||||
for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
|
for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
|
||||||
m_SummonSlot[i] = 0;
|
m_SummonSlot[i] = 0;
|
||||||
|
|
||||||
m_ObjectSlot[0] = m_ObjectSlot[1] = m_ObjectSlot[2] = m_ObjectSlot[3] = 0;
|
for (uint8 i = 0; i < MAX_GAMEOBJECT_SLOT; ++i)
|
||||||
|
m_ObjectSlot[i] = 0;
|
||||||
|
|
||||||
m_auraUpdateIterator = m_ownedAuras.end();
|
m_auraUpdateIterator = m_ownedAuras.end();
|
||||||
|
|
||||||
@@ -4661,7 +4662,7 @@ void Unit::RemoveGameObject(GameObject* gameObj, bool del)
|
|||||||
|
|
||||||
gameObj->SetOwnerGUID(0);
|
gameObj->SetOwnerGUID(0);
|
||||||
|
|
||||||
for (uint32 i = 0; i < 4; ++i)
|
for (uint8 i = 0; i < MAX_GAMEOBJECT_SLOT; ++i)
|
||||||
{
|
{
|
||||||
if (m_ObjectSlot[i] == gameObj->GetGUID())
|
if (m_ObjectSlot[i] == gameObj->GetGUID())
|
||||||
{
|
{
|
||||||
@@ -4721,12 +4722,13 @@ void Unit::RemoveGameObject(uint32 spellid, bool del)
|
|||||||
void Unit::RemoveAllGameObjects()
|
void Unit::RemoveAllGameObjects()
|
||||||
{
|
{
|
||||||
// remove references to unit
|
// remove references to unit
|
||||||
for (GameObjectList::iterator i = m_gameObj.begin(); i != m_gameObj.end();)
|
while (!m_gameObj.empty())
|
||||||
{
|
{
|
||||||
|
GameObjectList::iterator i = m_gameObj.begin();
|
||||||
(*i)->SetOwnerGUID(0);
|
(*i)->SetOwnerGUID(0);
|
||||||
(*i)->SetRespawnTime(0);
|
(*i)->SetRespawnTime(0);
|
||||||
(*i)->Delete();
|
(*i)->Delete();
|
||||||
i = m_gameObj.erase(i);
|
m_gameObj.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1208,6 +1208,8 @@ enum ReactiveType
|
|||||||
#define SUMMON_SLOT_QUEST 6
|
#define SUMMON_SLOT_QUEST 6
|
||||||
#define MAX_SUMMON_SLOT 7
|
#define MAX_SUMMON_SLOT 7
|
||||||
|
|
||||||
|
#define MAX_GAMEOBJECT_SLOT 4
|
||||||
|
|
||||||
enum PlayerTotemType
|
enum PlayerTotemType
|
||||||
{
|
{
|
||||||
SUMMON_TYPE_TOTEM_FIRE = 63,
|
SUMMON_TYPE_TOTEM_FIRE = 63,
|
||||||
@@ -1891,7 +1893,7 @@ class Unit : public WorldObject
|
|||||||
|
|
||||||
uint32 m_addDmgOnce;
|
uint32 m_addDmgOnce;
|
||||||
uint64 m_SummonSlot[MAX_SUMMON_SLOT];
|
uint64 m_SummonSlot[MAX_SUMMON_SLOT];
|
||||||
uint64 m_ObjectSlot[4];
|
uint64 m_ObjectSlot[MAX_GAMEOBJECT_SLOT];
|
||||||
|
|
||||||
ShapeshiftForm GetShapeshiftForm() const { return ShapeshiftForm(GetByteValue(UNIT_FIELD_BYTES_2, 3)); }
|
ShapeshiftForm GetShapeshiftForm() const { return ShapeshiftForm(GetByteValue(UNIT_FIELD_BYTES_2, 3)); }
|
||||||
void SetShapeshiftForm(ShapeshiftForm form)
|
void SetShapeshiftForm(ShapeshiftForm form)
|
||||||
|
|||||||
Reference in New Issue
Block a user