From 0e77a7a4479624f034a604459681e84c69ae24f7 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 22 Feb 2025 18:38:07 -0300 Subject: [PATCH 01/57] fix(Scripts/OutdoorPvP): Fix Halaa guards not spawning (#21585) --- src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp index 05930308a..3af31cc6b 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp @@ -90,7 +90,7 @@ void UpdateCreatureHalaa(ObjectGuid::LowType spawnId, Map* map, float x, float y sObjectMgr->AddCreatureToGrid(spawnId, &data); // Spawn if necessary (loaded grids only) - if (!map->Instanceable() && !map->IsGridCreated(x, y)) + if (!map->Instanceable() && map->IsGridLoaded(x, y)) { Creature* creature = new Creature(); if (!creature->LoadCreatureFromDB(spawnId, map, true, true)) From d97563be4425eae2a1411adf9c48a8a771cb53bd Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 22 Feb 2025 18:38:44 -0300 Subject: [PATCH 02/57] =?UTF-8?q?fix(Scripts/SilverpineForest):=20Fix=20do?= =?UTF-8?q?uble=20spawn=20in=20Pyrewood=20Ambush=20an=E2=80=A6=20(#21584)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp index b07354ef5..2037f759f 100644 --- a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp +++ b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp @@ -174,6 +174,7 @@ struct npc_deathstalker_fearleia : public ScriptedAI { _playerGUID.Clear(); _summons.DespawnAll(); + me->SetNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); } } @@ -183,6 +184,7 @@ struct npc_deathstalker_fearleia : public ScriptedAI { _questInProgress = true; _playerGUID = player->GetGUID(); + me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); } Talk(NPCSAY_INIT, player); @@ -204,7 +206,6 @@ struct npc_deathstalker_fearleia : public ScriptedAI SummonCreatureWithRandomTarget(2065, 0); break; case 4: - SummonCreatureWithRandomTarget(2066, 1); SummonCreatureWithRandomTarget(2066, 1); SummonCreatureWithRandomTarget(2067, 0); SummonCreatureWithRandomTarget(2068, 2); From 5d32676193a09bca1734d1a90f24b893ba83701d Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sun, 23 Feb 2025 01:58:21 +0100 Subject: [PATCH 03/57] fix(Core/Misc): Fix NextPage Data Type in PageText Structure and Improve Logging Messages (#21586) --- src/server/game/Globals/ObjectMgr.cpp | 6 +++++- src/server/game/Globals/ObjectMgr.h | 2 +- src/server/game/Handlers/QueryHandler.cpp | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 9b04949b1..dede1dbed 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -5848,7 +5848,11 @@ void ObjectMgr::LoadPageTextLocales() QueryResult result = WorldDatabase.Query("SELECT ID, locale, Text FROM page_text_locale"); if (!result) + { + LOG_WARN("server.loading", ">> Loaded 0 page texts. DB table `page_text_locale` is empty!"); + LOG_INFO("server.loading", " "); return; + } do { @@ -5876,7 +5880,7 @@ void ObjectMgr::LoadInstanceTemplate() if (!result) { - LOG_WARN("server.loading", ">> Loaded 0 instance templates. DB table `page_text` is empty!"); + LOG_WARN("server.loading", ">> Loaded 0 instance templates. DB table `instance_template` is empty!"); LOG_INFO("server.loading", " "); return; } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 3e1a15f8b..0c2a307ea 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -56,7 +56,7 @@ struct PlayerLevelInfo; struct PageText { std::string Text; - uint16 NextPage; + uint32 NextPage; }; /// Key for storing temp summon data in TempSummonDataContainer diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 0e718484b..0666af71c 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -393,7 +393,7 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket& recvData) ObjectMgr::GetLocaleString(player->Text, loc_idx, Text); data << Text; - data << uint32(pageText->NextPage); + data << pageText->NextPage; pageID = pageText->NextPage; } SendPacket(&data); From e31674045bf5a142beb078dc01c64fbf2079be8d Mon Sep 17 00:00:00 2001 From: vrachv Date: Sun, 23 Feb 2025 10:05:54 +0000 Subject: [PATCH 04/57] fix(Core/Spells): Fix "Repelling Wave" stun radius (#21587) --- src/server/game/Spells/SpellInfoCorrections.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index 35092327e..4ac264c96 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -3342,6 +3342,7 @@ void SpellMgr::LoadSpellInfoCorrections() { spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd + spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd }); // Rallying Shout From 826b55dffba73f12e1c04f49a239b4e6cedc9f9e Mon Sep 17 00:00:00 2001 From: Paul <60552737+demetrzz@users.noreply.github.com> Date: Sun, 23 Feb 2025 13:13:31 +0300 Subject: [PATCH 05/57] fix(Core/Spells): Fixed pet swoop ability not rooting target (#21559) Co-authored-by: pavel_k --- src/server/game/Spells/SpellInfoCorrections.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index 4ac264c96..bbb45d557 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -4892,6 +4892,12 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->AttributesEx2 &= ~SPELL_ATTR2_IGNORE_LINE_OF_SIGHT; }); + // Swoop (Moth hunter pet) root effect fix + ApplySpellFix({ 52825 }, [](SpellInfo* spellInfo) + { + spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY); + }); + for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i) { SpellInfo* spellInfo = mSpellInfoMap[i]; From 6f38d3c817391e26e30088f886d4513c8fb75503 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sun, 23 Feb 2025 17:53:11 +0100 Subject: [PATCH 06/57] =?UTF-8?q?fix(Core/Logging):=20revert=20commit=20e3?= =?UTF-8?q?432102f7e66968f53c6e9afb11d7844e95=E2=80=A6=20(#21593)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/game/World/World.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index e62ae480f..1ab024299 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -172,10 +172,10 @@ void World::LoadConfigSettings(bool reload) LOG_ERROR("server.loading", "World settings reload fail: can't read settings."); return; } - } - sLog->LoadFromConfig(); - sMetric->LoadFromConfigs(); + sLog->LoadFromConfig(); + sMetric->LoadFromConfigs(); + } // Set realm id and enable db logging sLog->SetRealmId(realm.Id.Realm); From cd8761796fc90d5adbba68d055814516d80b21d3 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Mon, 24 Feb 2025 06:16:20 +0100 Subject: [PATCH 07/57] fix(CI/Codestyle): skip SQL keyword 'NOT' (#21591) --- apps/codestyle/codestyle-sql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/codestyle/codestyle-sql.py b/apps/codestyle/codestyle-sql.py index 92666d06c..2bc0d3a91 100644 --- a/apps/codestyle/codestyle-sql.py +++ b/apps/codestyle/codestyle-sql.py @@ -234,7 +234,7 @@ def backtick_check(file: io, file_path: str) -> None: # Skip SQL keywords if word.upper() in {"SELECT", "FROM", "JOIN", "WHERE", "GROUP", "BY", "ORDER", "DELETE", "UPDATE", "INSERT", "INTO", "SET", "VALUES", "AND", - "IN", "OR", "REPLACE"}: + "IN", "OR", "REPLACE", "NOT"}: continue # Make sure the word is enclosed in backticks From 96e7a20bd9325618b7adbd1381aa4e0e50bdba23 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 24 Feb 2025 02:18:55 -0300 Subject: [PATCH 08/57] fix(DB/Creature): Fix Felmyst flying animation in p1 and add despawn on evade (#21396) --- data/sql/updates/pending_db_world/rev_1739232932069708100.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1739232932069708100.sql diff --git a/data/sql/updates/pending_db_world/rev_1739232932069708100.sql b/data/sql/updates/pending_db_world/rev_1739232932069708100.sql new file mode 100644 index 000000000..9cbf75ecd --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1739232932069708100.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|512|2147483648 WHERE `entry` = 25038; From f6c29614d587c47b29d2321f918e058a69f48327 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 24 Feb 2025 05:19:56 +0000 Subject: [PATCH 09/57] chore(DB): import pending files Referenced commit(s): 96e7a20bd9325618b7adbd1381aa4e0e50bdba23 --- .../rev_1739232932069708100.sql => db_world/2025_02_24_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1739232932069708100.sql => db_world/2025_02_24_00.sql} (69%) diff --git a/data/sql/updates/pending_db_world/rev_1739232932069708100.sql b/data/sql/updates/db_world/2025_02_24_00.sql similarity index 69% rename from data/sql/updates/pending_db_world/rev_1739232932069708100.sql rename to data/sql/updates/db_world/2025_02_24_00.sql index 9cbf75ecd..c76342cf2 100644 --- a/data/sql/updates/pending_db_world/rev_1739232932069708100.sql +++ b/data/sql/updates/db_world/2025_02_24_00.sql @@ -1,2 +1,3 @@ +-- DB update 2025_02_22_00 -> 2025_02_24_00 -- UPDATE `creature_template` SET `flags_extra` = `flags_extra`|512|2147483648 WHERE `entry` = 25038; From 8f6d651471ee8b88c29dc92960f2342a7b8ff243 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 24 Feb 2025 02:36:22 -0300 Subject: [PATCH 10/57] =?UTF-8?q?fix(Scripts/SunwellPlateau):=20Felmyst=20?= =?UTF-8?q?should=20cast=20Noxious=20Cloud=20only=20a=E2=80=A6=20(#21596)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EasternKingdoms/SunwellPlateau/boss_felmyst.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp index 615fd8ee8..ed1b5408c 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp @@ -134,7 +134,7 @@ struct boss_felmyst : public BossAI void JustEngagedWith(Unit* who) override { BossAI::JustEngagedWith(who); - me->CastSpell(me, SPELL_NOXIOUS_FUMES, true); + me->m_Events.AddEventAtOffset([&] { Talk(YELL_BERSERK); DoCastSelf(SPELL_BERSERK, true); @@ -144,7 +144,7 @@ struct boss_felmyst : public BossAI Position landPos = who->GetPosition(); me->m_Events.AddEventAtOffset([&, landPos] { - me->GetMotionMaster()->MovePoint(POINT_GROUND, landPos, false, true); + me->GetMotionMaster()->MoveLand(POINT_GROUND, landPos); }, 2s); } @@ -168,11 +168,14 @@ struct boss_felmyst : public BossAI void MovementInform(uint32 type, uint32 point) override { - if (type != POINT_MOTION_TYPE) + if (type != EFFECT_MOTION_TYPE && type != POINT_MOTION_TYPE) return; if (point == POINT_GROUND) { + if (!me->HasAura(SPELL_NOXIOUS_FUMES)) + DoCastSelf(SPELL_NOXIOUS_FUMES, true); + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->SetCanFly(false); me->SetDisableGravity(false); From 835283bf26b02bd3c6e88505b123ad65aa9d0e98 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 24 Feb 2025 05:59:18 -0300 Subject: [PATCH 11/57] feat(Core/Scripting): Implement ScheduleEnrageTimer() helper (#21597) --- .../game/AI/ScriptedAI/ScriptedCreature.cpp | 15 +++++++++++++++ src/server/game/AI/ScriptedAI/ScriptedCreature.h | 6 ++++++ .../SunwellPlateau/boss_eredar_twins.cpp | 12 ++---------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 64678db31..72a4cc615 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -633,6 +633,7 @@ void BossAI::_Reset() me->ResetLootMode(); events.Reset(); scheduler.CancelAll(); + me->m_Events.KillAllEvents(false); summons.DespawnAll(); ClearUniqueTimedEventsDone(); _healthCheckEvents.clear(); @@ -787,6 +788,20 @@ void BossAI::ScheduleHealthCheckEvent(std::initializer_list healthPct, st _nextHealthCheck = _healthCheckEvents.front(); } +void BossAI::ScheduleEnrageTimer(uint32 spellId, Milliseconds timer, uint8 textId /*= 0*/) +{ + me->m_Events.AddEventAtOffset([this, spellId, textId] + { + if (!me->IsAlive()) + return; + + if (textId) + Talk(textId); + + DoCastSelf(spellId, true); + }, timer); +} + // WorldBossAI - for non-instanced bosses WorldBossAI::WorldBossAI(Creature* creature) : diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index d5f7f729f..9cb004a89 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -485,6 +485,12 @@ public: void ScheduleHealthCheckEvent(uint32 healthPct, std::function exec); void ScheduleHealthCheckEvent(std::initializer_list healthPct, std::function exec); + // @brief Casts the spell after the fixed time and says the text id if provided. Timer will run even if the creature is casting or out of combat. + // @param spellId The spell to cast. + // @param timer The time to wait before casting the spell. + // @param textId The text id to say. + void ScheduleEnrageTimer(uint32 spellId, Milliseconds timer, uint8 textId = 0); + // Hook used to execute events scheduled into EventMap without the need // to override UpdateAI // note: You must re-schedule the event within this method if the event diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp index 75de3d41c..4a325c5ef 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp @@ -83,7 +83,6 @@ struct boss_sacrolash : public BossAI _isSisterDead = false; BossAI::Reset(); me->SetLootMode(0); - me->m_Events.KillAllEvents(false); } void DoAction(int32 param) override @@ -124,10 +123,7 @@ struct boss_sacrolash : public BossAI if (alythess->IsAlive() && !alythess->IsInCombat()) alythess->AI()->AttackStart(who); - me->m_Events.AddEventAtOffset([&] { - Talk(YELL_BERSERK); - DoCastSelf(SPELL_ENRAGE, true); - }, 6min); + ScheduleEnrageTimer(SPELL_ENRAGE, 6min, YELL_BERSERK); ScheduleTimedEvent(10s, [&] { DoCastSelf(SPELL_SHADOW_BLADES); @@ -195,7 +191,6 @@ struct boss_alythess : public BossAI _isSisterDead = false; BossAI::Reset(); me->SetLootMode(0); - me->m_Events.KillAllEvents(false); } void DoAction(int32 param) override @@ -236,10 +231,7 @@ struct boss_alythess : public BossAI if (sacrolash->IsAlive() && !sacrolash->IsInCombat()) sacrolash->AI()->AttackStart(who); - me->m_Events.AddEventAtOffset([&] { - Talk(YELL_BERSERK); - DoCastSelf(SPELL_ENRAGE, true); - }, 6min); + ScheduleEnrageTimer(SPELL_ENRAGE, 6min, YELL_BERSERK); ScheduleTimedEvent(1s, [&] { DoCastVictim(SPELL_BLAZE); From f234f034a10bf1822882dfcae2f81806b6f8cab5 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 24 Feb 2025 11:48:44 -0300 Subject: [PATCH 12/57] fix(Scripts/SunwellPlateau): Fix twins respawn (#21598) --- .../SunwellPlateau/boss_eredar_twins.cpp | 32 +++++-------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp index 4a325c5ef..676bd301c 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp @@ -83,6 +83,10 @@ struct boss_sacrolash : public BossAI _isSisterDead = false; BossAI::Reset(); me->SetLootMode(0); + + if (Creature* alythess = instance->GetCreature(DATA_ALYTHESS)) + if (!alythess->IsAlive()) + alythess->Respawn(true); } void DoAction(int32 param) override @@ -104,18 +108,6 @@ struct boss_sacrolash : public BossAI } } - void EnterEvadeMode(EvadeReason why) override - { - BossAI::EnterEvadeMode(why); - if (Creature* alythess = instance->GetCreature(DATA_ALYTHESS)) - { - if (!alythess->IsAlive()) - alythess->Respawn(true); - else if (!alythess->IsInEvadeMode()) - alythess->AI()->EnterEvadeMode(why); - } - } - void JustEngagedWith(Unit* who) override { BossAI::JustEngagedWith(who); @@ -191,6 +183,10 @@ struct boss_alythess : public BossAI _isSisterDead = false; BossAI::Reset(); me->SetLootMode(0); + + if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH)) + if (!sacrolash->IsAlive()) + sacrolash->Respawn(true); } void DoAction(int32 param) override @@ -212,18 +208,6 @@ struct boss_alythess : public BossAI } } - void EnterEvadeMode(EvadeReason why) override - { - BossAI::EnterEvadeMode(why); - if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH)) - { - if (!sacrolash->IsAlive()) - sacrolash->Respawn(true); - else if (!sacrolash->IsInEvadeMode()) - sacrolash->AI()->EnterEvadeMode(why); - } - } - void JustEngagedWith(Unit* who) override { BossAI::JustEngagedWith(who); From b83071388c7d69f42dc57e299f20241be035a850 Mon Sep 17 00:00:00 2001 From: vrachv Date: Mon, 24 Feb 2025 14:49:33 +0000 Subject: [PATCH 13/57] fix(Scripts/SunwellPlateau) Fix flame touched stacking (#21594) --- .../SunwellPlateau/boss_eredar_twins.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp index 676bd301c..e33aadb6e 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp @@ -22,6 +22,7 @@ #include "SpellInfo.h" #include "SpellScript.h" #include "SpellScriptLoader.h" +#include "SpellAuraEffects.h" #include "sunwell_plateau.h" enum Quotes @@ -365,8 +366,15 @@ public: return ValidateSpellInfo({ _touchSpell }); } - void OnPeriodic(AuraEffect const* /*aurEff*/) + void OnPeriodic(AuraEffect const* aurEff) { + if (aurEff->GetId() == SPELL_FLAME_SEAR) + { + uint32 tick = aurEff->GetTickNumber(); + if (tick % 2 != 0 || tick > 10) + return; + } + if (Unit* owner = GetOwner()->ToUnit()) owner->CastSpell(owner, _touchSpell, true); } From 9f99e89bc325c1a102a042eb07ccfdeb49625048 Mon Sep 17 00:00:00 2001 From: SaW Date: Mon, 24 Feb 2025 19:49:54 +0100 Subject: [PATCH 14/57] fix(Core/Threading): Refactored Map class - some code optimization (#21288) --- src/server/game/Maps/Map.cpp | 81 ++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 5e04e0ba6..b6a239274 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -588,16 +588,20 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) if (t_diff) _dynamicTree.update(t_diff); - /// update worldsessions for existing players + // Update world sessions and players for (m_mapRefIter = m_mapRefMgr.begin(); m_mapRefIter != m_mapRefMgr.end(); ++m_mapRefIter) { Player* player = m_mapRefIter->GetSource(); if (player && player->IsInWorld()) { - //player->Update(t_diff); + // Update session WorldSession* session = player->GetSession(); MapSessionFilter updater(session); session->Update(s_diff, updater); + + // update players at tick + if (!t_diff) + player->Update(s_diff); } } @@ -605,17 +609,6 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) if (!t_diff) { - for (m_mapRefIter = m_mapRefMgr.begin(); m_mapRefIter != m_mapRefMgr.end(); ++m_mapRefIter) - { - Player* player = m_mapRefIter->GetSource(); - - if (!player || !player->IsInWorld()) - continue; - - // update players at tick - player->Update(s_diff); - } - HandleDelayedVisibility(); return; } @@ -624,36 +617,35 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) resetMarkedCells(); resetMarkedCellsLarge(); + // Prepare object updaters Acore::ObjectUpdater updater(t_diff, false); - // for creature - TypeContainerVisitor grid_object_update(updater); - // for pets - TypeContainerVisitor world_object_update(updater); + // For creature + TypeContainerVisitor grid_object_update(updater); - // for large creatures + // For pets + TypeContainerVisitor world_object_update(updater); + + // For large creatures Acore::ObjectUpdater largeObjectUpdater(t_diff, true); - TypeContainerVisitor grid_large_object_update(largeObjectUpdater); - TypeContainerVisitor world_large_object_update(largeObjectUpdater); + TypeContainerVisitor grid_large_object_update(largeObjectUpdater); + TypeContainerVisitor world_large_object_update(largeObjectUpdater); // pussywizard: container for far creatures in combat with players std::vector updateList; updateList.reserve(10); - // non-player active objects, increasing iterator in the loop in case of object removal + // Update non-player active objects for (m_activeNonPlayersIter = m_activeNonPlayers.begin(); m_activeNonPlayersIter != m_activeNonPlayers.end();) { WorldObject* obj = *m_activeNonPlayersIter; ++m_activeNonPlayersIter; - if (!obj || !obj->IsInWorld()) - continue; - - VisitNearbyCellsOf(obj, grid_object_update, world_object_update, grid_large_object_update, world_large_object_update); + if (obj && obj->IsInWorld()) + VisitNearbyCellsOf(obj, grid_object_update, world_object_update, grid_large_object_update, world_large_object_update); } - // the player iterator is stored in the map object - // to make sure calls to Map::Remove don't invalidate it + // Update players and their associated objects for (m_mapRefIter = m_mapRefMgr.begin(); m_mapRefIter != m_mapRefMgr.end(); ++m_mapRefIter) { Player* player = m_mapRefIter->GetSource(); @@ -661,12 +653,10 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) if (!player || !player->IsInWorld()) continue; - // update players at tick player->Update(s_diff); - VisitNearbyCellsOfPlayer(player, grid_object_update, world_object_update, grid_large_object_update, world_large_object_update); - // If player is using far sight, visit that object too + // If player is using far sight, update viewpoint if (WorldObject* viewPoint = player->GetViewpoint()) { if (Creature* viewCreature = viewPoint->ToCreature()) @@ -684,7 +674,8 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) { updateList.clear(); float rangeSq = player->GetGridActivationRange() - 1.0f; - rangeSq = rangeSq * rangeSq; + rangeSq *= rangeSq; + HostileReference* ref = player->getHostileRefMgr().getFirst(); while (ref) { @@ -694,20 +685,20 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) updateList.push_back(cre); ref = ref->next(); } - for (std::vector::const_iterator itr = updateList.begin(); itr != updateList.end(); ++itr) - VisitNearbyCellsOf(*itr, grid_object_update, world_object_update, grid_large_object_update, world_large_object_update); + + for (Creature* cre : updateList) + VisitNearbyCellsOf(cre, grid_object_update, world_object_update, grid_large_object_update, world_large_object_update); } } - for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();) // pussywizard: transports updated after VisitNearbyCellsOf, grids around are loaded, everything ok + // Update transports - pussywizard: transports updated after VisitNearbyCellsOf, grids around are loaded, everything ok + for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();) { MotionTransport* transport = *_transportsUpdateIter; ++_transportsUpdateIter; - if (!transport->IsInWorld()) - continue; - - transport->Update(t_diff); + if (transport->IsInWorld()) + transport->Update(t_diff); } SendObjectUpdates(); @@ -1674,14 +1665,16 @@ bool Map::IsUnderWater(uint32 phaseMask, float x, float y, float z, float collis bool Map::HasEnoughWater(WorldObject const* searcher, float x, float y, float z) const { - LiquidData const& liquidData = const_cast(this)->GetLiquidData(searcher->GetPhaseMask(), x, y, z, searcher->GetCollisionHeight(), MAP_ALL_LIQUIDS); - return (liquidData.Status & MAP_LIQUID_STATUS_SWIMMING) != 0 && HasEnoughWater(searcher, liquidData); -} + LiquidData const& liquidData = const_cast(this)->GetLiquidData( + searcher->GetPhaseMask(), x, y, z, searcher->GetCollisionHeight(), MAP_ALL_LIQUIDS); + + if ((liquidData.Status & MAP_LIQUID_STATUS_SWIMMING) == 0) + return false; -bool Map::HasEnoughWater(WorldObject const* searcher, LiquidData const& liquidData) const -{ float minHeightInWater = searcher->GetMinHeightInWater(); - return liquidData.Level > INVALID_HEIGHT && liquidData.Level > liquidData.DepthLevel && liquidData.Level - liquidData.DepthLevel >= minHeightInWater; + return liquidData.Level > INVALID_HEIGHT && + liquidData.Level > liquidData.DepthLevel && + liquidData.Level - liquidData.DepthLevel >= minHeightInWater; } char const* Map::GetMapName() const From a2eaa5739423fe613f66bce0d118a097edf150ef Mon Sep 17 00:00:00 2001 From: Razor2142 Date: Tue, 25 Feb 2025 19:40:42 +0100 Subject: [PATCH 15/57] fix(Scripts/Naxxramas): refactored instance script (#21539) --- .../rev_1739822360188928600.sql | 8 + .../Northrend/Naxxramas/boss_anubrekhan.cpp | 2 +- .../Northrend/Naxxramas/boss_faerlina.cpp | 9 +- .../Naxxramas/boss_four_horsemen.cpp | 50 +- .../Northrend/Naxxramas/boss_gluth.cpp | 14 +- .../Northrend/Naxxramas/boss_gothik.cpp | 79 +- .../Northrend/Naxxramas/boss_grobbulus.cpp | 17 +- .../Northrend/Naxxramas/boss_heigan.cpp | 71 +- .../Northrend/Naxxramas/boss_kelthuzad.cpp | 119 +- .../Northrend/Naxxramas/boss_loatheb.cpp | 33 +- .../Northrend/Naxxramas/boss_maexxna.cpp | 22 +- .../scripts/Northrend/Naxxramas/boss_noth.cpp | 31 +- .../Northrend/Naxxramas/boss_patchwerk.cpp | 18 +- .../Northrend/Naxxramas/boss_razuvious.cpp | 43 +- .../Northrend/Naxxramas/boss_sapphiron.cpp | 15 +- .../Northrend/Naxxramas/boss_thaddius.cpp | 133 +- .../Naxxramas/instance_naxxramas.cpp | 1844 ++++++----------- .../scripts/Northrend/Naxxramas/naxxramas.h | 301 ++- 18 files changed, 1053 insertions(+), 1756 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1739822360188928600.sql diff --git a/data/sql/updates/pending_db_world/rev_1739822360188928600.sql b/data/sql/updates/pending_db_world/rev_1739822360188928600.sql new file mode 100644 index 000000000..77db67f34 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1739822360188928600.sql @@ -0,0 +1,8 @@ +-- update Mr. Bigglesworth script name +UPDATE `creature_template` SET `ScriptName` = 'npc_mr_bigglesworth' WHERE (`entry` = 16998); + +-- update Living Poison script name +UPDATE `creature_template` SET `ScriptName` = 'npc_living_poison' WHERE (`entry` = 16027); + +-- update Naxxramas Trigger script name +UPDATE `creature_template` SET `ScriptName` = 'npc_naxxramas_trigger' WHERE (`entry` = 16082); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp index f89542bba..b8cc1d9c2 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp @@ -118,7 +118,7 @@ public: Talk(SAY_SLAY); victim->CastSpell(victim, SPELL_SUMMON_CORPSE_SCRABS_5, true, nullptr, nullptr, me->GetGUID()); - instance->SetData(DATA_IMMORTAL_FAIL, 0); + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustEngagedWith(Unit* who) override diff --git a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp index 1be14803f..9ab1fcde0 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp @@ -83,8 +83,6 @@ public: BossAI::Reset(); summons.DespawnAll(); SummonHelpers(); - if (GameObject* go = me->GetMap()->GetGameObject(instance->GetGuidData(DATA_FAERLINA_WEB))) - go->SetGoState(GO_STATE_ACTIVE); } void JustEngagedWith(Unit* who) override @@ -114,9 +112,6 @@ public: else context.Repeat(30s); }); - - if (GameObject* go = me->GetMap()->GetGameObject(instance->GetGuidData(DATA_FAERLINA_WEB))) - go->SetGoState(GO_STATE_READY); } void MoveInLineOfSight(Unit* who) override @@ -137,15 +132,13 @@ public: if (!urand(0, 3)) Talk(SAY_SLAY); - instance->SetData(DATA_IMMORTAL_FAIL, 0); + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustDied(Unit* killer) override { BossAI::JustDied(killer); Talk(SAY_DEATH); - if (GameObject* go = me->GetMap()->GetGameObject(instance->GetGuidData(DATA_FAERLINA_WEB))) - go->SetGoState(GO_STATE_ACTIVE); } void SpellHit(Unit* caster, SpellInfo const* spell) override diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp index 0308ab316..6439f45ad 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp @@ -131,7 +131,6 @@ public: { explicit boss_four_horsemenAI(Creature* c) : BossAI(c, BOSS_HORSEMAN) { - pInstance = me->GetInstanceScript(); switch (me->GetEntry()) { case NPC_SIR_ZELIEK: @@ -150,7 +149,6 @@ public: } EventMap events; - InstanceScript* pInstance; uint8 currentWaypoint{}; uint8 movementPhase{}; uint8 horsemanId; @@ -203,16 +201,6 @@ public: { events.RescheduleEvent(EVENT_SECONDARY_SPELL, 15s); } - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_HORSEMEN_GATE))) - { - if (pInstance->GetBossState(BOSS_GOTHIK) == DONE) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } - } } void MovementInform(uint32 type, uint32 id) override @@ -262,36 +250,19 @@ public: return; Talk(SAY_SLAY); - if (pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustDied(Unit* killer) override { BossAI::JustDied(killer); - if (pInstance) - { - if (pInstance->GetBossState(BOSS_HORSEMAN) == DONE) - { - if (!me->GetMap()->GetPlayers().IsEmpty()) - { - if (Player* player = me->GetMap()->GetPlayers().getFirst()->GetSource()) - { - if (GameObject* chest = player->SummonGameObject(RAID_MODE(GO_HORSEMEN_CHEST_10, GO_HORSEMEN_CHEST_25), 2514.8f, -2944.9f, 245.55f, 5.51f, 0, 0, 0, 0, 0)) - { - chest->SetLootRecipient(me); - } - } - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_HORSEMEN_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } - } Talk(SAY_DEATH); + + if (instance->GetBossState(BOSS_HORSEMAN) == DONE) + if (!me->GetMap()->GetPlayers().IsEmpty()) + if (Player* player = me->GetMap()->GetPlayers().getFirst()->GetSource()) + if (GameObject* chest = player->SummonGameObject(RAID_MODE(GO_HORSEMEN_CHEST_10, GO_HORSEMEN_CHEST_25), 2514.8f, -2944.9f, 245.55f, 5.51f, 0, 0, 0, 0, 0)) + chest->SetLootRecipient(me); } void JustEngagedWith(Unit* who) override @@ -305,13 +276,6 @@ public: me->SetSpeed(MOVE_RUN, me->GetSpeedRate(MOVE_RUN), true); MoveToCorner(); } - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_HORSEMEN_GATE))) - { - go->SetGoState(GO_STATE_READY); - } - } } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp index cea3baccf..30b678a87 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp @@ -79,13 +79,10 @@ public: struct boss_gluthAI : public BossAI { explicit boss_gluthAI(Creature* c) : BossAI(c, BOSS_GLUTH), summons(me) - { - pInstance = me->GetInstanceScript(); - } + {} EventMap events; SummonList summons; - InstanceScript* pInstance; void Reset() override { @@ -138,13 +135,10 @@ public: void KilledUnit(Unit* who) override { if (me->IsAlive() && who->GetEntry() == NPC_ZOMBIE_CHOW) - { me->ModifyHealth(int32(me->GetMaxHealth() * 0.05f)); - } - if (who->IsPlayer() && pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + + if (who->IsPlayer()) + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustDied(Unit* killer) override diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp index fd4bb92e7..939f0bf19 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp @@ -201,12 +201,10 @@ public: struct boss_gothikAI : public BossAI { explicit boss_gothikAI(Creature* c) : BossAI(c, BOSS_GOTHIK), summons(me) - { - pInstance = me->GetInstanceScript(); - } + {} + EventMap events; SummonList summons; - InstanceScript* pInstance; bool secondPhase{}; bool gateOpened{}; uint8 waveCount{}; @@ -233,21 +231,6 @@ public: gateOpened = false; waveCount = 0; me->NearTeleportTo(2642.139f, -3386.959f, 285.492f, 6.265f); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_GOTHIK_ENTER_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_GOTHIK_INNER_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_GOTHIK_EXIT_GATE))) - { - go->SetGoState(GO_STATE_READY); - } - } } void JustEngagedWith(Unit* who) override @@ -261,17 +244,6 @@ public: me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE); events.ScheduleEvent(EVENT_SUMMON_ADDS, 30s); events.ScheduleEvent(EVENT_CHECK_PLAYERS, 2min); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_GOTHIK_ENTER_GATE))) - { - go->SetGoState(GO_STATE_READY); - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_GOTHIK_INNER_GATE))) - { - go->SetGoState(GO_STATE_READY); - } - } } void JustSummoned(Creature* summon) override @@ -327,10 +299,7 @@ public: return; Talk(SAY_KILL); - if (pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustDied(Unit* killer) override @@ -338,21 +307,6 @@ public: BossAI::JustDied(killer); Talk(SAY_DEATH); summons.DespawnAll(); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_GOTHIK_ENTER_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_GOTHIK_INNER_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_GOTHIK_EXIT_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } } void SummonHelpers(uint32 entry) @@ -472,12 +426,11 @@ public: events.Repeat(20s); break; case EVENT_CHECK_HEALTH: - if (me->HealthBelowPct(30) && pInstance) + if (me->HealthBelowPct(30)) { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_GOTHIK_INNER_GATE))) - { + if (GameObject* go = instance->GetGameObject(DATA_GOTHIK_INNER_GATE)) go->SetGoState(GO_STATE_ACTIVE); - } + events.CancelEvent(EVENT_TELEPORT); break; } @@ -509,10 +462,9 @@ public: case EVENT_CHECK_PLAYERS: if (!CheckGroupSplitted()) { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_GOTHIK_INNER_GATE))) - { + if (GameObject* go = instance->GetGameObject(DATA_GOTHIK_INNER_GATE)) go->SetGoState(GO_STATE_ACTIVE); - } + gateOpened = true; Talk(EMOTE_GATE_OPENED); } @@ -597,10 +549,8 @@ public: void KilledUnit(Unit* who) override { - if (who->IsPlayer() && me->GetInstanceScript()) - { - me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0); - } + if (who->IsPlayer()) + me->GetInstanceScript()->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void UpdateAI(uint32 diff) override @@ -767,17 +717,14 @@ public: // dead side summons are "owned" by gothik void JustSummoned(Creature* summon) override { - if (Creature* gothik = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(DATA_GOTHIK_BOSS))) - { + if (Creature* gothik = me->GetInstanceScript()->GetCreature(DATA_GOTHIK_BOSS)) gothik->AI()->JustSummoned(summon); - } } + void SummonedCreatureDespawn(Creature* summon) override { - if (Creature* gothik = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(DATA_GOTHIK_BOSS))) - { + if (Creature* gothik = me->GetInstanceScript()->GetCreature(DATA_GOTHIK_BOSS)) gothik->AI()->SummonedCreatureDespawn(summon); - } } }; }; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp index 39a84201e..fd3f395f8 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp @@ -70,13 +70,10 @@ public: struct boss_grobbulusAI : public BossAI { explicit boss_grobbulusAI(Creature* c) : BossAI(c, BOSS_GROBBULUS), summons(me) - { - pInstance = me->GetInstanceScript(); - } + {} EventMap events; SummonList summons; - InstanceScript* pInstance; uint32 dropSludgeTimer{}; void Reset() override @@ -138,10 +135,8 @@ public: void KilledUnit(Unit* who) override { - if (who->IsPlayer() && pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + if (who->IsPlayer()) + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void UpdateAI(uint32 diff) override @@ -217,10 +212,8 @@ public: void KilledUnit(Unit* who) override { - if (who->IsPlayer() && me->GetInstanceScript()) - { - me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0); - } + if (who->IsPlayer()) + me->GetInstanceScript()->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp index c91f67ba7..de73995e9 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp @@ -69,11 +69,8 @@ public: struct boss_heiganAI : public BossAI { explicit boss_heiganAI(Creature* c) : BossAI(c, BOSS_HEIGAN) - { - pInstance = me->GetInstanceScript(); - } + {} - InstanceScript* pInstance; EventMap events; uint8 currentPhase{}; uint8 currentSection{}; @@ -86,13 +83,6 @@ public: currentPhase = 0; currentSection = 3; moveRight = true; - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_HEIGAN_ENTER_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } } void KilledUnit(Unit* who) override @@ -101,10 +91,7 @@ public: return; Talk(SAY_SLAY); - if (pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustDied(Unit* killer) override @@ -118,13 +105,6 @@ public: BossAI::JustEngagedWith(who); me->SetInCombatWithZone(); Talk(SAY_AGGRO); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_HEIGAN_ENTER_GATE))) - { - go->SetGoState(GO_STATE_READY); - } - } StartFightPhase(PHASE_SLOW_DANCE); } @@ -206,41 +186,38 @@ public: } break; case EVENT_ERUPT_SECTION: - if (pInstance) - { - pInstance->SetData(DATA_HEIGAN_ERUPTION, currentSection); - if (currentSection == 3) - { - moveRight = false; - } - else if (currentSection == 0) - { - moveRight = true; - } - moveRight ? currentSection++ : currentSection--; - } + { + instance->SetData(DATA_HEIGAN_ERUPTION, currentSection); + if (currentSection == 3) + moveRight = false; + else if (currentSection == 0) + moveRight = true; + + moveRight ? currentSection++ : currentSection--; + if (currentPhase == PHASE_SLOW_DANCE) - { Talk(SAY_TAUNT); - } + events.Repeat(currentPhase == PHASE_SLOW_DANCE ? 10s : 4s); break; + } case EVENT_SAFETY_DANCE: + { + Map::PlayerList const& pList = me->GetMap()->GetPlayers(); + for (auto const& itr : pList) { - Map::PlayerList const& pList = me->GetMap()->GetPlayers(); - for (auto const& itr : pList) + if (IsInRoom(itr.GetSource()) && !itr.GetSource()->IsAlive()) { - if (IsInRoom(itr.GetSource()) && !itr.GetSource()->IsAlive()) - { - pInstance->SetData(DATA_DANCE_FAIL, 0); - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - return; - } + instance->SetData(DATA_DANCE_FAIL, 0); + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); + return; } - events.Repeat(5s); - return; } + events.Repeat(5s); + return; + } } + DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index 2fab24707..e6f781e60 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -145,15 +145,10 @@ public: struct boss_kelthuzadAI : public BossAI { explicit boss_kelthuzadAI(Creature* c) : BossAI(c, BOSS_KELTHUZAD), summons(me) - { - pInstance = me->GetInstanceScript(); - _justSpawned = true; - } + {} EventMap events; SummonList summons; - InstanceScript* pInstance; - bool _justSpawned; float NormalizeOrientation(float o) { @@ -224,35 +219,23 @@ public: summons.DespawnAll(); me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); me->SetReactState(REACT_AGGRESSIVE); - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_FLOOR))) + if (GameObject* go = instance->GetGameObject(DATA_KELTHUZAD_FLOOR)) { go->SetPhaseMask(1, true); go->SetGoState(GO_STATE_READY); } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_GATE))) - { - if (!_justSpawned) // Don't open the door if we just spawned and are still doing the conversation - { - go->SetGoState(GO_STATE_ACTIVE); - } - } - _justSpawned = false; - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_PORTAL_1))) - { + + if (GameObject* go = instance->GetGameObject(DATA_KELTHUZAD_PORTAL_1)) go->SetGoState(GO_STATE_READY); - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_PORTAL_2))) - { + + if (GameObject* go = instance->GetGameObject(DATA_KELTHUZAD_PORTAL_2)) go->SetGoState(GO_STATE_READY); - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_PORTAL_3))) - { + + if (GameObject* go = instance->GetGameObject(DATA_KELTHUZAD_PORTAL_3)) go->SetGoState(GO_STATE_READY); - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_PORTAL_4))) - { + + if (GameObject* go = instance->GetGameObject(DATA_KELTHUZAD_PORTAL_4)) go->SetGoState(GO_STATE_READY); - } } void EnterEvadeMode(EvadeReason why) override @@ -267,10 +250,7 @@ public: return; Talk(SAY_SLAY); - if (pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustDied(Unit* killer) override @@ -282,13 +262,6 @@ public: guardian->AI()->Talk(EMOTE_GUARDIAN_FLEE); } Talk(SAY_DEATH); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } } void MoveInLineOfSight(Unit* who) override @@ -312,17 +285,11 @@ public: events.ScheduleEvent(EVENT_SUMMON_SOUL_WEAVER, 12s); events.ScheduleEvent(EVENT_PHASE_2, 228s); events.ScheduleEvent(EVENT_ENRAGE, 15min); - if (pInstance) + + if (GameObject* go = instance->GetGameObject(DATA_KELTHUZAD_FLOOR)) { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_FLOOR))) - { - events.ScheduleEvent(EVENT_FLOOR_CHANGE, 15s); - go->SetGoState(GO_STATE_ACTIVE); - } - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_GATE))) - { - go->SetGoState(GO_STATE_READY); + events.ScheduleEvent(EVENT_FLOOR_CHANGE, 15s); + go->SetGoState(GO_STATE_ACTIVE); } } @@ -354,14 +321,11 @@ public: switch (events.ExecuteEvent()) { case EVENT_FLOOR_CHANGE: - if (pInstance) + if (GameObject* go = instance->GetGameObject(DATA_KELTHUZAD_FLOOR)) { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_FLOOR))) - { - events.ScheduleEvent(EVENT_FLOOR_CHANGE, 15s); - go->SetGoState(GO_STATE_READY); - go->SetPhaseMask(2, true); - } + events.ScheduleEvent(EVENT_FLOOR_CHANGE, 15s); + go->SetGoState(GO_STATE_READY); + go->SetPhaseMask(2, true); } break; case EVENT_SPAWN_POOL: @@ -465,39 +429,32 @@ public: Talk(SAY_REQUEST_AID); events.DelayEvents(5500ms); events.ScheduleEvent(EVENT_P3_LICH_KING_SAY, 5s); - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_PORTAL_1))) - { + if (GameObject* go = instance->GetGameObject(DATA_KELTHUZAD_PORTAL_1)) go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_PORTAL_2))) - { + + if (GameObject* go = instance->GetGameObject(DATA_KELTHUZAD_PORTAL_2)) go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_PORTAL_3))) - { + + if (GameObject* go = instance->GetGameObject(DATA_KELTHUZAD_PORTAL_3)) go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_PORTAL_4))) - { + + if (GameObject* go = instance->GetGameObject(DATA_KELTHUZAD_PORTAL_4)) go->SetGoState(GO_STATE_ACTIVE); - } + break; } events.Repeat(1s); break; case EVENT_P3_LICH_KING_SAY: - if (pInstance) - { - if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_LICH_KING_BOSS))) - { - cr->AI()->Talk(SAY_ANSWER_REQUEST); - } - } + { + if (Creature* cr = instance->GetCreature(DATA_LICH_KING_BOSS)) + cr->AI()->Talk(SAY_ANSWER_REQUEST); + for (uint8 i = 0 ; i < RAID_MODE(2, 4); ++i) - { events.ScheduleEvent(EVENT_SUMMON_GUARDIAN_OF_ICECROWN, 10000 + (i * 5000)); - } + break; + } case EVENT_SUMMON_GUARDIAN_OF_ICECROWN: if (Creature* cr = me->SummonCreature(NPC_GUARDIAN_OF_ICECROWN, SpawnPool[RAND(0, 1, 3, 4)])) { @@ -573,10 +530,8 @@ public: void JustDied(Unit* /*killer*/) override { - if (me->GetEntry() == NPC_UNSTOPPABLE_ABOMINATION && me->GetInstanceScript()) - { + if (me->GetEntry() == NPC_UNSTOPPABLE_ABOMINATION) me->GetInstanceScript()->SetData(DATA_ABOMINATION_KILLED, 0); - } } void AttackStart(Unit* who) override @@ -618,10 +573,8 @@ public: void KilledUnit(Unit* who) override { - if (who->IsPlayer() && me->GetInstanceScript()) - { - me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0); - } + if (who->IsPlayer()) + me->GetInstanceScript()->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustReachedHome() override diff --git a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp index 52a0b4fe5..fe8d1589e 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp @@ -62,11 +62,9 @@ public: { explicit boss_loathebAI(Creature* c) : BossAI(c, BOSS_LOATHEB), summons(me) { - pInstance = me->GetInstanceScript(); me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); } - InstanceScript* pInstance; uint8 doomCounter; EventMap events; SummonList summons; @@ -77,14 +75,6 @@ public: events.Reset(); summons.DespawnAll(); doomCounter = 0; - if (pInstance) - { - pInstance->SetData(BOSS_LOATHEB, NOT_STARTED); - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_LOATHEB_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } } void JustSummoned(Creature* cr) override @@ -95,18 +85,13 @@ public: void SummonedCreatureDies(Creature* /*cr*/, Unit*) override { - if (pInstance) - { - pInstance->SetData(DATA_SPORE_KILLED, 0); - } + instance->SetData(DATA_SPORE_KILLED, 0); } void KilledUnit(Unit* who) override { - if (who->IsPlayer() && pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + if (who->IsPlayer()) + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustEngagedWith(Unit* who) override @@ -118,24 +103,12 @@ public: events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 2min); events.ScheduleEvent(EVENT_SUMMON_SPORE, 15s); events.ScheduleEvent(EVENT_BERSERK, 12min); - if (pInstance) - { - pInstance->SetData(BOSS_LOATHEB, IN_PROGRESS); - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_LOATHEB_GATE))) - { - go->SetGoState(GO_STATE_READY); - } - } } void JustDied(Unit* killer) override { BossAI::JustDied(killer); summons.DespawnAll(); - if (pInstance) - { - pInstance->SetData(BOSS_LOATHEB, DONE); - } } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp index eb4757c6f..76bf91ccb 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp @@ -106,11 +106,8 @@ public: struct boss_maexxnaAI : public BossAI { explicit boss_maexxnaAI(Creature* c) : BossAI(c, BOSS_MAEXXNA), summons(me) - { - pInstance = me->GetInstanceScript(); - } + {} - InstanceScript* pInstance; EventMap events; SummonList summons; @@ -131,10 +128,6 @@ public: BossAI::Reset(); events.Reset(); summons.DespawnAll(); - if (pInstance) - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_MAEXXNA_GATE))) - if (pInstance->GetBossState(BOSS_FAERLINA) == DONE) - go->SetGoState(GO_STATE_ACTIVE); } void JustEngagedWith(Unit* who) override @@ -147,13 +140,6 @@ public: events.ScheduleEvent(EVENT_NECROTIC_POISON, 5s); events.ScheduleEvent(EVENT_HEALTH_CHECK, 1s); events.ScheduleEvent(EVENT_SUMMON_SPIDERLINGS, 30s); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_MAEXXNA_GATE))) - { - go->SetGoState(GO_STATE_READY); - } - } } void JustSummoned(Creature* cr) override @@ -171,10 +157,8 @@ public: void KilledUnit(Unit* who) override { - if (who->IsPlayer() && pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + if (who->IsPlayer()) + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustDied(Unit* killer) override diff --git a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp index c461384fd..79045abcf 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp @@ -89,11 +89,8 @@ public: struct boss_nothAI : public BossAI { explicit boss_nothAI(Creature* c) : BossAI(c, BOSS_NOTH), summons(me) - { - pInstance = me->GetInstanceScript(); - } + {} - InstanceScript* pInstance; uint8 timesInBalcony; EventMap events; SummonList summons; @@ -151,13 +148,6 @@ public: me->SetControlled(false, UNIT_STATE_ROOT); me->SetReactState(REACT_AGGRESSIVE); timesInBalcony = 0; - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_NOTH_ENTRY_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } } void EnterEvadeMode(EvadeReason why) override @@ -171,13 +161,6 @@ public: BossAI::JustEngagedWith(who); Talk(SAY_AGGRO); StartGroundPhase(); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_NOTH_ENTRY_GATE))) - { - go->SetGoState(GO_STATE_READY); - } - } } void JustSummoned(Creature* summon) override @@ -195,13 +178,6 @@ public: } BossAI::JustDied(killer); Talk(SAY_DEATH); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_NOTH_ENTRY_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } } void KilledUnit(Unit* who) override @@ -210,10 +186,7 @@ public: return; Talk(SAY_SLAY); - if (pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp b/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp index aa61c5fb1..3342c9a23 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp @@ -63,12 +63,9 @@ public: struct boss_patchwerkAI : public BossAI { explicit boss_patchwerkAI(Creature* c) : BossAI(c, BOSS_PATCHWERK) - { - pInstance = me->GetInstanceScript(); - } + {} EventMap events; - InstanceScript* pInstance; void Reset() override { @@ -82,13 +79,9 @@ public: return; if (!urand(0, 3)) - { Talk(SAY_SLAY); - } - if (pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustDied(Unit* killer) override @@ -105,10 +98,7 @@ public: events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 1500ms); events.ScheduleEvent(EVENT_BERSERK, 6min); events.ScheduleEvent(EVENT_HEALTH_CHECK, 1s); - if (pInstance) - { - pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT); - } + instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp index b3cac8840..14f334245 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp @@ -82,13 +82,10 @@ public: struct boss_razuviousAI : public BossAI { explicit boss_razuviousAI(Creature* c) : BossAI(c, BOSS_RAZUVIOUS), summons(me) - { - pInstance = me->GetInstanceScript(); - } + {} EventMap events; SummonList summons; - InstanceScript* pInstance; void SpawnHelpers() { @@ -210,13 +207,10 @@ public: void KilledUnit(Unit* who) override { if (roll_chance_i(30)) - { Talk(SAY_SLAY); - } - if (who->IsPlayer() && pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + + if (who->IsPlayer()) + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override @@ -331,17 +325,16 @@ public: switch (action) { case ACTION_FACE_ME: + { scheduler.CancelGroup(GROUP_OOC_RP); me->SetSheath(SHEATH_STATE_UNARMED); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); - if (InstanceScript* instance = me->GetInstanceScript()) - { - if (Creature* creature = instance->GetCreature(DATA_RAZUVIOUS)) - { - me->SetFacingToObject(creature); - } - } + + if (Creature* creature = me->GetInstanceScript()->GetCreature(DATA_RAZUVIOUS_BOSS)) + me->SetFacingToObject(creature); + break; + } case ACTION_TALK: Talk(SAY_DEATH_KNIGHT_UNDERSTUDY); break; @@ -360,22 +353,18 @@ public: void KilledUnit(Unit* who) override { - if (who->IsPlayer() && me->GetInstanceScript()) - { - me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0); - } + if (who->IsPlayer()) + me->GetInstanceScript()->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustEngagedWith(Unit* who) override { scheduler.CancelGroup(GROUP_OOC_RP); - if (InstanceScript* instance = me->GetInstanceScript()) + + if (Creature* creature = me->GetInstanceScript()->GetCreature(DATA_RAZUVIOUS_BOSS)) { - if (Creature* creature = instance->GetCreature(DATA_RAZUVIOUS)) - { - creature->SetInCombatWithZone(); - creature->AI()->AttackStart(who); - } + creature->SetInCombatWithZone(); + creature->AI()->AttackStart(who); } } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp index 8ecc62f56..98717dcbb 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp @@ -92,12 +92,9 @@ public: struct boss_sapphironAI : public BossAI { explicit boss_sapphironAI(Creature* c) : BossAI(c, BOSS_SAPPHIRON) - { - pInstance = me->GetInstanceScript(); - } + {} EventMap events; - InstanceScript* pInstance; uint8 iceboltCount{}; uint32 spawnTimer{}; GuidList blockList; @@ -221,10 +218,8 @@ public: void KilledUnit(Unit* who) override { - if (who->IsPlayer() && pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + if (who->IsPlayer()) + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void UpdateAI(uint32 diff) override @@ -402,9 +397,9 @@ public: Map::PlayerList const& pList = me->GetMap()->GetPlayers(); for (auto const& itr : pList) { - if (itr.GetSource()->GetResistance(SPELL_SCHOOL_FROST) > 100 && pInstance) + if (itr.GetSource()->GetResistance(SPELL_SCHOOL_FROST) > 100) { - pInstance->SetData(DATA_HUNDRED_CLUB, 0); + instance->SetData(DATA_HUNDRED_CLUB, 0); return; } } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp index dd25921e9..cf953363d 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp @@ -123,11 +123,8 @@ public: struct boss_thaddiusAI : public BossAI { explicit boss_thaddiusAI(Creature* c) : BossAI(c, BOSS_THADDIUS), summons(me), ballLightningEnabled(false) - { - pInstance = me->GetInstanceScript(); - } + {} - InstanceScript* pInstance; EventMap events; SummonList summons; uint32 summonTimer{}; @@ -184,28 +181,15 @@ public: } if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_LEFT, 100.0f)) - { go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_RIGHT, 100.0f)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_THADDIUS_GATE))) - { - if (pInstance->GetBossState(BOSS_GLUTH) == DONE) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } - } - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_POLARITY); - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_STACK); - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_POLARITY); - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_STACK); + if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_RIGHT, 100.0f)) + go->SetGoState(GO_STATE_ACTIVE); + + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_POLARITY); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_STACK); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_POLARITY); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_STACK); } void KilledUnit(Unit* who) override @@ -214,27 +198,17 @@ public: return; Talk(SAY_SLAY); - if (pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustDied(Unit* killer) override { BossAI::JustDied(killer); Talk(SAY_DEATH); - if (pInstance) - { - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_POLARITY); - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_STACK); - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_POLARITY); - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_STACK); - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_THADDIUS_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_POLARITY); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_STACK); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_POLARITY); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_STACK); } void JustSummoned(Creature* cr) override @@ -384,11 +358,9 @@ public: { explicit boss_thaddius_summonAI(Creature* c) : ScriptedAI(c) { - pInstance = me->GetInstanceScript(); overload = false; } - InstanceScript* pInstance; EventMap events; uint32 pullTimer{}; uint32 visualTimer{}; @@ -439,17 +411,11 @@ public: { events.ScheduleEvent(EVENT_MINION_MAGNETIC_PULL, 20s); } - if (pInstance) + + if (Creature* cr = me->GetInstanceScript()->GetCreature(DATA_THADDIUS_BOSS)) { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_THADDIUS_GATE))) - { - go->SetGoState(GO_STATE_READY); - } - if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_THADDIUS_BOSS))) - { - cr->AI()->AttackStart(pWho); - cr->AddThreat(pWho, 10.0f); - } + cr->AI()->AttackStart(pWho); + cr->AddThreat(pWho, 10.0f); } } @@ -479,13 +445,9 @@ public: { Talk(me->GetEntry() == NPC_STALAGG ? SAY_STAL_DEATH : SAY_FEUG_DEATH); Talk(me->GetEntry() == NPC_STALAGG ? EMOTE_STAL_DEATH : EMOTE_FEUG_DEATH); - if (pInstance) - { - if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_THADDIUS_BOSS))) - { - cr->AI()->DoAction(ACTION_SUMMON_DIED); - } - } + + if (Creature* cr = me->GetInstanceScript()->GetCreature(DATA_THADDIUS_BOSS)) + cr->AI()->DoAction(ACTION_SUMMON_DIED); } void KilledUnit(Unit* who) override @@ -493,14 +455,10 @@ public: if (!who->IsPlayer()) return; - if (pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } if (!urand(0, 2)) - { Talk(me->GetEntry() == NPC_STALAGG ? SAY_STAL_SLAY : SAY_FEUG_SLAY); - } + + me->GetInstanceScript()->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void UpdateAI(uint32 diff) override @@ -547,31 +505,30 @@ public: events.Repeat(3s); break; case EVENT_MINION_MAGNETIC_PULL: + { events.Repeat(20s); - if (pInstance) + if (Creature* feugen = me->GetInstanceScript()->GetCreature(DATA_FEUGEN_BOSS)) { - if (Creature* feugen = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_FEUGEN_BOSS))) - { - if (!feugen->IsAlive() || !feugen->GetVictim() || !me->GetVictim()) - return; + if (!feugen->IsAlive() || !feugen->GetVictim() || !me->GetVictim()) + return; - float threatFeugen = feugen->GetThreatMgr().GetThreat(feugen->GetVictim()); - float threatStalagg = me->GetThreatMgr().GetThreat(me->GetVictim()); - Unit* tankFeugen = feugen->GetVictim(); - Unit* tankStalagg = me->GetVictim(); + float threatFeugen = feugen->GetThreatMgr().GetThreat(feugen->GetVictim()); + float threatStalagg = me->GetThreatMgr().GetThreat(me->GetVictim()); + Unit* tankFeugen = feugen->GetVictim(); + Unit* tankStalagg = me->GetVictim(); - feugen->GetThreatMgr().ModifyThreatByPercent(tankFeugen, -100); - feugen->AddThreat(tankStalagg, threatFeugen); - feugen->CastSpell(tankStalagg, SPELL_MAGNETIC_PULL, true); - feugen->AI()->DoAction(ACTION_MAGNETIC_PULL); + feugen->GetThreatMgr().ModifyThreatByPercent(tankFeugen, -100); + feugen->AddThreat(tankStalagg, threatFeugen); + feugen->CastSpell(tankStalagg, SPELL_MAGNETIC_PULL, true); + feugen->AI()->DoAction(ACTION_MAGNETIC_PULL); - me->GetThreatMgr().ModifyThreatByPercent(tankStalagg, -100); - me->AddThreat(tankFeugen, threatStalagg); - me->CastSpell(tankFeugen, SPELL_MAGNETIC_PULL, true); - DoAction(ACTION_MAGNETIC_PULL); - } + me->GetThreatMgr().ModifyThreatByPercent(tankStalagg, -100); + me->AddThreat(tankFeugen, threatStalagg); + me->CastSpell(tankFeugen, SPELL_MAGNETIC_PULL, true); + DoAction(ACTION_MAGNETIC_PULL); } break; + } case EVENT_MINION_CHECK_DISTANCE: if (Creature* cr = ObjectAccessor::GetCreature(*me, myCoil)) { @@ -652,9 +609,9 @@ class spell_thaddius_pos_neg_charge : public SpellScript { SetHitDamage(0); } - else if (target->GetInstanceScript()) + else if (InstanceScript* instance = target->GetInstanceScript()) { - target->GetInstanceScript()->SetData(DATA_CHARGES_CROSSED, 0); + instance->SetData(DATA_CHARGES_CROSSED, 0); } } @@ -736,15 +693,13 @@ public: bool OnTrigger(Player* player, AreaTrigger const* /*areaTrigger*/) override { InstanceScript* instance = player->GetInstanceScript(); - if (!instance || instance->GetData(DATA_HAD_THADDIUS_GREET) || instance->GetBossState(BOSS_THADDIUS) == DONE) + if (!instance || instance->GetData(DATA_THADDIUS_INTRO) || instance->GetBossState(BOSS_THADDIUS) == DONE) return true; - if (Creature* thaddius = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_THADDIUS_BOSS))) - { + if (Creature* thaddius = instance->GetCreature(DATA_THADDIUS_BOSS)) thaddius->AI()->Talk(SAY_GREET); - } - instance->SetData(DATA_HAD_THADDIUS_GREET, 1); + instance->SetData(DATA_THADDIUS_INTRO, 1); return true; } }; diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index a72a33e29..f116047d8 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -17,1250 +17,748 @@ #include "AreaTriggerScript.h" #include "CellImpl.h" +#include "CreatureAIImpl.h" #include "CreatureScript.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" #include "InstanceMapScript.h" +#include "InstanceScript.h" #include "PassiveAI.h" -#include "ScriptedCreature.h" +#include "Player.h" #include "naxxramas.h" -static constexpr uint8 HorsemanCount = 4; +struct LivingPoisonData +{ + Position Start {}; + Position End {}; + uint32 DespawnTime {}; +}; -const float HeiganPos[2] = {2796, -3707}; -const float HeiganEruptionSlope[3] = +static const LivingPoisonData LivingPoisonDataList[3] +{ + { Position { 3128.59, -3118.81, 293.346, 4.76754 }, Position { 3130.322, -3156.51, 293.324 }, 15200 }, + { Position { 3154.25, -3125.7, 293.43, 4.47694 }, Position { 3144.779, -3158.416, 293.324 }, 14800 }, + { Position { 3175.42, -3134.86, 293.34, 4.284 }, Position { 3158.778, -3164.201, 293.312 }, 14800 } +}; + +static const float HeiganPos[2] +{ + 2796, -3707 +}; + +static const float HeiganEruptionSlope[3] { (-3685 - HeiganPos[1]) / (2724 - HeiganPos[0]), (-3647 - HeiganPos[1]) / (2749 - HeiganPos[0]), (-3637 - HeiganPos[1]) / (2771 - HeiganPos[0]), }; -inline uint8 GetEruptionSection(float x, float y) +static constexpr std::array HorsemanDataGroup { - y -= HeiganPos[1]; - if (y < 1.0f) - return 0; - - x -= HeiganPos[0]; - if (x > -1.0f) - return 3; - - float slope = y / x; - for (uint32 i = 0; i < 3; ++i) - { - if (slope > HeiganEruptionSlope[i]) - return i; - } - return 3; -} - -DoorData const doorData[] = -{ - { GO_ANUB_GATE, BOSS_ANUB, DOOR_TYPE_ROOM }, - { 0, 0, DOOR_TYPE_ROOM }, + DATA_BARON_RIVENDARE_BOSS, + DATA_SIR_ZELIEK_BOSS, + DATA_LADY_BLAUMEUX_BOSS, + DATA_THANE_KORTHAZZ_BOSS }; -ObjectData const creatureData[] = +static WorldLocation const SapphironTeleportPos { - { NPC_RAZUVIOUS, DATA_RAZUVIOUS }, - { 0, 0 } + NaxxramasMapId, 3498.300049f, -5349.490234f, 144.968002f, 1.3698910f }; -ObjectData const gameObjectData[] = +static DoorData const doorData[] { - { 0, 0 } + { GO_PATCHWERK_GATE, BOSS_PATCHWERK, DOOR_TYPE_PASSAGE }, + { GO_PATCHWERK_GATE, BOSS_GROBBULUS, DOOR_TYPE_ROOM }, + { GO_GLUTH_GATE, BOSS_GLUTH, DOOR_TYPE_PASSAGE }, + { GO_THADDIUS_GATE, BOSS_GLUTH, DOOR_TYPE_PASSAGE }, + { GO_NOTH_ENTRY_GATE, BOSS_NOTH, DOOR_TYPE_ROOM }, + { GO_NOTH_EXIT_GATE, BOSS_NOTH, DOOR_TYPE_PASSAGE }, + { GO_HEIGAN_ENTRY_GATE, BOSS_NOTH, DOOR_TYPE_PASSAGE }, + { GO_HEIGAN_ENTRY_GATE, BOSS_HEIGAN, DOOR_TYPE_ROOM }, + { GO_HEIGAN_EXIT_GATE, BOSS_HEIGAN, DOOR_TYPE_PASSAGE }, + { GO_LOATHEB_GATE, BOSS_HEIGAN, DOOR_TYPE_PASSAGE }, + { GO_LOATHEB_GATE, BOSS_LOATHEB, DOOR_TYPE_ROOM }, + { GO_PLAGUE_EYE_PORTAL, BOSS_LOATHEB, DOOR_TYPE_PASSAGE }, + { GO_PLAG_EYE_RAMP_BOSS, BOSS_LOATHEB, DOOR_TYPE_PASSAGE }, + { GO_ANUB_GATE, BOSS_ANUB, DOOR_TYPE_ROOM }, + { GO_ANUB_NEXT_GATE, BOSS_ANUB, DOOR_TYPE_PASSAGE }, + { GO_FAERLINA_WEB, BOSS_FAERLINA, DOOR_TYPE_ROOM }, + { GO_FAERLINA_GATE, BOSS_FAERLINA, DOOR_TYPE_PASSAGE }, + { GO_MAEXXNA_GATE, BOSS_FAERLINA, DOOR_TYPE_PASSAGE }, + { GO_MAEXXNA_GATE, BOSS_MAEXXNA, DOOR_TYPE_ROOM }, + { GO_SPIDER_EYE_PORTAL, BOSS_MAEXXNA, DOOR_TYPE_PASSAGE }, + { GO_ARAC_EYE_RAMP_BOSS, BOSS_MAEXXNA, DOOR_TYPE_PASSAGE }, + { GO_THADDIUS_GATE, BOSS_THADDIUS, DOOR_TYPE_ROOM }, + { GO_ABOM_EYE_PORTAL, BOSS_THADDIUS, DOOR_TYPE_PASSAGE }, + { GO_CONS_EYE_RAMP_BOSS, BOSS_THADDIUS, DOOR_TYPE_PASSAGE }, + { GO_GOTHIK_ENTER_GATE, BOSS_GOTHIK, DOOR_TYPE_ROOM }, + { GO_GOTHIK_INNER_GATE, BOSS_GOTHIK, DOOR_TYPE_ROOM }, + { GO_GOTHIK_EXIT_GATE, BOSS_GOTHIK, DOOR_TYPE_PASSAGE }, + { GO_HORSEMEN_GATE, BOSS_GOTHIK, DOOR_TYPE_PASSAGE }, + { GO_HORSEMEN_GATE, BOSS_HORSEMAN, DOOR_TYPE_ROOM }, + { GO_DEATHKNIGHT_EYE_PORTAL, BOSS_HORSEMAN, DOOR_TYPE_PASSAGE }, + { GO_MILI_EYE_RAMP_BOSS, BOSS_HORSEMAN, DOOR_TYPE_PASSAGE }, + { GO_KELTHUZAD_GATE, BOSS_KELTHUZAD, DOOR_TYPE_ROOM }, + { 0, 0, DOOR_TYPE_ROOM } }; -class instance_naxxramas : public InstanceMapScript +static ObjectData const creatureData[] +{ + { NPC_PATCHWERK, DATA_PATCHWERK_BOSS }, + { NPC_STALAGG, DATA_STALAGG_BOSS }, + { NPC_FEUGEN, DATA_FEUGEN_BOSS }, + { NPC_THADDIUS, DATA_THADDIUS_BOSS }, + { NPC_RAZUVIOUS, DATA_RAZUVIOUS_BOSS }, + { NPC_GOTHIK, DATA_GOTHIK_BOSS }, + { NPC_BARON_RIVENDARE, DATA_BARON_RIVENDARE_BOSS }, + { NPC_SIR_ZELIEK, DATA_SIR_ZELIEK_BOSS }, + { NPC_LADY_BLAUMEUX, DATA_LADY_BLAUMEUX_BOSS }, + { NPC_THANE_KORTHAZZ, DATA_THANE_KORTHAZZ_BOSS }, + { NPC_SAPPHIRON, DATA_SAPPHIRON_BOSS }, + { NPC_KELTHUZAD, DATA_KELTHUZAD_BOSS }, + { NPC_LICH_KING, DATA_LICH_KING_BOSS }, + { 0, 0 } +}; + +static ObjectData const gameObjectData[] +{ + { GO_GOTHIK_INNER_GATE, DATA_GOTHIK_INNER_GATE }, + { GO_LOATHEB_PORTAL, DATA_LOATHEB_PORTAL }, + { GO_MAEXXNA_PORTAL, DATA_MAEXXNA_PORTAL }, + { GO_THADDIUS_PORTAL, DATA_THADDIUS_PORTAL }, + { GO_HORSEMAN_PORTAL, DATA_HORSEMAN_PORTAL }, + { GO_SAPPHIRON_GATE, DATA_SAPPHIRON_GATE }, + { GO_KELTHUZAD_FLOOR, DATA_KELTHUZAD_FLOOR }, + { GO_KELTHUZAD_GATE, DATA_KELTHUZAD_GATE }, + { GO_KELTHUZAD_PORTAL_1, DATA_KELTHUZAD_PORTAL_1 }, + { GO_KELTHUZAD_PORTAL_2, DATA_KELTHUZAD_PORTAL_2 }, + { GO_KELTHUZAD_PORTAL_3, DATA_KELTHUZAD_PORTAL_3 }, + { GO_KELTHUZAD_PORTAL_4, DATA_KELTHUZAD_PORTAL_4 }, + { 0, 0 } +}; + +class instance_naxxramas : public InstanceScript { public: - instance_naxxramas() : InstanceMapScript("instance_naxxramas", 533) { } - - InstanceScript* GetInstanceScript(InstanceMap* pMap) const override + instance_naxxramas(Map* map) : InstanceScript(map) { - return new instance_naxxramas_InstanceMapScript(pMap); - } + SetHeaders(DataHeader); + SetBossNumber(MAX_ENCOUNTERS); + SetPersistentDataCount(PERSISTENT_DATA_COUNT); + LoadDoorData(doorData); + LoadObjectData(creatureData, gameObjectData); - struct instance_naxxramas_InstanceMapScript : public InstanceScript - { - explicit instance_naxxramas_InstanceMapScript(Map* pMap) : InstanceScript(pMap) - { - SetHeaders(DataHeader); - SetBossNumber(MAX_ENCOUNTERS); - LoadDoorData(doorData); - LoadObjectData(creatureData, gameObjectData); - for (auto& i : HeiganEruption) - i.clear(); - - // NPCs - PatchwerkRoomTrash.clear(); - - // Controls - _speakTimer = 0; - _horsemanTimer = 0; - _screamTimer = 2 * MINUTE * IN_MILLISECONDS; - _hadThaddiusGreet = false; - _currentWingTaunt = SAY_FIRST_WING_TAUNT; - _currentHorsemenLine = 0; - - // Achievements - abominationsKilled = 0; - faerlinaAchievement = true; - thaddiusAchievement = true; - loathebAchievement = true; - sapphironAchievement = true; - heiganAchievement = true; - immortalAchievement = 1; - } - - std::set HeiganEruption[4]; - - // GOs - ObjectGuid _patchwerkGateGUID; - ObjectGuid _gluthGateGUID; - ObjectGuid _nothEntryGateGUID; - ObjectGuid _nothExitGateGUID; - ObjectGuid _heiganGateGUID; - ObjectGuid _heiganGateExitGUID; - ObjectGuid _loathebGateGUID; - ObjectGuid _anubNextGateGUID; - ObjectGuid _faerlinaWebGUID; - ObjectGuid _faerlinaGateGUID; - ObjectGuid _maexxnaGateGUID; - ObjectGuid _thaddiusGateGUID; - ObjectGuid _gothikEnterGateGUID; - ObjectGuid _gothikInnerGateGUID; - ObjectGuid _gothikExitGateGUID{}; - ObjectGuid _horsemanGateGUID; - ObjectGuid _kelthuzadFloorGUID; - ObjectGuid _kelthuzadGateGUID; - ObjectGuid _kelthuzadPortal1GUID; - ObjectGuid _kelthuzadPortal2GUID; - ObjectGuid _kelthuzadPortal3GUID; - ObjectGuid _kelthuzadPortal4GUID; - ObjectGuid _sapphironGateGUID; - ObjectGuid _horsemanPortalGUID; - ObjectGuid _loathebPortalGUID; - ObjectGuid _maexxnaPortalGUID; - ObjectGuid _thaddiusPortalGUID; - ObjectGuid _deathknightEyePortalGUID; - ObjectGuid _plagueEyePortalGUID; - ObjectGuid _spiderEyePortalGUID; - ObjectGuid _abomEyePortalGUID; - ObjectGuid _deathknightGlowEyePortalGUID; - ObjectGuid _plagueGlowEyePortalGUID; - ObjectGuid _spiderGlowEyePortalGUID; - ObjectGuid _abomGlowEyePortalGUID; + // GameObjects + for (auto& i : _heiganEruption) + i.clear(); // NPCs - GuidList PatchwerkRoomTrash; - ObjectGuid _patchwerkGUID; - ObjectGuid _thaddiusGUID; - ObjectGuid _gothikGUID; - ObjectGuid _stalaggGUID; - ObjectGuid _feugenGUID; - ObjectGuid _zeliekGUID; - ObjectGuid _rivendareGUID; - ObjectGuid _blaumeuxGUID; - ObjectGuid _korthazzGUID; - ObjectGuid _sapphironGUID; - ObjectGuid _kelthuzadGUID; - ObjectGuid _lichkingGUID; + _patchwerkRoomTrash.clear(); // Controls - uint32 _speakTimer; - uint32 _horsemanTimer; - uint32 _screamTimer; - bool _hadThaddiusGreet; - EventMap events; - uint8 _currentWingTaunt; - uint8 _currentHorsemenLine; - uint8 _horsemanLoaded; + _events.Reset(); + _currentWingTaunt = SAY_FIRST_WING_TAUNT; + _horsemanLoaded = 0; // Achievements - uint8 abominationsKilled; - bool faerlinaAchievement; - bool thaddiusAchievement; - bool loathebAchievement; - bool sapphironAchievement; - bool heiganAchievement; - uint32 immortalAchievement; + _abominationsKilled = 0; + _faerlinaAchievement = true; + _thaddiusAchievement = true; + _loathebAchievement = true; + _heiganAchievement = true; + _sapphironAchievement = true; + _horsemanAchievement = true; + } - void HeiganEruptSections(uint32 section) - { - for (uint8 i = 0; i < 4; ++i) - { - if (i == section) - continue; + inline void CreatureTalk(uint32 dataCreature, uint8 dialog) + { + if (Creature* creature = GetCreature(dataCreature)) + creature->AI()->Talk(dialog); + } - for (auto itr : HeiganEruption[i]) - { - itr->SendCustomAnim(itr->GetGoAnimProgress()); - itr->CastSpell(nullptr, SPELL_ERUPTION); - } - } - } + inline void SetGoState(uint32 dataGameObject, GOState state) + { + if (GameObject* go = GetGameObject(dataGameObject)) + go->SetGoState(state); + } - bool IsEncounterInProgress() const override - { - for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i) - { - if (GetBossState(i) == IN_PROGRESS) - return true; - } - return false; - } + inline void ActivateWingPortal(GameObject* go, EncounterState state) + { + if (!go || state != DONE) + return; - void OnCreatureCreate(Creature* creature) override - { - switch (creature->GetEntry()) - { - case NPC_PATCHWERK: - _patchwerkGUID = creature->GetGUID(); - return; - case NPC_PATCHWORK_GOLEM: - PatchwerkRoomTrash.push_back(creature->GetGUID()); - return; - case NPC_BILE_RETCHER: - if (creature->GetPositionY() > -3258.0f) // we want only those inside the room, not before - PatchwerkRoomTrash.push_back(creature->GetGUID()); - return; - case NPC_SLUDGE_BELCHER: - if (creature->GetPositionY() > -3258.0f) // we want only those inside the room, not before - PatchwerkRoomTrash.push_back(creature->GetGUID()); - return; - case NPC_MAD_SCIENTIST: - PatchwerkRoomTrash.push_back(creature->GetGUID()); - return; - case NPC_LIVING_MONSTROSITY: - PatchwerkRoomTrash.push_back(creature->GetGUID()); - return; - case NPC_SURGICAL_ASSIST: - PatchwerkRoomTrash.push_back(creature->GetGUID()); - return; - case NPC_THADDIUS: - _thaddiusGUID = creature->GetGUID(); - return; - case NPC_STALAGG: - _stalaggGUID = creature->GetGUID(); - return; - case NPC_FEUGEN: - _feugenGUID = creature->GetGUID(); - return; - case NPC_GOTHIK: - _gothikGUID = creature->GetGUID(); - return; - case NPC_LADY_BLAUMEUX: - _blaumeuxGUID = creature->GetGUID(); - ++_horsemanLoaded; - return; - case NPC_SIR_ZELIEK: - _zeliekGUID = creature->GetGUID(); - ++_horsemanLoaded; - return; - case NPC_BARON_RIVENDARE: - _rivendareGUID = creature->GetGUID(); - ++_horsemanLoaded; - return; - case NPC_THANE_KORTHAZZ: - _korthazzGUID = creature->GetGUID(); - ++_horsemanLoaded; - return; - case NPC_SAPPHIRON: - _sapphironGUID = creature->GetGUID(); - return; - case NPC_KELTHUZAD: - _kelthuzadGUID = creature->GetGUID(); - return; - case NPC_LICH_KING: - _lichkingGUID = creature->GetGUID(); - return; - } + go->SetGoState(GO_STATE_ACTIVE); + go->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); + } - if (_horsemanLoaded == HorsemanCount) - SetBossState(BOSS_HORSEMAN, GetBossState(BOSS_HORSEMAN)); - - InstanceScript::OnCreatureCreate(creature); - } - - void OnGameObjectCreate(GameObject* pGo) override - { - if (pGo->GetGOInfo()->displayId == 6785 || pGo->GetGOInfo()->displayId == 1287) - { - HeiganEruption[GetEruptionSection(pGo->GetPositionX(), pGo->GetPositionY())].insert(pGo); - return; - } - - switch (pGo->GetEntry()) - { - case GO_PATCHWERK_GATE: - _patchwerkGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_PATCHWERK) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_GLUTH_GATE: - _gluthGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_GLUTH) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_NOTH_ENTRY_GATE: - _nothEntryGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_NOTH) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_NOTH_EXIT_GATE: - _nothExitGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_NOTH) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_HEIGAN_ENTRY_GATE: - _heiganGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_HEIGAN) == DONE || GetBossState(BOSS_NOTH) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_HEIGAN_EXIT_GATE: - _heiganGateExitGUID = pGo->GetGUID(); - if (GetBossState(BOSS_HEIGAN) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_LOATHEB_GATE: - _loathebGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_LOATHEB) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_ANUB_NEXT_GATE: - _anubNextGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_ANUB) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_FAERLINA_GATE: - _faerlinaGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_FAERLINA) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_FAERLINA_WEB: - _faerlinaWebGUID = pGo->GetGUID(); - if (GetBossState(BOSS_FAERLINA) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_MAEXXNA_GATE: - _maexxnaGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_FAERLINA) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_THADDIUS_GATE: - _thaddiusGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_GLUTH) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_GOTHIK_ENTER_GATE: - _gothikEnterGateGUID = pGo->GetGUID(); - break; - case GO_GOTHIK_INNER_GATE: - _gothikInnerGateGUID = pGo->GetGUID(); - break; - case GO_GOTHIK_EXIT_GATE: - _gothikExitGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_GOTHIK) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_HORSEMEN_GATE: - _horsemanGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_GOTHIK) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_KELTHUZAD_FLOOR: - _kelthuzadFloorGUID = pGo->GetGUID(); - break; - case GO_KELTHUZAD_GATE: - _kelthuzadGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_SAPPHIRON) == DONE && _speakTimer == 0) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_KELTHUZAD_PORTAL_1: - _kelthuzadPortal1GUID = pGo->GetGUID(); - break; - case GO_KELTHUZAD_PORTAL_2: - _kelthuzadPortal2GUID = pGo->GetGUID(); - break; - case GO_KELTHUZAD_PORTAL_3: - _kelthuzadPortal3GUID = pGo->GetGUID(); - break; - case GO_KELTHUZAD_PORTAL_4: - _kelthuzadPortal4GUID = pGo->GetGUID(); - break; - case GO_SAPPHIRON_GATE: - _sapphironGateGUID = pGo->GetGUID(); - if (GetBossState(BOSS_SAPPHIRON) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_LOATHEB_PORTAL: - _loathebPortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_LOATHEB) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - pGo->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - } - break; - case GO_THADDIUS_PORTAL: - _thaddiusPortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_THADDIUS) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - pGo->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - } - break; - case GO_MAEXXNA_PORTAL: - _maexxnaPortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_MAEXXNA) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - pGo->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - } - break; - case GO_HORSEMAN_PORTAL: - _horsemanPortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_HORSEMAN) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - pGo->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - } - break; - - // Glow portals at center-side - case GO_DEATHKNIGHT_EYE_PORTAL: - _deathknightEyePortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_HORSEMAN) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_PLAGUE_EYE_PORTAL: - _plagueEyePortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_LOATHEB) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_SPIDER_EYE_PORTAL: - _spiderEyePortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_MAEXXNA) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_ABOM_EYE_PORTAL: - _abomEyePortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_THADDIUS) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - - // Glow portals at boss-side - case GO_MILI_EYE_RAMP_BOSS: - _deathknightGlowEyePortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_HORSEMAN) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_PLAG_EYE_RAMP_BOSS: - _plagueGlowEyePortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_LOATHEB) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_ARAC_EYE_RAMP_BOSS: - _spiderGlowEyePortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_MAEXXNA) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - case GO_CONS_EYE_RAMP_BOSS: - _abomGlowEyePortalGUID = pGo->GetGUID(); - if (GetBossState(BOSS_THADDIUS) == DONE) - { - pGo->SetGoState(GO_STATE_ACTIVE); - } - break; - } - - InstanceScript::OnGameObjectCreate(pGo); - } - - void OnGameObjectRemove(GameObject* pGo) override - { - if (pGo->GetGOInfo()->displayId == 6785 || pGo->GetGOInfo()->displayId == 1287) - { - uint32 section = GetEruptionSection(pGo->GetPositionX(), pGo->GetPositionY()); - HeiganEruption[section].erase(pGo); - return; - } - if (pGo->GetEntry() == GO_SAPPHIRON_BIRTH) - { - if (Creature* cr = instance->GetCreature(_sapphironGUID)) - { - cr->AI()->DoAction(ACTION_SAPPHIRON_BIRTH); - } - } - } - - bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/) override - { - switch (criteria_id) - { - case 7600: // And They Would All Go Down Together (10 player) - case 7601: // And They Would All Go Down Together (25 player) - return (_horsemanTimer < 15 * IN_MILLISECONDS); - case 7614: // Just Can't Get Enough (10 player) - case 7615: // Just Can't Get Enough (25 player) - return abominationsKilled >= 18; - case 7265: // Momma Said Knock You Out (10 player) - case 7549: // Momma Said Knock You Out (25 player) - return faerlinaAchievement; - case 7604: // Shocking! (10 player) - case 7605: // Shocking! (25 player) - return thaddiusAchievement; - case 7612: // Spore Loser (10 player) - case 7613: // Spore Loser (25 player) - return loathebAchievement; - case 7264: // The Safety Dance (10 player) - case 7548: // The Safety Dance (25 player) - return heiganAchievement; - case 7608: // Subtraction (10 player) - // The Dedicated few (10 player) - case 6802: - case 7146: - case 7147: - case 7148: - case 7149: - case 7150: - case 7151: - case 7152: - case 7153: - case 7154: - case 7155: - case 7156: - case 7157: - case 7158: - return (instance->GetPlayersCountExceptGMs() < 9); - case 7609: // Subtraction (25 player) - // The Dedicated few (25 player) - case 7159: - case 7160: - case 7161: - case 7162: - case 7163: - case 7164: - case 7165: - case 7166: - case 7167: - case 7168: - case 7169: - case 7170: - case 7171: - case 7172: - return (instance->GetPlayersCountExceptGMs() < 21); - case 7567: // The Hundred Club (10 player) - case 7568: // The Hundred Club (25 player) - return sapphironAchievement; - // The Undying - case 7617: - case 13237: - case 13238: - case 13239: - case 13240: - // The Immortal - case 7616: - case 13233: - case 13234: - case 13235: - case 13236: - { - uint8 count = 0; - for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i) - { - if (GetBossState(i) == NOT_STARTED) - ++count; - } - return !count && immortalAchievement; - } - - default: - return false; - } - } - - void SetData(uint32 id, uint32 data) override - { - switch (id) - { - case DATA_ABOMINATION_KILLED: - abominationsKilled++; - return; - case DATA_FRENZY_REMOVED: - faerlinaAchievement = false; - return; - case DATA_CHARGES_CROSSED: - thaddiusAchievement = false; - return; - case DATA_SPORE_KILLED: - loathebAchievement = false; - return; - case DATA_HUNDRED_CLUB: - sapphironAchievement = false; - return; - case DATA_DANCE_FAIL: - heiganAchievement = false; - return; - case DATA_IMMORTAL_FAIL: - immortalAchievement = 0; - SaveToDB(); - return; - case DATA_HEIGAN_ERUPTION: - HeiganEruptSections(data); - return; - case DATA_HAD_THADDIUS_GREET: - _hadThaddiusGreet = (data == 1); - default: - return; - } - } - - uint32 GetData(uint32 id) const override - { - if (id == DATA_HAD_THADDIUS_GREET && _hadThaddiusGreet) - return 1; + inline void ActivateWingPortal(uint32 wingPortal) + { + ActivateWingPortal(GetGameObject(wingPortal), DONE); + _events.RescheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6s); + } + static inline uint8 GetEruptionSection(float x, float y) + { + y -= HeiganPos[1]; + if (y < 1.0f) return 0; + + x -= HeiganPos[0]; + if (x > -1.0f) + return 3; + + float slope = y / x; + for (uint32 i = 0; i < 3; ++i) + if (slope > HeiganEruptionSlope[i]) + return i; + + return 3; + } + + inline void HeiganEruptSections(uint32 section) + { + for (uint8 i = 0; i < HeiganEruptSectionCount; ++i) + { + if (i == section) + continue; + + for (GameObject* go : _heiganEruption[i]) + { + go->SendCustomAnim(go->GetGoAnimProgress()); + go->CastSpell(nullptr, SPELL_ERUPTION); + } + } + } + + void OnPlayerEnter(Player* player) override + { + InstanceScript::OnPlayerEnter(player); + + _events.ScheduleEvent(EVENT_THADDIUS_SCREAMS, 2min, 2min + 30s); + } + + void OnCreatureCreate(Creature* creature) override + { + switch (creature->GetEntry()) + { + case NPC_LIVING_MONSTROSITY: + case NPC_MAD_SCIENTIST: + case NPC_PATCHWORK_GOLEM: + case NPC_SURGICAL_ASSIST: + _patchwerkRoomTrash.push_back(creature->GetGUID()); + return; + case NPC_BILE_RETCHER: + case NPC_SLUDGE_BELCHER: + if (creature->GetPositionY() > -3258.0f) // we want only those inside the room, not before + _patchwerkRoomTrash.push_back(creature->GetGUID()); + return; + case NPC_BARON_RIVENDARE: + case NPC_SIR_ZELIEK: + case NPC_LADY_BLAUMEUX: + case NPC_THANE_KORTHAZZ: + if (++_horsemanLoaded == HorsemanCount) + SetBossState(BOSS_HORSEMAN, GetBossState(BOSS_HORSEMAN)); + break; + default: + break; } - bool SetBossState(uint32 bossId, EncounterState state) override + InstanceScript::OnCreatureCreate(creature); + } + + void OnGameObjectCreate(GameObject* go) override + { + switch (go->GetGOInfo()->displayId) { - // pull all the trash if not killed - if (bossId == BOSS_PATCHWERK && state == IN_PROGRESS) - { - if (Creature* patch = instance->GetCreature(_patchwerkGUID)) - { - for (auto& itr : PatchwerkRoomTrash) - { - Creature* trash = ObjectAccessor::GetCreature(*patch, itr); - if (trash && trash->IsAlive() && !trash->IsInCombat()) - { - trash->AI()->AttackStart(patch->GetVictim()); - } - } - } - } + case GO_DISPLAY_ID_HEIGAN_ERUPTION1: + case GO_DISPLAY_ID_HEIGAN_ERUPTION2: + _heiganEruption[GetEruptionSection(go->GetPositionX(), go->GetPositionY())].insert(go); + break; + default: + break; + } - // Horseman handling - if (bossId == BOSS_HORSEMAN && _horsemanLoaded == HorsemanCount) - { - uint8 horsemanKilled {}; - if (Creature* cr = instance->GetCreature(_blaumeuxGUID)) - horsemanKilled += !cr->IsAlive(); + switch (go->GetEntry()) + { + case GO_SAPPHIRON_GATE: + if (GetBossState(BOSS_SAPPHIRON) == DONE) + go->SetGoState(GO_STATE_ACTIVE); + break; + case GO_LOATHEB_PORTAL: + ActivateWingPortal(go, GetBossState(BOSS_LOATHEB)); + break; + case GO_THADDIUS_PORTAL: + ActivateWingPortal(go, GetBossState(BOSS_THADDIUS)); + break; + case GO_MAEXXNA_PORTAL: + ActivateWingPortal(go, GetBossState(BOSS_MAEXXNA)); + break; + case GO_HORSEMAN_PORTAL: + ActivateWingPortal(go, GetBossState(BOSS_HORSEMAN)); + break; + default: + break; + } - if (Creature* cr = instance->GetCreature(_rivendareGUID)) - horsemanKilled += !cr->IsAlive(); + InstanceScript::OnGameObjectCreate(go); + } - if (Creature* cr = instance->GetCreature(_zeliekGUID)) - horsemanKilled += !cr->IsAlive(); + void OnGameObjectRemove(GameObject* go) override + { + switch (go->GetGOInfo()->displayId) + { + case GO_DISPLAY_ID_HEIGAN_ERUPTION1: + case GO_DISPLAY_ID_HEIGAN_ERUPTION2: + _heiganEruption[GetEruptionSection(go->GetPositionX(), go->GetPositionY())].erase(go); + break; + default: + break; + } - if (Creature* cr = instance->GetCreature(_korthazzGUID)) - horsemanKilled += !cr->IsAlive(); + switch (go->GetEntry()) + { + case GO_SAPPHIRON_BIRTH: + if (Creature* cr = GetCreature(DATA_SAPPHIRON_BOSS)) + cr->AI()->DoAction(ACTION_SAPPHIRON_BIRTH); + break; + default: + break; + } - if (state == DONE) - { - _horsemanTimer++; - if (horsemanKilled < HorsemanCount) - { + InstanceScript::OnGameObjectRemove(go); + } + + bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/) override + { + switch (criteria_id) + { + case ACHIEV_CRITERIA_AND_THEY_WOULD_ALL_GO_DOWN_TOGETHER_10_PLAYER: + case ACHIEV_CRITERIA_AND_THEY_WOULD_ALL_GO_DOWN_TOGETHER_25_PLAYER: + return _horsemanAchievement; + case ACHIEV_CRITERIA_JUST_CANT_GET_ENOUGH_10_PLAYER: + case ACHIEV_CRITERIA_JUST_CANT_GET_ENOUGH_25_PLAYER: + return _abominationsKilled >= AbominationKillCountReq; + case ACHIEV_CRITERIA_MOMMA_SAID_KNOCK_YOU_OUT_10_PLAYER: + case ACHIEV_CRITERIA_MOMMA_SAID_KNOCK_YOU_OUT_25_PLAYER: + return _faerlinaAchievement; + case ACHIEV_CRITERIA_SHOKING_10_PLAYER: + case ACHIEV_CRITERIA_SHOKING_25_PLAYER: + return _thaddiusAchievement; + case ACHIEV_CRITERIA_SPORE_LOSER_10_PLAYER: + case ACHIEV_CRITERIA_SPORE_LOSER_25_PLAYER: + return _loathebAchievement; + case ACHIEV_CRITERIA_THE_SAFETY_DANCE_10_PLAYER: + case ACHIEV_CRITERIA_THE_SAFETY_DANCE_25_PLAYER: + return _heiganAchievement; + case ACHIEV_CRITERIA_SUBTRACTION_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_KELTHUZAD_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_GOTHIK_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_ANUB_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_GROBBULUS_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_HEIGAN_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_FAERLINA_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_MAEXXNA_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_SAPPHIRON_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_LOATHEB_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_GLUTH_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_THADDIUS_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_PATCHWERK_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_RAZUVIOUS_10_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_NOTH_10_PLAYER: + return instance->GetPlayersCountExceptGMs() < TheDedicatedFew10PlayerReq; + case ACHIEV_CRITERIA_SUBTRACTION_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_ANUB_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_FAERLINA_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_MAEXXNA_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_PATCHWERK_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_GROBBULUS_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_GLUTH_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_THADDIUS_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_NOTH_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_HEIGAN_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_LOATHEB_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_RAZUVIOUS_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_GOTHIK_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_SAPPHIRON_25_PLAYER: + case ACHIEV_CRITERIA_THE_DEDICATED_FEW_KELTHUZAD_25_PLAYER: + return instance->GetPlayersCountExceptGMs() < TheDedicatedFew25PlayerReq; + case ACHIEV_CRITERIA_THE_HUNDRED_CLUB_10_PLAYER: + case ACHIEV_CRITERIA_THE_HUNDRED_CLUB_25_PLAYER: + return _sapphironAchievement; + case ACHIEV_CRITERIA_THE_UNDYING_KELTHUZAD: + case ACHIEV_CRITERIA_THE_UNDYING_THE_FOUR_HORSEMEN: + case ACHIEV_CRITERIA_THE_UNDYING_MAEXXNA: + case ACHIEV_CRITERIA_THE_UNDYING_LOATHEB: + case ACHIEV_CRITERIA_THE_UNDYING_THADDIUS: + case ACHIEV_CRITERIA_THE_IMMORTAL_KELTHUZAD: + case ACHIEV_CRITERIA_THE_IMMORTAL_THE_FOUR_HORSEMEN: + case ACHIEV_CRITERIA_THE_IMMORTAL_MAEXXNA: + case ACHIEV_CRITERIA_THE_IMMORTAL_LOATHEB: + case ACHIEV_CRITERIA_THE_IMMORTAL_THADDIUS: + for (int i = 0; i < MAX_ENCOUNTERS; ++i) + if (GetBossState(i) != DONE) return false; - } - // All horsemans are killed - if (Creature* cr = instance->GetCreature(_blaumeuxGUID)) - { - cr->CastSpell(cr, 59450, true); // credit - } - } - // respawn - else if (state == NOT_STARTED && horsemanKilled > 0) - { - Creature* cr; - if ((cr = instance->GetCreature(_blaumeuxGUID))) - { - if (!cr->IsAlive()) - { - cr->SetPosition(cr->GetHomePosition()); - cr->Respawn(); - } - } - if ((cr = instance->GetCreature(_rivendareGUID))) - { - if (!cr->IsAlive()) - { - cr->SetPosition(cr->GetHomePosition()); - cr->Respawn(); - } - } - if ((cr = instance->GetCreature(_zeliekGUID))) - { - if (!cr->IsAlive()) - { - cr->SetPosition(cr->GetHomePosition()); - cr->Respawn(); - } - } - if ((cr = instance->GetCreature(_korthazzGUID))) - { - if (!cr->IsAlive()) - { - cr->SetPosition(cr->GetHomePosition()); - cr->Respawn(); - } - } - } - else if (state == IN_PROGRESS) - { - Creature* cr; - if ((cr = instance->GetCreature(_blaumeuxGUID))) - { - cr->SetInCombatWithZone(); - } - if ((cr = instance->GetCreature(_rivendareGUID))) - { - cr->SetInCombatWithZone(); - } - if ((cr = instance->GetCreature(_zeliekGUID))) - { - cr->SetInCombatWithZone(); - } - if ((cr = instance->GetCreature(_korthazzGUID))) - { - cr->SetInCombatWithZone(); - } - } - - if (state == NOT_STARTED) - { - _horsemanTimer = 0; - } - } - - if (!InstanceScript::SetBossState(bossId, state)) + return !GetPersistentData(PERSISTENT_DATA_IMMORTAL_FAIL); + default: return false; + } + } - // Bosses data - switch (bossId) + void SetData(uint32 id, uint32 data) override + { + switch (id) + { + case DATA_ABOMINATION_KILLED: + ++_abominationsKilled; + return; + case DATA_FRENZY_REMOVED: + _faerlinaAchievement = false; + return; + case DATA_CHARGES_CROSSED: + _thaddiusAchievement = false; + return; + case DATA_SPORE_KILLED: + _loathebAchievement = false; + return; + case DATA_HUNDRED_CLUB: + _sapphironAchievement = false; + return; + case DATA_DANCE_FAIL: + _heiganAchievement = false; + return; + case DATA_HEIGAN_ERUPTION: + HeiganEruptSections(data); + return; + default: + return; + } + } + + bool SetBossState(uint32 bossId, EncounterState state) override + { + switch (bossId) + { + case BOSS_PATCHWERK: { - case BOSS_KELTHUZAD: - if (state == NOT_STARTED) - { - abominationsKilled = 0; - } + if (state != IN_PROGRESS) break; - case BOSS_FAERLINA: - if (state == NOT_STARTED) - { - faerlinaAchievement = true; - } - break; - case BOSS_THADDIUS: - if (state == NOT_STARTED) - { - thaddiusAchievement = true; - } - break; - case BOSS_LOATHEB: - if (state == NOT_STARTED) - { - loathebAchievement = true; - } - break; - case BOSS_HEIGAN: - if (state == NOT_STARTED) - { - heiganAchievement = true; - } - break; - case BOSS_SAPPHIRON: - if (state == DONE) - { - _speakTimer = 1; - } - else if (state == NOT_STARTED) - { - sapphironAchievement = true; - } - break; - default: - break; - } - // Save instance and open gates - if (state == DONE) - { - SaveToDB(); - - switch (bossId) + // pull all the trash if not killed + if (Creature* patchwerk = GetCreature(DATA_PATCHWERK_BOSS)) { - case BOSS_PATCHWERK: - if (GameObject* go = instance->GetGameObject(_patchwerkGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } + for (auto& itr : _patchwerkRoomTrash) + { + Creature* trash = ObjectAccessor::GetCreature(*patchwerk, itr); + if (trash && trash->IsAlive() && !trash->IsInCombat()) + trash->AI()->AttackStart(patchwerk->GetVictim()); + } + } + + break; + } + case BOSS_HEIGAN: + { + if (state == NOT_STARTED) + _heiganAchievement = true; + + break; + } + case BOSS_LOATHEB: + { + switch (state) + { + case NOT_STARTED: + _loathebAchievement = true; break; - case BOSS_GLUTH: - if (GameObject* go = instance->GetGameObject(_gluthGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_thaddiusGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - break; - case BOSS_NOTH: - if (GameObject* go = instance->GetGameObject(_nothExitGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_heiganGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - break; - case BOSS_HEIGAN: - if (GameObject* go = instance->GetGameObject(_heiganGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_heiganGateExitGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - break; - case BOSS_LOATHEB: - if (GameObject* go = instance->GetGameObject(_loathebGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_loathebPortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - go->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - } - if (GameObject* go = instance->GetGameObject(_plagueEyePortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_plagueGlowEyePortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6s); - break; - case BOSS_ANUB: - if (GameObject* go = instance->GetGameObject(_anubNextGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - break; - case BOSS_FAERLINA: - if (GameObject* go = instance->GetGameObject(_faerlinaGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_maexxnaGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - break; - case BOSS_MAEXXNA: - if (GameObject* go = instance->GetGameObject(_maexxnaGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_maexxnaPortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - go->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - } - if (GameObject* go = instance->GetGameObject(_spiderEyePortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_spiderGlowEyePortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6s); - break; - case BOSS_GOTHIK: - if (GameObject* go = instance->GetGameObject(_gothikEnterGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_gothikExitGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_horsemanGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - events.ScheduleEvent(EVENT_HORSEMEN_INTRO, 10s); - break; - case BOSS_SAPPHIRON: - events.ScheduleEvent(EVENT_FROSTWYRM_WATERFALL_DOOR, 5s); - break; - case BOSS_THADDIUS: - if (GameObject* go = instance->GetGameObject(_thaddiusPortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - go->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - } - if (GameObject* go = instance->GetGameObject(_abomEyePortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_abomGlowEyePortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6s); - break; - case BOSS_HORSEMAN: - if (GameObject* go = instance->GetGameObject(_horsemanPortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - go->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - } - if (GameObject* go = instance->GetGameObject(_deathknightEyePortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - if (GameObject* go = instance->GetGameObject(_deathknightGlowEyePortalGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6s); + case DONE: + ActivateWingPortal(DATA_LOATHEB_PORTAL); break; default: break; } - } - return true; - } - void Update(uint32 diff) override - { - if (_speakTimer) + break; + } + case BOSS_FAERLINA: { - Creature* kel = instance->GetCreature(_kelthuzadGUID); - Creature* lich = instance->GetCreature(_lichkingGUID); - if (kel && lich) + if (state == NOT_STARTED) + _faerlinaAchievement = true; + + break; + } + case BOSS_MAEXXNA: + { + if (state == DONE) + ActivateWingPortal(DATA_MAEXXNA_PORTAL); + + break; + } + case BOSS_THADDIUS: + { + switch (state) { - _speakTimer += diff; + case NOT_STARTED: + _thaddiusAchievement = true; + break; + case DONE: + ActivateWingPortal(DATA_THADDIUS_PORTAL); + break; + default: + break; } - else + + break; + } + case BOSS_HORSEMAN: + { + uint32 horsemanKilled = std::count_if(HorsemanDataGroup.begin(), HorsemanDataGroup.end(), [this](auto&& entry) { - return; - } - if (_speakTimer > 10000 && _speakTimer < 20000) + Creature* cr = GetCreature(entry); + return cr && !cr->IsAlive(); + }); + + switch (state) { - kel->AI()->Talk(SAY_SAPP_DIALOG1); - _speakTimer = 20000; - } - else if (_speakTimer > 30000 && _speakTimer < 40000) - { - lich->AI()->Talk(SAY_SAPP_DIALOG2_LICH); - _speakTimer = 40000; - } - else if (_speakTimer > 54000 && _speakTimer < 60000) - { - kel->AI()->Talk(SAY_SAPP_DIALOG3); - _speakTimer = 60000; - } - else if (_speakTimer > 70000 && _speakTimer < 80000) - { - lich->AI()->Talk(SAY_SAPP_DIALOG4_LICH); - _speakTimer = 80000; - } - else if (_speakTimer > 92000 && _speakTimer < 100000) - { - kel->AI()->Talk(SAY_SAPP_DIALOG5); - _speakTimer = 100000; - } - else if (_speakTimer > 105000) - { - kel->AI()->Talk(SAY_SAPP_DIALOG6); - _speakTimer = 0; - if (GameObject* go = instance->GetGameObject(_kelthuzadGateGUID)) + case NOT_STARTED: { - go->SetGoState(GO_STATE_ACTIVE); + _horsemanAchievement = true; + + if (!horsemanKilled) + break; + + for (auto&& entry : HorsemanDataGroup) + { + if (Creature* cr = GetCreature(entry)) + { + cr->SetPosition(cr->GetHomePosition()); + cr->Respawn(); + } + } + + break; } + case IN_PROGRESS: + { + for (auto&& entry : HorsemanDataGroup) + if (Creature* cr = GetCreature(entry)) + cr->SetInCombatWithZone(); + + break; + } + case DONE: + { + _events.RescheduleEvent(EVENT_AND_THEY_WOULD_ALL_GO_DOWN_TOGETHER, 15s); + + if (horsemanKilled != HorsemanCount) + return false; + + // all horsemans are killed + if (Creature* cr = GetCreature(DATA_BARON_RIVENDARE_BOSS)) + cr->CastSpell(cr, SPELL_THE_FOUR_HORSEMAN_CREDIT, true); + + ActivateWingPortal(DATA_HORSEMAN_PORTAL); + break; + } + default: + break; } - } - // And They would all - if (_horsemanTimer) - { - _horsemanTimer += diff; + break; } - - if (_screamTimer && GetBossState(BOSS_THADDIUS) != DONE) + case BOSS_SAPPHIRON: { - if (_screamTimer <= diff) + switch (state) { - instance->PlayDirectSoundToMap(SOUND_SCREAM + urand(0, 3)); - _screamTimer = (2 * MINUTE + urand(0, 30)) * IN_MILLISECONDS; + case NOT_STARTED: + _sapphironAchievement = true; + break; + case DONE: + { + if (GetPersistentData(PERSISTENT_DATA_KELTHUZAD_DIALOG)) + break; + + StorePersistentData(PERSISTENT_DATA_KELTHUZAD_DIALOG, 1); + SetGoState(DATA_KELTHUZAD_GATE, GO_STATE_READY); + _events.ScheduleEvent(EVENT_FROSTWYRM_WATERFALL_DOOR, 5s); + break; + } + default: + break; } - else - { - _screamTimer -= diff; - } - } - events.Update(diff); - switch (events.ExecuteEvent()) + break; + } + case BOSS_KELTHUZAD: { - case EVENT_KELTHUZAD_WING_TAUNT: - if (Creature* kelthuzad = instance->GetCreature(_kelthuzadGUID)) - { - kelthuzad->AI()->Talk(_currentWingTaunt); - } - ++_currentWingTaunt; - break; - case EVENT_FROSTWYRM_WATERFALL_DOOR: - if (GameObject* go = instance->GetGameObject(_sapphironGateGUID)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - break; - case EVENT_HORSEMEN_INTRO: - switch (_currentHorsemenLine) - { - case 0: // To arms, ye roustabouts! We've got company! - if (Creature* korthazz = instance->GetCreature(_korthazzGUID)) - korthazz->AI()->Talk(SAY_HORSEMEN_DIALOG1); - events.ScheduleEvent(EVENT_HORSEMEN_INTRO, 4500ms); - break; - case 1: // Invaders, cease this foolish venture at once! Turn away while you still can! - if (Creature* zeliek = instance->GetCreature(_zeliekGUID)) - zeliek->AI()->Talk(SAY_HORSEMEN_DIALOG1); - events.ScheduleEvent(EVENT_HORSEMEN_INTRO, 6500ms); - break; - case 2: // Come, Zeliek, do not drive them out. Not before we've had our fun! - if (Creature* blaumeux = instance->GetCreature(_blaumeuxGUID)) - blaumeux->AI()->Talk(SAY_HORSEMEN_DIALOG1); - events.ScheduleEvent(EVENT_HORSEMEN_INTRO, 6500ms); - break; - case 3: // Enough prattling. Let them come. We shall grind their bones to dust. - if (Creature* rivendare = instance->GetCreature(_rivendareGUID)) - rivendare->AI()->Talk(SAY_HORSEMEN_DIALOG1); - events.ScheduleEvent(EVENT_HORSEMEN_INTRO, 6500ms); - break; - case 4: // I do hope they stay alive long enough for me to... introduce myself. - if (Creature* blaumeux = instance->GetCreature(_blaumeuxGUID)) - blaumeux->AI()->Talk(SAY_HORSEMEN_DIALOG2); - events.ScheduleEvent(EVENT_HORSEMEN_INTRO, 6500ms); - break; - case 5: // Perhaps they will come to their senses... and run away as fast as they can. - if (Creature* zeliek = instance->GetCreature(_zeliekGUID)) - zeliek->AI()->Talk(SAY_HORSEMEN_DIALOG2); - events.ScheduleEvent(EVENT_HORSEMEN_INTRO, 6500ms); - break; - case 6: // I've heard about enough a' yer snivelin'! Shut yer flytrap before I shut it for ye'! - if (Creature* korthazz = instance->GetCreature(_korthazzGUID)) - korthazz->AI()->Talk(SAY_HORSEMEN_DIALOG2); - events.ScheduleEvent(EVENT_HORSEMEN_INTRO, 6500ms); - break; - case 7: // Conserve your anger. Harness your rage. You will all have outlets for your frustrations soon enough. - if (Creature* rivendare = instance->GetCreature(_rivendareGUID)) - rivendare->AI()->Talk(SAY_HORSEMEN_DIALOG2); - events.ScheduleEvent(EVENT_HORSEMEN_INTRO, 6500ms); - break; - } - ++_currentHorsemenLine; - break; + if (state == NOT_STARTED) + _abominationsKilled = 0; + + break; } + default: + break; } - ObjectGuid GetGuidData(uint32 id) const override - { - switch (id) - { - // GameObjects - case DATA_HEIGAN_ENTER_GATE: - return _heiganGateGUID; - case DATA_LOATHEB_GATE: - return _loathebGateGUID; - case DATA_FAERLINA_WEB: - return _faerlinaWebGUID; - case DATA_MAEXXNA_GATE: - return _maexxnaGateGUID; - case DATA_GOTHIK_ENTER_GATE: - return _gothikEnterGateGUID; - case DATA_GOTHIK_INNER_GATE: - return _gothikInnerGateGUID; - case DATA_GOTHIK_EXIT_GATE: - return _gothikExitGateGUID; - case DATA_HORSEMEN_GATE: - return _horsemanGateGUID; - case DATA_THADDIUS_GATE: - return _thaddiusGateGUID; - case DATA_NOTH_ENTRY_GATE: - return _nothEntryGateGUID; - case DATA_KELTHUZAD_FLOOR: - return _kelthuzadFloorGUID; - case DATA_KELTHUZAD_GATE: - return _kelthuzadGateGUID; - case DATA_KELTHUZAD_PORTAL_1: - return _kelthuzadPortal1GUID; - case DATA_KELTHUZAD_PORTAL_2: - return _kelthuzadPortal2GUID; - case DATA_KELTHUZAD_PORTAL_3: - return _kelthuzadPortal3GUID; - case DATA_KELTHUZAD_PORTAL_4: - return _kelthuzadPortal4GUID; - - // NPCs - case DATA_THADDIUS_BOSS: - return _thaddiusGUID; - case DATA_STALAGG_BOSS: - return _stalaggGUID; - case DATA_FEUGEN_BOSS: - return _feugenGUID; - case DATA_GOTHIK_BOSS: - return _gothikGUID; - case DATA_LICH_KING_BOSS: - return _lichkingGUID; - default: - break; - } - - return ObjectGuid::Empty; - } - - void ReadSaveDataMore(std::istringstream& data) override - { - data >> immortalAchievement; - } - - void WriteSaveDataMore(std::ostringstream& data) override - { - data << immortalAchievement; - } - }; -}; -class boss_naxxramas_misc : public CreatureScript -{ -public: - boss_naxxramas_misc() : CreatureScript("boss_naxxramas_misc") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetNaxxramasAI(pCreature); + return InstanceScript::SetBossState(bossId, state); } - struct boss_naxxramas_miscAI : public NullCreatureAI + void Update(uint32 diff) override { - explicit boss_naxxramas_miscAI(Creature* c) : NullCreatureAI(c) - { - timer = 0; - } + _events.Update(diff); - uint32 timer; - - void JustDied(Unit* /*killer*/) override + switch (_events.ExecuteEvent()) { - if (me->GetEntry() == NPC_MR_BIGGLESWORTH && me->GetInstanceScript()) + case EVENT_THADDIUS_SCREAMS: { - if (Creature* cr = me->SummonCreature(20350/*NPC_KELTHUZAD*/, *me, TEMPSUMMON_TIMED_DESPAWN, 1)) - { - cr->SetDisplayId(11686); - cr->AI()->Talk(SAY_CAT_DIED); - } - } - } + if (GetBossState(BOSS_THADDIUS) == DONE) + break; - void UpdateAI(uint32 diff) override - { - if (me->GetEntry() == NPC_NAXXRAMAS_TRIGGER) - { - timer += diff; - if (timer >= 5000) - { - if (Creature* cr = me->SummonCreature(NPC_LIVING_POISON, 3128.59, -3118.81, 293.346, 4.76754, TEMPSUMMON_TIMED_DESPAWN, 15200)) - { - cr->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); - cr->GetMotionMaster()->MovePoint(0, 3130.322, -3156.51, 293.324, false); - } - if (Creature* cr = me->SummonCreature(NPC_LIVING_POISON, *me, TEMPSUMMON_TIMED_DESPAWN, 14800)) - { - cr->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); - cr->GetMotionMaster()->MovePoint(0, 3144.779, -3158.416, 293.324, false); - } - if (Creature* cr = me->SummonCreature(NPC_LIVING_POISON, 3175.42, -3134.86, 293.34, 4.284, TEMPSUMMON_TIMED_DESPAWN, 14800)) - { - cr->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); - cr->GetMotionMaster()->MovePoint(0, 3158.778, -3164.201, 293.312, false); - } - timer = 0; - } - } - else if (me->GetEntry() == NPC_LIVING_POISON) - { - Unit* target = nullptr; - Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 0.5f); - Acore::UnitLastSearcher searcher(me, target, u_check); - Cell::VisitAllObjects(me, searcher, 1.5f); - if (target) - { - me->CastSpell(me, SPELL_FROGGER_EXPLODE, true); - } + instance->PlayDirectSoundToMap(SOUND_SCREAM + urand(0, 3)); + return _events.ScheduleEvent(EVENT_THADDIUS_SCREAMS, 2min, 2min + 30s); } + case EVENT_AND_THEY_WOULD_ALL_GO_DOWN_TOGETHER: + _horsemanAchievement = false; + break; + case EVENT_KELTHUZAD_WING_TAUNT: + return CreatureTalk(DATA_KELTHUZAD_BOSS, _currentWingTaunt++); + case EVENT_HORSEMEN_INTRO1: + CreatureTalk(DATA_THANE_KORTHAZZ_BOSS, SAY_HORSEMEN_DIALOG1); + return _events.ScheduleEvent(EVENT_HORSEMEN_INTRO2, 4500ms); + case EVENT_HORSEMEN_INTRO2: + CreatureTalk(DATA_SIR_ZELIEK_BOSS, SAY_HORSEMEN_DIALOG1); + return _events.ScheduleEvent(EVENT_HORSEMEN_INTRO3, 6500ms); + case EVENT_HORSEMEN_INTRO3: + CreatureTalk(DATA_LADY_BLAUMEUX_BOSS, SAY_HORSEMEN_DIALOG1); + return _events.ScheduleEvent(EVENT_HORSEMEN_INTRO4, 6500ms); + case EVENT_HORSEMEN_INTRO4: + CreatureTalk(DATA_BARON_RIVENDARE_BOSS, SAY_HORSEMEN_DIALOG1); + return _events.ScheduleEvent(EVENT_HORSEMEN_INTRO5, 6500ms); + case EVENT_HORSEMEN_INTRO5: + CreatureTalk(DATA_LADY_BLAUMEUX_BOSS, SAY_HORSEMEN_DIALOG2); + return _events.ScheduleEvent(EVENT_HORSEMEN_INTRO6, 6500ms); + case EVENT_HORSEMEN_INTRO6: + CreatureTalk(DATA_SIR_ZELIEK_BOSS, SAY_HORSEMEN_DIALOG2); + return _events.ScheduleEvent(EVENT_HORSEMEN_INTRO7, 6500ms); + case EVENT_HORSEMEN_INTRO7: + CreatureTalk(DATA_THANE_KORTHAZZ_BOSS, SAY_HORSEMEN_DIALOG2); + return _events.ScheduleEvent(EVENT_HORSEMEN_INTRO8, 6500ms); + case EVENT_HORSEMEN_INTRO8: + return CreatureTalk(DATA_BARON_RIVENDARE_BOSS, SAY_HORSEMEN_DIALOG2); + case EVENT_FROSTWYRM_WATERFALL_DOOR: + SetGoState(DATA_SAPPHIRON_GATE, GO_STATE_ACTIVE); + return _events.ScheduleEvent(EVENT_KELTHUZAD_LICH_KING_TALK1, 5s); + case EVENT_KELTHUZAD_LICH_KING_TALK1: + CreatureTalk(DATA_KELTHUZAD_BOSS, SAY_SAPP_DIALOG1); + return _events.ScheduleEvent(EVENT_KELTHUZAD_LICH_KING_TALK2, 10s); + case EVENT_KELTHUZAD_LICH_KING_TALK2: + CreatureTalk(DATA_LICH_KING_BOSS, SAY_SAPP_DIALOG2_LICH); + return _events.ScheduleEvent(EVENT_KELTHUZAD_LICH_KING_TALK3, 14s); + case EVENT_KELTHUZAD_LICH_KING_TALK3: + CreatureTalk(DATA_KELTHUZAD_BOSS, SAY_SAPP_DIALOG3); + return _events.ScheduleEvent(EVENT_KELTHUZAD_LICH_KING_TALK4, 10s); + case EVENT_KELTHUZAD_LICH_KING_TALK4: + CreatureTalk(DATA_LICH_KING_BOSS, SAY_SAPP_DIALOG4_LICH); + return _events.ScheduleEvent(EVENT_KELTHUZAD_LICH_KING_TALK5, 12s); + case EVENT_KELTHUZAD_LICH_KING_TALK5: + CreatureTalk(DATA_KELTHUZAD_BOSS, SAY_SAPP_DIALOG5); + return _events.ScheduleEvent(EVENT_KELTHUZAD_LICH_KING_TALK6, 5s); + case EVENT_KELTHUZAD_LICH_KING_TALK6: + CreatureTalk(DATA_KELTHUZAD_BOSS, SAY_SAPP_DIALOG6); + return SetGoState(DATA_KELTHUZAD_GATE, GO_STATE_ACTIVE); + default: + break; } - }; + } + +private: + // Controls + EventMap _events; + uint8 _currentWingTaunt; + uint8 _horsemanLoaded; + + // GameObjects + std::set _heiganEruption[HeiganEruptSectionCount]; + + // NPCs + GuidList _patchwerkRoomTrash; + + // Achievements + uint8 _abominationsKilled; + bool _faerlinaAchievement; + bool _thaddiusAchievement; + bool _loathebAchievement; + bool _sapphironAchievement; + bool _heiganAchievement; + bool _horsemanAchievement; }; -const Position sapphironEntryTP = { 3498.300049f, -5349.490234f, 144.968002f, 1.3698910f }; +class npc_mr_bigglesworth : public NullCreatureAI +{ +public: + npc_mr_bigglesworth(Creature* c) : NullCreatureAI(c) { } + + void JustDied(Unit* /*killer*/) override + { + InstanceScript* instance = me->GetInstanceScript(); + if (!instance) + return; + + Creature* kelThuzard = instance->GetCreature(DATA_KELTHUZAD_BOSS); + if (!kelThuzard) + return; + + kelThuzard->AI()->Talk(SAY_CAT_DIED); + } +}; + +class npc_living_poison : public NullCreatureAI +{ +public: + npc_living_poison(Creature* c) : NullCreatureAI(c) { } + + void UpdateAI(uint32 /*diff*/) override + { + if (me->SelectNearestTarget(1.5f, true)) + me->CastSpell(me, SPELL_EXPLODE, true); + } +}; + +class npc_naxxramas_trigger : public NullCreatureAI +{ +public: + npc_naxxramas_trigger(Creature* c) : NullCreatureAI(c) { } + + void Reset() override + { + _events.Reset(); + _events.ScheduleEvent(EVENT_SUMMON_LIVING_POISON, 5s); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + switch (_events.ExecuteEvent()) + { + case EVENT_SUMMON_LIVING_POISON: + { + for (LivingPoisonData const& entry : LivingPoisonDataList) + if (Creature* cr = me->SummonCreature(NPC_LIVING_POISON, entry.Start, TEMPSUMMON_TIMED_DESPAWN, entry.DespawnTime)) + { + cr->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); + cr->GetMotionMaster()->MovePoint(0, entry.End, false); + } + + _events.Repeat(5s); + break; + } + default: + break; + } + } + +private: + EventMap _events; +}; class at_naxxramas_hub_portal : public AreaTriggerScript { @@ -1269,29 +767,29 @@ public: bool OnTrigger(Player* player, AreaTrigger const* /*trigger*/) override { - if (player->IsAlive() && !player->IsInCombat()) - { - if (InstanceScript *instance = player->GetInstanceScript()) - { - bool AreAllWingsCleared = instance->GetBossState(BOSS_MAEXXNA) == DONE - && (instance->GetBossState(BOSS_LOATHEB) == DONE) - && (instance->GetBossState(BOSS_THADDIUS) == DONE) - && (instance->GetBossState(BOSS_HORSEMAN) == DONE); + if (!player->IsAlive() || player->IsInCombat()) + return false; - if (AreAllWingsCleared) - { - player->TeleportTo(533, sapphironEntryTP.m_positionX, sapphironEntryTP.m_positionY, sapphironEntryTP.m_positionZ, sapphironEntryTP.m_orientation); - return true; - } - } - } - return false; + InstanceScript* instance = player->GetInstanceScript(); + if (!instance) + return false; + + if ((instance->GetBossState(BOSS_MAEXXNA) != DONE) || + (instance->GetBossState(BOSS_LOATHEB) != DONE) || + (instance->GetBossState(BOSS_THADDIUS) != DONE) || + (instance->GetBossState(BOSS_HORSEMAN) != DONE)) + return false; + + player->TeleportTo(SapphironTeleportPos); + return true; } }; void AddSC_instance_naxxramas() { - new instance_naxxramas(); - new boss_naxxramas_misc(); + RegisterInstanceScript(instance_naxxramas, NaxxramasMapId); + RegisterNaxxramasCreatureAI(npc_mr_bigglesworth); + RegisterNaxxramasCreatureAI(npc_living_poison); + RegisterNaxxramasCreatureAI(npc_naxxramas_trigger); new at_naxxramas_hub_portal(); } diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h index 981230f15..b77b124ea 100644 --- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h +++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h @@ -18,68 +18,78 @@ #ifndef DEF_NAXXRAMAS_H #define DEF_NAXXRAMAS_H -#include "CreatureAIImpl.h" - #define DataHeader "NAX" #define NaxxramasScriptName "instance_naxxramas" -enum Encouters +enum NaxxramasEncouter { - BOSS_PATCHWERK = 0, - BOSS_GROBBULUS = 1, - BOSS_GLUTH = 2, - BOSS_NOTH = 3, - BOSS_HEIGAN = 4, - BOSS_LOATHEB = 5, - BOSS_ANUB = 6, - BOSS_FAERLINA = 7, - BOSS_MAEXXNA = 8, - BOSS_THADDIUS = 9, - BOSS_RAZUVIOUS = 10, - BOSS_GOTHIK = 11, - BOSS_HORSEMAN = 12, - BOSS_SAPPHIRON = 13, - BOSS_KELTHUZAD = 14, - MAX_ENCOUNTERS, + BOSS_PATCHWERK = 0, + BOSS_GROBBULUS = 1, + BOSS_GLUTH = 2, + BOSS_NOTH = 3, + BOSS_HEIGAN = 4, + BOSS_LOATHEB = 5, + BOSS_ANUB = 6, + BOSS_FAERLINA = 7, + BOSS_MAEXXNA = 8, + BOSS_THADDIUS = 9, + BOSS_RAZUVIOUS = 10, + BOSS_GOTHIK = 11, + BOSS_HORSEMAN = 12, + BOSS_SAPPHIRON = 13, + BOSS_KELTHUZAD = 14, + MAX_ENCOUNTERS }; -enum NXData +enum NaxxramasData { - DATA_NOTH_ENTRY_GATE = 100, - DATA_HEIGAN_ERUPTION = 101, - DATA_HEIGAN_ENTER_GATE = 102, - DATA_LOATHEB_GATE = 103, - DATA_FAERLINA_WEB = 105, - DATA_MAEXXNA_GATE = 106, - DATA_THADDIUS_BOSS = 107, - DATA_STALAGG_BOSS = 108, - DATA_FEUGEN_BOSS = 109, - DATA_THADDIUS_GATE = 110, - DATA_RAZUVIOUS = 111, - DATA_GOTHIK_BOSS = 112, - DATA_GOTHIK_ENTER_GATE = 113, - DATA_GOTHIK_INNER_GATE = 114, - DATA_GOTHIK_EXIT_GATE = 115, - DATA_HORSEMEN_GATE = 116, - DATA_LICH_KING_BOSS = 117, - DATA_KELTHUZAD_FLOOR = 118, - DATA_ABOMINATION_KILLED = 119, - DATA_FRENZY_REMOVED = 120, - DATA_CHARGES_CROSSED = 121, - DATA_SPORE_KILLED = 122, - DATA_HUNDRED_CLUB = 123, - DATA_DANCE_FAIL = 124, - DATA_IMMORTAL_FAIL = 125, - DATA_KELTHUZAD_GATE = 126, - DATA_HAD_THADDIUS_GREET = 127, - DATA_KELTHUZAD_PORTAL_1 = 128, - DATA_KELTHUZAD_PORTAL_2 = 129, - DATA_KELTHUZAD_PORTAL_3 = 130, - DATA_KELTHUZAD_PORTAL_4 = 131 + DATA_PATCHWERK_BOSS = 100, + DATA_STALAGG_BOSS = 101, + DATA_FEUGEN_BOSS = 102, + DATA_THADDIUS_BOSS = 103, + DATA_RAZUVIOUS_BOSS = 104, + DATA_GOTHIK_BOSS = 105, + DATA_BARON_RIVENDARE_BOSS = 106, + DATA_SIR_ZELIEK_BOSS = 107, + DATA_LADY_BLAUMEUX_BOSS = 108, + DATA_THANE_KORTHAZZ_BOSS = 109, + DATA_SAPPHIRON_BOSS = 110, + DATA_KELTHUZAD_BOSS = 111, + DATA_LICH_KING_BOSS = 112, + + DATA_LOATHEB_PORTAL = 200, + DATA_MAEXXNA_PORTAL = 201, + DATA_THADDIUS_PORTAL = 202, + DATA_HORSEMAN_PORTAL = 203, + DATA_GOTHIK_INNER_GATE = 204, + DATA_SAPPHIRON_GATE = 205, + DATA_KELTHUZAD_GATE = 206, + DATA_KELTHUZAD_FLOOR = 207, + DATA_KELTHUZAD_PORTAL_1 = 208, + DATA_KELTHUZAD_PORTAL_2 = 209, + DATA_KELTHUZAD_PORTAL_3 = 210, + DATA_KELTHUZAD_PORTAL_4 = 211, + + DATA_HEIGAN_ERUPTION = 300, + DATA_DANCE_FAIL = 301, + DATA_SPORE_KILLED = 302, + DATA_FRENZY_REMOVED = 303, + DATA_THADDIUS_INTRO = 304, + DATA_CHARGES_CROSSED = 305, + DATA_HUNDRED_CLUB = 306, + DATA_ABOMINATION_KILLED = 307, }; -enum NXGOs +enum NaxxramasPersistentData +{ + PERSISTENT_DATA_THADDIUS_INTRO = 0, + PERSISTENT_DATA_KELTHUZAD_DIALOG = 1, + PERSISTENT_DATA_IMMORTAL_FAIL = 2, + PERSISTENT_DATA_COUNT +}; + +enum NaxxramasGameObject { GO_PATCHWERK_GATE = 181123, GO_GLUTH_GATE = 181120, @@ -129,8 +139,25 @@ enum NXGOs GO_CONS_EYE_RAMP_BOSS = 181232 }; -enum NXNPCs +enum NaxxramasGameObjectsDisplayId { + GO_DISPLAY_ID_HEIGAN_ERUPTION1 = 1287, + GO_DISPLAY_ID_HEIGAN_ERUPTION2 = 6785 +}; + +enum NaxxramasCreatureId +{ + // Patchwerk + NPC_PATCHWERK = 16028, + NPC_PATCHWORK_GOLEM = 16017, + NPC_BILE_RETCHER = 16018, + NPC_MAD_SCIENTIST = 16020, + NPC_LIVING_MONSTROSITY = 16021, + NPC_SURGICAL_ASSIST = 16022, + NPC_SLUDGE_BELCHER = 16029, + + NPC_LIVING_POISON = 16027, + // Thaddius NPC_THADDIUS = 15928, NPC_STALAGG = 15929, @@ -139,6 +166,9 @@ enum NXNPCs // Razuvious NPC_RAZUVIOUS = 16061, + // Gothik + NPC_GOTHIK = 16060, + // Four horseman NPC_BARON_RIVENDARE = 30549, NPC_SIR_ZELIEK = 16063, @@ -150,30 +180,124 @@ enum NXNPCs // Kel'Thuzad NPC_KELTHUZAD = 15990, - NPC_LICH_KING = 16980, - - // Frogger - NPC_LIVING_POISON = 16027, - NPC_NAXXRAMAS_TRIGGER = 16082, - NPC_MR_BIGGLESWORTH = 16998, - - // Patchwerk - NPC_PATCHWERK = 16028, - NPC_PATCHWORK_GOLEM = 16017, - NPC_BILE_RETCHER = 16018, - NPC_MAD_SCIENTIST = 16020, - NPC_LIVING_MONSTROSITY = 16021, - NPC_SURGICAL_ASSIST = 16022, - NPC_SLUDGE_BELCHER = 16029, - - // Gothik - NPC_GOTHIK = 16060 + NPC_LICH_KING = 16980 }; -enum NXMisc +enum NaxxramasAchievemmentCriteria +{ + ACHIEV_CRITERIA_AND_THEY_WOULD_ALL_GO_DOWN_TOGETHER_10_PLAYER = 7600, // And They Would All Go Down Together (10 player) + ACHIEV_CRITERIA_AND_THEY_WOULD_ALL_GO_DOWN_TOGETHER_25_PLAYER = 7601, // And They Would All Go Down Together (25 player) + + ACHIEV_CRITERIA_JUST_CANT_GET_ENOUGH_10_PLAYER = 7614, // Just Can't Get Enough (10 player) + ACHIEV_CRITERIA_JUST_CANT_GET_ENOUGH_25_PLAYER = 7615, // Just Can't Get Enough (25 player) + + ACHIEV_CRITERIA_MOMMA_SAID_KNOCK_YOU_OUT_10_PLAYER = 7265, // Momma Said Knock You Out (10 player) + ACHIEV_CRITERIA_MOMMA_SAID_KNOCK_YOU_OUT_25_PLAYER = 7549, // Momma Said Knock You Out (25 player) + + ACHIEV_CRITERIA_SHOKING_10_PLAYER = 7604, // Shocking! (10 player) + ACHIEV_CRITERIA_SHOKING_25_PLAYER = 7605, // Shocking! (25 player) + + ACHIEV_CRITERIA_SPORE_LOSER_10_PLAYER = 7612, // Spore Loser (10 player) + ACHIEV_CRITERIA_SPORE_LOSER_25_PLAYER = 7613, // Spore Loser (25 player) + + ACHIEV_CRITERIA_THE_SAFETY_DANCE_10_PLAYER = 7264, // The Safety Dance (10 player) + ACHIEV_CRITERIA_THE_SAFETY_DANCE_25_PLAYER = 7548, // The Safety Dance (25 player) + + ACHIEV_CRITERIA_SUBTRACTION_10_PLAYER = 7608, // Subtraction (10 player) + ACHIEV_CRITERIA_SUBTRACTION_25_PLAYER = 7609, // Subtraction (25 player) + + ACHIEV_CRITERIA_THE_HUNDRED_CLUB_10_PLAYER = 7567, // The Hundred Club (10 player) + ACHIEV_CRITERIA_THE_HUNDRED_CLUB_25_PLAYER = 7568, // The Hundred Club (25 player) + + ACHIEV_CRITERIA_THE_DEDICATED_FEW_ANUB_10_PLAYER = 7146, // The Dedicated Few (25 player) - Anub'Rekhan + ACHIEV_CRITERIA_THE_DEDICATED_FEW_FAERLINA_10_PLAYER = 7147, // The Dedicated Few (25 player) - Grand Widow Faerlina + ACHIEV_CRITERIA_THE_DEDICATED_FEW_MAEXXNA_10_PLAYER = 7148, // The Dedicated Few (25 player) - Maexxna + ACHIEV_CRITERIA_THE_DEDICATED_FEW_PATCHWERK_10_PLAYER = 7149, // The Dedicated Few (25 player) - Patchwerk + ACHIEV_CRITERIA_THE_DEDICATED_FEW_GROBBULUS_10_PLAYER = 7150, // The Dedicated Few (25 player) - Grobbulus + ACHIEV_CRITERIA_THE_DEDICATED_FEW_GLUTH_10_PLAYER = 7151, // The Dedicated Few (25 player) - Gluth + ACHIEV_CRITERIA_THE_DEDICATED_FEW_THADDIUS_10_PLAYER = 7152, // The Dedicated Few (25 player) - Thaddius + ACHIEV_CRITERIA_THE_DEDICATED_FEW_NOTH_10_PLAYER = 7153, // The Dedicated Few (25 player) - Noth the Plaguebringer + ACHIEV_CRITERIA_THE_DEDICATED_FEW_HEIGAN_10_PLAYER = 7154, // The Dedicated Few (25 player) - Heigan the Unclean + ACHIEV_CRITERIA_THE_DEDICATED_FEW_LOATHEB_10_PLAYER = 7155, // The Dedicated Few (25 player) - Loatheb + ACHIEV_CRITERIA_THE_DEDICATED_FEW_RAZUVIOUS_10_PLAYER = 7156, // The Dedicated Few (25 player) - Instructor Razuvious + ACHIEV_CRITERIA_THE_DEDICATED_FEW_GOTHIK_10_PLAYER = 7157, // The Dedicated Few (25 player) - Gothik the Harvester + ACHIEV_CRITERIA_THE_DEDICATED_FEW_SAPPHIRON_10_PLAYER = 7158, // The Dedicated Few (25 player) - Sapphiron + ACHIEV_CRITERIA_THE_DEDICATED_FEW_KELTHUZAD_10_PLAYER = 6802, // The Dedicated Few (25 player) - Kel'Thuzad + + ACHIEV_CRITERIA_THE_DEDICATED_FEW_ANUB_25_PLAYER = 7159, // The Dedicated Few (25 player) - Anub'Rekhan + ACHIEV_CRITERIA_THE_DEDICATED_FEW_FAERLINA_25_PLAYER = 7160, // The Dedicated Few (25 player) - Grand Widow Faerlina + ACHIEV_CRITERIA_THE_DEDICATED_FEW_MAEXXNA_25_PLAYER = 7161, // The Dedicated Few (25 player) - Maexxna + ACHIEV_CRITERIA_THE_DEDICATED_FEW_PATCHWERK_25_PLAYER = 7162, // The Dedicated Few (25 player) - Patchwerk + ACHIEV_CRITERIA_THE_DEDICATED_FEW_GROBBULUS_25_PLAYER = 7163, // The Dedicated Few (25 player) - Grobbulus + ACHIEV_CRITERIA_THE_DEDICATED_FEW_GLUTH_25_PLAYER = 7164, // The Dedicated Few (25 player) - Gluth + ACHIEV_CRITERIA_THE_DEDICATED_FEW_THADDIUS_25_PLAYER = 7165, // The Dedicated Few (25 player) - Thaddius + ACHIEV_CRITERIA_THE_DEDICATED_FEW_NOTH_25_PLAYER = 7166, // The Dedicated Few (25 player) - Noth the Plaguebringer + ACHIEV_CRITERIA_THE_DEDICATED_FEW_HEIGAN_25_PLAYER = 7167, // The Dedicated Few (25 player) - Heigan the Unclean + ACHIEV_CRITERIA_THE_DEDICATED_FEW_LOATHEB_25_PLAYER = 7168, // The Dedicated Few (25 player) - Loatheb + ACHIEV_CRITERIA_THE_DEDICATED_FEW_RAZUVIOUS_25_PLAYER = 7169, // The Dedicated Few (25 player) - Instructor Razuvious + ACHIEV_CRITERIA_THE_DEDICATED_FEW_GOTHIK_25_PLAYER = 7170, // The Dedicated Few (25 player) - Gothik the Harvester + ACHIEV_CRITERIA_THE_DEDICATED_FEW_SAPPHIRON_25_PLAYER = 7171, // The Dedicated Few (25 player) - Sapphiron + ACHIEV_CRITERIA_THE_DEDICATED_FEW_KELTHUZAD_25_PLAYER = 7172, // The Dedicated Few (25 player) - Kel'Thuzad + + ACHIEV_CRITERIA_THE_UNDYING_KELTHUZAD = 7617, // The Undying - Kel'Thuzad + ACHIEV_CRITERIA_THE_UNDYING_THE_FOUR_HORSEMEN = 13237, // The Undying - The Four Horsemen + ACHIEV_CRITERIA_THE_UNDYING_MAEXXNA = 13238, // The Undying - Maexxna + ACHIEV_CRITERIA_THE_UNDYING_LOATHEB = 13239, // The Undying - Loatheb + ACHIEV_CRITERIA_THE_UNDYING_THADDIUS = 13240, // The Undying - Thaddius + + ACHIEV_CRITERIA_THE_IMMORTAL_KELTHUZAD = 7616, // The Immortal - Kel'Thuzad + ACHIEV_CRITERIA_THE_IMMORTAL_THE_FOUR_HORSEMEN = 13233, // The Immortal - The Four Horsemen + ACHIEV_CRITERIA_THE_IMMORTAL_MAEXXNA = 13234, // The Immortal - Maexxna + ACHIEV_CRITERIA_THE_IMMORTAL_LOATHEB = 13235, // The Immortal - Loatheb + ACHIEV_CRITERIA_THE_IMMORTAL_THADDIUS = 13236 // The Immortal - Thaddius +}; + +enum NaxxramasSay +{ + SAY_HORSEMEN_DIALOG1 = 5, + SAY_HORSEMEN_DIALOG2 = 6, + + SAY_SAPP_DIALOG1 = 0, + SAY_SAPP_DIALOG2_LICH = 1, + SAY_SAPP_DIALOG3 = 2, + SAY_SAPP_DIALOG4_LICH = 2, + SAY_SAPP_DIALOG5 = 4, + SAY_SAPP_DIALOG6 = 20, + + SAY_CAT_DIED = 5, // No!!! A curse upon you, interlopers! The armies of the Lich King will hunt you down. You will not escape your fate... + SAY_FIRST_WING_TAUNT = 16 +}; + +enum NaxxramasEvent +{ + EVENT_SUMMON_LIVING_POISON = 1, + EVENT_THADDIUS_SCREAMS = 2, + EVENT_AND_THEY_WOULD_ALL_GO_DOWN_TOGETHER = 3, + EVENT_KELTHUZAD_WING_TAUNT = 4, + + EVENT_HORSEMEN_INTRO1 = 5, // Thane Korth'azz: To arms, ye roustabouts! We've got company! + EVENT_HORSEMEN_INTRO2 = 6, // Sir Zeliek: Invaders, cease this foolish venture at once! Turn away while you still can! + EVENT_HORSEMEN_INTRO3 = 7, // Lady Blaumeux: Come, Zeliek, do not drive them out. Not before we've had our fun! + EVENT_HORSEMEN_INTRO4 = 8, // Baron Rivendare: Enough prattling. Let them come. We shall grind their bones to dust. + EVENT_HORSEMEN_INTRO5 = 9, // Lady Blaumeux: I do hope they stay alive long enough for me to... introduce myself. + EVENT_HORSEMEN_INTRO6 = 10, // Sir Zeliek: Perhaps they will come to their senses... and run away as fast as they can. + EVENT_HORSEMEN_INTRO7 = 11, // Thane Korth'azz: I've heard about enough a' yer snivelin'! Shut yer flytrap before I shut it for ye'! + EVENT_HORSEMEN_INTRO8 = 12, // Baron Rivendare: Conserve your anger. Harness your rage. You will all have outlets for your frustrations soon enough. + + EVENT_FROSTWYRM_WATERFALL_DOOR = 13, + EVENT_KELTHUZAD_LICH_KING_TALK1 = 14, + EVENT_KELTHUZAD_LICH_KING_TALK2 = 15, + EVENT_KELTHUZAD_LICH_KING_TALK3 = 16, + EVENT_KELTHUZAD_LICH_KING_TALK4 = 17, + EVENT_KELTHUZAD_LICH_KING_TALK5 = 18, + EVENT_KELTHUZAD_LICH_KING_TALK6 = 19 +}; + +enum NaxxramasMisc { SPELL_ERUPTION = 29371, - SPELL_FROGGER_EXPLODE = 28433, + SPELL_EXPLODE = 28433, + SPELL_THE_FOUR_HORSEMAN_CREDIT = 59450, ACTION_SAPPHIRON_BIRTH = 1, @@ -181,32 +305,19 @@ enum NXMisc SOUND_SCREAM = 8873 }; -enum NXSays -{ - SAY_SAPP_DIALOG1 = 0, - SAY_SAPP_DIALOG2_LICH = 1, - SAY_SAPP_DIALOG3 = 2, - SAY_SAPP_DIALOG4_LICH = 2, - SAY_SAPP_DIALOG5 = 4, - SAY_SAPP_DIALOG6 = 20, - SAY_CAT_DIED = 5, - SAY_FIRST_WING_TAUNT = 16, - SAY_HORSEMEN_DIALOG1 = 5, - SAY_HORSEMEN_DIALOG2 = 6 -}; +static constexpr uint32 NaxxramasMapId = 533; +static constexpr uint8 HeiganEruptSectionCount = 4; +static constexpr uint8 HorsemanCount = 4; +static constexpr uint8 AbominationKillCountReq = 18; +static constexpr uint8 TheDedicatedFew10PlayerReq = 9; +static constexpr uint8 TheDedicatedFew25PlayerReq = 21; -enum NXEvents -{ - EVENT_THADDIUS_SCREAMS = 0, - EVENT_KELTHUZAD_WING_TAUNT = 1, - EVENT_FROSTWYRM_WATERFALL_DOOR = 2, - EVENT_HORSEMEN_INTRO = 3 -}; - -template +template inline AI* GetNaxxramasAI(T* obj) { return GetInstanceAI(obj, NaxxramasScriptName); } +#define RegisterNaxxramasCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetNaxxramasAI) + #endif From cb0e66e8c4ae69546fb36e03ed6fdf9eb09f8748 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 25 Feb 2025 18:41:42 +0000 Subject: [PATCH 16/57] chore(DB): import pending files Referenced commit(s): a2eaa5739423fe613f66bce0d118a097edf150ef --- .../rev_1739822360188928600.sql => db_world/2025_02_25_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1739822360188928600.sql => db_world/2025_02_25_00.sql} (90%) diff --git a/data/sql/updates/pending_db_world/rev_1739822360188928600.sql b/data/sql/updates/db_world/2025_02_25_00.sql similarity index 90% rename from data/sql/updates/pending_db_world/rev_1739822360188928600.sql rename to data/sql/updates/db_world/2025_02_25_00.sql index 77db67f34..764c79daa 100644 --- a/data/sql/updates/pending_db_world/rev_1739822360188928600.sql +++ b/data/sql/updates/db_world/2025_02_25_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_02_24_00 -> 2025_02_25_00 -- update Mr. Bigglesworth script name UPDATE `creature_template` SET `ScriptName` = 'npc_mr_bigglesworth' WHERE (`entry` = 16998); From 9fcd9b3684021331f8a293a345eb2bca330839d1 Mon Sep 17 00:00:00 2001 From: sudlud Date: Tue, 25 Feb 2025 20:20:39 +0100 Subject: [PATCH 17/57] fix(scripts/SWP): remove whitespaces to fix codestyle check (#21609) --- .../EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp index e33aadb6e..4bf78c4ab 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp @@ -84,7 +84,7 @@ struct boss_sacrolash : public BossAI _isSisterDead = false; BossAI::Reset(); me->SetLootMode(0); - + if (Creature* alythess = instance->GetCreature(DATA_ALYTHESS)) if (!alythess->IsAlive()) alythess->Respawn(true); @@ -184,7 +184,7 @@ struct boss_alythess : public BossAI _isSisterDead = false; BossAI::Reset(); me->SetLootMode(0); - + if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH)) if (!sacrolash->IsAlive()) sacrolash->Respawn(true); From 0ff1a9756c3f667b13e84b43087f81849f911a10 Mon Sep 17 00:00:00 2001 From: vrachv Date: Tue, 25 Feb 2025 22:52:23 +0000 Subject: [PATCH 18/57] fix(Core/Spell) Removed Prey on the Weak triggering on dead targets (#21611) --- src/server/scripts/Spells/spell_rogue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index bbdb9314a..e6dbe948c 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -508,7 +508,7 @@ class spell_rog_prey_on_the_weak : public AuraScript if (!victim && target->IsPlayer()) victim = target->ToPlayer()->GetSelectedUnit(); - if (victim && (target->GetHealthPct() > victim->GetHealthPct())) + if (victim && victim->IsAlive() && (target->GetHealthPct() > victim->GetHealthPct())) { if (!target->HasAura(SPELL_ROGUE_PREY_ON_THE_WEAK)) { From 60b1bd8f0d1eae9cb27747c72dd3344169f2a72e Mon Sep 17 00:00:00 2001 From: Takenbacon Date: Tue, 25 Feb 2025 18:11:36 -0800 Subject: [PATCH 19/57] fix(Core/Server): Disable out of world packet requeuing (#21608) --- src/server/game/Server/WorldSession.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 4a414d23d..6b893cb8f 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -362,8 +362,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later. if (!m_playerRecentlyLogout) { - requeuePackets.push_back(packet); - deletePacket = false; + //requeuePackets.push_back(packet); + //deletePacket = false; LOG_DEBUG("network", "Delaying processing of message with status STATUS_LOGGEDIN: No players in the world for account id {}", GetAccountId()); } From e18df16abdfed9caf64696415718643ed75e8102 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Wed, 26 Feb 2025 11:57:35 +0100 Subject: [PATCH 20/57] fix(DB/Creature) Volatile Fiends now reach the end of the ramp. (#21600) --- .../pending_db_world/Volatile_Fiend.sql | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 data/sql/updates/pending_db_world/Volatile_Fiend.sql diff --git a/data/sql/updates/pending_db_world/Volatile_Fiend.sql b/data/sql/updates/pending_db_world/Volatile_Fiend.sql new file mode 100644 index 000000000..33d5566f7 --- /dev/null +++ b/data/sql/updates/pending_db_world/Volatile_Fiend.sql @@ -0,0 +1,50 @@ + +-- Add new waypoints +DELETE FROM `waypoints` WHERE `entry` IN (25851); +INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `point_comment`) VALUES +(25851, 1, 1691.8, 513.581, 85.272, NULL, 0, 'Volatile Fiend'), +(25851, 2, 1685.3, 531.707, 85.2726, NULL, 0, 'Volatile Fiend'), +(25851, 3, 1678.34, 548.748, 85.1301, NULL, 0, 'Volatile Fiend'), +(25851, 4, 1666.06, 562.532, 85.0835, NULL, 0, 'Volatile Fiend'), +(25851, 5, 1637.52, 577.188, 85.0895, NULL, 0, 'Volatile Fiend'), +(25851, 6, 1614.78, 593.407, 84.98, NULL, 0, 'Volatile Fiend'), +(25851, 7, 1597.61, 586.214, 84.9866, NULL, 0, 'Volatile Fiend'), +(25851, 8, 1600.17, 579.387, 84.8456, NULL, 0, 'Volatile Fiend'), +(25851, 9, 1614.05, 560.661, 73.5036, NULL, 0, 'Volatile Fiend'), +(25851, 10, 1628.04, 541.932, 63.0932, NULL, 0, 'Volatile Fiend'), +(25851, 11, 1647.24, 530.052, 53.9219, NULL, 0, 'Volatile Fiend'), +(25851, 12, 1654.32, 527.089, 50.6408, NULL, 0, 'Volatile Fiend'), +(25851, 13, 1659.93, 519.575, 50.5756, NULL, 0, 'Volatile Fiend'), +(25851, 14, 1653.65, 505.556, 50.5756, NULL, 0, 'Volatile Fiend'), +(25851, 15, 1632.21, 514.799, 50.5756, NULL, 0, 'Volatile Fiend'), +(25851, 16, 1614, 529.46, 50.5756, NULL, 0, 'Volatile Fiend'), +(25851, 17, 1596.71, 543.375, 50.5756, NULL, 0, 'Volatile Fiend'), +(25851, 18, 1583.25, 560.562, 50.5756, NULL, 0, 'Volatile Fiend'), +(25851, 19, 1570.92, 574.75, 50.6095, NULL, 0, 'Volatile Fiend'), +(25851, 20, 1557.81, 569.841, 50.5778, NULL, 0, 'Volatile Fiend'), +(25851, 21, 1561.98, 553.198, 47.4638, NULL, 0, 'Volatile Fiend'), +(25851, 22, 1572.27, 537.190, 38.7821, NULL, 0, 'Volatile Fiend'), +(25851, 23, 1583.75, 521.830, 32.7347, NULL, 0, 'Volatile Fiend'), +(25851, 24, 1588.91, 506.692, 32.7835, NULL, 0, 'Volatile Fiend'); + +-- Remove Wrong Flag (Pacified) +UPDATE `creature_template` SET `unit_flags`=`unit_flags`& ~131072 WHERE (`entry` = 25851); + +-- Set Movement Type on Random in Radius +UPDATE `creature` SET `wander_distance` = 5, `MovementType` = 1 WHERE (`id1` = 25851) AND (`guid` IN (47044, 47153, 47154, 47155, 47265, 47309, 47313, 47449, 47454, 47470, 47471, 47475, 47578, 47607, 47608, 47768, 47769, 47875, 47884, 47893, 47897, 47898, 47899, 47901, 48151)); + +-- Modify SmartAI +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 25851; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 25851); +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 +(25851, 0, 0, 1, 54, 0, 100, 513, 0, 0, 0, 0, 0, 0, 11, 46308, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Volatile Fiend - On Just Summoned - Cast \'Burning Winds\' (No Repeat)'), +(25851, 0, 1, 2, 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, 'Volatile Fiend - On Just Summoned - Set Event Phase 1 (No Repeat)'), +(25851, 0, 2, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 53, 1, 25851, 0, 0, 2500, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Volatile Fiend - On Just Summoned - Start Waypoint Path 25851 (No Repeat)'), +(25851, 0, 3, 4, 40, 0, 100, 0, 24, 0, 0, 0, 0, 0, 11, 47287, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Volatile Fiend - On Point 24 of Path Any Reached - Cast \'Burning Destruction\''), +(25851, 0, 4, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 41, 1000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Volatile Fiend - On Point 24 of Path Any Reached - Despawn In 1000 ms'), +(25851, 0, 5, 0, 6, 2, 100, 512, 0, 0, 0, 0, 0, 0, 11, 45779, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Volatile Fiend - On Just Died - Cast \'Felfire Fission\' (Phase 2)'), +(25851, 0, 6, 7, 0, 1, 100, 513, 0, 0, 0, 0, 0, 5, 11, 47287, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Volatile Fiend - In Combat - Cast \'Burning Destruction\' (Phase 1) (No Repeat)'), +(25851, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Volatile Fiend - In Combat - Set Event Phase 3 (Phase 1) (No Repeat)'), +(25851, 0, 8, 0, 25, 0, 100, 512, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Volatile Fiend - On Reset - Set Event Phase 2'), +(25851, 0, 9, 0, 23, 4, 100, 1, 47287, 0, 0, 0, 0, 0, 11, 46751, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Volatile Fiend - On Aura \'Burning Destruction\' - Cast \'Suicide\' (Phase 3) (No Repeat)'); From df710719ace0018fa9b2c28a54332fe862f77de3 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Wed, 26 Feb 2025 11:57:46 +0100 Subject: [PATCH 21/57] fix(DB/Creature) Elf patrols are now in formation. (#21613) --- .../pending_db_world/SwP_elves_patrols.sql | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 data/sql/updates/pending_db_world/SwP_elves_patrols.sql diff --git a/data/sql/updates/pending_db_world/SwP_elves_patrols.sql b/data/sql/updates/pending_db_world/SwP_elves_patrols.sql new file mode 100644 index 000000000..a0379fb73 --- /dev/null +++ b/data/sql/updates/pending_db_world/SwP_elves_patrols.sql @@ -0,0 +1,178 @@ + +-- New sniffed waypoints for Vindicators +DELETE FROM `waypoint_data` WHERE `id` IN (483970); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(483970, 1, 1646.2877, 1094.1549, 44.342278, NULL, 0, 0, 0, 100, 0), +(483970, 2, 1662.9437, 1095.1677, 47.942604, NULL, 0, 0, 0, 100, 0), +(483970, 3, 1680.2102, 1095.8654, 51.137077, NULL, 0, 0, 0, 100, 0), +(483970, 4, 1689.7664, 1096.0767, 52.755, NULL, 0, 0, 0, 100, 0), +(483970, 5, 1706.0358, 1095.9752, 52.82473, NULL, 0, 0, 0, 100, 0), +(483970, 6, 1722.817, 1095.9159, 52.768322, NULL, 0, 0, 0, 100, 0), +(483970, 7, 1737.7158, 1094.9585, 50.68262, NULL, 0, 0, 0, 100, 0), +(483970, 8, 1758.9626, 1094.3884, 46.612896, NULL, 0, 0, 0, 100, 0), +(483970, 9, 1776.1573, 1091.3165, 42.720085, NULL, 0, 0, 0, 100, 0), +(483970, 10, 1795.4512, 1079.2858, 37.95213, NULL, 0, 0, 0, 100, 0), +(483970, 11, 1802.0015, 1065.321, 36.409225, NULL, 0, 0, 0, 100, 0), +(483970, 12, 1803.2385, 1049.7919, 35.760597, NULL, 0, 0, 0, 100, 0), +(483970, 13, 1802.0015, 1065.321, 36.409225, NULL, 0, 0, 0, 100, 0), +(483970, 14, 1795.4512, 1079.2858, 37.95213, NULL, 0, 0, 0, 100, 0), +(483970, 15, 1776.1573, 1091.3165, 42.720085, NULL, 0, 0, 0, 100, 0), +(483970, 16, 1758.9626, 1094.3884, 46.612896, NULL, 0, 0, 0, 100, 0), +(483970, 17, 1737.7158, 1094.9585, 50.68262, NULL, 0, 0, 0, 100, 0), +(483970, 18, 1722.817, 1095.9159, 52.768322, NULL, 0, 0, 0, 100, 0), +(483970, 19, 1706.0358, 1095.9752, 52.82473, NULL, 0, 0, 0, 100, 0), +(483970, 20, 1689.7664, 1096.0767, 52.755, NULL, 0, 0, 0, 100, 0), +(483970, 21, 1680.2102, 1095.8654, 51.137077, NULL, 0, 0, 0, 100, 0), +(483970, 22, 1662.9437, 1095.1677, 47.942604, NULL, 0, 0, 0, 100, 0), +(483970, 23, 1646.2877, 1094.1549, 44.342278, NULL, 0, 0, 0, 100, 0), +(483970, 24, 1636.6041, 1093.0988, 41.88343, NULL, 0, 0, 0, 100, 0), +(483970, 25, 1623.0975, 1084.906, 38.59068, NULL, 0, 0, 0, 100, 0), +(483970, 26, 1612.5037, 1069.7399, 36.53206, NULL, 0, 0, 0, 100, 0), +(483970, 27, 1611.1992, 1059.485, 35.985447, NULL, 0, 0, 0, 100, 0), +(483970, 28, 1611.3134, 1049.9519, 35.64077, NULL, 0, 0, 0, 100, 0), +(483970, 29, 1611.1992, 1059.485, 35.985447, NULL, 0, 0, 0, 100, 0), +(483970, 30, 1612.5037, 1069.7399, 36.53206, NULL, 0, 0, 0, 100, 0), +(483970, 31, 1623.0975, 1084.906, 38.59068, NULL, 0, 0, 0, 100, 0), +(483970, 32, 1636.6041, 1093.0988, 41.88343, NULL, 0, 0, 0, 100, 0), +(483970, 33, 1646.2877, 1094.1549, 44.342278, NULL, 0, 0, 0, 100, 0); + +DELETE FROM `waypoint_data` WHERE `id` IN (483960); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(483960, 1, 1774.8724, 836.3321, 36.32849, NULL, 0, 0, 0, 100, 0), +(483960, 2, 1768.3956, 836.36, 35.32849, NULL, 0, 0, 0, 100, 0), +(483960, 3, 1752.8463, 836.4012, 33.92224, NULL, 0, 0, 0, 100, 0), +(483960, 4, 1733.8491, 836.57697, 33.922237, NULL, 0, 0, 0, 100, 0), +(483960, 5, 1714.5634, 836.6511, 35.54724, NULL, 0, 0, 0, 100, 0), +(483960, 6, 1694.0593, 837.08527, 35.55463, NULL, 0, 0, 0, 100, 0), +(483960, 7, 1658.3192, 838.1326, 33.92224, NULL, 0, 0, 0, 100, 0), +(483960, 8, 1637.4122, 838.4397, 35.469112, NULL, 0, 0, 0, 100, 0), +(483960, 9, 1624.4858, 840.2041, 36.062862, NULL, 0, 0, 0, 100, 0), +(483960, 10, 1617.1686, 849.7756, 36.062843, NULL, 0, 0, 0, 100, 0), +(483960, 11, 1610.0963, 858.7788, 36.062855, NULL, 0, 0, 0, 100, 0), +(483960, 12, 1607.2747, 866.5177, 36.328487, NULL, 0, 0, 0, 100, 0), +(483960, 13, 1606.8698, 884.1786, 35.56981, NULL, 0, 0, 0, 100, 0), +(483960, 14, 1606.9554, 907.58167, 35.56875, NULL, 0, 0, 0, 100, 0), +(483960, 15, 1607.6558, 933.41797, 35.567177, NULL, 0, 0, 0, 100, 0), +(483960, 16, 1608.352, 957.584, 35.565678, NULL, 0, 0, 0, 100, 0), +(483960, 17, 1608.94, 987.12415, 35.573025, NULL, 0, 0, 0, 100, 0), +(483960, 18, 1608.352, 957.584, 35.565678, NULL, 0, 0, 0, 100, 0), +(483960, 19, 1607.6558, 933.41797, 35.567177, NULL, 0, 0, 0, 100, 0), +(483960, 20, 1606.9554, 907.58167, 35.56875, NULL, 0, 0, 0, 100, 0), +(483960, 21, 1606.8698, 884.1786, 35.56981, NULL, 0, 0, 0, 100, 0), +(483960, 22, 1607.2747, 866.5177, 36.328487, NULL, 0, 0, 0, 100, 0), +(483960, 23, 1610.0963, 858.7788, 36.062855, NULL, 0, 0, 0, 100, 0), +(483960, 24, 1617.1686, 849.7756, 36.062843, NULL, 0, 0, 0, 100, 0), +(483960, 25, 1624.4858, 840.2041, 36.062862, NULL, 0, 0, 0, 100, 0), +(483960, 26, 1637.4122, 838.4397, 35.469112, NULL, 0, 0, 0, 100, 0), +(483960, 27, 1658.3192, 838.1326, 33.92224, NULL, 0, 0, 0, 100, 0), +(483960, 28, 1694.0593, 837.08527, 35.55463, NULL, 0, 0, 0, 100, 0), +(483960, 29, 1714.5634, 836.6511, 35.54724, NULL, 0, 0, 0, 100, 0), +(483960, 30, 1733.8491, 836.57697, 33.922237, NULL, 0, 0, 0, 100, 0), +(483960, 31, 1752.8463, 836.4012, 33.92224, NULL, 0, 0, 0, 100, 0), +(483960, 32, 1768.3956, 836.36, 35.32849, NULL, 0, 0, 0, 100, 0), +(483960, 33, 1774.8724, 836.3321, 36.32849, NULL, 0, 0, 0, 100, 0); + +DELETE FROM `waypoint_data` WHERE `id` IN (481940); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(481940, 1, 1662.921, 1031.9761, 15.985676, NULL, 0, 0, 0, 100, 0), +(481940, 2, 1671.6886, 1044.9114, 15.985804, NULL, 0, 0, 0, 100, 0), +(481940, 3, 1688.9246, 1056.0344, 15.985803, NULL, 0, 0, 0, 100, 0), +(481940, 4, 1698.7399, 1058.056, 18.015984, NULL, 0, 0, 0, 100, 0), +(481940, 5, 1712.9889, 1058.221, 18.015984, NULL, 0, 0, 0, 100, 0), +(481940, 6, 1732.618, 1055.4069, 15.985794, NULL, 0, 0, 0, 100, 0), +(481940, 7, 1743.3898, 1041.8229, 15.985684, NULL, 0, 0, 0, 100, 0), +(481940, 8, 1756.496, 1019.7752, 15.985794, NULL, 0, 0, 0, 100, 0), +(481940, 9, 1776.5123, 986.125, 15.98579, NULL, 0, 0, 0, 100, 0), +(481940, 10, 1756.496, 1019.7752, 15.985794, NULL, 0, 0, 0, 100, 0), +(481940, 11, 1743.3898, 1041.8229, 15.985684, NULL, 0, 0, 0, 100, 0), +(481940, 12, 1732.618, 1055.4069, 15.985794, NULL, 0, 0, 0, 100, 0), +(481940, 13, 1712.9889, 1058.221, 18.015984, NULL, 0, 0, 0, 100, 0), +(481940, 14, 1698.7399, 1058.056, 18.015984, NULL, 0, 0, 0, 100, 0), +(481940, 15, 1688.9246, 1056.0344, 15.985803, NULL, 0, 0, 0, 100, 0), +(481940, 16, 1671.6886, 1044.9114, 15.985804, NULL, 0, 0, 0, 100, 0), +(481940, 17, 1662.921, 1031.9761, 15.985676, NULL, 0, 0, 0, 100, 0), +(481940, 18, 1657.1139, 1022.9647, 15.985677, NULL, 0, 0, 0, 100, 0), +(481940, 19, 1651.9424, 1013.9453, 15.9857855, NULL, 0, 0, 0, 100, 0), +(481940, 20, 1647.3245, 996.7984, 15.986502, NULL, 0, 0, 0, 100, 0), +(481940, 21, 1646.149, 978.1148, 15.986507, NULL, 0, 0, 0, 100, 0), +(481940, 22, 1646.2843, 964.768, 15.979303, NULL, 0, 0, 0, 100, 0), +(481940, 23, 1646.149, 978.1148, 15.986507, NULL, 0, 0, 0, 100, 0), +(481940, 24, 1647.3245, 996.7984, 15.986502, NULL, 0, 0, 0, 100, 0), +(481940, 25, 1651.9424, 1013.9453, 15.9857855, NULL, 0, 0, 0, 100, 0), +(481940, 26, 1657.1139, 1022.9647, 15.985677, NULL, 0, 0, 0, 100, 0); + +-- Delete useless waypoints +DELETE FROM `waypoint_data` WHERE `id` IN (483980, 483590, 483930, 483950, 483730, 530260, 481610, 483920, 481950); + +-- Delete Creature_addon for Arch mage, Dusk and Dawn Priests +DELETE FROM `creature_addon` WHERE (`guid` IN (48398, 48359, 48393, 48395, 48373, 53026, 48161, 48392, 48195)); + +-- Update Movement Type +UPDATE `creature` SET `MovementType` = 0 WHERE (`guid` IN (48398, 48359, 48393, 48395, 48373, 53026, 48161, 48392, 48195)); + +-- Add formations +DELETE FROM `creature_formations` WHERE `leaderGUID` = 48194; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(48194, 48194, 0, 0, 515, 0, 0), +(48194, 48393, 2, 90, 515, 0, 0), +(48194, 48359, 2, 180, 515, 0, 0), +(48194, 48398, 2, 270, 515, 0, 0); + +DELETE FROM `creature_formations` WHERE `leaderGUID` = 48396; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(48396, 48396, 0, 0, 515, 0, 0), +(48396, 48395, 2, 90, 515, 0, 0), +(48396, 48373, 2, 180, 515, 0, 0), +(48396, 53026, 2, 270, 515, 0, 0); + +DELETE FROM `creature_formations` WHERE `leaderGUID` = 48397; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(48397, 48397, 0, 0, 515, 0, 0), +(48397, 48195, 2, 90, 515, 0, 0), +(48397, 48392, 2, 180, 515, 0, 0), +(48397, 48161, 2, 270, 515, 0, 0); + +-- Remove SmartAI row 2 (or 3) from general AIs +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (25369, 25367)) AND (`source_type` = 0) AND (`id` IN (2)); +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (25363, 25370, 25371)) AND (`source_type` = 0) AND (`id` IN (3)); + +-- Add don't override sai +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|134217728 WHERE (`entry` IN (25369, 25363, 25370, 25367, 25371)); + +-- Add Comments +UPDATE `creature` SET `Comment` = "has guid specific SAI" WHERE (`id1` = 25369) AND (`guid` IN (42573, 42574, 42582, 42586, 42587, 42591, 42592)); +UPDATE `creature` SET `Comment` = "has guid specific SAI" WHERE (`id1` = 25363) AND (`guid` IN (54820, 54817, 54825, 54824)); +UPDATE `creature` SET `Comment` = "has guid specific SAI" WHERE (`id1` = 25370) AND (`guid` IN (42647, 42656, 42657, 42640)); +UPDATE `creature` SET `Comment` = "has guid specific SAI" WHERE (`id1` = 25367) AND (`guid` IN (54832, 54834, 54835, 54829)); +UPDATE `creature` SET `Comment` = "has guid specific SAI" WHERE (`id1` = 25371) AND (`guid` IN (43439, 42894, 43654, 42660, 42659)); + +-- Add row 2 in GuidAI +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (-42573, -42574, -42582, -42586, -42587, -42591, -42592, -54832, -54834, -54835, -54829)) AND (`source_type` = 0) AND (`id` IN (2)); +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 +(-42573, 0, 2, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Vindicator - Out of Combat - Cast \'Felblood Channel\''), +(-42574, 0, 2, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Vindicator - Out of Combat - Cast \'Felblood Channel\''), +(-42582, 0, 2, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Vindicator - Out of Combat - Cast \'Felblood Channel\''), +(-42586, 0, 2, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Vindicator - Out of Combat - Cast \'Felblood Channel\''), +(-42587, 0, 2, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Vindicator - Out of Combat - Cast \'Felblood Channel\''), +(-42591, 0, 2, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Vindicator - Out of Combat - Cast \'Felblood Channel\''), +(-42592, 0, 2, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Vindicator - Out of Combat - Cast \'Felblood Channel\''), +(-54832, 0, 2, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Arch Mage - Out of Combat - Cast \'Felblood Channel\''), +(-54834, 0, 2, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Arch Mage - Out of Combat - Cast \'Felblood Channel\''), +(-54835, 0, 2, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Arch Mage - Out of Combat - Cast \'Felblood Channel\''), +(-54829, 0, 2, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Arch Mage - Out of Combat - Cast \'Felblood Channel\''); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (-54820, -54817, -54825, -54824, -42647, -42656, -42657, -42640, -43439, -42894, -43654, -42660, -42659)) AND (`source_type` = 0) AND (`id` IN (3)); +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 +(-54820, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Cabalist - Out of Combat - Cast \'Felblood Channel\''), +(-54817, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Cabalist - Out of Combat - Cast \'Felblood Channel\''), +(-54825, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Cabalist - Out of Combat - Cast \'Felblood Channel\''), +(-54824, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Cabalist - Out of Combat - Cast \'Felblood Channel\''), +(-42647, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Dusk Priest - Out of Combat - Cast \'Felblood Channel\''), +(-42656, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Dusk Priest - Out of Combat - Cast \'Felblood Channel\''), +(-42657, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Dusk Priest - Out of Combat - Cast \'Felblood Channel\''), +(-42640, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Dusk Priest - Out of Combat - Cast \'Felblood Channel\''), +(-43439, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Dawn Priest - Out of Combat - Cast \'Felblood Channel\''), +(-42894, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Dawn Priest - Out of Combat - Cast \'Felblood Channel\''), +(-43654, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Dawn Priest - Out of Combat - Cast \'Felblood Channel\''), +(-42660, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Dawn Priest - Out of Combat - Cast \'Felblood Channel\''), +(-42659, 0, 3, 0, 1, 0, 100, 0, 0, 0, 15000, 45000, 0, 0, 11, 46319, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Dawn Priest - Out of Combat - Cast \'Felblood Channel\''); From a42509836bbeca768bffb357561a7c093e6a4845 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Feb 2025 10:58:39 +0000 Subject: [PATCH 22/57] chore(DB): import pending files Referenced commit(s): e18df16abdfed9caf64696415718643ed75e8102 --- .../SwP_elves_patrols.sql => db_world/2025_02_26_00.sql} | 1 + .../Volatile_Fiend.sql => db_world/2025_02_26_01.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/SwP_elves_patrols.sql => db_world/2025_02_26_00.sql} (99%) rename data/sql/updates/{pending_db_world/Volatile_Fiend.sql => db_world/2025_02_26_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/SwP_elves_patrols.sql b/data/sql/updates/db_world/2025_02_26_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/SwP_elves_patrols.sql rename to data/sql/updates/db_world/2025_02_26_00.sql index a0379fb73..1b5a176c6 100644 --- a/data/sql/updates/pending_db_world/SwP_elves_patrols.sql +++ b/data/sql/updates/db_world/2025_02_26_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_02_25_00 -> 2025_02_26_00 -- New sniffed waypoints for Vindicators DELETE FROM `waypoint_data` WHERE `id` IN (483970); diff --git a/data/sql/updates/pending_db_world/Volatile_Fiend.sql b/data/sql/updates/db_world/2025_02_26_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/Volatile_Fiend.sql rename to data/sql/updates/db_world/2025_02_26_01.sql index 33d5566f7..0241d659c 100644 --- a/data/sql/updates/pending_db_world/Volatile_Fiend.sql +++ b/data/sql/updates/db_world/2025_02_26_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_02_26_00 -> 2025_02_26_01 -- Add new waypoints DELETE FROM `waypoints` WHERE `entry` IN (25851); From bf1e3e4ce812ad36037062dcf35ae382532aefe0 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Wed, 26 Feb 2025 12:07:24 +0100 Subject: [PATCH 23/57] fix(DB/Creature) Add formations to Scout's packs. (#21614) --- .../pending_db_world/SwP_Scout_Formations.sql | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 data/sql/updates/pending_db_world/SwP_Scout_Formations.sql diff --git a/data/sql/updates/pending_db_world/SwP_Scout_Formations.sql b/data/sql/updates/pending_db_world/SwP_Scout_Formations.sql new file mode 100644 index 000000000..4743a0911 --- /dev/null +++ b/data/sql/updates/pending_db_world/SwP_Scout_Formations.sql @@ -0,0 +1,45 @@ + +-- Remove old formation (it will be changed with 48372) +DELETE FROM `creature_formations` WHERE `leaderGUID` = 41817; + +-- Add formations for all elf packs with a Scout as a leader +DELETE FROM `creature_formations` WHERE `leaderGUID` = 48372; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(48372, 48372, 0, 0, 3, 0, 0), +(48372, 41817, 0, 0, 3, 0, 0), +(48372, 43739, 0, 0, 3, 0, 0), +(48372, 54826, 0, 0, 3, 0, 0), +(48372, 42595, 0, 0, 3, 0, 0), +(48372, 54838, 0, 0, 3, 0, 0), +(48372, 42661, 0, 0, 3, 0, 0); + +DELETE FROM `creature_formations` WHERE `leaderGUID` = 48160; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(48160, 48160, 0, 0, 3, 0, 0), +(48160, 54816, 0, 0, 3, 0, 0), +(48160, 54837, 0, 0, 3, 0, 0), +(48160, 54858, 0, 0, 3, 0, 0), +(48160, 43661, 0, 0, 3, 0, 0), +(48160, 42589, 0, 0, 3, 0, 0), +(48160, 54988, 0, 0, 3, 0, 0), +(48160, 56686, 0, 0, 3, 0, 0); + +DELETE FROM `creature_formations` WHERE `leaderGUID` = 48162; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(48162, 48162, 0, 0, 3, 0, 0), +(48162, 42594, 0, 0, 3, 0, 0), +(48162, 43655, 0, 0, 3, 0, 0), +(48162, 54818, 0, 0, 3, 0, 0), +(48162, 54836, 0, 0, 3, 0, 0), +(48162, 42590, 0, 0, 3, 0, 0), +(48162, 42658, 0, 0, 3, 0, 0); + +DELETE FROM `creature_formations` WHERE `leaderGUID` = 48360; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(48360, 48360, 0, 0, 3, 0, 0), +(48360, 42593, 0, 0, 3, 0, 0), +(48360, 43440, 0, 0, 3, 0, 0), +(48360, 54833, 0, 0, 3, 0, 0), +(48360, 42655, 0, 0, 3, 0, 0), +(48360, 43738, 0, 0, 3, 0, 0), +(48360, 54819, 0, 0, 3, 0, 0); From 1ddec44220e95c6f7da3e0a0f78f92d1aed8bec8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Feb 2025 11:08:23 +0000 Subject: [PATCH 24/57] chore(DB): import pending files Referenced commit(s): bf1e3e4ce812ad36037062dcf35ae382532aefe0 --- .../SwP_Scout_Formations.sql => db_world/2025_02_26_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/SwP_Scout_Formations.sql => db_world/2025_02_26_02.sql} (97%) diff --git a/data/sql/updates/pending_db_world/SwP_Scout_Formations.sql b/data/sql/updates/db_world/2025_02_26_02.sql similarity index 97% rename from data/sql/updates/pending_db_world/SwP_Scout_Formations.sql rename to data/sql/updates/db_world/2025_02_26_02.sql index 4743a0911..fc4e2bd7d 100644 --- a/data/sql/updates/pending_db_world/SwP_Scout_Formations.sql +++ b/data/sql/updates/db_world/2025_02_26_02.sql @@ -1,3 +1,4 @@ +-- DB update 2025_02_26_01 -> 2025_02_26_02 -- Remove old formation (it will be changed with 48372) DELETE FROM `creature_formations` WHERE `leaderGUID` = 41817; From 97471151e7a50612831092bef862ebd2073f6549 Mon Sep 17 00:00:00 2001 From: sudlud Date: Wed, 26 Feb 2025 21:52:02 +0100 Subject: [PATCH 25/57] fix(DB/Gameobject): Sniffed Values for 'Smuggled Mana Cell' spawns (#21617) --- .../rev_1740599827613124400.sql | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1740599827613124400.sql diff --git a/data/sql/updates/pending_db_world/rev_1740599827613124400.sql b/data/sql/updates/pending_db_world/rev_1740599827613124400.sql new file mode 100644 index 000000000..e35504b7d --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1740599827613124400.sql @@ -0,0 +1,67 @@ +-- Update gameobject 'Smuggled Mana Cell' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (187039)) +AND (`guid` IN (47211, 47218)); +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 +(47211, 187039, 530, 0, 0, 1, 2, 3802.25341796875, 6071.35595703125, 267.14678955078125, 2.234017848968505859, 0, 0, 0.898793220520019531, 0.438372820615768432, 300, 255, 1, "", 49936, NULL), +(47218, 187039, 530, 0, 0, 1, 2, 3712.7783203125, 6107.95849609375, 266.455841064453125, 1.204277276992797851, 0, 0, 0.56640625, 0.824126183986663818, 300, 255, 1, "", 49936, NULL); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (187039)) +AND (`guid` BETWEEN 3587 AND 3638); +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 +(3587, 187039, 530, 0, 0, 1, 2, 3668.37158203125, 6135.6220703125, 266.69952392578125, 1.623155713081359863, 0, 0, 0.725374221801757812, 0.688354730606079101, 300, 255, 1, "", 49936, NULL), +(3588, 187039, 530, 0, 0, 1, 2, 3672.96435546875, 6157.6220703125, 266.512542724609375, 2.949595451354980468, 0, 0, 0.995395660400390625, 0.095851235091686248, 300, 255, 1, "", 49936, NULL), +(3589, 187039, 530, 0, 0, 1, 2, 3675.26513671875, 6070.5859375, 267.049041748046875, 6.073746204376220703, 0, 0, -0.10452842712402343, 0.994521915912628173, 300, 255, 1, "", 49936, NULL), +(3590, 187039, 530, 0, 0, 1, 2, 3679.548095703125, 6054.12158203125, 267.049285888671875, 1.151916384696960449, 0, 0, 0.544638633728027343, 0.838670849800109863, 300, 255, 1, "", 49936, NULL), +(3591, 187039, 530, 0, 0, 1, 2, 3689.249267578125, 6176.6259765625, 265.839752197265625, 5.061456203460693359, 0, 0, -0.57357597351074218, 0.819152355194091796, 300, 255, 1, "", 49936, NULL), +(3592, 187039, 530, 0, 0, 1, 2, 3694.231689453125, 6145.6904296875, 267.73199462890625, 1.466075778007507324, 0, 0, 0.669130325317382812, 0.74314504861831665, 300, 255, 1, "", 49936, NULL), +(3593, 187039, 530, 0, 0, 1, 2, 3694.341064453125, 6010.08837890625, 265.655670166015625, 5.270895957946777343, 0, 0, -0.48480892181396484, 0.87462007999420166, 300, 255, 1, "", 49936, NULL), +(3594, 187039, 530, 0, 0, 1, 2, 3704.829833984375, 5979.626953125, 267.292144775390625, 0.401424884796142578, 0, 0, 0.199367523193359375, 0.979924798011779785, 300, 255, 1, "", 49936, NULL), +(3595, 187039, 530, 0, 0, 1, 2, 3709.30859375, 6081.39990234375, 267.088165283203125, 4.97418975830078125, 0, 0, -0.60876083374023437, 0.793353796005249023, 300, 255, 1, "", 49936, NULL), +(3596, 187039, 530, 0, 0, 1, 2, 3712.35107421875, 6116.68017578125, 266.49993896484375, 5.567600727081298828, 0, 0, -0.35020732879638671, 0.936672210693359375, 300, 255, 1, "", 51666, NULL), +(3597, 187039, 530, 0, 0, 1, 2, 3721.878173828125, 5911.95556640625, 266.48077392578125, 0.959929943084716796, 0, 0, 0.461748123168945312, 0.887011110782623291, 300, 255, 1, "", 51666, NULL), +(3598, 187039, 530, 0, 0, 1, 2, 3724.14404296875, 6182.51611328125, 265.497283935546875, 3.804818391799926757, 0, 0, -0.94551849365234375, 0.325568377971649169, 300, 255, 1, "", 49936, NULL), +(3599, 187039, 530, 0, 0, 1, 2, 3727.646728515625, 5968.20751953125, 268.0377197265625, 0.837757468223571777, 0, 0, 0.406736373901367187, 0.913545548915863037, 300, 255, 1, "", 49936, NULL), +(3600, 187039, 530, 0, 0, 1, 2, 3733.13720703125, 5906.81494140625, 266.45770263671875, 3.036838293075561523, 0, 0, 0.998628616333007812, 0.052353221923112869, 300, 255, 1, "", 51666, NULL), +(3601, 187039, 530, 0, 0, 1, 2, 3735.05810546875, 5931.11767578125, 267.352783203125, 5.829400539398193359, 0, 0, -0.22495079040527343, 0.974370121955871582, 300, 255, 1, "", 49936, NULL), +(3602, 187039, 530, 0, 0, 1, 2, 3738.077392578125, 6027.93798828125, 266.662994384765625, 2.530723094940185546, 0, 0, 0.953716278076171875, 0.300707906484603881, 300, 255, 1, "", 49936, NULL), +(3603, 187039, 530, 0, 0, 1, 2, 3753.967041015625, 6101.2724609375, 268.450408935546875, 0.872663915157318115, 0, 0, 0.422617912292480468, 0.906307935714721679, 300, 255, 1, "", 49936, NULL), +(3604, 187039, 530, 0, 0, 1, 2, 3765.03955078125, 5904.611328125, 265.63397216796875, 2.949595451354980468, 0, 0, 0.995395660400390625, 0.095851235091686248, 300, 255, 1, "", 51666, NULL), +(3605, 187039, 530, 0, 0, 1, 2, 3765.7822265625, 6167.2587890625, 266.251373291015625, 0.436331570148468017, 0, 0, 0.216439247131347656, 0.976296067237854003, 300, 255, 1, "", 49936, NULL), +(3606, 187039, 530, 0, 0, 1, 2, 3765.936767578125, 5926.2353515625, 265.694915771484375, 4.782202720642089843, 0, 0, -0.68199825286865234, 0.731353819370269775, 300, 255, 1, "", 51666, NULL), +(3607, 187039, 530, 0, 0, 1, 2, 3773.61279296875, 6032.35400390625, 265.545074462890625, 5.829400539398193359, 0, 0, -0.22495079040527343, 0.974370121955871582, 300, 255, 1, "", 49936, NULL), +(3608, 187039, 530, 0, 0, 1, 2, 3774.935791015625, 6006.2421875, 267.2779541015625, 5.288348197937011718, 0, 0, -0.4771585464477539, 0.878817260265350341, 300, 255, 1, "", 49936, NULL), +(3609, 187039, 530, 0, 0, 1, 2, 3775.311279296875, 6178.49169921875, 266.12078857421875, 4.206246376037597656, 0, 0, -0.86162853240966796, 0.50753939151763916, 300, 255, 1, "", 49936, NULL), +(3610, 187039, 530, 0, 0, 1, 2, 3781.671875, 6085.78466796875, 266.2579345703125, 0.226892471313476562, 0, 0, 0.113203048706054687, 0.993571877479553222, 300, 255, 1, "", 49936, NULL), +(3611, 187039, 530, 0, 0, 1, 2, 3789.5712890625, 6007.6728515625, 265.2188720703125, 5.585053920745849609, 0, 0, -0.34202003479003906, 0.939692676067352294, 300, 255, 1, "", 49936, NULL), +(3612, 187039, 530, 0, 0, 1, 2, 3792.1416015625, 6160.3154296875, 266.664947509765625, 4.188792228698730468, 0, 0, -0.86602497100830078, 0.50000077486038208, 300, 255, 1, "", 49936, NULL), +(3613, 187039, 530, 0, 0, 1, 2, 3796.958740234375, 6051.1337890625, 268.68023681640625, 0.575957298278808593, 0, 0, 0.284014701843261718, 0.958819925785064697, 300, 255, 1, "", 49936, NULL), +(3614, 187039, 530, 0, 0, 1, 2, 3809.899658203125, 6040.74169921875, 265.542388916015625, 0.785396754741668701, 0, 0, 0.38268280029296875, 0.923879802227020263, 300, 255, 1, "", 49936, NULL), +(3615, 187039, 530, 0, 0, 1, 2, 3812.818115234375, 6122.8896484375, 265.945037841796875, 5.288348197937011718, 0, 0, -0.4771585464477539, 0.878817260265350341, 300, 255, 1, "", 49936, NULL), +(3616, 187039, 530, 0, 0, 1, 2, 3813.9619140625, 5935.2333984375, 266.694671630859375, 0.191985160112380981, 0, 0, 0.095845222473144531, 0.995396256446838378, 300, 255, 1, "", 49936, NULL), +(3617, 187039, 530, 0, 0, 1, 2, 3822.53173828125, 5968.72900390625, 267.40045166015625, 3.90954136848449707, 0, 0, -0.92718315124511718, 0.37460830807685852, 300, 255, 1, "", 49936, NULL), +(3618, 187039, 530, 0, 0, 1, 2, 3832.146240234375, 6026.24658203125, 268.865386962890625, 0.942476630210876464, 0, 0, 0.453989982604980468, 0.891006767749786376, 300, 255, 1, "", 49936, NULL), +(3619, 187039, 530, 0, 0, 1, 2, 3835.288330078125, 6123.421875, 265.945587158203125, 0.069811686873435974, 0, 0, 0.034898757934570312, 0.999390840530395507, 300, 255, 1, "", 49936, NULL), +(3620, 187039, 530, 0, 0, 1, 2, 3842.87451171875, 6104.00927734375, 269.40936279296875, 0.610863447189331054, 0, 0, 0.3007049560546875, 0.953717231750488281, 300, 255, 1, "", 49936, NULL), +(3621, 187039, 530, 0, 0, 1, 2, 3855.89892578125, 6047.43994140625, 266.722137451171875, 4.607671737670898437, 0, 0, -0.74314403533935546, 0.669131457805633544, 300, 255, 1, "", 49936, NULL), +(3622, 187039, 530, 0, 0, 1, 2, 3907.057861328125, 6045.35791015625, 265.235504150390625, 5.864306926727294921, 0, 0, -0.20791149139404296, 0.978147625923156738, 300, 255, 1, "", 49936, NULL), +(3623, 187039, 530, 0, 0, 1, 2, 3907.084716796875, 6093.44482421875, 271.591461181640625, 5.288348197937011718, 0, 0, -0.4771585464477539, 0.878817260265350341, 300, 255, 1, "", 49936, NULL), +(3624, 187039, 530, 0, 0, 1, 2, 3920.4541015625, 6009.75634765625, 269.50244140625, 0.261798173189163208, 0, 0, 0.130525588989257812, 0.991444945335388183, 300, 255, 1, "", 49936, NULL), +(3625, 187039, 530, 0, 0, 1, 2, 3926.932373046875, 6094.12158203125, 271.715972900390625, 5.654868602752685546, 0, 0, -0.30901622772216796, 0.95105677843093872, 300, 255, 1, "", 49936, NULL), +(3626, 187039, 530, 0, 0, 1, 2, 3927.088134765625, 5975.74267578125, 267.513092041015625, 3.630291461944580078, 0, 0, -0.97029495239257812, 0.241925001144409179, 300, 255, 1, "", 49936, NULL), +(3627, 187039, 530, 0, 0, 1, 2, 3930.541259765625, 6023.57421875, 270.066162109375, 3.089183330535888671, 0, 0, 0.99965667724609375, 0.026201646775007247, 300, 255, 1, "", 49936, NULL), +(3628, 187039, 530, 0, 0, 1, 2, 3959.75341796875, 6085.04736328125, 269.512725830078125, 3.560472726821899414, 0, 0, -0.97814750671386718, 0.207912087440490722, 300, 255, 1, "", 50063, NULL), +(3629, 187039, 530, 0, 0, 1, 2, 3972.138427734375, 5929.31884765625, 267.9949951171875, 2.478367090225219726, 0, 0, 0.94551849365234375, 0.325568377971649169, 300, 255, 1, "", 50063, NULL), +(3630, 187039, 530, 0, 0, 1, 2, 3974.123291015625, 6079.91064453125, 267.497100830078125, 4.223697185516357421, 0, 0, -0.85716724395751953, 0.515038192272186279, 300, 255, 1, "", 50063, NULL), +(3631, 187039, 530, 0, 0, 1, 2, 3981.595458984375, 6009.26123046875, 268.73297119140625, 2.949595451354980468, 0, 0, 0.995395660400390625, 0.095851235091686248, 300, 255, 1, "", 50063, NULL), +(3632, 187039, 530, 0, 0, 1, 2, 3995.835205078125, 6053.37451171875, 266.387481689453125, 3.420850038528442382, 0, 0, -0.99026775360107421, 0.139175355434417724, 300, 255, 1, "", 50063, NULL), +(3633, 187039, 530, 0, 0, 1, 2, 4002.076904296875, 6012.9033203125, 268.688873291015625, 0.872663915157318115, 0, 0, 0.422617912292480468, 0.906307935714721679, 300, 255, 1, "", 50063, NULL), +(3634, 187039, 530, 0, 0, 1, 2, 4009.73828125, 5926.0185546875, 268.410003662109375, 3.961898565292358398, 0, 0, -0.91705989837646484, 0.398749500513076782, 300, 255, 1, "", 50063, NULL), +(3635, 187039, 530, 0, 0, 1, 2, 4011.09765625, 5901.36767578125, 267.86163330078125, 0.191985160112380981, 0, 0, 0.095845222473144531, 0.995396256446838378, 300, 255, 1, "", 50063, NULL), +(3636, 187039, 530, 0, 0, 1, 2, 4032.626708984375, 5937.7568359375, 267.582672119140625, 1.274088263511657714, 0, 0, 0.594821929931640625, 0.80385744571685791, 300, 255, 1, "", 50063, NULL), +(3637, 187039, 530, 0, 0, 1, 2, 4040.290771484375, 5843.75634765625, 267.0892333984375, 3.403396368026733398, 0, 0, -0.99144458770751953, 0.130528271198272705, 300, 255, 1, "", 50063, NULL), +(3638, 187039, 530, 0, 0, 1, 2, 4043.84423828125, 5874.72314453125, 267.866729736328125, 2.862335443496704101, 0, 0, 0.990267753601074218, 0.139175355434417724, 300, 255, 1, "", 50063, NULL); + +-- remaining spawns (no sniffed values available) +-- (`guid` IN (47217, 47216, 47219, 47215, 47213, 47214, 47212, 47210, 47209, 28282, 28115)) From 4603e26b6ab5832ce337dfdf180259826e3d4f1e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Feb 2025 20:53:03 +0000 Subject: [PATCH 26/57] chore(DB): import pending files Referenced commit(s): 97471151e7a50612831092bef862ebd2073f6549 --- .../rev_1740599827613124400.sql => db_world/2025_02_26_03.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1740599827613124400.sql => db_world/2025_02_26_03.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1740599827613124400.sql b/data/sql/updates/db_world/2025_02_26_03.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1740599827613124400.sql rename to data/sql/updates/db_world/2025_02_26_03.sql index e35504b7d..e7b323fcc 100644 --- a/data/sql/updates/pending_db_world/rev_1740599827613124400.sql +++ b/data/sql/updates/db_world/2025_02_26_03.sql @@ -1,3 +1,4 @@ +-- DB update 2025_02_26_02 -> 2025_02_26_03 -- Update gameobject 'Smuggled Mana Cell' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (187039)) From fa0a8858e8e6042694204f189f9dc0c42b606b3d Mon Sep 17 00:00:00 2001 From: Ryan Turner Date: Thu, 27 Feb 2025 19:04:56 +0000 Subject: [PATCH 27/57] fix(DB/Item) - Envolpe Assignment loot no longer gives you empty loot. (#21073) --- data/sql/updates/pending_db_world/rev_1735665765897578900.sql | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1735665765897578900.sql diff --git a/data/sql/updates/pending_db_world/rev_1735665765897578900.sql b/data/sql/updates/pending_db_world/rev_1735665765897578900.sql new file mode 100644 index 000000000..c81fc64a3 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1735665765897578900.sql @@ -0,0 +1,3 @@ +-- +-- Change all assignment loot entries `flagsCustom` from 0 => 2 (CU_IGNORE_QUEST_STATUS) +UPDATE `item_template` SET `flagsCustom` = `flagsCustom` | 2 WHERE `entry` IN (21751, 21750, 21749, 21514, 21385, 21384, 21382, 21381, 21380, 21379, 21378, 21265, 21264, 21263, 21262, 21261, 21260, 21259, 21258, 21257, 21256, 21255, 21253, 21252, 21251, 21250, 21249, 21248, 21245, 21167, 21166, 21165, 20948, 20947, 20944, 20943, 20942, 20941, 20940, 20939, 20807, 20806); From 1c65032c0f934ccf460f07aea6e8eaf5f2097aa5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 27 Feb 2025 19:05:56 +0000 Subject: [PATCH 28/57] chore(DB): import pending files Referenced commit(s): fa0a8858e8e6042694204f189f9dc0c42b606b3d --- .../rev_1735665765897578900.sql => db_world/2025_02_27_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1735665765897578900.sql => db_world/2025_02_27_00.sql} (91%) diff --git a/data/sql/updates/pending_db_world/rev_1735665765897578900.sql b/data/sql/updates/db_world/2025_02_27_00.sql similarity index 91% rename from data/sql/updates/pending_db_world/rev_1735665765897578900.sql rename to data/sql/updates/db_world/2025_02_27_00.sql index c81fc64a3..15055f584 100644 --- a/data/sql/updates/pending_db_world/rev_1735665765897578900.sql +++ b/data/sql/updates/db_world/2025_02_27_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_02_26_03 -> 2025_02_27_00 -- -- Change all assignment loot entries `flagsCustom` from 0 => 2 (CU_IGNORE_QUEST_STATUS) UPDATE `item_template` SET `flagsCustom` = `flagsCustom` | 2 WHERE `entry` IN (21751, 21750, 21749, 21514, 21385, 21384, 21382, 21381, 21380, 21379, 21378, 21265, 21264, 21263, 21262, 21261, 21260, 21259, 21258, 21257, 21256, 21255, 21253, 21252, 21251, 21250, 21249, 21248, 21245, 21167, 21166, 21165, 20948, 20947, 20944, 20943, 20942, 20941, 20940, 20939, 20807, 20806); From b9cd73ae03d0405213b77e9b2450e74376865aae Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Fri, 28 Feb 2025 16:23:51 +0100 Subject: [PATCH 29/57] fix(DB/Creature) Various trash's issues on the road between Felmyst and Eredar Twins are now solved. (#21623) --- .../pending_db_world/Road_To_Twins.sql | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 data/sql/updates/pending_db_world/Road_To_Twins.sql diff --git a/data/sql/updates/pending_db_world/Road_To_Twins.sql b/data/sql/updates/pending_db_world/Road_To_Twins.sql new file mode 100644 index 000000000..9488b316d --- /dev/null +++ b/data/sql/updates/pending_db_world/Road_To_Twins.sql @@ -0,0 +1,119 @@ + +-- Add Waypoints +DELETE FROM `waypoint_data` WHERE `id` IN (14154200); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(14154200, 1, 1760.6979, 573.85925, 85.1191, NULL, 0, 0, 0, 100, 0), +(14154200, 2, 1756.0143, 568.31, 85.123055, NULL, 0, 0, 0, 100, 0), +(14154200, 3, 1752.3616, 564.8392, 85.12352, NULL, 0, 0, 0, 100, 0), +(14154200, 4, 1756.0143, 568.31, 85.123055, NULL, 0, 0, 0, 100, 0), +(14154200, 5, 1760.6979, 573.85925, 85.1191, NULL, 0, 0, 0, 100, 0), +(14154200, 6, 1764.0201, 578.5973, 85.11262, NULL, 0, 0, 0, 100, 0); + +DELETE FROM `waypoint_data` WHERE `id` IN (4376900); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(4376900, 1, 1598.7472, 584.1803, 84.95168, NULL, 0, 0, 0, 100, 0), +(4376900, 2, 1604.4705, 571.67554, 80.41126, NULL, 0, 0, 0, 100, 0), +(4376900, 3, 1614.62, 557.94464, 72.1739, NULL, 0, 0, 0, 100, 0), +(4376900, 4, 1630.1543, 541.5376, 62.263496, NULL, 0, 0, 0, 100, 0), +(4376900, 5, 1648.82, 527.84894, 52.854412, NULL, 0, 0, 0, 100, 0), +(4376900, 6, 1630.1543, 541.5376, 62.263496, NULL, 0, 0, 0, 100, 0), +(4376900, 7, 1614.62, 557.94464, 72.1739, NULL, 0, 0, 0, 100, 0), +(4376900, 8, 1604.4705, 571.67554, 80.41126, NULL, 0, 0, 0, 100, 0), +(4376900, 9, 1598.7472, 584.1803, 84.95168, NULL, 0, 0, 0, 100, 0), +(4376900, 10, 1594.0377, 597.88556, 85.11365, NULL, 0, 0, 0, 100, 0); + +DELETE FROM `waypoint_data` WHERE `id` IN (4374100); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(4374100, 1, 1660.8033, 507.39877, 50.56238, NULL, 0, 0, 0, 100, 0), +(4374100, 2, 1662.8678, 524.444, 50.562378, NULL, 0, 0, 0, 100, 0), +(4374100, 3, 1660.8033, 507.39877, 50.56238, NULL, 0, 0, 0, 100, 0), +(4374100, 4, 1655.2913, 495.21875, 50.562378, NULL, 0, 0, 0, 100, 0); + +DELETE FROM `waypoint_data` WHERE `id` IN (4402100); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(4402100, 1, 1770.5005, 498.57526, 74.143776, NULL, 0, 0, 0, 100, 0), +(4402100, 2, 1761.895, 511.81027, 80.350655, NULL, 0, 0, 0, 100, 0), +(4402100, 3, 1756.6216, 520.43225, 85.26244, NULL, 0, 0, 0, 100, 0), +(4402100, 4, 1747.6699, 535.4413, 85.2586, NULL, 0, 0, 0, 100, 0), +(4402100, 5, 1756.6216, 520.43225, 85.26244, NULL, 0, 0, 0, 100, 0), +(4402100, 6, 1761.895, 511.81027, 80.350655, NULL, 0, 0, 0, 100, 0), +(4402100, 7, 1770.5005, 498.57526, 74.143776, NULL, 0, 0, 0, 100, 0), +(4402100, 8, 1782.6758, 498.85693, 74.130875, NULL, 0, 0, 0, 100, 0), +(4402100, 9, 1790.207, 509.90317, 74.15089, NULL, 0, 0, 0, 100, 0), +(4402100, 10, 1783.75, 522.1627, 69.57731, NULL, 0, 0, 0, 100, 0), +(4402100, 11, 1774.7915, 537.0277, 62.078495, NULL, 0, 0, 0, 100, 0), +(4402100, 12, 1772.6086, 545.96106, 62.07849, NULL, 0, 0, 0, 100, 0), +(4402100, 13, 1781.791, 556.1232, 59.427723, NULL, 0, 0, 0, 100, 0), +(4402100, 14, 1792.0605, 567.6834, 53.94507, NULL, 0, 0, 0, 100, 0), +(4402100, 15, 1781.791, 556.1232, 59.427723, NULL, 0, 0, 0, 100, 0), +(4402100, 16, 1772.6086, 545.96106, 62.07849, NULL, 0, 0, 0, 100, 0), +(4402100, 17, 1774.7915, 537.0277, 62.078495, NULL, 0, 0, 0, 100, 0), +(4402100, 18, 1783.75, 522.1627, 69.57731, NULL, 0, 0, 0, 100, 0), +(4402100, 19, 1790.207, 509.90317, 74.15089, NULL, 0, 0, 0, 100, 0), +(4402100, 20, 1782.6758, 498.85693, 74.130875, NULL, 0, 0, 0, 100, 0); + +-- Remove Wrong npcs +DELETE FROM `creature` WHERE (`id1` = 25486) AND (`guid` IN (44464, 44948)); +DELETE FROM `creature` WHERE (`id1` = 25373) AND (`guid` IN (43740)); + +-- Remove deleted npcs from linked respawn +DELETE FROM `linked_respawn` WHERE (`guid` IN (43740, 44464)); + +-- Add new Npcs +DELETE FROM `creature` WHERE (`id1` = 25506) AND (`guid` IN (44948)); +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`) VALUES +(44948, 25506, 0, 0, 580, 0, 0, 1, 1, 1, 1759.415, 579.98596, 85.16913, 5.3494, 604800, 0, 0, 227630, 16155, 0, 0, 0, 0, '', 0); + +DELETE FROM `creature` WHERE (`id1` = 25837) AND (`guid` IN (141542)); +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`) VALUES +(141542, 25837, 0, 0, 580, 0, 0, 1, 1, 1, 1764.0201, 578.5973, 85.11262, 4.0692, 604800, 0, 0, 175935, 0, 2, 0, 0, 0, '', 0); + +-- Add new npcs in linked respawn +DELETE FROM `linked_respawn` WHERE (`guid` IN (44948, 141542)); +INSERT INTO `linked_respawn` (`guid`, `linkedGuid`, `linkType`) VALUES +(44948, 53668, 0), +(141542, 53668, 0); + +-- Update various NPCs positions and movement type +UPDATE `creature` SET `MovementType` = 2, `position_x` = 1655.2913, `position_y` = 495.21875, `position_z` = 50.562378, `orientation` = 1.2064 WHERE (`id1` = 25373) AND (`guid` IN (43741)); +UPDATE `creature` SET `MovementType` = 2, `position_x` = 1594.0377, `position_y` = 597.88556, `position_z` = 85.11365, `orientation` = 5.2748 WHERE (`id1` = 25373) AND (`guid` IN (43769)); +UPDATE `creature` SET `position_x` = 1560.3777, `position_y` = 561.6525, `position_z` = 50.655094, `orientation` = 5.1609 WHERE (`id1` = 25373) AND (`guid` IN (43772)); +UPDATE `creature` SET `position_x` = 1752.6904, `position_y` = 574.16266, `position_z` = 85.1591, `orientation` = 5.5261 WHERE (`id1` = 25486) AND (`guid` IN (44458)); +UPDATE `creature` SET `position_x` = 1762.0695, `position_y` = 562.6295, `position_z` = 85.28138, `orientation` = 2.3099 WHERE (`id1` = 25486) AND (`guid` IN (44421)); +UPDATE `creature` SET `position_x` = 1770.9169, `position_y` = 574.36676, `position_z` = 85.26621, `orientation` = 3.0639 WHERE (`id1` = 25483) AND (`guid` IN (44024)); +UPDATE `creature` SET `MovementType` = 2 WHERE (`id1` = 25483) AND (`guid` IN (44021)); + +-- Add creature_addon rows +DELETE FROM `creature_addon` WHERE (`guid` IN (43741, 43769, 44024, 141542, 44948, 44021)); +INSERT INTO `creature_addon` (`guid`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(43741, 4374100, 0, 0, 0, 0, 0, NULL), +(43769, 4376900, 0, 0, 0, 0, 0, NULL), +(141542, 14154200, 0, 0, 0, 0, 0, NULL), +(44024, 0, 0, 1, 0, 0, 0, NULL), +(44948, 0, 0, 1, 0, 0, 0, NULL), +(44021, 4402100, 0, 0, 0, 0, 0, NULL); + +-- Add Creature Formation +DELETE FROM `creature_formations` WHERE `leaderGUID` = 44021; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(44021, 44021, 0, 0, 515, 0, 0), +(44021, 45516, 2, 270, 515, 0, 0); + +-- Add don't override sai (Shadowsword Commander) +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|134217728 WHERE (`entry` IN (25837)); + +-- Add Comment (Shadowsword Commander) +UPDATE `creature` SET `Comment` = "has guid specific SAI" WHERE (`id1` = 25837) AND (`guid` IN (247107)); + +-- Update General sai (Shadowsword Commander) +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 25837; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 25837) AND (`source_type` = 0) AND (`id` IN (0, 1, 2, 3)); +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 +(25837, 0, 0, 0, 0, 0, 100, 0, 0, 0, 30000, 30000, 0, 0, 11, 46763, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shadowsword Commander - In Combat - Cast \'Battle Shout\''), +(25837, 0, 1, 0, 0, 0, 100, 0, 4000, 8000, 15000, 20000, 0, 0, 11, 46762, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Shadowsword Commander - In Combat - Cast \'Shield Slam\''); + +-- Update personal SmartAI (Shadowsword Commander) +DELETE FROM `smart_scripts` WHERE (`entryorguid` = -247107) AND (`source_type` = 0) AND (`id` IN (2)); +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 +(-247107, 0, 2, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 19, 25848, 200, 0, 0, 0, 0, 0, 0, 'Shadowsword Commander - On Just Died - Despawn Instant'); From 6930d2beda123196c9233fc65d08cefa3162b6df Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 28 Feb 2025 15:24:52 +0000 Subject: [PATCH 30/57] chore(DB): import pending files Referenced commit(s): b9cd73ae03d0405213b77e9b2450e74376865aae --- .../Road_To_Twins.sql => db_world/2025_02_28_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/Road_To_Twins.sql => db_world/2025_02_28_00.sql} (99%) diff --git a/data/sql/updates/pending_db_world/Road_To_Twins.sql b/data/sql/updates/db_world/2025_02_28_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/Road_To_Twins.sql rename to data/sql/updates/db_world/2025_02_28_00.sql index 9488b316d..d8981b28b 100644 --- a/data/sql/updates/pending_db_world/Road_To_Twins.sql +++ b/data/sql/updates/db_world/2025_02_28_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_02_27_00 -> 2025_02_28_00 -- Add Waypoints DELETE FROM `waypoint_data` WHERE `id` IN (14154200); From de6732da343d28690db2e0b7f045b093de0a904e Mon Sep 17 00:00:00 2001 From: Tereneckla Date: Sat, 1 Mar 2025 13:42:09 +0000 Subject: [PATCH 31/57] fix(Core/Spells): remove custom loop so that one lightning damage instance can only proc one lightning overload (#21625) --- src/server/game/Entities/Unit/Unit.cpp | 34 ++++++-------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 60721d04d..3445d6b3e 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -8412,37 +8412,17 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere if (!procSpell || !IsPlayer() || !victim) return false; + uint32 spell = procSpell->SpellFamilyFlags[0] & 0x2 ? 45297 : 45284; + if (procEx & PROC_EX_CRITICAL_HIT) damage /= 2; - // do not proc off from itself - if (procSpell->Id == 45297 || procSpell->Id == 45284) - { - return false; - } + // do not reduce damage-spells have correct basepoints + damage /= 2; + int32 dmg = damage; - do - { - uint32 spell = 0; - - if (procSpell->SpellFamilyFlags[0] & 0x2) - { - // 1/3 of 33% if 11% - if (!roll_chance_i(33)) - return false; - - spell = 45297; - } - else - spell = 45284; - - // do not reduce damage-spells have correct basepoints - damage /= 2; - int32 dmg = damage; - - // Cast - CastCustomSpell(victim, spell, &dmg, 0, 0, true, castItem, triggeredByAura); - } while (roll_chance_i(33)); + // Cast + CastCustomSpell(victim, spell, &dmg, 0, 0, true, castItem, triggeredByAura); return true; } // Static Shock From a3f7e1e76d93b91c089eef4c8dfcf7f61c98cc32 Mon Sep 17 00:00:00 2001 From: valsan-azerty-boi <52854501+valsan-azerty-boi@users.noreply.github.com> Date: Sat, 1 Mar 2025 16:01:10 +0100 Subject: [PATCH 32/57] feat(Core/BG): Allow battlegrounds to be configurable (#20320) (#21124) --- .../apps/worldserver/worldserver.conf.dist | 44 +++++++++++++++++++ .../Battlegrounds/Zones/BattlegroundAB.cpp | 14 +++--- .../game/Battlegrounds/Zones/BattlegroundAB.h | 1 + .../Battlegrounds/Zones/BattlegroundAV.cpp | 15 +++++-- .../game/Battlegrounds/Zones/BattlegroundAV.h | 12 ++--- .../Battlegrounds/Zones/BattlegroundEY.cpp | 13 ++++-- .../game/Battlegrounds/Zones/BattlegroundEY.h | 1 + .../Battlegrounds/Zones/BattlegroundWS.cpp | 11 +++-- .../game/Battlegrounds/Zones/BattlegroundWS.h | 1 + src/server/game/World/IWorld.h | 5 +++ src/server/game/World/World.cpp | 6 +++ 11 files changed, 101 insertions(+), 22 deletions(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 484c4736e..6853dd54b 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -3698,6 +3698,50 @@ Battleground.SpeedBuffRespawn = 150 Battleground.Override.LowLevels.MinPlayers = 0 +# +# Battleground.Warsong.Flags +# Description: Set the number of flags required for a team to win in Warsong battleground +# Default: 3 (Blizzlike) +# 1 (Minimum) + +Battleground.Warsong.Flags = 3 + +# +# Battleground.Arathi.CapturePoints +# Description: Set the number of capture points required for a team to win in Arathi battleground +# Default: 1600 (WotLK) +# 2000 (Vanilla) + +Battleground.Arathi.CapturePoints = 1600 + +# +# Battleground.Alterac.Reinforcements +# Description: Set the number of total reinforcements for each teams in Alterac battleground +# (It is necessary to restart the server after changing the Reinforcements value) +# Default: 600 (Enabled, WotLK) +# 500 (Enabled, MoP) +# 0 (Disabled, early Vanilla, victory only on boss death) + +Battleground.Alterac.Reinforcements = 600 + +# +# Battleground.Alterac.ReputationOnBossDeath +# Description: Set the number of rep point given for a boss killed in Alterac battleground +# (It is necessary to restart the server after changing the ReputationOnBossDeath value) +# Default: 350 (WotLK) +# 389 (Vanilla) + +Battleground.Alterac.ReputationOnBossDeath = 350 + +# +# Battleground.EyeOfTheStorm.CapturePoints +# Description: Set the number of capture points required for a team to win in Eye of the Storm battleground +# (The UI part of the max team score will not be compliant with this parameter without client modification) +# Default: 1600 (WotLK, UI compliant) +# 2000 (TBC, not UI compliant) + +Battleground.EyeOfTheStorm.CapturePoints = 1600 + # ################################################################################################### diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index b9064de35..b105cb27e 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -108,8 +108,8 @@ void BattlegroundAB::PostUpdateImpl(uint32 diff) auto reputationRewards = uint8(m_TeamScores[teamId] / _reputationTics); auto information = uint8(m_TeamScores[teamId] / BG_AB_WARNING_NEAR_VICTORY_SCORE); m_TeamScores[teamId] += BG_AB_TickPoints[controlledPoints]; - if (m_TeamScores[teamId] > BG_AB_MAX_TEAM_SCORE) - m_TeamScores[teamId] = BG_AB_MAX_TEAM_SCORE; + if (m_TeamScores[teamId] > static_cast(_configurableMaxTeamScore)) + m_TeamScores[teamId] = _configurableMaxTeamScore; if (honorRewards < uint8(m_TeamScores[teamId] / _honorTics)) RewardHonorToTeam(GetBonusHonorFromKill(1), teamId); @@ -132,7 +132,7 @@ void BattlegroundAB::PostUpdateImpl(uint32 diff) UpdateWorldState(teamId == TEAM_ALLIANCE ? BG_AB_OP_RESOURCES_ALLY : BG_AB_OP_RESOURCES_HORDE, m_TeamScores[teamId]); if (m_TeamScores[teamId] > m_TeamScores[GetOtherTeamId(teamId)] + 500) _teamScores500Disadvantage[GetOtherTeamId(teamId)] = true; - if (m_TeamScores[teamId] >= BG_AB_MAX_TEAM_SCORE) + if (m_TeamScores[teamId] >= static_cast(_configurableMaxTeamScore)) EndBattleground(teamId); _bgEvents.ScheduleEvent(eventId, BG_AB_TickIntervals[controlledPoints]); @@ -245,12 +245,11 @@ void BattlegroundAB::FillInitialWorldStates(WorldPackets::WorldState::InitWorldS for (uint8 i = BG_AB_NODE_STATE_ALLY_OCCUPIED; i <= BG_AB_NODE_STATE_HORDE_CONTESTED; ++i) packet.Worldstates.emplace_back(node._iconCapture + i - 1, node._state == i ? 1 : 0); - } packet.Worldstates.emplace_back(BG_AB_OP_OCCUPIED_BASES_ALLY, _controlledPoints[TEAM_ALLIANCE]); packet.Worldstates.emplace_back(BG_AB_OP_OCCUPIED_BASES_HORDE, _controlledPoints[TEAM_HORDE]); - packet.Worldstates.emplace_back(BG_AB_OP_RESOURCES_MAX, BG_AB_MAX_TEAM_SCORE); + packet.Worldstates.emplace_back(BG_AB_OP_RESOURCES_MAX, _configurableMaxTeamScore); packet.Worldstates.emplace_back(BG_AB_OP_RESOURCES_WARNING, BG_AB_WARNING_NEAR_VICTORY_SCORE); packet.Worldstates.emplace_back(BG_AB_OP_RESOURCES_ALLY, m_TeamScores[TEAM_ALLIANCE]); packet.Worldstates.emplace_back(BG_AB_OP_RESOURCES_HORDE, m_TeamScores[TEAM_HORDE]); @@ -481,6 +480,11 @@ void BattlegroundAB::Init() _capturePointInfo[BG_AB_NODE_BLACKSMITH]._iconCapture = BG_AB_OP_BLACKSMITH_STATE_ALIENCE; _capturePointInfo[BG_AB_NODE_LUMBER_MILL]._iconCapture = BG_AB_OP_LUMBERMILL_STATE_ALIENCE; _capturePointInfo[BG_AB_NODE_GOLD_MINE]._iconCapture = BG_AB_OP_GOLDMINE_STATE_ALIENCE; + + uint32 bgArathiCapturePointsConfig = sWorld->getIntConfig(CONFIG_BATTLEGROUND_ARATHI_CAPTUREPOINTS); + _configurableMaxTeamScore = bgArathiCapturePointsConfig > 0 + ? bgArathiCapturePointsConfig + : static_cast(BG_AB_MAX_TEAM_SCORE); } void BattlegroundAB::EndBattleground(TeamId winnerTeamId) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h index b63b9fae9..2dfbc0f49 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h @@ -341,5 +341,6 @@ private: uint32 _reputationTics; uint8 _controlledPoints[PVP_TEAMS_COUNT] {}; bool _teamScores500Disadvantage[PVP_TEAMS_COUNT] {}; + uint32 _configurableMaxTeamScore; }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp index f4c601fa8..99dbfd11c 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp @@ -266,6 +266,9 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player) void BattlegroundAV::UpdateScore(TeamId teamId, int16 points) { + if (BG_AV_SCORE_INITIAL_POINTS == 0) + return; // don't update teamscores if reinforcements are disabled + //note: to remove reinforcementpoints points must be negative, for adding reinforcements points must be positive m_Team_Scores[teamId] += points; @@ -475,8 +478,11 @@ void BattlegroundAV::StartingEventOpenDoors() for (uint8 mine = AV_NORTH_MINE; mine <= AV_SOUTH_MINE; mine++) //mine population ChangeMineOwner(mine, TEAM_NEUTRAL, true); - UpdateWorldState(AV_SHOW_H_SCORE, 1); - UpdateWorldState(AV_SHOW_A_SCORE, 1); + if (BG_AV_SCORE_INITIAL_POINTS > 0) // display teamscores on top only if reinforcements are enabled + { + UpdateWorldState(AV_SHOW_H_SCORE, 1); + UpdateWorldState(AV_SHOW_A_SCORE, 1); + } DoorOpen(BG_AV_OBJECT_DOOR_H); DoorOpen(BG_AV_OBJECT_DOOR_A); @@ -1114,11 +1120,12 @@ void BattlegroundAV::FillInitialWorldStates(WorldPackets::WorldState::InitWorldS { packet.Worldstates.emplace_back(AV_SNOWFALL_N, 1); } + packet.Worldstates.emplace_back(AV_Alliance_Score, m_Team_Scores[0]); packet.Worldstates.emplace_back(AV_Horde_Score, m_Team_Scores[1]); - packet.Worldstates.emplace_back(AV_SHOW_A_SCORE, GetStatus() == STATUS_IN_PROGRESS ? 1 : 0); - packet.Worldstates.emplace_back(AV_SHOW_H_SCORE, GetStatus() == STATUS_IN_PROGRESS ? 1 : 0); + packet.Worldstates.emplace_back(AV_SHOW_A_SCORE, GetStatus() == STATUS_IN_PROGRESS && BG_AV_SCORE_INITIAL_POINTS > 0 ? 1 : 0); + packet.Worldstates.emplace_back(AV_SHOW_H_SCORE, GetStatus() == STATUS_IN_PROGRESS && BG_AV_SCORE_INITIAL_POINTS > 0 ? 1 : 0); SendMineWorldStates(AV_NORTH_MINE); SendMineWorldStates(AV_SOUTH_MINE); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h index e0195206a..a9b9ada7e 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h @@ -21,14 +21,14 @@ #include "Battleground.h" #include "BattlegroundScore.h" -#define BG_AV_CAPTIME 240000 //4:00 -#define BG_AV_SNOWFALL_FIRSTCAP 300000 //5:00 but i also have seen 4:05 +#define BG_AV_CAPTIME 240000 //4:00 +#define BG_AV_SNOWFALL_FIRSTCAP 300000 //5:00 but i also have seen 4:05 -#define BG_AV_SCORE_INITIAL_POINTS 600 -#define SEND_MSG_NEAR_LOSE 120 +#define BG_AV_SCORE_INITIAL_POINTS (sWorld->getIntConfig(CONFIG_BATTLEGROUND_ALTERAC_REINFORCEMENTS)) // Blizzlike default is 600 +#define SEND_MSG_NEAR_LOSE 120 #define BG_AV_KILL_BOSS 4 -#define BG_AV_REP_BOSS 350 +#define BG_AV_REP_BOSS (sWorld->getIntConfig(CONFIG_BATTLEGROUND_ALTERAC_REP_ONBOSSDEATH)) // Blizzlike default is 350 #define BG_AV_KILL_CAPTAIN 3 #define BG_AV_REP_CAPTAIN 125 @@ -38,7 +38,7 @@ #define BG_AV_REP_TOWER 12 #define BG_AV_RES_TOWER 75 -#define BG_AV_GET_COMMANDER 1 //for a safely returned wingcommander +#define BG_AV_GET_COMMANDER 1 //for a safely returned wingcommander //bonushonor at the end #define BG_AV_KILL_SURVIVING_TOWER 2 #define BG_AV_REP_SURVIVING_TOWER 12 diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index 8cf1f7813..4f9f608c6 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -114,14 +114,14 @@ void BattlegroundEY::AddPoints(TeamId teamId, uint32 points) { uint8 honorRewards = uint8(m_TeamScores[teamId] / _honorTics); m_TeamScores[teamId] += points; - if (m_TeamScores[teamId] > BG_EY_MAX_TEAM_SCORE) - m_TeamScores[teamId] = BG_EY_MAX_TEAM_SCORE; + if (m_TeamScores[teamId] > static_cast(_configurableMaxTeamScore)) + m_TeamScores[teamId] = _configurableMaxTeamScore; for (; honorRewards < uint8(m_TeamScores[teamId] / _honorTics); ++honorRewards) RewardHonorToTeam(GetBonusHonorFromKill(1), teamId); - UpdateWorldState(teamId == TEAM_ALLIANCE ? EY_ALLIANCE_RESOURCES : EY_HORDE_RESOURCES, std::min(m_TeamScores[teamId], BG_EY_MAX_TEAM_SCORE)); - if (m_TeamScores[teamId] >= BG_EY_MAX_TEAM_SCORE) + UpdateWorldState(teamId == TEAM_ALLIANCE ? EY_ALLIANCE_RESOURCES : EY_HORDE_RESOURCES, std::min(m_TeamScores[teamId], _configurableMaxTeamScore)); + if (m_TeamScores[teamId] >= static_cast(_configurableMaxTeamScore)) EndBattleground(teamId); } @@ -362,6 +362,11 @@ void BattlegroundEY::Init() _droppedFlagGUID.Clear(); _flagState = BG_EY_FLAG_STATE_ON_BASE; _flagCapturedObject = 0; + + uint32 bgEyCapturePointsConfig = sWorld->getIntConfig(CONFIG_BATTLEGROUND_EYEOFTHESTORM_CAPTUREPOINTS); + _configurableMaxTeamScore = bgEyCapturePointsConfig > 0 + ? bgEyCapturePointsConfig + : static_cast(BG_EY_MAX_TEAM_SCORE); } void BattlegroundEY::RespawnFlag() diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h index acd51fddc..f80416c1a 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h @@ -456,5 +456,6 @@ private: ObjectGuid _droppedFlagGUID; uint8 _flagState; uint32 _flagCapturedObject; + uint32 _configurableMaxTeamScore; }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index 64f30a7a0..da875ad3e 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -222,10 +222,10 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player) RewardHonorToTeam(GetBonusHonorFromKill(2), player->GetTeamId()); - if (GetTeamScore(TEAM_ALLIANCE) == BG_WS_MAX_TEAM_SCORE || GetTeamScore(TEAM_HORDE) == BG_WS_MAX_TEAM_SCORE) + if (GetTeamScore(TEAM_ALLIANCE) == _configurableMaxTeamScore || GetTeamScore(TEAM_HORDE) == _configurableMaxTeamScore) { UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 0); - EndBattleground(GetTeamScore(TEAM_HORDE) == BG_WS_MAX_TEAM_SCORE ? TEAM_HORDE : TEAM_ALLIANCE); + EndBattleground(GetTeamScore(TEAM_HORDE) == _configurableMaxTeamScore ? TEAM_HORDE : TEAM_ALLIANCE); } else _bgEvents.ScheduleEvent(BG_WS_EVENT_RESPAWN_BOTH_FLAGS, BG_WS_FLAG_RESPAWN_TIME); @@ -497,6 +497,11 @@ void BattlegroundWS::Init() _honorWinKills = 1; _honorEndKills = 2; } + + uint32 bgWarsongFlagsConfig = sWorld->getIntConfig(CONFIG_BATTLEGROUND_WARSONG_FLAGS); + _configurableMaxTeamScore = bgWarsongFlagsConfig > 0 + ? bgWarsongFlagsConfig + : static_cast(BG_WS_MAX_TEAM_SCORE); } void BattlegroundWS::EndBattleground(TeamId winnerTeamId) @@ -551,7 +556,7 @@ void BattlegroundWS::FillInitialWorldStates(WorldPackets::WorldState::InitWorldS packet.Worldstates.reserve(7); packet.Worldstates.emplace_back(BG_WS_FLAG_CAPTURES_ALLIANCE, GetTeamScore(TEAM_ALLIANCE)); packet.Worldstates.emplace_back(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(TEAM_HORDE)); - packet.Worldstates.emplace_back(BG_WS_FLAG_CAPTURES_MAX, BG_WS_MAX_TEAM_SCORE); + packet.Worldstates.emplace_back(BG_WS_FLAG_CAPTURES_MAX, _configurableMaxTeamScore); packet.Worldstates.emplace_back(BG_WS_STATE_TIMER_ACTIVE, GetStatus() == STATUS_IN_PROGRESS ? 1 : 0); packet.Worldstates.emplace_back(BG_WS_STATE_TIMER, GetMatchTime()); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h index 5b97d5d39..e5c1560bd 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h @@ -272,6 +272,7 @@ private: uint32 _reputationCapture; uint32 _honorWinKills; uint32 _honorEndKills; + uint32 _configurableMaxTeamScore; void PostUpdateImpl(uint32 diff) override; }; diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index a8afd153e..3386d8049 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -318,6 +318,11 @@ enum WorldIntConfigs CONFIG_BATTLEGROUND_SPEED_BUFF_RESPAWN, CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_LIMIT_MIN_LEVEL, CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_LIMIT_MIN_PLAYERS, + CONFIG_BATTLEGROUND_WARSONG_FLAGS, + CONFIG_BATTLEGROUND_ARATHI_CAPTUREPOINTS, + CONFIG_BATTLEGROUND_ALTERAC_REINFORCEMENTS, + CONFIG_BATTLEGROUND_ALTERAC_REP_ONBOSSDEATH, + CONFIG_BATTLEGROUND_EYEOFTHESTORM_CAPTUREPOINTS, CONFIG_WINTERGRASP_ENABLE, CONFIG_ARENA_MAX_RATING_DIFFERENCE, CONFIG_ARENA_RATING_DISCARD_TIMER, diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 1ab024299..097d4f655 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -927,6 +927,12 @@ void World::LoadConfigSettings(bool reload) _int_configs[CONFIG_BATTLEGROUND_SPEED_BUFF_RESPAWN] = 150; } + _int_configs[CONFIG_BATTLEGROUND_WARSONG_FLAGS] = sConfigMgr->GetOption("Battleground.Warsong.Flags", 3); + _int_configs[CONFIG_BATTLEGROUND_ARATHI_CAPTUREPOINTS] = sConfigMgr->GetOption("Battleground.Arathi.CapturePoints", 1600); + _int_configs[CONFIG_BATTLEGROUND_ALTERAC_REINFORCEMENTS] = sConfigMgr->GetOption("Battleground.Alterac.Reinforcements", 600); + _int_configs[CONFIG_BATTLEGROUND_ALTERAC_REP_ONBOSSDEATH] = sConfigMgr->GetOption("Battleground.Alterac.ReputationOnBossDeath", 350); + _int_configs[CONFIG_BATTLEGROUND_EYEOFTHESTORM_CAPTUREPOINTS] = sConfigMgr->GetOption("Battleground.EyeOfTheStorm.CapturePoints", 1600); + _int_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfigMgr->GetOption("Arena.MaxRatingDifference", 150); _int_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfigMgr->GetOption("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILLISECONDS); _int_configs[CONFIG_ARENA_PREV_OPPONENTS_DISCARD_TIMER] = sConfigMgr->GetOption("Arena.PreviousOpponentsDiscardTimer", 2 * MINUTE * IN_MILLISECONDS); From c7981bea852d12e8f2e01ff5ce57b7abc3fc8f76 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:39:30 +0100 Subject: [PATCH 33/57] fix(DB/Text) Add correct text on Sunblade Scouts. (#21626) --- data/sql/updates/pending_db_world/Scout_text.sql | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 data/sql/updates/pending_db_world/Scout_text.sql diff --git a/data/sql/updates/pending_db_world/Scout_text.sql b/data/sql/updates/pending_db_world/Scout_text.sql new file mode 100644 index 000000000..de7d1d676 --- /dev/null +++ b/data/sql/updates/pending_db_world/Scout_text.sql @@ -0,0 +1,5 @@ + +-- Correct text +DELETE FROM `creature_text` WHERE (`CreatureID` = 25372) AND (`GroupID` IN (0)); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(25372, 0, 0, 'Enemies spotted! Attack while I try to activate a Protector!', 14, 0, 100, 0, 0, 0, 25202, 0, 'Sunblade Scout'); From f9ca059868bb44cba8865ab7835713cd195e4608 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 1 Mar 2025 19:40:30 +0000 Subject: [PATCH 34/57] chore(DB): import pending files Referenced commit(s): c7981bea852d12e8f2e01ff5ce57b7abc3fc8f76 --- .../Scout_text.sql => db_world/2025_03_01_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/Scout_text.sql => db_world/2025_03_01_00.sql} (90%) diff --git a/data/sql/updates/pending_db_world/Scout_text.sql b/data/sql/updates/db_world/2025_03_01_00.sql similarity index 90% rename from data/sql/updates/pending_db_world/Scout_text.sql rename to data/sql/updates/db_world/2025_03_01_00.sql index de7d1d676..4cf22fe7a 100644 --- a/data/sql/updates/pending_db_world/Scout_text.sql +++ b/data/sql/updates/db_world/2025_03_01_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_02_28_00 -> 2025_03_01_00 -- Correct text DELETE FROM `creature_text` WHERE (`CreatureID` = 25372) AND (`GroupID` IN (0)); From 3834bac43d6f34a0aaa9de3f254b7bd37a89980a Mon Sep 17 00:00:00 2001 From: p-tkachuk Date: Sat, 1 Mar 2025 21:50:13 +0100 Subject: [PATCH 35/57] fix (Core/Wintergrasp) Change spell used by WG NPCs (#21621) Co-authored-by: Hexadecimal --- src/server/scripts/Northrend/zone_wintergrasp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/Northrend/zone_wintergrasp.cpp b/src/server/scripts/Northrend/zone_wintergrasp.cpp index 56aa104a6..9dbbd68f4 100644 --- a/src/server/scripts/Northrend/zone_wintergrasp.cpp +++ b/src/server/scripts/Northrend/zone_wintergrasp.cpp @@ -279,7 +279,7 @@ enum eWgQueue NPC_ARCANIST_BRAEDIN = 32169, NPC_MAGISTER_SURDIEL = 32170, - SPELL_FROST_ARMOR = 31256 + SPELL_FROST_ARMOR = 12544 }; class npc_wg_queue : public CreatureScript From 9a6078a2629013e83b401a56d2e694bcc83519b7 Mon Sep 17 00:00:00 2001 From: p-tkachuk Date: Sat, 1 Mar 2025 21:51:46 +0100 Subject: [PATCH 36/57] fix (Core/Wintergrasp) Icon now disappears when player leaves queue (#21619) Co-authored-by: Hexadecimal --- src/server/game/Battlefield/Battlefield.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 0b25e18d1..e8655f413 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -403,6 +403,8 @@ void Battlefield::AskToLeaveQueue(Player* player) { // Remove player from queue m_PlayersInQueue[player->GetTeamId()].erase(player->GetGUID()); + // Send notification + player->GetSession()->SendBfLeaveMessage(m_BattleId, BF_LEAVE_REASON_CLOSE); } // Called in WorldSession::HandleHearthAndResurrect From 00df52ff192f231978d2858e5a98ac0fbd060628 Mon Sep 17 00:00:00 2001 From: p-tkachuk Date: Sat, 1 Mar 2025 21:53:05 +0100 Subject: [PATCH 37/57] fix (Core/Wintergrasp) hearthstone was visibly on cooldown when player left WG (#21620) Co-authored-by: Hexadecimal --- src/server/game/Battlefield/Battlefield.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index e8655f413..e6e086463 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -410,8 +410,8 @@ void Battlefield::AskToLeaveQueue(Player* player) // Called in WorldSession::HandleHearthAndResurrect void Battlefield::PlayerAskToLeave(Player* player) { - // Player leaving Wintergrasp, trigger Hearthstone spell. - player->CastSpell(player, 8690, true); + // Player leaving Wintergrasp, teleport to homebind possition. + player->TeleportTo(player->m_homebindMapId, player->m_homebindX, player->m_homebindY, player->m_homebindZ, player->GetOrientation()); } // Called in WorldSession::HandleBfEntryInviteResponse From b7e33283a5755bb85a7beee8acdfbac7c32ff231 Mon Sep 17 00:00:00 2001 From: Ryan Turner Date: Sat, 1 Mar 2025 23:33:10 +0000 Subject: [PATCH 38/57] feat(DB): clarify IDs for faction changes (#20480) --- .../rev_1731031220479040900.sql | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1731031220479040900.sql diff --git a/data/sql/updates/pending_db_world/rev_1731031220479040900.sql b/data/sql/updates/pending_db_world/rev_1731031220479040900.sql new file mode 100644 index 000000000..bc83a7b91 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1731031220479040900.sql @@ -0,0 +1,159 @@ +-- Adding COMMENT COLUMN +-- Achievements +ALTER TABLE `player_factionchange_achievement` +ADD `alliance_comment` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci' AFTER `alliance_id`, +ADD `horde_comment` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci' AFTER `horde_id`; +-- Reputations +ALTER TABLE `player_factionchange_reputations` +ADD `alliance_comment` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci' AFTER `alliance_id`, +ADD `horde_comment` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci' AFTER `horde_id`; + +-- Adding Achievements +DELETE FROM `player_factionchange_achievement` WHERE `alliance_id` IN +(33,34,35,37,41,58,202,203,206,220,225,230,246,388,433,434,435,436,437,438,439,440,441,442,470,471,472,473,604,610,611,612,613,614,701,707,709,711,713,764,899,907,908,942,948,963,966,969,970,1012,1022,1023,1024,1028,1029,1030,1034,1035,1038,1040,1151,1167,1169,1172,1184,1189,1191,1192,1255,1262,1279,1466,1563,1656,1676,1678,1681,1684,1686,1692,1697,1707,1737,1752,1757,1762,1782,2016,2144,2194,2419,2421,2536,2760,2761,2762,2763,2764,2770,2777,2778,2779,2780,2781,2782,2797,2817,3356,3478,3556,3576,3580,3596,3676,3846,3851,3856,3857,4156,4296,4298,4436,4784,4786); +INSERT INTO `player_factionchange_achievement` (`alliance_id`, `alliance_comment`, `horde_id`, `horde_comment`) VALUES +-- Achievements +(33, "Nothing Boring About Borean", 1358, "Nothing Boring About Borean"), +(34, "I've Toured the Fjord", 1356, "I've Toured the Fjord"), +(35, "Might of Dragonblight", 1359, "Might of Dragonblight"), +(37, "Fo' Grizzle My Shizzle", 1357, "Fo' Grizzle My Shizzle"), +(41, "Loremaster of Northrend", 1360, "Loremaster of Northrend"), +(58, "Deaths from Drek'Thar", 593, "Deaths from Vanndar Stormpike"), +(202, "Quick Cap", 1502, "Quick Cap"), +(203, "Not In My House", 1251, "Not In My House"), +(206, "Supreme Defender", 1252, "Supreme Defender"), +(220, "Stormpike Perfection", 873, "Frostwolf Perfection"), +(225, "Everything Counts", 1164, "Everything Counts"), +(230, "Battlemaster", 1175, "Battlemaster"), +(246, "Know Thy Enemy", 1005, "Know Thy Enemy"), +(388, "City Defender", 1006, "City Defender"), +(433, "Grand Marshal", 443, "High Warlord"), +(434, "Field Marshal", 445, "Warlord"), +(435, "Commander", 444, "Lieutenant General"), +(436, "Lieutenant Commander", 447, "Champion"), +(437, "Knight-Champion", 448, "Centurion"), +(438, "Knight-Captain", 469, "Legionnaire"), +(439, "Knight", 451, "Stone Guard"), +(440, "Sergeant Major", 452, "First Sergeant"), +(441, "Master Sergeant", 450, "Senior Sergeant"), +(442, "Private", 454, "Scout"), +(470, "Corporal", 468, "Grunt"), +(471, "Sergeant", 453, "Sergeant"), +(472, "Knight-Lieutenant", 449, "Blood Guard"), +(473, "Marshal", 446, "General"), +(604, "Wrath of the Alliance", 603, "Wrath of the Horde"), +(610, "Death to the Warchief!", 615, "Storming Stormwind"), +(611, "Bleeding Bloodhoof", 616, "Death to the King!"), +(612, "Downing the Dark Lady", 617, "Immortal No More"), +(613, "Killed in Quel'Thalas", 618, "Putting Out the Light"), +(614, "For The Alliance!", 619, "For The Horde!"), +(701, "Freedom of the Alliance", 700, "Freedom of the Horde"), +(707, "Stormpike Battle Charger", 706, "Frostwolf Howler"), +(709, "Hero of the Stormpike Guard", 708, "Hero of the Frostwolf Clan"), +(711, "Knight of Arathor", 710, "The Defiler"), +(713, "Silverwing Sentinel", 712, "Warsong Outrider"), +(764, "The Burning Crusader", 763, "The Burning Crusader"), +(899, "Oh My, Kurenai", 901, "Mag'har of Draenor"), +(907, "The Justicar", 714, "The Conqueror"), +(908, "Call to Arms!", 909, "Call to Arms!"), +(942, "The Diplomat", 943, "The Diplomat"), +(948, "Ambassador of the Alliance", 762, "Ambassador of the Horde"), +(963, "Tricks and Treats of Kalimdor", 965, "Tricks and Treats of Kalimdor"), +(966, "Tricks and Treats of Eastern Kingdoms", 967, "Tricks and Treats of Eastern Kingdoms"), +(969, "Tricks and Treats of Outland", 968, "Tricks and Treats of Outland"), +(970, "Tricks and Treats of Azeroth", 971, "Tricks and Treats of Azeroth"), +(1012, "The Winds of the North", 1011, "The Winds of the North"), +(1022, "Flame Warden of Eastern Kingdoms", 1025, "Flame Keeper of Eastern Kingdoms"), +(1023, "Flame Warden of Kalimdor", 1026, "Flame Keeper of Kalimdor"), +(1024, "Flame Warden of Outland", 1027, "Flame Keeper of Outland"), +(1028, "Extinguishing Eastern Kingdoms", 1031, "Extinguishing Eastern Kingdoms"), +(1029, "Extinguishing Kalimdor", 1032, "Extinguishing Kalimdor"), +(1030, "Extinguishing Outland", 1033, "Extinguishing Outland"), +(1034, "The Fires of Azeroth", 1036, "The Fires of Azeroth"), +(1035, "Desecration of the Horde", 1037, "Desecration of the Alliance"), +(1038, "The Flame Warden", 1039, "The Flame Keeper"), +(1040, "Rotten Hallow", 1041, "Rotten Hallow"), +(1151, "Loyal Defender", 224, "Loyal Defender"), +(1167, "Master of Alterac Valley", 1168, "Master of Alterac Valley"), +(1169, "Master of Arathi Basin", 1170, "Master of Arathi Basin"), +(1172, "Master of Warsong Gulch", 1173, "Master of Warsong Gulch"), +(1184, "Strange Brew", 1203, "Strange Brew"), +(1189, "To Hellfire and Back", 1271, "To Hellfire and Back"), +(1191, "Terror of Terokkar", 1272, "Terror of Terokkar"), +(1192, "Nagrand Slam", 1273, "Nagrand Slam"), +(1255, "Scrooge", 259, "Scrooge"), +(1262, "Loremaster of Outland", 1274, "Loremaster of Outland"), +(1279, "Flirt With Disaster", 1280, "Flirt With Disaster"), +(1466, "Most Alliance factions at Exalted", 926, "Most Horde factions at Exalted"), +(1563, "Hail to the Chef", 1784, "Hail to the Chef"), +(1656, "Hallowed Be Thy Name", 1657, "Hallowed Be Thy Name"), +(1676, "Loremaster of Eastern Kingdoms", 1677, "Loremaster of Eastern Kingdoms"), +(1678, "Loremaster of Kalimdor", 1680, "Loremaster of Kalimdor"), +(1681, "The Loremaster", 1682, "The Loremaster"), +(1684, "Brewmaster", 1683, "Brewmaster"), +(1686, "Bros. Before Ho Ho Ho's", 1685, "Bros. Before Ho Ho Ho's"), +(1692, "Merrymaker", 1691, "Merrymaker"), +(1697, "Nation of Adoration", 1698, "Nation of Adoration"), +(1707, "Fool For Love", 1693, "Fool For Love"), +(1737, "Destruction Derby", 2476, "Destruction Derby"), +(1752, "Master of Wintergrasp", 2776, "Master of Wintergrasp"), +(1757, "Defense of the Ancients", 2200, "Defense of the Ancients"), +(1762, "Not Even a Scratch", 2192, "Not Even a Scratch"), +(1782, "Our Daily Bread", 1783, "Our Daily Bread"), +(2016, "Grizzled Veteran", 2017, "Grizzled Veteran"), +(2144, "What A Long, Strange Trip It's Been", 2145, "What A Long, Strange Trip It's Been"), +(2194, "Master of Strand of the Ancients", 2195, "Master of Strand of the Ancients"), +(2419, "Spring Fling", 2497, "Spring Fling"), +(2421, "Noble Garden", 2420, "Noble Garden"), +(2536, "Mountain o' Mounts", 2537, "Mountain o' Mounts"), +(2760, "Exalted Champion of Darnassus", 2768, "Exalted Champion of Thunder Bluff"), +(2761, "Exalted Champion of the Exodar", 2767, "Exalted Champion of Silvermoon City"), +(2762, "Exalted Champion of Gnomeregan", 2766, "Exalted Champion of Sen'jin"), +(2763, "Exalted Champion of Ironforge", 2769, "Exalted Champion of the Undercity"), +(2764, "Exalted Champion of Stormwind", 2765, "Exalted Champion of Orgrimmar"), +(2770, "Exalted Champion of the Alliance", 2771, "Exalted Champion of the Horde"), +(2777, "Champion of Darnassus", 2786, "Champion of Thunder Bluff"), +(2778, "Champion of the Exodar", 2785, "Champion of Silvermoon City"), +(2779, "Champion of Gnomeregan", 2784, "Champion of Sen'jin"), +(2780, "Champion of Ironforge", 2787, "Champion of the Undercity"), +(2781, "Champion of Stormwind", 2783, "Champion of Orgrimmar"), +(2782, "Champion of the Alliance", 2788, "Champion of the Horde"), +(2797, "Noble Gardener", 2798, "Noble Gardener"), +(2817, "Exalted Argent Champion of the Alliance", 2816, "Exalted Argent Champion of the Horde"), +(3356, "Winterspring Frostsaber", 3357, "Venomhide Ravasaur"), +(3478, "Pilgrim", 3656, "Pilgrim"), +(3556, "Pilgrim's Paunch", 3557, "Pilgrim's Paunch"), +(3576, "Now We're Cookin'", 3577, "Now We're Cookin'"), +(3580, "Pilgrim's Peril", 3581, "Pilgrim's Peril"), +(3596, "Pilgrim's Progress", 3597, "Pilgrim's Progress"), +(3676, "A Silver Confidant", 3677, "The Sunreavers"), +(3846, "Resource Glut", 4176, "Resource Glut"), +(3851, "Mine", 4177, "Mine"), +(3856, "Demolition Derby", 4256, "Demolition Derby"), +(3857, "Master of Isle of Conquest", 3957, "Master of Isle of Conquest"), +(4156, "A Tribute to Immortality", 4079, "A Tribute to Immortality"), +(4296, "Trial of the Champion", 3778, "Trial of the Champion"), +(4298, "Heroic: Trial of the Champion", 4297, "Heroic: Trial of the Champion"), +(4436, "BB King", 4437, "BB King"), +(4784, "Emblematic", 4785, "Emblematic"), +(4786, "Operation: Gnomeregan", 4790, "Zalazane's Fall"); + +-- Reputation +DELETE FROM `player_factionchange_reputations` WHERE `alliance_id` IN +(47,54,69,72,509,730,890,930,946,978,1037,1050,1068,1094,1126); +INSERT INTO `player_factionchange_reputations` (`alliance_id`, `alliance_comment`, `horde_id`, `horde_comment`) VALUES +(47, "Ironforge", 530, "Darkspear Trolls"), +(54, "Gnomeregan Exiles", 81, "Thunder Bluff"), +(69, "Darnassus", 68, "Undercity"), +(72, "Stormwind", 76, "Orgrimmar"), +(509, "The League of Arathor", 510, "The Defilers"), +(730, "Stormpike Guard", 729, "Frostwolf Clan"), +(890, "Silverwing Sentinels", 889, "Warsong Outriders"), +(930, "Exodar", 911, "Silvermoon City"), +(946, "Honor Hold", 947, "Thrallmar"), +(978, "Kurenai", 941, "The Mag'har"), +(1037, "Alliance Vanguard", 1052, "Horde Expedition"), +(1050, "Valiance Expedition", 1085, "Warsong Offensive"), +(1068, "Explorers' League", 1064, "The Taunka"), +(1094, "The Silver Covenant", 1124, "The Sunreavers"), +(1126, "The Frostborn", 1067, "The Hand of Vengeance"); From e1f84d5604b26459e51529e60d295fc976e1ab1f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 1 Mar 2025 23:34:08 +0000 Subject: [PATCH 39/57] chore(DB): import pending files Referenced commit(s): b7e33283a5755bb85a7beee8acdfbac7c32ff231 --- .../rev_1731031220479040900.sql => db_world/2025_03_01_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1731031220479040900.sql => db_world/2025_03_01_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1731031220479040900.sql b/data/sql/updates/db_world/2025_03_01_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1731031220479040900.sql rename to data/sql/updates/db_world/2025_03_01_01.sql index bc83a7b91..d98abd64e 100644 --- a/data/sql/updates/pending_db_world/rev_1731031220479040900.sql +++ b/data/sql/updates/db_world/2025_03_01_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_03_01_00 -> 2025_03_01_01 -- Adding COMMENT COLUMN -- Achievements ALTER TABLE `player_factionchange_achievement` From 544878c04893df6cb94a6433c15d1ac26144d0a8 Mon Sep 17 00:00:00 2001 From: p-tkachuk Date: Sun, 2 Mar 2025 05:46:49 +0100 Subject: [PATCH 40/57] fix (Core/Wintergrasp) Fix map and battle icon (#21622) --- src/server/game/Battlefield/Battlefield.cpp | 4 ++ src/server/game/Battlefield/Battlefield.h | 1 + .../game/Battlefield/Zones/BattlefieldWG.cpp | 38 ++++++++++++++++++- .../game/Battlefield/Zones/BattlefieldWG.h | 4 ++ src/server/game/Entities/Player/Player.cpp | 8 +--- 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index e6e086463..e63d73e30 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -168,6 +168,7 @@ bool Battlefield::Update(uint32 diff) m_StartGrouping = true; InvitePlayersInZoneToQueue(); OnStartGrouping(); + SendUpdateWorldStates(); } bool objective_changed = false; @@ -353,6 +354,8 @@ void Battlefield::StartBattle() DoPlaySoundToAll(BF_START); OnBattleStart(); + + SendUpdateWorldStates(); } void Battlefield::EndBattle(bool endByTimer) @@ -377,6 +380,7 @@ void Battlefield::EndBattle(bool endByTimer) // Reset battlefield timer m_Timer = m_NoWarBattleTime; SendInitWorldStatesToAll(); + SendUpdateWorldStates(); } void Battlefield::DoPlaySoundToAll(uint32 SoundID) diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 966c5fc98..28c3cd062 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -335,6 +335,7 @@ public: /// Send all worldstate data to all player in zone. virtual void SendInitWorldStatesToAll() = 0; virtual void FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& /*packet*/) = 0; + virtual void SendUpdateWorldStates(Player* player = nullptr) = 0; /// Return if we can use mount in battlefield bool CanFlyIn() { return !m_isActive; } diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index 91d75a385..0184386c8 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -29,6 +29,7 @@ #include "TemporarySummon.h" #include "Vehicle.h" #include "WorldSession.h" +#include "WorldSessionMgr.h" #include "WorldStatePackets.h" BattlefieldWG::~BattlefieldWG() @@ -936,16 +937,21 @@ uint32 BattlefieldWG::GetData(uint32 data) const void BattlefieldWG::FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& packet) { - packet.Worldstates.reserve(4+2+WG_MAX_OBJ+WG_MAX_WORKSHOP); + uint32 timer = GetTimer() / 1000; + bool iconActive = timer < 15 * MINUTE || IsWarTime(); + + packet.Worldstates.reserve(4+4+WG_MAX_OBJ+WG_MAX_WORKSHOP); packet.Worldstates.emplace_back(BATTLEFIELD_WG_WORLD_STATE_ATTACKER, GetAttackerTeam()); packet.Worldstates.emplace_back(BATTLEFIELD_WG_WORLD_STATE_DEFENDER, GetDefenderTeam()); // Note: cleanup these two, their names look awkward packet.Worldstates.emplace_back(BATTLEFIELD_WG_WORLD_STATE_ACTIVE, IsWarTime() ? 0 : 1); packet.Worldstates.emplace_back(BATTLEFIELD_WG_WORLD_STATE_SHOW_WORLDSTATE, IsWarTime() ? 1 : 0); + packet.Worldstates.emplace_back(BATTLEFIELD_WG_WORLD_STATE_CONTROL, m_DefenderTeam == TEAM_ALLIANCE ? 2 : 1); // Alliance 2, Hord 1 + packet.Worldstates.emplace_back(BATTLEFIELD_WG_WORLD_STATE_ICON_ACTIVE, iconActive ? 1 : 0); for (uint32 i = 0; i < 2; ++i) - packet.Worldstates.emplace_back(ClockWorldState[i], GameTime::GetGameTime().count() + (m_Timer / 1000)); + packet.Worldstates.emplace_back(ClockWorldState[i], GameTime::GetGameTime().count() + timer); packet.Worldstates.emplace_back(BATTLEFIELD_WG_WORLD_STATE_VEHICLE_H, GetData(BATTLEFIELD_WG_DATA_VEHICLE_H)); packet.Worldstates.emplace_back(BATTLEFIELD_WG_WORLD_STATE_MAX_VEHICLE_H, GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H)); @@ -984,6 +990,34 @@ void BattlefieldWG::SendInitWorldStatesToAll() SendInitWorldStatesTo(player); } +void BattlefieldWG::SendUpdateWorldStates(Player* player) +{ + uint32 timer = GetTimer() / 1000; + bool iconActive = timer < 15 * MINUTE || IsWarTime(); + + SendUpdateWorldStateMessage(BATTLEFIELD_WG_WORLD_STATE_ATTACKER, GetAttackerTeam(), player); + SendUpdateWorldStateMessage(BATTLEFIELD_WG_WORLD_STATE_DEFENDER, GetDefenderTeam(), player); + SendUpdateWorldStateMessage(BATTLEFIELD_WG_WORLD_STATE_ACTIVE, IsWarTime() ? 0 : 1, player); + SendUpdateWorldStateMessage(BATTLEFIELD_WG_WORLD_STATE_SHOW_WORLDSTATE, IsWarTime() ? 1 : 0, player); + SendUpdateWorldStateMessage(BATTLEFIELD_WG_WORLD_STATE_CONTROL, GetDefenderTeam() == TEAM_ALLIANCE ? 2 : 1, player); + SendUpdateWorldStateMessage(BATTLEFIELD_WG_WORLD_STATE_ICON_ACTIVE, iconActive ? 1 : 0, player); + + for (uint32 i = 0; i < 2; ++i) + SendUpdateWorldStateMessage(ClockWorldState[i], uint32(GameTime::GetGameTime().count() + timer), player); +} + +void BattlefieldWG::SendUpdateWorldStateMessage(uint32 variable, uint32 value, Player* player) +{ + WorldPackets::WorldState::UpdateWorldState worldState; + worldState.VariableID = variable; + worldState.Value = value; + + if (player) + player->SendDirectMessage(worldState.Write()); + else + sWorldSessionMgr->SendGlobalMessage(worldState.Write()); +} + void BattlefieldWG::BrokenWallOrTower(TeamId /*team*/) { // might be some use for this in the future. old code commented out below. KL diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index 66ad47147..a2459b0e4 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -109,6 +109,8 @@ enum WintergraspWorldStates BATTLEFIELD_WG_WORLD_STATE_DEFENDER = 3802, BATTLEFIELD_WG_WORLD_STATE_ATTACKER = 3803, BATTLEFIELD_WG_WORLD_STATE_SHOW_WORLDSTATE = 3710, + BATTLEFIELD_WG_WORLD_STATE_CONTROL = 3804, // Shows on the map who controls WG + BATTLEFIELD_WG_WORLD_STATE_ICON_ACTIVE = 4375, // Activates "ice" icon }; enum WintergraspAreaIds @@ -405,6 +407,8 @@ public: void SendInitWorldStatesTo(Player* player); void SendInitWorldStatesToAll() override; void FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& packet) override; + void SendUpdateWorldStates(Player* player = nullptr) override; + void SendUpdateWorldStateMessage(uint32 variable, uint32 value, Player* player = nullptr); void HandleKill(Player* killer, Unit* victim) override; void OnUnitDeath(Unit* unit) override; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 9aeda887c..da573bcf5 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -8909,13 +8909,7 @@ void Player::SendBattlefieldWorldStates() { if (BattlefieldWG* wg = (BattlefieldWG*)sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) { - SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_ATTACKER, wg->GetAttackerTeam()); - SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_DEFENDER, wg->GetDefenderTeam()); - SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE, wg->IsWarTime() ? 0 : 1); // Note: cleanup these two, their names look awkward - SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_SHOW_WORLDSTATE, wg->IsWarTime() ? 1 : 0); - - for (uint32 i = 0; i < 2; ++i) - SendUpdateWorldState(ClockWorldState[i], uint32(GameTime::GetGameTime().count() + (wg->GetTimer() / 1000))); + wg->SendUpdateWorldStates(this); } } } From ee23fdca3dc42e8d0976ace1fb103411b19c908d Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sun, 2 Mar 2025 16:49:18 +0100 Subject: [PATCH 41/57] fix(CI/Codestyle): Escape all MySQL keywords and skip /* comments (#21631) --- apps/codestyle/codestyle-sql.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/apps/codestyle/codestyle-sql.py b/apps/codestyle/codestyle-sql.py index 2bc0d3a91..06f8a0903 100644 --- a/apps/codestyle/codestyle-sql.py +++ b/apps/codestyle/codestyle-sql.py @@ -177,6 +177,10 @@ def semicolon_check(file: io, file_path: str) -> None: for line_number, line in enumerate(lines, start=1): if line.startswith('--'): continue + if line.startswith('/*'): + continue + if line.startswith('*/'): + continue # Remove trailing whitespace including newline # Remove comments from the line stripped_line = line.split('--', 1)[0].strip() @@ -231,10 +235,22 @@ def backtick_check(file: io, file_path: str) -> None: words = re.findall(r'\b(? Date: Sun, 2 Mar 2025 18:02:09 +0100 Subject: [PATCH 42/57] fix(CI/Codestyle): Imrpove semicolon check and general improvements (#21632) --- apps/codestyle/codestyle-sql.py | 137 +++++++++++++++++++++++--------- 1 file changed, 99 insertions(+), 38 deletions(-) diff --git a/apps/codestyle/codestyle-sql.py b/apps/codestyle/codestyle-sql.py index 06f8a0903..b4b53ed27 100644 --- a/apps/codestyle/codestyle-sql.py +++ b/apps/codestyle/codestyle-sql.py @@ -49,18 +49,20 @@ def parsing_file(files: list) -> None: semicolon_check(file, file_path) backtick_check(file, file_path) except UnicodeDecodeError: - print(f"\nCould not decode file {file_path}") + print(f"\n❌ Could not decode file {file_path}") sys.exit(1) # Output the results - print("") + print("\n ") for check, result in results.items(): print(f"{check} : {result}") if error_handler: - print("\nPlease fix the codestyle issues above.") + print("\n ") + print("\n❌ Please fix the codestyle issues above.") sys.exit(1) else: - print(f"\nEverything looks good") + print("\n ") + print(f"\n✅ Everything looks good") # Codestyle patterns checking for multiple blank lines def multiple_blank_lines_check(file: io, file_path: str) -> None: @@ -73,13 +75,13 @@ def multiple_blank_lines_check(file: io, file_path: str) -> None: if line.strip() == '': consecutive_blank_lines += 1 if consecutive_blank_lines > 1: - print(f"Multiple blank lines found in {file_path} at line {line_number - 1}") + print(f"❌ Multiple blank lines found in {file_path} at line {line_number - 1}") check_failed = True else: consecutive_blank_lines = 0 # Additional check for the end of the file if consecutive_blank_lines >= 1: - print(f"Multiple blank lines found at the end of: {file_path}") + print(f"❌ Multiple blank lines found at the end of: {file_path}") check_failed = True # Handle the script error and update the result output if check_failed: @@ -94,7 +96,7 @@ def trailing_whitespace_check(file: io, file_path: str) -> None: # Parse all the file for line_number, line in enumerate(file, start = 1): if line.endswith(' \n'): - print(f"Trailing whitespace found: {file_path} at line {line_number}") + print(f"❌ Trailing whitespace found: {file_path} at line {line_number}") check_failed = True if check_failed: error_handler = True @@ -110,25 +112,25 @@ def sql_check(file: io, file_path: str) -> None: for line_number, line in enumerate(file, start = 1): if [match for match in ['broadcast_text'] if match in line]: print( - f"DON'T EDIT broadcast_text TABLE UNLESS YOU KNOW WHAT YOU ARE DOING!\nThis error can safely be ignored if the changes are approved to be sniffed: {file_path} at line {line_number}") + f"❌ DON'T EDIT broadcast_text TABLE UNLESS YOU KNOW WHAT YOU ARE DOING!\nThis error can safely be ignored if the changes are approved to be sniffed: {file_path} at line {line_number}") check_failed = True if "EntryOrGuid" in line: print( - f"Please use entryorguid syntax instead of EntryOrGuid in {file_path} at line {line_number}\nWe recommend to use keira to have the right syntax in auto-query generation") + f"❌ Please use entryorguid syntax instead of EntryOrGuid in {file_path} at line {line_number}\nWe recommend to use keira to have the right syntax in auto-query generation") check_failed = True if [match for match in [';;'] if match in line]: print( - f"Double semicolon (;;) found in {file_path} at line {line_number}") + f"❌ Double semicolon (;;) found in {file_path} at line {line_number}") check_failed = True if re.match(r"\t", line): print( - f"Tab found! Replace it to 4 spaces: {file_path} at line {line_number}") + f"❌ Tab found! Replace it to 4 spaces: {file_path} at line {line_number}") check_failed = True last_line = line[-1].strip() if last_line: print( - f"The last line is not a newline. Please add a newline: {file_path}") + f"❌ The last line is not a newline. Please add a newline: {file_path}") check_failed = True # Handle the script error and update the result output @@ -148,7 +150,7 @@ def insert_delete_safety_check(file: io, file_path: str) -> None: if line.startswith("--"): continue if "INSERT" in line and "DELETE" not in previous_line: - print(f"No DELETE keyword found before the INSERT in {file_path} at line {line_number}\nIf this error is intended, please advert a maintainer") + print(f"❌ No DELETE keyword found before the INSERT in {file_path} at line {line_number}\nIf this error is intended, please advert a maintainer") check_failed = True previous_line = line match = re.match(r"DELETE FROM\s+`([^`]+)`", line, re.IGNORECASE) @@ -156,7 +158,7 @@ def insert_delete_safety_check(file: io, file_path: str) -> None: table_name = match.group(1) if table_name in not_delete: print( - f"Entries from {table} should not be deleted! {file_path} at line {line_number}") + f"❌ Entries from {table} should not be deleted! {file_path} at line {line_number}") check_failed = True # Handle the script error and update the result output @@ -166,39 +168,99 @@ def insert_delete_safety_check(file: io, file_path: str) -> None: def semicolon_check(file: io, file_path: str) -> None: global error_handler, results - file.seek(0) # Reset file pointer to the beginning + + file.seek(0) # Reset file pointer to the start check_failed = False - sql_keywords = ["SELECT", "INSERT", "UPDATE", "DELETE"] + + sql_statement_regex = re.compile(r'^\s*(SELECT|INSERT|UPDATE|DELETE|REPLACE|SET)\b', re.IGNORECASE) + block_comment_start = re.compile(r'/\*') + block_comment_end = re.compile(r'\*/') + inline_comment = re.compile(r'--.*') + query_open = False + in_block_comment = False + inside_values_block = False lines = file.readlines() total_lines = len(lines) - for line_number, line in enumerate(lines, start=1): - if line.startswith('--'): - continue - if line.startswith('/*'): - continue - if line.startswith('*/'): - continue - # Remove trailing whitespace including newline - # Remove comments from the line - stripped_line = line.split('--', 1)[0].strip() + def get_next_non_blank_line(start): + """ Get the next non-blank, non-comment line starting from `start` """ + for idx in range(start, total_lines): + next_line = lines[idx].strip() + if next_line and not next_line.startswith('--') and not next_line.startswith('/*'): + return next_line + return None - # Check if one keyword is in the line - if not query_open and any(keyword in stripped_line for keyword in sql_keywords): + for line_number, line in enumerate(lines, start=1): + stripped_line = line.strip() + + # Skip single-line comments + if stripped_line.startswith('--'): + continue + + # Handle block comments + if in_block_comment: + if '*/' in stripped_line: + in_block_comment = False + stripped_line = stripped_line.split('*/', 1)[1].strip() + else: + continue + else: + if '/*' in stripped_line: + query_open = False # Reset query state at start of block comment + in_block_comment = True + stripped_line = stripped_line.split('/*', 1)[0].strip() + + # Skip empty lines (unless inside values block) + if not stripped_line and not inside_values_block: + continue + + # Remove inline comments after SQL + stripped_line = stripped_line.split('--', 1)[0].strip() + + if stripped_line.upper().startswith("SET") and not stripped_line.endswith(";"): + print(f"❌ Missing semicolon in {file_path} at line {line_number}") + check_failed = True + + # Detect query start + if not query_open and any(keyword in stripped_line.upper() for keyword in ["SELECT", "INSERT", "UPDATE", "DELETE", "REPLACE"]): query_open = True - if query_open: - if stripped_line == '': - print(f"Missing semicolon in {file_path} at line {line_number - 1}") + # Detect start of multi-line VALUES block + if any(kw in stripped_line.upper() for kw in ["INSERT", "REPLACE"]) and "VALUES" in stripped_line.upper(): + inside_values_block = True + query_open = True # Ensure query is marked open too + + if inside_values_block: + if not stripped_line: + continue # Allow blank lines inside VALUES block + + if stripped_line.startswith('('): + # Get next non-blank line to detect if we're at the last row + next_line = get_next_non_blank_line(line_number) + + if next_line and next_line.startswith('('): + # Expect comma if another row follows + if not stripped_line.endswith(','): + print(f"❌ Missing comma in {file_path} at line {line_number}") + check_failed = True + else: + # Expect semicolon if this is the final row + if not stripped_line.endswith(';'): + print(f"❌ Missing semicolon in {file_path} at line {line_number}") + check_failed = True + inside_values_block = False + query_open = False + else: + inside_values_block = False # Close block if semicolon was found + + elif query_open and not inside_values_block: + # Normal query handling (outside multi-row VALUES block) + if line_number == total_lines and not stripped_line.endswith(';'): + print(f"❌ Missing semicolon in {file_path} at the last line {line_number}") check_failed = True query_open = False - elif line_number == total_lines: - if not stripped_line.endswith(';'): - print(f"Missing semicolon in {file_path} at the last line {line_number}") - check_failed = True - query_open = False elif stripped_line.endswith(';'): query_open = False @@ -217,7 +279,6 @@ def backtick_check(file: io, file_path: str) -> None: re.IGNORECASE | re.DOTALL ) - # Make sure to ignore values enclosed in single- and doublequotes quote_pattern = re.compile(r"'(?:\\'|[^'])*'|\"(?:\\\"|[^\"])*\"") @@ -255,7 +316,7 @@ def backtick_check(file: io, file_path: str) -> None: # Make sure the word is enclosed in backticks if not re.search(rf'`{re.escape(word)}`', content): - print(f"Missing backticks around ({word}). {file_path} at line {line_number}") + print(f"❌ Missing backticks around ({word}). {file_path} at line {line_number}") check_failed = True if check_failed: From 9e4c74bab1319d8b212d4d57503a6f00b3a19a55 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sun, 2 Mar 2025 18:48:42 +0100 Subject: [PATCH 43/57] fix(CI/Codestyle): Minor typo in insert_delete_safety_check (#21639) --- apps/codestyle/codestyle-sql.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/codestyle/codestyle-sql.py b/apps/codestyle/codestyle-sql.py index b4b53ed27..7d7511323 100644 --- a/apps/codestyle/codestyle-sql.py +++ b/apps/codestyle/codestyle-sql.py @@ -150,7 +150,7 @@ def insert_delete_safety_check(file: io, file_path: str) -> None: if line.startswith("--"): continue if "INSERT" in line and "DELETE" not in previous_line: - print(f"❌ No DELETE keyword found before the INSERT in {file_path} at line {line_number}\nIf this error is intended, please advert a maintainer") + print(f"❌ No DELETE keyword found before the INSERT in {file_path} at line {line_number}\nIf this error is intended, please notify a maintainer") check_failed = True previous_line = line match = re.match(r"DELETE FROM\s+`([^`]+)`", line, re.IGNORECASE) @@ -158,7 +158,7 @@ def insert_delete_safety_check(file: io, file_path: str) -> None: table_name = match.group(1) if table_name in not_delete: print( - f"❌ Entries from {table} should not be deleted! {file_path} at line {line_number}") + f"❌ Entries from {table_name} should not be deleted! {file_path} at line {line_number}\nIf this error is intended, please notify a maintainer") check_failed = True # Handle the script error and update the result output From c60b294228e0f84f2f96692a27c6176198eb1f43 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 2 Mar 2025 16:07:43 -0300 Subject: [PATCH 44/57] fix(Scripts/SunwellPlateau): Fix Felmyst air phase (#21637) --- .../rev_1740880295787400500.sql | 2 + .../SunwellPlateau/boss_felmyst.cpp | 306 +++++++++--------- 2 files changed, 160 insertions(+), 148 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1740880295787400500.sql diff --git a/data/sql/updates/pending_db_world/rev_1740880295787400500.sql b/data/sql/updates/pending_db_world/rev_1740880295787400500.sql new file mode 100644 index 000000000..b2c1af887 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1740880295787400500.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_text` SET `Type` = 41, `BroadcastTextId` = 24548 WHERE `CreatureId` = 25038 AND `GroupId` = 6; diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp index ed1b5408c..2c29cce45 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp @@ -66,12 +66,14 @@ enum Misc // Misc ACTION_START_EVENT = 1, POINT_GROUND = 1, - POINT_AIR = 2, - POINT_AIR_BREATH_START1 = 3, - POINT_AIR_BREATH_END1 = 4, - POINT_AIR_BREATH_START2 = 5, - POINT_AIR_BREATH_END2 = 6, - POINT_MISC = 7, + POINT_TAKEOFF = 2, + POINT_AIR = 3, + POINT_AIR_UP = 4, + POINT_LANE = 5, + POINT_AIR_BREATH_START1 = 6, + POINT_AIR_BREATH_END = 7, + POINT_AIR_BREATH_START2 = 8, + POINT_MISC = 9, POINT_KALECGOS = 1, @@ -79,9 +81,28 @@ enum Misc GROUP_BREATH = 1, NPC_FOG_TRIGGER = 23472, - NPC_KALECGOS_FELMYST = 24844 // Same as Magister's Terrace + NPC_KALECGOS_FELMYST = 24844, // Same as Magister's Terrace + NPC_WORLD_TRIGGER_RIGHT = 25358 }; +const Position LeftSideLanes[3] = +{ + { 1494.745f, 704.0001f, 50.084652f, 4.7472f }, // top + { 1469.923f, 703.23914f, 50.08592f, 4.7472f }, // middle + { 1446.5154f, 701.5184f, 50.085438f, 4.7472f } // bottom +}; + +const Position RightSideLanes[3] = +{ + { 1492.82f, 515.668f, 50.0833f, 1.4486f }, // top + { 1466.7322f, 515.5953f, 50.571518f, 1.4486f }, // middle + { 1441.64f, 520.52f, 50.0833f, 1.4486f } // bottom +}; + +const Position RightSide = { 1458.5555f, 502.1995f, 59.899513f, 1.605702f }; +const Position LeftSide = { 1469.0642f, 729.5854f, 59.823853f, 4.6774f }; +const Position LandingPos = { 1476.77f, 665.094f, 20.6423f }; + class CorruptTriggers : public BasicEvent { public: @@ -103,7 +124,7 @@ private: struct boss_felmyst : public BossAI { - boss_felmyst(Creature* creature) : BossAI(creature, DATA_FELMYST) { } + boss_felmyst(Creature* creature) : BossAI(creature, DATA_FELMYST), _currentLane(0), _strafeCount(0) { } void InitializeAI() override { @@ -127,25 +148,24 @@ struct boss_felmyst : public BossAI void Reset() override { BossAI::Reset(); - me->m_Events.KillAllEvents(false); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FOG_OF_CORRUPTION_CHARM); + _currentLane = 0; + _strafeCount = 0; + me->SetCombatMovement(false); } void JustEngagedWith(Unit* who) override { BossAI::JustEngagedWith(who); - me->m_Events.AddEventAtOffset([&] { - Talk(YELL_BERSERK); - DoCastSelf(SPELL_BERSERK, true); - }, 10min); + ScheduleEnrageTimer(SPELL_BERSERK, 10min, YELL_BERSERK); me->GetMotionMaster()->Clear(); Position landPos = who->GetPosition(); me->m_Events.AddEventAtOffset([&, landPos] { me->GetMotionMaster()->MoveLand(POINT_GROUND, landPos); - }, 2s); + }, 1s); } void KilledUnit(Unit* victim) override @@ -166,153 +186,139 @@ struct boss_felmyst : public BossAI kalec->GetMotionMaster()->MovePoint(POINT_KALECGOS, 1474.2347f, 624.0703f, 29.32589f, false, true); } + void ScheduleGroundAbilities() + { + ScheduleTimedEvent(7500ms, [&] { + DoCastVictim(SPELL_CLEAVE); + }, 7500ms); + + ScheduleTimedEvent(12s, [&] { + DoCastVictim(SPELL_CORROSION); + }, 20s); + + ScheduleTimedEvent(18s, [&] { + Talk(YELL_BREATH); + DoCastSelf(SPELL_GAS_NOVA); + }, 20s); + + ScheduleTimedEvent(25s, [&] { + DoCastRandomTarget(SPELL_ENCAPSULATE_CHANNEL, 0, 50.0f); + }, 25s); + + me->m_Events.AddEventAtOffset([&] { + Talk(YELL_TAKEOFF); + scheduler.CancelAll(); + me->SetReactState(REACT_PASSIVE); + me->SetTarget(); + me->AttackStop(); + me->SetCombatMovement(false); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveIdle(); + me->SetCanFly(true); + me->SetDisableGravity(true); + me->SendMovementFlagUpdate(); + SetInvincibility(true); + me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + me->GetMotionMaster()->MovePoint(POINT_TAKEOFF, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 20.0f); + }, 1min); + } + void MovementInform(uint32 type, uint32 point) override { if (type != EFFECT_MOTION_TYPE && type != POINT_MOTION_TYPE) return; - if (point == POINT_GROUND) + switch (point) { - if (!me->HasAura(SPELL_NOXIOUS_FUMES)) - DoCastSelf(SPELL_NOXIOUS_FUMES, true); + case POINT_GROUND: - me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); - me->SetCanFly(false); - me->SetDisableGravity(false); - me->SendMovementFlagUpdate(); - SetInvincibility(false); + if (!me->HasAura(SPELL_NOXIOUS_FUMES)) + DoCastSelf(SPELL_NOXIOUS_FUMES, true); - me->m_Events.AddEventAtOffset([&] { - me->SetReactState(REACT_AGGRESSIVE); - - if (me->GetVictim()) - me->SetTarget(me->GetVictim()->GetGUID()); - - me->ResumeChasingVictim(); - }, 2s); - - ScheduleTimedEvent(7500ms, [&] { - DoCastVictim(SPELL_CLEAVE); - }, 7500ms); - - ScheduleTimedEvent(12s, [&] { - DoCastVictim(SPELL_CORROSION); - }, 20s); - - ScheduleTimedEvent(18s, [&] { - DoCastSelf(SPELL_GAS_NOVA); - }, 20s); - - ScheduleTimedEvent(25s, [&] { - DoCastRandomTarget(SPELL_ENCAPSULATE_CHANNEL, 0, 50.0f); - }, 25s); - - me->m_Events.AddEventAtOffset([&] { - scheduler.CancelAll(); - me->SetReactState(REACT_PASSIVE); - me->StopMoving(); - me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveIdle(); + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + me->SetCanFly(false); + me->SetDisableGravity(false); + me->SendMovementFlagUpdate(); + SetInvincibility(false); me->m_Events.AddEventAtOffset([&] { - ScheduleFlightSequence(); - }, 1s); - }, 1min); - } - else if (point == POINT_AIR_BREATH_START1) - { - me->SetTarget(); - me->SetFacingTo(4.71f); - ScheduleFlightAbilities(point); - } - else if (point == POINT_AIR_BREATH_END1) - { - me->RemoveAurasDueToSpell(SPELL_FELMYST_SPEED_BURST); - me->SetFacingTo(1.57f); - if (!scheduler.IsGroupScheduled(GROUP_BREATH)) - { + me->SetReactState(REACT_AGGRESSIVE); + + if (me->GetVictim()) + me->SetTarget(me->GetVictim()->GetGUID()); + + me->ResumeChasingVictim(); + me->SetCombatMovement(true); + }, 5s); + + ScheduleGroundAbilities(); + break; + case POINT_TAKEOFF: me->m_Events.AddEventAtOffset([&] { - Position pos = { 1447.0f + urand(0, 2) * 25.0f, 515.0f, 50.0f, 1.57f }; - me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_START2, pos, false, true); + me->CastCustomSpell(SPELL_SUMMON_DEMONIC_VAPOR, SPELLVALUE_MAX_TARGETS, 1, me, true); + }, 5s); + + me->m_Events.AddEventAtOffset([&] { + me->CastCustomSpell(SPELL_SUMMON_DEMONIC_VAPOR, SPELLVALUE_MAX_TARGETS, 1, me, true); + }, 17s); + + scheduler.Schedule(27s, GROUP_BREATH, [this](TaskContext) + { + me->GetMotionMaster()->MovePoint(POINT_AIR_UP, RightSide); + }); + break; + case POINT_AIR_UP: + me->m_Events.AddEventAtOffset([&] { + if (_strafeCount >= 3) + { + _strafeCount = 0; + me->GetMotionMaster()->MoveLand(POINT_GROUND, LandingPos); + return; + } + + ++_strafeCount; + _currentLane = urand(0, 2); + if (me->FindNearestCreature(NPC_WORLD_TRIGGER_RIGHT, 30.0f)) + me->GetMotionMaster()->MovePoint(POINT_LANE, RightSideLanes[_currentLane], false); + else + me->GetMotionMaster()->MovePoint(POINT_LANE, LeftSideLanes[_currentLane], false); }, 2s); - } + break; + case POINT_LANE: + Talk(EMOTE_BREATH); + me->m_Events.AddEventAtOffset([&] { + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(0)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(500)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1000)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1500)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2000)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2500)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3000)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3500)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(4000)); + }, 5s); + + me->m_Events.AddEventAtOffset([&] { + DoCastSelf(SPELL_FELMYST_SPEED_BURST, true); + + if (me->FindNearestCreature(NPC_WORLD_TRIGGER_RIGHT, 30.0f)) + me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END, LeftSideLanes[_currentLane], false); + else + me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END, RightSideLanes[_currentLane], false); + }, 5s); + break; + case POINT_AIR_BREATH_END: + me->RemoveAurasDueToSpell(SPELL_FELMYST_SPEED_BURST); + + me->m_Events.AddEventAtOffset([&] { + if (me->FindNearestCreature(NPC_WORLD_TRIGGER_RIGHT, 30.0f)) + me->GetMotionMaster()->MovePoint(POINT_AIR_UP, RightSide, false); + else + me->GetMotionMaster()->MovePoint(POINT_AIR_UP, LeftSide, false); + }, 2s); + break; } - else if (point == POINT_AIR_BREATH_START2) - { - me->SetTarget(); - me->SetFacingTo(1.57f); - ScheduleFlightAbilities(point); - } - else if (point == POINT_AIR_BREATH_END2) - { - me->RemoveAurasDueToSpell(SPELL_FELMYST_SPEED_BURST); - me->SetFacingTo(4.71f); - } - } - - void ScheduleFlightSequence() - { - Talk(YELL_TAKEOFF); - me->SetTarget(); - me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - me->SetDisableGravity(true); - me->SendMovementFlagUpdate(); - SetInvincibility(true); - - me->m_Events.AddEventAtOffset([&] { - me->GetMotionMaster()->MovePoint(POINT_AIR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 15.0f, false, true); - }, 2s); - - me->m_Events.AddEventAtOffset([&] { - me->CastCustomSpell(SPELL_SUMMON_DEMONIC_VAPOR, SPELLVALUE_MAX_TARGETS, 1, me, true); - }, 8s); - - me->m_Events.AddEventAtOffset([&] { - me->CastCustomSpell(SPELL_SUMMON_DEMONIC_VAPOR, SPELLVALUE_MAX_TARGETS, 1, me, true); - }, 21s); - - scheduler.Schedule(35s, GROUP_BREATH, [this](TaskContext) - { - Position pos = { 1447.0f + urand(0, 2) * 25.0f, 705.0f, 50.0f, 4.71f }; - me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_START1, pos, false, true); - }); - - scheduler.Schedule(72s, GROUP_BREATH, [this](TaskContext) - { - Position pos = { 1447.0f + urand(0, 2) * 25.0f, 705.0f, 50.0f, 4.71f }; - me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_START1, pos, false, true); - }); - - me->m_Events.AddEventAtOffset([&] { - me->GetMotionMaster()->MovePoint(POINT_GROUND, 1500.0f, 552.8f, 26.52f, false, true); - }, 86s); - } - - void ScheduleFlightAbilities(uint8 point) - { - me->m_Events.AddEventAtOffset([&] { - Talk(EMOTE_BREATH); - }, 2s); - - me->m_Events.AddEventAtOffset([&] { - Talk(YELL_BREATH); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(0)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1000)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2000)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3000)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(4000)); - }, 5s); - - me->m_Events.AddEventAtOffset([this, point] { - DoCastSelf(SPELL_FELMYST_SPEED_BURST, true); - if (point == POINT_AIR_BREATH_START1) - me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END1, me->GetPositionX(), me->GetPositionY() - 200.0f, me->GetPositionZ() + 5.0f, false, true); - else if (point == POINT_AIR_BREATH_START2) - me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END2, me->GetPositionX(), me->GetPositionY() + 200.0f, me->GetPositionZ() + 5.0f, false, true); - }, 5s); } void StartIntro() @@ -346,6 +352,10 @@ struct boss_felmyst : public BossAI if (!me->HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY)) DoMeleeAttackIfReady(); } + + private: + uint8 _currentLane = 0; + uint8 _strafeCount = 0; }; struct npc_demonic_vapor : public NullCreatureAI From 6422026893a08aba480c98a0a3a5b4884a5b4871 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 2 Mar 2025 19:08:41 +0000 Subject: [PATCH 45/57] chore(DB): import pending files Referenced commit(s): c60b294228e0f84f2f96692a27c6176198eb1f43 --- .../rev_1740880295787400500.sql => db_world/2025_03_02_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1740880295787400500.sql => db_world/2025_03_02_00.sql} (72%) diff --git a/data/sql/updates/pending_db_world/rev_1740880295787400500.sql b/data/sql/updates/db_world/2025_03_02_00.sql similarity index 72% rename from data/sql/updates/pending_db_world/rev_1740880295787400500.sql rename to data/sql/updates/db_world/2025_03_02_00.sql index b2c1af887..868d9fb70 100644 --- a/data/sql/updates/pending_db_world/rev_1740880295787400500.sql +++ b/data/sql/updates/db_world/2025_03_02_00.sql @@ -1,2 +1,3 @@ +-- DB update 2025_03_01_01 -> 2025_03_02_00 -- UPDATE `creature_text` SET `Type` = 41, `BroadcastTextId` = 24548 WHERE `CreatureId` = 25038 AND `GroupId` = 6; From 7e78484bd84650ffb6cbf00a402275fcbee96bf5 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Sun, 2 Mar 2025 15:29:18 -0500 Subject: [PATCH 46/57] fix(DB): Add Argent Dawn spawns for Scourge Invasion. (#21630) --- .../scourge-invasion-spawns.sql | 210 ++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 data/sql/updates/pending_db_world/scourge-invasion-spawns.sql diff --git a/data/sql/updates/pending_db_world/scourge-invasion-spawns.sql b/data/sql/updates/pending_db_world/scourge-invasion-spawns.sql new file mode 100644 index 000000000..548d5d374 --- /dev/null +++ b/data/sql/updates/pending_db_world/scourge-invasion-spawns.sql @@ -0,0 +1,210 @@ +SET @CGUID := 12860; +DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+30 AND `id1` IN (16241, 16255, 16285, 16359, 16490, 16493, 16494, 16495, 16786, 16787, 29441, 29442, 16241, 16281, 16285, 16361, 16478, 16484, 16786); +INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`, `CreateObject`) VALUES +/* +Argent Recruiter 16241 +Argent Scout 16255 +Keeper of the Rolls 16281 +Argent Emissary 16285 +Argent Messenger 16359 +Commander Thomas Helleran 16361 +Lieutenant Orrin 16478 +Lieutenant Nevell 16484 +Lieutenant Rukag 16494 +Lieutenant Beitha 16495 +Argent Quartermaster 16786 +Argent Outfitter 16787 +Lieutenant Kregor 29442 +*/ + +-- Light's Hope +(@CGUID+0, 16281, 0, 0, 0, 1, 1, 0, 2242.44091796875, -5317.3154296875, 82.25064849853515625, 1.413716673851013183, 120, 0, 0, 5742, 0, 0, 0, 0, 49345, 1), +(@CGUID+1, 16285, 0, 0, 0, 1, 1, 0, 2247.78955078125, -5317.314453125, 82.1934661865234375, 1.570796370506286621, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+2, 16361, 0, 0, 0, 1, 1, 0, 2240.872802734375, -5317.2626953125, 82.25064849853515625, 1.675516128540039062, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), + +-- Stormwind +(@CGUID+3, 16241, 0, 0, 0, 1, 1, 0, -8832.8681640625, 642.7821044921875, 94.80999755859375, 4.450589656829833984, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+4, 16285, 0, 0, 0, 1, 1, 0, -8830.8251953125, 640.75823974609375, 94.52800750732421875, 4.223696708679199218, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+5, 16478, 0, 0, 0, 1, 1, 0, -8955.3173828125, 523.41436767578125, 96.43996429443359375, 3.787364482879638671, 120, 0, 0, 198, 0, 0, 0, 0, 49345, 1), +(@CGUID+6, 16786, 0, 0, 0, 1, 1, 0, -8835.7548828125, 644.27618408203125, 95.60742950439453125, 4.188790321350097656, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), + +-- Ironforge +(@CGUID+7, 16241, 0, 0, 0, 1, 1, 0, -4933.83837890625, -988.72222900390625, 501.54107666015625, 2.059488534927368164, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+8, 16285, 0, 0, 0, 1, 1, 0, -4935.4775390625, -990.11456298828125, 501.538818359375, 2.234021425247192382, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+9, 16484, 0, 0, 0, 1, 1, 0, -5027.18212890625, -806.9814453125, 496.484344482421875, 3.001966238021850585, 120, 0, 0, 198, 0, 0, 0, 0, 49345, 1), + +-- Darnassus +(@CGUID+10, 16241, 1, 0, 0, 1, 1, 0, 9918.359375, 2520.5986328125, 1317.5728759765625, 3.31612563133239746, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+11, 16241, 1, 0, 0, 1, 1, 0, 9919.1357421875, 2510.427978515625, 1317.6175537109375, 4.398229598999023437, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+12, 16285, 1, 0, 0, 1, 1, 0, 9918.9423828125, 2518.56689453125, 1317.6417236328125, 3.473205089569091796, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+13, 16495, 1, 0, 0, 1, 1, 0, 9939.365234375, 2114.40234375, 1328.6136474609375, 6.108652114868164062, 120, 0, 0, 198, 0, 0, 0, 0, 49345, 1), +(@CGUID+14, 16786, 1, 0, 0, 1, 1, 0, 9917.6669921875, 2524.45458984375, 1317.53125, 3.874630928039550781, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), + +-- The Exodar +(@CGUID+15, 29442, 530, 0, 0, 1, 1, 0, -4039.0625, -11923.4052734375, -1.13312458992004394, 4.86946868896484375, 120, 0, 0, 198, 0, 0, 0, 0, 49345, 1), + +-- Orgrimmar +(@CGUID+16, 16255, 1, 0, 0, 1, 1, 0, 1584.5823974609375, -4416.3515625, 8.298021316528320312, 3.385938644409179687, 120, 0, 0, 5922, 0, 0, 0, 0, 49345, 1), +(@CGUID+17, 16359, 1, 0, 0, 1, 1, 0, 1585.2174072265625, -4420.50927734375, 8.329293251037597656, 3.455751895904541015, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+18, 16493, 1, 0, 0, 1, 1, 0, 1512.3350830078125, -4403.78662109375, 19.753875732421875, 5.777040004730224609, 120, 0, 0, 198, 0, 0, 0, 0, 46248, 1), +(@CGUID+19, 16787, 1, 0, 0, 1, 1, 0, 1586.276611328125, -4425.21484375, 7.955701351165771484, 3.054326057434082031, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), + +-- Thunder Bluff +(@CGUID+20, 16255, 1, 0, 0, 1, 1, 0, -1273.4107666015625, 69.5706939697265625, 128.057403564453125, 5.689773082733154296, 120, 0, 0, 5922, 0, 0, 0, 0, 49345, 1), +(@CGUID+21, 16359, 1, 0, 0, 1, 1, 0, -1272.7305908203125, 75.3866119384765625, 128.1531524658203125, 0.401425719261169433, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+22, 16490, 1, 0, 0, 1, 1, 0, -1346.690673828125, 192.2804107666015625, 61.57354736328125, 4.380776405334472656, 120, 0, 0, 198, 0, 0, 0, 0, 49345, 1), +(@CGUID+23, 16787, 1, 0, 0, 1, 1, 0, -1272.548583984375, 72.46506500244140625, 128.02685546875, 6.213372230529785156, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), + +-- Undercity +(@CGUID+24, 16255, 0, 0, 0, 1, 1, 0, 1578.8802490234375, 238.5615997314453125, -61.993988037109375, 3.03687286376953125, 120, 0, 0, 5922, 0, 0, 0, 0, 49345, 1), +(@CGUID+25, 16359, 0, 0, 0, 1, 1, 0, 1578.800537109375, 241.7307891845703125, -61.9939918518066406, 2.932153224945068359, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+26, 16494, 0, 0, 0, 1, 1, 0, 1736.86865234375, 239.555938720703125, 62.7902679443359375, 6.2657318115234375, 120, 0, 0, 198, 0, 0, 0, 0, 46248, 1), + +-- Silvermoon City +(@CGUID+27, 16255, 530, 0, 0, 1, 1, 0, 9516.109375, -7350.31005859375, 14.41531562805175781, 1.710422635078430175, 120, 0, 0, 5922, 0, 0, 0, 0, 49345, 1), +(@CGUID+28, 16359, 530, 0, 0, 1, 1, 0, 9525.328125, -7347.88623046875, 14.41493511199951171, 1.710422635078430175, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+29, 16787, 530, 0, 0, 1, 1, 0, 9522.7626953125, -7352.30126953125, 14.40223979949951171, 2.111848354339599609, 120, 0, 0, 5228, 0, 0, 0, 0, 49345, 1), +(@CGUID+30, 29441, 530, 0, 0, 1, 1, 0, 9348.6884765625, -7286.931640625, 14.66600990295410156, 4.171336650848388671, 120, 0, 0, 198, 0, 0, 0, 0, 46248, 1); + +SET @OGUID := 2164; +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+39 AND `id` IN (181254, 181255, 181256); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`) VALUES +/* +Argent Dawn Buffer Tent 181254 +Argent Dawn Buffer Crate 181255 +Argent Dawn Banner 181256 +*/ + +-- Light's Hope +(@OGUID+0, 181254, 0, 0, 0, 1, 1, 2243.857177734375, -5321.142578125, 82.1673126220703125, 1.48352813720703125, 0, 0, 0.675589561462402343, 0.737277925014495849, 120, 255, 1, 49345), +(@OGUID+1, 181255, 0, 0, 0, 1, 1, 2239.55859375, -5320.30029296875, 82.1270599365234375, 4.1538848876953125, 0, 0, -0.8746194839477539, 0.484810054302215576, 120, 255, 1, 49345), +(@OGUID+2, 181255, 0, 0, 0, 1, 1, 2239.470458984375, -5320.43212890625, 82.62839508056640625, 1.274088263511657714, 0, 0, 0.594821929931640625, 0.80385744571685791, 120, 255, 1, 49345), +(@OGUID+3, 181256, 0, 0, 0, 1, 1, 2238.9111328125, -5318.666015625, 82.15229034423828125, 1.553341388702392578, 0, 0, 0.700908660888671875, 0.713251054286956787, 120, 255, 1, 49345), +(@OGUID+4, 181256, 0, 0, 0, 1, 1, 2248.46923828125, -5318.94287109375, 82.11429595947265625, 1.570795774459838867, 0, 0, 0.707106590270996093, 0.707106947898864746, 120, 255, 1, 49345), + +-- Stormwind +(@OGUID+5, 181254, 0, 0, 0, 1, 1, -8828.5146484375, 644.6435546875, 94.47904205322265625, 3.717553615570068359, 0, 0, -0.95881938934326171, 0.284016460180282592, 120, 255, 1, 49345), +(@OGUID+6, 181255, 0, 0, 0, 1, 1, -8824.83984375, 644.90533447265625, 94.81845855712890625, 5.515241622924804687, 0, 0, -0.37460613250732421, 0.927184045314788818, 120, 255, 1, 49345), +(@OGUID+7, 181255, 0, 0, 0, 1, 1, -8824.9287109375, 644.94024658203125, 94.38431549072265625, 1.954769015312194824, 0, 0, 0.829037666320800781, 0.559192776679992675, 120, 255, 1, 49345), +(@OGUID+8, 181256, 0, 0, 0, 1, 1, -8833.5234375, 645.7451171875, 95.3211212158203125, 3.90954136848449707, 0, 0, -0.92718315124511718, 0.37460830807685852, 120, 255, 1, 49345), +(@OGUID+9, 181256, 0, 0, 0, 1, 1, -8829.498046875, 640.2664794921875, 94.3803863525390625, 3.717553615570068359, 0, 0, -0.95881938934326171, 0.284016460180282592, 120, 255, 1, 49345), + +-- Ironforge +(@OGUID+10, 181254, 0, 0, 0, 1, 1, -4930.55224609375, -992.54864501953125, 501.443145751953125, 2.234017848968505859, 0, 0, 0.898793220520019531, 0.438372820615768432, 120, 255, 1, 49345), +(@OGUID+11, 181255, 0, 0, 0, 1, 1, -4930.486328125, -988.3055419921875, 501.455291748046875, 2.094393253326416015, 0, 0, 0.866024971008300781, 0.50000077486038208, 120, 255, 1, 49345), +(@OGUID+12, 181255, 0, 0, 0, 1, 1, -4930.68408203125, -988.201416015625, 501.9072265625, 2.251473426818847656, 0, 0, 0.902585029602050781, 0.430511653423309326, 120, 255, 1, 49345), +(@OGUID+13, 181256, 0, 0, 0, 1, 1, -4935.90625, -992.138916015625, 501.450531005859375, 2.234017848968505859, 0, 0, 0.898793220520019531, 0.438372820615768432, 120, 255, 1, 49345), +(@OGUID+14, 181256, 0, 0, 0, 1, 1, -4929.71533203125, -987.20660400390625, 501.4576416015625, 2.181660413742065429, 0, 0, 0.887010574340820312, 0.461749136447906494, 120, 255, 1, 49345), + +-- Darnassus +(@OGUID+15, 181254, 1, 0, 0, 1, 1, 9921.0732421875, 2521.541259765625, 1318.099609375, 3.420850038528442382, 0, 0, -0.99026775360107421, 0.139175355434417724, 120, 255, 1, 49345), +(@OGUID+16, 181255, 1, 0, 0, 1, 1, 9920.84765625, 2526.055908203125, 1318.470947265625, 0.977383077144622802, 0, 0, 0.469470977783203125, 0.882947921752929687, 120, 255, 1, 49345), +(@OGUID+17, 181255, 1, 0, 0, 1, 1, 9920.939453125, 2525.911376953125, 1318.9603271484375, 1.239183306694030761, 0, 0, 0.580702781677246093, 0.814115643501281738, 120, 255, 1, 49345), +(@OGUID+18, 181256, 1, 0, 0, 1, 1, 9918.6259765625, 2525.05029296875, 1317.7940673828125, 2.513273954391479492, 0, 0, 0.951056480407714843, 0.309017121791839599, 120, 255, 1, 49345), +(@OGUID+19, 181256, 1, 0, 0, 1, 1, 9920.845703125, 2516.857666015625, 1317.96044921875, 4.101525306701660156, 0, 0, -0.88701057434082031, 0.461749136447906494, 120, 255, 1, 49345), + +-- Orgrimmar +(@OGUID+20, 181254, 1, 0, 0, 1, 1, 1587.87158203125, -4417.876953125, 8.158654212951660156, 3.298687219619750976, 0, 0, -0.99691677093505859, 0.078466430306434631, 120, 255, 1, 49345), +(@OGUID+21, 181255, 1, 0, 0, 1, 1, 1587.9427490234375, -4413.60400390625, 8.889185905456542968, 2.862335443496704101, 0, 0, 0.990267753601074218, 0.139175355434417724, 120, 255, 1, 49345), +(@OGUID+22, 181255, 1, 0, 0, 1, 1, 1588.2056884765625, -4413.59375, 8.402263641357421875, 6.265733242034912109, 0, 0, -0.00872611999511718, 0.999961912631988525, 120, 255, 1, 49345), +(@OGUID+23, 181256, 1, 0, 0, 1, 1, 1585.4385986328125, -4414.01025390625, 8.089628219604492187, 3.368495941162109375, 0, 0, -0.99357128143310546, 0.113208353519439697, 120, 255, 1, 49345), +(@OGUID+24, 181256, 1, 0, 0, 1, 1, 1586.84033203125, -4422.4541015625, 8.260054588317871093, 3.22885894775390625, 0, 0, -0.99904823303222656, 0.043619260191917419, 120, 255, 1, 49345), + +-- Thunder Bluff +(@OGUID+25, 181254, 1, 0, 0, 1, 1, -1277.0220947265625, 72.71939849853515625, 128.6679534912109375, 6.178466320037841796, 0, 0, -0.05233573913574218, 0.998629570007324218, 120, 255, 1, 49345), +(@OGUID+26, 181255, 1, 0, 0, 1, 1, -1277.00634765625, 77.34407806396484375, 128.3838348388671875, 6.265733242034912109, 0, 0, -0.00872611999511718, 0.999961912631988525, 120, 255, 1, 49345), +(@OGUID+27, 181255, 1, 0, 0, 1, 1, -1277.022705078125, 77.24370574951171875, 128.88458251953125, 5.969027042388916015, 0, 0, -0.1564340591430664, 0.987688362598419189, 120, 255, 1, 49345), +(@OGUID+28, 181256, 1, 0, 0, 1, 1, -1275.02099609375, 68.62082672119140625, 128.1173553466796875, 5.497788906097412109, 0, 0, -0.38268280029296875, 0.923879802227020263, 120, 255, 1, 49345), +(@OGUID+29, 181256, 1, 0, 0, 1, 1, -1273.957275390625, 76.5033111572265625, 128.1967010498046875, 0.733038187026977539, 0, 0, 0.358367919921875, 0.933580458164215087, 120, 255, 1, 49345), + +-- Undercity +(@OGUID+30, 181254, 0, 0, 0, 1, 1, 1583.4111328125, 240.459747314453125, -62.0773124694824218, 3.036838293075561523, 0, 0, 0.998628616333007812, 0.052353221923112869, 120, 255, 1, 49345), +(@OGUID+31, 181255, 0, 0, 0, 1, 1, 1582.51708984375, 236.040069580078125, -62.0773200988769531, 3.351046562194824218, 0, 0, -0.99452114105224609, 0.104535527527332305, 120, 255, 1, 49345), +(@OGUID+32, 181255, 0, 0, 0, 1, 1, 1582.244384765625, 236.144073486328125, -62.0773200988769531, 0.087265998125076293, 0, 0, 0.043619155883789062, 0.999048233032226562, 120, 255, 1, 49345), +(@OGUID+33, 181256, 0, 0, 0, 1, 1, 1580.111572265625, 236.9007720947265625, -62.0773200988769531, 3.665196180343627929, 0, 0, -0.96592521667480468, 0.258821308612823486, 120, 255, 1, 49345), +(@OGUID+34, 181256, 0, 0, 0, 1, 1, 1582.0145263671875, 244.990692138671875, -62.0773200988769531, 2.199114561080932617, 0, 0, 0.8910064697265625, 0.453990638256072998, 120, 255, 1, 49345), + +-- Silvermoon City +(@OGUID+35, 181254, 530, 0, 0, 1, 1, 9522.5283203125, -7353.31005859375, 14.314422607421875, 1.85004889965057373, 0, 0, 0.798635482788085937, 0.60181504487991333, 120, 255, 1, 49345), +(@OGUID+36, 181255, 530, 0, 0, 1, 1, 9521.119140625, -7354.52978515625, 14.76799869537353515, 3.211419343948364257, 0, 0, -0.9993906021118164, 0.034906134009361267, 120, 255, 1, 49345), +(@OGUID+37, 181255, 530, 0, 0, 1, 1, 9521.236328125, -7354.58056640625, 14.30936145782470703, 0.261798173189163208, 0, 0, 0.130525588989257812, 0.991444945335388183, 120, 255, 1, 49345), +(@OGUID+38, 181256, 530, 0, 0, 1, 1, 9516.470703125, -7352.04248046875, 14.323822021484375, 1.832594871520996093, 0, 0, 0.793353080749511718, 0.608761727809906005, 120, 255, 1, 49345), +(@OGUID+39, 181256, 530, 0, 0, 1, 1, 9526.6220703125, -7349.025390625, 14.32355976104736328, 1.815141916275024414, 0, 0, 0.788010597229003906, 0.615661680698394775, 120, 255, 1, 49345); + +SET @SCOURGEINVASION := 17; +DELETE FROM `game_event_creature` WHERE `eventEntry` = @SCOURGEINVASION AND `guid` BETWEEN @CGUID+0 AND @CGUID+30; +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES +(@SCOURGEINVASION, @CGUID+0), +(@SCOURGEINVASION, @CGUID+1), +(@SCOURGEINVASION, @CGUID+2), +(@SCOURGEINVASION, @CGUID+3), +(@SCOURGEINVASION, @CGUID+4), +(@SCOURGEINVASION, @CGUID+5), +(@SCOURGEINVASION, @CGUID+6), +(@SCOURGEINVASION, @CGUID+7), +(@SCOURGEINVASION, @CGUID+8), +(@SCOURGEINVASION, @CGUID+9), +(@SCOURGEINVASION, @CGUID+10), +(@SCOURGEINVASION, @CGUID+11), +(@SCOURGEINVASION, @CGUID+12), +(@SCOURGEINVASION, @CGUID+13), +(@SCOURGEINVASION, @CGUID+14), +(@SCOURGEINVASION, @CGUID+15), +(@SCOURGEINVASION, @CGUID+16), +(@SCOURGEINVASION, @CGUID+17), +(@SCOURGEINVASION, @CGUID+18), +(@SCOURGEINVASION, @CGUID+19), +(@SCOURGEINVASION, @CGUID+20), +(@SCOURGEINVASION, @CGUID+21), +(@SCOURGEINVASION, @CGUID+22), +(@SCOURGEINVASION, @CGUID+23), +(@SCOURGEINVASION, @CGUID+24), +(@SCOURGEINVASION, @CGUID+25), +(@SCOURGEINVASION, @CGUID+26), +(@SCOURGEINVASION, @CGUID+27), +(@SCOURGEINVASION, @CGUID+28), +(@SCOURGEINVASION, @CGUID+29), +(@SCOURGEINVASION, @CGUID+30); + +DELETE FROM `game_event_gameobject` WHERE `eventEntry` = @SCOURGEINVASION AND `guid` BETWEEN @OGUID+0 AND @OGUID+39; +INSERT INTO `game_event_gameobject` (`eventEntry`, `guid`) VALUES +(@SCOURGEINVASION, @OGUID+0), +(@SCOURGEINVASION, @OGUID+1), +(@SCOURGEINVASION, @OGUID+2), +(@SCOURGEINVASION, @OGUID+3), +(@SCOURGEINVASION, @OGUID+4), +(@SCOURGEINVASION, @OGUID+5), +(@SCOURGEINVASION, @OGUID+6), +(@SCOURGEINVASION, @OGUID+7), +(@SCOURGEINVASION, @OGUID+8), +(@SCOURGEINVASION, @OGUID+9), +(@SCOURGEINVASION, @OGUID+10), +(@SCOURGEINVASION, @OGUID+11), +(@SCOURGEINVASION, @OGUID+12), +(@SCOURGEINVASION, @OGUID+13), +(@SCOURGEINVASION, @OGUID+14), +(@SCOURGEINVASION, @OGUID+15), +(@SCOURGEINVASION, @OGUID+16), +(@SCOURGEINVASION, @OGUID+17), +(@SCOURGEINVASION, @OGUID+18), +(@SCOURGEINVASION, @OGUID+19), +(@SCOURGEINVASION, @OGUID+20), +(@SCOURGEINVASION, @OGUID+21), +(@SCOURGEINVASION, @OGUID+22), +(@SCOURGEINVASION, @OGUID+23), +(@SCOURGEINVASION, @OGUID+24), +(@SCOURGEINVASION, @OGUID+25), +(@SCOURGEINVASION, @OGUID+26), +(@SCOURGEINVASION, @OGUID+27), +(@SCOURGEINVASION, @OGUID+28), +(@SCOURGEINVASION, @OGUID+29), +(@SCOURGEINVASION, @OGUID+30), +(@SCOURGEINVASION, @OGUID+31), +(@SCOURGEINVASION, @OGUID+32), +(@SCOURGEINVASION, @OGUID+33), +(@SCOURGEINVASION, @OGUID+34), +(@SCOURGEINVASION, @OGUID+35), +(@SCOURGEINVASION, @OGUID+36), +(@SCOURGEINVASION, @OGUID+37), +(@SCOURGEINVASION, @OGUID+38), +(@SCOURGEINVASION, @OGUID+39); From a414b5776afd015c1fdbf4abe57386bb3041fb12 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 2 Mar 2025 20:30:17 +0000 Subject: [PATCH 47/57] chore(DB): import pending files Referenced commit(s): 7e78484bd84650ffb6cbf00a402275fcbee96bf5 --- .../scourge-invasion-spawns.sql => db_world/2025_03_02_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/scourge-invasion-spawns.sql => db_world/2025_03_02_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/scourge-invasion-spawns.sql b/data/sql/updates/db_world/2025_03_02_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/scourge-invasion-spawns.sql rename to data/sql/updates/db_world/2025_03_02_01.sql index 548d5d374..ea6baba6a 100644 --- a/data/sql/updates/pending_db_world/scourge-invasion-spawns.sql +++ b/data/sql/updates/db_world/2025_03_02_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_03_02_00 -> 2025_03_02_01 SET @CGUID := 12860; DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+30 AND `id1` IN (16241, 16255, 16285, 16359, 16490, 16493, 16494, 16495, 16786, 16787, 29441, 29442, 16241, 16281, 16285, 16361, 16478, 16484, 16786); INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`, `CreateObject`) VALUES From ed6f296849f7b04c232b936da881a90a5251afff Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Sun, 2 Mar 2025 15:31:02 -0500 Subject: [PATCH 48/57] fix(DB/Disables): Remove incorrectly disabled quests. (#21628) --- .../pending_db_world/zombie-infestation-quest-disables.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/zombie-infestation-quest-disables.sql diff --git a/data/sql/updates/pending_db_world/zombie-infestation-quest-disables.sql b/data/sql/updates/pending_db_world/zombie-infestation-quest-disables.sql new file mode 100644 index 000000000..3662b43ba --- /dev/null +++ b/data/sql/updates/pending_db_world/zombie-infestation-quest-disables.sql @@ -0,0 +1,2 @@ +DELETE FROM `creature_queststarter` WHERE `quest` IN (12752, 12753, 12771, 12772, 12773, 12774, 12775, 12776, 12777, 12782, 12783, 12784, 12785, 12786, 12787, 12788, 12808, 12809, 12811, 12812); -- Should later be assigned in `game_event_creature_quest`. +DELETE FROM `disables` WHERE `sourceType` = 1 AND `entry` IN (12752, 12753, 12771, 12772, 12773, 12774, 12775, 12776, 12777, 12782, 12783, 12784, 12785, 12786, 12787, 12788, 12808, 12809, 12811, 12812); From bff7b0dd7c9b944cdb5d0640c3588816989db36f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 2 Mar 2025 20:31:17 +0000 Subject: [PATCH 49/57] chore(DB): import pending files Referenced commit(s): a414b5776afd015c1fdbf4abe57386bb3041fb12 --- .../2025_03_02_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/zombie-infestation-quest-disables.sql => db_world/2025_03_02_02.sql} (91%) diff --git a/data/sql/updates/pending_db_world/zombie-infestation-quest-disables.sql b/data/sql/updates/db_world/2025_03_02_02.sql similarity index 91% rename from data/sql/updates/pending_db_world/zombie-infestation-quest-disables.sql rename to data/sql/updates/db_world/2025_03_02_02.sql index 3662b43ba..cfce03fee 100644 --- a/data/sql/updates/pending_db_world/zombie-infestation-quest-disables.sql +++ b/data/sql/updates/db_world/2025_03_02_02.sql @@ -1,2 +1,3 @@ +-- DB update 2025_03_02_01 -> 2025_03_02_02 DELETE FROM `creature_queststarter` WHERE `quest` IN (12752, 12753, 12771, 12772, 12773, 12774, 12775, 12776, 12777, 12782, 12783, 12784, 12785, 12786, 12787, 12788, 12808, 12809, 12811, 12812); -- Should later be assigned in `game_event_creature_quest`. DELETE FROM `disables` WHERE `sourceType` = 1 AND `entry` IN (12752, 12753, 12771, 12772, 12773, 12774, 12775, 12776, 12777, 12782, 12783, 12784, 12785, 12786, 12787, 12788, 12808, 12809, 12811, 12812); From 2957143338bb4f39b244122e43aa45c523bc28b7 Mon Sep 17 00:00:00 2001 From: sudlud Date: Sun, 2 Mar 2025 22:05:20 +0100 Subject: [PATCH 50/57] fix(CI/linux-build): use correct OS name for cache key (#21640) --- .github/actions/linux-build/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/linux-build/action.yml b/.github/actions/linux-build/action.yml index fc1bc2466..4da8f39b9 100644 --- a/.github/actions/linux-build/action.yml +++ b/.github/actions/linux-build/action.yml @@ -46,11 +46,11 @@ runs: path: ${{ github.workspace }}/var/ccache # format # ccache:OS:CC_CXX:MODULES:GITHUB_REF:GITHUB_SHA - key: ccache:ubuntu-latest:${{ inputs.CC }}_${{ inputs.CXX }}:${{ inputs.modules }}:${{ github.ref }}:${{ github.sha }} + key: ccache:${{ runner.os }}:${{ inputs.CC }}_${{ inputs.CXX }}:${{ inputs.modules }}:${{ github.ref }}:${{ github.sha }} restore-keys: | - ccache:ubuntu-latest:${{ inputs.CC }}_${{ inputs.CXX }}:${{ inputs.modules }}:${{ github.ref }} - ccache:ubuntu-latest:${{ inputs.CC }}_${{ inputs.CXX }}:${{ inputs.modules }} - ccache:ubuntu-latest:${{ inputs.CC }}_${{ inputs.CXX }} + ccache:${{ runner.os }}:${{ inputs.CC }}_${{ inputs.CXX }}:${{ inputs.modules }}:${{ github.ref }} + ccache:${{ runner.os }}:${{ inputs.CC }}_${{ inputs.CXX }}:${{ inputs.modules }} + ccache:${{ runner.os }}:${{ inputs.CC }}_${{ inputs.CXX }} # This script moves sql files from "data/sql/updates/pending_$DB" to the # proper folder for the db From 945b2d79fdcd2807872b445db38e5fafa41896dc Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 2 Mar 2025 22:23:36 -0300 Subject: [PATCH 51/57] fix(DB/Creature): Disable Felmyst pathfinding (#21641) --- data/sql/updates/pending_db_world/rev_1740956472100490700.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1740956472100490700.sql diff --git a/data/sql/updates/pending_db_world/rev_1740956472100490700.sql b/data/sql/updates/pending_db_world/rev_1740956472100490700.sql new file mode 100644 index 000000000..c37f0194d --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1740956472100490700.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|536870912 WHERE `entry` = 25038; From 222beca66da96995ea525c93aed4b5da679e0bc2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 3 Mar 2025 01:24:41 +0000 Subject: [PATCH 52/57] chore(DB): import pending files Referenced commit(s): 945b2d79fdcd2807872b445db38e5fafa41896dc --- .../rev_1740956472100490700.sql => db_world/2025_03_03_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1740956472100490700.sql => db_world/2025_03_03_00.sql} (68%) diff --git a/data/sql/updates/pending_db_world/rev_1740956472100490700.sql b/data/sql/updates/db_world/2025_03_03_00.sql similarity index 68% rename from data/sql/updates/pending_db_world/rev_1740956472100490700.sql rename to data/sql/updates/db_world/2025_03_03_00.sql index c37f0194d..40b2ad9ec 100644 --- a/data/sql/updates/pending_db_world/rev_1740956472100490700.sql +++ b/data/sql/updates/db_world/2025_03_03_00.sql @@ -1,2 +1,3 @@ +-- DB update 2025_03_02_02 -> 2025_03_03_00 -- UPDATE `creature_template` SET `flags_extra` = `flags_extra`|536870912 WHERE `entry` = 25038; From fdd469b61b0263bcb5a0e0a2a0a353a1b5a65df2 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Mon, 3 Mar 2025 00:12:17 -0500 Subject: [PATCH 53/57] fix(DB): Add spawns for Tenris Mirkblood room in Karazhan. (#21638) --- .../chamber-of-secrets-spawns.sql | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 data/sql/updates/pending_db_world/chamber-of-secrets-spawns.sql diff --git a/data/sql/updates/pending_db_world/chamber-of-secrets-spawns.sql b/data/sql/updates/pending_db_world/chamber-of-secrets-spawns.sql new file mode 100644 index 000000000..005192758 --- /dev/null +++ b/data/sql/updates/pending_db_world/chamber-of-secrets-spawns.sql @@ -0,0 +1,35 @@ +SET @CGUID := 452; +SET @OGUID := 517; + +DELETE FROM `creature` WHERE `guid` = @CGUID AND `id1` = 28194; +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, 28194, 532, 0, 0, 1, 1, 0, -11099.45703125, -1967.8096923828125, 76.2422027587890625, 2.49582076072692871, 7200, 0, 0, 398370, 0, 0, 0, 0, 0, 49345, 2); + +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+6 AND `id` IN (190604, 190609, 190610); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`) VALUES +(@OGUID+0, 190604, 532, 0, 0, 1, 1, -11084.806640625, -1981.458984375, 76.17449951171875, 4.049167633056640625, 0, 0, -0.89879322052001953, 0.438372820615768432, 7200, 255, 1, 49345), +(@OGUID+1, 190604, 532, 0, 0, 1, 1, -11097.796875, -1982.6768798828125, 76.17401885986328125, 1.570795774459838867, 0, 0, 0.707106590270996093, 0.707106947898864746, 7200, 255, 1, 49345), +(@OGUID+2, 190604, 532, 0, 0, 1, 1, -11091.640625, -1962.049072265625, 76.17254638671875, 0.122172988951206207, 0, 0, 0.061048507690429687, 0.998134791851043701, 7200, 255, 1, 49345), +(@OGUID+3, 190604, 532, 0, 0, 1, 1, -11104.51171875, -1973.4371337890625, 76.17641448974609375, 1.48352813720703125, 0, 0, 0.675589561462402343, 0.737277925014495849, 7200, 255, 1, 49345), +(@OGUID+4, 190609, 532, 0, 0, 1, 1, -11082.6298828125, -1973.4215087890625, 77.53208160400390625, 1.448621988296508789, 0, 0, 0.662619590759277343, 0.748956084251403808, 7200, 255, 1, 49345), +(@OGUID+5, 190610, 532, 0, 0, 1, 1, -11083.3388671875, -1972.9371337890625, 77.55469512939453125, 1.832594871520996093, 0, 0, 0.793353080749511718, 0.608761727809906005, 7200, 255, 1, 49345), +(@OGUID+6, 190604, 532, 0, 0, 1, 1, -11087.6552734375, -1996.1715087890625, 76.1771392822265625, 2.792518377304077148, 0, 0, 0.984807014465332031, 0.173652306199073791, 7200, 255, 1, 49345); + +DELETE FROM `gameobject_template` WHERE `entry` = 190610; +INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `IconName`, `castBarCaption`, `unk1`, `size`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `Data6`, `Data7`, `Data8`, `Data9`, `Data10`, `Data11`, `Data12`, `Data13`, `Data14`, `Data15`, `Data16`, `Data17`, `Data18`, `Data19`, `Data20`, `Data21`, `Data22`, `Data23`, `AIName`, `ScriptName`, `VerifiedBuild`) VALUES +(190610, 1, 220, 'Orders from the Lich King', '', 'Reading orders', '', 1, 0, 1690, 1000, 190611, 0, 0, 33041, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 49345); + +SET @SCOURGEINVASION := 17; +DELETE FROM `game_event_creature` WHERE `eventEntry` = @SCOURGEINVASION AND `guid` = @CGUID; +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES +(@SCOURGEINVASION, @CGUID); + +DELETE FROM `game_event_gameobject` WHERE `eventEntry` = @SCOURGEINVASION AND `guid` BETWEEN @OGUID+0 AND @OGUID+6; +INSERT INTO `game_event_gameobject` (`eventEntry`, `guid`) VALUES +(@SCOURGEINVASION, @OGUID+0), +(@SCOURGEINVASION, @OGUID+1), +(@SCOURGEINVASION, @OGUID+2), +(@SCOURGEINVASION, @OGUID+3), +(@SCOURGEINVASION, @OGUID+4), +(@SCOURGEINVASION, @OGUID+5), +(@SCOURGEINVASION, @OGUID+6); From 6fc63331411057fd2174906688a2bb8c29852978 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 3 Mar 2025 05:13:16 +0000 Subject: [PATCH 54/57] chore(DB): import pending files Referenced commit(s): fdd469b61b0263bcb5a0e0a2a0a353a1b5a65df2 --- .../chamber-of-secrets-spawns.sql => db_world/2025_03_03_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/chamber-of-secrets-spawns.sql => db_world/2025_03_03_01.sql} (98%) diff --git a/data/sql/updates/pending_db_world/chamber-of-secrets-spawns.sql b/data/sql/updates/db_world/2025_03_03_01.sql similarity index 98% rename from data/sql/updates/pending_db_world/chamber-of-secrets-spawns.sql rename to data/sql/updates/db_world/2025_03_03_01.sql index 005192758..ec5639c07 100644 --- a/data/sql/updates/pending_db_world/chamber-of-secrets-spawns.sql +++ b/data/sql/updates/db_world/2025_03_03_01.sql @@ -1,3 +1,4 @@ +-- DB update 2025_03_03_00 -> 2025_03_03_01 SET @CGUID := 452; SET @OGUID := 517; From ba37b3d1307d50b701d9312212c4c6aa1fc38bbb Mon Sep 17 00:00:00 2001 From: sudlud Date: Mon, 3 Mar 2025 18:46:03 +0100 Subject: [PATCH 55/57] feat(CI/modules-build): add all current azerothcore modules (#21624) --- apps/ci/ci-install-modules.sh | 120 +++++++++++++++++++++++++++------- 1 file changed, 98 insertions(+), 22 deletions(-) diff --git a/apps/ci/ci-install-modules.sh b/apps/ci/ci-install-modules.sh index b3271de3c..abb085a7b 100755 --- a/apps/ci/ci-install-modules.sh +++ b/apps/ci/ci-install-modules.sh @@ -3,29 +3,105 @@ set -e echo "install modules" -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-eluna.git modules/mod-eluna -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-autobalance.git modules/mod-autobalance -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-ah-bot.git modules/mod-ah-bot -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-anticheat.git modules/mod-anticheat -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-bg-item-reward.git modules/mod-bg-item-reward +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-1v1-arena modules/mod-1v1-arena +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-account-mounts modules/mod-account-mounts +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-ah-bot modules/mod-ah-bot +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-anticheat modules/mod-anticheat +# NOTE: disabled because it does not compile right now with latest AC +# git clone --depth=1 --branch=master https://github.com/azerothcore/mod-antifarming modules/mod-antifarming +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-arena-3v3-solo-queue modules/mod-arena-3v3-solo-queue +git clone --depth=1 --branch=main https://github.com/azerothcore/mod-arena-replay modules/mod-arena-replay +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-auto-revive modules/mod-auto-revive +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-autobalance modules/mod-autobalance # NOTE: disabled because it causes DB error # git clone --depth=1 --branch=master https://github.com/azerothcore/mod-azerothshard.git modules/mod-azerothshard -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-cfbg.git modules/mod-cfbg +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-better-item-reloading modules/mod-better-item-reloading +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-bg-item-reward modules/mod-bg-item-reward +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-bg-reward modules/mod-bg-reward +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-boss-announcer modules/mod-boss-announcer +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-breaking-news-override modules/mod-breaking-news-override +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-buff-command modules/mod-buff-command +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-cfbg modules/mod-cfbg +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-character-tools modules/mod-character-tools +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-chat-login modules/mod-chat-login git clone --depth=1 --branch=master https://github.com/azerothcore/mod-chat-transmitter modules/mod-chat-transmitter -# NOTE: disabled because it causes DB error -#git clone --depth=1 --branch=master https://github.com/azerothcore/mod-chromie-xp.git modules/mod-chromie-xp -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-cta-switch.git modules/mod-cta-switch -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-desertion-warnings.git modules/mod-desertion-warnings -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-duel-reset.git modules/mod-duel-reset -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-ip-tracker.git modules/mod-ip-tracker -git clone --depth=1 --branch=main https://github.com/azerothcore/mod-low-level-arena.git modules/mod-low-level-arena -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-low-level-rbg.git modules/mod-low-level-rbg -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-multi-client-check.git modules/mod-multi-client-check -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-pvp-titles.git modules/mod-pvp-titles -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-pvpstats-announcer.git modules/mod-pvpstats-announcer -git clone --depth=1 --branch=main https://github.com/azerothcore/mod-queue-list-cache.git modules/mod-queue-list-cache -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-server-auto-shutdown.git modules/mod-server-auto-shutdown -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-transmog.git modules/mod-transmog +# NOTE: disabled because it causes DB startup error +# git clone --depth=1 --branch=master https://github.com/azerothcore/mod-chromie-xp modules/mod-chromie-xp +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-congrats-on-level modules/mod-congrats-on-level +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-costumes modules/mod-costumes +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-cta-switch modules/mod-cta-switch +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-custom-login modules/mod-custom-login +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-desertion-warnings modules/mod-desertion-warnings +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-detailed-logging modules/mod-detailed-logging +git clone --depth=1 --branch=main https://github.com/azerothcore/mod-dmf-switch modules/mod-dmf-switch +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-duel-reset modules/mod-duel-reset +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-dynamic-xp modules/mod-dynamic-xp +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-eluna modules/mod-eluna +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-emblem-transfer modules/mod-emblem-transfer +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-fireworks-on-level modules/mod-fireworks-on-level +git clone --depth=1 --branch=main https://github.com/azerothcore/mod-global-chat modules/mod-global-chat +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-guild-zone-system modules/mod-guild-zone-system +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-guildhouse modules/mod-guildhouse +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-individual-xp modules/mod-individual-xp +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-instance-reset modules/mod-instance-reset +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-instanced-worldbosses modules/mod-instanced-worldbosses +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-ip-tracker modules/mod-ip-tracker +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-item-level-up modules/mod-item-level-up +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-keep-out modules/mod-keep-out +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-learn-highest-talent modules/mod-learn-highest-talent +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-learn-spells modules/mod-learn-spells +git clone --depth=1 --branch=main https://github.com/azerothcore/mod-low-level-arena modules/mod-low-level-arena +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-low-level-rbg modules/mod-low-level-rbg +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-mall-teleport modules/mod-mall-teleport +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-morph-all-players modules/mod-morph-all-players +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-morphsummon modules/mod-morphsummon +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-multi-client-check modules/mod-multi-client-check +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-notify-muted modules/mod-notify-muted +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-npc-all-mounts modules/mod-npc-all-mounts +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-npc-beastmaster modules/mod-npc-beastmaster +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-npc-buffer modules/mod-npc-buffer +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-npc-codebox modules/mod-npc-codebox +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-npc-enchanter modules/mod-npc-enchanter +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-npc-free-professions modules/mod-npc-free-professions +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-npc-gambler modules/mod-npc-gambler +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-npc-morph modules/mod-npc-morph +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-npc-services modules/mod-npc-services +# not yet on azerothcore github +git clone --depth=1 --branch=master https://github.com/gozzim/mod-npc-spectator modules/mod-npc-spectator +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-npc-talent-template modules/mod-npc-talent-template +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-npc-titles-tokens modules/mod-npc-titles-tokens +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-phased-duels modules/mod-phased-duels +# outdated +# git clone --depth=1 --branch=master https://github.com/azerothcore/mod-playerbots modules/mod-playerbots +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-pocket-portal modules/mod-pocket-portal +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-premium modules/mod-premium git clone --depth=1 --branch=main https://github.com/azerothcore/mod-progression-system.git modules/mod-progression-system -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-arena-3v3-solo-queue.git modules/mod-arena-3v3-solo-queue -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-costumes.git modules/mod-costumes +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-promotion-azerothcore modules/mod-promotion-azerothcore +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-pvp-quests modules/mod-pvp-quests +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-pvp-titles modules/mod-pvp-titles +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-pvp-zones modules/mod-pvp-zones +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-pvpscript modules/mod-pvpscript +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-pvpstats-announcer modules/mod-pvpstats-announcer +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-quest-status modules/mod-quest-status +git clone --depth=1 --branch=main https://github.com/azerothcore/mod-queue-list-cache modules/mod-queue-list-cache +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-quick-teleport modules/mod-quick-teleport +git clone --depth=1 --branch=main https://github.com/azerothcore/mod-racial-trait-swap modules/mod-racial-trait-swap +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-random-enchants modules/mod-random-enchants +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-rdf-expansion modules/mod-rdf-expansion +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-resurrection-scroll modules/mod-resurrection-scroll +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-reward-played-time modules/mod-reward-played-time +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-reward-shop modules/mod-reward-shop +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-server-auto-shutdown.git modules/mod-server-auto-shutdown +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-solocraft modules/mod-solocraft +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-skip-dk-starting-area modules/mod-skip-dk-starting-area +# has core patch file +# git clone --depth=1 --branch=master https://github.com/azerothcore/mod-spell-regulator modules/mod-spell-regulator +git clone --depth=1 --branch=master https://github.com/azerothcore/mod-starter-guild modules/mod-starter-guild +git clone --depth=1 --branch=main https://github.com/azerothcore/mod-system-vip modules/mod-system-vip +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 +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 a2a0bc51ab5e8c33a650a77b6098b1a6c5d3ff82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E9=B9=BF?= <18535853+PkllonG@users.noreply.github.com> Date: Tue, 4 Mar 2025 05:11:56 +0800 Subject: [PATCH 56/57] fix(Core/Bones): Unable to create bones (#21635) --- src/server/game/Maps/Map.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index b6a239274..bfed9c5e7 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2828,7 +2828,7 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const ownerGuid, bool insignia /*= // ignore bones creating option in case insignia if ((insignia || (IsBattlegroundOrArena() ? sWorld->getBoolConfig(CONFIG_DEATH_BONES_BG_OR_ARENA) : sWorld->getBoolConfig(CONFIG_DEATH_BONES_WORLD))) && - !IsGridCreated(corpse->GetPositionX(), corpse->GetPositionY())) + IsGridLoaded(corpse->GetPositionX(), corpse->GetPositionY())) { // Create bones, don't change Corpse bones = new Corpse(); From 82bc814858c2f9f507bfa707fce1b2507d6afaed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E9=B9=BF?= <18535853+PkllonG@users.noreply.github.com> Date: Tue, 4 Mar 2025 05:12:54 +0800 Subject: [PATCH 57/57] fix(Core/PvP): Sometimes mobs and objects fail to spawn in OutdoorPvP (#21636) --- src/server/game/Globals/ObjectMgr.cpp | 6 +++--- src/server/game/Globals/ObjectMgr.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index dede1dbed..47cdd1cf7 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2362,7 +2362,7 @@ void ObjectMgr::RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData co } } -uint32 ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, float y, float z, float o, uint32 spawntimedelay, float rotation0, float rotation1, float rotation2, float rotation3) +ObjectGuid::LowType ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, float y, float z, float o, uint32 spawntimedelay, float rotation0, float rotation1, float rotation2, float rotation3) { GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry); if (!goinfo) @@ -2413,7 +2413,7 @@ uint32 ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, float y, float return spawnId; } -uint32 ObjectMgr::AddCreData(uint32 entry, uint32 mapId, float x, float y, float z, float o, uint32 spawntimedelay) +ObjectGuid::LowType ObjectMgr::AddCreData(uint32 entry, uint32 mapId, float x, float y, float z, float o, uint32 spawntimedelay) { CreatureTemplate const* cInfo = GetCreatureTemplate(entry); if (!cInfo) @@ -2454,7 +2454,7 @@ uint32 ObjectMgr::AddCreData(uint32 entry, uint32 mapId, float x, float y, float AddCreatureToGrid(spawnId, &data); // Spawn if necessary (loaded grids only) - if (!map->Instanceable() && !map->IsGridCreated(x, y)) + if (!map->Instanceable() && map->IsGridLoaded(x, y)) { Creature* creature = new Creature(); if (!creature->LoadCreatureFromDB(spawnId, map, true, true)) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 0c2a307ea..553bf3b26 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1324,8 +1324,8 @@ public: void RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData const* data); void AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData const* data); void RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectData const* data); - uint32 AddGOData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0, float rotation0 = 0, float rotation1 = 0, float rotation2 = 0, float rotation3 = 0); - uint32 AddCreData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0); + ObjectGuid::LowType AddGOData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0, float rotation0 = 0, float rotation1 = 0, float rotation2 = 0, float rotation3 = 0); + ObjectGuid::LowType AddCreData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0); // reserved names void LoadReservedPlayerNamesDB();