diff --git a/Source/Game/Chat/Commands/GameObjectCommands.cs b/Source/Game/Chat/Commands/GameObjectCommands.cs index 83e59dd60..b5baa9a46 100644 --- a/Source/Game/Chat/Commands/GameObjectCommands.cs +++ b/Source/Game/Chat/Commands/GameObjectCommands.cs @@ -69,39 +69,35 @@ namespace Game.Chat if (string.IsNullOrEmpty(id)) return false; - if (!ulong.TryParse(id, out ulong guidLow) || guidLow == 0) + if (!ulong.TryParse(id, out ulong spawnId) || spawnId == 0) return false; - Player player = handler.GetSession().GetPlayer(); - // force respawn to make sure we find something - player.GetMap().ForceRespawn(SpawnObjectType.GameObject, guidLow); - GameObject obj = handler.GetObjectFromPlayerMapByDbGuid(guidLow); - if (!obj) + GameObject obj = handler.GetObjectFromPlayerMapByDbGuid(spawnId); + if (obj != null) { - handler.SendSysMessage(CypherStrings.CommandObjnotfound, guidLow); - return false; - } - - ObjectGuid ownerGuid = obj.GetOwnerGUID(); - if (!ownerGuid.IsEmpty()) - { - Unit owner = Global.ObjAccessor.GetUnit(player, ownerGuid); - if (!owner || !ownerGuid.IsPlayer()) + Player player = handler.GetSession().GetPlayer(); + ObjectGuid ownerGuid = obj.GetOwnerGUID(); + if (!ownerGuid.IsEmpty()) { - handler.SendSysMessage(CypherStrings.CommandDelobjrefercreature, ownerGuid.ToString(), obj.GetGUID().ToString()); - return false; - } + Unit owner = Global.ObjAccessor.GetUnit(player, ownerGuid); + if (!owner || !ownerGuid.IsPlayer()) + { + handler.SendSysMessage(CypherStrings.CommandDelobjrefercreature, ownerGuid.ToString(), obj.GetGUID().ToString()); + return false; + } - owner.RemoveGameObject(obj, false); + owner.RemoveGameObject(obj, false); + } } - obj.SetRespawnTime(0); // not save respawn time - obj.Delete(); - obj.DeleteFromDB(); + if (GameObject.DeleteFromDB(spawnId)) + { + handler.SendSysMessage(CypherStrings.CommandDelobjmessage, spawnId); + return true; + } - handler.SendSysMessage(CypherStrings.CommandDelobjmessage, obj.GetGUID().ToString()); - - return true; + handler.SendSysMessage(CypherStrings.CommandObjnotfound, obj.GetGUID().ToString()); + return false; } [Command("despawngroup", RBACPermissions.CommandGobjectDespawngroup)] diff --git a/Source/Game/Chat/Commands/NPCCommands.cs b/Source/Game/Chat/Commands/NPCCommands.cs index 9774d84d3..b41d83137 100644 --- a/Source/Game/Chat/Commands/NPCCommands.cs +++ b/Source/Game/Chat/Commands/NPCCommands.cs @@ -869,7 +869,7 @@ namespace Game.Chat [Command("", RBACPermissions.CommandNpcDelete)] static bool HandleNpcDeleteCommand(StringArguments args, CommandHandler handler) { - Creature creature; + ulong spawnId; if (!args.Empty()) { @@ -881,34 +881,36 @@ namespace Game.Chat if (!ulong.TryParse(cId, out ulong guidLow) || guidLow == 0) return false; - // force respawn to make sure we find something - handler.GetSession().GetPlayer().GetMap().ForceRespawn(SpawnObjectType.Creature, guidLow); - // then try to find it - creature = handler.GetCreatureFromPlayerMapByDbGuid(guidLow); + spawnId = guidLow; } else - creature = handler.GetSelectedCreature(); - - if (!creature || creature.IsPet() || creature.IsTotem()) { - handler.SendSysMessage(CypherStrings.SelectCreature); - return false; + Creature creature = handler.GetSelectedCreature(); + + if (!creature || creature.IsPet() || creature.IsTotem()) + { + handler.SendSysMessage(CypherStrings.SelectCreature); + return false; + } + + TempSummon summon = creature.ToTempSummon(); + if (summon != null) + { + summon.UnSummon(); + handler.SendSysMessage(CypherStrings.CommandDelcreatmessage); + return true; + } + spawnId = creature.GetSpawnId(); } - TempSummon summon = creature.ToTempSummon(); - if (summon != null) - summon.UnSummon(); - else + if (Creature.DeleteFromDB(spawnId)) { - // Delete the creature - creature.CombatStop(); - creature.DeleteFromDB(); - creature.AddObjectToRemoveList(); + handler.SendSysMessage(CypherStrings.CommandDelcreatmessage); + return true; } - handler.SendSysMessage(CypherStrings.CommandDelcreatmessage); - - return true; + handler.SendSysMessage(CypherStrings.CommandCreatguidnotfound, spawnId); + return false; } [Command("item", RBACPermissions.CommandNpcDeleteItem)] diff --git a/Source/Game/Chat/Commands/WPCommands.cs b/Source/Game/Chat/Commands/WPCommands.cs index 1848d49ad..ac104f3ac 100644 --- a/Source/Game/Chat/Commands/WPCommands.cs +++ b/Source/Game/Chat/Commands/WPCommands.cs @@ -512,21 +512,27 @@ namespace Game.Chat.Commands { handler.SendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff{0}|r", pathid); - target.DeleteFromDB(); - target.AddObjectToRemoveList(); + if (Creature.DeleteFromDB(target.GetSpawnId())) + { - stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_WAYPOINT_DATA); - stmt.AddValue(0, pathid); - stmt.AddValue(1, point); - DB.World.Execute(stmt); + stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_WAYPOINT_DATA); + stmt.AddValue(0, pathid); + stmt.AddValue(1, point); + DB.World.Execute(stmt); - stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_WAYPOINT_DATA_POINT); - stmt.AddValue(0, pathid); - stmt.AddValue(1, point); - DB.World.Execute(stmt); + stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_WAYPOINT_DATA_POINT); + stmt.AddValue(0, pathid); + stmt.AddValue(1, point); + DB.World.Execute(stmt); - handler.SendSysMessage(CypherStrings.WaypointRemoved); - return true; + handler.SendSysMessage(CypherStrings.WaypointRemoved); + return true; + } + else + { + handler.SendSysMessage(CypherStrings.WaypointNotremoved); + return false; + } } // del if (show == "move") @@ -538,8 +544,11 @@ namespace Game.Chat.Commands // What to do: // Move the visual spawnpoint // Respawn the owner of the waypoints - target.DeleteFromDB(); - target.AddObjectToRemoveList(); + if (!Creature.DeleteFromDB(target.GetSpawnId())) + { + handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, 1); + return false; + } // re-create Creature creature = Creature.CreateCreature(1, map, chr.GetPosition()); @@ -721,21 +730,10 @@ namespace Game.Chat.Commands { ulong wpguid = result2.Read(0); - Creature creature = handler.GetCreatureFromPlayerMapByDbGuid(wpguid); - if (!creature) + if (!Creature.DeleteFromDB(wpguid)) { handler.SendSysMessage(CypherStrings.WaypointNotremoved, wpguid); hasError = true; - - stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_CREATURE); - stmt.AddValue(0, wpguid); - DB.World.Execute(stmt); - } - else - { - creature.CombatStop(); - creature.DeleteFromDB(); - creature.AddObjectToRemoveList(); } } @@ -931,21 +929,10 @@ namespace Game.Chat.Commands { ulong lowguid = result.Read(0); - Creature creature = handler.GetCreatureFromPlayerMapByDbGuid(lowguid); - if (!creature) + if (!Creature.DeleteFromDB(lowguid)) { handler.SendSysMessage(CypherStrings.WaypointNotremoved, lowguid); hasError = true; - - stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_CREATURE); - stmt.AddValue(0, lowguid); - DB.World.Execute(stmt); - } - else - { - creature.CombatStop(); - creature.DeleteFromDB(); - creature.AddObjectToRemoveList(); } } while (result.NextRow()); diff --git a/Source/Game/Entities/Creature/Creature.cs b/Source/Game/Entities/Creature/Creature.cs index 30954dfa0..b0a941399 100644 --- a/Source/Game/Entities/Creature/Creature.cs +++ b/Source/Game/Entities/Creature/Creature.cs @@ -1607,66 +1607,79 @@ namespace Game.Entities return false; } - public void DeleteFromDB() + public static bool DeleteFromDB(ulong spawnId) { - if (m_spawnId == 0) - { - Log.outError(LogFilter.Unit, "Trying to delete not saved {0}", GetGUID().ToString(), GetEntry()); - return; - } - - GetMap().RemoveRespawnTime(SpawnObjectType.Creature, m_spawnId); - Global.ObjectMgr.DeleteCreatureData(m_spawnId); + CreatureData data = Global.ObjectMgr.GetCreatureData(spawnId); + if (data == null) + return false; SQLTransaction trans = new(); + Global.MapMgr.DoForAllMapsWithMapId(data.spawnPoint.GetMapId(), map => + { + // despawn all active creatures, and remove their respawns + List toUnload = new(); + foreach (var creature in map.GetCreatureBySpawnIdStore().LookupByKey(spawnId)) + toUnload.Add(creature); + + foreach (Creature creature in toUnload) + map.AddObjectToRemoveList(creature); + + map.RemoveRespawnTime(SpawnObjectType.Creature, spawnId, false, trans); + }); + + // delete data from memory ... + Global.ObjectMgr.DeleteCreatureData(spawnId); + + DB.Characters.CommitTransaction(trans); + + // ... and the database + trans = new(); + PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_CREATURE); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_SPAWNGROUP_MEMBER); stmt.AddValue(0, (byte)SpawnObjectType.Creature); - stmt.AddValue(1, m_spawnId); + stmt.AddValue(1, spawnId); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_CREATURE_ADDON); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_GAME_EVENT_CREATURE); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_GAME_EVENT_MODEL_EQUIP); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_LINKED_RESPAWN); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); stmt.AddValue(1, (uint)CreatureLinkedRespawnType.CreatureToCreature); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_LINKED_RESPAWN); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); stmt.AddValue(1, (uint)CreatureLinkedRespawnType.CreatureToGO); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_LINKED_RESPAWN_MASTER); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); stmt.AddValue(1, (uint)CreatureLinkedRespawnType.CreatureToCreature); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_LINKED_RESPAWN_MASTER); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); stmt.AddValue(1, (uint)CreatureLinkedRespawnType.GOToCreature); trans.Append(stmt); DB.World.CommitTransaction(trans); - // then delete any active instances of the creature - var spawnMap = GetMap().GetCreatureBySpawnIdStore().LookupByKey(m_spawnId); - foreach (var creature in spawnMap.ToList()) - creature.AddObjectToRemoveList(); + return true; } public override bool IsInvisibleDueToDespawn() diff --git a/Source/Game/Entities/GameObject/GameObject.cs b/Source/Game/Entities/GameObject/GameObject.cs index e25be58ed..ba261eed4 100644 --- a/Source/Game/Entities/GameObject/GameObject.cs +++ b/Source/Game/Entities/GameObject/GameObject.cs @@ -1155,46 +1155,68 @@ namespace Game.Entities return true; } - public void DeleteFromDB() + public static bool DeleteFromDB(ulong spawnId) { - GetMap().RemoveRespawnTime(SpawnObjectType.GameObject, m_spawnId); - Global.ObjectMgr.DeleteGameObjectData(m_spawnId); + GameObjectData data = Global.ObjectMgr.GetGameObjectData(spawnId); + if (data == null) + return false; SQLTransaction trans = new(); + Global.MapMgr.DoForAllMapsWithMapId(data.spawnPoint.GetMapId(), map => + { + // despawn all active objects, and remove their respawns + List toUnload = new(); + foreach (var creature in map.GetGameObjectBySpawnIdStore().LookupByKey(spawnId)) + toUnload.Add(creature); + + foreach (GameObject obj in toUnload) + map.AddObjectToRemoveList(obj); + + map.RemoveRespawnTime(SpawnObjectType.GameObject, spawnId, false, trans); + }); + + // delete data from memory + Global.ObjectMgr.DeleteGameObjectData(spawnId); + + trans = new(); + + // ... and the database PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_GAMEOBJECT); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_EVENT_GAMEOBJECT); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_LINKED_RESPAWN); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); stmt.AddValue(1, (uint)CreatureLinkedRespawnType.GOToGO); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_LINKED_RESPAWN); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); stmt.AddValue(1, (uint)CreatureLinkedRespawnType.GOToCreature); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_LINKED_RESPAWN_MASTER); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); stmt.AddValue(1, (uint)CreatureLinkedRespawnType.GOToGO); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_LINKED_RESPAWN_MASTER); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); stmt.AddValue(1, (uint)CreatureLinkedRespawnType.CreatureToGO); trans.Append(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_GAMEOBJECT_ADDON); - stmt.AddValue(0, m_spawnId); + stmt.AddValue(0, spawnId); trans.Append(stmt); DB.World.CommitTransaction(trans); + + return true; } public override bool HasQuest(uint quest_id) diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index 3cc888eb7..297cdc284 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -2443,9 +2443,9 @@ namespace Game.Maps } } - void Respawn(RespawnInfo info, bool force = false, SQLTransaction dbTrans = null) + void Respawn(RespawnInfo info, SQLTransaction dbTrans = null) { - if (!force && !CheckRespawn(info)) + if (!CheckRespawn(info)) { if (info.respawnTime != 0) SaveRespawnTime(info.type, info.spawnId, info.entry, info.respawnTime, info.zoneId, info.gridId, true, true, dbTrans); @@ -2463,11 +2463,11 @@ namespace Game.Maps DoRespawn(type, spawnId, gridId); } - void Respawn(List respawnData, bool force, SQLTransaction dbTrans) + void Respawn(List respawnData, SQLTransaction dbTrans) { SQLTransaction trans = dbTrans != null ? dbTrans : new SQLTransaction(); foreach (RespawnInfo info in respawnData) - Respawn(info, force, trans); + Respawn(info, trans); if (dbTrans == null) DB.Characters.CommitTransaction(trans); @@ -2545,13 +2545,6 @@ namespace Game.Maps _respawnTimes.Remove(info); } - public void ForceRespawn(SpawnObjectType type, ulong spawnId) - { - RespawnInfo info = GetRespawnInfo(type, spawnId); - if (info != null) - Respawn(info, true); - } - public void RemoveRespawnTime(RespawnInfo info, bool doRespawn = false, SQLTransaction dbTrans = null) { PreparedStatement stmt; diff --git a/Source/Game/OutdoorPVP/OutdoorPvP.cs b/Source/Game/OutdoorPVP/OutdoorPvP.cs index 3835d4d98..845cfe695 100644 --- a/Source/Game/OutdoorPVP/OutdoorPvP.cs +++ b/Source/Game/OutdoorPVP/OutdoorPvP.cs @@ -434,48 +434,24 @@ namespace Game.PvP } ulong spawnId = m_Creatures[type]; - var bounds = PvP.GetMap().GetCreatureBySpawnIdStore().LookupByKey(spawnId); - foreach (var creature in bounds) - { - // Don't save respawn time - creature.SetRespawnTime(0); - creature.DespawnOrUnsummon(); - creature.AddObjectToRemoveList(); - } - Log.outDebug(LogFilter.Outdoorpvp, "deleting opvp creature type {0}", type); - // delete respawn time for this creature - PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CREATURE_RESPAWN); - stmt.AddValue(0, spawnId); - stmt.AddValue(1, PvP.GetMap().GetId()); - stmt.AddValue(2, 0); // instance id, always 0 for world maps - DB.Characters.Execute(stmt); - - Global.ObjectMgr.DeleteCreatureData(spawnId); m_CreatureTypes.Remove(spawnId); m_Creatures.Remove(type); - return true; + + return Creature.DeleteFromDB(spawnId); } public bool DelObject(uint type) { - if (!m_Objects.ContainsKey(type)) + ulong spawnId = m_Objects[type]; + if (spawnId == 0) return false; - ulong spawnId = m_Objects[type]; - var bounds = PvP.GetMap().GetGameObjectBySpawnIdStore().LookupByKey(spawnId); - foreach (var gameobject in bounds) - { - // Don't save respawn time - gameobject.SetRespawnTime(0); - gameobject.Delete(); - } - - Global.ObjectMgr.DeleteGameObjectData(spawnId); m_ObjectTypes.Remove(spawnId); m_Objects.Remove(type); - return true; + + return GameObject.DeleteFromDB(spawnId); } bool DelCapturePoint()