diff options
| author | Treeston <treeston.mmoc@gmail.com> | 2019-07-08 11:33:09 +0200 |
|---|---|---|
| committer | Treeston <treeston.mmoc@gmail.com> | 2019-07-08 11:56:41 +0200 |
| commit | 84b7b2e08ea55575cbe62d795383d4a5341ffd4d (patch) | |
| tree | d0ce35d87614d0a45bc7747631e84949bf68d6c5 /src/server/game/Entities/GameObject | |
| parent | ec1a77bca20487f86765620485db9b13bb03aee8 (diff) | |
Entities/Unit: Nuke Map::ForceRespawn from orbit, with the following implications:
- .npc respawn no longer causes stupid things to happen (Fixes #23014)
- ::DeleteFromDB methods on Creature and GameObject rewritten to be as sensible as such a colossally stupid method can ever be. They're static now.
- .npc delete and .gobj delete ported to new argument handling, and rewritten as per above. They can no longer crash the server when used in instances, too. Yay for that.
- Adjusted various dusty cobwebbed hacks around the core (why does waypoint visualization use permanent spawns *shudder*) to still work too.
Diffstat (limited to 'src/server/game/Entities/GameObject')
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 44 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 2 |
2 files changed, 34 insertions, 12 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 2212267b179..40a56400e19 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -30,6 +30,8 @@ #include "GroupMgr.h" #include "Log.h" #include "LootMgr.h" +#include "Map.h" +#include "MapManager.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "OutdoorPvPMgr.h" @@ -1111,51 +1113,71 @@ bool GameObject::LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap return true; } -void GameObject::DeleteFromDB() +/*static*/ bool GameObject::DeleteFromDB(ObjectGuid::LowType spawnId) { - GetMap()->RemoveRespawnTime(SPAWN_TYPE_GAMEOBJECT, m_spawnId); - sObjectMgr->DeleteGameObjectData(m_spawnId); + GameObjectData const* data = sObjectMgr->GetGameObjectData(spawnId); + if (!data) + return false; SQLTransaction trans = WorldDatabase.BeginTransaction(); + sMapMgr->DoForAllMapsWithMapId(data->spawnPoint.GetMapId(), + [spawnId, trans](Map* map) -> void + { + // despawn all active objects, and remove their respawns + std::vector<GameObject*> toUnload; + for (auto const& pair : Trinity::Containers::MapEqualRange(map->GetGameObjectBySpawnIdStore(), spawnId)) + toUnload.push_back(pair.second); + for (GameObject* obj : toUnload) + map->AddObjectToRemoveList(obj); + map->RemoveRespawnTime(SPAWN_TYPE_GAMEOBJECT, spawnId, false, trans); + } + ); + + // delete data from memory + sObjectMgr->DeleteGameObjectData(spawnId); + + // ... and the database PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT); - stmt->setUInt32(0, m_spawnId); + stmt->setUInt32(0, spawnId); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_SPAWNGROUP_MEMBER); stmt->setUInt8(0, uint8(SPAWN_TYPE_GAMEOBJECT)); - stmt->setUInt32(1, m_spawnId); + stmt->setUInt32(1, spawnId); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_EVENT_GAMEOBJECT); - stmt->setUInt32(0, m_spawnId); + stmt->setUInt32(0, spawnId); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN); - stmt->setUInt32(0, m_spawnId); + stmt->setUInt32(0, spawnId); stmt->setUInt32(1, LINKED_RESPAWN_GO_TO_GO); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN); - stmt->setUInt32(0, m_spawnId); + stmt->setUInt32(0, spawnId); stmt->setUInt32(1, LINKED_RESPAWN_GO_TO_CREATURE); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN_MASTER); - stmt->setUInt32(0, m_spawnId); + stmt->setUInt32(0, spawnId); stmt->setUInt32(1, LINKED_RESPAWN_GO_TO_GO); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN_MASTER); - stmt->setUInt32(0, m_spawnId); + stmt->setUInt32(0, spawnId); stmt->setUInt32(1, LINKED_RESPAWN_CREATURE_TO_GO); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT_ADDON); - stmt->setUInt32(0, m_spawnId); + stmt->setUInt32(0, spawnId); trans->Append(stmt); WorldDatabase.CommitTransaction(trans); + + return true; } /*********************************************************/ diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index f47611cee9f..7abf6223cf5 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -118,7 +118,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void SaveToDB(); void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask); bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap, bool = true); // arg4 is unused, only present to match the signature on Creature - void DeleteFromDB(); + static bool DeleteFromDB(ObjectGuid::LowType spawnId); void SetOwnerGUID(ObjectGuid owner) { |
