From 468457a63ef84c2f359bf29c126c9b4b339bdf05 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Sun, 10 Aug 2025 16:12:46 +0200 Subject: [PATCH 01/57] fix(DB/Creature): En'kilah Gargoyles fly well again. (#22658) --- data/sql/updates/pending_db_world/gargoyles.sql | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 data/sql/updates/pending_db_world/gargoyles.sql diff --git a/data/sql/updates/pending_db_world/gargoyles.sql b/data/sql/updates/pending_db_world/gargoyles.sql new file mode 100644 index 000000000..0ec1048f5 --- /dev/null +++ b/data/sql/updates/pending_db_world/gargoyles.sql @@ -0,0 +1,3 @@ + +-- Remove Creature_addon tables from some Gargoyles. +DELETE FROM `creature_addon` WHERE (`guid` IN (100016, 100017, 100018, 100032, 100033, 100034, 100035, 100056, 100057, 100058, 100059, 100060, 100061)); From 72d3db08e50f48a00b4571704cf5b706cc035f60 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 10 Aug 2025 14:19:02 +0000 Subject: [PATCH 02/57] chore(DB): import pending files Referenced commit(s): 468457a63ef84c2f359bf29c126c9b4b339bdf05 --- .../gargoyles.sql => db_world/2025_08_10_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/gargoyles.sql => db_world/2025_08_10_00.sql} (82%) diff --git a/data/sql/updates/pending_db_world/gargoyles.sql b/data/sql/updates/db_world/2025_08_10_00.sql similarity index 82% rename from data/sql/updates/pending_db_world/gargoyles.sql rename to data/sql/updates/db_world/2025_08_10_00.sql index 0ec1048f5..cbbdd0811 100644 --- a/data/sql/updates/pending_db_world/gargoyles.sql +++ b/data/sql/updates/db_world/2025_08_10_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_08_01 -> 2025_08_10_00 -- Remove Creature_addon tables from some Gargoyles. DELETE FROM `creature_addon` WHERE (`guid` IN (100016, 100017, 100018, 100032, 100033, 100034, 100035, 100056, 100057, 100058, 100059, 100060, 100061)); From 5b36ba898ecc7454f8932735484d2f399bedcb12 Mon Sep 17 00:00:00 2001 From: Christian M Date: Sun, 10 Aug 2025 15:06:57 -0400 Subject: [PATCH 03/57] fix(DB/creature_loot): Remove wotlk skinning items from creature loot tables (#22645) --- data/sql/updates/pending_db_world/rev_1754674822967930380.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1754674822967930380.sql diff --git a/data/sql/updates/pending_db_world/rev_1754674822967930380.sql b/data/sql/updates/pending_db_world/rev_1754674822967930380.sql new file mode 100644 index 000000000..c564974fa --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1754674822967930380.sql @@ -0,0 +1,4 @@ +-- Delete Nerubian Chitin, Borean Leather, and Arctic Fur from loot table from various creatures in WotLK +DELETE from `creature_loot_template` WHERE `item` = 33568; +DELETE from `creature_loot_template` WHERE `item` = 44128; +DELETE from `creature_loot_template` WHERE `item` = 38558; From ba1fcf242455b05d1f1ccb6ae9ca2809fcf76a45 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 10 Aug 2025 19:08:00 +0000 Subject: [PATCH 04/57] chore(DB): import pending files Referenced commit(s): 5b36ba898ecc7454f8932735484d2f399bedcb12 --- .../rev_1754674822967930380.sql => db_world/2025_08_10_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1754674822967930380.sql => db_world/2025_08_10_01.sql} (86%) diff --git a/data/sql/updates/pending_db_world/rev_1754674822967930380.sql b/data/sql/updates/db_world/2025_08_10_01.sql similarity index 86% rename from data/sql/updates/pending_db_world/rev_1754674822967930380.sql rename to data/sql/updates/db_world/2025_08_10_01.sql index c564974fa..0629204ae 100644 --- a/data/sql/updates/pending_db_world/rev_1754674822967930380.sql +++ b/data/sql/updates/db_world/2025_08_10_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_10_00 -> 2025_08_10_01 -- Delete Nerubian Chitin, Borean Leather, and Arctic Fur from loot table from various creatures in WotLK DELETE from `creature_loot_template` WHERE `item` = 33568; DELETE from `creature_loot_template` WHERE `item` = 44128; From 2485ff7f5fbb1029132d083cbe201a46fa2ada8c Mon Sep 17 00:00:00 2001 From: Takenbacon Date: Sun, 10 Aug 2025 12:15:55 -0700 Subject: [PATCH 05/57] fix(Core/Transports): Improve static transport visibility (#22660) --- .../game/Entities/GameObject/GameObject.h | 4 +- .../Object/ObjectVisibilityContainer.cpp | 4 ++ .../game/Entities/Player/PlayerUpdates.cpp | 5 +- .../game/Entities/Transport/Transport.cpp | 43 +++++++++++++-- .../game/Entities/Transport/Transport.h | 6 ++- src/server/game/Grids/GridObjectLoader.cpp | 25 ++++++--- src/server/game/Maps/Map.cpp | 53 +++++++------------ src/server/game/Maps/Map.h | 3 +- src/server/game/Maps/TransportMgr.cpp | 4 +- 9 files changed, 92 insertions(+), 55 deletions(-) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 37605de21..1b8ccd047 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -156,8 +156,8 @@ public: void SaveToDB(bool saveAddon = false); void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask, bool saveAddon = false); - bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); } - bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true); + virtual bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); } + virtual bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true); void DeleteFromDB(); void SetOwnerGUID(ObjectGuid owner) diff --git a/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp b/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp index 9831adf5a..358626180 100644 --- a/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp +++ b/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp @@ -66,6 +66,10 @@ void ObjectVisibilityContainer::LinkWorldObjectVisibility(WorldObject* worldObje if (worldObject == _selfObject) return; + // Transports are special and should not be added to our visibility map + if (worldObject->IsGameObject() && worldObject->ToGameObject()->IsTransport()) + return; + // Only players can link visibility if (!_visibleWorldObjectsMap) return; diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 074dc4923..8426e4c8c 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -1645,10 +1645,7 @@ template <> inline void UpdateVisibilityOf_helper(Player* player, GameObject* target, std::vector& /*v*/) { - // @HACK: This is to prevent objects like deeprun tram from disappearing - // when player moves far from its spawn point while riding it - if ((target->GetGOInfo()->type != GAMEOBJECT_TYPE_TRANSPORT)) - player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target); + player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target); } template <> diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 251cdb936..ee87af41d 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -607,12 +607,12 @@ void MotionTransport::DelayedTeleportTransport() } Map* newMap = sMapMgr->CreateBaseMap(newMapId); - GetMap()->RemoveFromMap(this, false); + GetMap()->RemoveFromMap(this, false); newMap->LoadGrid(x, y); // xinef: load before adding passengers to new map SetMap(newMap); Relocate(x, y, z, o); - GetMap()->AddToMap(this); + GetMap()->AddToMap(this); LoadStaticPassengers(); } @@ -690,6 +690,40 @@ StaticTransport::~StaticTransport() ASSERT(_passengers.empty()); } +bool StaticTransport::LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap) +{ + GameObjectData const* data = sObjectMgr->GetGameObjectData(spawnId); + + if (!data) + { + LOG_ERROR("sql.sql", "Gameobject (GUID: {}) not found in table `gameobject`, can't load. ", spawnId); + return false; + } + + uint32 entry = data->id; + //uint32 map_id = data->mapid; // already used before call + uint32 phaseMask = data->phaseMask; + float x = data->posX; + float y = data->posY; + float z = data->posZ; + float ang = data->orientation; + + uint32 animprogress = data->animprogress; + GOState go_state = data->go_state; + uint32 artKit = data->artKit; + + m_goData = data; + m_spawnId = spawnId; + + if (!Create(map->GenerateLowGuid(), entry, map, phaseMask, x, y, z, ang, data->rotation, animprogress, go_state, artKit)) + return false; + + if (addToMap && !GetMap()->AddToMap(this)) + return false; + + return true; +} + bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit) { ASSERT(map); @@ -794,7 +828,6 @@ bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* m LastUsedScriptID = GetGOInfo()->ScriptId; AIM_Initialize(); - this->setActive(true); return true; } @@ -929,7 +962,9 @@ void StaticTransport::UpdatePosition(float x, float y, float z, float o) if (!GetMap()->IsGridLoaded(x, y)) // pussywizard: should not happen, but just in case GetMap()->LoadGrid(x, y); - GetMap()->GameObjectRelocation(this, x, y, z, o); // this also relocates the model + Relocate(x, y, z, o); + UpdateModelPosition(); + UpdatePassengerPositions(); } diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 005e9d789..9b50775af 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -38,6 +38,8 @@ public: virtual void RemovePassenger(WorldObject* passenger, bool withAll = false) = 0; PassengerSet const& GetPassengers() const { return _passengers; } + virtual void DelayedUpdate(uint32 /*diff*/) {} + uint32 GetPathProgress() const { return GetGOValue()->Transport.PathProgress; } void SetPathProgress(uint32 val) { m_goValue.Transport.PathProgress = val; } @@ -57,7 +59,7 @@ public: void BuildUpdate(UpdateDataMapType& data_map) override; void Update(uint32 diff) override; - void DelayedUpdate(uint32 diff); + void DelayedUpdate(uint32 diff) override; void UpdatePosition(float x, float y, float z, float o); void AddPassenger(WorldObject* passenger, bool withAll = false) override; @@ -115,6 +117,8 @@ public: StaticTransport(); ~StaticTransport() override; + bool LoadFromDB(ObjectGuid::LowType guid, Map* map) override { return LoadGameObjectFromDB(guid, map, false); } + bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true) override; bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0) override; void CleanupsBeforeDelete(bool finalCleanup = true) override; void BuildUpdate(UpdateDataMapType& data_map) override; diff --git a/src/server/game/Grids/GridObjectLoader.cpp b/src/server/game/Grids/GridObjectLoader.cpp index 6a5b4b736..d8b39ebd6 100644 --- a/src/server/game/Grids/GridObjectLoader.cpp +++ b/src/server/game/Grids/GridObjectLoader.cpp @@ -64,15 +64,28 @@ void GridObjectLoader::LoadGameObjects(CellGuidSet const& guid_set, Map* map) for (ObjectGuid::LowType const& guid : guid_set) { GameObjectData const* data = sObjectMgr->GetGameObjectData(guid); - GameObject* obj = data && sObjectMgr->IsGameObjectStaticTransport(data->id) ? new StaticTransport() : new GameObject(); - if (!obj->LoadFromDB(guid, map)) + if (data && sObjectMgr->IsGameObjectStaticTransport(data->id)) { - delete obj; - continue; - } + StaticTransport* transport = new StaticTransport(); - AddObjectHelper(map, obj); + // Special case for static transports - we are loaded via grids + // but we do not want to actually be stored in the grid + if (!transport->LoadGameObjectFromDB(guid, map, true)) + delete transport; + } + else + { + GameObject* obj = new GameObject(); + + if (!obj->LoadFromDB(guid, map)) + { + delete obj; + continue; + } + + AddObjectHelper(map, obj); + } } } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index e06a22d64..9ad4cfb4e 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -345,7 +345,7 @@ bool Map::AddToMap(T* obj, bool checkTransport) } template<> -bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/) +bool Map::AddToMap(Transport* obj, bool /*checkTransport*/) { //TODO: Needs clean up. An object should not be added to map twice. if (obj->IsInWorld()) @@ -360,26 +360,22 @@ bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/) } Cell cell(cellCoord); - if (obj->isActiveObject()) - EnsureGridLoaded(cell); + EnsureGridLoaded(cell); obj->AddToWorld(); _transports.insert(obj); // Broadcast creation to players - if (!GetPlayers().IsEmpty()) + for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) { - for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if (itr->GetSource()->GetTransport() != obj) { - if (itr->GetSource()->GetTransport() != obj) - { - UpdateData data; - obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource()); - WorldPacket packet; - data.BuildPacket(packet); - itr->GetSource()->SendDirectMessage(&packet); - } + UpdateData data; + obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource()); + WorldPacket packet; + data.BuildPacket(packet); + itr->GetSource()->SendDirectMessage(&packet); } } @@ -667,7 +663,7 @@ void Map::RemoveFromMap(T* obj, bool remove) } template<> -void Map::RemoveFromMap(MotionTransport* obj, bool remove) +void Map::RemoveFromMap(Transport* obj, bool remove) { obj->RemoveFromWorld(); @@ -697,8 +693,6 @@ void Map::RemoveFromMap(MotionTransport* obj, bool remove) obj->ResetMap(); - // Transports are never actually deleted, but it *should* be safe to clear - // from update list when removing from world RemoveObjectFromMapUpdateList(obj); if (remove) @@ -966,11 +960,10 @@ void Map::UnloadAll() for (TransportsContainer::iterator itr = _transports.begin(); itr != _transports.end();) { - MotionTransport* transport = *itr; + Transport* transport = *itr; ++itr; - transport->RemoveFromWorld(); - delete transport; + RemoveFromMap(transport, true); } _transports.clear(); @@ -1589,6 +1582,9 @@ void Map::SendInitSelf(Player* player) void Map::SendInitTransports(Player* player) { + if (_transports.empty()) + return; + // Hack to send out transports UpdateData transData; for (TransportsContainer::const_iterator itr = _transports.begin(); itr != _transports.end(); ++itr) @@ -1605,24 +1601,15 @@ void Map::SendInitTransports(Player* player) void Map::SendRemoveTransports(Player* player) { + if (_transports.empty()) + return; + // Hack to send out transports UpdateData transData; for (TransportsContainer::const_iterator itr = _transports.begin(); itr != _transports.end(); ++itr) if (*itr != player->GetTransport()) (*itr)->BuildOutOfRangeUpdateBlock(&transData); - // pussywizard: remove static transports from client - /*for (GuidUnorderedSet::const_iterator it = player->m_clientGUIDs.begin(); it != player->m_clientGUIDs.end(); ) - { - if ((*it).IsTransport()) - { - transData.AddOutOfRangeGUID(*it); - it = player->m_clientGUIDs.erase(it); - } - else - ++it; - }*/ - if (!transData.HasData()) return; @@ -1693,7 +1680,7 @@ void Map::DelayedUpdate(const uint32 t_diff) { for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();) { - MotionTransport* transport = *_transportsUpdateIter; + Transport* transport = *_transportsUpdateIter; ++_transportsUpdateIter; if (!transport->IsInWorld()) @@ -1738,7 +1725,7 @@ void Map::RemoveAllObjectsInRemoveList() RemoveFromMap((DynamicObject*)obj, true); break; case TYPEID_GAMEOBJECT: - if (MotionTransport* transport = obj->ToGameObject()->ToMotionTransport()) + if (Transport* transport = obj->ToGameObject()->ToTransport()) RemoveFromMap(transport, true); else RemoveFromMap(obj->ToGameObject(), true); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index fb24b0924..df1f73cfe 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -146,7 +146,7 @@ struct ZoneDynamicInfo typedef std::map CreatureGroupHolderType; typedef std::unordered_map ZoneDynamicInfoMap; -typedef std::set TransportsContainer; +typedef std::unordered_set TransportsContainer; enum EncounterCreditType : uint8 { @@ -535,7 +535,6 @@ protected: MapRefMgr m_mapRefMgr; MapRefMgr::iterator m_mapRefIter; - // Objects that must update even in inactive grids without activating them TransportsContainer _transports; TransportsContainer::iterator _transportsUpdateIter; diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp index ad319e943..f065ccf56 100644 --- a/src/server/game/Maps/TransportMgr.cpp +++ b/src/server/game/Maps/TransportMgr.cpp @@ -412,10 +412,8 @@ MotionTransport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType if (map && map->IsDungeon()) trans->m_zoneScript = map->ToInstanceMap()->GetInstanceScript(); - // xinef: transports are active so passengers can be relocated (grids must be loaded) - trans->setActive(true); HashMapHolder::Insert(trans); - trans->GetMap()->AddToMap(trans); + trans->GetMap()->AddToMap(trans); return trans; } From 2450237b7d11fe5ea60e000f8e9a0d800fc9910e Mon Sep 17 00:00:00 2001 From: Takenbacon Date: Sun, 10 Aug 2025 12:16:04 -0700 Subject: [PATCH 06/57] fix(Core/Maps): Improve large object updater (#22659) --- src/server/game/Entities/Creature/Creature.cpp | 2 +- src/server/game/Entities/GameObject/GameObject.cpp | 2 +- src/server/game/Maps/Map.h | 2 +- src/server/scripts/Commands/cs_debug.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 8c070c6db..8ef6206bb 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -3903,7 +3903,7 @@ bool Creature::IsUpdateNeeded() if (IsInCombat()) return true; - if (IsVisibilityOverridden()) + if (!GetObjectVisibilityContainer().GetVisiblePlayersMap().empty()) return true; if (ToTempSummon()) diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 827dc38dd..1fa5a4177 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -3086,7 +3086,7 @@ bool GameObject::IsUpdateNeeded() if (GetMap()->isCellMarked(GetCurrentCell().GetCellCoord().GetId())) return true; - if (IsVisibilityOverridden()) + if (!GetObjectVisibilityContainer().GetVisiblePlayersMap().empty()) return true; if (IsTransport()) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index df1f73cfe..f43111633 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -479,7 +479,7 @@ public: _updateObjects.erase(obj); } - size_t GetUpdateObjectsCount() const { return _updateObjects.size(); } + size_t GetUpdatableObjectsCount() const { return _updatableObjectList.size(); } virtual std::string GetDebugInfo() const; diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 3198936fa..a9fe5d9e0 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -1351,7 +1351,7 @@ public: map->GetId(), map->GetMapName(), map->GetInstanceId(), uint64(map->GetObjectsStore().Size()), uint64(map->GetObjectsStore().Size()), - uint64(map->GetUpdateObjectsCount())); + uint64(map->GetUpdatableObjectsCount())); CreatureCountWorker worker; TypeContainerVisitor visitor(worker); From 1d70c6acc3192684ac1665057cfa9bfd4f7aaffa Mon Sep 17 00:00:00 2001 From: EricksOliveira Date: Sun, 10 Aug 2025 17:18:53 -0300 Subject: [PATCH 07/57] =?UTF-8?q?fix(Scripts/Pet):=20Fix=20Risen=20Ghoul?= =?UTF-8?q?=20behavior=20that=20does=20not=20automaticall=E2=80=A6=20(#225?= =?UTF-8?q?46)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/scripts/Pet/pet_dk.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/server/scripts/Pet/pet_dk.cpp b/src/server/scripts/Pet/pet_dk.cpp index c2eedba77..d1df1ef83 100644 --- a/src/server/scripts/Pet/pet_dk.cpp +++ b/src/server/scripts/Pet/pet_dk.cpp @@ -245,6 +245,20 @@ struct npc_pet_dk_ghoul : public CombatAI { npc_pet_dk_ghoul(Creature* c) : CombatAI(c) { } + void IsSummonedBy(WorldObject* summoner) override + { + if (!summoner || !summoner->IsPlayer()) + return; + + Player* player = summoner->ToPlayer(); + + if (Unit* victim = player->GetVictim()) + { + me->Attack(victim, true); + me->GetMotionMaster()->MoveChase(victim); + } + } + void JustDied(Unit* /*who*/) override { if (me->IsGuardian() || me->IsSummon()) From 12bee97df93cdf1431275722fecf8bf07d6fc2e9 Mon Sep 17 00:00:00 2001 From: Takenbacon Date: Mon, 11 Aug 2025 10:07:00 -0700 Subject: [PATCH 08/57] fix(Core/Visibility): Fix initial visibility on player reused sessions (#22673) --- src/server/game/Handlers/CharacterHandler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index f6ee1479d..2169cb531 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1180,6 +1180,10 @@ void WorldSession::HandlePlayerLoginToCharInWorld(Player* pCurrChar) pCurrChar->GetMap()->SendInitTransports(pCurrChar); pCurrChar->GetMap()->SendInitSelf(pCurrChar); pCurrChar->GetMap()->SendZoneDynamicInfo(pCurrChar); + + // If we are logging into an existing player, simply clear visibility references + // so player will receive a fresh list of new objects on the next vis update. + pCurrChar->GetObjectVisibilityContainer().CleanVisibilityReferences(); pCurrChar->UpdateObjectVisibility(false); pCurrChar->CleanupChannels(); From 2e07a0fe1f6f6f1af9dffd7e6a7f8f19a2082599 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Tue, 12 Aug 2025 14:23:25 +0200 Subject: [PATCH 09/57] fix(DB/SAI): Fezzix Geartwist now flies correctly and the wreckages despawn. (#22674) --- data/sql/updates/pending_db_world/Fezzix.sql | 41 ++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 data/sql/updates/pending_db_world/Fezzix.sql diff --git a/data/sql/updates/pending_db_world/Fezzix.sql b/data/sql/updates/pending_db_world/Fezzix.sql new file mode 100644 index 000000000..772136e73 --- /dev/null +++ b/data/sql/updates/pending_db_world/Fezzix.sql @@ -0,0 +1,41 @@ + +-- Set SmartAI (Wreckage A, B, C) +UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE (`entry`IN (188087, 188088, 188089)); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 1) AND (`entryorguid` IN (188087, 188088, 188089)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(188087, 1, 0, 0, 38, 0, 100, 0, 0, 1, 0, 0, 0, 0, 41, 0, 60, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Wreckage A - On Data Set 0 1 - Despawn Instant'), +(188088, 1, 0, 0, 38, 0, 100, 0, 0, 1, 0, 0, 0, 0, 41, 0, 60, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Wreckage B - On Data Set 0 1 - Despawn Instant'), +(188089, 1, 0, 0, 38, 0, 100, 0, 0, 1, 0, 0, 0, 0, 41, 0, 60, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Wreckage C - On Data Set 0 1 - Despawn Instant'); + +-- Set SmartAI (Fezzix Geartwist) +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 25849; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 25849); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(25849, 0, 0, 0, 25, 0, 100, 512, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - On Reset - Set Event Phase 1'), +(25849, 0, 1, 2, 20, 1, 100, 0, 11894, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - On Quest \'Patching Up\' Finished - Say Line 0 (Phase 1)'), +(25849, 0, 2, 0, 61, 1, 100, 512, 0, 0, 0, 0, 0, 0, 80, 2584900, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - On Quest \'Patching Up\' Finished - Run Script (Phase 1)'), +(25849, 0, 3, 0, 40, 2, 100, 512, 11, 25849, 0, 0, 0, 0, 80, 2584901, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - On Point 11 of Path 25849 Reached - Run Script (Phase 2)'), +(25849, 0, 4, 5, 40, 2, 100, 512, 12, 25849, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - On Point 12 of Path 25849 Reached - Set Event Phase 1 (Phase 2)'), +(25849, 0, 5, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4.06662, 'Fezzix Geartwist - On Point 12 of Path 25849 Reached - Set Orientation 4.06662 (Phase 2)'); + +-- Set Timed Actionlist (Fezzix Geartwist) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND (`entryorguid` IN (2584900, 2584901)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2584900, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Event Phase 2'), +(2584900, 9, 1, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 12, 26040, 1, 13000, 0, 0, 0, 8, 0, 0, 0, 0, 3481.33, 4099.85, 17.839, 3.35103, 'Fezzix Geartwist - Actionlist - Summon Creature \'Fezzix\'s Flying Machine\''), +(2584900, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 14, 60069, 188087, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Data 0 1'), +(2584900, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 14, 60080, 188088, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Data 0 1'), +(2584900, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 14, 60095, 188089, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Data 0 1'), +(2584900, 9, 5, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Say Line 1'), +(2584900, 9, 6, 0, 0, 0, 100, 0, 9000, 9000, 0, 0, 0, 0, 43, 0, 22719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Mount To Model 22719'), +(2584900, 9, 7, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Say Line 2'), +(2584900, 9, 8, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Fly On'), +(2584900, 9, 9, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 53, 0, 25849, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Start Waypoint Path 25849'), +(2584901, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 46419, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Cast \'Cosmetic - Explosion\''), +(2584901, 9, 1, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Dismount'), +(2584901, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Fly Off'), +(2584901, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 42963, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Cast \'Cosmetic - Combat Knockdown Self\''), +(2584901, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Say Line 3'), +(2584901, 9, 5, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Say Line 4'); From 9efdd9798f9789590f7533afac0e4ac857d01d42 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 12 Aug 2025 12:24:27 +0000 Subject: [PATCH 10/57] chore(DB): import pending files Referenced commit(s): 2e07a0fe1f6f6f1af9dffd7e6a7f8f19a2082599 --- .../{pending_db_world/Fezzix.sql => db_world/2025_08_12_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/Fezzix.sql => db_world/2025_08_12_00.sql} (99%) diff --git a/data/sql/updates/pending_db_world/Fezzix.sql b/data/sql/updates/db_world/2025_08_12_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/Fezzix.sql rename to data/sql/updates/db_world/2025_08_12_00.sql index 772136e73..430efa851 100644 --- a/data/sql/updates/pending_db_world/Fezzix.sql +++ b/data/sql/updates/db_world/2025_08_12_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_10_01 -> 2025_08_12_00 -- Set SmartAI (Wreckage A, B, C) UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE (`entry`IN (188087, 188088, 188089)); From 743b6e7cd971808bf57efd94ba61f9db98b15e34 Mon Sep 17 00:00:00 2001 From: EricksOliveira Date: Tue, 12 Aug 2025 13:10:20 -0300 Subject: [PATCH 11/57] =?UTF-8?q?fix(Scripts/Pet):=20Fixes=20behavior=20of?= =?UTF-8?q?=20Army=20of=20the=20Dead=20Ghouls=20to=20attack=E2=80=A6=20(#2?= =?UTF-8?q?2665)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/scripts/Pet/pet_dk.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/server/scripts/Pet/pet_dk.cpp b/src/server/scripts/Pet/pet_dk.cpp index d1df1ef83..1a8a81540 100644 --- a/src/server/scripts/Pet/pet_dk.cpp +++ b/src/server/scripts/Pet/pet_dk.cpp @@ -292,6 +292,28 @@ struct npc_pet_dk_army_of_the_dead : public CombatAI CombatAI::InitializeAI(); ((Minion*)me)->SetFollowAngle(rand_norm() * 2 * M_PI); } + + void IsSummonedBy(WorldObject* summoner) override + { + if (Unit* owner = summoner->ToUnit()) + { + Unit* victim = owner->GetVictim(); + + if (victim && me->IsValidAttackTarget(victim)) + { + AttackStart(victim); + } + else + { + // If there is no valid target, attack the nearest enemy within 30m + if (Unit* nearest = me->SelectNearbyTarget(nullptr, 30.0f)) + { + if (me->IsValidAttackTarget(nearest)) + AttackStart(nearest); + } + } + } + } }; struct npc_pet_dk_dancing_rune_weapon : public NullCreatureAI From 5369aec3c9df2e2888d3312f5e087b43e6614abf Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 12 Aug 2025 14:31:08 -0300 Subject: [PATCH 12/57] =?UTF-8?q?fix(Core/SAI):=20=20Force=20SMC=20creatur?= =?UTF-8?q?es=20to=20resume=20chasing=20victims=20once=20in=E2=80=A6=20(#2?= =?UTF-8?q?2581)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/game/AI/SmartScripts/SmartAI.cpp | 2 ++ src/server/game/AI/SmartScripts/SmartAI.h | 5 +++++ src/server/game/AI/SmartScripts/SmartScript.cpp | 2 ++ src/server/game/Entities/Unit/Unit.cpp | 14 ++++++++++++-- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index d48cf2681..4c2b252e2 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -72,6 +72,8 @@ SmartAI::SmartAI(Creature* c) : CreatureAI(c) mcanSpawn = true; + _chaseOnInterrupt = false; + // Xinef: Vehicle conditions m_ConditionsTimer = 0; if (me->GetVehicleKit()) diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index ede658a47..1cc940df4 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -212,6 +212,9 @@ public: // Xinef void SetWPPauseTimer(uint32 time) { mWPPauseTimer = time; } + void SetChaseOnInterrupt(bool apply) { _chaseOnInterrupt = apply; } + [[nodiscard]] bool CanChaseOnInterrupt() const { return _chaseOnInterrupt; } + private: bool mIsCharmed; uint32 mFollowCreditType; @@ -257,6 +260,8 @@ private: void CheckConditions(const uint32 diff); ConditionList conditions; uint32 m_ConditionsTimer; + + bool _chaseOnInterrupt; }; class SmartGameObjectAI : public GameObjectAI diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 24a3d6901..2cc4a246b 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -742,6 +742,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (e.action.cast.castFlags & SMARTCAST_COMBAT_MOVE) { + CAST_AI(SmartAI, me->AI())->SetChaseOnInterrupt(true); + if (!me->isMoving()) // Don't try to reposition while we are moving { // If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed unless target is outside spell range, out of mana, or LOS. diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f65cdbd97..a2a33e89d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -53,6 +53,7 @@ #include "Player.h" #include "ReputationMgr.h" #include "ScriptMgr.h" +#include "SmartAI.h" #include "Spell.h" #include "SpellAuraEffects.h" #include "SpellAuras.h" @@ -4109,8 +4110,8 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi //LOG_DEBUG("entities.unit", "Interrupt spell for unit {}.", GetEntry()); Spell* spell = m_currentSpells[spellType]; if (spell - && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) - && (withInstant || spell->GetCastTime() > 0 || spell->getState() == SPELL_STATE_CASTING)) // xinef: or spell is in casting state (channeled spells only) + && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) + && (withInstant || spell->GetCastTime() > 0 || spell->getState() == SPELL_STATE_CASTING)) // xinef: or spell is in casting state (channeled spells only) { // for example, do not let self-stun aura interrupt itself if (!spell->IsInterruptable()) @@ -4128,6 +4129,15 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi m_currentSpells[spellType] = nullptr; spell->SetReferencedFromCurrent(false); } + + // SAI creatures only + // Start chasing victim if they are spell casters (at least one SMC spell) if interrupted/silenced. + if (IsCreature()) + { + if (SmartAI* ai = dynamic_cast(ToCreature()->AI())) + if (ai->CanChaseOnInterrupt()) + ai->SetCombatMove(true); + } } } From 58504b8a3624bece1bc82c62d334b7b072b09fe2 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Tue, 12 Aug 2025 20:54:09 +0200 Subject: [PATCH 13/57] Fix Error (#22681) --- data/sql/updates/db_world/2025_08_12_00.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/sql/updates/db_world/2025_08_12_00.sql b/data/sql/updates/db_world/2025_08_12_00.sql index 430efa851..c25388c09 100644 --- a/data/sql/updates/db_world/2025_08_12_00.sql +++ b/data/sql/updates/db_world/2025_08_12_00.sql @@ -22,7 +22,7 @@ INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_ (25849, 0, 5, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4.06662, 'Fezzix Geartwist - On Point 12 of Path 25849 Reached - Set Orientation 4.06662 (Phase 2)'); -- Set Timed Actionlist (Fezzix Geartwist) -DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND (`entryorguid` IN (2584900, 2584901)); +DELETE FROM `smart_scripts` WHERE (`source_type` = 9) AND (`entryorguid` IN (2584900, 2584901)); INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES (2584900, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Event Phase 2'), (2584900, 9, 1, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 12, 26040, 1, 13000, 0, 0, 0, 8, 0, 0, 0, 0, 3481.33, 4099.85, 17.839, 3.35103, 'Fezzix Geartwist - Actionlist - Summon Creature \'Fezzix\'s Flying Machine\''), From d917eec2614fdeb5225145de8e136b0d7a578369 Mon Sep 17 00:00:00 2001 From: v-mstrs <104088833+v-mstrs@users.noreply.github.com> Date: Wed, 13 Aug 2025 00:09:37 +0200 Subject: [PATCH 14/57] fix(DB/Spell): Allow Sunder Armor to stack (#22669) --- .../sql/updates/pending_db_world/rev_1754911204417603800.sql | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1754911204417603800.sql diff --git a/data/sql/updates/pending_db_world/rev_1754911204417603800.sql b/data/sql/updates/pending_db_world/rev_1754911204417603800.sql new file mode 100644 index 000000000..f07b70f79 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1754911204417603800.sql @@ -0,0 +1,5 @@ +-- Anub'ar Guardian - Sunder Armor, Sunder Armor(H) +DELETE FROM `spell_custom_attr` WHERE `spell_id` IN (53618, 59350); +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES +(53618, 4194304), +(59350, 4194304); From 55a8e8514503231c2d06ef42b229f91526dd89a3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 12 Aug 2025 22:10:39 +0000 Subject: [PATCH 15/57] chore(DB): import pending files Referenced commit(s): d917eec2614fdeb5225145de8e136b0d7a578369 --- .../rev_1754911204417603800.sql => db_world/2025_08_12_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1754911204417603800.sql => db_world/2025_08_12_01.sql} (83%) diff --git a/data/sql/updates/pending_db_world/rev_1754911204417603800.sql b/data/sql/updates/db_world/2025_08_12_01.sql similarity index 83% rename from data/sql/updates/pending_db_world/rev_1754911204417603800.sql rename to data/sql/updates/db_world/2025_08_12_01.sql index f07b70f79..0f712fbf3 100644 --- a/data/sql/updates/pending_db_world/rev_1754911204417603800.sql +++ b/data/sql/updates/db_world/2025_08_12_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_12_00 -> 2025_08_12_01 -- Anub'ar Guardian - Sunder Armor, Sunder Armor(H) DELETE FROM `spell_custom_attr` WHERE `spell_id` IN (53618, 59350); INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES From 5ad345a873f5d3e0923c022ed0f12891471989cb Mon Sep 17 00:00:00 2001 From: sudlud Date: Wed, 13 Aug 2025 08:48:22 +0200 Subject: [PATCH 16/57] fix(Conf/Logs): fix Error appender log level, enable sql.updates error logging (#22682) --- src/server/apps/worldserver/worldserver.conf.dist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 9034da67a..9b36fe680 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -656,7 +656,7 @@ Allow.IP.Based.Action.Logging = 0 Appender.Console=1,4,0,"1 9 3 6 5 8" Appender.Server=2,5,0,Server.log,w # Appender.GM=2,5,15,gm_%s.log -Appender.Errors=2,5,0,Errors.log,w +Appender.Errors=2,2,0,Errors.log,w # Appender.DB=3,5,0 # Logger config values: Given a logger "name" @@ -685,6 +685,7 @@ Logger.mmaps=4,Server Logger.scripts.hotswap=4,Console Server Logger.server=4,Console Server Logger.sql.sql=2,Console Errors +Logger.sql.updates=4,Console Server Errors Logger.sql=4,Console Server Logger.time.update=4,Console Server Logger.module=4,Console Server @@ -783,7 +784,6 @@ Logger.spells.scripts=2,Console Errors #Logger.spells=4,Console Server #Logger.sql.dev=4,Console Server #Logger.sql.driver=4,Console Server -#Logger.sql.updates=4,Console Server #Logger.vehicles=4,Console Server #Logger.warden=4,Console Server #Logger.weather=4,Console Server From 2877502fb337b3ee1fd1469906d0caf2c35506d6 Mon Sep 17 00:00:00 2001 From: v-mstrs <104088833+v-mstrs@users.noreply.github.com> Date: Wed, 13 Aug 2025 13:35:27 +0200 Subject: [PATCH 17/57] fix(DB/Spell): Allow Poison Bolt to stack (#22668) --- .../updates/pending_db_world/rev_1754910707047949800.sql | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1754910707047949800.sql diff --git a/data/sql/updates/pending_db_world/rev_1754910707047949800.sql b/data/sql/updates/pending_db_world/rev_1754910707047949800.sql new file mode 100644 index 000000000..d9231f97d --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1754910707047949800.sql @@ -0,0 +1,7 @@ +-- Anub'ar Venomancer - Poison Bolt +DELETE FROM `spell_custom_attr` WHERE `spell_id` = 53617; +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (53617, 4194304); + +-- Anub'ar Venomancer - Poison Bolt(H) +DELETE FROM `spell_custom_attr` WHERE `spell_id` = 59359; +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (59359, 4194304); From 8bffcab5cfe98bd1253fa70eb625d18704099b00 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 13 Aug 2025 11:36:33 +0000 Subject: [PATCH 18/57] chore(DB): import pending files Referenced commit(s): 2877502fb337b3ee1fd1469906d0caf2c35506d6 --- .../rev_1754910707047949800.sql => db_world/2025_08_13_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1754910707047949800.sql => db_world/2025_08_13_00.sql} (89%) diff --git a/data/sql/updates/pending_db_world/rev_1754910707047949800.sql b/data/sql/updates/db_world/2025_08_13_00.sql similarity index 89% rename from data/sql/updates/pending_db_world/rev_1754910707047949800.sql rename to data/sql/updates/db_world/2025_08_13_00.sql index d9231f97d..719b7b844 100644 --- a/data/sql/updates/pending_db_world/rev_1754910707047949800.sql +++ b/data/sql/updates/db_world/2025_08_13_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_12_01 -> 2025_08_13_00 -- Anub'ar Venomancer - Poison Bolt DELETE FROM `spell_custom_attr` WHERE `spell_id` = 53617; INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (53617, 4194304); From 3e36b35a158ad37a71ecbbccdf7b250cccfdc6b8 Mon Sep 17 00:00:00 2001 From: Christian M Date: Thu, 14 Aug 2025 07:58:36 -0400 Subject: [PATCH 19/57] fix(DB/SAI): Some Azjob-Nerub spell fixes (#22603) --- .../updates/pending_db_world/rev_1753816572154118506.sql | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1753816572154118506.sql diff --git a/data/sql/updates/pending_db_world/rev_1753816572154118506.sql b/data/sql/updates/pending_db_world/rev_1753816572154118506.sql new file mode 100644 index 000000000..09f9b5bf6 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1753816572154118506.sql @@ -0,0 +1,9 @@ +-- Allow Anub'ar warrior to use Strike ability. (Set the event_type 0 to "incombat update" instead of "out of combat update") +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 28732; +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28732) AND (`source_type` = 0) AND (`id` IN (0)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(28732, 0, 0, 0, 0, 0, 100, 0, 2000, 5000, 6000, 8000, 0, 0, 11, 52532, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, "Anub'ar Warrior - In Combat - Cast Strike"); + +-- Fix misplaced spell IDs in spelldifficulty for Skittering Infector's Acid Splash +UPDATE `spelldifficulty_dbc` SET `DifficultySpellID_1` = 52446 WHERE `ID` = 59363; +UPDATE `spelldifficulty_dbc` SET `DifficultySpellID_2` = 59363 WHERE `ID` = 59363; From 1878efda1eb469868a5164db30416a34f0ef3246 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 14 Aug 2025 11:59:36 +0000 Subject: [PATCH 20/57] chore(DB): import pending files Referenced commit(s): 3e36b35a158ad37a71ecbbccdf7b250cccfdc6b8 --- .../rev_1753816572154118506.sql => db_world/2025_08_14_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1753816572154118506.sql => db_world/2025_08_14_00.sql} (96%) diff --git a/data/sql/updates/pending_db_world/rev_1753816572154118506.sql b/data/sql/updates/db_world/2025_08_14_00.sql similarity index 96% rename from data/sql/updates/pending_db_world/rev_1753816572154118506.sql rename to data/sql/updates/db_world/2025_08_14_00.sql index 09f9b5bf6..0323cc323 100644 --- a/data/sql/updates/pending_db_world/rev_1753816572154118506.sql +++ b/data/sql/updates/db_world/2025_08_14_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_13_00 -> 2025_08_14_00 -- Allow Anub'ar warrior to use Strike ability. (Set the event_type 0 to "incombat update" instead of "out of combat update") UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 28732; DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28732) AND (`source_type` = 0) AND (`id` IN (0)); From 1a019f967d910a5eeabaf2f2fe68bdeb697e5834 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Mon, 18 Aug 2025 11:32:43 -0400 Subject: [PATCH 21/57] fix(DB/Creature): Add more spawns for Isle of Quel'Danas harbor quest credit creatures. (#22698) --- .../keep-the-enemy-at-bay-spawns.sql | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 data/sql/updates/pending_db_world/keep-the-enemy-at-bay-spawns.sql diff --git a/data/sql/updates/pending_db_world/keep-the-enemy-at-bay-spawns.sql b/data/sql/updates/pending_db_world/keep-the-enemy-at-bay-spawns.sql new file mode 100644 index 000000000..fe4d6cb4c --- /dev/null +++ b/data/sql/updates/pending_db_world/keep-the-enemy-at-bay-spawns.sql @@ -0,0 +1,65 @@ +SET @CGUID := 82950; + +DELETE FROM `creature` WHERE `id1` IN (25090, 25091, 25092); +DELETE FROM `creature` WHERE `id1` IN (25090, 25091, 25092) AND `guid` BETWEEN @CGUID+0 AND @CGUID+57; +INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`, `CreateObject`) VALUES +(@CGUID+0 , 25090, 530, 0, 0, 1, 1, 0, 13196.1201171875, -7049.33642578125, 16.22812080383300781, 0.855211317539215087, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+1 , 25090, 530, 0, 0, 1, 1, 0, 13210.173828125 , -7052.376953125 , 16.07102394104003906, 4.572762489318847656, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+2 , 25090, 530, 0, 0, 1, 1, 0, 13202.560546875 , -7051.39697265625, 16.39847373962402343, 4.188790321350097656, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+3 , 25090, 530, 0, 0, 1, 1, 0, 13201.0830078125, -7048.72509765625, 13.21125602722167968, 0.191986218094825744, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+4 , 25090, 530, 0, 0, 1, 1, 0, 13199.25 , -7050.6953125 , 14.45721721649169921, 3.700098037719726562, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+5 , 25090, 530, 0, 0, 1, 1, 0, 13207.0126953125, -7053.20068359375, 15.47437477111816406, 2.740166902542114257, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+6 , 25090, 530, 0, 0, 1, 1, 0, 13246.345703125 , -7053.97412109375, 20.62376213073730468, 4.904375076293945312, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+7 , 25090, 530, 0, 0, 1, 1, 0, 13242.1611328125, -7054.7880859375 , 17.20347023010253906, 4.764749050140380859, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+8 , 25090, 530, 0, 0, 1, 1, 0, 13240.6982421875, -7053.22998046875, 14.11119270324707031, 4.97418832778930664 , 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+9 , 25090, 530, 0, 0, 1, 1, 0, 13235.609375 , -7053.92626953125, 15.19749736785888671, 5.934119224548339843, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+10, 25090, 530, 0, 0, 1, 1, 0, 13247.880859375 , -7055.54150390625, 18.45570755004882812, 0.575958669185638427, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+11, 25090, 530, 0, 0, 1, 1, 0, 13212.2255859375, -7054.658203125 , 17.02962112426757812, 6.108652114868164062, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+12, 25090, 530, 0, 0, 1, 1, 0, 13237.314453125 , -7053.35498046875, 18.92669677734375 , 3.351032257080078125, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+13, 25090, 530, 0, 0, 1, 1, 0, 13253.2548828125, -7054.8837890625 , 16.24456024169921875, 0.069813169538974761, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+14, 25090, 530, 0, 0, 1, 1, 0, 13274.5966796875, -7057.69384765625, 24.88401985168457031, 0.244346097111701965, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+15, 25090, 530, 0, 0, 1, 1, 0, 13264.31640625 , -7057.705078125 , 24.02816200256347656, 1.570796370506286621, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+16, 25090, 530, 0, 0, 1, 1, 0, 13261.1611328125, -7055.92529296875, 26.55978202819824218, 3.298672199249267578, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+17, 25090, 530, 0, 0, 1, 1, 0, 13255.951171875 , -7056.603515625 , 19.514129638671875 , 1.134464025497436523, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+18, 25090, 530, 0, 0, 1, 1, 0, 13262.6103515625, -7056.1162109375 , 22.68890190124511718, 4.520402908325195312, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+19, 25090, 530, 0, 0, 1, 1, 0, 13260.7216796875, -7056.51025390625, 24.51448440551757812, 5.899212837219238281, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), + +(@CGUID+20, 25091, 530, 0, 0, 1, 1, 0, 13330.6298828125, -6993.73974609375, 18.55262374877929687, 0.453785598278045654, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+21, 25091, 530, 0, 0, 1, 1, 0, 13329.9267578125, -6994.26416015625, 15.69489192962646484, 0.279252678155899047, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+22, 25091, 530, 0, 0, 1, 1, 0, 13317.7392578125, -6990.34716796875, 17.51109886169433593, 0.03490658476948738 , 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+23, 25091, 530, 0, 0, 1, 1, 0, 13317.330078125 , -6988.69384765625, 15.31146907806396484, 1.413716673851013183, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+24, 25091, 530, 0, 0, 1, 1, 0, 13325.728515625 , -6992.54296875 , 17.86301040649414062, 0.314159274101257324, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+25, 25091, 530, 0, 0, 1, 1, 0, 13321.5322265625, -6991.05859375 , 18.0410003662109375 , 3.473205089569091796, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+26, 25091, 530, 0, 0, 1, 1, 0, 13312.7392578125, -6989.04150390625, 16.80069160461425781, 3.03687286376953125 , 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+27, 25091, 530, 0, 0, 1, 1, 0, 13326.6171875 , -6991.60400390625, 15.73497295379638671, 3.874630928039550781, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+28, 25091, 530, 0, 0, 1, 1, 0, 13321.43359375 , -6992.02294921875, 15.16357707977294921, 1.850049018859863281, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+29, 25091, 530, 0, 0, 1, 1, 0, 13315.4501953125, -6990.5986328125 , 14.17850494384765625, 5.323254108428955078, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+30, 25091, 530, 0, 0, 1, 1, 0, 13351.2919921875, -6989.8095703125 , 14.9304962158203125 , 5.619960308074951171, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+31, 25091, 530, 0, 0, 1, 1, 0, 13348.5439453125, -6990.99853515625, 17.81970596313476562, 3.525565147399902343, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+32, 25091, 530, 0, 0, 1, 1, 0, 13359.8720703125, -6990.33447265625, 11.86795330047607421, 3.892084121704101562, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+33, 25091, 530, 0, 0, 1, 1, 0, 13363.31640625 , -6990.54541015625, 17.51730155944824218, 5.044001579284667968, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+34, 25091, 530, 0, 0, 1, 1, 0, 13357.7421875 , -6991.56103515625, 18.46755599975585937, 4.729842185974121093, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+35, 25091, 530, 0, 0, 1, 1, 0, 13361.9384765625, -6990.98291015625, 21.16696739196777343, 1.308996915817260742, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+36, 25091, 530, 0, 0, 1, 1, 0, 13357.88671875 , -6991.5693359375 , 15.036224365234375 , 1.850049018859863281, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+37, 25091, 530, 0, 0, 1, 1, 0, 13364.1953125 , -6991.95556640625, 18.6686553955078125 , 4.293509960174560546, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+38, 25091, 530, 0, 0, 1, 1, 0, 13374.556640625 , -6992.58837890625, 20.41219139099121093, 0.872664630413055419, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+39, 25091, 530, 0, 0, 1, 1, 0, 13372.1640625 , -6991.0869140625 , 22.58947563171386718, 4.904375076293945312, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+40, 25091, 530, 0, 0, 1, 1, 0, 13367.83203125 , -6992.177734375 , 11.62636184692382812, 2.530727386474609375, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+41, 25091, 530, 0, 0, 1, 1, 0, 13374.2861328125, -6991.216796875 , 18.20113945007324218, 5.026548385620117187, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+42, 25091, 530, 0, 0, 1, 1, 0, 13367.4873046875, -6992.15625 , 15.75841045379638671, 4.328416347503662109, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), + +(@CGUID+43, 25092, 530, 0, 0, 1, 1, 0, 13276.2861328125, -7148.3115234375 , 18.78717231750488281, 5.25344085693359375 , 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+44, 25092, 530, 0, 0, 1, 1, 0, 13267.578125 , -7146.2333984375 , 17.49614906311035156, 3.089232683181762695, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+45, 25092, 530, 0, 0, 1, 1, 0, 13273.84375 , -7146.33349609375, 11.37590885162353515, 0.314159274101257324, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+46, 25092, 530, 0, 0, 1, 1, 0, 13332.458984375 , -7149.9892578125 , 25.62369537353515625, 3.455751895904541015, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+47, 25092, 530, 0, 0, 1, 1, 0, 13324.3798828125, -7148.763671875 , 12.40258979797363281, 5.393067359924316406, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+48, 25092, 530, 0, 0, 1, 1, 0, 13283.3359375 , -7150.99072265625, 16.36432838439941406, 2.49582076072692871 , 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+49, 25092, 530, 0, 0, 1, 1, 0, 13306.396484375 , -7148.45556640625, 19.448272705078125 , 6.126105785369873046, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+50, 25092, 530, 0, 0, 1, 1, 0, 13323.8916015625, -7149.33056640625, 23.59075736999511718, 0.331612557172775268, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+51, 25092, 530, 0, 0, 1, 1, 0, 13314.80859375 , -7148.80078125 , 21.43866920471191406, 4.834561824798583984, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+52, 25092, 530, 0, 0, 1, 1, 0, 13308.7783203125, -7147.53515625 , 14.74446582794189453, 2.652900457382202148, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+53, 25092, 530, 0, 0, 1, 1, 0, 13336.470703125 , -7149.71533203125, 24.01339530944824218, 0.942477762699127197, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+54, 25092, 530, 0, 0, 1, 1, 0, 13279.6572265625, -7149.91162109375, 16.28713226318359375, 4.747295379638671875, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+55, 25092, 530, 0, 0, 1, 1, 0, 13285.5986328125, -7150.7265625 , 20.10992622375488281, 5.113814830780029296, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+56, 25092, 530, 0, 0, 1, 1, 0, 13315.0751953125, -7149.388671875 , 15.76729774475097656, 4.066617012023925781, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+57, 25092, 530, 0, 0, 1, 1, 0, 13323.4755859375, -7150.04931640625, 19.51647567749023437, 2.251474618911743164, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1); From 36f04acdd5326d9901b5c7a4321065d6c4372076 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 18 Aug 2025 15:33:47 +0000 Subject: [PATCH 22/57] chore(DB): import pending files Referenced commit(s): 1a019f967d910a5eeabaf2f2fe68bdeb697e5834 --- .../2025_08_18_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/keep-the-enemy-at-bay-spawns.sql => db_world/2025_08_18_00.sql} (99%) diff --git a/data/sql/updates/pending_db_world/keep-the-enemy-at-bay-spawns.sql b/data/sql/updates/db_world/2025_08_18_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/keep-the-enemy-at-bay-spawns.sql rename to data/sql/updates/db_world/2025_08_18_00.sql index fe4d6cb4c..02662cf65 100644 --- a/data/sql/updates/pending_db_world/keep-the-enemy-at-bay-spawns.sql +++ b/data/sql/updates/db_world/2025_08_18_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_14_00 -> 2025_08_18_00 SET @CGUID := 82950; DELETE FROM `creature` WHERE `id1` IN (25090, 25091, 25092); From 7a9f430935a3ad4895304d7c33b4f88417aee56d Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Mon, 18 Aug 2025 15:04:06 -0400 Subject: [PATCH 23/57] fix(Scripts/SunwellPlateau): Remove Kil'jaeden's debuffs from Shield of the Blue effects. (#22687) --- .../pending_db_world/shield-of-the-buffs.sql | 3 +++ .../SunwellPlateau/boss_kiljaeden.cpp | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 data/sql/updates/pending_db_world/shield-of-the-buffs.sql diff --git a/data/sql/updates/pending_db_world/shield-of-the-buffs.sql b/data/sql/updates/pending_db_world/shield-of-the-buffs.sql new file mode 100644 index 000000000..30d7f6123 --- /dev/null +++ b/data/sql/updates/pending_db_world/shield-of-the-buffs.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` = 45848; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(45848, 'spell_kiljaeden_shield_of_the_blue'); diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index 2858a5cf6..ddd75f48a 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -1181,6 +1181,26 @@ class spell_kiljaeden_dragon_breath : public SpellScript } }; +// 45848 - Shield of the Blue +class spell_kiljaeden_shield_of_the_blue : public AuraScript +{ + PrepareAuraScript(spell_kiljaeden_shield_of_the_blue); + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* target = GetTarget()) + { + target->RemoveAurasDueToSpell(SPELL_FIRE_BLOOM); + target->RemoveMovementImpairingAuras(false); + } + } + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_kiljaeden_shield_of_the_blue::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + } +}; + void AddSC_boss_kiljaeden() { RegisterSunwellPlateauCreatureAI(npc_kiljaeden_controller); @@ -1196,4 +1216,5 @@ void AddSC_boss_kiljaeden() RegisterSpellScript(spell_kiljaeden_armageddon_periodic_aura); RegisterSpellScript(spell_kiljaeden_armageddon_missile); RegisterSpellScript(spell_kiljaeden_dragon_breath); + RegisterSpellScript(spell_kiljaeden_shield_of_the_blue); } From f41fb5a1693e2f5a30b003f84f6e3726fa925b01 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 18 Aug 2025 19:05:07 +0000 Subject: [PATCH 24/57] chore(DB): import pending files Referenced commit(s): 7a9f430935a3ad4895304d7c33b4f88417aee56d --- .../shield-of-the-buffs.sql => db_world/2025_08_18_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/shield-of-the-buffs.sql => db_world/2025_08_18_01.sql} (79%) diff --git a/data/sql/updates/pending_db_world/shield-of-the-buffs.sql b/data/sql/updates/db_world/2025_08_18_01.sql similarity index 79% rename from data/sql/updates/pending_db_world/shield-of-the-buffs.sql rename to data/sql/updates/db_world/2025_08_18_01.sql index 30d7f6123..2a0dbeedb 100644 --- a/data/sql/updates/pending_db_world/shield-of-the-buffs.sql +++ b/data/sql/updates/db_world/2025_08_18_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_18_00 -> 2025_08_18_01 DELETE FROM `spell_script_names` WHERE `spell_id` = 45848; INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (45848, 'spell_kiljaeden_shield_of_the_blue'); From 2ae1dbeab25cd27ba1de702d1a06370448439ebe Mon Sep 17 00:00:00 2001 From: Yehonal Date: Tue, 19 Aug 2025 03:29:34 +0200 Subject: [PATCH 25/57] feat(core): add standalone functions for player settings (#22703) --- .../game/Entities/Player/PlayerSettings.cpp | 111 ++++++++++++++---- .../game/Entities/Player/PlayerSettings.h | 15 +++ 2 files changed, 101 insertions(+), 25 deletions(-) diff --git a/src/server/game/Entities/Player/PlayerSettings.cpp b/src/server/game/Entities/Player/PlayerSettings.cpp index dba4afaa5..89b719d71 100644 --- a/src/server/game/Entities/Player/PlayerSettings.cpp +++ b/src/server/game/Entities/Player/PlayerSettings.cpp @@ -18,11 +18,95 @@ #include "Player.h" #include "StringConvert.h" #include "Tokenize.h" +#include "CharacterDatabase.h" /*********************************************************/ /*** PLAYER SETTINGS SYSTEM ***/ /*********************************************************/ +namespace PlayerSettingsStore +{ + // Common helper: parse space-separated data string into PlayerSettingVector + PlayerSettingVector ParseSettingsData(std::string const& data) + { + PlayerSettingVector result; + std::vector tokens = Acore::Tokenize(data, ' ', false); + result.reserve(tokens.size()); + for (auto const& token : tokens) + { + if (token.empty()) + continue; + if (auto parsed = Acore::StringTo(token)) + result.emplace_back(*parsed); + } + return result; + } + + // Common helper: serialize PlayerSettingVector to space-separated string + std::string SerializeSettingsData(PlayerSettingVector const& settings) + { + if (settings.empty()) + return ""; + + std::ostringstream data; + data << settings[0].value; + for (size_t i = 1; i < settings.size(); ++i) + data << ' ' << settings[i].value; + return data.str(); + } + + // helper: load a single source row for a player and parse to vector + static PlayerSettingVector LoadPlayerSettings(uint32 playerLowGuid, std::string const& source) + { + PlayerSettingVector result; + + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_SETTINGS); + stmt->SetData(0, playerLowGuid); + PreparedQueryResult dbRes = CharacterDatabase.Query(stmt); + if (!dbRes) + return result; + + do + { + Field* fields = dbRes->Fetch(); + std::string rowSource = fields[0].Get(); + if (rowSource != source) + continue; + + std::string data = fields[1].Get(); + return ParseSettingsData(data); + } while (dbRes->NextRow()); + + return result; + } + + void UpdateSetting(uint32 playerLowGuid, std::string const& source, uint8 index, uint32 value) + { + if (!sWorld->getBoolConfig(CONFIG_PLAYER_SETTINGS_ENABLED)) + return; + + PlayerSettingVector settings = LoadPlayerSettings(playerLowGuid, source); + size_t const requiredSize = static_cast(index) + 1; + if (settings.size() < requiredSize) + settings.resize(requiredSize); // zero-initialized PlayerSetting::value + + settings[index].value = value; + + CharacterDatabasePreparedStatement* stmt = PlayerSettingsStore::PrepareReplaceStatement(playerLowGuid, source, settings); + CharacterDatabase.Execute(stmt); + } +} + +// Implementation of PrepareReplaceStatement +CharacterDatabasePreparedStatement* PlayerSettingsStore::PrepareReplaceStatement(uint32 playerLowGuid, std::string const& source, PlayerSettingVector const& settings) +{ + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_SETTINGS); + stmt->SetData(0, playerLowGuid); + stmt->SetData(1, source); + stmt->SetData(2, SerializeSettingsData(settings)); + return stmt; +} + void Player::_LoadCharacterSettings(PreparedQueryResult result) { m_charSettingsMap.clear(); @@ -39,21 +123,7 @@ void Player::_LoadCharacterSettings(PreparedQueryResult result) std::string source = fields[0].Get(); std::string data = fields[1].Get(); - std::vector tokens = Acore::Tokenize(data, ' ', false); - - PlayerSettingVector settings; - settings.reserve(tokens.size()); // reserve capacity but don't resize - - for (auto const& token : tokens) - { - if (token.empty()) - continue; - - // Try to parse the value safely - if (auto parsed = Acore::StringTo(token)) - settings.emplace_back(*parsed); - } - + PlayerSettingVector settings = PlayerSettingsStore::ParseSettingsData(data); m_charSettingsMap.emplace(std::move(source), std::move(settings)); } while (result->NextRow()); @@ -81,16 +151,7 @@ void Player::_SavePlayerSettings(CharacterDatabaseTransaction trans) if (settings.empty()) continue; - std::ostringstream data; - data << settings[0].value; - - for (size_t i = 1; i < settings.size(); ++i) - data << ' ' << settings[i].value; - - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_SETTINGS); - stmt->SetData(0, GetGUID().GetCounter()); - stmt->SetData(1, source); - stmt->SetData(2, data.str()); + CharacterDatabasePreparedStatement* stmt = PlayerSettingsStore::PrepareReplaceStatement(GetGUID().GetCounter(), source, settings); trans->Append(stmt); } } diff --git a/src/server/game/Entities/Player/PlayerSettings.h b/src/server/game/Entities/Player/PlayerSettings.h index 027062e3c..612225114 100644 --- a/src/server/game/Entities/Player/PlayerSettings.h +++ b/src/server/game/Entities/Player/PlayerSettings.h @@ -17,6 +17,7 @@ #ifndef _PLAYER_SETTINGS_H #define _PLAYER_SETTINGS_H +#include "DatabaseEnvFwd.h" class Player; @@ -51,4 +52,18 @@ struct PlayerSetting typedef std::vector PlayerSettingVector; typedef std::map PlayerSettingMap; +// Standalone API: update a player's setting directly on DB by GUID (low part) without requiring a Player instance +namespace PlayerSettingsStore +{ + // Update a single setting value for any player by GUID (works for online or offline players). + // This reads the existing "source" row from character_settings, adjusts the index, and REPLACE's it back. + void UpdateSetting(uint32 playerLowGuid, std::string const& source, uint8 index, uint32 value); + + // Common helpers for parsing and serializing settings data + PlayerSettingVector ParseSettingsData(std::string const& data); + std::string SerializeSettingsData(PlayerSettingVector const& settings); + // Prepare a REPLACE statement populated with given settings data. Caller may execute or append to a transaction. + CharacterDatabasePreparedStatement* PrepareReplaceStatement(uint32 playerLowGuid, std::string const& source, PlayerSettingVector const& settings); +} + #endif From e3505df99f93e48a3af1ffb72a40dc5f9bd0f890 Mon Sep 17 00:00:00 2001 From: Takenbacon Date: Mon, 18 Aug 2025 21:14:08 -0700 Subject: [PATCH 26/57] fix(Core/Visibility): Fix visibility crash (#22704) --- src/server/game/Entities/Object/Object.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index a9fcd7199..3081013be 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1696,7 +1696,7 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo if (this == obj) return true; - if (obj->IsNeverVisible() || CanNeverSee(obj)) + if (CanNeverSee(obj)) return false; if (obj->IsAlwaysVisibleFor(this) || CanAlwaysSee(obj)) @@ -1840,6 +1840,12 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo bool WorldObject::CanNeverSee(WorldObject const* obj) const { + if (!IsInWorld()) + return true; + + if (obj->IsNeverVisible()) + return true; + if (IsCreature() && obj->IsCreature()) return GetMap() != obj->GetMap() || (!InSamePhase(obj) && ToUnit()->GetVehicleBase() != obj && this != obj->ToUnit()->GetVehicleBase()); return GetMap() != obj->GetMap() || !InSamePhase(obj); From 0f08b6e8ab058e7c42a73c4bfc2346d772ae3a46 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Tue, 19 Aug 2025 14:05:57 +0200 Subject: [PATCH 27/57] fix(DB/Creature) Resolve Return of the High Chief quest issues. (#22695) --- data/sql/updates/pending_db_world/Roanauk.sql | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 data/sql/updates/pending_db_world/Roanauk.sql diff --git a/data/sql/updates/pending_db_world/Roanauk.sql b/data/sql/updates/pending_db_world/Roanauk.sql new file mode 100644 index 000000000..63d6dd95b --- /dev/null +++ b/data/sql/updates/pending_db_world/Roanauk.sql @@ -0,0 +1,65 @@ + +-- Remove Unit Flags from Roanauk Icemist (IMMUNE_TO_PC, IMMUNE_TO_NPC) +UPDATE `creature_template` SET `unit_flags` = `unit_flags` &~(256|512) WHERE (`entry` = 26654); + +-- Remove Unit Flags from Icemist Warriors (IMMUNE_TO_PC, IMMUNE_TO_NPC, STUNNED) +UPDATE `creature_template` SET `unit_flags` = `unit_flags` &~(256|512|262144) WHERE (`entry` = 26772); + +-- Update SmartAI (Roanauk Icemist) +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE (`entry` IN (26654, 26772)); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 26654); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(26654, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Respawn - Set Flags Immune To Players & Immune To NPC\'s'), +(26654, 0, 1, 2, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 11, 26656, 10, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Respawn - Set Data 1 1'), +(26654, 0, 2, 3, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Respawn - Set Event Phase 1'), +(26654, 0, 3, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 11, 47273, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Respawn - Cast \'Icemist`s Prison\''), +(26654, 0, 4, 0, 1, 1, 100, 0, 5000, 30000, 120000, 150000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Out of Combat - Say Line 0 (Phase 1)'), +(26654, 0, 5, 0, 38, 0, 100, 513, 1, 1, 0, 0, 0, 0, 80, 2665400, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Data Set 1 1 - Run Script (No Repeat)'), +(26654, 0, 6, 0, 40, 0, 100, 512, 1, 0, 0, 0, 0, 0, 80, 2665401, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Point 1 of Path Any Reached - Run Script'), +(26654, 0, 7, 0, 38, 0, 100, 512, 2, 2, 0, 0, 0, 0, 80, 2665402, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Data Set 2 2 - Run Script'); + +-- Update Action List (Roanauk Icemist) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9) AND (`entryorguid` IN (2665400, 2665401)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2665400, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 28, 47273, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Remove Aura \'Icemist`s Prison\''), +(2665400, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 2, 2, 0, 0, 0, 0, 9, 26656, 0, 200, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Set Data 2 2'), +(2665400, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Set Event Phase 2'), +(2665400, 9, 3, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 1'), +(2665400, 9, 4, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 53, 0, 26654, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Start Waypoint Path 26654'), +(2665401, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 2'), +(2665401, 9, 1, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 3'), +(2665401, 9, 2, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 19, 26608, 100, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 1'), +(2665401, 9, 3, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 11, 47378, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Cast \'Glory of the Ancestors\''), +(2665401, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 4'), +(2665401, 9, 5, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Remove Flags Immune To Players & Immune To NPC\'s'), +(2665401, 9, 6, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 47379, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Cast \'Icemist`s Blessing\''), +(2665401, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 5'), +(2665401, 9, 8, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 6'), +(2665401, 9, 9, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 19, 26608, 100, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 2'), +(2665401, 9, 10, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 1, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 7'), +(2665401, 9, 11, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 19, 26608, 100, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Set Data 1 1'), +(2665401, 9, 12, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Set Home Position'), +(2665401, 9, 13, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 19, 26608, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Start Attacking'); + +-- Update SmartAI (Icemist Warriors) +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 26772); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(26772, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 29266, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - On Respawn - Cast \'Permanent Feign Death\''), +(26772, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 18, 262912, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - On Respawn - Set Flags Immune To Players & Immune To NPC\'s & Stunned'), +(26772, 0, 2, 3, 8, 0, 100, 512, 47378, 0, 0, 0, 0, 0, 28, 29266, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - On Spellhit \'Glory of the Ancestors\' - Remove Aura \'Permanent Feign Death\''), +(26772, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2677200, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - On Spellhit \'Glory of the Ancestors\' - Run Script'), +(26772, 0, 4, 0, 38, 0, 100, 512, 1, 1, 0, 0, 0, 0, 41, 5000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - On Data Set 1 1 - Despawn In 5000 ms'); + +-- Add Action List (Icemist Warriors) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2677200); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2677200, 9, 0, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 12, 26676, 6, 6000, 0, 0, 0, 202, 5, 1, 1, 0, 0, 0, 0, 0, 'Icemist Warrior - Actionlist - Summon Creature \'Anub\'ar Invader\''), +(2677200, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 262912, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - Actionlist - Remove Flags Immune To Players & Immune To NPC\'s & Stunned'); + +-- Set Conditions for Icemist's Blessing +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` = 47379; +INSERT INTO `conditions`(`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13,3,47379,0,0,31,0,3,26654,0,0,0,0,'','Icemist\'s Blessing (47379) - target is Roanauk Icemist'), +(13,3,47379,0,1,31,0,3,26772,0,0,0,0,'','Icemist\'s Blessing (47379) - target is Icemist Warrior'), +(13,3,47379,0,2,9,0,12069,0,0,0,0,0,'','Icemist\'s Blessing (47379) - player has quest 12069 active'); From a19dc17cc5164fc3a2fbabbf2d90e878af73cf1b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 19 Aug 2025 12:06:59 +0000 Subject: [PATCH 28/57] chore(DB): import pending files Referenced commit(s): 0f08b6e8ab058e7c42a73c4bfc2346d772ae3a46 --- .../{pending_db_world/Roanauk.sql => db_world/2025_08_19_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/Roanauk.sql => db_world/2025_08_19_00.sql} (99%) diff --git a/data/sql/updates/pending_db_world/Roanauk.sql b/data/sql/updates/db_world/2025_08_19_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/Roanauk.sql rename to data/sql/updates/db_world/2025_08_19_00.sql index 63d6dd95b..a3589d86d 100644 --- a/data/sql/updates/pending_db_world/Roanauk.sql +++ b/data/sql/updates/db_world/2025_08_19_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_18_01 -> 2025_08_19_00 -- Remove Unit Flags from Roanauk Icemist (IMMUNE_TO_PC, IMMUNE_TO_NPC) UPDATE `creature_template` SET `unit_flags` = `unit_flags` &~(256|512) WHERE (`entry` = 26654); From 2602add0fd09dd281ea8318ab162b1cf63c78bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E9=B9=AD?= <18535853+PkllonG@users.noreply.github.com> Date: Tue, 19 Aug 2025 21:03:03 +0800 Subject: [PATCH 29/57] refactor(Core): Improve readability (#22691) --- src/server/game/AI/SmartScripts/SmartScript.cpp | 6 +++--- src/server/game/AuctionHouse/AuctionHouseMgr.cpp | 2 +- src/server/game/Chat/HyperlinkTags.cpp | 2 +- src/server/game/Conditions/ConditionMgr.cpp | 2 +- src/server/game/Entities/Creature/CreatureGroups.h | 2 +- src/server/game/Entities/Player/Player.h | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 2cc4a246b..e0a6f4fb8 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -895,7 +895,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u go->SetLootState(GO_READY); } - go->UseDoorOrButton(0, !!e.action.activateObject.alternative, unit); + go->UseDoorOrButton(0, e.action.activateObject.alternative, unit); LOG_DEBUG("sql.sql", "SmartScript::ProcessAction:: SMART_ACTION_ACTIVATE_GOBJECT. Gameobject {} activated", go->GetGUID().ToString()); } } @@ -1485,14 +1485,14 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { for (WorldObject* target : targets) if (IsUnit(target)) - target->ToUnit()->SetVisible(!!e.action.visibility.state); + target->ToUnit()->SetVisible(e.action.visibility.state); break; } case SMART_ACTION_SET_ACTIVE: { for (WorldObject* target : targets) - target->setActive(!!e.action.setActive.state); + target->setActive(e.action.setActive.state); break; } case SMART_ACTION_ATTACK_START: diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 736fd46e1..dcc1b7662 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -488,7 +488,7 @@ void AuctionHouseObject::AddAuction(AuctionEntry* auction) bool AuctionHouseObject::RemoveAuction(AuctionEntry* auction) { - bool wasInMap = !!_auctionsMap.erase(auction->Id); + bool wasInMap = _auctionsMap.erase(auction->Id); sAuctionMgr->GetAuctionHouseSearcher()->RemoveAuction(auction); sScriptMgr->OnAuctionRemove(this, auction); diff --git a/src/server/game/Chat/HyperlinkTags.cpp b/src/server/game/Chat/HyperlinkTags.cpp index 342ba3035..2cb36b698 100644 --- a/src/server/game/Chat/HyperlinkTags.cpp +++ b/src/server/game/Chat/HyperlinkTags.cpp @@ -206,7 +206,7 @@ bool Acore::Hyperlinks::LinkTags::spell::StoreTo(SpellInfo const*& val, std::str if (!(t.TryConsumeTo(spellId) && t.IsEmpty())) return false; - return !!(val = sSpellMgr->GetSpellInfo(spellId)); + return (val = sSpellMgr->GetSpellInfo(spellId)); } bool Acore::Hyperlinks::LinkTags::talent::StoreTo(TalentLinkData& val, std::string_view text) diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 93bdc0c8a..09edfab28 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -68,7 +68,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) { // don't allow 0 items (it's checked during table load) ASSERT(ConditionValue2); - bool checkBank = !!ConditionValue3; + bool checkBank = ConditionValue3; condMeets = player->HasItemCount(ConditionValue1, ConditionValue2, checkBank); } } diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index 2cb6e9ae8..54b01c08c 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -67,7 +67,7 @@ struct FormationInfo uint32 point_1; uint32 point_2; - bool HasGroupFlag(uint16 flag) const { return !!(groupAI & flag); } + bool HasGroupFlag(uint16 flag) const { return (groupAI & flag); } }; typedef std::unordered_map CreatureGroupInfoType; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index adc4f04c0..16a97177e 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1692,7 +1692,7 @@ public: bool RemoveMItem(ObjectGuid::LowType itemLowGuid) { - return !!mMitems.erase(itemLowGuid); + return mMitems.erase(itemLowGuid); } void PetSpellInitialize(); From e0f2ec41efb7159248b9161825be85fdb8b030c7 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 19 Aug 2025 12:59:57 -0300 Subject: [PATCH 30/57] fix(Scripts/Commands): Allow using debug LFG and BG from console (#22705) --- src/server/scripts/Commands/cs_debug.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index a9fe5d9e0..a18e01e0b 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -73,7 +73,7 @@ public: { "hostile", HandleDebugHostileRefListCommand, SEC_ADMINISTRATOR, Console::No }, { "anim", HandleDebugAnimCommand, SEC_ADMINISTRATOR, Console::No }, { "arena", HandleDebugArenaCommand, SEC_ADMINISTRATOR, Console::No }, - { "bg", HandleDebugBattlegroundCommand, SEC_ADMINISTRATOR, Console::No }, + { "bg", HandleDebugBattlegroundCommand, SEC_ADMINISTRATOR, Console::Yes}, { "cooldown", HandleDebugCooldownCommand, SEC_ADMINISTRATOR, Console::No }, { "getitemstate", HandleDebugGetItemStateCommand, SEC_ADMINISTRATOR, Console::No }, { "lootrecipient", HandleDebugGetLootRecipientCommand, SEC_ADMINISTRATOR, Console::No }, @@ -92,7 +92,7 @@ public: { "update", HandleDebugUpdateCommand, SEC_ADMINISTRATOR, Console::No }, { "itemexpire", HandleDebugItemExpireCommand, SEC_ADMINISTRATOR, Console::No }, { "areatriggers", HandleDebugAreaTriggersCommand, SEC_ADMINISTRATOR, Console::No }, - { "lfg", HandleDebugDungeonFinderCommand, SEC_ADMINISTRATOR, Console::No }, + { "lfg", HandleDebugDungeonFinderCommand, SEC_ADMINISTRATOR, Console::Yes}, { "los", HandleDebugLoSCommand, SEC_ADMINISTRATOR, Console::No }, { "moveflags", HandleDebugMoveflagsCommand, SEC_ADMINISTRATOR, Console::No }, { "unitstate", HandleDebugUnitStateCommand, SEC_ADMINISTRATOR, Console::No }, From d4713356a095f0f1c26f33252ed698b2ee910c80 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Tue, 19 Aug 2025 15:51:06 -0400 Subject: [PATCH 31/57] refactor(Core/Packets): Rewrite `MSG_MINIMAP_PING` to modern packet class. (#22696) --- src/server/game/Groups/Group.cpp | 11 +++++++++ src/server/game/Groups/Group.h | 2 ++ src/server/game/Handlers/GroupHandler.cpp | 20 ++++++---------- .../game/Server/Packets/MiscPackets.cpp | 15 ++++++++++++ src/server/game/Server/Packets/MiscPackets.h | 23 +++++++++++++++++++ src/server/game/Server/WorldSession.h | 3 ++- 6 files changed, 60 insertions(+), 14 deletions(-) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 3fede6ffc..b4b2331e1 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -28,6 +28,7 @@ #include "LFGMgr.h" #include "Log.h" #include "MapMgr.h" +#include "MiscPackets.h" #include "ObjectMgr.h" #include "Opcodes.h" #include "Player.h" @@ -2059,6 +2060,16 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* return GroupJoinBattlegroundResult(bgTemplate->GetBgTypeID()); } +void Group::DoMinimapPing(ObjectGuid sourceGuid, float mapX, float mapY) +{ + WorldPackets::Misc::MinimapPing minimapPing; + minimapPing.SourceGuid = sourceGuid; + minimapPing.MapX = mapX; + minimapPing.MapY = mapY; + + BroadcastPacket(minimapPing.Write(), true, -1, sourceGuid); +} + //=================================================== //============== Roll =============================== //=================================================== diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index f4afabf6f..acf6fc0e1 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -255,6 +255,8 @@ public: void SetBattlefieldGroup(Battlefield* bf); GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const* bgTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot); + void DoMinimapPing(ObjectGuid sourceGuid, float mapX, float mapY); + void ChangeMembersGroup(ObjectGuid guid, uint8 group); void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid); void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index ee4e0676a..85a9f0888 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -22,6 +22,7 @@ #include "LFGMgr.h" #include "Language.h" #include "Log.h" +#include "MapMgr.h" #include "MiscPackets.h" #include "ObjectMgr.h" #include "Opcodes.h" @@ -522,24 +523,17 @@ void WorldSession::HandleLootRoll(WorldPacket& recvData) } } -void WorldSession::HandleMinimapPingOpcode(WorldPacket& recvData) +void WorldSession::HandleMinimapPingOpcode(WorldPackets::Misc::MinimapPingClient& packet) { - if (!GetPlayer()->GetGroup()) + if (!sMapMgr->IsValidMapCoord(GetPlayer()->GetMap()->GetId(), packet.MapX, packet.MapY)) return; - float x, y; - recvData >> x; - recvData >> y; + Group* group = GetPlayer()->GetGroup(); - /** error handling **/ - /********************/ + if (!group) + return; - // everything's fine, do it - WorldPacket data(MSG_MINIMAP_PING, (8 + 4 + 4)); - data << GetPlayer()->GetGUID(); - data << float(x); - data << float(y); - GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID()); + group->DoMinimapPing(GetPlayer()->GetGUID(), packet.MapX, packet.MapY); } void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet) diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index a418a517e..109845381 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -67,6 +67,21 @@ WorldPacket const* WorldPackets::Misc::Playsound::Write() return &_worldPacket; } +void WorldPackets::Misc::MinimapPingClient::Read() +{ + _worldPacket >> MapX; + _worldPacket >> MapY; +} + +WorldPacket const* WorldPackets::Misc::MinimapPing::Write() +{ + _worldPacket << SourceGuid; + _worldPacket << float(MapX); + _worldPacket << float(MapY); + + return &_worldPacket; +} + void WorldPackets::Misc::RandomRollClient::Read() { _worldPacket >> Min; diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index 6f991293f..7453ad7fc 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -93,6 +93,29 @@ namespace WorldPackets uint32 SoundKitID = 0; }; + class MinimapPingClient final : public ClientPacket + { + public: + MinimapPingClient(WorldPacket&& packet) : ClientPacket(MSG_MINIMAP_PING, std::move(packet)) {} + + void Read() override; + + float MapX = 0.0f; // Raw position coordinates + float MapY = 0.0f; + }; + + class MinimapPing final : public ServerPacket + { + public: + MinimapPing() : ServerPacket(MSG_MINIMAP_PING, 8 + 4 + 4) { } + + WorldPacket const* Write() override; + + ObjectGuid SourceGuid; + float MapX = 0.0f; + float MapY = 0.0f; + }; + class RandomRollClient final : public ClientPacket { public: diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 02948d249..9e570f9b0 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -148,6 +148,7 @@ namespace WorldPackets namespace Misc { + class MinimapPingClient; class RandomRollClient; } @@ -933,7 +934,7 @@ public: // opcodes handlers void HandleWardenDataOpcode(WorldPacket& recvData); void HandleWorldTeleportOpcode(WorldPacket& recvData); - void HandleMinimapPingOpcode(WorldPacket& recvData); + void HandleMinimapPingOpcode(WorldPackets::Misc::MinimapPingClient& packet); void HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet); void HandleFarSightOpcode(WorldPacket& recvData); void HandleSetDungeonDifficultyOpcode(WorldPacket& recvData); From 413178662ae43db09f23b6a1c69f75eba36b91d9 Mon Sep 17 00:00:00 2001 From: iThorgrim <125808072+iThorgrim@users.noreply.github.com> Date: Thu, 21 Aug 2025 00:31:00 +0200 Subject: [PATCH 32/57] fix(Core/SAI): GameObject smart_script based on GUID (#22710) --- .../game/AI/SmartScripts/SmartScriptMgr.cpp | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 0040e0bd3..9185f77ac 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -202,10 +202,29 @@ void SmartAIMgr::LoadSmartAIFromDB() } else { - if (!sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid)))) + switch (source_type) { - LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid ({}) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid))); - continue; + case SMART_SCRIPT_TYPE_CREATURE: + { + if (!sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid)))) + { + LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid ({}) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid))); + continue; + } + break; + } + case SMART_SCRIPT_TYPE_GAMEOBJECT: + { + if (!sObjectMgr->GetGameObjectData(uint32(std::abs(temp.entryOrGuid)))) + { + LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: GameObject guid ({}) does not exist, skipped loading.", uint32(temp.entryOrGuid)); + continue; + } + break; + } + default: + LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: not yet implemented source_type {}", (uint32)source_type); + continue; } } From 9d82ae97ae5cf5730b6ed71a5e1470285e75474c Mon Sep 17 00:00:00 2001 From: SAS2000 Date: Thu, 21 Aug 2025 19:13:04 +0200 Subject: [PATCH 33/57] fix(SERVER/Main): Implementation for version param (#22707) --- src/server/apps/authserver/Main.cpp | 9 ++++----- src/server/apps/worldserver/Main.cpp | 8 +++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/server/apps/authserver/Main.cpp b/src/server/apps/authserver/Main.cpp index e9ed0119f..b5fbb319a 100644 --- a/src/server/apps/authserver/Main.cpp +++ b/src/server/apps/authserver/Main.cpp @@ -29,6 +29,7 @@ #include "Config.h" #include "DatabaseEnv.h" #include "DatabaseLoader.h" +#include "GitRevision.h" #include "IPLocation.h" #include "IoContext.h" #include "Log.h" @@ -75,7 +76,7 @@ int main(int argc, char** argv) auto vm = GetConsoleArguments(argc, argv, configFile); // exit if help or version is enabled - if (vm.count("help")) + if (vm.count("help") || vm.count("version")) return 0; // Add file and args in config @@ -292,13 +293,11 @@ variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile) } if (variablesMap.count("help")) - { std::cout << all << "\n"; - } + else if (variablesMap.count("version")) + std::cout << GitRevision::GetFullVersion() << "\n"; else if (variablesMap.count("dry-run")) - { sConfigMgr->setDryRun(true); - } return variablesMap; } diff --git a/src/server/apps/worldserver/Main.cpp b/src/server/apps/worldserver/Main.cpp index 26a13985f..bdc2f860f 100644 --- a/src/server/apps/worldserver/Main.cpp +++ b/src/server/apps/worldserver/Main.cpp @@ -127,7 +127,7 @@ int main(int argc, char** argv) auto vm = GetConsoleArguments(argc, argv, configFile, configService); // exit if help or version is enabled - if (vm.count("help")) + if (vm.count("help") || vm.count("version")) return 0; #if AC_PLATFORM == AC_PLATFORM_WINDOWS @@ -733,13 +733,11 @@ variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, [ } if (vm.count("help")) - { std::cout << all << "\n"; - } + else if (vm.count("version")) + std::cout << GitRevision::GetFullVersion() << "\n"; else if (vm.count("dry-run")) - { sConfigMgr->setDryRun(true); - } return vm; } From c67d4efa4a19625a3d0bbe902dd3ba9f6980d2a2 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Fri, 22 Aug 2025 05:26:35 -0300 Subject: [PATCH 34/57] fix(Core/DB): Update connection type for character settings select (#22712) --- .../database/Database/Implementation/CharacterDatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index b397b0142..ec080b784 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -606,7 +606,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_INS_PROFANITY_PLAYER_NAME, "INSERT IGNORE INTO profanity_name (name) VALUES (?)", CONNECTION_ASYNC); // Character settings - PrepareStatement(CHAR_SEL_CHAR_SETTINGS, "SELECT source, data FROM character_settings WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CHAR_SETTINGS, "SELECT source, data FROM character_settings WHERE guid = ?", CONNECTION_BOTH); PrepareStatement(CHAR_REP_CHAR_SETTINGS, "REPLACE INTO character_settings (guid, source, data) VALUES (?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_SETTINGS, "DELETE FROM character_settings WHERE guid = ?", CONNECTION_ASYNC); From 82d98f9fb7674f0b2f98170e74ecbd66cbd1e287 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Fri, 22 Aug 2025 22:25:15 -0300 Subject: [PATCH 35/57] =?UTF-8?q?chore(Core/Player):=20Change=20player=20s?= =?UTF-8?q?etting=20index=20type=20from=20uint8=20to=20ui=E2=80=A6=20(#227?= =?UTF-8?q?16)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/game/Entities/Player/Player.h | 4 ++-- src/server/game/Entities/Player/PlayerSettings.cpp | 6 +++--- src/server/game/Entities/Player/PlayerSettings.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 16a97177e..ae6b6767c 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2641,8 +2641,8 @@ public: std::string GetPlayerName(); // Settings - [[nodiscard]] PlayerSetting GetPlayerSetting(std::string const& source, uint8 index); - void UpdatePlayerSetting(std::string const& source, uint8 index, uint32 value); + [[nodiscard]] PlayerSetting GetPlayerSetting(std::string const& source, uint32 index); + void UpdatePlayerSetting(std::string const& source, uint32 index, uint32 value); void SendSystemMessage(std::string_view msg, bool escapeCharacters = false); diff --git a/src/server/game/Entities/Player/PlayerSettings.cpp b/src/server/game/Entities/Player/PlayerSettings.cpp index 89b719d71..1fd4aae3a 100644 --- a/src/server/game/Entities/Player/PlayerSettings.cpp +++ b/src/server/game/Entities/Player/PlayerSettings.cpp @@ -80,7 +80,7 @@ namespace PlayerSettingsStore return result; } - void UpdateSetting(uint32 playerLowGuid, std::string const& source, uint8 index, uint32 value) + void UpdateSetting(uint32 playerLowGuid, std::string const& source, uint32 index, uint32 value) { if (!sWorld->getBoolConfig(CONFIG_PLAYER_SETTINGS_ENABLED)) return; @@ -129,7 +129,7 @@ void Player::_LoadCharacterSettings(PreparedQueryResult result) } while (result->NextRow()); } -PlayerSetting Player::GetPlayerSetting(std::string const& source, uint8 index) +PlayerSetting Player::GetPlayerSetting(std::string const& source, uint32 index) { auto it = m_charSettingsMap.find(source); if (it == m_charSettingsMap.end() || static_cast(index) >= it->second.size()) @@ -156,7 +156,7 @@ void Player::_SavePlayerSettings(CharacterDatabaseTransaction trans) } } -void Player::UpdatePlayerSetting(std::string const& source, uint8 index, uint32 value) +void Player::UpdatePlayerSetting(std::string const& source, uint32 index, uint32 value) { auto it = m_charSettingsMap.find(source); size_t const requiredSize = static_cast(index) + 1; diff --git a/src/server/game/Entities/Player/PlayerSettings.h b/src/server/game/Entities/Player/PlayerSettings.h index 612225114..4e0c96135 100644 --- a/src/server/game/Entities/Player/PlayerSettings.h +++ b/src/server/game/Entities/Player/PlayerSettings.h @@ -57,7 +57,7 @@ namespace PlayerSettingsStore { // Update a single setting value for any player by GUID (works for online or offline players). // This reads the existing "source" row from character_settings, adjusts the index, and REPLACE's it back. - void UpdateSetting(uint32 playerLowGuid, std::string const& source, uint8 index, uint32 value); + void UpdateSetting(uint32 playerLowGuid, std::string const& source, uint32 index, uint32 value); // Common helpers for parsing and serializing settings data PlayerSettingVector ParseSettingsData(std::string const& data); From fc90e30e5016d4bf705b4aa49c8be7c4e1e27035 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Sat, 23 Aug 2025 01:11:03 -0400 Subject: [PATCH 36/57] fix(DB): Add spawns/events for Ahn'Qiraj War Effort event. (#22497) --- .../pending_db_world/creature-spawns.sql | 83 ++++ .../updates/pending_db_world/game-events.sql | 464 ++++++++++++++++++ .../pending_db_world/gobject-spawns.sql | 102 ++++ 3 files changed, 649 insertions(+) create mode 100644 data/sql/updates/pending_db_world/creature-spawns.sql create mode 100644 data/sql/updates/pending_db_world/game-events.sql create mode 100644 data/sql/updates/pending_db_world/gobject-spawns.sql diff --git a/data/sql/updates/pending_db_world/creature-spawns.sql b/data/sql/updates/pending_db_world/creature-spawns.sql new file mode 100644 index 000000000..23346778e --- /dev/null +++ b/data/sql/updates/pending_db_world/creature-spawns.sql @@ -0,0 +1,83 @@ +SET @GUID = 83113; + +DELETE FROM `creature` WHERE `id1` IN (3296, 5595, 15383, 15431, 15432, 15434, 15437, 15445, 15446, 15448, 15450, 15451, 15452, 15453, 15455, 15456, 15457, 15458, 15459, 15460, 15469, 15477, 15508, 15512, 15515, 15522, 15525, 15528, 15529, 15532, 15533, 15534, 15535, 15539, 15663, 15696, 15700, 15701, 15702, 15703, 15704, 15707, 15708, 15709, 15731, 15733, 15734, 15735, 15736, 15737, 15738, 15739, 15761, 15762, 15763, 15764, 15765, 15766, 15767, 15768) AND `guid` BETWEEN @GUID AND @GUID+69; +INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +-- Ironforge +(@GUID+0, 15731, 0, 0, 0, 0, 0, 1, 1, 0, -4935.1743, -1197.6975, 501.62204, 2.460914134979248046, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Darnassus Commendation Officer +(@GUID+1, 15733, 0, 0, 0, 0, 0, 1, 1, 0, -4952.5264, -1176.9742, 501.63916, 5.393067359924316406, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Gnomeregan Commendation Officer +(@GUID+2, 15734, 0, 0, 0, 0, 0, 1, 1, 0, -4975.3374, -1196.7572, 501.74588, 1.884955525398254394, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Ironforge Commendation Officer +(@GUID+3, 15735, 0, 0, 0, 0, 0, 1, 1, 0, -4934.9854, -1214.3094, 501.7179, 3.333578824996948242, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Stormwind Commendation Officer +(@GUID+4, 5595, 0, 0, 0, 0, 0, 1, 1, 0, -4980.02, -1219.984, 501.75632, 3.822271108627319335, 300, 0, 0, 5228, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Ironforge Guard +(@GUID+5, 15539, 0, 0, 0, 0, 0, 1, 1, 0, -4981.2524, -1218.3779, 501.7562, 3.804817676544189453, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- General Zog +(@GUID+6, 5595, 0, 0, 0, 0, 0, 1, 1, 0, -4982.4688, -1216.806, 501.7562, 3.874630928039550781, 300, 0, 0, 5228, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Ironforge Guard +(@GUID+7, 15383, 0, 0, 0, 0, 0, 1, 1, 0, -4924.3657, -1222.7299, 501.71756, 3.926990747451782226, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Sergeant Stonebrow +(@GUID+8, 15431, 0, 0, 0, 0, 0, 1, 1, 0, -4914.172, -1227.4949, 501.73282, 3.59537816047668457, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Corporal Carnes +(@GUID+9, 15432, 0, 0, 0, 0, 0, 1, 1, 0, -4930.287, -1218.7476, 501.71875, 3.752457857131958007, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Dame Twinbraid +(@GUID+10, 15434, 0, 0, 0, 0, 0, 1, 1, 0, -4952.255, -1274.4495, 501.75662, 1.797689080238342285, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Private Draxlegauge +(@GUID+11, 15437, 0, 0, 0, 0, 0, 1, 1, 0, -4945.4204, -1282.0215, 501.75787, 1.029744267463684082, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Master Nightsong +(@GUID+12, 15445, 0, 0, 0, 0, 0, 1, 1, 0, -4948.3345, -1273.7974, 501.75522, 1.064650893211364746, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Sergeant Major Germaine +(@GUID+13, 15446, 0, 0, 0, 0, 0, 1, 1, 0, -4972.2017, -1169.0591, 501.72, 3.281219005584716796, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Bonnie Stoneflayer +(@GUID+14, 15448, 0, 0, 0, 0, 0, 1, 1, 0, -4966.0938, -1176.0596, 501.74265, 3.298672199249267578, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Private Porter +(@GUID+15, 15450, 0, 0, 0, 0, 0, 1, 1, 0, -4969.4565, -1180.2417, 501.7428, 3.246312379837036132, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Marta Finespindle +(@GUID+16, 15451, 0, 0, 0, 0, 0, 1, 1, 0, -4971.5747, -1151.5566, 501.73938, 3.560471534729003906, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Sentinel Silversky +(@GUID+17, 15452, 0, 0, 0, 0, 0, 1, 1, 0, -4979.116, -1149.51, 501.7331, 3.368485450744628906, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Nurse Stonefield +(@GUID+18, 15453, 0, 0, 0, 0, 0, 1, 1, 0, -4979.9287, -1142.1707, 501.7428, 3.682644605636596679, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Keeper Moonshade +(@GUID+19, 15455, 0, 0, 0, 0, 0, 1, 1, 0, -4938.0024, -1275.1202, 501.75195, 2.460914134979248046, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Slicky Gastronome +(@GUID+20, 15456, 0, 0, 0, 0, 0, 1, 1, 0, -4940.392, -1277.704, 501.7544, 1.989675283432006835, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Sarah Sadwhistle +(@GUID+21, 15457, 0, 0, 0, 0, 0, 1, 1, 0, -4933.8027, -1279.1617, 501.74948, 2.426007747650146484, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Huntress Swiftriver +(@GUID+22, 15663, 0, 0, 0, 0, 0, 1, 1, 0, -4917.319, -1224.8823, 501.7417, 4.327857494354248046, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Volunteer +(@GUID+23, 15663, 0, 0, 0, 0, 0, 1, 1, 0, -4944.852, -1277.7028, 501.75586, 4.258603572845458984, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Volunteer +(@GUID+24, 15663, 0, 0, 0, 0, 0, 1, 1, 0, -4966.2954, -1173.8835, 501.72675, 3.648972272872924804, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Volunteer +(@GUID+25, 15663, 0, 0, 0, 0, 0, 1, 1, 0, -4975.13, -1153.5369, 501.74008, 3.013503551483154296, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Volunteer +(@GUID+26, 15663, 0, 0, 0, 0, 0, 1, 1, 0, -4937.548, -1280.2931, 501.7544, 4.558997154235839843, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Volunteer +(@GUID+27, 15701, 0, 0, 0, 0, 0, 1, 1, 0, -4977.4976, -1172.4156, 501.7317, 2.282009840011596679, 300, 0, 0, 30520, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- Field Marshal Snowfall +-- Orgrimmar +(@GUID+28, 15736, 0, 0, 1, 0, 0, 1, 1, 0, 1584.7704, -4112.9443, 33.37767, 5.410520553588867187, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Orgrimmar Commendation Officer +(@GUID+29, 15737, 0, 0, 1, 0, 0, 1, 1, 0, 1618.4412, -4101.7646, 32.95245, 5.235987663269042968, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Darkspear Commendation Officer +(@GUID+30, 15738, 0, 0, 1, 0, 0, 1, 1, 0, 1660.3582, -4107.4517, 34.620274, 2.059488534927368164, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Undercity Commendation Officer +(@GUID+31, 15739, 0, 0, 1, 0, 0, 1, 1, 0, 1603.886, -4142.897, 33.78176, 2.443460941314697265, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Thunder Bluff Commendation Officer +(@GUID+32, 3296, 0, 0, 1, 0, 0, 1, 1, 0, 1628.9564, -4119.1763, 31.244139, 2.094395160675048828, 300, 0, 0, 5228, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Orgrimmar Grunt +(@GUID+33, 15458, 0, 0, 1, 0, 0, 1, 1, 0, 1630.693, -4118.458, 31.265778, 1.972222089767456054, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Commander Stronghammer +(@GUID+34, 3296, 0, 0, 1, 0, 0, 1, 1, 0, 1632.3059, -4117.596, 31.29346, 2.042035102844238281, 300, 0, 0, 5228, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Orgrimmar Grunt +(@GUID+35, 15522, 0, 0, 1, 0, 0, 1, 1, 0, 1593.2671, -4159.4404, 36.90244, 2.94960641860961914, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Sergeant Umala +(@GUID+36, 15533, 0, 0, 1, 0, 0, 1, 1, 0, 1643.4338, -4085.0864, 37.337215, 4.677482128143310546, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Bloodguard Rawtar +(@GUID+37, 15534, 0, 0, 1, 0, 0, 1, 1, 0, 1629.785, -4089.1484, 35.632874, 5.25344085693359375, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Fisherman Lin'do +(@GUID+38, 15535, 0, 0, 1, 0, 0, 1, 1, 0, 1634.1218, -4084.9915, 36.52574, 5.218534469604492187, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Chief Sharpclaw +(@GUID+39, 15459, 0, 0, 1, 0, 0, 1, 1, 0, 1650.3278, -4124.2856, 31.452269, 2.652900457382202148, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Miner Cromwell +(@GUID+40, 15460, 0, 0, 1, 0, 0, 1, 1, 0, 1665.7623, -4117.497, 34.37464, 2.443460941314697265, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Grunt Maug +(@GUID+41, 15469, 0, 0, 1, 0, 0, 1, 1, 0, 1655.7728, -4119.1626, 32.695107, 1.326450228691101074, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Senior Sergeant T'kelah +(@GUID+42, 15477, 0, 0, 1, 0, 0, 1, 1, 0, 1615.0131, -4145.532, 35.131996, 1.378810048103332519, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Herbalist Proudfeather +(@GUID+43, 15508, 0, 0, 1, 0, 0, 1, 1, 0, 1625.951, -4149.423, 36.395786, 1.902408838272094726, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Batrider Pele'keiki +(@GUID+44, 15512, 0, 0, 1, 0, 0, 1, 1, 0, 1633.2582, -4142.117, 34.70991, 2.111848354339599609, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Apothecary Jezel +(@GUID+45, 15515, 0, 0, 1, 0, 0, 1, 1, 0, 1588.1735, -4179.9014, 39.98489, 2.897246599197387695, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Skinner Jamani +(@GUID+46, 15525, 0, 0, 1, 0, 0, 1, 1, 0, 1595.7618, -4174.3965, 39.766666, 2.722713708877563476, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Doctor Serratus +(@GUID+47, 15528, 0, 0, 1, 0, 0, 1, 1, 0, 1580.1736, -4116.1064, 34.41577, 5.602506637573242187, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Healer Longrunner +(@GUID+48, 15529, 0, 0, 1, 0, 0, 1, 1, 0, 1571.1464, -4118.6587, 36.584232, 5.026548385620117187, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Lady Callow +(@GUID+49, 15532, 0, 0, 1, 0, 0, 1, 1, 0, 1565.0651, -4123.9863, 37.44075, 0, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Stoneguard Clayhoof +(@GUID+50, 15696, 0, 0, 1, 0, 0, 1, 1, 0, 1576.2423, -4118.5137, 35.26423, 4.112950801849365234, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Recruit +(@GUID+51, 15696, 0, 0, 1, 0, 0, 1, 1, 0, 1591.8158, -4162.673, 37.39431, 4.81041717529296875, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Recruit +(@GUID+52, 15696, 0, 0, 1, 0, 0, 1, 1, 0, 1639.2985, -4081.972, 37.58056, 4.678342819213867187, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Recruit +(@GUID+53, 15696, 0, 0, 1, 0, 0, 1, 1, 0, 1629.4264, -4142.979, 34.864754, 3.117774009704589843, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Recruit +(@GUID+54, 15696, 0, 0, 1, 0, 0, 1, 1, 0, 1666.3688, -4109.401, 35.089664, 1.868425965309143066, 300, 0, 0, 4775, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Recruit +(@GUID+55, 15700, 0, 0, 1, 0, 0, 1, 1, 0, 1581.5414, -4184.574, 39.5738, 1.563615918159484863, 300, 0, 0, 30520, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Warlord Gorchuk + +-- War Effort Recruiters +(@GUID+56, 15702, 0, 0, 1, 0, 0, 1, 1, 0, -1209.5848, 100.22011, 134.661, 3.159045934677124023, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Senior Sergeant Taiga +(@GUID+57, 15703, 0, 0, 0, 0, 0, 1, 1, 0, 1572.5758, 272.70654, -43.01935, 5.026548385620117187, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Senior Sergeant Grimsford +(@GUID+58, 15704, 0, 0, 1, 0, 0, 1, 1, 0, 1653.0684, -4403.811, 18.581886, 4.450589656829833984, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Senior Sergeant Kai'jin +(@GUID+59, 15707, 0, 0, 0, 0, 0, 1, 1, 0, -4956.0864, -931.13306, 503.3468, 5.375614166259765625, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Master Sergeant Fizzlebolt +(@GUID+60, 15708, 0, 0, 0, 0, 0, 1, 1, 0, -8813.751, 654.0678, 96.16028, 4.834561824798583984, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Master Sergeant Maclure +(@GUID+61, 15709, 0, 0, 1, 0, 0, 1, 1, 0, 9945.1455, 2494.2393, 1317.5244, 4.206243515014648437, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Master Sergeant Moonshadow +-- Commendation Officers +(@GUID+62, 15761, 0, 0, 1, 0, 0, 1, 1, 0, 1945.322, -4330.305, 22.101057, 3.50811171531677246, 300, 0, 0, 2914, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Vu'Shalay +(@GUID+63, 15762, 0, 0, 1, 0, 0, 1, 1, 0, 9965.52, 2533.7234, 1319.0049, 0.471238881349563598, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Lunalight +(@GUID+64, 15763, 0, 0, 0, 0, 0, 1, 1, 0, -4811.9756, -1264.849, 501.95117, 3.054326057434082031, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Porterhouse +(@GUID+65, 15764, 0, 0, 0, 0, 0, 1, 1, 0, -4814.475, -1055.5201, 502.26733, 6.213372230529785156, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Ironbeard +(@GUID+66, 15765, 0, 0, 1, 0, 0, 1, 1, 0, 1911.704, -4276.771, 31.655682, 4.886921882629394531, 300, 0, 0, 2914, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Redblade +(@GUID+67, 15766, 0, 0, 0, 0, 0, 1, 1, 0, -8859.14, 638.28687, 96.34692, 1.815142393112182617, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Maloof +(@GUID+68, 15767, 0, 0, 1, 0, 0, 1, 1, 0, -1246.4849, 74.262695, 128.36818, 5.026548385620117187, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Thunderstrider +(@GUID+69, 15768, 0, 0, 0, 0, 0, 1, 1, 0, 1587.8914, 279.28018, -43.019344, 4.852015495300292968, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL); -- Officer Gothena + +-- Old spawns +DELETE FROM `creature` WHERE `guid` IN (37, 2032, 6519, 6520, 25997, 32076, 46803) AND `id1` IN (14724, 15761, 15762, 15764, 15765, 15767, 15768); +DELETE FROM `creature_addon` WHERE `guid` IN (6519, 6520, 25997, 32076, 46803); diff --git a/data/sql/updates/pending_db_world/game-events.sql b/data/sql/updates/pending_db_world/game-events.sql new file mode 100644 index 000000000..17b1fb939 --- /dev/null +++ b/data/sql/updates/pending_db_world/game-events.sql @@ -0,0 +1,464 @@ +SET @EventID = 131, + @OGUID = 3639, + @CGUID = 83113; + +SET @AQWarAllianceBarsInitial = @EventID+0, + @AQWarAllianceBarsT1 = @EventID+1, + @AQWarAllianceBarsT2 = @EventID+2, + @AQWarAllianceBarsT3 = @EventID+3, + @AQWarAllianceBarsT4 = @EventID+4, + @AQWarAllianceBarsT5 = @EventID+5, + @AQWarAllianceHerbsInitial = @EventID+6, + @AQWarAllianceHerbsT1 = @EventID+7, + @AQWarAllianceHerbsT2 = @EventID+8, + @AQWarAllianceHerbsT3 = @EventID+9, + @AQWarAllianceHerbsT4 = @EventID+10, + @AQWarAllianceHerbsT5 = @EventID+11, + @AQWarAllianceSkinsInitial = @EventID+12, + @AQWarAllianceSkinsT1 = @EventID+13, + @AQWarAllianceSkinsT2 = @EventID+14, + @AQWarAllianceSkinsT3 = @EventID+15, + @AQWarAllianceSkinsT4 = @EventID+16, + @AQWarAllianceSkinsT5 = @EventID+17, + @AQWarAllianceBandagesInitial = @EventID+18, + @AQWarAllianceBandagesT1 = @EventID+19, + @AQWarAllianceBandagesT2 = @EventID+20, + @AQWarAllianceBandagesT3 = @EventID+21, + @AQWarAllianceBandagesT4 = @EventID+22, + @AQWarAllianceBandagesT5 = @EventID+23, + @AQWarAllianceCookedGoodsInitial = @EventID+24, + @AQWarAllianceCookedGoodsT1 = @EventID+25, + @AQWarAllianceCookedGoodsT2 = @EventID+26, + @AQWarAllianceCookedGoodsT3 = @EventID+27, + @AQWarAllianceCookedGoodsT4 = @EventID+28, + @AQWarAllianceCookedGoodsT5 = @EventID+29, + @AQWarHordeBarsInitial = @EventID+30, + @AQWarHordeBarsT1 = @EventID+31, + @AQWarHordeBarsT2 = @EventID+32, + @AQWarHordeBarsT3 = @EventID+33, + @AQWarHordeBarsT4 = @EventID+34, + @AQWarHordeBarsT5 = @EventID+35, + @AQWarHordeHerbsInitial = @EventID+36, + @AQWarHordeHerbsT1 = @EventID+37, + @AQWarHordeHerbsT2 = @EventID+38, + @AQWarHordeHerbsT3 = @EventID+39, + @AQWarHordeHerbsT4 = @EventID+40, + @AQWarHordeHerbsT5 = @EventID+41, + @AQWarHordeSkinsInitial = @EventID+42, + @AQWarHordeSkinsT1 = @EventID+43, + @AQWarHordeSkinsT2 = @EventID+44, + @AQWarHordeSkinsT3 = @EventID+45, + @AQWarHordeSkinsT4 = @EventID+46, + @AQWarHordeSkinsT5 = @EventID+47, + @AQWarHordeBandagesInitial = @EventID+48, + @AQWarHordeBandagesT1 = @EventID+49, + @AQWarHordeBandagesT2 = @EventID+50, + @AQWarHordeBandagesT3 = @EventID+51, + @AQWarHordeBandagesT4 = @EventID+52, + @AQWarHordeBandagesT5 = @EventID+53, + @AQWarHordeCookedGoodsInitial = @EventID+54, + @AQWarHordeCookedGoodsT1 = @EventID+55, + @AQWarHordeCookedGoodsT2 = @EventID+56, + @AQWarHordeCookedGoodsT3 = @EventID+57, + @AQWarHordeCookedGoodsT4 = @EventID+58, + @AQWarHordeCookedGoodsT5 = @EventID+59; + +DELETE FROM `game_event` WHERE `eventEntry` IN (@AQWarAllianceBarsInitial, @AQWarAllianceBarsT1, @AQWarAllianceBarsT2, @AQWarAllianceBarsT3, @AQWarAllianceBarsT4, @AQWarAllianceBarsT5, @AQWarAllianceHerbsInitial, @AQWarAllianceHerbsT1, @AQWarAllianceHerbsT2, @AQWarAllianceHerbsT3, @AQWarAllianceHerbsT4, @AQWarAllianceHerbsT5, @AQWarAllianceSkinsInitial, @AQWarAllianceSkinsT1, @AQWarAllianceSkinsT2, @AQWarAllianceSkinsT3, @AQWarAllianceSkinsT4, @AQWarAllianceSkinsT5, @AQWarAllianceBandagesInitial, @AQWarAllianceBandagesT1, @AQWarAllianceBandagesT2, @AQWarAllianceBandagesT3, @AQWarAllianceBandagesT4, @AQWarAllianceBandagesT5, @AQWarAllianceCookedGoodsInitial, @AQWarAllianceCookedGoodsT1, @AQWarAllianceCookedGoodsT2, @AQWarAllianceCookedGoodsT3, @AQWarAllianceCookedGoodsT4, @AQWarAllianceCookedGoodsT5, @AQWarHordeBarsInitial, @AQWarHordeBarsT1, @AQWarHordeBarsT2, @AQWarHordeBarsT3, @AQWarHordeBarsT4, @AQWarHordeBarsT5, @AQWarHordeHerbsInitial, @AQWarHordeHerbsT1, @AQWarHordeHerbsT2, @AQWarHordeHerbsT3, @AQWarHordeHerbsT4, @AQWarHordeHerbsT5, @AQWarHordeSkinsInitial, @AQWarHordeSkinsT1, @AQWarHordeSkinsT2, @AQWarHordeSkinsT3, @AQWarHordeSkinsT4, @AQWarHordeSkinsT5, @AQWarHordeBandagesInitial, @AQWarHordeBandagesT1, @AQWarHordeBandagesT2, @AQWarHordeBandagesT3, @AQWarHordeBandagesT4, @AQWarHordeBandagesT5, @AQWarHordeCookedGoodsInitial, @AQWarHordeCookedGoodsT1, @AQWarHordeCookedGoodsT2, @AQWarHordeCookedGoodsT3, @AQWarHordeCookedGoodsT4, @AQWarHordeCookedGoodsT5); +INSERT INTO `game_event` (`eventEntry`, `start_time`, `end_time`, `occurence`, `length`, `holiday`, `holidayStage`, `description`, `world_event`, `announce`) VALUES +(@AQWarAllianceBarsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Initial', 5, 2), +(@AQWarAllianceBarsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Tier 1', 5, 2), +(@AQWarAllianceBarsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Tier 2', 5, 2), +(@AQWarAllianceBarsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Tier 3', 5, 2), +(@AQWarAllianceBarsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Tier 4', 5, 2), +(@AQWarAllianceBarsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Tier 5', 5, 2), +(@AQWarAllianceHerbsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Initial', 5, 2), +(@AQWarAllianceHerbsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Tier 1', 5, 2), +(@AQWarAllianceHerbsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Tier 2', 5, 2), +(@AQWarAllianceHerbsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Tier 3', 5, 2), +(@AQWarAllianceHerbsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Tier 4', 5, 2), +(@AQWarAllianceHerbsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Tier 5', 5, 2), +(@AQWarAllianceSkinsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Initial', 5, 2), +(@AQWarAllianceSkinsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Tier 1', 5, 2), +(@AQWarAllianceSkinsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Tier 2', 5, 2), +(@AQWarAllianceSkinsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Tier 3', 5, 2), +(@AQWarAllianceSkinsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Tier 4', 5, 2), +(@AQWarAllianceSkinsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Tier 5', 5, 2), +(@AQWarAllianceBandagesInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Initial', 5, 2), +(@AQWarAllianceBandagesT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Tier 1', 5, 2), +(@AQWarAllianceBandagesT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Tier 2', 5, 2), +(@AQWarAllianceBandagesT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Tier 3', 5, 2), +(@AQWarAllianceBandagesT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Tier 4', 5, 2), +(@AQWarAllianceBandagesT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Tier 5', 5, 2), +(@AQWarAllianceCookedGoodsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Initial', 5, 2), +(@AQWarAllianceCookedGoodsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Tier 1', 5, 2), +(@AQWarAllianceCookedGoodsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Tier 2', 5, 2), +(@AQWarAllianceCookedGoodsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Tier 3', 5, 2), +(@AQWarAllianceCookedGoodsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Tier 4', 5, 2), +(@AQWarAllianceCookedGoodsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Tier 5', 5, 2), +(@AQWarHordeBarsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Initial', 5, 2), +(@AQWarHordeBarsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Tier 1', 5, 2), +(@AQWarHordeBarsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Tier 2', 5, 2), +(@AQWarHordeBarsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Tier 3', 5, 2), +(@AQWarHordeBarsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Tier 4', 5, 2), +(@AQWarHordeBarsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Tier 5', 5, 2), +(@AQWarHordeHerbsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Initial', 5, 2), +(@AQWarHordeHerbsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Tier 1', 5, 2), +(@AQWarHordeHerbsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Tier 2', 5, 2), +(@AQWarHordeHerbsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Tier 3', 5, 2), +(@AQWarHordeHerbsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Tier 4', 5, 2), +(@AQWarHordeHerbsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Tier 5', 5, 2), +(@AQWarHordeSkinsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Initial', 5, 2), +(@AQWarHordeSkinsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Tier 1', 5, 2), +(@AQWarHordeSkinsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Tier 2', 5, 2), +(@AQWarHordeSkinsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Tier 3', 5, 2), +(@AQWarHordeSkinsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Tier 4', 5, 2), +(@AQWarHordeSkinsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Tier 5', 5, 2), +(@AQWarHordeBandagesInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Initial', 5, 2), +(@AQWarHordeBandagesT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Tier 1', 5, 2), +(@AQWarHordeBandagesT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Tier 2', 5, 2), +(@AQWarHordeBandagesT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Tier 3', 5, 2), +(@AQWarHordeBandagesT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Tier 4', 5, 2), +(@AQWarHordeBandagesT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Tier 5', 5, 2), +(@AQWarHordeCookedGoodsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Initial', 5, 2), +(@AQWarHordeCookedGoodsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Tier 1', 5, 2), +(@AQWarHordeCookedGoodsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Tier 2', 5, 2), +(@AQWarHordeCookedGoodsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Tier 3', 5, 2), +(@AQWarHordeCookedGoodsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Tier 4', 5, 2), +(@AQWarHordeCookedGoodsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Tier 5', 5, 2); + +DELETE FROM `game_event_creature` WHERE `eventEntry` = 22 AND `guid` BETWEEN @CGUID AND @CGUID+69; +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES +(22, @CGUID+0), +(22, @CGUID+1), +(22, @CGUID+2), +(22, @CGUID+3), +(22, @CGUID+4), +(22, @CGUID+5), +(22, @CGUID+6), +(22, @CGUID+7), +(22, @CGUID+8), +(22, @CGUID+9), +(22, @CGUID+10), +(22, @CGUID+11), +(22, @CGUID+12), +(22, @CGUID+13), +(22, @CGUID+14), +(22, @CGUID+15), +(22, @CGUID+16), +(22, @CGUID+17), +(22, @CGUID+18), +(22, @CGUID+19), +(22, @CGUID+20), +(22, @CGUID+21), +(22, @CGUID+22), +(22, @CGUID+23), +(22, @CGUID+24), +(22, @CGUID+25), +(22, @CGUID+26), +(22, @CGUID+27), +(22, @CGUID+28), +(22, @CGUID+29), +(22, @CGUID+30), +(22, @CGUID+31), +(22, @CGUID+32), +(22, @CGUID+33), +(22, @CGUID+34), +(22, @CGUID+35), +(22, @CGUID+36), +(22, @CGUID+37), +(22, @CGUID+38), +(22, @CGUID+39), +(22, @CGUID+40), +(22, @CGUID+41), +(22, @CGUID+42), +(22, @CGUID+43), +(22, @CGUID+44), +(22, @CGUID+45), +(22, @CGUID+46), +(22, @CGUID+47), +(22, @CGUID+48), +(22, @CGUID+49), +(22, @CGUID+50), +(22, @CGUID+51), +(22, @CGUID+52), +(22, @CGUID+53), +(22, @CGUID+54), +(22, @CGUID+55), +(22, @CGUID+56), +(22, @CGUID+57), +(22, @CGUID+58), +(22, @CGUID+59), +(22, @CGUID+60), +(22, @CGUID+61), +(22, @CGUID+62), +(22, @CGUID+63), +(22, @CGUID+64), +(22, @CGUID+65), +(22, @CGUID+66), +(22, @CGUID+67), +(22, @CGUID+68), +(22, @CGUID+69); + +DELETE FROM `game_event_creature` WHERE `eventEntry` = 22 AND `guid` IN (37, 2032, 6519, 6520, 25997, 32076, 46803); + +DELETE FROM `game_event_gameobject` WHERE `eventEntry` IN (@AQWarAllianceBarsInitial, @AQWarAllianceBarsT1, @AQWarAllianceBarsT2, @AQWarAllianceBarsT3, @AQWarAllianceBarsT4, @AQWarAllianceBarsT5, @AQWarAllianceHerbsInitial, @AQWarAllianceHerbsT1, @AQWarAllianceHerbsT2, @AQWarAllianceHerbsT3, @AQWarAllianceHerbsT4, @AQWarAllianceHerbsT5, @AQWarAllianceSkinsInitial, @AQWarAllianceSkinsT1, @AQWarAllianceSkinsT2, @AQWarAllianceSkinsT3, @AQWarAllianceSkinsT4, @AQWarAllianceSkinsT5, @AQWarAllianceBandagesInitial, @AQWarAllianceBandagesT1, @AQWarAllianceBandagesT2, @AQWarAllianceBandagesT3, @AQWarAllianceBandagesT4, @AQWarAllianceBandagesT5, @AQWarAllianceCookedGoodsInitial, @AQWarAllianceCookedGoodsT1, @AQWarAllianceCookedGoodsT2, @AQWarAllianceCookedGoodsT3, @AQWarAllianceCookedGoodsT4, @AQWarAllianceCookedGoodsT5, @AQWarHordeBarsInitial, @AQWarHordeBarsT1, @AQWarHordeBarsT2, @AQWarHordeBarsT3, @AQWarHordeBarsT4, @AQWarHordeBarsT5, @AQWarHordeHerbsInitial, @AQWarHordeHerbsT1, @AQWarHordeHerbsT2, @AQWarHordeHerbsT3, @AQWarHordeHerbsT4, @AQWarHordeHerbsT5, @AQWarHordeSkinsInitial, @AQWarHordeSkinsT1, @AQWarHordeSkinsT2, @AQWarHordeSkinsT3, @AQWarHordeSkinsT4, @AQWarHordeSkinsT5, @AQWarHordeBandagesInitial, @AQWarHordeBandagesT1, @AQWarHordeBandagesT2, @AQWarHordeBandagesT3, @AQWarHordeBandagesT4, @AQWarHordeBandagesT5, @AQWarHordeCookedGoodsInitial, @AQWarHordeCookedGoodsT1, @AQWarHordeCookedGoodsT2, @AQWarHordeCookedGoodsT3, @AQWarHordeCookedGoodsT4, @AQWarHordeCookedGoodsT5); +INSERT INTO `game_event_gameobject` (`eventEntry`, `guid`) VALUES +(@AQWarAllianceBarsInitial, @OGUID+19), +(@AQWarAllianceBarsT1, @OGUID+19), +(@AQWarAllianceBarsT1, @OGUID+20), +(@AQWarAllianceBarsT2, @OGUID+19), +(@AQWarAllianceBarsT2, @OGUID+20), +(@AQWarAllianceBarsT2, @OGUID+21), +(@AQWarAllianceBarsT3, @OGUID+19), +(@AQWarAllianceBarsT3, @OGUID+20), +(@AQWarAllianceBarsT3, @OGUID+21), +(@AQWarAllianceBarsT3, @OGUID+22), +(@AQWarAllianceBarsT4, @OGUID+19), +(@AQWarAllianceBarsT4, @OGUID+20), +(@AQWarAllianceBarsT4, @OGUID+21), +(@AQWarAllianceBarsT4, @OGUID+22), +(@AQWarAllianceBarsT4, @OGUID+23), +(@AQWarAllianceBarsT5, @OGUID+19), +(@AQWarAllianceBarsT5, @OGUID+20), +(@AQWarAllianceBarsT5, @OGUID+21), +(@AQWarAllianceBarsT5, @OGUID+22), +(@AQWarAllianceBarsT5, @OGUID+23), +(@AQWarAllianceBarsT5, @OGUID+24), +(@AQWarAllianceHerbsInitial, @OGUID+25), +(@AQWarAllianceHerbsT1, @OGUID+25), +(@AQWarAllianceHerbsT1, @OGUID+31), +(@AQWarAllianceHerbsT2, @OGUID+25), +(@AQWarAllianceHerbsT2, @OGUID+31), +(@AQWarAllianceHerbsT2, @OGUID+32), +(@AQWarAllianceHerbsT3, @OGUID+25), +(@AQWarAllianceHerbsT3, @OGUID+31), +(@AQWarAllianceHerbsT3, @OGUID+32), +(@AQWarAllianceHerbsT3, @OGUID+33), +(@AQWarAllianceHerbsT4, @OGUID+25), +(@AQWarAllianceHerbsT4, @OGUID+31), +(@AQWarAllianceHerbsT4, @OGUID+32), +(@AQWarAllianceHerbsT4, @OGUID+33), +(@AQWarAllianceHerbsT4, @OGUID+34), +(@AQWarAllianceHerbsT5, @OGUID+25), +(@AQWarAllianceHerbsT5, @OGUID+31), +(@AQWarAllianceHerbsT5, @OGUID+32), +(@AQWarAllianceHerbsT5, @OGUID+33), +(@AQWarAllianceHerbsT5, @OGUID+34), +(@AQWarAllianceHerbsT5, @OGUID+35), +(@AQWarAllianceSkinsInitial, @OGUID+36), +(@AQWarAllianceSkinsT1, @OGUID+36), +(@AQWarAllianceSkinsT1, @OGUID+37), +(@AQWarAllianceSkinsT2, @OGUID+36), +(@AQWarAllianceSkinsT2, @OGUID+37), +(@AQWarAllianceSkinsT2, @OGUID+38), +(@AQWarAllianceSkinsT3, @OGUID+36), +(@AQWarAllianceSkinsT3, @OGUID+37), +(@AQWarAllianceSkinsT3, @OGUID+38), +(@AQWarAllianceSkinsT3, @OGUID+39), +(@AQWarAllianceSkinsT4, @OGUID+36), +(@AQWarAllianceSkinsT4, @OGUID+37), +(@AQWarAllianceSkinsT4, @OGUID+38), +(@AQWarAllianceSkinsT4, @OGUID+39), +(@AQWarAllianceSkinsT4, @OGUID+40), +(@AQWarAllianceSkinsT5, @OGUID+36), +(@AQWarAllianceSkinsT5, @OGUID+37), +(@AQWarAllianceSkinsT5, @OGUID+38), +(@AQWarAllianceSkinsT5, @OGUID+39), +(@AQWarAllianceSkinsT5, @OGUID+40), +(@AQWarAllianceSkinsT5, @OGUID+41), +(@AQWarAllianceBandagesInitial, @OGUID+0), +(@AQWarAllianceBandagesT1, @OGUID+0), +(@AQWarAllianceBandagesT1, @OGUID+1), +(@AQWarAllianceBandagesT1, @OGUID+6), +(@AQWarAllianceBandagesT2, @OGUID+0), +(@AQWarAllianceBandagesT2, @OGUID+1), +(@AQWarAllianceBandagesT2, @OGUID+2), +(@AQWarAllianceBandagesT2, @OGUID+6), +(@AQWarAllianceBandagesT2, @OGUID+7), +(@AQWarAllianceBandagesT2, @OGUID+8), +(@AQWarAllianceBandagesT2, @OGUID+9), +(@AQWarAllianceBandagesT3, @OGUID+0), +(@AQWarAllianceBandagesT3, @OGUID+1), +(@AQWarAllianceBandagesT3, @OGUID+2), +(@AQWarAllianceBandagesT3, @OGUID+3), +(@AQWarAllianceBandagesT3, @OGUID+6), +(@AQWarAllianceBandagesT3, @OGUID+7), +(@AQWarAllianceBandagesT3, @OGUID+8), +(@AQWarAllianceBandagesT3, @OGUID+9), +(@AQWarAllianceBandagesT3, @OGUID+10), +(@AQWarAllianceBandagesT3, @OGUID+11), +(@AQWarAllianceBandagesT3, @OGUID+12), +(@AQWarAllianceBandagesT3, @OGUID+13), +(@AQWarAllianceBandagesT4, @OGUID+0), +(@AQWarAllianceBandagesT4, @OGUID+1), +(@AQWarAllianceBandagesT4, @OGUID+2), +(@AQWarAllianceBandagesT4, @OGUID+3), +(@AQWarAllianceBandagesT4, @OGUID+4), +(@AQWarAllianceBandagesT4, @OGUID+6), +(@AQWarAllianceBandagesT4, @OGUID+7), +(@AQWarAllianceBandagesT4, @OGUID+8), +(@AQWarAllianceBandagesT4, @OGUID+9), +(@AQWarAllianceBandagesT4, @OGUID+10), +(@AQWarAllianceBandagesT4, @OGUID+11), +(@AQWarAllianceBandagesT4, @OGUID+12), +(@AQWarAllianceBandagesT4, @OGUID+13), +(@AQWarAllianceBandagesT4, @OGUID+14), +(@AQWarAllianceBandagesT4, @OGUID+15), +(@AQWarAllianceBandagesT4, @OGUID+16), +(@AQWarAllianceBandagesT4, @OGUID+17), +(@AQWarAllianceBandagesT4, @OGUID+18), +(@AQWarAllianceBandagesT5, @OGUID+0), +(@AQWarAllianceBandagesT5, @OGUID+1), +(@AQWarAllianceBandagesT5, @OGUID+2), +(@AQWarAllianceBandagesT5, @OGUID+3), +(@AQWarAllianceBandagesT5, @OGUID+4), +(@AQWarAllianceBandagesT5, @OGUID+5), +(@AQWarAllianceBandagesT5, @OGUID+6), +(@AQWarAllianceBandagesT5, @OGUID+7), +(@AQWarAllianceBandagesT5, @OGUID+8), +(@AQWarAllianceBandagesT5, @OGUID+9), +(@AQWarAllianceBandagesT5, @OGUID+10), +(@AQWarAllianceBandagesT5, @OGUID+11), +(@AQWarAllianceBandagesT5, @OGUID+12), +(@AQWarAllianceBandagesT5, @OGUID+13), +(@AQWarAllianceBandagesT5, @OGUID+14), +(@AQWarAllianceBandagesT5, @OGUID+15), +(@AQWarAllianceBandagesT5, @OGUID+16), +(@AQWarAllianceBandagesT5, @OGUID+17), +(@AQWarAllianceBandagesT5, @OGUID+18), +(@AQWarAllianceBandagesT5, @OGUID+72), +(@AQWarAllianceBandagesT5, @OGUID+73), +(@AQWarAllianceBandagesT5, @OGUID+74), +(@AQWarAllianceBandagesT5, @OGUID+75), +(@AQWarAllianceBandagesT5, @OGUID+76), +(@AQWarAllianceBandagesT5, @OGUID+77), +(@AQWarAllianceBandagesT5, @OGUID+78), +(@AQWarAllianceBandagesT5, @OGUID+79), +(@AQWarAllianceBandagesT5, @OGUID+80), +(@AQWarAllianceBandagesT5, @OGUID+81), +(@AQWarAllianceCookedGoodsInitial, @OGUID+25), +(@AQWarAllianceCookedGoodsT1, @OGUID+25), +(@AQWarAllianceCookedGoodsT1, @OGUID+26), +(@AQWarAllianceCookedGoodsT2, @OGUID+25), +(@AQWarAllianceCookedGoodsT2, @OGUID+26), +(@AQWarAllianceCookedGoodsT2, @OGUID+27), +(@AQWarAllianceCookedGoodsT3, @OGUID+25), +(@AQWarAllianceCookedGoodsT3, @OGUID+26), +(@AQWarAllianceCookedGoodsT3, @OGUID+27), +(@AQWarAllianceCookedGoodsT3, @OGUID+28), +(@AQWarAllianceCookedGoodsT4, @OGUID+25), +(@AQWarAllianceCookedGoodsT4, @OGUID+26), +(@AQWarAllianceCookedGoodsT4, @OGUID+27), +(@AQWarAllianceCookedGoodsT4, @OGUID+28), +(@AQWarAllianceCookedGoodsT4, @OGUID+29), +(@AQWarAllianceCookedGoodsT5, @OGUID+25), +(@AQWarAllianceCookedGoodsT5, @OGUID+26), +(@AQWarAllianceCookedGoodsT5, @OGUID+27), +(@AQWarAllianceCookedGoodsT5, @OGUID+28), +(@AQWarAllianceCookedGoodsT5, @OGUID+29), +(@AQWarAllianceCookedGoodsT5, @OGUID+30), +(@AQWarHordeBarsInitial, @OGUID+48), +(@AQWarHordeBarsT1, @OGUID+48), +(@AQWarHordeBarsT1, @OGUID+49), +(@AQWarHordeBarsT2, @OGUID+48), +(@AQWarHordeBarsT2, @OGUID+49), +(@AQWarHordeBarsT2, @OGUID+50), +(@AQWarHordeBarsT3, @OGUID+48), +(@AQWarHordeBarsT3, @OGUID+49), +(@AQWarHordeBarsT3, @OGUID+50), +(@AQWarHordeBarsT3, @OGUID+51), +(@AQWarHordeBarsT4, @OGUID+48), +(@AQWarHordeBarsT4, @OGUID+49), +(@AQWarHordeBarsT4, @OGUID+50), +(@AQWarHordeBarsT4, @OGUID+51), +(@AQWarHordeBarsT4, @OGUID+52), +(@AQWarHordeBarsT5, @OGUID+48), +(@AQWarHordeBarsT5, @OGUID+49), +(@AQWarHordeBarsT5, @OGUID+50), +(@AQWarHordeBarsT5, @OGUID+51), +(@AQWarHordeBarsT5, @OGUID+52), +(@AQWarHordeBarsT5, @OGUID+53), +(@AQWarHordeHerbsInitial, @OGUID+60), +(@AQWarHordeHerbsT1, @OGUID+60), +(@AQWarHordeHerbsT1, @OGUID+61), +(@AQWarHordeHerbsT2, @OGUID+60), +(@AQWarHordeHerbsT2, @OGUID+61), +(@AQWarHordeHerbsT2, @OGUID+62), +(@AQWarHordeHerbsT3, @OGUID+60), +(@AQWarHordeHerbsT3, @OGUID+61), +(@AQWarHordeHerbsT3, @OGUID+62), +(@AQWarHordeHerbsT3, @OGUID+63), +(@AQWarHordeHerbsT4, @OGUID+60), +(@AQWarHordeHerbsT4, @OGUID+61), +(@AQWarHordeHerbsT4, @OGUID+62), +(@AQWarHordeHerbsT4, @OGUID+63), +(@AQWarHordeHerbsT4, @OGUID+64), +(@AQWarHordeHerbsT5, @OGUID+60), +(@AQWarHordeHerbsT5, @OGUID+61), +(@AQWarHordeHerbsT5, @OGUID+62), +(@AQWarHordeHerbsT5, @OGUID+63), +(@AQWarHordeHerbsT5, @OGUID+64), +(@AQWarHordeHerbsT5, @OGUID+65), +(@AQWarHordeSkinsInitial, @OGUID+66), +(@AQWarHordeSkinsT1, @OGUID+66), +(@AQWarHordeSkinsT1, @OGUID+67), +(@AQWarHordeSkinsT2, @OGUID+66), +(@AQWarHordeSkinsT2, @OGUID+67), +(@AQWarHordeSkinsT2, @OGUID+68), +(@AQWarHordeSkinsT3, @OGUID+66), +(@AQWarHordeSkinsT3, @OGUID+67), +(@AQWarHordeSkinsT3, @OGUID+68), +(@AQWarHordeSkinsT3, @OGUID+69), +(@AQWarHordeSkinsT4, @OGUID+66), +(@AQWarHordeSkinsT4, @OGUID+67), +(@AQWarHordeSkinsT4, @OGUID+68), +(@AQWarHordeSkinsT4, @OGUID+69), +(@AQWarHordeSkinsT4, @OGUID+70), +(@AQWarHordeSkinsT5, @OGUID+66), +(@AQWarHordeSkinsT5, @OGUID+67), +(@AQWarHordeSkinsT5, @OGUID+68), +(@AQWarHordeSkinsT5, @OGUID+69), +(@AQWarHordeSkinsT5, @OGUID+70), +(@AQWarHordeSkinsT5, @OGUID+71), +(@AQWarHordeBandagesInitial, @OGUID+42), +(@AQWarHordeBandagesT1, @OGUID+42), +(@AQWarHordeBandagesT1, @OGUID+43), +(@AQWarHordeBandagesT2, @OGUID+42), +(@AQWarHordeBandagesT2, @OGUID+43), +(@AQWarHordeBandagesT2, @OGUID+44), +(@AQWarHordeBandagesT3, @OGUID+42), +(@AQWarHordeBandagesT3, @OGUID+43), +(@AQWarHordeBandagesT3, @OGUID+44), +(@AQWarHordeBandagesT3, @OGUID+45), +(@AQWarHordeBandagesT4, @OGUID+42), +(@AQWarHordeBandagesT4, @OGUID+43), +(@AQWarHordeBandagesT4, @OGUID+44), +(@AQWarHordeBandagesT4, @OGUID+45), +(@AQWarHordeBandagesT4, @OGUID+46), +(@AQWarHordeBandagesT5, @OGUID+42), +(@AQWarHordeBandagesT5, @OGUID+43), +(@AQWarHordeBandagesT5, @OGUID+44), +(@AQWarHordeBandagesT5, @OGUID+45), +(@AQWarHordeBandagesT5, @OGUID+46), +(@AQWarHordeBandagesT5, @OGUID+47), +(@AQWarHordeCookedGoodsInitial, @OGUID+54), +(@AQWarHordeCookedGoodsT1, @OGUID+54), +(@AQWarHordeCookedGoodsT1, @OGUID+55), +(@AQWarHordeCookedGoodsT2, @OGUID+54), +(@AQWarHordeCookedGoodsT2, @OGUID+55), +(@AQWarHordeCookedGoodsT2, @OGUID+56), +(@AQWarHordeCookedGoodsT3, @OGUID+54), +(@AQWarHordeCookedGoodsT3, @OGUID+55), +(@AQWarHordeCookedGoodsT3, @OGUID+56), +(@AQWarHordeCookedGoodsT3, @OGUID+57), +(@AQWarHordeCookedGoodsT4, @OGUID+54), +(@AQWarHordeCookedGoodsT4, @OGUID+55), +(@AQWarHordeCookedGoodsT4, @OGUID+56), +(@AQWarHordeCookedGoodsT4, @OGUID+57), +(@AQWarHordeCookedGoodsT4, @OGUID+58), +(@AQWarHordeCookedGoodsT5, @OGUID+54), +(@AQWarHordeCookedGoodsT5, @OGUID+55), +(@AQWarHordeCookedGoodsT5, @OGUID+56), +(@AQWarHordeCookedGoodsT5, @OGUID+57), +(@AQWarHordeCookedGoodsT5, @OGUID+58), +(@AQWarHordeCookedGoodsT5, @OGUID+59); diff --git a/data/sql/updates/pending_db_world/gobject-spawns.sql b/data/sql/updates/pending_db_world/gobject-spawns.sql new file mode 100644 index 000000000..8b2082ea4 --- /dev/null +++ b/data/sql/updates/pending_db_world/gobject-spawns.sql @@ -0,0 +1,102 @@ +SET @GUID = 3639; +-- Note: Some of these are CO2s, especially since there's some weird destroy/recreate thing going on on official, but I just noted them as CO1s for the time being. +DELETE FROM `gameobject` WHERE `id` IN (180598, 180674, 180675, 180676, 180677, 180678, 180679, 180680, 180681, 180692, 180693, 180694, 180695, 180696, 180714, 180780, 180781, 180782, 180783, 180784, 180800, 180801, 180802, 180803, 180804, 180805, 180806, 180807, 180808, 180809, 180812, 180813, 180814, 180815, 180816, 180817, 180818, 180819, 180820, 180821, 180822, 180823, 180826, 180827, 180828, 180829, 180830, 180831, 180832, 180833, 180834, 180835, 180836, 180837, 180838, 180839, 180840, 180841, 180842, 180843) AND `guid` BETWEEN @GUID AND @GUID+81; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES +-- Ironforge +-- Bandages +(@GUID+0, 180598, 0, 0, 0, 1, 1, -4971.5483, -1148.5706, 501.648, 2.2863789, 0, 0, 0.90996075, 0.4146944, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+1, 180674, 0, 0, 0, 1, 1, -4968.3267, -1152.889, 501.9254, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+2, 180675, 0, 0, 0, 1, 1, -4969.2095, -1143.8433, 509.2506, 2.2863789, 0, 0, 0.90996075, 0.4146944, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+3, 180676, 0, 0, 0, 1, 1, -4983.004, -1136.2194, 501.6594, 2.3038306, 0, 0, 0.91354465, 0.40673843, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+4, 180677, 0, 0, 0, 1, 1, -4975.6016, -1147.3348, 509.2504, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+5, 180678, 0, 0, 0, 1, 1, -4974.111, -1148.3993, 510.8475, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T5 +-- CrateAllianceFirstAid01 +(@GUID+6, 180714, 0, 0, 0, 1, 1, -4972.807, -1145.8307, 501.64996, 3.6128378, 0, 0, -0.9723692, 0.23344836, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+7, 180714, 0, 0, 0, 1, 1, -4976.2925, -1158.7479, 501.64252, 0.85521054, 0, 0, 0.41469288, 0.90996146, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+8, 180714, 0, 0, 0, 1, 1, -4979.9673, -1146.8904, 501.65506, 4.2062464, 0, 0, -0.86162853, 0.5075394, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+9, 180714, 0, 0, 0, 1, 1, -4972.857, -1145.8458, 502.8929, 2.1991146, 0, 0, 0.89100647, 0.45399064, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+10, 180714, 0, 0, 0, 1, 1, -4977.4546, -1157.944, 501.64926, 3.9269955, 0, 0, -0.92387867, 0.3826855, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+11, 180714, 0, 0, 0, 1, 1, -4985.743, -1137.5488, 501.6594, 3.5430236, 0, 0, -0.9799242, 0.19937038, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+12, 180714, 0, 0, 0, 1, 1, -4979.9263, -1139.9106, 501.65945, 1.3613561, 0, 0, 0.62932014, 0.77714616, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+13, 180714, 0, 0, 0, 1, 1, -4972.919, -1145.8206, 504.1289, 1.7627825, 0, 0, 0.77162457, 0.63607824, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+14, 180714, 0, 0, 0, 1, 1, -4976.9517, -1158.2965, 502.88937, 4.153885, 0, 0, -0.8746195, 0.48481005, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+15, 180714, 0, 0, 0, 1, 1, -4972.6714, -1152.6599, 509.25027, 0.3316107, 0, 0, 0.16504669, 0.98628575, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+16, 180714, 0, 0, 0, 1, 1, -4968.471, -1149.9625, 501.9254, 5.0265493, 0, 0, -0.58778477, 0.80901736, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+17, 180714, 0, 0, 0, 1, 1, -4979.914, -1139.9069, 502.9025, 1.4835281, 0, 0, 0.67558956, 0.7372779, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+18, 180714, 0, 0, 0, 1, 1, -4985.936, -1135.9319, 501.6594, 3.1590624, 0, 0, -0.99996185, 0.008734641, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+72, 180714, 0, 0, 0, 1, 1, -4972.6826, -1136.9497, 509.77707, 4.3807764, 0, 0, -0.8141155, 0.58070296, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+73, 180714, 0, 0, 0, 1, 1, -4979.8037, -1146.875, 502.89078, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+74, 180714, 0, 0, 0, 1, 1, -4971.91, -1153.9872, 509.25027, 5.2359877, 0, 0, -0.5, 0.8660254, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+75, 180714, 0, 0, 0, 1, 1, -4978.415, -1159.3356, 501.64444, 3.0368383, 0, 0, 0.9986286, 0.052353222, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+76, 180714, 0, 0, 0, 1, 1, -4974.837, -1156.8785, 503.5236, 6.003934, 0, 0, -0.13917255, 0.9902682, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+77, 180714, 0, 0, 0, 1, 1, -4986.0234, -1136.7771, 502.90247, 3.1940022, 0, 0, -0.9996567, 0.026201647, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+78, 180714, 0, 0, 0, 1, 1, -4979.7725, -1139.9098, 504.1386, 5.98648, 0, 0, -0.14780903, 0.98901594, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+79, 180714, 0, 0, 0, 1, 1, -4968.3887, -1150.027, 503.16846, 0.36651757, 0, 0, 0.18223476, 0.983255, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+80, 180714, 0, 0, 0, 1, 1, -4972.4443, -1153.132, 510.49332, 5.2534423, 0, 0, -0.49242306, 0.87035596, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+81, 180714, 0, 0, 0, 1, 1, -4984.3228, -1135.7563, 504.87466, 3.6302915, 0, 0, -0.97029495, 0.241925, 300, 0, 1, '', 61582, NULL), -- T5 +-- Bars +(@GUID+19, 180680, 0, 0, 0, 1, 1, -4913.854, -1225.9967, 501.6508, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+20, 180780, 0, 0, 0, 1, 1, -4913.729, -1225.9507, 501.6506, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+21, 180781, 0, 0, 0, 1, 1, -4913.737, -1225.9277, 501.65067, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+22, 180782, 0, 0, 0, 1, 1, -4913.723, -1225.9167, 501.65067, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+23, 180783, 0, 0, 0, 1, 1, -4913.71, -1225.9053, 501.65067, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+24, 180784, 0, 0, 0, 1, 1, -4913.7773, -1225.8594, 501.65082, 2.2863789, 0, 0, 0.90996075, 0.4146944, 300, 0, 1, '', 61582, NULL), -- T5 +-- Cooking +(@GUID+25, 180679, 0, 0, 0, 1, 1, -4937.2886, -1282.7358, 501.67215, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- Cooking/Herbs Initial +(@GUID+26, 180800, 0, 0, 0, 1, 1, -4937.282, -1282.8739, 501.67227, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+27, 180806, 0, 0, 0, 1, 1, -4937.136, -1282.895, 501.6721, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+28, 180807, 0, 0, 0, 1, 1, -4937.2856, -1282.869, 501.67227, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+29, 180808, 0, 0, 0, 1, 1, -4937.336, -1282.7858, 501.67227, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+30, 180809, 0, 0, 0, 1, 1, -4937.2197, -1282.8075, 501.67215, 2.2863789, 0, 0, 0.90996075, 0.4146944, 300, 0, 1, '', 61582, NULL), -- T5 +-- Herbs +(@GUID+31, 180801, 0, 0, 0, 1, 1, -4935.5796, -1284.82, 501.67105, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+32, 180802, 0, 0, 0, 1, 1, -4935.6045, -1284.8381, 501.6711, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+33, 180803, 0, 0, 0, 1, 1, -4935.594, -1284.833, 501.6711, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+34, 180804, 0, 0, 0, 1, 1, -4935.621, -1284.8282, 501.6711, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+35, 180805, 0, 0, 0, 1, 1, -4935.5576, -1284.8864, 501.67105, 2.2340178, 0, 0, 0.8987932, 0.43837282, 300, 0, 1, '', 61582, NULL), -- T5 +-- Skins +(@GUID+36, 180681, 0, 0, 0, 1, 1, -4958.5093, -1179.3196, 501.65945, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+37, 180692, 0, 0, 0, 1, 1, -4958.517, -1179.3344, 501.65945, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+38, 180693, 0, 0, 0, 1, 1, -4958.528, -1179.335, 501.65945, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+39, 180694, 0, 0, 0, 1, 1, -4958.526, -1179.3273, 501.65945, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+40, 180695, 0, 0, 0, 1, 1, -4958.5156, -1179.3286, 501.65945, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+41, 180696, 0, 0, 0, 1, 1, -4958.5293, -1179.3357, 501.65945, 2.2863789, 0, 0, 0.90996075, 0.4146944, 300, 0, 1, '', 61582, NULL), -- T5 +-- Orgrimmar +-- Bandages +(@GUID+42, 180826, 1, 0, 0, 1, 1, 1579.3531, -4109.2544, 34.541737, 3.7524624, 0, 0, -0.9537163, 0.3007079, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+43, 180827, 1, 0, 0, 1, 1, 1579.3342, -4109.2476, 34.54871, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+44, 180828, 1, 0, 0, 1, 1, 1579.321, -4109.278, 34.551514, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+45, 180829, 1, 0, 0, 1, 1, 1579.333, -4109.2837, 34.547028, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+46, 180830, 1, 0, 0, 1, 1, 1579.3325, -4109.2783, 34.547504, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+47, 180831, 1, 0, 0, 1, 1, 1579.331, -4109.2827, 34.54776, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T5 +-- Bars +(@GUID+48, 180838, 1, 0, 0, 1, 1, 1683.1149, -4134.354, 39.541912, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+49, 180839, 1, 0, 0, 1, 1, 1683.0984, -4134.31, 39.539, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+50, 180840, 1, 0, 0, 1, 1, 1683.097, -4134.3, 39.538742, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+51, 180841, 1, 0, 0, 1, 1, 1683.1057, -4134.3135, 39.54028, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+52, 180842, 1, 0, 0, 1, 1, 1683.0347, -4134.3135, 39.52796, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+53, 180843, 1, 0, 0, 1, 1, 1683.1418, -4134.3403, 39.54657, 3.7524624, 0, 0, -0.9537163, 0.3007079, 300, 0, 1, '', 61582, NULL), -- T5 +-- Cooking +(@GUID+54, 180832, 1, 0, 0, 1, 1, 1619.8307, -4092.4302, 34.51068, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+55, 180833, 1, 0, 0, 1, 1, 1619.8004, -4092.5334, 34.488815, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+56, 180834, 1, 0, 0, 1, 1, 1619.8002, -4092.5317, 34.489204, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+57, 180835, 1, 0, 0, 1, 1, 1619.8073, -4092.5269, 34.490135, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+58, 180836, 1, 0, 0, 1, 1, 1619.8062, -4092.5305, 34.48937, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+59, 180837, 1, 0, 0, 1, 1, 1619.8094, -4092.5217, 34.491196, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T5 +-- Herbs +(@GUID+60, 180818, 1, 0, 0, 1, 1, 1637.1053, -4147.2134, 36.04144, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+61, 180819, 1, 0, 0, 1, 1, 1637.1001, -4147.2534, 36.053123, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+62, 180820, 1, 0, 0, 1, 1, 1637.111, -4147.2534, 36.05357, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+63, 180821, 1, 0, 0, 1, 1, 1637.1099, -4147.2573, 36.054718, 3.7524624, 0, 0, -0.9537163, 0.3007079, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+64, 180822, 1, 0, 0, 1, 1, 1637.079, -4147.228, 36.04483, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+65, 180823, 1, 0, 0, 1, 1, 1637.1013, -4147.226, 36.045063, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- T5 +-- Skins +(@GUID+66, 180812, 1, 0, 0, 1, 1, 1590.8248, -4155.328, 36.292576, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+67, 180813, 1, 0, 0, 1, 1, 1590.8755, -4155.335, 36.298023, 3.6826503, 0, 0, -0.9636297, 0.267241, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+68, 180814, 1, 0, 0, 1, 1, 1590.8511, -4155.342, 36.299625, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+69, 180815, 1, 0, 0, 1, 1, 1590.8533, -4155.339, 36.299156, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+70, 180816, 1, 0, 0, 1, 1, 1590.8516, -4155.341, 36.299488, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+71, 180817, 1, 0, 0, 1, 1, 1590.8517, -4155.3438, 36.299927, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL); -- T5 + +-- Old spawns +DELETE FROM `gameobject` WHERE `guid` IN (29294, 29299, 29300, 29301) AND `id` IN (180598, 180679, 180680, 180681); From efd7a006306ba8da1da822022708fd08926bc1c9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 23 Aug 2025 05:12:05 +0000 Subject: [PATCH 37/57] chore(DB): import pending files Referenced commit(s): fc90e30e5016d4bf705b4aa49c8be7c4e1e27035 --- .../creature-spawns.sql => db_world/2025_08_23_00.sql} | 1 + .../game-events.sql => db_world/2025_08_23_01.sql} | 1 + .../gobject-spawns.sql => db_world/2025_08_23_02.sql} | 1 + 3 files changed, 3 insertions(+) rename data/sql/updates/{pending_db_world/creature-spawns.sql => db_world/2025_08_23_00.sql} (99%) rename data/sql/updates/{pending_db_world/game-events.sql => db_world/2025_08_23_01.sql} (99%) rename data/sql/updates/{pending_db_world/gobject-spawns.sql => db_world/2025_08_23_02.sql} (99%) diff --git a/data/sql/updates/pending_db_world/creature-spawns.sql b/data/sql/updates/db_world/2025_08_23_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/creature-spawns.sql rename to data/sql/updates/db_world/2025_08_23_00.sql index 23346778e..064b7cb64 100644 --- a/data/sql/updates/pending_db_world/creature-spawns.sql +++ b/data/sql/updates/db_world/2025_08_23_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_19_00 -> 2025_08_23_00 SET @GUID = 83113; DELETE FROM `creature` WHERE `id1` IN (3296, 5595, 15383, 15431, 15432, 15434, 15437, 15445, 15446, 15448, 15450, 15451, 15452, 15453, 15455, 15456, 15457, 15458, 15459, 15460, 15469, 15477, 15508, 15512, 15515, 15522, 15525, 15528, 15529, 15532, 15533, 15534, 15535, 15539, 15663, 15696, 15700, 15701, 15702, 15703, 15704, 15707, 15708, 15709, 15731, 15733, 15734, 15735, 15736, 15737, 15738, 15739, 15761, 15762, 15763, 15764, 15765, 15766, 15767, 15768) AND `guid` BETWEEN @GUID AND @GUID+69; diff --git a/data/sql/updates/pending_db_world/game-events.sql b/data/sql/updates/db_world/2025_08_23_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/game-events.sql rename to data/sql/updates/db_world/2025_08_23_01.sql index 17b1fb939..d63bf23ff 100644 --- a/data/sql/updates/pending_db_world/game-events.sql +++ b/data/sql/updates/db_world/2025_08_23_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_23_00 -> 2025_08_23_01 SET @EventID = 131, @OGUID = 3639, @CGUID = 83113; diff --git a/data/sql/updates/pending_db_world/gobject-spawns.sql b/data/sql/updates/db_world/2025_08_23_02.sql similarity index 99% rename from data/sql/updates/pending_db_world/gobject-spawns.sql rename to data/sql/updates/db_world/2025_08_23_02.sql index 8b2082ea4..acc01795c 100644 --- a/data/sql/updates/pending_db_world/gobject-spawns.sql +++ b/data/sql/updates/db_world/2025_08_23_02.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_23_01 -> 2025_08_23_02 SET @GUID = 3639; -- Note: Some of these are CO2s, especially since there's some weird destroy/recreate thing going on on official, but I just noted them as CO1s for the time being. DELETE FROM `gameobject` WHERE `id` IN (180598, 180674, 180675, 180676, 180677, 180678, 180679, 180680, 180681, 180692, 180693, 180694, 180695, 180696, 180714, 180780, 180781, 180782, 180783, 180784, 180800, 180801, 180802, 180803, 180804, 180805, 180806, 180807, 180808, 180809, 180812, 180813, 180814, 180815, 180816, 180817, 180818, 180819, 180820, 180821, 180822, 180823, 180826, 180827, 180828, 180829, 180830, 180831, 180832, 180833, 180834, 180835, 180836, 180837, 180838, 180839, 180840, 180841, 180842, 180843) AND `guid` BETWEEN @GUID AND @GUID+81; From 3bdcd83f4a2e4d9c1db34b7d9497e1c9120fc28b Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 23 Aug 2025 04:39:32 -0300 Subject: [PATCH 38/57] fix(Scripts/Spells): Fix Death and Decay interrupting spellcasting (#22720) --- src/server/scripts/Spells/spell_dk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index d1d371710..b2d312a5a 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -345,7 +345,7 @@ class spell_dk_death_and_decay_aura : public AuraScript if (GetCaster() && GetTarget()) { int32 basePoints0 = aurEff->GetAmount(); - GetCaster()->CastCustomSpell(GetTarget(), SPELL_DK_DEATH_AND_DECAY_TRIGGER, &basePoints0, nullptr, nullptr, false, 0, aurEff); + GetCaster()->CastCustomSpell(GetTarget(), SPELL_DK_DEATH_AND_DECAY_TRIGGER, &basePoints0, nullptr, nullptr, true, 0, aurEff); } } From 2a73b89f6a2446b1225c79c29d8834621e161977 Mon Sep 17 00:00:00 2001 From: sudlud Date: Sat, 23 Aug 2025 21:05:17 +0200 Subject: [PATCH 39/57] fix(CI/modules-build): disable archived / outdated module mod-war-effort (#22722) --- apps/ci/ci-install-modules.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/ci/ci-install-modules.sh b/apps/ci/ci-install-modules.sh index d584682ab..5987eaf7a 100755 --- a/apps/ci/ci-install-modules.sh +++ b/apps/ci/ci-install-modules.sh @@ -100,7 +100,8 @@ git clone --depth=1 --branch=main https://github.com/azerothcore/mod-system-vi git clone --depth=1 --branch=master https://github.com/azerothcore/mod-tic-tac-toe modules/mod-tic-tac-toe git clone --depth=1 --branch=master https://github.com/azerothcore/mod-top-arena modules/mod-top-arena git clone --depth=1 --branch=master https://github.com/azerothcore/mod-transmog modules/mod-transmog -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-war-effort modules/mod-war-effort +# archived / outdated +#git clone --depth=1 --branch=master https://github.com/azerothcore/mod-war-effort modules/mod-war-effort git clone --depth=1 --branch=master https://github.com/azerothcore/mod-weekend-xp modules/mod-weekend-xp git clone --depth=1 --branch=master https://github.com/azerothcore/mod-who-logged modules/mod-who-logged git clone --depth=1 --branch=master https://github.com/azerothcore/mod-zone-difficulty modules/mod-zone-difficulty From a1eb3e5cec4a52811979411b63179946089b36ad Mon Sep 17 00:00:00 2001 From: sudlud Date: Sun, 24 Aug 2025 07:40:37 +0200 Subject: [PATCH 40/57] fix(DB/SAI): fix event_type of Pit Commander SAI entry (#22723) --- data/sql/updates/pending_db_world/rev_1755975503363547000.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1755975503363547000.sql diff --git a/data/sql/updates/pending_db_world/rev_1755975503363547000.sql b/data/sql/updates/pending_db_world/rev_1755975503363547000.sql new file mode 100644 index 000000000..061c27534 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1755975503363547000.sql @@ -0,0 +1,2 @@ +-- +UPDATE `smart_scripts` SET `event_type` = 61 WHERE `entryorguid` = 18945 AND `source_type` = 0 AND `id` = 4; From 915b39202a7c602546947b4b8ab70f5d42ce34b5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 24 Aug 2025 05:41:39 +0000 Subject: [PATCH 41/57] chore(DB): import pending files Referenced commit(s): a1eb3e5cec4a52811979411b63179946089b36ad --- .../rev_1755975503363547000.sql => db_world/2025_08_24_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1755975503363547000.sql => db_world/2025_08_24_00.sql} (71%) diff --git a/data/sql/updates/pending_db_world/rev_1755975503363547000.sql b/data/sql/updates/db_world/2025_08_24_00.sql similarity index 71% rename from data/sql/updates/pending_db_world/rev_1755975503363547000.sql rename to data/sql/updates/db_world/2025_08_24_00.sql index 061c27534..0f3d678d9 100644 --- a/data/sql/updates/pending_db_world/rev_1755975503363547000.sql +++ b/data/sql/updates/db_world/2025_08_24_00.sql @@ -1,2 +1,3 @@ +-- DB update 2025_08_23_02 -> 2025_08_24_00 -- UPDATE `smart_scripts` SET `event_type` = 61 WHERE `entryorguid` = 18945 AND `source_type` = 0 AND `id` = 4; From 9ed31bd63e56cbc6a4d82a491bd08576d108a73c Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Sun, 24 Aug 2025 08:50:16 -0400 Subject: [PATCH 42/57] refactor(Core/Packets): Rewrite various query packets to modern class. (#22719) --- src/server/game/Handlers/QueryHandler.cpp | 59 ++++++------- src/server/game/Handlers/TicketHandler.cpp | 2 +- src/server/game/Server/Packets/AllPackets.h | 1 + .../game/Server/Packets/QueryPackets.cpp | 58 +++++++++++++ src/server/game/Server/Packets/QueryPackets.h | 87 +++++++++++++++++++ src/server/game/Server/Protocol/Opcodes.cpp | 2 +- src/server/game/Server/WorldSession.h | 15 +++- 7 files changed, 184 insertions(+), 40 deletions(-) create mode 100644 src/server/game/Server/Packets/QueryPackets.cpp create mode 100644 src/server/game/Server/Packets/QueryPackets.h diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 0666af71c..604977301 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -24,6 +24,7 @@ #include "Opcodes.h" #include "Pet.h" #include "Player.h" +#include "QueryPackets.h" #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" @@ -32,62 +33,55 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid) { CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid); - WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 1 + 1 + 1 + 1 + 10)); - data << guid.WriteAsPacked(); + WorldPackets::Query::NameQueryResponse nameQueryResponse; + nameQueryResponse.Guid = guid.WriteAsPacked(); if (!playerData) { - data << uint8(1); // name unknown - SendPacket(&data); + nameQueryResponse.NameUnknown = true; + SendPacket(nameQueryResponse.Write()); return; } Player* player = ObjectAccessor::FindConnectedPlayer(guid); - data << uint8(0); // name known - data << playerData->Name; // played name - data << uint8(0); // realm name - only set for cross realm interaction (such as Battlegrounds) - data << uint8(player ? player->getRace() : playerData->Race); - data << uint8(playerData->Sex); - data << uint8(playerData->Class); + nameQueryResponse.NameUnknown = false; + nameQueryResponse.Name = playerData->Name; + nameQueryResponse.Race = player ? player->getRace() : playerData->Race; + nameQueryResponse.Sex = player ? player->getGender() : playerData->Sex; + nameQueryResponse.Class = player ? player->getClass() : playerData->Class; - // pussywizard: optimization - /*Player* player = ObjectAccessor::FindConnectedPlayer(guid); if (DeclinedName const* names = (player ? player->GetDeclinedNames() : nullptr)) { - data << uint8(1); // Name is declined - for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) - data << names->name[i]; + nameQueryResponse.Declined = true; + nameQueryResponse.DeclinedNames = *names; } - else*/ - data << uint8(0); // Name is not declined + else + nameQueryResponse.Declined = false; - SendPacket(&data); + SendPacket(nameQueryResponse.Write()); } -void WorldSession::HandleNameQueryOpcode(WorldPacket& recvData) +void WorldSession::HandleNameQueryOpcode(WorldPackets::Query::NameQuery& packet) { - ObjectGuid guid; - recvData >> guid; - // This is disable by default to prevent lots of console spam // LOG_INFO("network.opcode", "HandleNameQueryOpcode {}", guid); - SendNameQueryOpcode(guid); + SendNameQueryOpcode(packet.Guid); } -void WorldSession::HandleQueryTimeOpcode(WorldPacket& /*recvData*/) +void WorldSession::HandleTimeQueryOpcode(WorldPackets::Query::TimeQuery& /*packet*/) { - SendQueryTimeResponse(); + SendTimeQueryResponse(); } -void WorldSession::SendQueryTimeResponse() +void WorldSession::SendTimeQueryResponse() { auto timeResponse = sWorld->GetNextDailyQuestsResetTime() - GameTime::GetGameTime(); - WorldPacket data(SMSG_QUERY_TIME_RESPONSE, 4 + 4); - data << uint32(GameTime::GetGameTime().count()); - data << uint32(timeResponse.count()); - SendPacket(&data); + WorldPackets::Query::TimeQueryResponse timeQueryResponse; + timeQueryResponse.ServerTime = GameTime::GetGameTime().count(); + timeQueryResponse.TimeResponse = timeResponse.count(); + SendPacket(timeQueryResponse.Write()); } /// Only _static_ data is sent in this packet !!! @@ -402,13 +396,10 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket& recvData) } } -void WorldSession::HandleCorpseMapPositionQuery(WorldPacket& recvData) +void WorldSession::HandleCorpseMapPositionQuery(WorldPackets::Query::CorpseMapPositionQuery& /*packet*/) { LOG_DEBUG("network", "WORLD: Recv CMSG_CORPSE_MAP_POSITION_QUERY"); - uint32 unk; - recvData >> unk; - WorldPacket data(SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, 4 + 4 + 4 + 4); data << float(0); data << float(0); diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp index eb6243b21..089546aa5 100644 --- a/src/server/game/Handlers/TicketHandler.cpp +++ b/src/server/game/Handlers/TicketHandler.cpp @@ -172,7 +172,7 @@ void WorldSession::HandleGMTicketDeleteOpcode(WorldPacket& /*recv_data*/) void WorldSession::HandleGMTicketGetTicketOpcode(WorldPacket& /*recv_data*/) { - SendQueryTimeResponse(); + SendTimeQueryResponse(); if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID())) { diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index 1e3457e1d..30aecbb6f 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -27,6 +27,7 @@ #include "LFGPackets.h" #include "MiscPackets.h" #include "PetPackets.h" +#include "QueryPackets.h" #include "TotemPackets.h" #include "WorldStatePackets.h" diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp new file mode 100644 index 000000000..6efa96275 --- /dev/null +++ b/src/server/game/Server/Packets/QueryPackets.cpp @@ -0,0 +1,58 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "QueryPackets.h" + +void WorldPackets::Query::NameQuery::Read() +{ + _worldPacket >> Guid; +} + +WorldPacket const* WorldPackets::Query::NameQueryResponse::Write() +{ + _worldPacket << Guid; + _worldPacket << NameUnknown; + if (NameUnknown) + return &_worldPacket; + + _worldPacket << Name; + _worldPacket << RealmName; + _worldPacket << Race; + _worldPacket << Sex; + _worldPacket << Class; + _worldPacket << Declined; + if (Declined) + { + for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + _worldPacket << DeclinedNames.name[i]; + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Query::TimeQueryResponse::Write() +{ + _worldPacket << ServerTime; + _worldPacket << TimeResponse; + + return &_worldPacket; +} + +void WorldPackets::Query::CorpseMapPositionQuery::Read() +{ + _worldPacket >> unk; +} diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h new file mode 100644 index 000000000..85d7a76ce --- /dev/null +++ b/src/server/game/Server/Packets/QueryPackets.h @@ -0,0 +1,87 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef QueryPackets_h__ +#define QueryPackets_h__ + +#include "Packet.h" +#include "Unit.h" + +namespace WorldPackets +{ + namespace Query + { + class NameQuery final : public ClientPacket + { + public: + NameQuery(WorldPacket&& packet) : ClientPacket(CMSG_NAME_QUERY, std::move(packet)) {} + + void Read() override; + + ObjectGuid Guid; + }; + + class NameQueryResponse final : public ServerPacket + { + public: + NameQueryResponse() : ServerPacket(SMSG_NAME_QUERY_RESPONSE, 8 + 1 + 1 + 1 + 1 + 1 + 10) {} + + WorldPacket const* Write() override; + + PackedGuid Guid; + uint8 NameUnknown = false; + std::string_view Name; + std::string_view RealmName = ""; // Only set for cross realm interaction (such as Battlegrounds) + uint8 Race = RACE_NONE; + uint8 Sex = GENDER_MALE; + uint8 Class = CLASS_NONE; + uint8 Declined = false; + DeclinedName DeclinedNames; + }; + + class TimeQuery final : public ClientPacket + { + public: + TimeQuery(WorldPacket&& packet) : ClientPacket(CMSG_QUERY_TIME, std::move(packet)) {} + + void Read() override {}; + }; + + class TimeQueryResponse final : public ServerPacket + { + public: + TimeQueryResponse() : ServerPacket(SMSG_QUERY_TIME_RESPONSE, 4 + 4) {} + + WorldPacket const* Write() override; + + uint32 ServerTime; + uint32 TimeResponse; + }; + + class CorpseMapPositionQuery final : public ClientPacket + { + public: + CorpseMapPositionQuery(WorldPacket&& packet) : ClientPacket(CMSG_CORPSE_MAP_POSITION_QUERY, std::move(packet)) {} + + void Read() override; + + uint32 unk; + }; + } +} + +#endif // QueryPackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 85bcb4186..bc12f7764 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -590,7 +590,7 @@ void OpcodeTable::Initialize() /*0x1CB*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFICATION, STATUS_NEVER); /*0x1CC*/ DEFINE_HANDLER(CMSG_PLAYED_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePlayedTime ); /*0x1CD*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_NEVER); - /*0x1CE*/ DEFINE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleQueryTimeOpcode ); + /*0x1CE*/ DEFINE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTimeQueryOpcode ); /*0x1CF*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_NEVER); /*0x1D0*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOG_XPGAIN, STATUS_NEVER); /*0x1D1*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURACASTLOG, STATUS_NEVER); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 9e570f9b0..032e18abf 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -160,6 +160,13 @@ namespace WorldPackets class PetSpellAutocast; class RequestPetInfo; } + + namespace Query + { + class NameQuery; + class TimeQuery; + class CorpseMapPositionQuery; + } } enum AccountDataType @@ -371,7 +378,7 @@ public: } void SendSetPhaseShift(uint32 phaseShift); - void SendQueryTimeResponse(); + void SendTimeQueryResponse(); void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos = 0); void SendClientCacheVersion(uint32 version); @@ -661,9 +668,9 @@ public: // opcodes handlers void HandleGameObjectUseOpcode(WorldPacket& recPacket); void HandleGameobjectReportUse(WorldPacket& recvPacket); - void HandleNameQueryOpcode(WorldPacket& recvPacket); + void HandleNameQueryOpcode(WorldPackets::Query::NameQuery& packet); - void HandleQueryTimeOpcode(WorldPacket& recvPacket); + void HandleTimeQueryOpcode(WorldPackets::Query::TimeQuery& packet); void HandleCreatureQueryOpcode(WorldPacket& recvPacket); @@ -863,7 +870,7 @@ public: // opcodes handlers void HandleReclaimCorpseOpcode(WorldPacket& recvPacket); void HandleCorpseQueryOpcode(WorldPacket& recvPacket); - void HandleCorpseMapPositionQuery(WorldPacket& recvPacket); + void HandleCorpseMapPositionQuery(WorldPackets::Query::CorpseMapPositionQuery& packet); void HandleResurrectResponseOpcode(WorldPacket& recvPacket); void HandleSummonResponseOpcode(WorldPacket& recvData); From cd9bdf7a665b170463b08492ca2fe1cb97fa2574 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 25 Aug 2025 11:52:07 -0300 Subject: [PATCH 43/57] fix(DB/Conditions): Everfrost Chip should require atleast friendly Sons of Hodir standing (#22718) --- data/sql/updates/pending_db_world/rev_1755916063283631200.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1755916063283631200.sql diff --git a/data/sql/updates/pending_db_world/rev_1755916063283631200.sql b/data/sql/updates/pending_db_world/rev_1755916063283631200.sql new file mode 100644 index 000000000..3ab80be7b --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1755916063283631200.sql @@ -0,0 +1,4 @@ +-- +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 4) AND (`SourceGroup` = 193997) AND (`SourceEntry` = 44725) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 5) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 1119) AND (`ConditionValue2` = 16) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(4, 26782, 44725, 0, 0, 5, 0, 1119, 240, 0, 0, 0, 0, '', 'Everfrost Chip requires Sons of Hodir friendly'); From 8a340b1efb8bb078e05adb398703b19900c6688c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 25 Aug 2025 14:53:13 +0000 Subject: [PATCH 44/57] chore(DB): import pending files Referenced commit(s): cd9bdf7a665b170463b08492ca2fe1cb97fa2574 --- .../rev_1755916063283631200.sql => db_world/2025_08_25_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1755916063283631200.sql => db_world/2025_08_25_00.sql} (94%) diff --git a/data/sql/updates/pending_db_world/rev_1755916063283631200.sql b/data/sql/updates/db_world/2025_08_25_00.sql similarity index 94% rename from data/sql/updates/pending_db_world/rev_1755916063283631200.sql rename to data/sql/updates/db_world/2025_08_25_00.sql index 3ab80be7b..c5793e675 100644 --- a/data/sql/updates/pending_db_world/rev_1755916063283631200.sql +++ b/data/sql/updates/db_world/2025_08_25_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_24_00 -> 2025_08_25_00 -- DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 4) AND (`SourceGroup` = 193997) AND (`SourceEntry` = 44725) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 5) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 1119) AND (`ConditionValue2` = 16) AND (`ConditionValue3` = 0); INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES From 2e614069a53c3ea46856ad391e083c860a33b383 Mon Sep 17 00:00:00 2001 From: sudlud Date: Mon, 25 Aug 2025 17:32:35 +0200 Subject: [PATCH 45/57] =?UTF-8?q?fix(Entities/Creature):=20do=20not=20touc?= =?UTF-8?q?h=20setActive()=20state=20in=20setDeathSta=E2=80=A6=20(#22729)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Takenbacon --- src/server/game/Entities/Creature/Creature.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 8ef6206bb..996b5ae05 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1986,8 +1986,6 @@ void Creature::setDeathState(DeathState state, bool despawn) Dismount(); // if creature is mounted on a virtual mount, remove it at death - setActive(false); - if (HasSearchedAssistance()) { SetNoSearchAssistance(false); From ddf0997c558edcb43637d4592c54c046e4542859 Mon Sep 17 00:00:00 2001 From: sudlud Date: Mon, 25 Aug 2025 17:33:43 +0200 Subject: [PATCH 46/57] fix(DB/SAI): set dark portal event creatures active (#22724) --- .../rev_1756036806680249000.sql | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1756036806680249000.sql diff --git a/data/sql/updates/pending_db_world/rev_1756036806680249000.sql b/data/sql/updates/pending_db_world/rev_1756036806680249000.sql new file mode 100644 index 000000000..f9ff17b47 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1756036806680249000.sql @@ -0,0 +1,59 @@ +-- set dark portal creatures active +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (18944, 18946, 18948, 18949, 18950, 18965, 18966, 18969, 18970, 18971, 18972, 18986, -68744, -68745, -74081, -74082)) AND (`source_type` = 0) AND (`event_type` IN (11, 36)) AND (`id` IN (42, 43)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +-- 18944 Fel Soldier +(18944, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fel Soldier - On Respawn - Set Active On'), +(18944, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fel Soldier - On Corpse Removed - Set Active On'), +-- 18945 Pit Commander, already set active +-- 18946 Infernal Siegebreaker +(18946, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Siegebreaker - On Respawn - Set Active On'), +(18946, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Siegebreaker - On Corpse Removed - Set Active On'), +-- 18948 Stormwind Soldier +(18948, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Stormwind Soldier - On Respawn - Set Active On'), +(18948, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Stormwind Soldier - On Corpse Removed - Set Active On'), +-- 18949 Stormwind Mage +(18949, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Stormwind Mage - On Respawn - Set Active On'), +(18949, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Stormwind Mage - On Corpse Removed - Set Active On'), +-- 18950 Orgrimmar Grunt +(18950, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Orgrimmar Grunt - On Respawn - Set Active On'), +(18950, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Orgrimmar Grunt - On Corpse Removed - Set Active On'), +-- 18965 Darnassian Archer +(18965, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Archer - On Respawn - Set Active On'), +(18965, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Archer - On Corpse Removed - Set Active On'), +-- 18966 Justinius the Harbinger +(18966, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Justinius the Harbinger - On Respawn - Set Active On'), +(18966, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Justinius the Harbinger - On Corpse Removed - Set Active On'), +-- 18969 Melgromm Highmountain +(18969, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Melgromm Highmountain - On Respawn - Set Active On'), +(18969, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Melgromm Highmountain - On Corpse Removed - Set Active On'), +-- 18970 Darkspear Axe Thrower +(18970, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darkspear Axe Thrower - On Respawn - Set Active On'), +(18970, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darkspear Axe Thrower - On Corpse Removed - Set Active On'), +-- 18971 Undercity Mage +(18971, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Undercity Mage - On Respawn - Set Active On'), +(18971, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Undercity Mage - On Corpse Removed - Set Active On'), +-- 18972 Orgrimmar Shaman +(18972, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Orgrimmar Shaman - On Respawn - Set Active On'), +(18972, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Orgrimmar Shaman - On Corpse Removed - Set Active On'), +-- 18986 Ironforge Paladin +(18986, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ironforge Paladin - On Respawn - Set Active On'), +(18986, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ironforge Paladin - On Corpse Removed - Set Active On'), +-- 19005 Wrath Master, GUID SAI -68311, -68312, -68313, -68314, already set active +-- 19215 Infernal Relay (Hellfire) +(-68744, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Relay (Hellfire) - On Respawn - Set Active On'), +(-68744, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Relay (Hellfire) - On Corpse Removed - Set Active On'), +(-68745, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Relay (Hellfire) - On Respawn - Set Active On'), +(-68745, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Relay (Hellfire) - On Corpse Removed - Set Active On'), +-- 21075 Infernal Target (Hyjal) +(-74081, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Target (Hyjal) - On Respawn - Set Active On'), +(-74081, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Target (Hyjal)- On Corpse Removed - Set Active On'), +(-74082, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Target (Hyjal) - On Respawn - Set Active On'), +(-74082, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Target (Hyjal) - On Corpse Removed - Set Active On'); + +-- cleanup +-- Infernal Relay (Hellfire) used to set nearby 19005 Wrath Master active +DELETE FROM `smart_scripts` WHERE (`entryorguid` = -68744) AND (`source_type` = 0) AND (`id` IN (10)); +UPDATE `smart_scripts` SET `link` = 0 WHERE (`entryorguid` = -68744) AND (`source_type` = 0) AND (`id` IN (9)); + +-- update spawn comment for GUID SAI +UPDATE `creature` SET `Comment` = 'GUID SAI, SAI Target' WHERE (`id1` = 19215) AND (`guid` = 68745); From d22d5ae40ca48525d238807242452b7f08d73a57 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 25 Aug 2025 15:33:46 +0000 Subject: [PATCH 47/57] chore(DB): import pending files Referenced commit(s): 2e614069a53c3ea46856ad391e083c860a33b383 --- .../rev_1756036806680249000.sql => db_world/2025_08_25_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1756036806680249000.sql => db_world/2025_08_25_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1756036806680249000.sql b/data/sql/updates/db_world/2025_08_25_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1756036806680249000.sql rename to data/sql/updates/db_world/2025_08_25_01.sql index f9ff17b47..196057350 100644 --- a/data/sql/updates/pending_db_world/rev_1756036806680249000.sql +++ b/data/sql/updates/db_world/2025_08_25_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_25_00 -> 2025_08_25_01 -- set dark portal creatures active DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (18944, 18946, 18948, 18949, 18950, 18965, 18966, 18969, 18970, 18971, 18972, 18986, -68744, -68745, -74081, -74082)) AND (`source_type` = 0) AND (`event_type` IN (11, 36)) AND (`id` IN (42, 43)); INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES From f02af61358e1376823ddd15a821ec2d03815e811 Mon Sep 17 00:00:00 2001 From: sudlud Date: Mon, 25 Aug 2025 19:21:33 +0200 Subject: [PATCH 48/57] fix(DB/SAI): fix dark portal creatures calling for help on aggro (#22730) --- .../sql/updates/pending_db_world/rev_1756036806680249000.sql | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1756036806680249000.sql diff --git a/data/sql/updates/pending_db_world/rev_1756036806680249000.sql b/data/sql/updates/pending_db_world/rev_1756036806680249000.sql new file mode 100644 index 000000000..e49637c15 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1756036806680249000.sql @@ -0,0 +1,5 @@ +-- fix dark portal creatures calling for help on aggro +-- 18948 Stormwind Soldier +UPDATE `smart_scripts` SET `event_type` = 4 WHERE (`entryorguid` = 18948) AND (`source_type` = 0) AND (`id` IN (7)); +-- 18950 Orgrimmar Grunt +UPDATE `smart_scripts` SET `event_type` = 4 WHERE (`entryorguid` = 18950) AND (`source_type` = 0) AND (`id` IN (7)); From 846efc3b6407b83da1b09eee78d1d94a654b219a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 25 Aug 2025 17:22:38 +0000 Subject: [PATCH 49/57] chore(DB): import pending files Referenced commit(s): f02af61358e1376823ddd15a821ec2d03815e811 --- .../rev_1756036806680249000.sql => db_world/2025_08_25_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1756036806680249000.sql => db_world/2025_08_25_02.sql} (88%) diff --git a/data/sql/updates/pending_db_world/rev_1756036806680249000.sql b/data/sql/updates/db_world/2025_08_25_02.sql similarity index 88% rename from data/sql/updates/pending_db_world/rev_1756036806680249000.sql rename to data/sql/updates/db_world/2025_08_25_02.sql index e49637c15..47a79017c 100644 --- a/data/sql/updates/pending_db_world/rev_1756036806680249000.sql +++ b/data/sql/updates/db_world/2025_08_25_02.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_25_01 -> 2025_08_25_02 -- fix dark portal creatures calling for help on aggro -- 18948 Stormwind Soldier UPDATE `smart_scripts` SET `event_type` = 4 WHERE (`entryorguid` = 18948) AND (`source_type` = 0) AND (`id` IN (7)); From de98f424116e77b9ec802db59d4c515cc6be144f Mon Sep 17 00:00:00 2001 From: Yehonal Date: Mon, 25 Aug 2025 20:25:17 +0200 Subject: [PATCH 50/57] feat(Service Manager): add service registry custom dir and restore functionality (#22589) This pull request introduces significant enhancements to the service management system by adding a service registry with features like automatic tracking, reboot persistence, and restoration of missing services. The goal of this PR is to allow the user to store the service configuration files into an arbitrary directory, in this way they can be easily tracked, versioned, and replicated across different environments It also includes a migration script to transition from the legacy service configuration format to the new registry-based system. Below is a summary of the most important changes: ### Service Registry and Management Enhancements: 1. **Service Registry Integration**: - Added a comprehensive service registry system to track all created services, enabling features like cross-reboot persistence and restoration of missing services (`apps/startup-scripts/src/service-manager.sh`). [[1]](diffhunk://#diff-31edfed7f73d0647a5fc96ce74c249e025e884cd1fe06621cb78eb4a381464f9R41-R229) [[2]](diffhunk://#diff-31edfed7f73d0647a5fc96ce74c249e025e884cd1fe06621cb78eb4a381464f9R273) - Introduced commands for managing the registry, such as `restore` for recreating missing services and `list` for viewing registered services. [[1]](diffhunk://#diff-31edfed7f73d0647a5fc96ce74c249e025e884cd1fe06621cb78eb4a381464f9R273) [[2]](diffhunk://#diff-31edfed7f73d0647a5fc96ce74c249e025e884cd1fe06621cb78eb4a381464f9R332-R334) [[3]](diffhunk://#diff-31edfed7f73d0647a5fc96ce74c249e025e884cd1fe06621cb78eb4a381464f9R346-L172) 2. **PM2 Persistence**: - Enhanced PM2 integration to automatically configure startup persistence across reboots using `pm2 startup` and `pm2 save` after service creation. ### Migration and Compatibility: 3. **Migration Script**: - Added a `migrate-registry.sh` script to convert legacy service configurations into the new registry format. It ensures compatibility while preserving existing service information (`apps/startup-scripts/src/migrate-registry.sh`). ### Documentation Updates: 4. **Updated README**: - Expanded documentation in `README.md` to explain the new service registry features, including usage examples, custom configuration directories, and migration instructions. [[1]](diffhunk://#diff-0917b2888cc9b16539173f318b77773d08f7bf360579b68b9710a96ca2bcbb64L387-R468) [[2]](diffhunk://#diff-0917b2888cc9b16539173f318b77773d08f7bf360579b68b9710a96ca2bcbb64R613-R626) ### Configuration Improvements: 5. **Custom Configuration Directories**: - Added support for overriding the default configuration directory for service registry and files using the `AC_SERVICE_CONFIG_DIR` environment variable. [[1]](diffhunk://#diff-31edfed7f73d0647a5fc96ce74c249e025e884cd1fe06621cb78eb4a381464f9L14-R15) [[2]](diffhunk://#diff-31edfed7f73d0647a5fc96ce74c249e025e884cd1fe06621cb78eb4a381464f9R346-L172) These changes significantly improve the usability, reliability, and maintainability of the service management system, especially for setups requiring persistence and multi-project configurations. --- apps/startup-scripts/README.md | 95 ++++- apps/startup-scripts/src/migrate-registry.sh | 144 +++++++ apps/startup-scripts/src/service-manager.sh | 407 +++++++++++++++---- 3 files changed, 561 insertions(+), 85 deletions(-) create mode 100755 apps/startup-scripts/src/migrate-registry.sh diff --git a/apps/startup-scripts/README.md b/apps/startup-scripts/README.md index 7b057581d..176ec3ed6 100644 --- a/apps/startup-scripts/README.md +++ b/apps/startup-scripts/README.md @@ -312,6 +312,9 @@ Services support two restart policies: # Edit configuration ./service-manager.sh edit world + +# Restore missing services from registry +./service-manager.sh restore ``` ## 🌍 Multiple Realms Setup @@ -384,22 +387,72 @@ cp examples/restarter-world.sh restarter-realm2.sh ## 🛠️ Service Management +### Service Registry and Persistence + +The service manager includes a comprehensive registry system that tracks all created services and enables automatic restoration: + +#### Service Registry Features + +- **Automatic Tracking**: All services are automatically registered when created +- **Cross-Reboot Persistence**: PM2 services are configured with startup persistence +- **Service Restoration**: Missing services can be detected and restored from registry +- **Migration Support**: Legacy service configurations can be migrated to the new format + +#### Using the Registry + +```bash +# Check for missing services and restore them +./service-manager.sh restore + +# List all registered services (includes status) +./service-manager.sh list + +# Services are automatically added to registry on creation +./service-manager.sh create auth authserver --bin-path /path/to/bin +``` + +#### Custom Configuration Directories + +You can customize where service configurations and PM2/systemd files are stored: + +```bash +# Set custom directories +export AC_SERVICE_CONFIG_DIR="/path/to/your/project/services" + +# Now all service operations will use these custom directories +./service-manager.sh create auth authserver --bin-path /path/to/bin +``` + +This is particularly useful for: +- **Version Control**: Keep service configurations in your project repository +- **Multiple Projects**: Separate service configurations per project +- **Team Collaboration**: Share service setups across development teams + +#### Migration from Legacy Format + +If you have existing services in the old format, use the migration script: + +```bash +# Migrate existing registry to new format +./migrate-registry.sh + +# The script will: +# - Detect old format automatically +# - Create a backup of the old registry +# - Convert to new format with proper tracking +# - Preserve all existing service information +``` + ### PM2 Services When using PM2 as the service provider: -```bash -# PM2-specific commands -pm2 list # List all PM2 processes -pm2 logs auth # View logs -pm2 monit # Real-time monitoring -pm2 restart auth # Restart service -pm2 delete auth # Remove service +* [PM2 CLI Documentation](https://pm2.io/docs/runtime/reference/pm2-cli/) -# Save PM2 configuration -pm2 save -pm2 startup # Auto-start on boot -``` +**Automatic PM2 Persistence**: The service manager automatically configures PM2 for persistence across reboots by: +- Running `pm2 startup` to set up the startup script +- Running `pm2 save` after each service creation/modification +- This ensures your services automatically start when the system reboots NOTE: pm2 cannot run tmux/screen sessions, but you can always use the `attach` command to connect to the service console because pm2 supports interactive mode. @@ -407,6 +460,12 @@ NOTE: pm2 cannot run tmux/screen sessions, but you can always use the `attach` c The startup scripts recognize several environment variables for configuration and runtime behavior: +#### Configuration Directory Variables + +- **`AC_SERVICE_CONFIG_DIR`**: Override the default configuration directory for services registry and configurations + - Default: `${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services` + - Used for storing service registry and run-engine configurations + #### Service Detection Variables - **`AC_LAUNCHED_BY_PM2`**: Set to `1` when launched by PM2 (automatically set by service-manager) @@ -551,4 +610,18 @@ npm install -g pm2 sudo npm install -g pm2 ``` +#### 7. Registry Out of Sync +```bash +# If the service registry shows services that don't actually exist +``` +**Solution**: Use registry sync or restore +```bash +# Check and restore missing services (also cleans up orphaned entries) +./service-manager.sh restore + +# If you have a very old registry format, migrate it +./migrate-registry.sh +``` + + diff --git a/apps/startup-scripts/src/migrate-registry.sh b/apps/startup-scripts/src/migrate-registry.sh new file mode 100755 index 000000000..c5898794f --- /dev/null +++ b/apps/startup-scripts/src/migrate-registry.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash + +# One-time migration script for service registry +# Converts old format to new format + +set -euo pipefail # Strict error handling + +CONFIG_DIR="${AC_SERVICE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services}" +REGISTRY_FILE="$CONFIG_DIR/service_registry.json" +BACKUP_FILE="$CONFIG_DIR/service_registry.json.backup" + +# Colors +readonly YELLOW='\033[1;33m' +readonly GREEN='\033[0;32m' +readonly RED='\033[0;31m' +readonly BLUE='\033[0;34m' +readonly NC='\033[0m' + +echo -e "${BLUE}AzerothCore Service Registry Migration Tool${NC}" +echo "==============================================" + +# Check dependencies +if ! command -v jq >/dev/null 2>&1; then + echo -e "${RED}Error: jq is required but not installed. Please install jq package.${NC}" + exit 1 +fi + +# Create config directory if it doesn't exist +mkdir -p "$CONFIG_DIR" + +# Check if registry exists +if [ ! -f "$REGISTRY_FILE" ]; then + echo -e "${YELLOW}No registry file found. Nothing to migrate.${NC}" + exit 0 +fi + +# Validate JSON format +if ! jq empty "$REGISTRY_FILE" >/dev/null 2>&1; then + echo -e "${RED}Error: Registry file contains invalid JSON.${NC}" + echo "Please check the file: $REGISTRY_FILE" + exit 1 +fi + +# Check if it's already new format +if jq -e 'type == "array" and (length == 0 or .[0] | has("bin_path"))' "$REGISTRY_FILE" >/dev/null 2>&1; then + echo -e "${GREEN}Registry is already in new format. No migration needed.${NC}" + exit 0 +fi + +# Check if it's old format +if ! jq -e 'type == "array" and (length == 0 or .[0] | has("config"))' "$REGISTRY_FILE" >/dev/null 2>&1; then + echo -e "${YELLOW}Registry format not recognized. Manual review needed.${NC}" + echo "Current registry content:" + cat "$REGISTRY_FILE" + exit 1 +fi + +echo -e "${YELLOW}Old format detected. Starting migration...${NC}" + +# Create backup +if ! cp "$REGISTRY_FILE" "$BACKUP_FILE"; then + echo -e "${RED}Error: Failed to create backup file.${NC}" + exit 1 +fi +echo -e "${BLUE}Backup created: $BACKUP_FILE${NC}" + +# Convert to new format +echo "[]" > "$REGISTRY_FILE.new" + +services_migrated=0 +while IFS= read -r service; do + if [ -n "$service" ] && [ "$service" != "null" ]; then + name=$(echo "$service" | jq -r '.name // ""') + provider=$(echo "$service" | jq -r '.provider // ""') + type=$(echo "$service" | jq -r '.type // ""') + config=$(echo "$service" | jq -r '.config // ""') + + # Validate required fields + if [ -z "$name" ] || [ -z "$provider" ] || [ -z "$type" ]; then + echo -e "${YELLOW}Skipping invalid service entry: $service${NC}" + continue + fi + + echo -e "${YELLOW}Migrating service: $name${NC}" + + # Create new format entry with all required fields + new_entry=$(jq -n \ + --arg name "$name" \ + --arg provider "$provider" \ + --arg type "$type" \ + --arg bin_path "unknown" \ + --arg args "" \ + --arg created "$(date -Iseconds)" \ + --arg status "migrated" \ + --arg systemd_type "--user" \ + --arg restart_policy "always" \ + --arg session_manager "none" \ + --arg gdb_enabled "0" \ + --arg pm2_opts "" \ + --arg server_config "" \ + --arg legacy_config "$config" \ + '{ + name: $name, + provider: $provider, + type: $type, + bin_path: $bin_path, + args: $args, + created: $created, + status: $status, + systemd_type: $systemd_type, + restart_policy: $restart_policy, + session_manager: $session_manager, + gdb_enabled: $gdb_enabled, + pm2_opts: $pm2_opts, + server_config: $server_config, + legacy_config: $legacy_config + }') + + # Add to new registry with error checking + if ! jq --argjson entry "$new_entry" '. += [$entry]' "$REGISTRY_FILE.new" > "$REGISTRY_FILE.new.tmp"; then + echo -e "${RED}Error: Failed to add service $name to new registry${NC}" + rm -f "$REGISTRY_FILE.new" "$REGISTRY_FILE.new.tmp" + exit 1 + fi + mv "$REGISTRY_FILE.new.tmp" "$REGISTRY_FILE.new" + + services_migrated=$((services_migrated + 1)) + fi +done < <(jq -c '.[]?' "$BACKUP_FILE" 2>/dev/null || echo "") + +# Replace old registry with new one +if ! mv "$REGISTRY_FILE.new" "$REGISTRY_FILE"; then + echo -e "${RED}Error: Failed to replace old registry with new one${NC}" + exit 1 +fi + +echo -e "${GREEN}Migration completed successfully!${NC}" +echo -e "${BLUE}Services migrated: $services_migrated${NC}" +echo -e "${BLUE}Use 'service-manager.sh restore' to review and update services.${NC}" +echo -e "${YELLOW}Note: Migrated services have bin_path='unknown' and need manual recreation.${NC}" +echo "" +echo -e "${BLUE}To recreate services, use commands like:${NC}" +echo " ./service-manager.sh create auth authserver --provider pm2 --bin-path /path/to/your/bin" +echo " ./service-manager.sh create world worldserver --provider systemd --bin-path /path/to/your/bin" diff --git a/apps/startup-scripts/src/service-manager.sh b/apps/startup-scripts/src/service-manager.sh index 980dfbb3a..34dc4c4d5 100755 --- a/apps/startup-scripts/src/service-manager.sh +++ b/apps/startup-scripts/src/service-manager.sh @@ -4,6 +4,8 @@ # A unified interface for managing AzerothCore services with PM2 or systemd # This script provides commands to create, update, delete, and manage server instances +set -euo pipefail # Strict error handling + # Script location CURRENT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -11,16 +13,16 @@ SCRIPT_DIR="$CURRENT_PATH" ROOT_DIR="$(cd "$CURRENT_PATH/../../.." && pwd)" -# Configuration directory -CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services" +# Configuration directory (can be overridden with AC_SERVICE_CONFIG_DIR) +CONFIG_DIR="${AC_SERVICE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services}" REGISTRY_FILE="$CONFIG_DIR/service_registry.json" # Colors for output -YELLOW='\033[1;33m' -GREEN='\033[0;32m' -RED='\033[0;31m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color +readonly YELLOW='\033[1;33m' +readonly GREEN='\033[0;32m' +readonly RED='\033[0;31m' +readonly BLUE='\033[0;34m' +readonly NC='\033[0m' # No Color # Create config directory if it doesn't exist mkdir -p "$CONFIG_DIR" @@ -38,6 +40,198 @@ check_dependencies() { } } +# Registry management functions +function add_service_to_registry() { + local service_name="$1" + local provider="$2" + local service_type="$3" + local bin_path="$4" + local args="$5" + local systemd_type="$6" + local restart_policy="$7" + local session_manager="$8" + local gdb_enabled="$9" + local pm2_opts="${10}" + local server_config="${11}" + + # Remove any existing entry with the same service name to avoid duplicates + local tmp_file + tmp_file=$(mktemp) + jq --arg name "$service_name" 'map(select(.name != $name))' "$REGISTRY_FILE" > "$tmp_file" && mv "$tmp_file" "$REGISTRY_FILE" + + # Add the new entry to the registry + tmp_file=$(mktemp) + jq --arg name "$service_name" \ + --arg provider "$provider" \ + --arg type "$service_type" \ + --arg bin_path "$bin_path" \ + --arg args "$args" \ + --arg created "$(date -Iseconds)" \ + --arg systemd_type "$systemd_type" \ + --arg restart_policy "$restart_policy" \ + --arg session_manager "$session_manager" \ + --arg gdb_enabled "$gdb_enabled" \ + --arg pm2_opts "$pm2_opts" \ + --arg server_config "$server_config" \ + '. += [{"name": $name, "provider": $provider, "type": $type, "bin_path": $bin_path, "args": $args, "created": $created, "status": "active", "systemd_type": $systemd_type, "restart_policy": $restart_policy, "session_manager": $session_manager, "gdb_enabled": $gdb_enabled, "pm2_opts": $pm2_opts, "server_config": $server_config}]' \ + "$REGISTRY_FILE" > "$tmp_file" && mv "$tmp_file" "$REGISTRY_FILE" + + echo -e "${GREEN}Service '$service_name' added to registry${NC}" +} + +function remove_service_from_registry() { + local service_name="$1" + + if [ -f "$REGISTRY_FILE" ]; then + local tmp_file + tmp_file=$(mktemp) + jq --arg name "$service_name" \ + 'map(select(.name != $name))' \ + "$REGISTRY_FILE" > "$tmp_file" && mv "$tmp_file" "$REGISTRY_FILE" + echo -e "${GREEN}Service '$service_name' removed from registry${NC}" + fi +} + +function restore_missing_services() { + echo -e "${BLUE}Checking for missing services...${NC}" + + if [ ! -f "$REGISTRY_FILE" ] || [ ! -s "$REGISTRY_FILE" ]; then + echo -e "${YELLOW}No services registry found or empty${NC}" + return 0 + fi + + local missing_services=() + local services_count + services_count=$(jq length "$REGISTRY_FILE") + + if [ "$services_count" -eq 0 ]; then + echo -e "${YELLOW}No services registered${NC}" + return 0 + fi + + echo -e "${BLUE}Found $services_count registered services. Checking status...${NC}" + + # Check each service + for i in $(seq 0 $((services_count-1))); do + local service=$(jq -r ".[$i]" "$REGISTRY_FILE") + local name=$(echo "$service" | jq -r '.name') + local provider=$(echo "$service" | jq -r '.provider') + local service_type=$(echo "$service" | jq -r '.type') + local bin_path=$(echo "$service" | jq -r '.bin_path // "unknown"') + local args=$(echo "$service" | jq -r '.args // ""') + local status=$(echo "$service" | jq -r '.status // "active"') + local systemd_type=$(echo "$service" | jq -r '.systemd_type // "--user"') + local restart_policy=$(echo "$service" | jq -r '.restart_policy // "always"') + local session_manager=$(echo "$service" | jq -r '.session_manager // "none"') + local gdb_enabled=$(echo "$service" | jq -r '.gdb_enabled // "0"') + local pm2_opts=$(echo "$service" | jq -r '.pm2_opts // ""') + local server_config=$(echo "$service" | jq -r '.server_config // ""') + + local service_exists=false + + if [ "$provider" = "pm2" ]; then + if pm2 describe "$name" >/dev/null 2>&1; then + service_exists=true + fi + elif [ "$provider" = "systemd" ]; then + local user_unit="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/$name.service" + local system_unit="/etc/systemd/system/$name.service" + if [ -f "$user_unit" ] || [ -f "$system_unit" ]; then + # Unit file present, you can also check if it is active + service_exists=true + else + # Unit file missing: service needs to be recreated! + service_exists=false + fi + fi + + if [ "$service_exists" = false ]; then + missing_services+=("$i") + echo -e "${YELLOW}Missing service: $name ($provider)${NC}" + else + echo -e "${GREEN}✓ Service $name ($provider) exists${NC}" + fi + done + + # Handle missing services + if [ ${#missing_services[@]} -eq 0 ]; then + echo -e "${GREEN}All registered services are present${NC}" + return 0 + fi + + echo -e "${YELLOW}Found ${#missing_services[@]} missing services${NC}" + + for index in "${missing_services[@]}"; do + local service=$(jq -r ".[$index]" "$REGISTRY_FILE") + local name=$(echo "$service" | jq -r '.name') + local provider=$(echo "$service" | jq -r '.provider') + local service_type=$(echo "$service" | jq -r '.type') + local bin_path=$(echo "$service" | jq -r '.bin_path') + local args=$(echo "$service" | jq -r '.args') + local systemd_type=$(echo "$service" | jq -r '.systemd_type // "--user"') + local restart_policy=$(echo "$service" | jq -r '.restart_policy // "always"') + local session_manager=$(echo "$service" | jq -r '.session_manager // "none"') + local gdb_enabled=$(echo "$service" | jq -r '.gdb_enabled // "0"') + local pm2_opts=$(echo "$service" | jq -r '.pm2_opts // ""') + local server_config=$(echo "$service" | jq -r '.server_config // ""') + + echo "" + echo -e "${YELLOW}Service '$name' ($provider) is missing${NC}" + echo " Type: $service_type" + echo " Status: $status" + + if [ "$bin_path" = "unknown" ] || [ "$bin_path" = "null" ] || [ "$status" = "migrated" ]; then + echo " Binary: " + echo " Args: " + echo "" + echo -e "${YELLOW}This service needs to be recreated manually:${NC}" + echo " $0 create $service_type $name --provider $provider --bin-path /path/to/your/bin" + else + echo " Binary: $bin_path" + echo " Args: $args" + fi + echo "" + + read -p "Do you want to (r)ecreate, (d)elete from registry, or (s)kip? [r/d/s]: " choice + + case "$choice" in + r|R|recreate) + if [ "$bin_path" = "unknown" ] || [ "$status" = "migrated" ]; then + echo -e "${YELLOW}Please recreate manually with full create command${NC}" + read -p "Remove this entry from registry? [y/n]: " remove_entry + if [[ "$remove_entry" =~ ^[Yy]$ ]]; then + remove_service_from_registry "$name" + fi + else + echo -e "${BLUE}Recreating service '$name'...${NC}" + if [ "$provider" = "pm2" ]; then + if [ "$args" != "null" ] && [ -n "$args" ]; then + pm2_create_service "$name" "$bin_path $args" "$restart_policy" $pm2_opts + else + pm2_create_service "$name" "$bin_path" "$restart_policy" $pm2_opts + fi + elif [ "$provider" = "systemd" ]; then + echo -e "${BLUE}Attempting to recreate systemd service '$name' automatically...${NC}" + if systemd_create_service "$name" "$bin_path $args" "$restart_policy" "$systemd_type" "$session_manager" "$gdb_enabled" "$server_config"; then + echo -e "${GREEN}Systemd service '$name' recreated successfully${NC}" + else + echo -e "${RED}Failed to recreate systemd service '$name'. Please recreate manually.${NC}" + echo " $0 create $name $service_type --provider systemd --bin-path $bin_path" + fi + fi + fi + ;; + d|D|delete) + echo -e "${BLUE}Removing '$name' from registry...${NC}" + remove_service_from_registry "$name" + ;; + s|S|skip|*) + echo -e "${BLUE}Skipping '$name'${NC}" + ;; + esac + done +} + # Check if PM2 is installed check_pm2() { if ! command -v pm2 >/dev/null 2>&1; then @@ -81,6 +275,7 @@ function print_help() { echo " $base_name update [options]" echo " $base_name delete " echo " $base_name list [provider]" + echo " $base_name restore" echo " $base_name start|stop|restart|status " echo " $base_name logs [--follow]" echo " $base_name attach " @@ -139,6 +334,9 @@ function print_help() { echo " $base_name attach worldserver-realm1" echo " $base_name list pm2" echo "" + echo " # Restore missing services from registry" + echo " $base_name restore" + echo "" echo "Notes:" echo " - Configuration editing modifies run-engine settings (GDB, session manager, etc.)" echo " - Use --server-config for the actual server configuration file" @@ -150,26 +348,13 @@ function print_help() { echo " - attach command automatically detects the configured session manager and connects appropriately" echo " - attach always provides interactive access to the server console" echo " - Use 'logs' command to view service logs without interaction" + echo " - restore command checks registry and helps recreate missing services" + echo "" + echo "Environment Variables:" + echo " AC_SERVICE_CONFIG_DIR - Override default config directory for services registry" } -function register_service() { - local service_name="$1" - local provider="$2" - local service_type="$3" - local config_file="$CONFIG_DIR/$service_name.conf" - - # Add to registry - local tmp_file=$(mktemp) - jq --arg name "$service_name" \ - --arg provider "$provider" \ - --arg type "$service_type" \ - --arg config "$config_file" \ - '. += [{"name": $name, "provider": $provider, "type": $type, "config": $config}]' \ - "$REGISTRY_FILE" > "$tmp_file" - mv "$tmp_file" "$REGISTRY_FILE" - - echo -e "${GREEN}Service $service_name registered successfully${NC}" -} + function validate_service_exists() { local service_name="$1" @@ -210,47 +395,42 @@ function validate_service_exists() { function sync_registry() { echo -e "${YELLOW}Syncing service registry with actual services...${NC}" - local services=$(jq -c '.[]' "$REGISTRY_FILE") - local tmp_file=$(mktemp) + if [ ! -f "$REGISTRY_FILE" ] || [ ! -s "$REGISTRY_FILE" ]; then + echo -e "${YELLOW}No services registry found or empty${NC}" + return 0 + fi - # Initialize with empty array + local services_count=$(jq length "$REGISTRY_FILE") + if [ "$services_count" -eq 0 ]; then + echo -e "${YELLOW}No services registered${NC}" + return 0 + fi + + local tmp_file=$(mktemp) echo "[]" > "$tmp_file" # Check each service in registry - while read -r service_info; do - if [ -n "$service_info" ]; then - local name=$(echo "$service_info" | jq -r '.name') - local provider=$(echo "$service_info" | jq -r '.provider') - - if validate_service_exists "$name" "$provider"; then - # Service exists, add it to the new registry - jq --argjson service "$service_info" '. += [$service]' "$tmp_file" > "$tmp_file.new" - mv "$tmp_file.new" "$tmp_file" - else - echo -e "${YELLOW}Service '$name' no longer exists. Removing from registry.${NC}" - # Don't add to new registry - fi + for i in $(seq 0 $((services_count-1))); do + local service=$(jq -r ".[$i]" "$REGISTRY_FILE") + local name=$(echo "$service" | jq -r '.name') + local provider=$(echo "$service" | jq -r '.provider') + + if validate_service_exists "$name" "$provider"; then + # Service exists, add it to the new registry + jq --argjson service "$service" '. += [$service]' "$tmp_file" > "$tmp_file.new" + mv "$tmp_file.new" "$tmp_file" + else + echo -e "${YELLOW}Service '$name' no longer exists. Removing from registry.${NC}" + # Don't add to new registry fi - done <<< "$services" + done # Replace registry with synced version mv "$tmp_file" "$REGISTRY_FILE" echo -e "${GREEN}Registry synchronized.${NC}" } -function unregister_service() { - local service_name="$1" - - # Remove from registry - local tmp_file=$(mktemp) - jq --arg name "$service_name" '. | map(select(.name != $name))' "$REGISTRY_FILE" > "$tmp_file" - mv "$tmp_file" "$REGISTRY_FILE" - - # Remove configuration file - rm -f "$CONFIG_DIR/$service_name.conf" - - echo -e "${GREEN}Service $service_name unregistered${NC}" -} + function get_service_info() { local service_name="$1" @@ -317,6 +497,15 @@ function pm2_create_service() { if eval "$pm2_cmd"; then echo -e "${GREEN}PM2 service '$service_name' created successfully${NC}" pm2 save + + # Setup PM2 startup for persistence across reboots + echo -e "${BLUE}Configuring PM2 startup for persistence...${NC}" + pm2 startup --auto >/dev/null 2>&1 || true + + # Add to registry (extract command and args from the full command) + local clean_command="$command$additional_args" + add_service_to_registry "$service_name" "pm2" "executable" "$command" "$additional_args" "" "$restart_policy" "none" "0" "$max_memory $max_restarts" "" + return 0 else echo -e "${RED}Failed to create PM2 service '$service_name'${NC}" @@ -334,8 +523,8 @@ function pm2_remove_service() { # Stop the service if it's running if pm2 describe "$service_name" >/dev/null 2>&1; then - pm2 stop "$service_name" 2>/dev/null || true - pm2 delete "$service_name" 2>/dev/null + pm2 stop "$service_name" 2>&1 || true + pm2 delete "$service_name" 2>&1 || true # Wait for PM2 to process the stop/delete command with timeout local timeout=10 @@ -357,8 +546,13 @@ function pm2_remove_service() { pm2 save echo -e "${GREEN}PM2 service '$service_name' stopped and removed${NC}" + + # Remove from registry + remove_service_from_registry "$service_name" else echo -e "${YELLOW}PM2 service '$service_name' not found or already removed${NC}" + # Still try to remove from registry in case it's orphaned + remove_service_from_registry "$service_name" fi return 0 @@ -391,6 +585,7 @@ function pm2_service_logs() { # Systemd service management functions function get_systemd_dir() { local type="$1" + if [ "$type" = "--system" ]; then echo "/etc/systemd/system" else @@ -403,17 +598,32 @@ function systemd_create_service() { local command="$2" local restart_policy="$3" local systemd_type="--user" + local bin_path="" + local gdb_enabled="0" + local server_config="" shift 3 check_systemd || return 1 - # Parse systemd type + # Parse systemd type and extract additional parameters while [[ $# -gt 0 ]]; do case "$1" in --system|--user) systemd_type="$1" shift ;; + --bin-path) + bin_path="$2" + shift 2 + ;; + --gdb-enabled) + gdb_enabled="$2" + shift 2 + ;; + --server-config) + server_config="$2" + shift 2 + ;; *) command+=" $1" shift @@ -421,6 +631,18 @@ function systemd_create_service() { esac done + # If bin_path is not provided, try to extract from command + if [ -z "$bin_path" ]; then + # Try to extract bin path from run-engine command + if [[ "$command" =~ run-engine[[:space:]]+start[[:space:]]+([^[:space:]]+) ]]; then + local binary_path="${BASH_REMATCH[1]}" + bin_path="$(dirname "$binary_path")" + else + # Fallback to current directory + bin_path="$(pwd)" + fi + fi + local systemd_dir=$(get_systemd_dir "$systemd_type") local service_file="$systemd_dir/$service_name.service" @@ -457,6 +679,11 @@ function systemd_create_service() { # Create service file echo -e "${YELLOW}Creating systemd service: $service_name${NC}" + # Ensure bin_path is absolute + if [[ ! "$bin_path" = /* ]]; then + bin_path="$(realpath "$bin_path")" + fi + if [ "$systemd_type" = "--system" ]; then # System service template (with User directive) cat > "$service_file" << EOF @@ -471,7 +698,7 @@ Restart=$restart_policy RestartSec=3 User=$(whoami) Group=$(id -gn) -WorkingDirectory=$(realpath "$bin_path") +WorkingDirectory=$bin_path StandardOutput=journal+console StandardError=journal+console @@ -490,7 +717,7 @@ Type=${service_type} ExecStart=$command Restart=$restart_policy RestartSec=3 -WorkingDirectory=$(realpath "$bin_path") +WorkingDirectory=$bin_path StandardOutput=journal+console StandardError=journal+console @@ -498,10 +725,6 @@ StandardError=journal+console WantedBy=default.target EOF fi - - if [ "$systemd_type" = "--system" ]; then - sed -i 's/WantedBy=default.target/WantedBy=multi-user.target/' "$service_file" - fi # Reload systemd and enable service if [ "$systemd_type" = "--system" ]; then @@ -513,6 +736,10 @@ EOF fi echo -e "${GREEN}Systemd service '$service_name' created successfully${NC}" + + # Add to registry + add_service_to_registry "$service_name" "systemd" "service" "$command" "" "$systemd_type" "$restart_policy" "$session_manager" "$gdb_enabled" "" "$server_config" + return 0 } @@ -572,6 +799,10 @@ function systemd_remove_service() { if [ "$removal_failed" = "true" ]; then echo -e "${YELLOW}Note: Service may still be running but configuration was removed${NC}" fi + + # Remove from registry + remove_service_from_registry "$service_name" + return 0 else echo -e "${RED}Failed to remove systemd service file '$service_file'${NC}" @@ -659,7 +890,7 @@ function create_service() { # Default values for run-engine configuration local provider="auto" - local bin_path="$BINPATH/bin" # get from config or environment + local bin_path="${BINPATH:-$ROOT_DIR/bin}" # get from config or environment local server_config="" local session_manager="none" local gdb_enabled="0" @@ -839,8 +1070,6 @@ EOF # Check if service creation was successful if [ "$service_creation_success" = "true" ]; then - # Register the service - register_service "$service_name" "$provider" "$service_type" echo -e "${GREEN}Service '$service_name' created successfully${NC}" echo -e "${BLUE}Run-engine config: $run_engine_config${NC}" @@ -880,14 +1109,20 @@ function update_service() { # Extract service information local provider=$(echo "$service_info" | jq -r '.provider') local service_type=$(echo "$service_info" | jq -r '.type') - local config_file=$(echo "$service_info" | jq -r '.config') + local config_file="$CONFIG_DIR/$service_name.conf" # Load current configuration + if [ ! -f "$config_file" ]; then + echo -e "${RED}Error: Service configuration file not found: $config_file${NC}" + return 1 + fi source "$config_file" # Load current run-engine configuration if [ -f "$RUN_ENGINE_CONFIG_FILE" ]; then source "$RUN_ENGINE_CONFIG_FILE" + else + echo -e "${YELLOW}Warning: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}" fi # Parse options to update @@ -1020,11 +1255,13 @@ function delete_service() { # Extract provider and config local provider=$(echo "$service_info" | jq -r '.provider') - local config_file=$(echo "$service_info" | jq -r '.config') + local config_file="$CONFIG_DIR/$service_name.conf" # Load configuration to get run-engine config file if [ -f "$config_file" ]; then source "$config_file" + else + echo -e "${YELLOW}Warning: Service configuration file not found: $config_file${NC}" fi echo -e "${YELLOW}Deleting service '$service_name' (provider: $provider)...${NC}" @@ -1048,8 +1285,9 @@ function delete_service() { echo -e "${GREEN}Removed run-engine config: $RUN_ENGINE_CONFIG_FILE${NC}" fi - # Unregister service - unregister_service "$service_name" + # Remove configuration file + rm -f "$config_file" + echo -e "${GREEN}Service '$service_name' deleted successfully${NC}" else echo -e "${RED}Failed to remove service '$service_name' from $provider${NC}" @@ -1166,7 +1404,7 @@ function edit_config() { fi # Get configuration file path - local config_file=$(echo "$service_info" | jq -r '.config') + local config_file="$CONFIG_DIR/$service_name.conf" # Load configuration to get run-engine config file source "$config_file" @@ -1191,7 +1429,7 @@ function attach_to_service() { # Extract provider local provider=$(echo "$service_info" | jq -r '.provider') - local config_file=$(echo "$service_info" | jq -r '.config') + local config_file="$CONFIG_DIR/$service_name.conf" # Load configuration to get run-engine config file if [ ! -f "$config_file" ]; then @@ -1206,6 +1444,11 @@ function attach_to_service() { echo -e "${RED}Error: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}" return 1 fi + + if [ ! -f "$RUN_ENGINE_CONFIG_FILE" ]; then + echo -e "${RED}Error: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}" + return 1 + fi source "$RUN_ENGINE_CONFIG_FILE" @@ -1264,9 +1507,22 @@ function attach_interactive_shell() { # For systemd without session manager, show helpful message local service_info=$(get_service_info "$service_name") - local config_file=$(echo "$service_info" | jq -r '.config') + local config_file="$CONFIG_DIR/$service_name.conf" + + # Check if config file exists before sourcing + if [ ! -f "$config_file" ]; then + echo -e "${RED}Error: Service configuration file not found: $config_file${NC}" + return 1 + fi source "$config_file" + + # Check if RUN_ENGINE_CONFIG_FILE exists before sourcing + if [ ! -f "$RUN_ENGINE_CONFIG_FILE" ]; then + echo -e "${RED}Error: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}" + return 1 + fi + source "$RUN_ENGINE_CONFIG_FILE" echo -e "${RED}Error: Cannot attach to systemd service '$service_name'${NC}" @@ -1375,6 +1631,9 @@ case "${1:-help}" in list) list_services "$2" ;; + restore) + restore_missing_services + ;; start|stop|restart|status) if [ $# -lt 2 ]; then echo -e "${RED}Error: Service name required for $1 command${NC}" From 2ad40a4d23f82054deb9582d58cf7b69489eb697 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Tue, 26 Aug 2025 20:58:41 -0400 Subject: [PATCH 51/57] fix(Core/GroupHandler): Adjust maximum value for rolls. (#22686) --- src/server/apps/worldserver/worldserver.conf.dist | 10 ++++++++++ src/server/game/Handlers/GroupHandler.cpp | 4 +--- src/server/game/World/WorldConfig.cpp | 2 ++ src/server/game/World/WorldConfig.h | 1 + 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 9b36fe680..9618e31a7 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -3141,6 +3141,16 @@ LeaveGroupOnLogout.Enabled = 0 Group.Raid.LevelRestriction = 10 +# +# Group.RandomRollMaximum +# +# The maximum value for use with the client '/roll' command. +# Blizzlike and maximum value is 1000000. (Based on Classic and 3.3.5a client testing respectively) +# Default: 1000000 +# + +Group.RandomRollMaximum = 1000000 + # ################################################################################################### diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 85a9f0888..c8f14779b 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -543,10 +543,8 @@ void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& maximum = packet.Max; /** error handling **/ - if (minimum > maximum || maximum > 10000) // < 32768 for urand call - { + if (minimum > maximum || maximum > sWorld->getIntConfig(CONFIG_RANDOM_ROLL_MAXIMUM)) return; - } GetPlayer()->DoRandomRoll(minimum, maximum); } diff --git a/src/server/game/World/WorldConfig.cpp b/src/server/game/World/WorldConfig.cpp index 7a0b1db40..c38b36ff0 100644 --- a/src/server/game/World/WorldConfig.cpp +++ b/src/server/game/World/WorldConfig.cpp @@ -492,6 +492,8 @@ void WorldConfig::BuildConfigCache() SetConfigValue(CONFIG_LEAVE_GROUP_ON_LOGOUT, "LeaveGroupOnLogout.Enabled", false); + SetConfigValue(CONFIG_RANDOM_ROLL_MAXIMUM, "Group.RandomRollMaximum", 1000000); + SetConfigValue(CONFIG_QUEST_POI_ENABLED, "QuestPOI.Enabled", true); SetConfigValue(CONFIG_CHANGE_FACTION_MAX_MONEY, "ChangeFaction.MaxMoney", 0); diff --git a/src/server/game/World/WorldConfig.h b/src/server/game/World/WorldConfig.h index 3776fcac9..475bed337 100644 --- a/src/server/game/World/WorldConfig.h +++ b/src/server/game/World/WorldConfig.h @@ -129,6 +129,7 @@ enum ServerConfigs CONFIG_ALLOW_JOIN_BG_AND_LFG, CONFIG_MISS_CHANCE_MULTIPLIER_ONLY_FOR_PLAYERS, CONFIG_LEAVE_GROUP_ON_LOGOUT, + CONFIG_RANDOM_ROLL_MAXIMUM, CONFIG_QUEST_POI_ENABLED, CONFIG_VMAP_BLIZZLIKE_PVP_LOS, CONFIG_VMAP_BLIZZLIKE_LOS_OPEN_WORLD, From 96ad9f88ba48ff0ddbdf39e9a0073bc025ea2638 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Tue, 26 Aug 2025 23:02:04 -0400 Subject: [PATCH 52/57] fix(DB/Item): Add some stat values to Death Knight Brutal Gladiator set. (#22725) --- data/sql/updates/pending_db_world/dk-brutal-stats.sql | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 data/sql/updates/pending_db_world/dk-brutal-stats.sql diff --git a/data/sql/updates/pending_db_world/dk-brutal-stats.sql b/data/sql/updates/pending_db_world/dk-brutal-stats.sql new file mode 100644 index 000000000..3c2107fa8 --- /dev/null +++ b/data/sql/updates/pending_db_world/dk-brutal-stats.sql @@ -0,0 +1,5 @@ +UPDATE `item_template` SET `armor` = 1983, `MaxDurability` = 165 WHERE `entry` = 40440; +UPDATE `item_template` SET `armor` = 1239, `MaxDurability` = 55 WHERE `entry` = 40441; +UPDATE `item_template` SET `armor` = 1611, `MaxDurability` = 100 WHERE `entry` = 40442; +UPDATE `item_template` SET `armor` = 1735, `MaxDurability` = 120 WHERE `entry` = 40443; +UPDATE `item_template` SET `armor` = 1487, `MaxDurability` = 100 WHERE `entry` = 40444; From a8284b71de9adf5f6da816cf846f6f2a9477a46e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 27 Aug 2025 03:03:06 +0000 Subject: [PATCH 53/57] chore(DB): import pending files Referenced commit(s): 96ad9f88ba48ff0ddbdf39e9a0073bc025ea2638 --- .../dk-brutal-stats.sql => db_world/2025_08_27_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/dk-brutal-stats.sql => db_world/2025_08_27_00.sql} (90%) diff --git a/data/sql/updates/pending_db_world/dk-brutal-stats.sql b/data/sql/updates/db_world/2025_08_27_00.sql similarity index 90% rename from data/sql/updates/pending_db_world/dk-brutal-stats.sql rename to data/sql/updates/db_world/2025_08_27_00.sql index 3c2107fa8..13cac6c78 100644 --- a/data/sql/updates/pending_db_world/dk-brutal-stats.sql +++ b/data/sql/updates/db_world/2025_08_27_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_25_02 -> 2025_08_27_00 UPDATE `item_template` SET `armor` = 1983, `MaxDurability` = 165 WHERE `entry` = 40440; UPDATE `item_template` SET `armor` = 1239, `MaxDurability` = 55 WHERE `entry` = 40441; UPDATE `item_template` SET `armor` = 1611, `MaxDurability` = 100 WHERE `entry` = 40442; From 0fc05ed4d25ca17604a22146979f10e32fdd854b Mon Sep 17 00:00:00 2001 From: Quartzi <34374881+realQuartzi@users.noreply.github.com> Date: Wed, 27 Aug 2025 09:32:02 +0200 Subject: [PATCH 54/57] feat(Core/Scripting): Add OnPlayerGiveReputation script hook (#21869) --- src/server/game/Entities/Player/Player.cpp | 7 +++++++ src/server/game/Entities/Player/Player.h | 11 ----------- .../game/Scripting/ScriptDefines/PlayerScript.cpp | 5 +++++ .../game/Scripting/ScriptDefines/PlayerScript.h | 4 ++++ src/server/game/Scripting/ScriptMgr.h | 1 + src/server/shared/SharedDefines.h | 11 +++++++++++ 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 6d5e8b24c..00cde81a6 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -6008,6 +6008,7 @@ void Player::RewardReputation(Unit* victim) if (Rep->RepFaction1 && (!Rep->TeamDependent || teamId == TEAM_ALLIANCE)) { float donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast(Rep->RepValue1), ChampioningFaction ? ChampioningFaction : Rep->RepFaction1); + sScriptMgr->OnPlayerGiveReputation(this, Rep->RepFaction1, donerep1, REPUTATION_SOURCE_KILL); FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction1); if (factionEntry1) @@ -6019,6 +6020,7 @@ void Player::RewardReputation(Unit* victim) if (Rep->RepFaction2 && (!Rep->TeamDependent || teamId == TEAM_HORDE)) { float donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast(Rep->RepValue2), ChampioningFaction ? ChampioningFaction : Rep->RepFaction2); + sScriptMgr->OnPlayerGiveReputation(this, Rep->RepFaction2, donerep2, REPUTATION_SOURCE_KILL); FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction2); if (factionEntry2) @@ -6058,22 +6060,27 @@ void Player::RewardReputation(Quest const* quest) if (quest->IsDaily()) { rep = CalculateReputationGain(REPUTATION_SOURCE_DAILY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false); + sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_DAILY_QUEST); } else if (quest->IsWeekly()) { rep = CalculateReputationGain(REPUTATION_SOURCE_WEEKLY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false); + sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_WEEKLY_QUEST); } else if (quest->IsMonthly()) { rep = CalculateReputationGain(REPUTATION_SOURCE_MONTHLY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false); + sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_MONTHLY_QUEST); } else if (quest->IsRepeatable()) { rep = CalculateReputationGain(REPUTATION_SOURCE_REPEATABLE_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false); + sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_REPEATABLE_QUEST); } else { rep = CalculateReputationGain(REPUTATION_SOURCE_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false); + sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_QUEST); } if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(quest->RewardFactionId[i])) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index ae6b6767c..17e18c0ef 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -235,17 +235,6 @@ enum ActionButtonType ACTION_BUTTON_ITEM = 0x80 }; -enum ReputationSource -{ - REPUTATION_SOURCE_KILL, - REPUTATION_SOURCE_QUEST, - REPUTATION_SOURCE_DAILY_QUEST, - REPUTATION_SOURCE_WEEKLY_QUEST, - REPUTATION_SOURCE_MONTHLY_QUEST, - REPUTATION_SOURCE_REPEATABLE_QUEST, - REPUTATION_SOURCE_SPELL -}; - enum QuestSound { QUEST_SOUND_FAILURE = 847 diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp index 57978f7a5..26ba8cba5 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp @@ -139,6 +139,11 @@ void ScriptMgr::OnPlayerReputationRankChange(Player* player, uint32 factionID, R CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_REPUTATION_RANK_CHANGE, script->OnPlayerReputationRankChange(player, factionID, newRank, oldRank, increased)); } +void ScriptMgr::OnPlayerGiveReputation(Player* player, int32 factionID, float& amount, ReputationSource repSource) +{ + CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_GIVE_REPUTATION, script->OnPlayerGiveReputation(player, factionID, amount, repSource)); +} + void ScriptMgr::OnPlayerLearnSpell(Player* player, uint32 spellID) { CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_LEARN_SPELL, script->OnPlayerLearnSpell(player, spellID)); diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.h b/src/server/game/Scripting/ScriptDefines/PlayerScript.h index 692e5c4cc..2faa19539 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.h +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.h @@ -210,6 +210,7 @@ enum PlayerHook PLAYERHOOK_CAN_RESURRECT, PLAYERHOOK_ON_CAN_GIVE_LEVEL, PLAYERHOOK_ON_SEND_LIST_INVENTORY, + PLAYERHOOK_ON_GIVE_REPUTATION, PLAYERHOOK_END }; @@ -283,6 +284,9 @@ public: // Called when a player's reputation rank changes (before it is actually changed) virtual void OnPlayerReputationRankChange(Player* /*player*/, uint32 /*factionID*/, ReputationRank /*newRank*/, ReputationRank /*olRank*/, bool /*increased*/) { } + // Called when a player gains Reputation (before anything is given) + virtual void OnPlayerGiveReputation(Player* /*player*/, int32 /*factionID*/, float& /*amount*/, ReputationSource /*repSource*/) { } + // Called when a player learned new spell virtual void OnPlayerLearnSpell(Player* /*player*/, uint32 /*spellID*/) {} diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 7a048e1a1..e15ac9050 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -313,6 +313,7 @@ public: /* PlayerScript */ void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource); bool OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental); void OnPlayerReputationRankChange(Player* player, uint32 factionID, ReputationRank newRank, ReputationRank oldRank, bool increased); + void OnPlayerGiveReputation(Player* player, int32 factionID, float& amount, ReputationSource repSource); void OnPlayerLearnSpell(Player* player, uint32 spellID); void OnPlayerForgotSpell(Player* player, uint32 spellID); void OnPlayerDuelRequest(Player* target, Player* challenger); diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index e114c997d..fb95d6cea 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -187,6 +187,17 @@ enum ReputationRank : uint8 REP_EXALTED = 7 }; +enum ReputationSource +{ + REPUTATION_SOURCE_KILL, + REPUTATION_SOURCE_QUEST, + REPUTATION_SOURCE_DAILY_QUEST, + REPUTATION_SOURCE_WEEKLY_QUEST, + REPUTATION_SOURCE_MONTHLY_QUEST, + REPUTATION_SOURCE_REPEATABLE_QUEST, + REPUTATION_SOURCE_SPELL +}; + enum FactionTemplates { FACTION_NONE = 0, From cdceb775a03ecfec8117d922108b21817aff1394 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Wed, 27 Aug 2025 05:28:18 -0400 Subject: [PATCH 55/57] fix(Scripts/Karazhan): Implement Tenris Mirkblood. (#22551) Co-authored-by: amed80 <8395873+amed80@users.noreply.github.com> --- .../pending_db_world/tenris-mirkblood.sql | 82 ++++ .../Karazhan/boss_tenris_mirkblood.cpp | 375 ++++++++++++++++++ .../Karazhan/instance_karazhan.cpp | 1 + .../EasternKingdoms/Karazhan/karazhan.h | 8 +- .../eastern_kingdoms_script_loader.cpp | 2 + 5 files changed, 466 insertions(+), 2 deletions(-) create mode 100644 data/sql/updates/pending_db_world/tenris-mirkblood.sql create mode 100644 src/server/scripts/EasternKingdoms/Karazhan/boss_tenris_mirkblood.cpp diff --git a/data/sql/updates/pending_db_world/tenris-mirkblood.sql b/data/sql/updates/pending_db_world/tenris-mirkblood.sql new file mode 100644 index 000000000..67a76c31a --- /dev/null +++ b/data/sql/updates/pending_db_world/tenris-mirkblood.sql @@ -0,0 +1,82 @@ +SET @SAY_APPROACH = 0, +@SAY_AGGRO = 1, +@SAY_SUMMON = 2, +@GUID = 12748; + +DELETE FROM `areatrigger_scripts` WHERE `entry` IN (5014, 5015); +INSERT INTO `areatrigger_scripts` (`entry`, `ScriptName`) VALUES +(5014, 'at_karazhan_mirkblood_approach'), +(5015, 'at_karazhan_mirkblood_entrance'); + +UPDATE `creature_template` SET `minlevel` = 73, `maxlevel` = 73, `speed_run` = 1.85714285714, `ScriptName` = 'boss_tenris_mirkblood' WHERE `entry` = 28194; +UPDATE `creature_template` SET `speed_walk` = 0.4, `speed_run` = 0.14285714285, `ScriptName` = 'npc_sanguine_spirit' WHERE `entry` = 28232; +UPDATE `creature_template` SET `unit_flags` = 33554432, `AIName` = 'SmartAI' WHERE `entry` = 28485; +UPDATE `creature_template` SET `unit_flags` = 33555200 WHERE `entry` = 28493; + +UPDATE `creature_model_info` SET `BoundingRadius` = 0.200000002980232238, `CombatReach` = 0.400000005960464477 WHERE `DisplayID` = 25296; +UPDATE `creature_model_info` SET `BoundingRadius` = 0.465000003576278686, `CombatReach` = 1.5 WHERE `DisplayID` = 25541; + +DELETE FROM `creature_text` WHERE `CreatureID` = 28194; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(28194, @SAY_APPROACH, 0, 'I smell... $r. Delicious!', 14, 0, 100, 0, 0, 0, 27780, 0, 'Prince Tenris Mirkblood - SAY_APPROACH'), +(28194, @SAY_AGGRO, 0, 'I shall consume you!', 14, 0, 100, 0, 0, 0, 27781, 0, 'Prince Tenris Mirkblood - SAY_AGGRO'), +(28194, @SAY_SUMMON, 0, 'Drink, mortals! Taste my blood! Taste your death!', 12, 0, 100, 0, 0, 0, 27712, 0, 'Prince Tenris Mirkblood - SAY_SUMMON'); + +UPDATE `gameobject_template` SET `ScriptName` = 'go_blood_drenched_door' WHERE `entry` = 181032; + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (50883, 50925, 51013); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(50883, 'spell_mirkblood_blood_mirror_target_picker'), +(50925, 'spell_mirkblood_dash_gash_return_to_tank_pre_spell'), +(51013, 'spell_mirkblood_exsanguinate'); + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` = -50845 AND `spell_effect` = -50844; +INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES +(-50845, -50844, 0, 'Tenris Mirkblood Blood Mirror'); + +DELETE FROM `creature_template_addon` WHERE `entry` IN (28232, 28485, 28493); +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(28232, 0, 0, 0, 0, 0, 0, '51282'), +(28485, 0, 0, 0, 0, 0, 0, '30987'), +(28493, 0, 0, 0, 0, 383, 0, ''); + +DELETE FROM `creature_template_movement` WHERE `CreatureId` IN (28485, 28493); +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`, `InteractionPauseTimer`) VALUES +(28485, 0, 0, 1, 0, 0, 0, NULL), +(28493, 0, 0, 1, 0, 0, 0, NULL); + +DELETE FROM `creature` WHERE `guid` BETWEEN @GUID+0 AND @GUID+9 AND `id1` IN (28485, 28493); +INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(@GUID+0, 28485, 0, 0, 532, 0, 0, 1, 1, 0, -11087.619, -1996.4193, 82.59072, 0.453785598278045654, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+1, 28485, 0, 0, 532, 0, 0, 1, 1, 0, -11104.703, -1973.5052, 82.73294, 0.05235987901687622, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+2, 28485, 0, 0, 532, 0, 0, 1, 1, 0, -11084.556, -1981.4388, 82.4658, 0.575958669185638427, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+3, 28485, 0, 0, 532, 0, 0, 1, 1, 0, -11091.643, -1961.8134, 82.77006, 0.104719758033752441, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+4, 28485, 0, 0, 532, 0, 0, 1, 1, 0, -11097.971, -1982.734, 82.39082, 0.418879032135009765, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+5, 28493, 0, 0, 532, 0, 0, 1, 1, 0, -11097.721, -1982.62, 77.43985, 5.113814830780029296, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+6, 28493, 0, 0, 532, 0, 0, 1, 1, 0, -11104.523, -1973.4592, 78.07421, 1.396263360977172851, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+7, 28493, 0, 0, 532, 0, 0, 1, 1, 0, -11084.696, -1981.4202, 77.87848, 4.904375076293945312, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+8, 28493, 0, 0, 532, 0, 0, 1, 1, 0, -11091.594, -1962.1276, 78.054115, 2.146754980087280273, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+9, 28493, 0, 0, 532, 0, 0, 1, 1, 0, -11087.617, -1996.2291, 77.72322, 0.436332315206527709, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL); + +DELETE FROM `game_event_creature` WHERE `eventEntry` = 120 AND `guid` BETWEEN @GUID+0 AND @GUID+9; +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES +(120, @GUID+0), +(120, @GUID+1), +(120, @GUID+2), +(120, @GUID+3), +(120, @GUID+4), +(120, @GUID+5), +(120, @GUID+6), +(120, @GUID+7), +(120, @GUID+8), +(120, @GUID+9); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28485) AND (`source_type` = 0) AND (`id` IN (0)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(28485, 0, 0, 0, 37, 0, 100, 0, 0, 0, 0, 0, 0, 11, 51773, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blood Vat Bunny - On Initialize - Cast \'Scourge Invasion Blood Vat Bunny\''); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` = 51773 AND `ConditionTypeOrReference` = 31 AND `ConditionValue2` = 28485; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 51773, 0, 0, 31, 0, 3, 28485, 0, 0, 0, 0, '', 'Target must be unit Blood Vat Bunny'); + +UPDATE `spell_dbc` SET `Effect_1` = 28, `EffectMiscValue_1` = 28232, `EffectMiscValueB_1` = 64 WHERE `ID` = 50996; diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_tenris_mirkblood.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_tenris_mirkblood.cpp new file mode 100644 index 000000000..518a46055 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_tenris_mirkblood.cpp @@ -0,0 +1,375 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "karazhan.h" +#include "AreaTriggerScript.h" +#include "CreatureScript.h" +#include "GameObjectAI.h" +#include "GameObjectScript.h" +#include "Player.h" +#include "ScriptedCreature.h" +#include "SpellInfo.h" +#include "SpellScript.h" +#include "SpellScriptLoader.h" +#include "UnitAI.h" + +enum Text +{ + SAY_APPROACH = 0, + SAY_AGGRO = 1, + SAY_SUMMON = 2 +}; + +enum Spells +{ + SPELL_BLOOD_MIRROR0 = 50844, + SPELL_BLOOD_MIRROR1 = 50845, + SPELL_BLOOD_MIRROR_TARGET_PICKER = 50883, + SPELL_BLOOD_MIRROR_TRANSITION_VISUAL = 50910, + SPELL_BLOOD_MIRROR_DAMAGE = 50846, + + SPELL_BLOOD_TAP = 51135, + + SPELL_BLOOD_SWOOP = 50922, + SPELL_DASH_GASH_PRE_SPELL = 50923, + SPELL_DASH_GASH_RETURN_TO_TANK = 50924, + // SPELL_DASH_GASH_RETURN_TO_TANK_PRE_SPELL = 50925, + // SPELL_DASH_GASH_RETURN_TO_TANK_PRE_SPELL_ROOT = 50932, + + SPELL_DESPAWN_SANGUINE_SPIRIT_VISUAL = 51214, + SPELL_DESPAWN_SANGUINE_SPIRITS = 51212, + SPELL_SANGUINE_SPIRIT_AURA = 50993, + SPELL_SANGUINE_SPIRIT_PRE_AURA = 51282, + SPELL_SANGUINE_SPIRIT_PRE_AURA2 = 51283, + SPELL_SUMMON_SANGUINE_SPIRIT0 = 50996, + SPELL_SUMMON_SANGUINE_SPIRIT1 = 50998, + // SPELL_SUMMON_SANGUINE_SPIRIT2 = 51204, + SPELL_SUMMON_SANGUINE_SPIRIT_MISSILE_BURST = 51208, + SPELL_SUMMON_SANGUINE_SPIRIT_SHORT_MISSILE_BURST = 51280, + SPELL_SUMMON_SANGUINE_SPIRIT_ON_KILL = 51205, + SPELL_EXSANGUINATE = 51013, + SPELL_DUMMY_NUKE_RANGE_SELF = 51106, +}; + +enum Events +{ + EVENT_SAY = 1, + EVENT_FLAG = 2 +}; + +struct boss_tenris_mirkblood : public BossAI +{ + boss_tenris_mirkblood(Creature* creature) : BossAI(creature, DATA_MIRKBLOOD) + { + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + } + + void Reset() override + { + _Reset(); + + me->SetImmuneToPC(true); + + ScheduleHealthCheckEvent(50, [&] { + Talk(SAY_SUMMON); + DoCast(SPELL_SUMMON_SANGUINE_SPIRIT_MISSILE_BURST); + }); + + ScheduleHealthCheckEvent(45, [&] { + ScheduleTimedEvent(10s, 15s, [&] { + DoCast(SPELL_BLOOD_TAP); + }, 15s, 40s); + }); + } + + void JustEngagedWith(Unit* /*who*/) override + { + DoZoneInCombat(); + + ScheduleTimedEvent(1s, 5s, [&] { + // Blood Mirror + DoCast(SPELL_BLOOD_MIRROR_TARGET_PICKER); + }, 20s, 50s); + ScheduleTimedEvent(30s, [&] { + // Blood Swoop + DoCast(SPELL_DASH_GASH_PRE_SPELL); + }, 15s, 40s); + ScheduleTimedEvent(6s, 15s, [&] { + // Sanguine Spirit + DoCast(SPELL_SUMMON_SANGUINE_SPIRIT_SHORT_MISSILE_BURST); + }, 6s, 15s); + } + + void KilledUnit(Unit* victim) override + { + if (!victim) + return; + + DoCast(victim, SPELL_SUMMON_SANGUINE_SPIRIT_ON_KILL); + } + + void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damageType, SpellSchoolMask damageSchoolMask) override + { + BossAI::DamageTaken(attacker, damage, damageType, damageSchoolMask); + + if (!me->HasAura(SPELL_BLOOD_MIRROR0)) + return; + + if (!_mirrorTarget) + return; + + int32 damageTaken = damage; + + me->CastCustomSpell(_mirrorTarget, SPELL_BLOOD_MIRROR_DAMAGE, &damageTaken, &damageTaken, &damageTaken, true, nullptr, nullptr, me->GetGUID()); + } + + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + if (spell->Id == SPELL_BLOOD_MIRROR0 && caster != me) + _mirrorTarget = caster; + } + + void EnterEvadeMode(EvadeReason why) override + { + _EnterEvadeMode(why); + me->SetImmuneToPC(false); + } + +private: + Unit* _mirrorTarget = nullptr; +}; + +struct npc_sanguine_spirit : public ScriptedAI +{ + npc_sanguine_spirit(Creature* creature) : ScriptedAI(creature) {} + + void Reset() override + { + scheduler.CancelAll(); + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_ALL, true); + + me->SetReactState(REACT_PASSIVE); + + DoCastSelf(SPELL_SANGUINE_SPIRIT_PRE_AURA); + + scheduler.Schedule(5s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_SANGUINE_SPIRIT_PRE_AURA2); + }).Schedule(3s, [this](TaskContext /*context*/) + { + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + DoCastSelf(SPELL_SANGUINE_SPIRIT_AURA); + }); + } + + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + UpdateVictim(); + } +}; + +class spell_mirkblood_blood_mirror_target_picker : public SpellScript +{ + PrepareSpellScript(spell_mirkblood_blood_mirror_target_picker) + + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_BLOOD_MIRROR0, SPELL_BLOOD_MIRROR1, SPELL_BLOOD_MIRROR_TRANSITION_VISUAL }); + } + + void HandleHit() + { + Unit* caster = GetCaster(); + + if (!caster->ToCreature()) + return; + + Unit* target = caster->GetAI()->SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, false); + + if (!target) // Only Blood Mirror the tank if they're the only one around + target = caster->GetVictim(); + + if (!target) + return; + + caster->CastSpell(caster, SPELL_BLOOD_MIRROR_TRANSITION_VISUAL, TRIGGERED_FULL_MASK); + caster->CastSpell(target, SPELL_BLOOD_MIRROR_TRANSITION_VISUAL, TRIGGERED_FULL_MASK); + + caster->AddAura(SPELL_BLOOD_MIRROR1, caster); // Should be a cast, but channeled spell results in either Mirkblood or player being unactionable + caster->AddAura(SPELL_BLOOD_MIRROR1, target); // Adding aura manually causes visual to not appear properly, but better than breaking gameplay + + target->CastSpell(caster, SPELL_BLOOD_MIRROR0); // Clone player + } + + void Register() override + { + OnCast += SpellCastFn(spell_mirkblood_blood_mirror_target_picker::HandleHit); + } +}; + +class spell_mirkblood_dash_gash_return_to_tank_pre_spell : public SpellScript +{ + PrepareSpellScript(spell_mirkblood_dash_gash_return_to_tank_pre_spell) + + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_DASH_GASH_RETURN_TO_TANK }); + } + + void HandleCast() + { + if (!GetCaster() || !GetCaster()->GetThreatMgr().GetCurrentVictim()) + return; + // Probably wrong, maybe don't charge if would charge the same target? + if (GetCaster()->GetDistance2d(GetCaster()->GetThreatMgr().GetCurrentVictim()) < 5.0f) + return; + + GetCaster()->CastSpell(GetCaster()->GetVictim(), SPELL_DASH_GASH_RETURN_TO_TANK); + } + + void Register() override + { + OnCast += SpellCastFn(spell_mirkblood_dash_gash_return_to_tank_pre_spell::HandleCast); + } +}; + +class spell_mirkblood_exsanguinate : public SpellScript +{ + PrepareSpellScript(spell_mirkblood_exsanguinate) + + void CalculateDamage() + { + if (!GetHitUnit()) + return; + + SetHitDamage(std::max((GetHitUnit()->GetHealth() * 0.66f), 2000.0f)); + } + + void Register() override + { + OnHit += SpellHitFn(spell_mirkblood_exsanguinate::CalculateDamage); + } +}; + +class at_karazhan_mirkblood_approach : public AreaTriggerScript +{ +public: + at_karazhan_mirkblood_approach() : AreaTriggerScript("at_karazhan_mirkblood_approach") {} + + bool OnTrigger(Player* player, AreaTrigger const* /*trigger*/) override + { + if (InstanceScript* instance = player->GetInstanceScript()) + if (instance->GetBossState(DATA_MIRKBLOOD) != DONE) + if (Creature* mirkblood = instance->GetCreature(DATA_MIRKBLOOD)) + mirkblood->AI()->Talk(SAY_APPROACH, player); + + return false; + } +}; + +class at_karazhan_mirkblood_entrance : public AreaTriggerScript +{ +public: + at_karazhan_mirkblood_entrance() : AreaTriggerScript("at_karazhan_mirkblood_entrance") {} + + bool OnTrigger(Player* player, AreaTrigger const* /*trigger*/) override + { + if (InstanceScript* instance = player->GetInstanceScript()) + if (instance->GetBossState(DATA_MIRKBLOOD) != DONE) + if (Creature* mirkblood = instance->GetCreature(DATA_MIRKBLOOD)) + mirkblood->SetImmuneToPC(false); + + return false; + } +}; + +class go_blood_drenched_door : public GameObjectScript +{ +public: + go_blood_drenched_door() : GameObjectScript("go_blood_drenched_door") {} + + struct go_blood_drenched_doorAI : public GameObjectAI + { + go_blood_drenched_doorAI(GameObject* go) : GameObjectAI(go) {} + + EventMap events; + Creature* mirkblood; + Player* opener; + + bool GossipHello(Player* player, bool /*reportUse*/) override + { + events.Reset(); + + if (InstanceScript* instance = player->GetInstanceScript()) + if (instance->GetBossState(DATA_MIRKBLOOD) != DONE) + { + opener = player; + mirkblood = instance->GetCreature(DATA_MIRKBLOOD); + + events.ScheduleEvent(EVENT_SAY, 1s); + events.ScheduleEvent(EVENT_FLAG, 5s); + me->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); + } + + return true; + } + + void UpdateAI(uint32 diff) override + { + if (events.Empty()) + return; + + events.Update(diff); + switch (events.ExecuteEvent()) + { + case EVENT_SAY: + if (!mirkblood) + return; + mirkblood->AI()->Talk(SAY_AGGRO, opener); + break; + case EVENT_FLAG: + if (!mirkblood) + return; + mirkblood->SetImmuneToPC(false); + me->Delete(); + break; + } + } + }; + + GameObjectAI* GetAI(GameObject* go) const override + { + return new go_blood_drenched_doorAI(go); + } +}; + +void AddSC_boss_tenris_mirkblood() +{ + RegisterKarazhanCreatureAI(boss_tenris_mirkblood); + RegisterKarazhanCreatureAI(npc_sanguine_spirit); + RegisterSpellScript(spell_mirkblood_blood_mirror_target_picker); + RegisterSpellScript(spell_mirkblood_dash_gash_return_to_tank_pre_spell); + RegisterSpellScript(spell_mirkblood_exsanguinate); + new at_karazhan_mirkblood_approach(); + new at_karazhan_mirkblood_entrance(); + new go_blood_drenched_door(); +} diff --git a/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp index 2f4f27dae..a283e65cc 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp @@ -47,6 +47,7 @@ ObjectData const creatureData[] = { NPC_JULIANNE, DATA_JULIANNE }, { NPC_NIGHTBANE, DATA_NIGHTBANE }, { NPC_TERESTIAN_ILLHOOF, DATA_TERESTIAN }, + { NPC_TENRIS_MIRKBLOOD, DATA_MIRKBLOOD }, { 0, 0 } }; diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h index 4e0d57f4b..890fdcf2d 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h @@ -73,7 +73,9 @@ enum KZDataTypes DATA_ROAR = 41, DATA_STRAWMAN = 42, DATA_TINHEAD = 43, - DATA_TITO = 44 + DATA_TITO = 44, + + DATA_MIRKBLOOD = 45 }; enum KZOperaEvents @@ -135,7 +137,9 @@ enum KZCreatures // Malchezaar Helpers NPC_INFERNAL_TARGET = 17644, - NPC_INFERNAL_RELAY = 17645 + NPC_INFERNAL_RELAY = 17645, + + NPC_TENRIS_MIRKBLOOD = 28194 }; diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp index 67360281a..b92b35215 100644 --- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp +++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp @@ -78,6 +78,7 @@ void AddSC_bosses_opera(); void AddSC_boss_netherspite(); void AddSC_karazhan(); void AddSC_boss_nightbane(); +void AddSC_boss_tenris_mirkblood(); void AddSC_boss_felblood_kaelthas(); // Magister's Terrace void AddSC_boss_selin_fireheart(); void AddSC_boss_vexallus(); @@ -229,6 +230,7 @@ void AddEasternKingdomsScripts() AddSC_boss_netherspite(); AddSC_karazhan(); AddSC_boss_nightbane(); + AddSC_boss_tenris_mirkblood(); AddSC_boss_felblood_kaelthas(); // Magister's Terrace AddSC_boss_selin_fireheart(); AddSC_boss_vexallus(); From 71c22ff6cf8c9d442579ec5905c5eee73408b029 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 27 Aug 2025 09:29:25 +0000 Subject: [PATCH 56/57] chore(DB): import pending files Referenced commit(s): cdceb775a03ecfec8117d922108b21817aff1394 --- .../tenris-mirkblood.sql => db_world/2025_08_27_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/tenris-mirkblood.sql => db_world/2025_08_27_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/tenris-mirkblood.sql b/data/sql/updates/db_world/2025_08_27_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/tenris-mirkblood.sql rename to data/sql/updates/db_world/2025_08_27_01.sql index 67a76c31a..eab3c1735 100644 --- a/data/sql/updates/pending_db_world/tenris-mirkblood.sql +++ b/data/sql/updates/db_world/2025_08_27_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_08_27_00 -> 2025_08_27_01 SET @SAY_APPROACH = 0, @SAY_AGGRO = 1, @SAY_SUMMON = 2, From a3131d5cdb81f6817bbcef8c43ee535ed4c831cf Mon Sep 17 00:00:00 2001 From: Jelle Meeus Date: Wed, 27 Aug 2025 11:43:39 -0700 Subject: [PATCH 57/57] =?UTF-8?q?fix(Core/Player):=20Recast=20lost=20by=20?= =?UTF-8?q?death=20item=20obtain=20spells=20of=20any=20item=E2=80=A6=20(#2?= =?UTF-8?q?2736)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ariel- --- src/server/game/Entities/Player/Player.cpp | 43 +++++++++++++++++++ src/server/game/Entities/Player/Player.h | 3 ++ .../game/Entities/Player/PlayerStorage.cpp | 25 +++++------ 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 00cde81a6..f9fb147a8 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4550,6 +4550,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) // update visibility UpdateObjectVisibility(); + // recast lost by death auras of any items held in the inventory + CastAllObtainSpells(); + sScriptMgr->OnPlayerResurrect(this, restore_percent, applySickness); if (!applySickness) @@ -7024,6 +7027,46 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt UpdateDamagePhysical(WeaponAttackType(attType)); } +void Player::CastAllObtainSpells() +{ + for (uint8 slot = INVENTORY_SLOT_ITEM_START; slot < INVENTORY_SLOT_ITEM_END; ++slot) + if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) + ApplyItemObtainSpells(item, true); + + for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) + { + Bag* bag = GetBagByPos(i); + if (!bag) + continue; + + for (uint32 slot = 0; slot < bag->GetBagSize(); ++slot) + if (Item* item = bag->GetItemByPos(slot)) + ApplyItemObtainSpells(item, true); + } +} + +void Player::ApplyItemObtainSpells(Item* item, bool apply) +{ + ItemTemplate const* itemTemplate = item->GetTemplate(); + for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) + { + if (itemTemplate->Spells[i].SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE) // On obtain trigger + continue; + + int32 const spellId = itemTemplate->Spells[i].SpellId; + if (spellId <= 0) + continue; + + if (apply) + { + if (!HasAura(spellId)) + CastSpell(this, spellId, true, item); + } + else + RemoveAurasDueToSpell(spellId); + } +} + SpellSchoolMask Player::GetMeleeDamageSchoolMask(WeaponAttackType attackType /*= BASE_ATTACK*/, uint8 damageIndex /*= 0*/) const { if (Item const* weapon = GetWeaponForAttack(attackType, true)) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 17e18c0ef..a79392e7f 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2206,6 +2206,9 @@ public: void ResetAllPowers(); + void CastAllObtainSpells(); + void ApplyItemObtainSpells(Item* item, bool apply); + SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK, uint8 damageIndex = 0) const override; void _ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply); diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 01595faa5..4836811e2 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -2577,8 +2577,6 @@ Item* Player::StoreItem(ItemPosCountVec const& dest, Item* pItem, bool update) return nullptr; Item* lastItem = pItem; - ItemTemplate const* proto = pItem->GetTemplate(); - for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end();) { uint16 pos = itr->pos; @@ -2595,13 +2593,6 @@ Item* Player::StoreItem(ItemPosCountVec const& dest, Item* pItem, bool update) lastItem = _StoreItem(pos, pItem, count, true, update); } - // cast after item storing - some checks in checkcast requires item to be present!! - if (lastItem) - for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) - if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger - if (!HasAura(proto->Spells[i].SpellId)) - CastSpell(this, proto->Spells[i].SpellId, true, lastItem); - return lastItem; } @@ -2664,6 +2655,9 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool AddEnchantmentDurations(pItem); AddItemDurations(pItem); + if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)) + ApplyItemObtainSpells(pItem, true); + return pItem; } else @@ -2700,6 +2694,9 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool pItem2->SetState(ITEM_CHANGED, this); + if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)) + ApplyItemObtainSpells(pItem2, true); + return pItem2; } } @@ -3046,10 +3043,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) pItem->ClearSoulboundTradeable(this); RemoveTradeableItem(pItem); - ItemTemplate const* proto = pItem->GetTemplate(); - for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) - if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger - RemoveAurasDueToSpell(proto->Spells[i].SpellId); + ApplyItemObtainSpells(pItem, false); ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount()); @@ -3102,8 +3096,9 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) pBag->RemoveItem(slot, update); // Xinef: item is removed, remove loot from storage if any - if (proto->HasFlag(ITEM_FLAG_HAS_LOOT)) - sLootItemStorage->RemoveStoredLoot(pItem->GetGUID()); + if (ItemTemplate const* proto = pItem->GetTemplate()) + if (proto->HasFlag(ITEM_FLAG_HAS_LOOT)) + sLootItemStorage->RemoveStoredLoot(pItem->GetGUID()); if (IsInWorld() && update) {