Core/Corpses: Fixed leaking corpses
Closes #15765 (cherry picked from commit bd16520ecc91d827abae7f0447cc292fe9e843e9)
This commit is contained in:
1 parent
8e7012f076
commit
20b4e6f03a
5 files changed
+41
-35
No files matched your search
@@ -61,7 +61,6 @@ void Corpse::RemoveFromWorld()
|
||||
|
||||
bool Corpse::Create(ObjectGuid::LowType guidlow, Map* map)
|
||||
{
|
||||
SetMap(map);
|
||||
Object::_Create(guidlow, 0, HighGuid::Corpse);
|
||||
return true;
|
||||
}
|
||||
@@ -79,16 +78,12 @@ bool Corpse::Create(ObjectGuid::LowType guidlow, Player* owner)
|
||||
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());
|
||||
|
||||
SetObjectScale(1.0f);
|
||||
SetGuidValue(CORPSE_FIELD_OWNER, owner->GetGUID());
|
||||
|
||||
_gridCoord = Trinity::ComputeGridCoord(GetPositionX(), GetPositionY());
|
||||
_cellCoord = Trinity::ComputeCellCoord(GetPositionX(), GetPositionY());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -123,20 +118,6 @@ void Corpse::SaveToDB()
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
}
|
||||
|
||||
void Corpse::DeleteBonesFromWorld()
|
||||
{
|
||||
ASSERT(GetType() == CORPSE_BONES);
|
||||
Corpse* corpse = ObjectAccessor::GetCorpse(*this, GetGUID());
|
||||
|
||||
if (!corpse)
|
||||
{
|
||||
TC_LOG_ERROR("entities.player", "Bones %u not found in world.", GetGUID().GetCounter());
|
||||
return;
|
||||
}
|
||||
|
||||
AddObjectToRemoveList();
|
||||
}
|
||||
|
||||
void Corpse::DeleteFromDB(SQLTransaction& trans)
|
||||
{
|
||||
DeleteFromDB(GetOwnerGUID(), trans);
|
||||
@@ -192,7 +173,7 @@ bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
|
||||
return false;
|
||||
}
|
||||
|
||||
_gridCoord = Trinity::ComputeGridCoord(GetPositionX(), GetPositionY());
|
||||
_cellCoord = Trinity::ComputeCellCoord(GetPositionX(), GetPositionY());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,6 @@ class Corpse : public WorldObject, public GridObject<Corpse>
|
||||
void SaveToDB();
|
||||
bool LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields);
|
||||
|
||||
void DeleteBonesFromWorld();
|
||||
void DeleteFromDB(SQLTransaction& trans);
|
||||
static void DeleteFromDB(ObjectGuid const& ownerGuid, SQLTransaction& trans);
|
||||
|
||||
@@ -71,8 +70,8 @@ class Corpse : public WorldObject, public GridObject<Corpse>
|
||||
void ResetGhostTime() { m_time = time(NULL); }
|
||||
CorpseType GetType() const { return m_type; }
|
||||
|
||||
GridCoord const& GetGridCoord() const { return _gridCoord; }
|
||||
void SetGridCoord(GridCoord const& gridCoord) { _gridCoord = gridCoord; }
|
||||
CellCoord const& GetCellCoord() const { return _cellCoord; }
|
||||
void SetCellCoord(CellCoord const& cellCoord) { _cellCoord = cellCoord; }
|
||||
|
||||
Loot loot; // remove insignia ONLY at BG
|
||||
Player* lootRecipient;
|
||||
@@ -83,6 +82,6 @@ class Corpse : public WorldObject, public GridObject<Corpse>
|
||||
private:
|
||||
CorpseType m_type;
|
||||
time_t m_time;
|
||||
GridCoord _gridCoord; // gride for corpse position for fast search
|
||||
CellCoord _cellCoord;
|
||||
};
|
||||
#endif
|
||||
@@ -5164,12 +5164,13 @@ Corpse* Player::CreateCorpse()
|
||||
}
|
||||
}
|
||||
|
||||
// register for player, but not show
|
||||
GetMap()->AddCorpse(corpse);
|
||||
|
||||
// we do not need to save corpses for BG/arenas
|
||||
if (!GetMap()->IsBattlegroundOrArena())
|
||||
corpse->SaveToDB();
|
||||
|
||||
// register for player, but not show
|
||||
GetMap()->AddCorpse(corpse);
|
||||
return corpse;
|
||||
}
|
||||
|
||||
|
||||
@@ -1601,6 +1601,13 @@ void Map::UnloadAll()
|
||||
|
||||
RemoveFromMap<Transport>(transport, true);
|
||||
}
|
||||
|
||||
for (auto& cellCorpsePair : _corpsesByCell)
|
||||
for (Corpse* corpse : cellCorpsePair.second)
|
||||
delete corpse;
|
||||
|
||||
_corpsesByCell.clear();
|
||||
_corpsesByPlayer.clear();
|
||||
}
|
||||
|
||||
// *****************************
|
||||
@@ -3575,14 +3582,16 @@ void Map::AddCorpse(Corpse* corpse)
|
||||
{
|
||||
corpse->SetMap(this);
|
||||
|
||||
CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
|
||||
_corpsesByCell[cellCoord.GetId()].insert(corpse);
|
||||
_corpsesByPlayer[corpse->GetOwnerGUID()] = corpse;
|
||||
_corpsesByCell[corpse->GetCellCoord().GetId()].insert(corpse);
|
||||
if (corpse->GetType() != CORPSE_BONES)
|
||||
_corpsesByPlayer[corpse->GetOwnerGUID()] = corpse;
|
||||
else
|
||||
_corpseBones.insert(corpse);
|
||||
}
|
||||
|
||||
void Map::RemoveCorpse(Corpse* corpse)
|
||||
{
|
||||
ASSERT(corpse && corpse->GetType() != CORPSE_BONES);
|
||||
ASSERT(corpse);
|
||||
|
||||
corpse->DestroyForNearbyPlayers();
|
||||
if (corpse->IsInGrid())
|
||||
@@ -3593,9 +3602,11 @@ void Map::RemoveCorpse(Corpse* corpse)
|
||||
corpse->ResetMap();
|
||||
}
|
||||
|
||||
CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
|
||||
_corpsesByCell[cellCoord.GetId()].erase(corpse);
|
||||
_corpsesByPlayer.erase(corpse->GetOwnerGUID());
|
||||
_corpsesByCell[corpse->GetCellCoord().GetId()].erase(corpse);
|
||||
if (corpse->GetType() != CORPSE_BONES)
|
||||
_corpsesByPlayer.erase(corpse->GetOwnerGUID());
|
||||
else
|
||||
_corpseBones.erase(corpse);
|
||||
}
|
||||
|
||||
Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*= false*/)
|
||||
@@ -3626,7 +3637,7 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*=
|
||||
for (uint8 i = OBJECT_FIELD_TYPE + 1; i < CORPSE_END; ++i) // don't overwrite guid and object type
|
||||
bones->SetUInt32Value(i, corpse->GetUInt32Value(i));
|
||||
|
||||
bones->SetGridCoord(corpse->GetGridCoord());
|
||||
bones->SetCellCoord(corpse->GetCellCoord());
|
||||
bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
|
||||
bones->SetPhaseMask(corpse->GetPhaseMask(), false);
|
||||
|
||||
@@ -3637,6 +3648,8 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*=
|
||||
if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i))
|
||||
bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0);
|
||||
|
||||
AddCorpse(bones);
|
||||
|
||||
// add bones in grid store if grid loaded where corpse placed
|
||||
AddToMap(bones);
|
||||
}
|
||||
@@ -3660,6 +3673,17 @@ void Map::RemoveOldCorpses()
|
||||
|
||||
for (ObjectGuid const& ownerGuid : corpses)
|
||||
ConvertCorpseToBones(ownerGuid);
|
||||
|
||||
std::vector<Corpse*> expiredBones;
|
||||
for (Corpse* bones : _corpseBones)
|
||||
if (bones->IsExpired(now))
|
||||
expiredBones.push_back(bones);
|
||||
|
||||
for (Corpse* bones : expiredBones)
|
||||
{
|
||||
RemoveCorpse(bones);
|
||||
delete bones;
|
||||
}
|
||||
}
|
||||
|
||||
void Map::SendZoneDynamicInfo(Player* player)
|
||||
|
||||
@@ -733,6 +733,7 @@ class Map : public GridRefManager<NGridType>
|
||||
GameObjectBySpawnIdContainer _gameobjectBySpawnIdStore;
|
||||
std::unordered_map<uint32/*cellId*/, std::unordered_set<Corpse*>> _corpsesByCell;
|
||||
std::unordered_map<ObjectGuid, Corpse*> _corpsesByPlayer;
|
||||
std::unordered_set<Corpse*> _corpseBones;
|
||||
|
||||
std::unordered_set<Object*> _updateObjects;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user