diff options
Diffstat (limited to 'src')
22 files changed, 344 insertions, 369 deletions
diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index aa3161ebfcd..4662fb2636f 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -797,25 +797,20 @@ Creature* Battlefield::SpawnCreature(uint32 entry, Position const& pos) return nullptr; } - CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry); - if (!cinfo) + if (!sObjectMgr->GetCreatureTemplate(entry)) { TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: entry %u does not exist.", entry); return nullptr; } - float x, y, z, o; - pos.GetPosition(x, y, z, 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) { TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: Can't create creature entry: %u", entry); - delete creature; return nullptr; } - creature->SetHomePosition(x, y, z, o); + creature->SetHomePosition(pos); // Set creature in world map->AddToMap(creature); @@ -835,19 +830,17 @@ GameObject* Battlefield::SpawnGameObject(uint32 entry, Position const& pos, Quat return nullptr; } - GameObjectTemplate const* goInfo = sObjectMgr->GetGameObjectTemplate(entry); - if (!goInfo) + if (!sObjectMgr->GetGameObjectTemplate(entry)) { TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: GameObject template %u not found in database! Battlefield not created!", entry); return nullptr; } // Create gameobject - GameObject* go = new GameObject(); - if (!go->Create(entry, map, pos, rot, 255, GO_STATE_READY)) + GameObject* go = GameObject::CreateGameObject(entry, map, pos, rot, 255, GO_STATE_READY); + if (!go) { TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Could not create gameobject template %u! Battlefield has not been created!", entry); - delete go; return nullptr; } diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 3a8a72dc3a0..152f56c2d8f 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1388,12 +1388,11 @@ bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float // 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(), Position(x, y, z, o), rot, 255, goState)) + GameObject* go = GameObject::CreateGameObject(entry, GetBgMap(), Position(x, y, z, o), rot, 255, goState); + if (!go) { TC_LOG_ERROR("bg.battleground", "Battleground::AddObject: cannot create gameobject (entry: %u) for BG (map: %u, instance id: %u)!", entry, m_MapId, m_InstanceID); - delete go; return false; } @@ -1517,7 +1516,14 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, Map* map = FindBgMap(); if (!map) - return NULL; + return nullptr; + + if (!sObjectMgr->GetCreatureTemplate(entry)) + { + TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: creature template (entry: %u) does not exist for BG (map: %u, instance id: %u)!", + entry, m_MapId, m_InstanceID); + return nullptr; + } if (transport) { @@ -1527,34 +1533,25 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, return creature; } - return NULL; + return nullptr; } - Creature* creature = new Creature(); + Position pos = { x, y, z, o }; - if (!creature->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, entry, x, y, z, o)) + Creature* creature = Creature::CreateCreature(entry, map, pos); + if (!creature) { TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: cannot create creature (entry: %u) for BG (map: %u, instance id: %u)!", entry, m_MapId, m_InstanceID); - delete creature; - return NULL; + return nullptr; } - creature->SetHomePosition(x, y, z, o); - - CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry); - if (!cinfo) - { - TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: creature template (entry: %u) does not exist for BG (map: %u, instance id: %u)!", - entry, m_MapId, m_InstanceID); - delete creature; - return NULL; - } + creature->SetHomePosition(pos); if (!map->AddToMap(creature)) { delete creature; - return NULL; + return nullptr; } BgCreatures[type] = creature->GetGUID(); diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index b5240737bfd..671ca840102 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -86,7 +86,7 @@ void AreaTrigger::RemoveFromWorld() } } -bool AreaTrigger::CreateAreaTrigger(uint32 spellMiscId, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, uint32 spellXSpellVisualId, ObjectGuid const& castId /*= ObjectGuid::Empty*/, AuraEffect const* aurEff) +bool AreaTrigger::Create(uint32 spellMiscId, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, uint32 spellXSpellVisualId, ObjectGuid const& castId, AuraEffect const* aurEff) { _targetGuid = target ? target->GetGUID() : ObjectGuid::Empty; _aurEff = aurEff; @@ -172,6 +172,18 @@ bool AreaTrigger::CreateAreaTrigger(uint32 spellMiscId, Unit* caster, Unit* targ return true; } +AreaTrigger* AreaTrigger::CreateAreaTrigger(uint32 spellMiscId, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, uint32 spellXSpellVisualId, ObjectGuid const& castId /*= ObjectGuid::Empty*/, AuraEffect const* aurEff /*= nullptr*/) +{ + AreaTrigger* at = new AreaTrigger(); + if (!at->Create(spellMiscId, caster, target, spell, pos, duration, spellXSpellVisualId, castId, aurEff)) + { + delete at; + return nullptr; + } + + return at; +} + void AreaTrigger::Update(uint32 diff) { WorldObject::Update(diff); diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h index 4332e57bf93..c4008c8e728 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h @@ -55,7 +55,11 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge AreaTriggerAI* AI() { return _ai.get(); } - bool CreateAreaTrigger(uint32 triggerEntry, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, uint32 spellXSpellVisualId, ObjectGuid const& castId = ObjectGuid::Empty, AuraEffect const* aurEff = nullptr); + private: + bool Create(uint32 spellMiscId, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, uint32 spellXSpellVisualId, ObjectGuid const& castId, AuraEffect const* aurEff); + public: + static AreaTrigger* CreateAreaTrigger(uint32 spellMiscId, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, uint32 spellXSpellVisualId, ObjectGuid const& castId = ObjectGuid::Empty, AuraEffect const* aurEff = nullptr); + void Update(uint32 p_time) override; void Remove(); bool IsRemoved() const { return _isRemoved; } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index c18b89a6840..e6b604d074a 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -943,6 +943,40 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, float return true; } +Creature* Creature::CreateCreature(uint32 entry, Map* map, Position const& pos, uint32 vehId /*= 0*/) +{ + CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry); + if (!cInfo) + return nullptr; + + ObjectGuid::LowType lowGuid; + if (vehId || cInfo->VehicleId) + 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(), nullptr, vehId)) + { + delete creature; + return nullptr; + } + + return creature; +} + +Creature* Creature::CreateCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap /*= true*/, bool allowDuplicate /*= false*/) +{ + Creature* creature = new Creature(); + if (!creature->LoadCreatureFromDB(spawnId, map, addToMap, allowDuplicate)) + { + delete creature; + return nullptr; + } + + return creature; +} + void Creature::InitializeReactState() { if (IsTotem() || IsTrigger() || IsCritter() || IsSpiritService()) @@ -1413,7 +1447,7 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool ad m_spawnId = spawnId; m_creatureData = data; - if (!Create(map->GenerateLowGuid<HighGuid::Creature>(), map, data->id, data->posX, data->posY, data->posZ, data->orientation, 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 diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 1630a745575..b5ee31479b8 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -62,7 +62,6 @@ typedef std::unordered_map<uint8, CreatureTextRepeatIds> CreatureTextRepeatGroup class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public MapObject { public: - explicit Creature(bool isWorldObject = false); virtual ~Creature(); @@ -74,7 +73,11 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma void DisappearAndDie(); - bool Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, float x, float y, float z, float ang, CreatureData const* data = nullptr, uint32 vehId = 0); + bool Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, float x, float y, float z, float ang, CreatureData const* data, uint32 vehId); + + static Creature* CreateCreature(uint32 entry, Map* map, Position const& pos, uint32 vehId = 0); + static Creature* CreateCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap = true, bool allowDuplicate = false); + bool LoadCreaturesAddon(); void SelectLevel(); void UpdateLevelDependantStats(); @@ -175,8 +178,10 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma void setDeathState(DeathState s) override; // override virtual Unit::setDeathState - bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map) { return LoadCreatureFromDB(spawnId, map, false); } - bool LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap = true, bool allowDuplicate = false); + bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map) { return LoadCreatureFromDB(spawnId, map, false, false); } + private: + bool LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap, bool allowDuplicate); + public: void SaveToDB(); // overriden in Pet virtual void SaveToDB(uint32 mapid, uint64 spawnMask); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index e33d099b2ac..ba2d4501301 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -197,7 +197,7 @@ void GameObject::RemoveFromWorld() } } -bool GameObject::Create(uint32 name_id, Map* map, Position const& pos, QuaternionData const& rotation, uint32 animprogress, GOState go_state, uint32 artKit /*= 0*/) +bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionData const& rotation, uint32 animProgress, GOState goState, uint32 artKit) { ASSERT(map); SetMap(map); @@ -206,34 +206,34 @@ bool GameObject::Create(uint32 name_id, Map* map, Position const& pos, Quaternio m_stationaryPosition.Relocate(pos); if (!IsPositionValid()) { - TC_LOG_ERROR("misc", "Gameobject (Spawn id: " UI64FMTD " Entry: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)", GetSpawnId(), name_id, pos.GetPositionX(), pos.GetPositionY()); + TC_LOG_ERROR("misc", "Gameobject (Spawn id: " UI64FMTD " Entry: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)", GetSpawnId(), entry, pos.GetPositionX(), pos.GetPositionY()); return false; } SetZoneScript(); if (m_zoneScript) { - name_id = m_zoneScript->GetGameObjectEntry(m_spawnId, name_id); - if (!name_id) + entry = m_zoneScript->GetGameObjectEntry(m_spawnId, entry); + if (!entry) return false; } - GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id); - if (!goinfo) + GameObjectTemplate const* goInfo = sObjectMgr->GetGameObjectTemplate(entry); + if (!goInfo) { - TC_LOG_ERROR("sql.sql", "Gameobject (Spawn id: " UI64FMTD " Entry: %u) not created: non-existing entry in `gameobject_template`. Map: %u (X: %f Y: %f Z: %f)", GetSpawnId(), name_id, map->GetId(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); + TC_LOG_ERROR("sql.sql", "Gameobject (Spawn id: " UI64FMTD " Entry: %u) not created: non-existing entry in `gameobject_template`. Map: %u (X: %f Y: %f Z: %f)", GetSpawnId(), entry, map->GetId(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); return false; } - if (goinfo->type == GAMEOBJECT_TYPE_MAP_OBJ_TRANSPORT) + if (goInfo->type == GAMEOBJECT_TYPE_MAP_OBJ_TRANSPORT) { - TC_LOG_ERROR("sql.sql", "Gameobject (Spawn id: " UI64FMTD " Entry: %u) not created: gameobject type GAMEOBJECT_TYPE_MAP_OBJ_TRANSPORT cannot be manually created.", GetSpawnId(), name_id); + TC_LOG_ERROR("sql.sql", "Gameobject (Spawn id: " UI64FMTD " Entry: %u) not created: gameobject type GAMEOBJECT_TYPE_MAP_OBJ_TRANSPORT cannot be manually created.", GetSpawnId(), entry); return false; } ObjectGuid guid; - if (goinfo->type != GAMEOBJECT_TYPE_TRANSPORT) - guid = ObjectGuid::Create<HighGuid::GameObject>(map->GetId(), goinfo->entry, map->GenerateLowGuid<HighGuid::GameObject>()); + if (goInfo->type != GAMEOBJECT_TYPE_TRANSPORT) + guid = ObjectGuid::Create<HighGuid::GameObject>(map->GetId(), goInfo->entry, map->GenerateLowGuid<HighGuid::GameObject>()); else { guid = ObjectGuid::Create<HighGuid::Transport>(map->GenerateLowGuid<HighGuid::Transport>()); @@ -242,12 +242,12 @@ bool GameObject::Create(uint32 name_id, Map* map, Position const& pos, Quaternio Object::_Create(guid); - m_goInfo = goinfo; - m_goTemplateAddon = sObjectMgr->GetGameObjectTemplateAddon(name_id); + m_goInfo = goInfo; + m_goTemplateAddon = sObjectMgr->GetGameObjectTemplateAddon(entry); - if (goinfo->type >= MAX_GAMEOBJECT_TYPE) + if (goInfo->type >= MAX_GAMEOBJECT_TYPE) { - TC_LOG_ERROR("sql.sql", "Gameobject (%s Spawn id: " UI64FMTD " Entry: %u) not created: non-existing GO type '%u' in `gameobject_template`. It will crash client if created.", guid.ToString().c_str(), GetSpawnId(), name_id, goinfo->type); + TC_LOG_ERROR("sql.sql", "Gameobject (%s Spawn id: " UI64FMTD " Entry: %u) not created: non-existing GO type '%u' in `gameobject_template`. It will crash client if created.", guid.ToString().c_str(), GetSpawnId(), entry, goInfo->type); return false; } @@ -261,7 +261,7 @@ bool GameObject::Create(uint32 name_id, Map* map, Position const& pos, Quaternio SetParentRotation(parentRotation); - SetObjectScale(goinfo->size); + SetObjectScale(goInfo->size); if (m_goTemplateAddon) { @@ -275,24 +275,24 @@ bool GameObject::Create(uint32 name_id, Map* map, Position const& pos, Quaternio } } - 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(GameobjectTypes(goinfo->type)); - m_prevGoState = go_state; - SetGoState(go_state); + SetGoType(GameobjectTypes(goInfo->type)); + m_prevGoState = goState; + SetGoState(goState); SetGoArtKit(artKit); - switch (goinfo->type) + switch (goInfo->type) { case GAMEOBJECT_TYPE_FISHINGHOLE: - SetGoAnimProgress(animprogress); + SetGoAnimProgress(animProgress); m_goValue.FishingHole.MaxOpens = urand(GetGOInfo()->fishingHole.minRestock, GetGOInfo()->fishingHole.maxRestock); break; case GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING: @@ -304,37 +304,37 @@ bool GameObject::Create(uint32 name_id, Map* map, Position const& pos, Quaternio break; case GAMEOBJECT_TYPE_TRANSPORT: { - m_goValue.Transport.AnimationInfo = sTransportMgr->GetTransportAnimInfo(goinfo->entry); + m_goValue.Transport.AnimationInfo = sTransportMgr->GetTransportAnimInfo(goInfo->entry); m_goValue.Transport.PathProgress = getMSTime(); if (m_goValue.Transport.AnimationInfo) 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 std::vector<uint32>(); - if (goinfo->transport.Timeto2ndfloor > 0) - m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto2ndfloor); - if (goinfo->transport.Timeto3rdfloor > 0) - m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto3rdfloor); - if (goinfo->transport.Timeto4thfloor > 0) - m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto4thfloor); - if (goinfo->transport.Timeto5thfloor > 0) - m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto5thfloor); - if (goinfo->transport.Timeto6thfloor > 0) - m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto6thfloor); - if (goinfo->transport.Timeto7thfloor > 0) - m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto7thfloor); - if (goinfo->transport.Timeto8thfloor > 0) - m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto8thfloor); - if (goinfo->transport.Timeto9thfloor > 0) - m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto9thfloor); - if (goinfo->transport.Timeto10thfloor > 0) - m_goValue.Transport.StopFrames->push_back(goinfo->transport.Timeto10thfloor); - if (goinfo->transport.startOpen) - SetTransportState(GO_STATE_TRANSPORT_STOPPED, goinfo->transport.startOpen - 1); + if (goInfo->transport.Timeto2ndfloor > 0) + m_goValue.Transport.StopFrames->push_back(goInfo->transport.Timeto2ndfloor); + if (goInfo->transport.Timeto3rdfloor > 0) + m_goValue.Transport.StopFrames->push_back(goInfo->transport.Timeto3rdfloor); + if (goInfo->transport.Timeto4thfloor > 0) + m_goValue.Transport.StopFrames->push_back(goInfo->transport.Timeto4thfloor); + if (goInfo->transport.Timeto5thfloor > 0) + m_goValue.Transport.StopFrames->push_back(goInfo->transport.Timeto5thfloor); + if (goInfo->transport.Timeto6thfloor > 0) + m_goValue.Transport.StopFrames->push_back(goInfo->transport.Timeto6thfloor); + if (goInfo->transport.Timeto7thfloor > 0) + m_goValue.Transport.StopFrames->push_back(goInfo->transport.Timeto7thfloor); + if (goInfo->transport.Timeto8thfloor > 0) + m_goValue.Transport.StopFrames->push_back(goInfo->transport.Timeto8thfloor); + if (goInfo->transport.Timeto9thfloor > 0) + m_goValue.Transport.StopFrames->push_back(goInfo->transport.Timeto9thfloor); + if (goInfo->transport.Timeto10thfloor > 0) + m_goValue.Transport.StopFrames->push_back(goInfo->transport.Timeto10thfloor); + if (goInfo->transport.startOpen) + SetTransportState(GO_STATE_TRANSPORT_STOPPED, goInfo->transport.startOpen - 1); else SetTransportState(GO_STATE_TRANSPORT_ACTIVE); - SetGoAnimProgress(animprogress); + SetGoAnimProgress(animProgress); break; } case GAMEOBJECT_TYPE_FISHINGNODE: @@ -355,7 +355,7 @@ bool GameObject::Create(uint32 name_id, Map* map, Position const& pos, Quaternio } break; default: - SetGoAnimProgress(animprogress); + SetGoAnimProgress(animProgress); break; } @@ -380,19 +380,45 @@ bool GameObject::Create(uint32 name_id, Map* map, Position const& pos, Quaternio if (uint32 linkedEntry = GetGOInfo()->GetLinkedGameObjectEntry()) { - GameObject* linkedGO = new GameObject(); - if (linkedGO->Create(linkedEntry, map, pos, rotation, 255, GO_STATE_READY)) + if (GameObject* linkedGo = GameObject::CreateGameObject(linkedEntry, map, pos, rotation, 255, GO_STATE_READY)) { - SetLinkedTrap(linkedGO); - map->AddToMap(linkedGO); + SetLinkedTrap(linkedGo); + if (!map->AddToMap(linkedGo)) + delete linkedGo; } - else - delete linkedGO; } return true; } +GameObject* GameObject::CreateGameObject(uint32 entry, Map* map, Position const& pos, QuaternionData const& rotation, uint32 animProgress, GOState goState, uint32 artKit /*= 0*/) +{ + GameObjectTemplate const* goInfo = sObjectMgr->GetGameObjectTemplate(entry); + if (!goInfo) + return nullptr; + + GameObject* go = new GameObject(); + if (!go->Create(entry, map, pos, rotation, animProgress, goState, artKit)) + { + delete go; + return nullptr; + } + + return go; +} + +GameObject* GameObject::CreateGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap /*= true*/) +{ + GameObject* go = new GameObject(); + if (!go->LoadGameObjectFromDB(spawnId, map, addToMap)) + { + delete go; + return nullptr; + } + + return go; +} + void GameObject::Update(uint32 diff) { if (AI()) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 73730efd58a..d43306e9983 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -91,7 +91,12 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void RemoveFromWorld() override; void CleanupsBeforeDelete(bool finalCleanup = true) override; - bool Create(uint32 name_id, Map* map, Position const& pos, QuaternionData const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0); + private: + bool Create(uint32 entry, Map* map, Position const& pos, QuaternionData const& rotation, uint32 animProgress, GOState goState, uint32 artKit); + public: + static GameObject* CreateGameObject(uint32 entry, Map* map, Position const& pos, QuaternionData const& rotation, uint32 animProgress, GOState goState, uint32 artKit = 0); + static GameObject* CreateGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap = true); + void Update(uint32 p_time) override; GameObjectTemplate const* GetGOInfo() const { return m_goInfo; } GameObjectTemplateAddon const* GetTemplateAddon() const { return m_goTemplateAddon; } @@ -116,7 +121,9 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void SaveToDB(); void SaveToDB(uint32 mapid, uint64 spawnMask); bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map) { return LoadGameObjectFromDB(spawnId, map, false); } - bool LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap = true); + private: + bool LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap); + public: void DeleteFromDB(); void SetOwnerGUID(ObjectGuid owner) diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index fd2b2ff6dfc..75fd5ed1248 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2397,11 +2397,11 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert break; } default: - return NULL; + return nullptr; } } - TempSummon* summon = NULL; + TempSummon* summon = nullptr; switch (mask) { case UNIT_MASK_SUMMON: @@ -2424,7 +2424,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert if (!summon->Create(GenerateLowGuid<HighGuid::Creature>(), this, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), nullptr, vehId)) { delete summon; - return NULL; + return nullptr; } // Set the summon to the summoner's phase @@ -2529,12 +2529,9 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, Position const& pos, Qua } Map* map = GetMap(); - GameObject* go = new GameObject(); - if (!go->Create(entry, map, pos, rot, 255, GO_STATE_READY)) - { - delete go; + GameObject* go = GameObject::CreateGameObject(entry, map, pos, rot, 255, GO_STATE_READY); + if (!go) return nullptr; - } go->CopyPhaseFrom(this); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 2290a1e9962..5a687b8387b 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -294,13 +294,10 @@ void Transport::RemovePassenger(WorldObject* passenger) Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData const* data) { Map* map = GetMap(); - Creature* creature = new Creature(); - if (!creature->LoadCreatureFromDB(guid, map, false)) - { - delete creature; - return NULL; - } + Creature* creature = Creature::CreateCreatureFromDB(guid, map, false); + if (!creature) + return nullptr; ASSERT(data); @@ -326,7 +323,7 @@ Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData c { TC_LOG_ERROR("entities.transport", "Passenger %s not created. Suggested coordinates aren't valid (X: %f Y: %f)", creature->GetGUID().ToString().c_str(), creature->GetPositionX(), creature->GetPositionY()); delete creature; - return NULL; + return nullptr; } if (data->phaseId) @@ -340,7 +337,7 @@ Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData c if (!map->AddToMap(creature)) { delete creature; - return NULL; + return nullptr; } _staticPassengers.insert(creature); @@ -351,13 +348,10 @@ Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData c GameObject* Transport::CreateGOPassenger(ObjectGuid::LowType guid, GameObjectData const* data) { Map* map = GetMap(); - GameObject* go = new GameObject(); - if (!go->LoadGameObjectFromDB(guid, map, false)) - { - delete go; - return NULL; - } + GameObject* go = GameObject::CreateGameObjectFromDB(guid, map, false); + if (!go) + return nullptr; ASSERT(data); @@ -378,13 +372,13 @@ GameObject* Transport::CreateGOPassenger(ObjectGuid::LowType guid, GameObjectDat { TC_LOG_ERROR("entities.transport", "Passenger %s not created. Suggested coordinates aren't valid (X: %f Y: %f)", go->GetGUID().ToString().c_str(), go->GetPositionX(), go->GetPositionY()); delete go; - return NULL; + return nullptr; } if (!map->AddToMap(go)) { delete go; - return NULL; + return nullptr; } _staticPassengers.insert(go); @@ -451,7 +445,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu else phases = GetPhases(); // If there was no summoner, try to use the transport phases - TempSummon* summon = NULL; + TempSummon* summon = nullptr; switch (mask) { case UNIT_MASK_SUMMON: @@ -478,7 +472,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu if (!summon->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, entry, x, y, z, o, nullptr, vehId)) { delete summon; - return NULL; + return nullptr; } for (uint32 phase : phases) @@ -502,7 +496,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu if (!map->AddToMap<Creature>(summon)) { delete summon; - return NULL; + return nullptr; } _staticPassengers.insert(summon); diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index 916001a3e20..27d03e7c002 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -1217,12 +1217,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id) Map* map = sMapMgr->CreateBaseMap(data->mapid); // We use spawn coords to spawn if (!map->Instanceable() && map->IsGridLoaded(data->posX, data->posY)) - { - Creature* creature = new Creature(); - //TC_LOG_DEBUG("misc", "Spawning creature %u", *itr); - if (!creature->LoadCreatureFromDB(*itr, map)) - delete creature; - } + Creature::CreateCreatureFromDB(*itr, map); } } @@ -1245,15 +1240,14 @@ void GameEventMgr::GameEventSpawn(int16 event_id) // 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; - //TC_LOG_DEBUG("misc", "Spawning gameobject %u", *itr); - /// @todo find out when it is add to map - if (!pGameobject->LoadGameObjectFromDB(*itr, map, false)) - delete pGameobject; - else + if (GameObject* go = GameObject::CreateGameObjectFromDB(*itr, map, false)) { - if (pGameobject->isSpawnedByDefault()) - map->AddToMap(pGameobject); + /// @todo find out when it is add to map + if (go->isSpawnedByDefault()) + { + if (!map->AddToMap(go)) + delete go; + } } } } diff --git a/src/server/game/Garrison/Garrison.cpp b/src/server/game/Garrison/Garrison.cpp index 22ac16d443f..e344e19b8f9 100644 --- a/src/server/game/Garrison/Garrison.cpp +++ b/src/server/game/Garrison/Garrison.cpp @@ -730,20 +730,16 @@ GameObject* Garrison::Plot::CreateGameObject(Map* map, GarrisonFactionIndex fact return nullptr; } - GameObject* building = new GameObject(); - if (!building->Create(entry, map, PacketInfo.PlotPos.Pos, QuaternionData(), 255, GO_STATE_READY)) - { - delete building; + GameObject* building = GameObject::CreateGameObject(entry, map, PacketInfo.PlotPos.Pos, QuaternionData(), 255, GO_STATE_READY); + if (!building) return nullptr; - } if (BuildingInfo.CanActivate() && BuildingInfo.PacketInfo && !BuildingInfo.PacketInfo->Active) { if (FinalizeGarrisonPlotGOInfo const* finalizeInfo = sGarrisonMgr.GetPlotFinalizeGOInfo(PacketInfo.GarrPlotInstanceID)) { Position const& pos2 = finalizeInfo->FactionInfo[faction].Pos; - GameObject* finalizer = new GameObject(); - if (finalizer->Create(finalizeInfo->FactionInfo[faction].GameObjectId, map, pos2, QuaternionData(), 255, GO_STATE_READY)) + if (GameObject* finalizer = GameObject::CreateGameObject(finalizeInfo->FactionInfo[faction].GameObjectId, map, pos2, QuaternionData(), 255, GO_STATE_READY)) { // set some spell id to make the object delete itself after use finalizer->SetSpellId(finalizer->GetGOInfo()->goober.spell); @@ -754,8 +750,6 @@ GameObject* Garrison::Plot::CreateGameObject(Map* map, GarrisonFactionIndex fact map->AddToMap(finalizer); } - else - delete finalizer; } } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index e17286abc18..d030149640d 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2132,11 +2132,10 @@ ObjectGuid::LowType ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, fl // 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) { TC_LOG_ERROR("misc", "AddGOData: cannot add gameobject entry %u to map", entry); - delete go; return UI64LIT(0); } } @@ -2185,11 +2184,10 @@ ObjectGuid::LowType ObjectMgr::AddCreatureData(uint32 entry, uint32 mapId, float // 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) { TC_LOG_ERROR("misc", "AddCreature: Cannot add creature entry %u to map", entry); - delete creature; return UI64LIT(0); } } diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index b3cdbfae513..8f5f8b14da3 100644 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -389,15 +389,7 @@ void PoolGroup<Creature>::Spawn1Object(PoolObject* obj) Map* map = sMapMgr->CreateBaseMap(data->mapid); // We use spawn coords to spawn if (!map->Instanceable() && map->IsGridLoaded(data->posX, data->posY)) - { - Creature* creature = new Creature(); - //TC_LOG_DEBUG("pool", "Spawning creature %u", guid); - if (!creature->LoadCreatureFromDB(obj->guid, map)) - { - delete creature; - return; - } - } + Creature::CreateCreatureFromDB(obj->guid, map); } } @@ -414,17 +406,13 @@ void PoolGroup<GameObject>::Spawn1Object(PoolObject* obj) // 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; - //TC_LOG_DEBUG("pool", "Spawning gameobject %u", guid); - if (!pGameobject->LoadGameObjectFromDB(obj->guid, map, false)) + if (GameObject* go = GameObject::CreateGameObjectFromDB(obj->guid, map, false)) { - delete pGameobject; - return; - } - else - { - if (pGameobject->isSpawnedByDefault()) - map->AddToMap(pGameobject); + if (go->isSpawnedByDefault()) + { + if (!map->AddToMap(go)) + delete go; + } } } } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 5cd52d19067..b3a59fbda6d 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -6139,9 +6139,7 @@ void AuraEffect::HandleCreateAreaTrigger(AuraApplication const* aurApp, uint8 mo if (apply) { - AreaTrigger* areaTrigger = new AreaTrigger(); - if (!areaTrigger->CreateAreaTrigger(GetMiscValue(), GetCaster(), target, GetSpellInfo(), *target, GetBase()->GetDuration(), GetBase()->GetSpellXSpellVisualId(), ObjectGuid::Empty, this)) - delete areaTrigger; + AreaTrigger::CreateAreaTrigger(GetMiscValue(), GetCaster(), target, GetSpellInfo(), *target, GetBase()->GetDuration(), GetBase()->GetSpellXSpellVisualId(), ObjectGuid::Empty, this); } else { diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index e81d7ef9b8c..eaab7d32b80 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3069,10 +3069,6 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - uint32 gameobject_id = effectInfo->MiscValue; - - GameObject* pGameObj = new GameObject(); - WorldObject* target = focusObject; if (!target) target = m_caster; @@ -3084,32 +3080,30 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); Map* map = target->GetMap(); - + Position pos = Position(x, y, z, target->GetOrientation()); QuaternionData rot = QuaternionData::fromEulerAnglesZYX(target->GetOrientation(), 0.f, 0.f); - if (!pGameObj->Create(gameobject_id, map, Position(x, y, z, target->GetOrientation()), rot, 255, GO_STATE_READY)) - { - delete pGameObj; + GameObject* go = GameObject::CreateGameObject(effectInfo->MiscValue, map, pos, rot, 255, GO_STATE_READY); + if (!go) return; - } - pGameObj->CopyPhaseFrom(m_caster); + go->CopyPhaseFrom(m_caster); int32 duration = m_spellInfo->CalcDuration(m_caster); - pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); - pGameObj->SetSpellId(m_spellInfo->Id); + go->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 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() == GAMEOBJECT_TYPE_FLAGDROP) + if (go->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP) if (Player* player = m_caster->ToPlayer()) if (Battleground* bg = player->GetBattleground()) - bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeam() == ALLIANCE ? TEAM_HORDE: TEAM_ALLIANCE); + bg->SetDroppedFlagGUID(go->GetGUID(), player->GetTeam() == ALLIANCE ? TEAM_HORDE: TEAM_ALLIANCE); - if (GameObject* linkedTrap = pGameObj->GetLinkedTrap()) + if (GameObject* linkedTrap = go->GetLinkedTrap()) { linkedTrap->CopyPhaseFrom(m_caster); @@ -3633,10 +3627,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex) } //CREATE DUEL FLAG OBJECT - GameObject* pGameObj = new GameObject(); - - uint32 gameobject_id = effectInfo->MiscValue; - + Map* map = m_caster->GetMap(); Position const pos = { m_caster->GetPositionX() + (unitTarget->GetPositionX() - m_caster->GetPositionX()) / 2, @@ -3644,31 +3635,29 @@ void Spell::EffectDuel(SpellEffIndex effIndex) m_caster->GetPositionZ(), m_caster->GetOrientation() }; + QuaternionData rot = QuaternionData::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f); - Map* map = m_caster->GetMap(); - if (!pGameObj->Create(gameobject_id, map, pos, QuaternionData::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f), 0, GO_STATE_READY)) - { - delete pGameObj; + GameObject* go = GameObject::CreateGameObject(effectInfo->MiscValue, map, pos, rot, 0, GO_STATE_READY); + if (!go) return; - } - pGameObj->CopyPhaseFrom(m_caster); + go->CopyPhaseFrom(m_caster); - pGameObj->SetUInt32Value(GAMEOBJECT_FACTION, m_caster->getFaction()); - pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1); + go->SetUInt32Value(GAMEOBJECT_FACTION, m_caster->getFaction()); + go->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1); int32 duration = m_spellInfo->CalcDuration(m_caster); - pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); - pGameObj->SetSpellId(m_spellInfo->Id); + go->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 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 WorldPackets::Duel::DuelRequested packet; - packet.ArbiterGUID = pGameObj->GetGUID(); + packet.ArbiterGUID = go->GetGUID(); packet.RequestedByGUID = caster->GetGUID(); packet.RequestedByWowAccount = caster->GetSession()->GetAccountGUID(); @@ -3693,8 +3682,8 @@ void Spell::EffectDuel(SpellEffIndex effIndex) duel2->isMounted = (GetSpellInfo()->Id == 62875); // Mounted Duel target->duel = duel2; - caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID()); - target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID()); + caster->SetGuidValue(PLAYER_DUEL_ARBITER, go->GetGUID()); + target->SetGuidValue(PLAYER_DUEL_ARBITER, go->GetGUID()); sScriptMgr->OnPlayerDuelRequest(target, caster); } @@ -3955,7 +3944,6 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - uint32 go_id = effectInfo->MiscValue; uint8 slot = effectInfo->Effect - SPELL_EFFECT_SUMMON_OBJECT_SLOT1; ObjectGuid guid = m_caster->m_ObjectSlot[slot]; if (!guid.IsEmpty()) @@ -3970,8 +3958,6 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) m_caster->m_ObjectSlot[slot].Clear(); } - GameObject* go = new GameObject(); - float x, y, z; // If dest location if present if (m_targets.HasDst()) @@ -3981,15 +3967,16 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); Map* map = m_caster->GetMap(); - if (!go->Create(go_id, map, Position(x, y, z, m_caster->GetOrientation()), QuaternionData::fromEulerAnglesZYX(m_caster->GetOrientation(), 0.f, 0.f), 255, GO_STATE_READY)) - { - delete go; + Position pos = Position(x, y, z, m_caster->GetOrientation()); + QuaternionData rot = QuaternionData::fromEulerAnglesZYX(m_caster->GetOrientation(), 0.f, 0.f); + + GameObject* go = GameObject::CreateGameObject(effectInfo->MiscValue, map, pos, rot, 255, GO_STATE_READY); + if (!go) return; - } go->CopyPhaseFrom(m_caster); - //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); + //go->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); int32 duration = m_spellInfo->CalcDuration(m_caster); go->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); go->SetSpellId(m_spellInfo->Id); @@ -4632,7 +4619,6 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) } GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id); - if (!goinfo) { TC_LOG_ERROR("sql.sql", "Gameobject (Entry: %u) does not exist and is not created by spell (ID: %u) cast.", name_id, m_spellInfo->Id); @@ -4664,17 +4650,14 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) if (goinfo->type == GAMEOBJECT_TYPE_RITUAL) m_caster->GetPosition(fx, fy, fz); - GameObject* pGameObj = new GameObject(); - Position pos = { fx, fy, fz, m_caster->GetOrientation() }; QuaternionData rot = QuaternionData::fromEulerAnglesZYX(m_caster->GetOrientation(), 0.f, 0.f); - if (!pGameObj->Create(name_id, cMap, pos, rot, 255, GO_STATE_READY)) - { - delete pGameObj; + + GameObject* go = GameObject::CreateGameObject(name_id, cMap, pos, rot, 255, GO_STATE_READY); + if (!go) return; - } - pGameObj->CopyPhaseFrom(m_caster); + go->CopyPhaseFrom(m_caster); int32 duration = m_spellInfo->CalcDuration(m_caster); @@ -4682,11 +4665,11 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) { case GAMEOBJECT_TYPE_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(UNIT_DYNAMIC_FIELD_CHANNEL_OBJECTS, 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) @@ -4706,13 +4689,13 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) { if (m_caster->GetTypeId() == 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 GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991 - m_caster->AddGameObject(pGameObj); + m_caster->AddGameObject(go); break; case GAMEOBJECT_TYPE_FISHINGHOLE: case GAMEOBJECT_TYPE_CHEST: @@ -4720,22 +4703,22 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) break; } - pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); + go->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); - pGameObj->SetOwnerGUID(m_caster->GetGUID()); + go->SetOwnerGUID(m_caster->GetGUID()); - //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); - pGameObj->SetSpellId(m_spellInfo->Id); + //go->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); + go->SetSpellId(m_spellInfo->Id); - ExecuteLogEffectSummonObject(effIndex, pGameObj); + ExecuteLogEffectSummonObject(effIndex, go); TC_LOG_DEBUG("spells", "AddObject at SpellEfects.cpp EffectTransmitted"); - //m_caster->AddGameObject(pGameObj); - //m_ObjToDel.push_back(pGameObj); + //m_caster->AddGameObject(go); + //m_ObjToDel.push_back(go); - cMap->AddToMap(pGameObj); + cMap->AddToMap(go); - if (GameObject* linkedTrap = pGameObj->GetLinkedTrap()) + if (GameObject* linkedTrap = go->GetLinkedTrap()) { linkedTrap->CopyPhaseFrom(m_caster); @@ -5491,9 +5474,8 @@ void Spell::EffectCreateAreaTrigger(SpellEffIndex /*effIndex*/) return; int32 duration = GetSpellInfo()->CalcDuration(GetCaster()); - AreaTrigger* areaTrigger = new AreaTrigger(); - if (!areaTrigger->CreateAreaTrigger(effectInfo->MiscValue, GetCaster(), nullptr, GetSpellInfo(), destTarget->GetPosition(), duration, m_SpellVisual, m_castId)) - delete areaTrigger; + + AreaTrigger::CreateAreaTrigger(effectInfo->MiscValue, GetCaster(), nullptr, GetSpellInfo(), destTarget->GetPosition(), duration, m_SpellVisual, m_castId); } void Spell::EffectRemoveTalent(SpellEffIndex /*effIndex*/) diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index a04ad5630f0..6e824b72288 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -938,19 +938,16 @@ public: if (!ve) return false; - Creature* v = new Creature(); - Map* map = handler->GetSession()->GetPlayer()->GetMap(); + Position pos = { x, y, z, o }; - if (!v->Create(map->GenerateLowGuid<HighGuid::Vehicle>(), map, entry, x, y, z, o, nullptr, id)) - { - delete v; + Creature* v = Creature::CreateCreature(entry, map, pos, id); + if (!v) return false; - } v->CopyPhaseFrom(handler->GetSession()->GetPlayer()); - map->AddToMap(v->ToCreature()); + map->AddToMap(v); return true; } diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index bc77d56e8a9..3f57f2c0fbc 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -142,13 +142,9 @@ public: Player* player = handler->GetSession()->GetPlayer(); Map* map = player->GetMap(); - GameObject* object = new GameObject(); - - if (!object->Create(objectInfo->entry, map, *player, QuaternionData::fromEulerAnglesZYX(player->GetOrientation(), 0.0f, 0.0f), 255, GO_STATE_READY)) - { - delete object; + GameObject* object = GameObject::CreateGameObject(objectInfo->entry, map, *player, QuaternionData::fromEulerAnglesZYX(player->GetOrientation(), 0.0f, 0.0f), 255, GO_STATE_READY); + if (!object) return false; - } object->CopyPhaseFrom(player); @@ -166,13 +162,10 @@ public: // this is required to avoid weird behavior and memory leaks delete object; - object = new GameObject(); // this will generate a new guid if the object is in an instance - if (!object->LoadGameObjectFromDB(spawnId, map)) - { - delete object; + object = GameObject::CreateGameObjectFromDB(spawnId, map); + if (!object) return false; - } /// @todo is it really necessary to add both the real and DB table guid here ? sObjectMgr->AddGameobjectToGrid(spawnId, ASSERT_NOTNULL(sObjectMgr->GetGOData(spawnId))); diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 9cf62049b0d..2ecdd51b230 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -285,10 +285,6 @@ public: 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(); if (Transport* trans = chr->GetTransport()) @@ -310,12 +306,9 @@ public: return true; } - Creature* creature = new Creature(); - if (!creature->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, id, x, y, z, o)) - { - delete creature; + Creature* creature = Creature::CreateCreature(id, map, chr->GetPosition()); + if (!creature) return false; - } creature->CopyPhaseFrom(chr); creature->SaveToDB(map->GetId(), UI64LIT(1) << map->GetSpawnMode()); @@ -326,12 +319,10 @@ public: // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior creature->CleanupsBeforeDelete(); delete creature; - creature = new Creature(); - if (!creature->LoadCreatureFromDB(db_guid, map)) - { - delete creature; + + creature = Creature::CreateCreatureFromDB(db_guid, map); + if (!creature) return false; - } sObjectMgr->AddCreatureToGrid(db_guid, sObjectMgr->GetCreatureData(db_guid)); return true; diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index 4e4fa0289ce..2fa3a081435 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -665,22 +665,27 @@ public: target->AddObjectToRemoveList(); // re-create - Creature* wpCreature = new Creature(); - if (!wpCreature->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) + Creature* wpCreature = Creature::CreateCreature(VISUAL_WAYPOINT, map, chr->GetPosition()); + if (!wpCreature) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); - delete wpCreature; return false; } wpCreature->CopyPhaseFrom(chr); wpCreature->SaveToDB(map->GetId(), UI64LIT(1) << map->GetSpawnMode()); + + ObjectGuid::LowType dbGuid = wpCreature->GetSpawnId(); + + // current "wpCreature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior + wpCreature->CleanupsBeforeDelete(); + delete wpCreature; + // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); - /// @todo Should we first use "Create" then use "LoadFromDB"? - if (!wpCreature->LoadCreatureFromDB(wpCreature->GetSpawnId(), map)) + wpCreature = Creature::CreateCreatureFromDB(dbGuid, map); + if (!wpCreature) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); - delete wpCreature; return false; } @@ -876,31 +881,29 @@ public: Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); - float o = chr->GetOrientation(); + Position pos = { x, y, z, chr->GetOrientation() }; - Creature* wpCreature = new Creature(); - if (!wpCreature->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, id, x, y, z, o)) + Creature* wpCreature = Creature::CreateCreature(id, map, pos); + if (!wpCreature) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); - delete wpCreature; return false; } wpCreature->CopyPhaseFrom(chr); wpCreature->SaveToDB(map->GetId(), UI64LIT(1) << map->GetSpawnMode()); - // Set "wpguid" column to the visual waypoint - stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); - stmt->setUInt64(0, wpCreature->GetSpawnId()); - stmt->setUInt32(1, pathid); - stmt->setUInt32(2, point); - WorldDatabase.Execute(stmt); + ObjectGuid::LowType dbGuid = wpCreature->GetSpawnId(); + + // current "wpCreature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior + wpCreature->CleanupsBeforeDelete(); + delete wpCreature; // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); - if (!wpCreature->LoadCreatureFromDB(wpCreature->GetSpawnId(), map)) + wpCreature = Creature::CreateCreatureFromDB(dbGuid, map); + if (!wpCreature) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); - delete wpCreature; return false; } @@ -910,6 +913,13 @@ public: wpCreature->SetObjectScale(0.5f); wpCreature->SetLevel(std::min<uint32>(point, STRONG_MAX_LEVEL)); } + + // Set "wpguid" column to the visual waypoint + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); + stmt->setUInt64(0, wpCreature->GetSpawnId()); + stmt->setUInt32(1, pathid); + stmt->setUInt32(2, point); + WorldDatabase.Execute(stmt); } while (result->NextRow()); @@ -939,24 +949,29 @@ public: uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); - float o = chr->GetOrientation(); Map* map = chr->GetMap(); + Position pos = { 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(id, map, pos); + if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); - delete creature; return false; } creature->CopyPhaseFrom(chr); creature->SaveToDB(map->GetId(), UI64LIT(1) << map->GetSpawnMode()); - if (!creature->LoadCreatureFromDB(creature->GetSpawnId(), map)) + ObjectGuid::LowType dbGuid = creature->GetSpawnId(); + + // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior + creature->CleanupsBeforeDelete(); + delete creature; + + creature = Creature::CreateCreatureFromDB(dbGuid, map); + if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); - delete creature; return false; } @@ -992,22 +1007,28 @@ public: Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); + Position pos = { 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(id, map, pos); + if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); - delete creature; return false; } creature->CopyPhaseFrom(chr); creature->SaveToDB(map->GetId(), UI64LIT(1) << map->GetSpawnMode()); - if (!creature->LoadCreatureFromDB(creature->GetSpawnId(), map)) + ObjectGuid::LowType dbGuid = creature->GetSpawnId(); + + // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior + creature->CleanupsBeforeDelete(); + delete creature; + + creature = Creature::CreateCreatureFromDB(dbGuid, map); + if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); - delete creature; return false; } diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index 7771e0b2781..9980c0d34db 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -89,13 +89,8 @@ public: // There is no other way afaik... void SpawnGameObject(uint32 entry, Position const& pos) { - GameObject* go = new GameObject(); - if (!go->Create(entry, instance, pos, QuaternionData(), 255, GO_STATE_READY)) - { - delete go; - return; - } - instance->AddToMap(go); + if (GameObject* go = GameObject::CreateGameObject(entry, instance, pos, QuaternionData(), 255, GO_STATE_READY)) + instance->AddToMap(go); } void OnGameObjectCreate(GameObject* go) override diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp index ef24b8a5af1..d259e8585c6 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp @@ -149,70 +149,25 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId) if (spellId == SI_SILITHYST_FLAG) { // if it was dropped away from the player's turn-in point, then create a silithyst mound, if it was dropped near the areatrigger, then it was dispelled by the outdoorpvp, so do nothing - switch (player->GetTeam()) + if (AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(player->GetTeam() == ALLIANCE ? SI_AREATRIGGER_A : SI_AREATRIGGER_H)) { - case ALLIANCE: + // 5.0f is safe-distance + if (player->GetDistance(atEntry->Pos.X, atEntry->Pos.Y, atEntry->Pos.Z) > 5.0f + atEntry->Radius) { - AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(SI_AREATRIGGER_A); - if (atEntry) + // he dropped it further, summon mound + Map* map = player->GetMap(); + if (GameObject* go = GameObject::CreateGameObject(SI_SILITHYST_MOUND, map, *player, QuaternionData(), 255, GO_STATE_READY)) { - // 5.0f is safe-distance - if (player->GetDistance(atEntry->Pos.X, atEntry->Pos.Y, atEntry->Pos.Z) > 5.0f + atEntry->Radius) - { - // he dropped it further, summon mound - GameObject* go = new GameObject(); - Map* map = player->GetMap(); - - if (!go->Create(SI_SILITHYST_MOUND, map, *player, QuaternionData(), 255, GO_STATE_READY)) - { - delete go; - return true; - } - - go->CopyPhaseFrom(player); - - go->SetRespawnTime(0); + go->CopyPhaseFrom(player); + go->SetRespawnTime(0); - if (!map->AddToMap(go)) - { - delete go; - return true; - } - } - } - } - break; - case HORDE: - { - AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(SI_AREATRIGGER_H); - if (atEntry) - { - // 5.0f is safe-distance - if (player->GetDistance(atEntry->Pos.X, atEntry->Pos.Y, atEntry->Pos.Z) > 5.0f + atEntry->Radius) + if (!map->AddToMap(go)) { - // he dropped it further, summon mound - GameObject* go = new GameObject(); - Map* map = player->GetMap(); - - if (!go->Create(SI_SILITHYST_MOUND, map, *player, QuaternionData(), 255, GO_STATE_READY)) - { - delete go; - return true; - } - - go->CopyPhaseFrom(player); - - go->SetRespawnTime(0); - - if (!map->AddToMap(go)) - { - delete go; - return true; - } + delete go; + return true; } } } - break; } return true; } |