diff --git a/Source/Game/BattleFields/BattleField.cs b/Source/Game/BattleFields/BattleField.cs index 886333140..835c40cba 100644 --- a/Source/Game/BattleFields/BattleField.cs +++ b/Source/Game/BattleFields/BattleField.cs @@ -672,24 +672,20 @@ namespace Game.BattleFields return null; } - CreatureTemplate cinfo = Global.ObjectMgr.GetCreatureTemplate(entry); - if (cinfo == null) + if (Global.ObjectMgr.GetCreatureTemplate(entry) == null) { Log.outError(LogFilter.Battlefield, "Battlefield:SpawnCreature: entry {0} does not exist.", entry); return null; } - float x, y, z, o; - pos.GetPosition(out x, out y, out z, out o); - - Creature creature = new Creature(); - if (!creature.Create(map.GenerateLowGuid(HighGuid.Creature), map, entry, x, y, z, o)) + Creature creature = Creature.CreateCreature(entry, map, pos); + if (!creature) { Log.outError(LogFilter.Battlefield, "Battlefield:SpawnCreature: Can't create creature entry: {0}", entry); return null; } - creature.SetHomePosition(x, y, z, o); + creature.SetHomePosition(pos); // Set creature in world map.AddToMap(creature); @@ -706,16 +702,15 @@ namespace Game.BattleFields if (!map) return null; - GameObjectTemplate goInfo = Global.ObjectMgr.GetGameObjectTemplate(entry); - if (goInfo == null) + if (Global.ObjectMgr.GetGameObjectTemplate(entry) == null) { Log.outError(LogFilter.Battlefield, "Battlefield.SpawnGameObject: GameObject template {0} not found in database! Battlefield not created!", entry); return null; } // Create gameobject - GameObject go = new GameObject(); - if (!go.Create(entry, map, pos, rotation, 255, GameObjectState.Ready)) + GameObject go = GameObject.CreateGameObject(entry, map, pos, rotation, 255, GameObjectState.Ready); + if (!go) { Log.outError(LogFilter.Battlefield, "Battlefield:SpawnGameObject: Cannot create gameobject template {1}! Battlefield not created!", entry); return null; diff --git a/Source/Game/BattleGrounds/BattleGround.cs b/Source/Game/BattleGrounds/BattleGround.cs index 202d2e10a..ccb0973c5 100644 --- a/Source/Game/BattleGrounds/BattleGround.cs +++ b/Source/Game/BattleGrounds/BattleGround.cs @@ -1331,8 +1331,8 @@ namespace Game.BattleGrounds // Must be created this way, adding to godatamap would add it to the base map of the instance // and when loading it (in go.LoadFromDB()), a new guid would be assigned to the object, and a new object would be created // So we must create it specific for this instance - GameObject go = new GameObject(); - if (!go.Create(entry, GetBgMap(), new Position(x, y, z, o), rotation, 100, goState)) + GameObject go = GameObject.CreateGameObject(entry, GetBgMap(), new Position(x, y, z, o), rotation, 255, goState); + if (!go) { Log.outError(LogFilter.Battleground, "Battleground.AddObject: cannot create gameobject (entry: {0}) for BG (map: {1}, instance id: {2})!", entry, m_MapId, m_InstanceID); return false; @@ -1435,6 +1435,13 @@ namespace Game.BattleGrounds if (!map) return null; + if (Global.ObjectMgr.GetCreatureTemplate(entry) == null) + { + Log.outError(LogFilter.Battleground, $"Battleground.AddCreature: creature template (entry: {entry}) does not exist for BG (map: {m_MapId}, instance id: {m_InstanceID})!"); + return null; + } + + if (transport) { Creature transCreature = transport.SummonPassenger(entry, new Position(x, y, z, o), TempSummonType.ManualDespawn); @@ -1447,26 +1454,17 @@ namespace Game.BattleGrounds return null; } - Creature creature = new Creature(); - if (!creature.Create(map.GenerateLowGuid(HighGuid.Creature), map, entry, x, y, z, o)) + Position pos = new Position(x, y, z, o); + + Creature creature = Creature.CreateCreature(entry, map, pos); + if (!creature) { Log.outError(LogFilter.Battleground, "Battleground.AddCreature: cannot create creature (entry: {0}) for BG (map: {1}, instance id: {2})!", entry, m_MapId, m_InstanceID); return null; } - creature.SetHomePosition(x, y, z, o); - - CreatureTemplate cinfo = Global.ObjectMgr.GetCreatureTemplate(entry); - if (cinfo == null) - { - Log.outError(LogFilter.Battleground, "Battleground.AddCreature: creature template (entry: {0}) does not exist for BG (map: {1}, instance id: {2})!", - entry, m_MapId, m_InstanceID); - return null; - } - // Force using DB speeds - creature.SetSpeed(UnitMoveType.Walk, cinfo.SpeedWalk); - creature.SetSpeed(UnitMoveType.Run, cinfo.SpeedRun); + creature.SetHomePosition(pos); if (!map.AddToMap(creature)) return null; diff --git a/Source/Game/Chat/Commands/DebugCommands.cs b/Source/Game/Chat/Commands/DebugCommands.cs index 235d91c21..1531a958d 100644 --- a/Source/Game/Chat/Commands/DebugCommands.cs +++ b/Source/Game/Chat/Commands/DebugCommands.cs @@ -938,13 +938,14 @@ namespace Game.Chat if (vehicleRecord == null) return false; - Creature creature = new Creature(); - Map map = handler.GetSession().GetPlayer().GetMap(); - if (!creature.Create(map.GenerateLowGuid(HighGuid.Vehicle), map, entry, x, y, z, o, null, id)) + Position pos = new Position(x, y, z, o); + + Creature creature = Creature.CreateCreature(entry, map, pos, id); + if (!creature) return false; - map.AddToMap(creature.ToCreature()); + map.AddToMap(creature); return true; } diff --git a/Source/Game/Chat/Commands/GameObjectCommands.cs b/Source/Game/Chat/Commands/GameObjectCommands.cs index 48700acb7..333532c7a 100644 --- a/Source/Game/Chat/Commands/GameObjectCommands.cs +++ b/Source/Game/Chat/Commands/GameObjectCommands.cs @@ -473,10 +473,8 @@ namespace Game.Chat Player player = handler.GetPlayer(); Map map = player.GetMap(); - GameObject obj = new GameObject(); - - Quaternion rotation = new Quaternion(Matrix3.fromEulerAnglesZYX(player.GetOrientation(), 0.0f, 0.0f)); - if (!obj.Create(objectInfo.entry, map, player, rotation, 255, GameObjectState.Ready)) + GameObject obj = GameObject.CreateGameObject(objectInfo.entry, map, player, new Quaternion(Matrix3.fromEulerAnglesZYX(player.GetOrientation(), 0.0f, 0.0f)), 255, GameObjectState.Ready); + if (!obj) return false; obj.CopyPhaseFrom(player); @@ -491,7 +489,8 @@ namespace Game.Chat ulong spawnId = obj.GetSpawnId(); // this will generate a new guid if the object is in an instance - if (!obj.LoadGameObjectFromDB(spawnId, map)) + obj = GameObject.CreateGameObjectFromDB(spawnId, map); + if (!obj) return false; // TODO: is it really necessary to add both the real and DB table guid here ? diff --git a/Source/Game/Chat/Commands/NPCCommands.cs b/Source/Game/Chat/Commands/NPCCommands.cs index 82f872f52..f1c0c013c 100644 --- a/Source/Game/Chat/Commands/NPCCommands.cs +++ b/Source/Game/Chat/Commands/NPCCommands.cs @@ -1094,10 +1094,6 @@ namespace Game.Chat return false; Player chr = handler.GetSession().GetPlayer(); - float x = chr.GetPositionX(); - float y = chr.GetPositionY(); - float z = chr.GetPositionZ(); - float o = chr.GetOrientation(); Map map = chr.GetMap(); Transport trans = chr.GetTransport(); @@ -1119,8 +1115,8 @@ namespace Game.Chat return true; } - Creature creature = new Creature(); - if (!creature.Create(map.GenerateLowGuid(HighGuid.Creature), map, id, x, y, z, o)) + Creature creature = Creature.CreateCreature(id, map, chr.GetPosition()); + if (!creature) return false; creature.CopyPhaseFrom(chr); @@ -1131,8 +1127,8 @@ namespace Game.Chat // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells() // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior creature.CleanupsBeforeDelete(); - creature = new Creature(); - if (!creature.LoadCreatureFromDB(db_guid, map)) + creature = Creature.CreateCreatureFromDB(db_guid, map); + if (!creature) return false; Global.ObjectMgr.AddCreatureToGrid(db_guid, Global.ObjectMgr.GetCreatureData(db_guid)); diff --git a/Source/Game/Chat/Commands/WPCommands.cs b/Source/Game/Chat/Commands/WPCommands.cs index 03adf0118..e4c581a8f 100644 --- a/Source/Game/Chat/Commands/WPCommands.cs +++ b/Source/Game/Chat/Commands/WPCommands.cs @@ -545,31 +545,42 @@ namespace Game.Chat.Commands target.AddObjectToRemoveList(); // re-create - Creature wpCreature = new Creature(); - if (!wpCreature.Create(map.GenerateLowGuid(HighGuid.Creature), map, 1, chr.GetPositionX(), chr.GetPositionY(), chr.GetPositionZ(), chr.GetOrientation())) + Creature creature = Creature.CreateCreature(1, map, chr.GetPosition()); + if (!creature) { - wpCreature.CopyPhaseFrom(chr); - wpCreature.SaveToDB(map.GetId(), 1ul << (int)map.GetSpawnMode()); - // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); - /// @todo Should we first use "Create" then use "LoadFromDB"? - if (!wpCreature.LoadCreatureFromDB(wpCreature.GetSpawnId(), map)) - { - handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, 1); - return false; - } - - stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_WAYPOINT_DATA_POSITION); - stmt.AddValue(0, chr.GetPositionX()); - stmt.AddValue(1, chr.GetPositionY()); - stmt.AddValue(2, chr.GetPositionZ()); - stmt.AddValue(3, pathid); - stmt.AddValue(4, point); - DB.World.Execute(stmt); - - handler.SendSysMessage(CypherStrings.WaypointChanged); + handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, 1); + return false; } + + creature.CopyPhaseFrom(chr); + creature.SaveToDB(map.GetId(), 1ul << (int)map.GetSpawnMode()); + + ulong dbGuid = creature.GetSpawnId(); + + // current "wpCreature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior + creature.CleanupsBeforeDelete(); + creature.Dispose(); + + // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); + creature = Creature.CreateCreatureFromDB(dbGuid, map); + if (!creature) + { + handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, 1); + return false; + } + + stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_WAYPOINT_DATA_POSITION); + stmt.AddValue(0, chr.GetPositionX()); + stmt.AddValue(1, chr.GetPositionY()); + stmt.AddValue(2, chr.GetPositionZ()); + stmt.AddValue(3, pathid); + stmt.AddValue(4, point); + DB.World.Execute(stmt); + + handler.SendSysMessage(CypherStrings.WaypointChanged); + return true; - } // move + } // move if (string.IsNullOrEmpty(arg_str)) { @@ -752,27 +763,27 @@ namespace Game.Chat.Commands Player chr = handler.GetSession().GetPlayer(); Map map = chr.GetMap(); - float o = chr.GetOrientation(); + Position pos = new Position(x, y, z, chr.GetOrientation()); - Creature wpCreature = new Creature(); - if (!wpCreature.Create(map.GenerateLowGuid(HighGuid.Creature), map, id, x, y, z, o)) + Creature creature = Creature.CreateCreature(id, map, pos); + if (!creature) { handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, id); return false; } - wpCreature.CopyPhaseFrom(chr); - wpCreature.SaveToDB(map.GetId(), 1ul << (int)map.GetSpawnMode()); + creature.CopyPhaseFrom(chr); + creature.SaveToDB(map.GetId(), 1ul << (int)map.GetSpawnMode()); - // Set "wpguid" column to the visual waypoint - stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_WAYPOINT_DATA_WPGUID); - stmt.AddValue(0, wpCreature.GetSpawnId()); - stmt.AddValue(1, pathid); - stmt.AddValue(2, point); - DB.World.Execute(stmt); + ulong dbGuid = creature.GetSpawnId(); + + // current "wpCreature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior + creature.CleanupsBeforeDelete(); + creature.Dispose(); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); - if (!wpCreature.LoadCreatureFromDB(wpCreature.GetSpawnId(), map)) + creature = Creature.CreateCreatureFromDB(dbGuid, map); + if (!creature) { handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, id); return false; @@ -780,10 +791,17 @@ namespace Game.Chat.Commands if (target) { - wpCreature.SetDisplayId(target.GetDisplayId()); - wpCreature.SetObjectScale(0.5f); - wpCreature.SetLevel(Math.Min(point, SharedConst.StrongMaxLevel)); + creature.SetDisplayId(target.GetDisplayId()); + creature.SetObjectScale(0.5f); + creature.SetLevel(Math.Min(point, SharedConst.StrongMaxLevel)); } + + // Set "wpguid" column to the visual waypoint + stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_WAYPOINT_DATA_WPGUID); + stmt.AddValue(0, creature.GetSpawnId()); + stmt.AddValue(1, pathid); + stmt.AddValue(2, point); + DB.World.Execute(stmt); } while (result.NextRow()); @@ -808,25 +826,31 @@ namespace Game.Chat.Commands float x = result.Read(0); float y = result.Read(1); float z = result.Read(2); - uint id = 1; Player chr = handler.GetSession().GetPlayer(); - float o = chr.GetOrientation(); Map map = chr.GetMap(); + Position pos = new Position(x, y, z, chr.GetOrientation()); - Creature creature = new Creature(); - if (!creature.Create(map.GenerateLowGuid(HighGuid.Creature), map, id, x, y, z, o)) + Creature creature = Creature.CreateCreature(1, map, pos); + if (!creature) { - handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, id); + handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, 1); return false; } creature.CopyPhaseFrom(chr); creature.SaveToDB(map.GetId(), 1ul << (int)map.GetSpawnMode()); - if (!creature.LoadCreatureFromDB(creature.GetSpawnId(), map)) + ulong dbGuid = creature.GetSpawnId(); + + // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior + creature.CleanupsBeforeDelete(); + creature.Dispose(); + + creature = Creature.CreateCreatureFromDB(dbGuid, map); + if (!creature) { - handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, id); + handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, 1); return false; } @@ -857,24 +881,31 @@ namespace Game.Chat.Commands float y = result.Read(1); float z = result.Read(2); float o = result.Read(3); - uint id = 1; Player chr = handler.GetSession().GetPlayer(); Map map = chr.GetMap(); + Position pos = new Position(x, y, z, o); - Creature creature = new Creature(); - if (!creature.Create(map.GenerateLowGuid(HighGuid.Creature), map, id, x, y, z, o)) + Creature creature = Creature.CreateCreature(1, map, pos); + if (!creature) { - handler.SendSysMessage(CypherStrings.WaypointNotcreated, id); + handler.SendSysMessage(CypherStrings.WaypointNotcreated, 1); return false; } creature.CopyPhaseFrom(chr); creature.SaveToDB(map.GetId(), 1ul << (int)map.GetSpawnMode()); - if (!creature.LoadCreatureFromDB(creature.GetSpawnId(), map)) + ulong dbGuid = creature.GetSpawnId(); + + // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior + creature.CleanupsBeforeDelete(); + creature.Dispose(); + + creature = Creature.CreateCreatureFromDB(dbGuid, map); + if (!creature) { - handler.SendSysMessage(CypherStrings.WaypointNotcreated, id); + handler.SendSysMessage(CypherStrings.WaypointNotcreated, 1); return false; } diff --git a/Source/Game/DataStorage/CliDB.cs b/Source/Game/DataStorage/CliDB.cs index 671dd7b57..e1d1e79cc 100644 --- a/Source/Game/DataStorage/CliDB.cs +++ b/Source/Game/DataStorage/CliDB.cs @@ -283,8 +283,6 @@ namespace Game.DataStorage foreach (var entry in TaxiPathNodeStorage.Values) TaxiPathNodesByPath[entry.PathID][entry.NodeIndex] = entry; - TaxiPathNodeStorage = null; - foreach (var node in TaxiNodesStorage.Values) { if (!node.Flags.HasAnyFlag(TaxiNodeFlags.Alliance | TaxiNodeFlags.Horde)) diff --git a/Source/Game/Entities/AreaTrigger/AreaTrigger.cs b/Source/Game/Entities/AreaTrigger/AreaTrigger.cs index db8a5710f..c9c12dfea 100644 --- a/Source/Game/Entities/AreaTrigger/AreaTrigger.cs +++ b/Source/Game/Entities/AreaTrigger/AreaTrigger.cs @@ -75,7 +75,16 @@ namespace Game.Entities } } - public bool CreateAreaTrigger(uint spellMiscId, Unit caster, Unit target, SpellInfo spell, Position pos, int duration, uint spellXSpellVisualId, ObjectGuid castId = default(ObjectGuid), AuraEffect aurEff = null) + public static AreaTrigger CreateAreaTrigger(uint spellMiscId, Unit caster, Unit target, SpellInfo spell, Position pos, int duration, uint spellXSpellVisualId, ObjectGuid castId = default(ObjectGuid), AuraEffect aurEff = null) + { + AreaTrigger at = new AreaTrigger(); + if (!at.Create(spellMiscId, caster, target, spell, pos, duration, spellXSpellVisualId, castId, aurEff)) + return null; + + return at; + } + + bool Create(uint spellMiscId, Unit caster, Unit target, SpellInfo spell, Position pos, int duration, uint spellXSpellVisualId, ObjectGuid castId, AuraEffect aurEff) { _targetGuid = target ? target.GetGUID() : ObjectGuid.Empty; _aurEff = aurEff; diff --git a/Source/Game/Entities/Creature/Creature.cs b/Source/Game/Entities/Creature/Creature.cs index bbb37acd5..dab257568 100644 --- a/Source/Game/Entities/Creature/Creature.cs +++ b/Source/Game/Entities/Creature/Creature.cs @@ -720,7 +720,35 @@ namespace Game.Entities GetMotionMaster().Initialize(); } - public bool Create(ulong guidlow, Map map, uint entry, float x, float y, float z, float ang, CreatureData data = null, uint vehId = 0) + public static Creature CreateCreature(uint entry, Map map, Position pos, uint vehId = 0) + { + CreatureTemplate cInfo = Global.ObjectMgr.GetCreatureTemplate(entry); + if (cInfo == null) + return null; + + ulong lowGuid; + if (vehId != 0 || cInfo.VehicleId != 0) + lowGuid = map.GenerateLowGuid(HighGuid.Vehicle); + else + lowGuid = map.GenerateLowGuid(HighGuid.Creature); + + Creature creature = new Creature(); + if (!creature.Create(lowGuid, map, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), null, vehId)) + return null; + + return creature; + } + + public static Creature CreateCreatureFromDB(ulong spawnId, Map map, bool addToMap = true, bool allowDuplicate = false) + { + Creature creature = new Creature(); + if (!creature.LoadCreatureFromDB(spawnId, map, addToMap, allowDuplicate)) + return null; + + return creature; + } + + public bool Create(ulong guidlow, Map map, uint entry, float x, float y, float z, float ang, CreatureData data, uint vehId) { SetMap(map); @@ -1281,83 +1309,6 @@ namespace Game.Entities return true; } - public bool LoadCreatureFromDB(ulong spawnId, Map map, bool addToMap = true, bool allowDuplicate = false) - { - if (!allowDuplicate) - { - // If an alive instance of this spawnId is already found, skip creation - // If only dead instance(s) exist, despawn them and spawn a new (maybe also dead) version - var creatureBounds = map.GetCreatureBySpawnIdStore().LookupByKey(spawnId); - List despawnList = new List(); - - foreach (var creature in creatureBounds) - { - if (creature.IsAlive()) - { - Log.outDebug(LogFilter.Maps, "Would have spawned {0} but {1} already exists", spawnId, creature.GetGUID().ToString()); - return false; - } - else - { - despawnList.Add(creature); - Log.outDebug(LogFilter.Maps, "Despawned dead instance of spawn {0} ({1})", spawnId, creature.GetGUID().ToString()); - } - } - - foreach (Creature despawnCreature in despawnList) - { - despawnCreature.AddObjectToRemoveList(); - } - } - - CreatureData data = Global.ObjectMgr.GetCreatureData(spawnId); - if (data == null) - { - Log.outError(LogFilter.Sql, "Creature (GUID: {0}) not found in table `creature`, can't load. ", spawnId); - return false; - } - - m_spawnId = spawnId; - m_creatureData = data; - if (!Create(map.GenerateLowGuid(HighGuid.Creature), map, data.id, data.posX, data.posY, data.posZ, data.orientation, data)) - return false; - - //We should set first home position, because then AI calls home movement - SetHomePosition(data.posX, data.posY, data.posZ, data.orientation); - - m_respawnradius = data.spawndist; - - m_respawnDelay = data.spawntimesecs; - m_deathState = DeathState.Alive; - - m_respawnTime = GetMap().GetCreatureRespawnTime(m_spawnId); - - // Is the creature script objecting to us spawning? If yes, delay by one second (then re-check in ::Update) - if (m_respawnTime == 0 && !Global.ScriptMgr.CanSpawn(spawnId, GetEntry(), GetCreatureTemplate(), GetCreatureData(), map)) - m_respawnTime = Time.UnixTime + 1; - - if (m_respawnTime != 0) // respawn on Update - { - m_deathState = DeathState.Dead; - if (CanFly()) - { - float tz = map.GetHeight(GetPhases(), data.posX, data.posY, data.posZ, true, MapConst.MaxFallDistance); - if (data.posZ - tz > 0.1f && GridDefines.IsValidMapCoord(tz)) - Relocate(data.posX, data.posY, tz); - } - } - - SetSpawnHealth(); - - m_defaultMovementType = (MovementGeneratorType)data.movementType; - - loot.SetGUID(ObjectGuid.Create(HighGuid.LootObject, data.mapid, data.id, GetMap().GenerateLowGuid(HighGuid.LootObject))); - - if (addToMap && !GetMap().AddToMap(this)) - return false; - return true; - } - public override void SetCanDualWield(bool value) { base.SetCanDualWield(value); @@ -2914,7 +2865,84 @@ namespace Game.Entities public override bool LoadFromDB(ulong spawnId, Map map) { - return LoadCreatureFromDB(spawnId, map, false); + return LoadCreatureFromDB(spawnId, map, false, false); + } + + public bool LoadCreatureFromDB(ulong spawnId, Map map, bool addToMap, bool allowDuplicate) + { + if (!allowDuplicate) + { + // If an alive instance of this spawnId is already found, skip creation + // If only dead instance(s) exist, despawn them and spawn a new (maybe also dead) version + var creatureBounds = map.GetCreatureBySpawnIdStore().LookupByKey(spawnId); + List despawnList = new List(); + + foreach (var creature in creatureBounds) + { + if (creature.IsAlive()) + { + Log.outDebug(LogFilter.Maps, "Would have spawned {0} but {1} already exists", spawnId, creature.GetGUID().ToString()); + return false; + } + else + { + despawnList.Add(creature); + Log.outDebug(LogFilter.Maps, "Despawned dead instance of spawn {0} ({1})", spawnId, creature.GetGUID().ToString()); + } + } + + foreach (Creature despawnCreature in despawnList) + { + despawnCreature.AddObjectToRemoveList(); + } + } + + CreatureData data = Global.ObjectMgr.GetCreatureData(spawnId); + if (data == null) + { + Log.outError(LogFilter.Sql, "Creature (GUID: {0}) not found in table `creature`, can't load. ", spawnId); + return false; + } + + m_spawnId = spawnId; + m_creatureData = data; + if (!Create(map.GenerateLowGuid(HighGuid.Creature), map, data.id, data.posX, data.posY, data.posZ, data.orientation, data, 0)) + return false; + + //We should set first home position, because then AI calls home movement + SetHomePosition(data.posX, data.posY, data.posZ, data.orientation); + + m_respawnradius = data.spawndist; + + m_respawnDelay = data.spawntimesecs; + m_deathState = DeathState.Alive; + + m_respawnTime = GetMap().GetCreatureRespawnTime(m_spawnId); + + // Is the creature script objecting to us spawning? If yes, delay by one second (then re-check in ::Update) + if (m_respawnTime == 0 && !Global.ScriptMgr.CanSpawn(spawnId, GetEntry(), GetCreatureTemplate(), GetCreatureData(), map)) + m_respawnTime = Time.UnixTime + 1; + + if (m_respawnTime != 0) // respawn on Update + { + m_deathState = DeathState.Dead; + if (CanFly()) + { + float tz = map.GetHeight(GetPhases(), data.posX, data.posY, data.posZ, true, MapConst.MaxFallDistance); + if (data.posZ - tz > 0.1f && GridDefines.IsValidMapCoord(tz)) + Relocate(data.posX, data.posY, tz); + } + } + + SetSpawnHealth(); + + m_defaultMovementType = (MovementGeneratorType)data.movementType; + + loot.SetGUID(ObjectGuid.Create(HighGuid.LootObject, data.mapid, data.id, GetMap().GenerateLowGuid(HighGuid.LootObject))); + + if (addToMap && !GetMap().AddToMap(this)) + return false; + return true; } public bool hasLootRecipient() { return !m_lootRecipient.IsEmpty() || !m_lootRecipientGroup.IsEmpty(); } diff --git a/Source/Game/Entities/GameObject/GameObject.cs b/Source/Game/Entities/GameObject/GameObject.cs index 071529ec6..b745a3cca 100644 --- a/Source/Game/Entities/GameObject/GameObject.cs +++ b/Source/Game/Entities/GameObject/GameObject.cs @@ -158,7 +158,29 @@ namespace Game.Entities } } - public bool Create(uint name_id, Map map, Position pos, Quaternion rotation, uint animprogress, GameObjectState go_state, uint artKit = 0) + public static GameObject CreateGameObject(uint entry, Map map, Position pos, Quaternion rotation, uint animProgress, GameObjectState goState, uint artKit = 0) + { + GameObjectTemplate goInfo = Global.ObjectMgr.GetGameObjectTemplate(entry); + if (goInfo == null) + return null; + + GameObject go = new GameObject(); + if (!go.Create(entry, map, pos, rotation, animProgress, goState, artKit)) + return null; + + return go; + } + + public static GameObject CreateGameObjectFromDB(ulong spawnId, Map map, bool addToMap = true) + { + GameObject go = new GameObject(); + if (!go.LoadGameObjectFromDB(spawnId, map, addToMap)) + return null; + + return go; + } + + bool Create(uint entry, Map map, Position pos, Quaternion rotation, uint animProgress, GameObjectState goState, uint artKit) { Contract.Assert(map); SetMap(map); @@ -167,34 +189,34 @@ namespace Game.Entities m_stationaryPosition.Relocate(pos); if (!IsPositionValid()) { - Log.outError(LogFilter.Server, "Gameobject (Spawn id: {0} Entry: {1}) not created. Suggested coordinates isn't valid (X: {2} Y: {3})", GetSpawnId(), name_id, pos.GetPositionX(), pos.GetPositionY()); + Log.outError(LogFilter.Server, "Gameobject (Spawn id: {0} Entry: {1}) not created. Suggested coordinates isn't valid (X: {2} Y: {3})", GetSpawnId(), entry, pos.GetPositionX(), pos.GetPositionY()); return false; } SetZoneScript(); if (m_zoneScript != null) { - name_id = m_zoneScript.GetGameObjectEntry(m_spawnId, name_id); - if (name_id == 0) + entry = m_zoneScript.GetGameObjectEntry(m_spawnId, entry); + if (entry == 0) return false; } - GameObjectTemplate goinfo = Global.ObjectMgr.GetGameObjectTemplate(name_id); - if (goinfo == null) + GameObjectTemplate goInfo = Global.ObjectMgr.GetGameObjectTemplate(entry); + if (goInfo == null) { - Log.outError(LogFilter.Sql, "Gameobject (Spawn id: {0} Entry: {1}) not created: non-existing entry in `gameobject_template`. Map: {2} (X: {3} Y: {4} Z: {5})", GetSpawnId(), name_id, map.GetId(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); + Log.outError(LogFilter.Sql, "Gameobject (Spawn id: {0} Entry: {1}) not created: non-existing entry in `gameobject_template`. Map: {2} (X: {3} Y: {4} Z: {5})", GetSpawnId(), entry, map.GetId(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); return false; } - if (goinfo.type == GameObjectTypes.MapObjTransport) + if (goInfo.type == GameObjectTypes.MapObjTransport) { - Log.outError(LogFilter.Sql, "Gameobject (Spawn id: {0} Entry: {1}) not created: gameobject type GAMEOBJECT_TYPE_MAP_OBJ_TRANSPORT cannot be manually created.", GetSpawnId(), name_id); + Log.outError(LogFilter.Sql, "Gameobject (Spawn id: {0} Entry: {1}) not created: gameobject type GAMEOBJECT_TYPE_MAP_OBJ_TRANSPORT cannot be manually created.", GetSpawnId(), entry); return false; } ObjectGuid guid; - if (goinfo.type != GameObjectTypes.Transport) - guid = ObjectGuid.Create(HighGuid.GameObject, map.GetId(), goinfo.entry, map.GenerateLowGuid(HighGuid.GameObject)); + if (goInfo.type != GameObjectTypes.Transport) + guid = ObjectGuid.Create(HighGuid.GameObject, map.GetId(), goInfo.entry, map.GenerateLowGuid(HighGuid.GameObject)); else { guid = ObjectGuid.Create(HighGuid.Transport, map.GenerateLowGuid(HighGuid.Transport)); @@ -203,12 +225,12 @@ namespace Game.Entities _Create(guid); - m_goInfo = goinfo; - m_goTemplateAddon = Global.ObjectMgr.GetGameObjectTemplateAddon(name_id); + m_goInfo = goInfo; + m_goTemplateAddon = Global.ObjectMgr.GetGameObjectTemplateAddon(entry); - if (goinfo.type >= GameObjectTypes.Max) + if (goInfo.type >= GameObjectTypes.Max) { - Log.outError(LogFilter.Sql, "Gameobject (Spawn id: {0} Entry: {1}) not created: non-existing GO type '{2}' in `gameobject_template`. It will crash client if created.", GetSpawnId(), name_id, goinfo.type); + Log.outError(LogFilter.Sql, "Gameobject (Spawn id: {0} Entry: {1}) not created: non-existing GO type '{2}' in `gameobject_template`. It will crash client if created.", GetSpawnId(), entry, goInfo.type); return false; } @@ -222,7 +244,7 @@ namespace Game.Entities SetParentRotation(parentRotation); - SetObjectScale(goinfo.size); + SetObjectScale(goInfo.size); if (m_goTemplateAddon != null) { @@ -236,85 +258,85 @@ namespace Game.Entities } } - SetEntry(goinfo.entry); + SetEntry(goInfo.entry); // set name for logs usage, doesn't affect anything ingame - SetName(goinfo.name); + SetName(goInfo.name); - SetDisplayId(goinfo.displayId); + SetDisplayId(goInfo.displayId); m_model = CreateModel(); // GAMEOBJECT_BYTES_1, index at 0, 1, 2 and 3 - SetGoType(goinfo.type); - m_prevGoState = go_state; - SetGoState(go_state); + SetGoType(goInfo.type); + m_prevGoState = goState; + SetGoState(goState); SetGoArtKit((byte)artKit); - switch (goinfo.type) + switch (goInfo.type) { case GameObjectTypes.FishingHole: - SetGoAnimProgress(animprogress); + SetGoAnimProgress(animProgress); m_goValue.FishingHole.MaxOpens = RandomHelper.URand(GetGoInfo().FishingHole.minRestock, GetGoInfo().FishingHole.maxRestock); break; case GameObjectTypes.DestructibleBuilding: m_goValue.Building.Health = 20000;//goinfo.DestructibleBuilding.intactNumHits + goinfo.DestructibleBuilding.damagedNumHits; m_goValue.Building.MaxHealth = m_goValue.Building.Health; SetGoAnimProgress(255); - SetUInt32Value(GameObjectFields.ParentRotation, goinfo.DestructibleBuilding.DestructibleModelRec); + SetUInt32Value(GameObjectFields.ParentRotation, goInfo.DestructibleBuilding.DestructibleModelRec); break; case GameObjectTypes.Transport: - m_goValue.Transport.AnimationInfo = Global.TransportMgr.GetTransportAnimInfo(goinfo.entry); + m_goValue.Transport.AnimationInfo = Global.TransportMgr.GetTransportAnimInfo(goInfo.entry); m_goValue.Transport.PathProgress = Time.GetMSTime(); if (m_goValue.Transport.AnimationInfo.Path != null) m_goValue.Transport.PathProgress -= m_goValue.Transport.PathProgress % GetTransportPeriod(); // align to period m_goValue.Transport.CurrentSeg = 0; m_goValue.Transport.StateUpdateTimer = 0; m_goValue.Transport.StopFrames = new List(); - if (goinfo.Transport.Timeto2ndfloor > 0) - m_goValue.Transport.StopFrames.Add(goinfo.Transport.Timeto2ndfloor); - if (goinfo.Transport.Timeto3rdfloor > 0) - m_goValue.Transport.StopFrames.Add(goinfo.Transport.Timeto3rdfloor); - if (goinfo.Transport.Timeto4thfloor > 0) - m_goValue.Transport.StopFrames.Add(goinfo.Transport.Timeto4thfloor); - if (goinfo.Transport.Timeto5thfloor > 0) - m_goValue.Transport.StopFrames.Add(goinfo.Transport.Timeto5thfloor); - if (goinfo.Transport.Timeto6thfloor > 0) - m_goValue.Transport.StopFrames.Add(goinfo.Transport.Timeto6thfloor); - if (goinfo.Transport.Timeto7thfloor > 0) - m_goValue.Transport.StopFrames.Add(goinfo.Transport.Timeto7thfloor); - if (goinfo.Transport.Timeto8thfloor > 0) - m_goValue.Transport.StopFrames.Add(goinfo.Transport.Timeto8thfloor); - if (goinfo.Transport.Timeto9thfloor > 0) - m_goValue.Transport.StopFrames.Add(goinfo.Transport.Timeto9thfloor); - if (goinfo.Transport.Timeto10thfloor > 0) - m_goValue.Transport.StopFrames.Add(goinfo.Transport.Timeto10thfloor); + if (goInfo.Transport.Timeto2ndfloor > 0) + m_goValue.Transport.StopFrames.Add(goInfo.Transport.Timeto2ndfloor); + if (goInfo.Transport.Timeto3rdfloor > 0) + m_goValue.Transport.StopFrames.Add(goInfo.Transport.Timeto3rdfloor); + if (goInfo.Transport.Timeto4thfloor > 0) + m_goValue.Transport.StopFrames.Add(goInfo.Transport.Timeto4thfloor); + if (goInfo.Transport.Timeto5thfloor > 0) + m_goValue.Transport.StopFrames.Add(goInfo.Transport.Timeto5thfloor); + if (goInfo.Transport.Timeto6thfloor > 0) + m_goValue.Transport.StopFrames.Add(goInfo.Transport.Timeto6thfloor); + if (goInfo.Transport.Timeto7thfloor > 0) + m_goValue.Transport.StopFrames.Add(goInfo.Transport.Timeto7thfloor); + if (goInfo.Transport.Timeto8thfloor > 0) + m_goValue.Transport.StopFrames.Add(goInfo.Transport.Timeto8thfloor); + if (goInfo.Transport.Timeto9thfloor > 0) + m_goValue.Transport.StopFrames.Add(goInfo.Transport.Timeto9thfloor); + if (goInfo.Transport.Timeto10thfloor > 0) + m_goValue.Transport.StopFrames.Add(goInfo.Transport.Timeto10thfloor); - if (goinfo.Transport.startOpen != 0) - SetTransportState(GameObjectState.TransportStopped, goinfo.Transport.startOpen - 1); + if (goInfo.Transport.startOpen != 0) + SetTransportState(GameObjectState.TransportStopped, goInfo.Transport.startOpen - 1); else SetTransportState(GameObjectState.TransportActive); - SetGoAnimProgress(animprogress); + SetGoAnimProgress(animProgress); break; case GameObjectTypes.FishingNode: SetUInt32Value(GameObjectFields.Level, 1); SetGoAnimProgress(255); break; case GameObjectTypes.Trap: - if (goinfo.Trap.stealthed != 0) + if (goInfo.Trap.stealthed != 0) { m_stealth.AddFlag(StealthType.Trap); m_stealth.AddValue(StealthType.Trap, 70); } - if (goinfo.Trap.stealthAffected != 0) + if (goInfo.Trap.stealthAffected != 0) { m_invisibility.AddFlag(InvisibilityType.Trap); m_invisibility.AddValue(InvisibilityType.Trap, 300); } break; default: - SetGoAnimProgress(animprogress); + SetGoAnimProgress(animProgress); break; } @@ -340,14 +362,14 @@ namespace Game.Entities uint linkedEntry = GetGoInfo().GetLinkedGameObjectEntry(); if (linkedEntry != 0) { - GameObject linkedGO = new GameObject(); - if (linkedGO.Create(linkedEntry, map, pos, rotation, 255, GameObjectState.Ready)) + GameObject linkedGo = CreateGameObject(linkedEntry, map, pos, rotation, 255, GameObjectState.Ready); + if (linkedGo != null) { - SetLinkedTrap(linkedGO); - map.AddToMap(linkedGO); + SetLinkedTrap(linkedGo); + map.AddToMap(linkedGo); } else - linkedGO.Dispose(); + linkedGo.Dispose(); } return true; @@ -907,10 +929,9 @@ namespace Game.Entities DB.World.Execute(stmt); } - public bool LoadGameObjectFromDB(ulong spawnId, Map map, bool addToMap = true) + bool LoadGameObjectFromDB(ulong spawnId, Map map, bool addToMap) { GameObjectData data = Global.ObjectMgr.GetGOData(spawnId); - if (data == null) { Log.outError(LogFilter.Maps, "Gameobject (SpawnId: {0}) not found in table `gameobject`, can't load. ", spawnId); diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index 681ab8276..26cae1131 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -2043,8 +2043,8 @@ namespace Game.Entities } Map map = GetMap(); - GameObject go = new GameObject(); - if (!go.Create(entry, map, pos, rotation, 255, GameObjectState.Ready)) + GameObject go = GameObject.CreateGameObject(entry, map, pos, rotation, 255, GameObjectState.Ready); + if (!go) return null; go.CopyPhaseFrom(this); diff --git a/Source/Game/Entities/Transport.cs b/Source/Game/Entities/Transport.cs index 3b2349ad9..83cdae569 100644 --- a/Source/Game/Entities/Transport.cs +++ b/Source/Game/Entities/Transport.cs @@ -309,9 +309,9 @@ namespace Game.Entities public Creature CreateNPCPassenger(ulong guid, CreatureData data) { Map map = GetMap(); - Creature creature = new Creature(); - if (!creature.LoadCreatureFromDB(guid, map, false)) + Creature creature = Creature.CreateCreatureFromDB(guid, map, false); + if (!creature) return null; float x = data.posX; @@ -359,9 +359,9 @@ namespace Game.Entities GameObject CreateGOPassenger(ulong guid, GameObjectData data) { Map map = GetMap(); - GameObject go = new GameObject(); - if (!go.LoadGameObjectFromDB(guid, map, false)) + GameObject go = CreateGameObjectFromDB(guid, map, false); + if (!go) return null; float x = data.posX; diff --git a/Source/Game/Events/GameEventManager.cs b/Source/Game/Events/GameEventManager.cs index a2b373c27..935948fa8 100644 --- a/Source/Game/Events/GameEventManager.cs +++ b/Source/Game/Events/GameEventManager.cs @@ -1189,11 +1189,7 @@ namespace Game Map map = Global.MapMgr.CreateBaseMap(data.mapid); // We use spawn coords to spawn if (!map.Instanceable() && map.IsGridLoaded(data.posX, data.posY)) - { - Creature creature = new Creature(); - Log.outDebug(LogFilter.Misc, "Spawning creature {0}", guid.ToString()); - creature.LoadCreatureFromDB(guid, map); - } + Creature.CreateCreatureFromDB(guid, map); } } @@ -1217,11 +1213,11 @@ namespace Game // We use current coords to unspawn, not spawn coords since creature can have changed grid if (!map.Instanceable() && map.IsGridLoaded(data.posX, data.posY)) { - GameObject pGameobject = new GameObject(); - Log.outDebug(LogFilter.Misc, "Spawning gameobject {0}", guid.ToString()); + GameObject pGameobject = GameObject.CreateGameObjectFromDB(guid, map, false); /// @todo find out when it is add to map - if (pGameobject.LoadGameObjectFromDB(guid, map, false)) + if (pGameobject) { + /// @todo find out when it is add to map if (pGameobject.isSpawnedByDefault()) map.AddToMap(pGameobject); } diff --git a/Source/Game/Garrisons/Garrisons.cs b/Source/Game/Garrisons/Garrisons.cs index dc9e2f126..792093072 100644 --- a/Source/Game/Garrisons/Garrisons.cs +++ b/Source/Game/Garrisons/Garrisons.cs @@ -707,9 +707,8 @@ namespace Game.Garrisons return null; } - Position pos = PacketInfo.PlotPos; - GameObject go = new GameObject(); - if (!go.Create(entry, map, pos, Quaternion.WAxis, 255, GameObjectState.Active)) + GameObject go = GameObject.CreateGameObject(entry, map, PacketInfo.PlotPos, Quaternion.WAxis, 255, GameObjectState.Ready); + if (!go) return null; if (BuildingInfo.CanActivate() && BuildingInfo.PacketInfo.HasValue && !BuildingInfo.PacketInfo.Value.Active) @@ -718,8 +717,8 @@ namespace Game.Garrisons if (finalizeInfo != null) { Position pos2 = finalizeInfo.factionInfo[faction].Pos; - GameObject finalizer = new GameObject(); - if (finalizer.Create(finalizeInfo.factionInfo[faction].GameObjectId, map, pos2, Quaternion.WAxis, 255, GameObjectState.Ready)) + GameObject finalizer = GameObject.CreateGameObject(finalizeInfo.factionInfo[faction].GameObjectId, map, pos2, Quaternion.WAxis, 255, GameObjectState.Ready); + if (finalizer) { // set some spell id to make the object delete itself after use finalizer.SetSpellId(finalizer.GetGoInfo().Goober.spell); diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index fdcf7752e..f67e5faad 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -3451,8 +3451,8 @@ namespace Game // We use spawn coords to spawn if (!map.Instanceable() && !map.IsRemovalGrid(x, y)) { - Creature creature = new Creature(); - if (!creature.LoadCreatureFromDB(guid, map)) + Creature creature = Creature.CreateCreatureFromDB(guid, map); + if (!creature) { Log.outError(LogFilter.Server, "AddCreature: Cannot add creature entry {0} to map", entry); return 0; @@ -4290,8 +4290,8 @@ namespace Game // We use spawn coords to spawn if (!map.Instanceable() && map.IsGridLoaded(x, y)) { - GameObject go = new GameObject(); - if (!go.LoadGameObjectFromDB(guid, map)) + GameObject go = GameObject.CreateGameObjectFromDB(guid, map); + if (!go) { Log.outError(LogFilter.Server, "AddGOData: cannot add gameobject entry {0} to map", entry); return 0; diff --git a/Source/Game/Pools/PoolManager.cs b/Source/Game/Pools/PoolManager.cs index 0374c39eb..2cf49b067 100644 --- a/Source/Game/Pools/PoolManager.cs +++ b/Source/Game/Pools/PoolManager.cs @@ -869,12 +869,7 @@ namespace Game Map map = Global.MapMgr.CreateBaseMap(data.mapid); // We use spawn coords to spawn if (!map.Instanceable() && map.IsGridLoaded(data.posX, data.posY)) - { - Creature creature = new Creature(); - if (!creature.LoadCreatureFromDB(obj.guid, map)) - return; - - } + Creature.CreateCreatureFromDB(obj.guid, map); } break; case "GameObject": @@ -888,13 +883,11 @@ namespace Game // We use current coords to unspawn, not spawn coords since creature can have changed grid if (!map.Instanceable() && map.IsGridLoaded(data_.posX, data_.posY)) { - GameObject pGameobject = new GameObject(); - if (!pGameobject.LoadGameObjectFromDB(obj.guid, map, false)) - return; - else + GameObject go = GameObject.CreateGameObjectFromDB(obj.guid, map, false); + if (go) { - if (pGameobject.isSpawnedByDefault()) - map.AddToMap(pGameobject); + if (go.isSpawnedByDefault()) + map.AddToMap(go); } } } diff --git a/Source/Game/Spells/Auras/AuraEffect.cs b/Source/Game/Spells/Auras/AuraEffect.cs index 9fe0eefb0..72f85304d 100644 --- a/Source/Game/Spells/Auras/AuraEffect.cs +++ b/Source/Game/Spells/Auras/AuraEffect.cs @@ -5944,9 +5944,7 @@ namespace Game.Spells if (apply) { - AreaTrigger areaTrigger = new AreaTrigger(); - if (!areaTrigger.CreateAreaTrigger((uint)GetMiscValue(), GetCaster(), target, GetSpellInfo(), target, GetBase().GetDuration(), GetBase().GetSpellXSpellVisualId(), ObjectGuid.Empty, this)) - areaTrigger.Dispose(); + AreaTrigger areaTrigger = AreaTrigger.CreateAreaTrigger((uint)GetMiscValue(), GetCaster(), target, GetSpellInfo(), target, GetBase().GetDuration(), GetBase().GetSpellXSpellVisualId(), ObjectGuid.Empty, this); } else { diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index 8592f3afe..10f427b92 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -2840,10 +2840,6 @@ namespace Game.Spells if (effectHandleMode != SpellEffectHandleMode.Hit) return; - uint gameobject_id = (uint)effectInfo.MiscValue; - - GameObject pGameObj = new GameObject(); - WorldObject target = focusObject; if (target == null) target = m_caster; @@ -2855,34 +2851,37 @@ namespace Game.Spells m_caster.GetClosePoint(out x, out y, out z, SharedConst.DefaultWorldObjectSize); Map map = target.GetMap(); + + Position pos = new Position(x, y, z, target.GetOrientation()); Quaternion rotation = new Quaternion(Matrix3.fromEulerAnglesZYX(target.GetOrientation(), 0.0f, 0.0f)); - if (!pGameObj.Create(gameobject_id, map, new Position(x, y, z, target.GetOrientation()), rotation, 255, GameObjectState.Ready)) + GameObject go = GameObject.CreateGameObject((uint)effectInfo.MiscValue, map, pos, rotation, 255, GameObjectState.Ready); + if (!go) return; - pGameObj.CopyPhaseFrom(m_caster); + go.CopyPhaseFrom(m_caster); int duration = m_spellInfo.CalcDuration(m_caster); - pGameObj.SetRespawnTime(duration > 0 ? duration / Time.InMilliseconds : 0); - pGameObj.SetSpellId(m_spellInfo.Id); + go.SetRespawnTime(duration > 0 ? duration / Time.InMilliseconds : 0); + go.SetSpellId(m_spellInfo.Id); - ExecuteLogEffectSummonObject(effIndex, pGameObj); + ExecuteLogEffectSummonObject(effIndex, go); // Wild object not have owner and check clickable by players - map.AddToMap(pGameObj); + map.AddToMap(go); - if (pGameObj.GetGoType() == GameObjectTypes.FlagDrop) + if (go.GetGoType() == GameObjectTypes.FlagDrop) { Player player = m_caster.ToPlayer(); if (player != null) { Battleground bg = player.GetBattleground(); if (bg) - bg.SetDroppedFlagGUID(pGameObj.GetGUID(), (player.GetTeam() == Team.Alliance ? TeamId.Horde : TeamId.Alliance)); + bg.SetDroppedFlagGUID(go.GetGUID(), (player.GetTeam() == Team.Alliance ? TeamId.Horde : TeamId.Alliance)); } } - GameObject linkedTrap = pGameObj.GetLinkedTrap(); + GameObject linkedTrap = go.GetLinkedTrap(); if (linkedTrap) { linkedTrap.CopyPhaseFrom(m_caster); @@ -3506,10 +3505,7 @@ namespace Game.Spells } //CREATE DUEL FLAG OBJECT - GameObject pGameObj = new GameObject(); - - int gameobject_id = effectInfo.MiscValue; - + Map map = m_caster.GetMap(); Position pos = new Position() { posX = m_caster.GetPositionX() + (unitTarget.GetPositionX() - m_caster.GetPositionX()) / 2, @@ -3517,29 +3513,29 @@ namespace Game.Spells posZ = m_caster.GetPositionZ(), Orientation = m_caster.GetOrientation() }; - - Map map = m_caster.GetMap(); Quaternion rotation = new Quaternion(Matrix3.fromEulerAnglesZYX(pos.GetOrientation(), 0.0f, 0.0f)); - if (!pGameObj.Create((uint)gameobject_id, map, pos, rotation, 0, GameObjectState.Ready)) + + GameObject go = GameObject.CreateGameObject((uint)effectInfo.MiscValue, map, pos, rotation, 0, GameObjectState.Ready); + if (!go) return; - pGameObj.CopyPhaseFrom(m_caster); + go.CopyPhaseFrom(m_caster); - pGameObj.SetUInt32Value(GameObjectFields.Faction, m_caster.getFaction()); - pGameObj.SetUInt32Value(GameObjectFields.Level, m_caster.getLevel() + 1); + go.SetUInt32Value(GameObjectFields.Faction, m_caster.getFaction()); + go.SetUInt32Value(GameObjectFields.Level, m_caster.getLevel() + 1); int duration = m_spellInfo.CalcDuration(m_caster); - pGameObj.SetRespawnTime(duration > 0 ? duration / Time.InMilliseconds : 0); - pGameObj.SetSpellId(m_spellInfo.Id); + go.SetRespawnTime(duration > 0 ? duration / Time.InMilliseconds : 0); + go.SetSpellId(m_spellInfo.Id); - ExecuteLogEffectSummonObject(effIndex, pGameObj); + ExecuteLogEffectSummonObject(effIndex, go); - m_caster.AddGameObject(pGameObj); - map.AddToMap(pGameObj); + m_caster.AddGameObject(go); + map.AddToMap(go); //END // Send request DuelRequested packet = new DuelRequested(); - packet.ArbiterGUID = pGameObj.GetGUID(); + packet.ArbiterGUID = go.GetGUID(); packet.RequestedByGUID = caster.GetGUID(); packet.RequestedByWowAccount = caster.GetSession().GetAccountGUID(); @@ -3563,8 +3559,8 @@ namespace Game.Spells duel2.isMounted = (GetSpellInfo().Id == 62875); // Mounted Duel target.duel = duel2; - caster.SetGuidValue(PlayerFields.DuelArbiter, pGameObj.GetGUID()); - target.SetGuidValue(PlayerFields.DuelArbiter, pGameObj.GetGUID()); + caster.SetGuidValue(PlayerFields.DuelArbiter, go.GetGUID()); + target.SetGuidValue(PlayerFields.DuelArbiter, go.GetGUID()); Global.ScriptMgr.OnPlayerDuelRequest(target, caster); } @@ -3836,7 +3832,6 @@ namespace Game.Spells if (effectHandleMode != SpellEffectHandleMode.Hit) return; - uint go_id = (uint)effectInfo.MiscValue; byte slot = (byte)(effectInfo.Effect - SpellEffectName.SummonObjectSlot1); ObjectGuid guid = m_caster.m_ObjectSlot[slot]; if (!guid.IsEmpty()) @@ -3852,8 +3847,6 @@ namespace Game.Spells m_caster.m_ObjectSlot[slot].Clear(); } - GameObject go = new GameObject(); - float x, y, z; // If dest location if present if (m_targets.HasDst()) @@ -3863,8 +3856,10 @@ namespace Game.Spells m_caster.GetClosePoint(out x, out y, out z, SharedConst.DefaultWorldObjectSize); Map map = m_caster.GetMap(); + Position pos = new Position(x, y, z, m_caster.GetOrientation()); Quaternion rotation = new Quaternion(Matrix3.fromEulerAnglesZYX(m_caster.GetOrientation(), 0.0f, 0.0f)); - if (!go.Create(go_id, map, new Position(x, y, z, m_caster.GetOrientation()), rotation, 255, GameObjectState.Ready)) + GameObject go = GameObject.CreateGameObject((uint)effectInfo.MiscValue, map, pos, rotation, 255, GameObjectState.Ready); + if (!go) return; go.CopyPhaseFrom(m_caster); @@ -4548,14 +4543,13 @@ namespace Game.Spells if (goinfo.type == GameObjectTypes.Ritual) m_caster.GetPosition(out fx, out fy, out fz); - GameObject pGameObj = new GameObject(); - Position pos = new Position(fx, fy, fz, m_caster.GetOrientation()); Quaternion rotation = new Quaternion(Matrix3.fromEulerAnglesZYX(m_caster.GetOrientation(), 0.0f, 0.0f)); - if (!pGameObj.Create(name_id, cMap, pos, rotation, 255, GameObjectState.Ready)) + GameObject go = GameObject.CreateGameObject(name_id, cMap, pos, rotation, 255, GameObjectState.Ready); + if (!go) return; - pGameObj.CopyPhaseFrom(m_caster); + go.CopyPhaseFrom(m_caster); int duration = m_spellInfo.CalcDuration(m_caster); @@ -4563,11 +4557,11 @@ namespace Game.Spells { case GameObjectTypes.FishingNode: { - pGameObj.SetFaction(m_caster.getFaction()); - ObjectGuid bobberGuid = pGameObj.GetGUID(); + go.SetFaction(m_caster.getFaction()); + ObjectGuid bobberGuid = go.GetGUID(); // client requires fishing bobber guid in channel object slot 0 to be usable m_caster.SetDynamicStructuredValue(UnitDynamicFields.ChannelObjects, 0, bobberGuid); - m_caster.AddGameObject(pGameObj); // will removed at spell cancel + m_caster.AddGameObject(go); // will removed at spell cancel // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo)) // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME) @@ -4587,13 +4581,13 @@ namespace Game.Spells { if (m_caster.IsTypeId(TypeId.Player)) { - pGameObj.AddUniqueUse(m_caster.ToPlayer()); - m_caster.AddGameObject(pGameObj); // will be removed at spell cancel + go.AddUniqueUse(m_caster.ToPlayer()); + m_caster.AddGameObject(go); // will be removed at spell cancel } break; } case GameObjectTypes.DuelArbiter: // 52991 - m_caster.AddGameObject(pGameObj); + m_caster.AddGameObject(go); break; case GameObjectTypes.FishingHole: case GameObjectTypes.Chest: @@ -4601,16 +4595,16 @@ namespace Game.Spells break; } - pGameObj.SetRespawnTime(duration > 0 ? duration / Time.InMilliseconds : 0); - pGameObj.SetOwnerGUID(m_caster.GetGUID()); - pGameObj.SetSpellId(m_spellInfo.Id); + go.SetRespawnTime(duration > 0 ? duration / Time.InMilliseconds : 0); + go.SetOwnerGUID(m_caster.GetGUID()); + go.SetSpellId(m_spellInfo.Id); - ExecuteLogEffectSummonObject(effIndex, pGameObj); + ExecuteLogEffectSummonObject(effIndex, go); Log.outDebug(LogFilter.Spells, "AddObject at SpellEfects.cpp EffectTransmitted"); - cMap.AddToMap(pGameObj); - GameObject linkedTrap = pGameObj.GetLinkedTrap(); + cMap.AddToMap(go); + GameObject linkedTrap = go.GetLinkedTrap(); if (linkedTrap != null) { linkedTrap.CopyPhaseFrom(m_caster); @@ -5401,9 +5395,7 @@ namespace Game.Spells uint triggerEntry = (uint)effectInfo.MiscValue; int duration = GetSpellInfo().CalcDuration(GetCaster()); - AreaTrigger areaTrigger = new AreaTrigger(); - if (!areaTrigger.CreateAreaTrigger((uint)effectInfo.MiscValue, GetCaster(), null, GetSpellInfo(), destTarget.GetPosition(), duration, m_SpellVisual, m_castId)) - areaTrigger.Dispose(); + AreaTrigger.CreateAreaTrigger((uint)effectInfo.MiscValue, GetCaster(), null, GetSpellInfo(), destTarget.GetPosition(), duration, m_SpellVisual, m_castId); } [SpellEffectHandler(SpellEffectName.RemoveTalent)] diff --git a/Source/Scripts/Northrend/Nexus/EyeOfEternity/EyeOfEternity.cs b/Source/Scripts/Northrend/Nexus/EyeOfEternity/EyeOfEternity.cs index 04f6958de..9f8ee6b43 100644 --- a/Source/Scripts/Northrend/Nexus/EyeOfEternity/EyeOfEternity.cs +++ b/Source/Scripts/Northrend/Nexus/EyeOfEternity/EyeOfEternity.cs @@ -143,8 +143,8 @@ namespace Scripts.Northrend.Nexus.EyeOfEternity // There is no other way afaik... void SpawnGameObject(uint entry, Position pos) { - GameObject go = new GameObject(); - if (go.Create(entry, instance, pos, Quaternion.WAxis, 255, GameObjectState.Ready)) + GameObject go = GameObject.CreateGameObject(entry, instance, pos, Quaternion.WAxis, 255, GameObjectState.Ready); + if (go) instance.AddToMap(go); }