aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp63
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.h1
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp10
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h4
4 files changed, 37 insertions, 41 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index a894ee16c2d..9e514ad34bb 100755
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -91,27 +91,31 @@ void GameObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
RemoveFromWorld();
if (m_uint32Values) // field array can be not exist if GameOBject not loaded
- {
- // Possible crash at access to deleted GO in Unit::m_gameobj
- if (uint64 owner_guid = GetOwnerGUID())
- {
- Unit* owner = ObjectAccessor::GetUnit(*this, owner_guid);
+ RemoveFromOwner();
+}
- if (owner)
- owner->RemoveGameObject(this, false);
- else
- {
- const char * ownerType = "creature";
- if (IS_PLAYER_GUID(owner_guid))
- ownerType = "player";
- else if (IS_PET_GUID(owner_guid))
- 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.",
- GetGUIDLow(), GetGOInfo()->entry, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType);
- }
- }
+void GameObject::RemoveFromOwner()
+{
+ uint64 ownerGUID = GetOwnerGUID();
+ if (!ownerGUID)
+ return;
+
+ if (Unit* owner = ObjectAccessor::GetUnit(*this, ownerGUID))
+ {
+ owner->RemoveGameObject(this, false);
+ ASSERT(!GetOwnerGUID());
+ return;
}
+
+ const char * ownerType = "creature";
+ if (IS_PLAYER_GUID(ownerGUID))
+ ownerType = "player";
+ else if (IS_PET_GUID(ownerGUID))
+ ownerType = "pet";
+
+ 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(ownerGUID), ownerType);
+ SetOwnerGUID(0);
}
void GameObject::AddToWorld()
@@ -135,14 +139,7 @@ void GameObject::RemoveFromWorld()
if (m_zoneScript)
m_zoneScript->OnGameObjectRemove(this);
- // Possible crash at access to deleted GO in Unit::m_gameobj
- 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));
- }
+ RemoveFromOwner();
WorldObject::RemoveFromWorld();
sObjectAccessor->RemoveObject(this);
}
@@ -601,15 +598,8 @@ void GameObject::AddUniqueUse(Player* player)
void GameObject::Delete()
{
SetLootState(GO_NOT_READY);
- if (GetOwnerGUID())
- {
- if (Unit* owner = GetOwner())
- owner->RemoveGameObject(this, false);
- else //! Owner not in world anymore
- SetOwnerGUID(0);
- }
+ RemoveFromOwner();
- ASSERT (!GetOwnerGUID());
SendObjectDeSpawnAnim(GetGUID());
SetGoState(GO_STATE_READY);
@@ -1284,8 +1274,9 @@ void GameObject::Use(Unit* user)
{
player->UpdateFishingSkill();
+ //TODO: I do not understand this hack. Need some explanation.
// prevent removing GO at spell cancel
- player->RemoveGameObject(this, false);
+ RemoveFromOwner();
SetOwnerGUID(player->GetGUID());
//TODO: find reasonable value for fishing hole search
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 13b410d7373..9167b40d285 100755
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -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
private:
+ void RemoveFromOwner();
void SwitchDoorOrButton(bool activate, bool alternative = false);
//! Object distance/size - overridden from Object::_IsWithinDist. Needs to take in account proper GO size.
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 7c3fecb83e1..a01848a7228 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -181,7 +181,8 @@ m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE), m_HostileRefManager(this)
for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
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();
@@ -4661,7 +4662,7 @@ void Unit::RemoveGameObject(GameObject* gameObj, bool del)
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())
{
@@ -4721,12 +4722,13 @@ void Unit::RemoveGameObject(uint32 spellid, bool del)
void Unit::RemoveAllGameObjects()
{
// 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)->SetRespawnTime(0);
(*i)->Delete();
- i = m_gameObj.erase(i);
+ m_gameObj.erase(i);
}
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 7d485a049d7..bbfe565e342 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1208,6 +1208,8 @@ enum ReactiveType
#define SUMMON_SLOT_QUEST 6
#define MAX_SUMMON_SLOT 7
+#define MAX_GAMEOBJECT_SLOT 4
+
enum PlayerTotemType
{
SUMMON_TYPE_TOTEM_FIRE = 63,
@@ -1891,7 +1893,7 @@ class Unit : public WorldObject
uint32 m_addDmgOnce;
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)); }
void SetShapeshiftForm(ShapeshiftForm form)