aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-10-28 21:43:44 +0100
committerShauren <shauren.trinity@gmail.com>2015-10-28 21:43:44 +0100
commitbd16520ecc91d827abae7f0447cc292fe9e843e9 (patch)
tree2fbb8ec8cd8234dda8dea2bfeaf9763989b2f7c3
parent9617da72492953fcbbc6f100079c3241e0c3a096 (diff)
Core/Corpses: Fixed leaking bones
Ref #15765
-rw-r--r--src/server/game/Entities/Corpse/Corpse.cpp23
-rw-r--r--src/server/game/Entities/Corpse/Corpse.h7
-rw-r--r--src/server/game/Entities/Player/Player.cpp5
-rw-r--r--src/server/game/Maps/Map.cpp42
-rw-r--r--src/server/game/Maps/Map.h1
5 files changed, 42 insertions, 36 deletions
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index 4122c3a61c2..3ed66a71cf4 100644
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -61,7 +61,6 @@ void Corpse::RemoveFromWorld()
bool Corpse::Create(ObjectGuid::LowType guidlow, Map* map)
{
- SetMap(map);
Object::_Create(ObjectGuid::Create<HighGuid::Corpse>(map->GetId(), 0, guidlow));
return true;
}
@@ -79,17 +78,13 @@ 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());
-
Object::_Create(ObjectGuid::Create<HighGuid::Corpse>(GetMapId(), 0, guidlow));
SetPhaseMask(owner->GetPhaseMask(), false);
SetObjectScale(1.0f);
SetGuidValue(CORPSE_FIELD_OWNER, owner->GetGUID());
- _gridCoord = Trinity::ComputeGridCoord(GetPositionX(), GetPositionY());
+ _cellCoord = Trinity::ComputeCellCoord(GetPositionX(), GetPositionY());
CopyPhaseFrom(owner);
@@ -133,20 +128,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 %s not found in world.", GetGUID().ToString().c_str());
- return;
- }
-
- AddObjectToRemoveList();
-}
-
void Corpse::DeleteFromDB(SQLTransaction& trans)
{
DeleteFromDB(GetOwnerGUID(), trans);
@@ -201,7 +182,7 @@ bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
return false;
}
- _gridCoord = Trinity::ComputeGridCoord(GetPositionX(), GetPositionY());
+ _cellCoord = Trinity::ComputeCellCoord(GetPositionX(), GetPositionY());
return true;
}
diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h
index be2cb435ac9..c135548bee3 100644
--- a/src/server/game/Entities/Corpse/Corpse.h
+++ b/src/server/game/Entities/Corpse/Corpse.h
@@ -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
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 21b7b4b84a9..ab2d4fbdbd0 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -4754,12 +4754,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;
}
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 85cc87eaa6e..30925fbe139 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -1612,6 +1612,13 @@ void Map::UnloadAll()
RemoveFromMap<Transport>(transport, true);
}
+
+ for (auto& cellCorpsePair : _corpsesByCell)
+ for (Corpse* corpse : cellCorpsePair.second)
+ delete corpse;
+
+ _corpsesByCell.clear();
+ _corpsesByPlayer.clear();
}
// *****************************
@@ -3659,14 +3666,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())
@@ -3677,9 +3686,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*/)
@@ -3710,12 +3721,12 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*=
for (uint8 i = OBJECT_FIELD_GUID + 4; i < CORPSE_END; ++i) // don't overwrite guid
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->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
bones->SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Empty);
- bones->SetGuidValue(OBJECT_FIELD_DATA, corpse->GetGuidValue(OBJECT_FIELD_DATA));
+ bones->SetGuidValue(OBJECT_FIELD_DATA, ObjectGuid::Empty);
for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i))
@@ -3723,6 +3734,8 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*=
bones->CopyPhaseFrom(corpse);
+ AddCorpse(bones);
+
// add bones in grid store if grid loaded where corpse placed
AddToMap(bones);
}
@@ -3746,6 +3759,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)
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 596a753ad34..ec8f789980c 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -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;
};