From b8a08dc008de8d871f913b6a9f680095bf2d6364 Mon Sep 17 00:00:00 2001 From: sudlud Date: Sat, 31 Jan 2026 08:30:18 +0100 Subject: [PATCH 001/335] fix(CI/Windows): installer script - update OpenSSL version to 3.6.1 (#24558) --- apps/installer/includes/os_configs/windows.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/installer/includes/os_configs/windows.sh b/apps/installer/includes/os_configs/windows.sh index cdba50c27..ae69640b0 100644 --- a/apps/installer/includes/os_configs/windows.sh +++ b/apps/installer/includes/os_configs/windows.sh @@ -24,6 +24,6 @@ fi choco install -y --skip-checksums "${INSTALL_ARGS[@]}" cmake.install -y --installargs 'ADD_CMAKE_TO_PATH=System' choco install -y --skip-checksums "${INSTALL_ARGS[@]}" visualstudio2022-workload-nativedesktop -choco install -y --skip-checksums "${INSTALL_ARGS[@]}" openssl --force --version=3.5.4 +choco install -y --skip-checksums "${INSTALL_ARGS[@]}" openssl --force --version=3.6.1 choco install -y --skip-checksums "${INSTALL_ARGS[@]}" boost-msvc-14.3 --force --version=1.87.0 choco install -y --skip-checksums "${INSTALL_ARGS[@]}" mysql --force --version=8.4.6 From 2a120350a46578a658961b08c11d972e1687a21b Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sat, 31 Jan 2026 05:39:43 -0300 Subject: [PATCH 002/335] fix(DB/Creature): Set Correct Faction for Spotted Hippogryph (23772) and Shoveltusk Forager (29479) (#24565) --- data/sql/updates/pending_db_world/rev_1769818524592891700.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1769818524592891700.sql diff --git a/data/sql/updates/pending_db_world/rev_1769818524592891700.sql b/data/sql/updates/pending_db_world/rev_1769818524592891700.sql new file mode 100644 index 000000000..ad5abc464 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769818524592891700.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template` SET `faction` = 634 WHERE (`entry` IN (23772, 29479)); From f5ee8dee4dfb651b30e13af4295fb3e6abaa3a55 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sat, 31 Jan 2026 05:40:53 -0300 Subject: [PATCH 003/335] fix(DB/Loot): Adjust Jotunheim Cage Key Chances (#24564) --- data/sql/updates/pending_db_world/rev_1769817956231984100.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1769817956231984100.sql diff --git a/data/sql/updates/pending_db_world/rev_1769817956231984100.sql b/data/sql/updates/pending_db_world/rev_1769817956231984100.sql new file mode 100644 index 000000000..50a37c25b --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769817956231984100.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_loot_template` SET `Chance` = 40 WHERE `Item` = 42422 AND `Entry` IN (29880, 30037, 30243, 30250, 30632, 30725); From f279dd168382eded87723152b1447c13497b05bf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 31 Jan 2026 08:42:01 +0000 Subject: [PATCH 004/335] chore(DB): import pending files Referenced commit(s): f5ee8dee4dfb651b30e13af4295fb3e6abaa3a55 --- .../rev_1769817956231984100.sql => db_world/2026_01_31_00.sql} | 1 + .../rev_1769818524592891700.sql => db_world/2026_01_31_01.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1769817956231984100.sql => db_world/2026_01_31_00.sql} (75%) rename data/sql/updates/{pending_db_world/rev_1769818524592891700.sql => db_world/2026_01_31_01.sql} (65%) diff --git a/data/sql/updates/pending_db_world/rev_1769817956231984100.sql b/data/sql/updates/db_world/2026_01_31_00.sql similarity index 75% rename from data/sql/updates/pending_db_world/rev_1769817956231984100.sql rename to data/sql/updates/db_world/2026_01_31_00.sql index 50a37c25b..f5d610d89 100644 --- a/data/sql/updates/pending_db_world/rev_1769817956231984100.sql +++ b/data/sql/updates/db_world/2026_01_31_00.sql @@ -1,2 +1,3 @@ +-- DB update 2026_01_30_01 -> 2026_01_31_00 -- UPDATE `creature_loot_template` SET `Chance` = 40 WHERE `Item` = 42422 AND `Entry` IN (29880, 30037, 30243, 30250, 30632, 30725); diff --git a/data/sql/updates/pending_db_world/rev_1769818524592891700.sql b/data/sql/updates/db_world/2026_01_31_01.sql similarity index 65% rename from data/sql/updates/pending_db_world/rev_1769818524592891700.sql rename to data/sql/updates/db_world/2026_01_31_01.sql index ad5abc464..7e84d0fca 100644 --- a/data/sql/updates/pending_db_world/rev_1769818524592891700.sql +++ b/data/sql/updates/db_world/2026_01_31_01.sql @@ -1,2 +1,3 @@ +-- DB update 2026_01_31_00 -> 2026_01_31_01 -- UPDATE `creature_template` SET `faction` = 634 WHERE (`entry` IN (23772, 29479)); From 324d014bb845437d82c8df7d807cd37f06e55f4a Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 31 Jan 2026 13:41:21 -0300 Subject: [PATCH 005/335] fix(Scripts/EoE): fix Malygos reseting at p3 and other improvements (#24566) --- .../Nexus/EyeOfEternity/boss_malygos.cpp | 65 ++----- .../Nexus/EyeOfEternity/eye_of_eternity.h | 9 +- .../instance_eye_of_eternity.cpp | 162 ++++++++---------- 3 files changed, 97 insertions(+), 139 deletions(-) diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index d77608b47..744b60477 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -188,16 +188,9 @@ enum MalygosLightOverrides LIGHT_OBSCURE_ARCANE_RUNES = 1825, }; -struct boss_malygos : public ScriptedAI +struct boss_malygos : public BossAI { - boss_malygos(Creature* c) : ScriptedAI(c), summons(me) - { - pInstance = me->GetInstanceScript(); - } - - InstanceScript* pInstance; - EventMap events; - SummonList summons; + boss_malygos(Creature* creature) : BossAI(creature, DATA_MALYGOS) { } uint32 timer1, timer2; uint8 IntroCounter; @@ -211,9 +204,7 @@ struct boss_malygos : public ScriptedAI void Reset() override { - events.Reset(); - events.SetPhase(PHASE_NONE); - summons.DespawnAll(); + _Reset(); timer1 = MalygosIntroIntervals[4]; timer2 = INTRO_MOVEMENT_INTERVAL; @@ -226,11 +217,7 @@ struct boss_malygos : public ScriptedAI me->SetAnimTier(AnimTier::Fly); - if (pInstance) - { - pInstance->SetData(DATA_ENCOUNTER_STATUS, NOT_STARTED); - pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_YOU_DONT_HAVE_AN_ENTERNITY_EVENT); - } + instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_YOU_DONT_HAVE_AN_ENTERNITY_EVENT); } void MovementInform(uint32 type, uint32 id) override @@ -305,14 +292,10 @@ struct boss_malygos : public ScriptedAI void JustEngagedWith(Unit* /*who*/) override { + _JustEngagedWith(); events.Reset(); - DoZoneInCombat(); - Talk(SAY_PHASE_1); - events.RescheduleEvent(EVENT_INTRO_MOVE_CENTER, 0ms, 1); - if (pInstance) - pInstance->SetData(DATA_ENCOUNTER_STATUS, IN_PROGRESS); } void AttackStart(Unit* victim) override @@ -372,8 +355,7 @@ struct boss_malygos : public ScriptedAI break; case EVENT_INTRO_MOVE_CENTER: { - if (pInstance) - pInstance->SetData(DATA_SET_IRIS_INACTIVE, 0); + instance->SetData(DATA_SET_IRIS_INACTIVE, 0); summons.DespawnAll(); me->InterruptNonMeleeSpells(true); me->RemoveAllAuras(); @@ -392,11 +374,8 @@ struct boss_malygos : public ScriptedAI } case EVENT_START_FIGHT: { - if (pInstance) - { - pInstance->SetData(DATA_HIDE_IRIS_AND_PORTAL, 0); - pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_YOU_DONT_HAVE_AN_ENTERNITY_EVENT); - } + instance->SetData(DATA_HIDE_IRIS_AND_PORTAL, 0); + instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_YOU_DONT_HAVE_AN_ENTERNITY_EVENT); me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED); if (Unit* target = me->SelectNearestTarget(250.0f)) { @@ -689,19 +668,16 @@ struct boss_malygos : public ScriptedAI me->GetThreatMgr().ClearAllThreat(); // players on vehicle are unattackable -> leads to EnterEvadeMode() because target is not acceptable! - // mount players: - Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers(); - if (!PlayerList.IsEmpty()) - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - if (Player* player = i->GetSource()) - { - sScriptMgr->AnticheatSetUnderACKmount(player); + me->GetMap()->DoForAllPlayers([&](Player* player) + { + if (player->IsAlive() && !player->IsGameMaster()) + { + sScriptMgr->AnticheatSetUnderACKmount(player); + player->CastSpell(player, SPELL_SUMMON_RED_DRAGON_BUDDY, true); + } + }); - if (!player->IsAlive() || player->IsGameMaster()) - continue; - - player->CastSpell(player, SPELL_SUMMON_RED_DRAGON_BUDDY, true); - } + DoZoneInCombat(); events.RescheduleEvent(EVENT_SAY_PHASE_3_INTRO, 3s, 1); } @@ -744,12 +720,9 @@ struct boss_malygos : public ScriptedAI void JustDied(Unit* /*killer*/) override { + _JustDied(); Talk(SAY_DEATH); - if (pInstance) - { - pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_MALYGOS, 1); - pInstance->SetData(DATA_ENCOUNTER_STATUS, DONE); - } + instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_MALYGOS, 1); } void KilledUnit(Unit* victim) override diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h index 77a4f7c46..2b3ddfd38 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h @@ -24,6 +24,8 @@ #define DataHeader "EOE" #define EyeOfEternityScriptName "instance_eye_of_eternity" +uint32 const EncounterCount = 1; + enum Objects { GO_NEXUS_PLATFORM = 193070, @@ -52,8 +54,8 @@ enum NPCs enum Data { + DATA_MALYGOS = 0, DATA_IRIS_ACTIVATED, - DATA_ENCOUNTER_STATUS, DATA_SET_IRIS_INACTIVE, DATA_HIDE_IRIS_AND_PORTAL, DATA_MALYGOS_GUID, @@ -87,6 +89,11 @@ enum eAchiev ACHIEV_YOU_DONT_HAVE_AN_ENTERNITY_EVENT = 20387, }; +enum EoEMisc : uint32 +{ + EVENT_IRIS_ACTIVATED = 20158 +}; + /*** POSITIONS/WAYPOINTS BELOW ***/ #define INTRO_MOVEMENT_INTERVAL 25000 diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index fea436c4b..42788ec50 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -26,18 +26,10 @@ class instance_eye_of_eternity : public InstanceMapScript public: instance_eye_of_eternity() : InstanceMapScript("instance_eye_of_eternity", MAP_THE_EYE_OF_ETERNITY) { } - InstanceScript* GetInstanceScript(InstanceMap* pMap) const override - { - return new instance_eye_of_eternity_InstanceMapScript(pMap); - } - struct instance_eye_of_eternity_InstanceMapScript : public InstanceScript { instance_eye_of_eternity_InstanceMapScript(Map* pMap) : InstanceScript(pMap) { Initialize(); } - uint32 EncounterStatus; - std::string str_data; - ObjectGuid NPC_MalygosGUID; ObjectGuid GO_IrisGUID; ObjectGuid GO_ExitPortalGUID; @@ -46,34 +38,24 @@ public: void Initialize() override { - EncounterStatus = NOT_STARTED; - + SetHeaders(DataHeader); + SetBossNumber(EncounterCount); bPokeAchiev = false; } - bool IsEncounterInProgress() const override - { - return EncounterStatus == IN_PROGRESS; - } - void OnPlayerEnter(Player* player) override { - if (EncounterStatus == DONE) + if (GetBossState(DATA_MALYGOS) == DONE) { // destroy platform, hide iris (actually ensure, done at loading, but doesn't always work - ProcessEvent(nullptr, 20158); + ProcessEvent(nullptr, EVENT_IRIS_ACTIVATED); if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) if (go->GetPhaseMask() != 2) go->SetPhaseMask(2, true); // no floor, so put players on drakes - if (player) - { - if (!player->IsAlive()) - return; - + if (player && player->IsAlive()) player->CastSpell(player, SPELL_SUMMON_RED_DRAGON_BUDDY, true); - } } } @@ -94,59 +76,34 @@ public: case GO_IRIS_N: case GO_IRIS_H: GO_IrisGUID = go->GetGUID(); + + if (GetBossState(DATA_MALYGOS) == DONE) + go->SetPhaseMask(2, true); break; case GO_EXIT_PORTAL: GO_ExitPortalGUID = go->GetGUID(); break; case GO_NEXUS_PLATFORM: GO_PlatformGUID = go->GetGUID(); + if (GetBossState(DATA_MALYGOS) == DONE) + { + go->ModifyHealth(-6500000); // We have HP 6 million in the database... So we have to do at least that + go->EnableCollision(false); + } break; } } - void SetData(uint32 type, uint32 data) override + void SetData(uint32 type, uint32 /*data*/) override { switch (type) { case DATA_IRIS_ACTIVATED: - if (EncounterStatus == NOT_STARTED) + if (GetBossState(DATA_MALYGOS) == NOT_STARTED) if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) if (Player* plr = c->SelectNearestPlayer(250.0f)) c->AI()->AttackStart(plr); break; - case DATA_ENCOUNTER_STATUS: - EncounterStatus = data; - switch (data) - { - case NOT_STARTED: - bPokeAchiev = false; - if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) - { - go->SetPhaseMask(1, true); - HandleGameObject(GO_IrisGUID, false, go); - } - if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) - go->SetPhaseMask(1, true); - if (GameObject* go = instance->GetGameObject(GO_PlatformGUID)) - { - go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, nullptr, true); - go->EnableCollision(true); - } - break; - case IN_PROGRESS: - bPokeAchiev = (instance->GetPlayersCountExceptGMs() < (instance->GetSpawnMode() == 0 ? (uint32)9 : (uint32)21)); - break; - case DONE: - bPokeAchiev = false; - if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) - go->SetPhaseMask(1, true); - if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) - if (c->SummonCreature(NPC_ALEXSTRASZA, 798.0f, 1268.0f, 299.0f, 2.45f, TEMPSUMMON_TIMED_DESPAWN, 604800000)) - break; - } - if (data == DONE) - SaveToDB(); - break; case DATA_SET_IRIS_INACTIVE: if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) { @@ -164,6 +121,49 @@ public: } } + bool SetBossState(uint32 type, EncounterState state) override + { + if (!InstanceScript::SetBossState(type, state)) + return false; + + if (type == DATA_MALYGOS) + { + switch (state) + { + case NOT_STARTED: + bPokeAchiev = false; + if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) + { + go->SetPhaseMask(1, true); + HandleGameObject(GO_IrisGUID, false, go); + } + if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) + go->SetPhaseMask(1, true); + if (GameObject* go = instance->GetGameObject(GO_PlatformGUID)) + { + go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, nullptr, true); + go->EnableCollision(true); + } + break; + case IN_PROGRESS: + bPokeAchiev = (instance->GetPlayersCountExceptGMs() < (instance->GetSpawnMode() == 0 ? (uint32)9 : (uint32)21)); + break; + case DONE: + bPokeAchiev = false; + if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) + go->SetPhaseMask(1, true); + if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) + if (c->SummonCreature(NPC_ALEXSTRASZA, 798.0f, 1268.0f, 299.0f, 2.45f, TEMPSUMMON_TIMED_DESPAWN, 604800000)) + break; + break; + default: + break; + } + } + + return true; + } + ObjectGuid GetGuidData(uint32 type) const override { switch (type) @@ -177,40 +177,13 @@ public: void ProcessEvent(WorldObject* /*unit*/, uint32 eventId) override { - switch (eventId) - { - case 20158: - if (GameObject* go = instance->GetGameObject(GO_PlatformGUID)) - if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) - { - go->ModifyHealth(-6500000, c); // We have HP 6 million in the database... So we have to do at least that - go->EnableCollision(false); - } - break; - } - } - - void ReadSaveDataMore(std::istringstream& data) override - { - data >> EncounterStatus; - - switch (EncounterStatus) - { - case IN_PROGRESS: - EncounterStatus = NOT_STARTED; - break; - case DONE: - // destroy platform, hide iris - ProcessEvent(nullptr, 20158); - if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) - go->SetPhaseMask(2, true); - break; - } - } - - void WriteSaveDataMore(std::ostringstream& data) override - { - data << EncounterStatus; + if (eventId == EVENT_IRIS_ACTIVATED) + if (GameObject* go = instance->GetGameObject(GO_PlatformGUID)) + if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) + { + go->ModifyHealth(-6500000, c); // We have HP 6 million in the database... So we have to do at least that + go->EnableCollision(false); + } } bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* /*target*/, uint32 /*miscvalue1*/) override @@ -227,6 +200,11 @@ public: return false; } }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new instance_eye_of_eternity_InstanceMapScript(map); + } }; void AddSC_instance_eye_of_eternity() From 4864b800b0ee8175aa5604c5ab22c0f3941f108e Mon Sep 17 00:00:00 2001 From: Victor Godoy <44324742+xDevICCI@users.noreply.github.com> Date: Sat, 31 Jan 2026 13:44:19 -0300 Subject: [PATCH 006/335] =?UTF-8?q?fix(Scripts/Naxx):=20Thaddius=20Ball=20?= =?UTF-8?q?Lightning=20should=20check=20all=20players=20i=E2=80=A6=20(#243?= =?UTF-8?q?92)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: victor --- .../Northrend/Naxxramas/boss_thaddius.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp index 61c609fe4..f0831da05 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp @@ -129,6 +129,15 @@ public: uint32 resetTimer{}; bool ballLightningEnabled; + bool IsAnyPlayerInMeleeRange() const + { + for (auto const& ref : me->GetThreatMgr().GetThreatList()) + if (Unit* target = ref->getTarget()) + if (target->IsPlayer() && me->IsWithinMeleeRange(target)) + return true; + return false; + } + void DoAction(int32 param) override { if (param == ACTION_SUMMON_DIED) @@ -327,17 +336,11 @@ public: break; } - if (me->IsWithinMeleeRange(me->GetVictim())) - { + if (IsAnyPlayerInMeleeRange()) DoMeleeAttackIfReady(); - } - else if (ballLightningEnabled) - { + else if (ballLightningEnabled && !IsAnyPlayerInMeleeRange()) if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat)) - { me->CastSpell(target, SPELL_BALL_LIGHTNING, false); - } - } } }; }; From a151c9a8941d63be725f856828a0a83ceae7fd12 Mon Sep 17 00:00:00 2001 From: sudlud Date: Sat, 31 Jan 2026 21:35:03 +0100 Subject: [PATCH 007/335] fix(DB/game_event): Brewfest Building (Ironforge) (#24527) Co-authored-by: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Co-authored-by: Gultask <100873791+Gultask@users.noreply.github.com> --- .../rev_1769462581164552400.sql | 307 ++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1769462581164552400.sql diff --git a/data/sql/updates/pending_db_world/rev_1769462581164552400.sql b/data/sql/updates/pending_db_world/rev_1769462581164552400.sql new file mode 100644 index 000000000..c686b416a --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769462581164552400.sql @@ -0,0 +1,307 @@ +-- update game event +UPDATE `game_event` SET `description` = "Brewfest Building (Ironforge)" WHERE `eventEntry` = 70; + +-- Update gameobject 'Brewfest Building (Ironforge)' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (186737, 186717, 180052, 186217, 180026)) AND (`guid` IN (66860, 66861, 66862, 66863, 66864, 66865, 66866, 66867, 66868, 66869, 66870, 66871)); +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 +(66860, 186737, 0, 0, 0, 1, 1, -5188.759765625, -594.41571044921875, 397.176177978515625, 5.096362113952636718, 0, 0, -0.55919265747070312, 0.829037725925445556, 120, 255, 1, "", 50664, NULL), +(66861, 186737, 0, 0, 0, 1, 1, -5140.78173828125, -578.31964111328125, 397.176177978515625, 3.926995515823364257, 0, 0, -0.92387866973876953, 0.38268551230430603, 120, 255, 1, "", 50664, NULL), +(66862, 186737, 0, 0, 0, 1, 1, -5155.751953125, -635.501953125, 397.1766357421875, 1.797688722610473632, 0, 0, 0.7826080322265625, 0.622514784336090087, 120, 255, 1, "", 50664, NULL), +(66863, 186717, 0, 0, 0, 1, 1, -5209.8369140625, -459.36285400390625, 386.537017822265625, 2.565631866455078125, 0, 0, 0.958819389343261718, 0.284016460180282592, 120, 255, 1, "", 50664, NULL), +(66864, 186717, 0, 0, 0, 1, 1, -5226.5390625, -479.025665283203125, 386.5343017578125, 2.234017848968505859, 0, 0, 0.898793220520019531, 0.438372820615768432, 120, 255, 1, "", 50664, NULL), +(66865, 186717, 0, 0, 0, 1, 1, -5233.375, -482.2637939453125, 386.3370361328125, 1.919861555099487304, 0, 0, 0.819151878356933593, 0.573576688766479492, 120, 255, 1, "", 50664, NULL), +(66866, 186717, 0, 0, 0, 1, 1, -5206.923828125, -452.243072509765625, 386.807891845703125, 3.019413232803344726, 0, 0, 0.998134613037109375, 0.061051756143569946, 120, 255, 1, "", 50664, NULL), +(66867, 180052, 0, 0, 0, 1, 1, -5175.2998046875, -625.16534423828125, 397.176177978515625, 2.914689540863037109, 0, 0, 0.993571281433105468, 0.113208353519439697, 120, 255, 1, "", 50664, NULL), +(66868, 186217, 0, 0, 0, 1, 1, -5208.20947265625, -456.07220458984375, 386.74652099609375, 2.70525527000427246, 0, 0, 0.97629547119140625, 0.216442063450813293, 120, 255, 1, "", 50664, NULL), +(66869, 186217, 0, 0, 0, 1, 1, -5230.0302734375, -480.293365478515625, 386.399810791015625, 2.129300594329833984, 0, 0, 0.874619483947753906, 0.484810054302215576, 120, 255, 1, "", 50664, NULL), +(66870, 180026, 0, 0, 0, 1, 1, -5208.1025390625, -455.9600830078125, 386.514923095703125, 3.298687219619750976, 0, 0, -0.99691677093505859, 0.078466430306434631, 120, 255, 1, "", 50664, NULL), +(66871, 180026, 0, 0, 0, 1, 1, -5229.85791015625, -480.2882080078125, 386.363250732421875, 2.687806606292724609, 0, 0, 0.974370002746582031, 0.224951311945915222, 120, 255, 1, "", 50664, NULL); + +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 70) AND (`guid` IN (66860, 66861, 66862, 66863, 66864, 66865, 66866, 66867, 66868, 66869, 66870, 66871)); +INSERT INTO `game_event_gameobject` (`eventEntry`,`guid`) VALUES +(70, 66860), +(70, 66861), +(70, 66862), +(70, 66863), +(70, 66864), +(70, 66865), +(70, 66866), +(70, 66867), +(70, 66868), +(70, 66869), +(70, 66870), +(70, 66871); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (178666, 179967, 179968, 179969, 179970, 179972, 179973, 179977, 180007, 180046, 180047, 180353, 186683)) AND (`guid` IN (3839, 3840, 3841, 3842, 3843, 3844, 3845, 3846, 3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856, 3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, 3871, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890, 3891, 3892, 3893, 3894, 3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903)); +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 +(3839, 178666, 0, 0, 0, 1, 1, -5147.7939453125, -607.88812255859375, 398.5308837890625, 4.1538848876953125, 0, 0, -0.8746194839477539, 0.484810054302215576, 120, 255, 1, "", 50664, NULL), +(3840, 178666, 0, 0, 0, 1, 1, -5151.845703125, -599.5625, 398.12542724609375, 5.93412017822265625, 0, 0, -0.17364788055419921, 0.984807789325714111, 120, 255, 1, "", 50664, NULL), +(3841, 178666, 0, 0, 0, 1, 1, -5157.3115234375, -606.39385986328125, 398.266204833984375, 1.762782454490661621, 0, 0, 0.771624565124511718, 0.636078238487243652, 120, 255, 1, "", 50664, NULL), +(3842, 179967, 0, 0, 0, 1, 1, -5133.91552734375, -587.81378173828125, 397.17620849609375, 3.316144466400146484, 0, 0, -0.99619388580322265, 0.087165042757987976, 120, 255, 1, "", 50664, NULL), +(3843, 179967, 0, 0, 0, 1, 1, -5134.89013671875, -586.86065673828125, 397.176177978515625, 2.338739633560180664, 0, 0, 0.920504570007324218, 0.3907318115234375, 120, 255, 1, "", 50664, NULL), +(3844, 179967, 0, 0, 0, 1, 1, -5142.607421875, -634.46307373046875, 397.176788330078125, 3.752462387084960937, 0, 0, -0.95371627807617187, 0.300707906484603881, 120, 255, 1, "", 50664, NULL), +(3845, 179967, 0, 0, 0, 1, 1, -5143.60009765625, -634.90350341796875, 397.17681884765625, 6.03883981704711914, 0, 0, -0.12186908721923828, 0.9925462007522583, 120, 255, 1, "", 50664, NULL), +(3846, 179967, 0, 0, 0, 1, 1, -5155.82666015625, -570.051025390625, 397.176177978515625, 1.797688722610473632, 0, 0, 0.7826080322265625, 0.622514784336090087, 120, 255, 1, "", 50664, NULL), +(3847, 179967, 0, 0, 0, 1, 1, -5173.16943359375, -624.42315673828125, 397.176177978515625, 2.879789113998413085, 0, 0, 0.991444587707519531, 0.130528271198272705, 120, 255, 1, "", 50664, NULL), +(3848, 179967, 0, 0, 0, 1, 1, -5174.89013671875, -623.0726318359375, 397.176177978515625, 3.176533222198486328, 0, 0, -0.999847412109375, 0.017469281330704689, 120, 255, 1, "", 50664, NULL), +(3849, 179968, 0, 0, 0, 1, 1, -5120.75048828125, -584.50518798828125, 397.176483154296875, 3.700104713439941406, 0, 0, -0.96126079559326171, 0.275640487670898437, 120, 255, 1, "", 50664, NULL), +(3850, 179968, 0, 0, 0, 1, 1, -5120.9609375, -583.06915283203125, 397.1778564453125, 1.535889506340026855, 0, 0, 0.694658279418945312, 0.719339847564697265, 120, 255, 1, "", 50664, NULL), +(3851, 179968, 0, 0, 0, 1, 1, -5121.9892578125, -585.78521728515625, 397.176239013671875, 2.042035102844238281, 0, 0, 0.852640151977539062, 0.522498607635498046, 120, 255, 1, "", 50664, NULL), +(3852, 179968, 0, 0, 0, 1, 1, -5122.4853515625, -584.760498046875, 397.176300048828125, 5.637413978576660156, 0, 0, -0.31730461120605468, 0.948323667049407958, 120, 255, 1, "", 50664, NULL), +(3853, 179968, 0, 0, 0, 1, 1, -5142.66015625, -635.97698974609375, 397.176361083984375, 0.104719325900077819, 0, 0, 0.052335739135742187, 0.998629570007324218, 120, 255, 1, "", 50664, NULL), +(3854, 179968, 0, 0, 0, 1, 1, -5178.49462890625, -550.72784423828125, 397.176177978515625, 1.204277276992797851, 0, 0, 0.56640625, 0.824126183986663818, 120, 255, 1, "", 50664, NULL), +(3855, 179968, 0, 0, 0, 1, 1, -5179.66259765625, -551.6282958984375, 397.176177978515625, 0.314158439636230468, 0, 0, 0.156434059143066406, 0.987688362598419189, 120, 255, 1, "", 50664, NULL), +(3856, 179969, 0, 0, 0, 1, 1, -5140.39306640625, -633.5538330078125, 397.17694091796875, 6.178466320037841796, 0, 0, -0.05233573913574218, 0.998629570007324218, 120, 255, 1, "", 50664, NULL), +(3857, 179969, 0, 0, 0, 1, 1, -5141.8134765625, -633.63275146484375, 397.177215576171875, 4.345870018005371093, 0, 0, -0.82412624359130859, 0.566406130790710449, 120, 255, 1, "", 50664, NULL), +(3858, 179969, 0, 0, 0, 1, 1, -5143.55615234375, -633.49005126953125, 397.178802490234375, 0.959929943084716796, 0, 0, 0.461748123168945312, 0.887011110782623291, 120, 255, 1, "", 50664, NULL), +(3859, 179969, 0, 0, 0, 1, 1, -5154.8193359375, -570.8985595703125, 397.176177978515625, 5.462882041931152343, 0, 0, -0.39874839782714843, 0.917060375213623046, 120, 255, 1, "", 50664, NULL), +(3860, 179969, 0, 0, 0, 1, 1, -5174.712890625, -621.16571044921875, 397.176177978515625, 1.972219824790954589, 0, 0, 0.83388519287109375, 0.55193793773651123, 120, 255, 1, "", 50664, NULL), +(3861, 179970, 0, 0, 0, 1, 1, -5125.87841796875, -609.6966552734375, 397.693511962890625, 5.201082706451416015, 0, 0, -0.51503753662109375, 0.857167601585388183, 120, 255, 1, "", 50664, NULL), +(3862, 179970, 0, 0, 0, 1, 1, -5141.72705078125, -634.87603759765625, 397.176910400390625, 5.84685373306274414, 0, 0, -0.21643924713134765, 0.976296067237854003, 120, 255, 1, "", 50664, NULL), +(3863, 179970, 0, 0, 0, 1, 1, -5158.0869140625, -568.03106689453125, 397.176177978515625, 1.378809213638305664, 0, 0, 0.636077880859375, 0.771624863147735595, 120, 255, 1, "", 50664, NULL), +(3864, 179970, 0, 0, 0, 1, 1, -5176.87353515625, -621.46600341796875, 397.176177978515625, 2.234017848968505859, 0, 0, 0.898793220520019531, 0.438372820615768432, 120, 255, 1, "", 50664, NULL), +(3865, 179970, 0, 0, 0, 1, 1, -5177.6591796875, -553.73699951171875, 397.176177978515625, 2.600535154342651367, 0, 0, 0.963629722595214843, 0.26724100112915039, 120, 255, 1, "", 50664, NULL), +(3866, 179970, 0, 0, 0, 1, 1, -5178.232421875, -552.29864501953125, 397.176177978515625, 3.054326534271240234, 0, 0, 0.999048233032226562, 0.043619260191917419, 120, 255, 1, "", 50664, NULL), +(3867, 179972, 0, 0, 0, 1, 1, -5124.74853515625, -611.6973876953125, 397.917449951171875, 1.448621988296508789, 0, 0, 0.662619590759277343, 0.748956084251403808, 120, 255, 1, "", 50664, NULL), +(3868, 179972, 0, 0, 0, 1, 1, -5132.57470703125, -587.78375244140625, 397.176177978515625, 4.607671737670898437, 0, 0, -0.74314403533935546, 0.669131457805633544, 120, 255, 1, "", 50664, NULL), +(3869, 179972, 0, 0, 0, 1, 1, -5132.58203125, -589.85333251953125, 397.176483154296875, 2.268925428390502929, 0, 0, 0.906307220458984375, 0.422619491815567016, 120, 255, 1, "", 50664, NULL), +(3870, 179972, 0, 0, 0, 1, 1, -5151.576171875, -605.25885009765625, 398.4732666015625, 0.907570242881774902, 0, 0, 0.438370704650878906, 0.898794233798980712, 120, 255, 1, "", 50664, NULL), +(3871, 179972, 0, 0, 0, 1, 1, -5153.62646484375, -569.24737548828125, 397.176177978515625, 2.565631866455078125, 0, 0, 0.958819389343261718, 0.284016460180282592, 120, 255, 1, "", 50664, NULL), +(3872, 179972, 0, 0, 0, 1, 1, -5156.2060546875, -567.0211181640625, 397.176177978515625, 2.426007747650146484, 0, 0, 0.936672210693359375, 0.350207358598709106, 120, 255, 1, "", 50664, NULL), +(3873, 179973, 0, 0, 0, 1, 1, -5134.728515625, -589.3590087890625, 397.176361083984375, 5.096362113952636718, 0, 0, -0.55919265747070312, 0.829037725925445556, 120, 255, 1, "", 50664, NULL), +(3874, 179973, 0, 0, 0, 1, 1, -5136.21484375, -588.2298583984375, 397.17620849609375, 1.815141916275024414, 0, 0, 0.788010597229003906, 0.615661680698394775, 120, 255, 1, "", 50664, NULL), +(3875, 179973, 0, 0, 0, 1, 1, -5140.60693359375, -635.26824951171875, 397.176513671875, 3.22885894775390625, 0, 0, -0.99904823303222656, 0.043619260191917419, 120, 255, 1, "", 50664, NULL), +(3876, 179973, 0, 0, 0, 1, 1, -5156.21142578125, -568.6014404296875, 397.17620849609375, 5.288348197937011718, 0, 0, -0.4771585464477539, 0.878817260265350341, 120, 255, 1, "", 50664, NULL), +(3877, 179973, 0, 0, 0, 1, 1, -5176.5712890625, -622.89501953125, 397.176177978515625, 3.124123096466064453, 0, 0, 0.99996185302734375, 0.008734640665352344, 120, 255, 1, "", 50664, NULL), +(3878, 179973, 0, 0, 0, 1, 1, -5201.66552734375, -469.016326904296875, 387.968597412109375, 3.508116960525512695, 0, 0, -0.98325443267822265, 0.182238012552261352, 120, 255, 1, "", 50664, NULL), +(3879, 179977, 0, 0, 0, 1, 1, -5179.45166015625, -561.93939208984375, 397.176177978515625, 4.415683269500732421, 0, 0, -0.80385684967041015, 0.594822824001312255, 120, 255, 1, "", 50664, NULL), +(3880, 179977, 0, 0, 0, 1, 1, -5195.63720703125, -489.8575439453125, 387.941253662109375, 3.036838293075561523, 0, 0, 0.998628616333007812, 0.052353221923112869, 120, 255, 1, "", 50664, NULL), +(3881, 179977, 0, 0, 0, 1, 1, -5201.69384765625, -469.09625244140625, 389.598114013671875, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 50664, NULL), +(3882, 180007, 0, 0, 0, 1, 1, -5129.5732421875, -617.77410888671875, 397.31353759765625, 4.747295856475830078, 0, 0, -0.69465827941894531, 0.719339847564697265, 120, 255, 1, "", 50664, NULL), +(3883, 180007, 0, 0, 0, 1, 1, -5177.41357421875, -564.8096923828125, 397.176177978515625, 2.111847877502441406, 0, 0, 0.870355606079101562, 0.492423713207244873, 120, 255, 1, "", 50664, NULL), +(3884, 180007, 0, 0, 0, 1, 1, -5186.525390625, -535.409423828125, 396.412017822265625, 5.864306926727294921, 0, 0, -0.20791149139404296, 0.978147625923156738, 120, 255, 1, "", 50664, NULL), +(3885, 180007, 0, 0, 0, 1, 1, -5195.3046875, -487.257537841796875, 387.869720458984375, 2.426007747650146484, 0, 0, 0.936672210693359375, 0.350207358598709106, 120, 255, 1, "", 50664, NULL), +(3886, 180007, 0, 0, 0, 1, 1, -5207.337890625, -549.64825439453125, 396.968597412109375, 3.071766138076782226, 0, 0, 0.999390602111816406, 0.034906134009361267, 120, 255, 1, "", 50664, NULL), +(3887, 180007, 0, 0, 0, 1, 1, -5210.072265625, -464.1983642578125, 387.626556396484375, 2.967041015625, 0, 0, 0.996193885803222656, 0.087165042757987976, 120, 255, 1, "", 50664, NULL), +(3888, 180007, 0, 0, 0, 1, 1, -5212.25732421875, -503.5504150390625, 388.158538818359375, 2.076939344406127929, 0, 0, 0.861628532409667968, 0.50753939151763916, 120, 255, 1, "", 50664, NULL), +(3889, 180007, 0, 0, 0, 1, 1, -5221.97021484375, -479.5455322265625, 386.895782470703125, 5.253442287445068359, 0, 0, -0.49242305755615234, 0.870355963706970214, 120, 255, 1, "", 50664, NULL), +(3890, 180046, 0, 0, 0, 1, 1, -5145.6220703125, -608.96112060546875, 398.486663818359375, 5.637413978576660156, 0, 0, -0.31730461120605468, 0.948323667049407958, 120, 255, 1, "", 50664, NULL), +(3891, 180046, 0, 0, 0, 1, 1, -5151.392578125, -596.8116455078125, 397.889984130859375, 1.117009282112121582, 0, 0, 0.529918670654296875, 0.84804844856262207, 120, 255, 1, "", 50664, NULL), +(3892, 180046, 0, 0, 0, 1, 1, -5160.09716796875, -607.23974609375, 398.097991943359375, 3.52557229995727539, 0, 0, -0.98162651062011718, 0.190812408924102783, 120, 255, 1, "", 50664, NULL), +(3893, 180046, 0, 0, 0, 1, 1, -5201.51318359375, -470.827362060546875, 388.036285400390625, 3.368495941162109375, 0, 0, -0.99357128143310546, 0.113208353519439697, 120, 255, 1, "", 50664, NULL), +(3894, 180047, 0, 0, 0, 1, 1, -5153.1015625, -604.0982666015625, 398.367340087890625, 5.497788906097412109, 0, 0, -0.38268280029296875, 0.923879802227020263, 120, 255, 1, "", 50664, NULL), +(3895, 180047, 0, 0, 0, 1, 1, -5200.54833984375, -472.899200439453125, 388.347930908203125, 0.052358884364366531, 0, 0, 0.02617645263671875, 0.999657332897186279, 120, 255, 1, "", 50664, NULL), +(3896, 180353, 0, 0, 0, 1, 1, -5152.06884765625, -622.81329345703125, 397.71875, 4.014260292053222656, 0, 0, -0.90630722045898437, 0.422619491815567016, 120, 255, 1, "", 50664, NULL), +(3897, 180353, 0, 0, 0, 1, 1, -5152.96337890625, -579.05950927734375, 397.17913818359375, 0.226892471313476562, 0, 0, 0.113203048706054687, 0.993571877479553222, 120, 255, 1, "", 50664, NULL), +(3898, 180353, 0, 0, 0, 1, 1, -5178.13134765625, -599.3812255859375, 397.375885009765625, 0.314158439636230468, 0, 0, 0.156434059143066406, 0.987688362598419189, 120, 255, 1, "", 50664, NULL), +(3899, 180353, 0, 0, 0, 1, 1, -5206.9130859375, -449.5999755859375, 386.780029296875, 2.879789113998413085, 0, 0, 0.991444587707519531, 0.130528271198272705, 120, 255, 1, "", 50664, NULL), +(3900, 180353, 0, 0, 0, 1, 1, -5211.6123046875, -462.171875, 386.502197265625, 0.890116631984710693, 0, 0, 0.430510520935058593, 0.902585566043853759, 120, 255, 1, "", 50664, NULL), +(3901, 180353, 0, 0, 0, 1, 1, -5228.52685546875, -479.38525390625, 386.44793701171875, 4.59021615982055664, 0, 0, -0.74895572662353515, 0.662620067596435546, 120, 255, 1, "", 50664, NULL), +(3902, 180353, 0, 0, 0, 1, 1, -5232.2861328125, -481.43212890625, 386.35211181640625, 5.969027042388916015, 0, 0, -0.1564340591430664, 0.987688362598419189, 120, 255, 1, "", 50664, NULL), +(3903, 186683, 0, 0, 0, 1, 1, -5165.91259765625, -549.84429931640625, 397.176177978515625, 2.914689540863037109, 0, 0, 0.993571281433105468, 0.113208353519439697, 120, 255, 1, "", 50664, NULL); + +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 70) AND (`guid` IN (3839, 3840, 3841, 3842, 3843, 3844, 3845, 3846, 3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856, 3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, 3871, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890, 3891, 3892, 3893, 3894, 3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903)); +INSERT INTO `game_event_gameobject` (`eventEntry`,`guid`) VALUES +(70, 3839), +(70, 3840), +(70, 3841), +(70, 3842), +(70, 3843), +(70, 3844), +(70, 3845), +(70, 3846), +(70, 3847), +(70, 3848), +(70, 3849), +(70, 3850), +(70, 3851), +(70, 3852), +(70, 3853), +(70, 3854), +(70, 3855), +(70, 3856), +(70, 3857), +(70, 3858), +(70, 3859), +(70, 3860), +(70, 3861), +(70, 3862), +(70, 3863), +(70, 3864), +(70, 3865), +(70, 3866), +(70, 3867), +(70, 3868), +(70, 3869), +(70, 3870), +(70, 3871), +(70, 3872), +(70, 3873), +(70, 3874), +(70, 3875), +(70, 3876), +(70, 3877), +(70, 3878), +(70, 3879), +(70, 3880), +(70, 3881), +(70, 3882), +(70, 3883), +(70, 3884), +(70, 3885), +(70, 3886), +(70, 3887), +(70, 3888), +(70, 3889), +(70, 3890), +(70, 3891), +(70, 3892), +(70, 3893), +(70, 3894), +(70, 3895), +(70, 3896), +(70, 3897), +(70, 3898), +(70, 3899), +(70, 3900), +(70, 3901), +(70, 3902), +(70, 3903); + +-- Update creature 'Brewfest Building (Ironforge)' with sniffed values +-- new spawns +DELETE FROM `creature` WHERE (`id1` IN (23504)) AND (`guid` IN (12820, 12821, 12822, 12823, 12824, 12825, 12826, 12827, 12828)); +INSERT INTO `creature` (`guid`, `id1`, `map`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(12820, 23504, 0, 1, 1, 1, -5130.50634765625, -619.58343505859375, 397.336334228515625, 1.448623299598693847, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL), +(12821, 23504, 0, 1, 1, 0, -5169.5498046875, -561.426513671875, 397.289520263671875, 2.513752937316894531, 120, 0, 0, 0, 0, 0, "", 50664, 1, "GUID SAI"), +(12822, 23504, 0, 1, 1, 0, -5172.8818359375, -622.4075927734375, 397.301177978515625, 3.694555997848510742, 120, 0, 0, 0, 0, 0, "", 50664, 1, "GUID SAI"), +(12823, 23504, 0, 1, 1, 1, -5178.921875, -565.07354736328125, 397.259521484375, 0.349065840244293212, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL), +(12824, 23504, 0, 1, 1, 1, -5186.578125, -533.9503173828125, 396.050445556640625, 5.044001579284667968, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL), +(12825, 23504, 0, 1, 1, 1, -5197.08056640625, -487.789215087890625, 388.21221923828125, 0.226892799139022827, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL), +(12826, 23504, 0, 1, 1, 1, -5206.8115234375, -550.51776123046875, 397.272247314453125, 2.146754980087280273, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL), +(12827, 23504, 0, 1, 1, 1, -5211.03173828125, -503.261444091796875, 388.160888671875, 3.351032257080078125, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL), +(12828, 23504, 0, 1, 1, 1, -5221.11572265625, -478.54193115234375, 386.972564697265625, 4.076367378234863281, 120, 0, 0, 0, 0, 0, "", 50664, 1, "GUID SAI"); + +DELETE FROM `game_event_creature` WHERE (`eventEntry` = 70) AND (`guid` IN (12820, 12821, 12822, 12823, 12824, 12825, 12826, 12827, 12828)); +INSERT INTO `game_event_creature` (`eventEntry`,`guid`) VALUES +(70, 12820), +(70, 12821), +(70, 12822), +(70, 12823), +(70, 12824), +(70, 12825), +(70, 12826), +(70, 12827), +(70, 12828); + +-- update auras +DELETE FROM `creature_addon` WHERE (`guid` IN (12820, 12821, 12822, 12823, 12824, 12825, 12826, 12827, 12828)); +INSERT INTO `creature_addon` (`guid`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(12820, 0, 0, 0, 0, 233, 0, '44372'), +(12821, 0, 0, 0, 0, 432, 0, '44372'), +(12822, 0, 0, 0, 0, 432, 0, '44372'), +(12823, 0, 0, 0, 0, 233, 0, '44372'), +(12824, 0, 0, 0, 0, 233, 0, '44372'), +(12825, 0, 0, 0, 0, 233, 0, '44372'), +(12826, 0, 0, 0, 0, 233, 0, '44372'), +(12827, 0, 0, 0, 0, 233, 0, '44372'), +(12828, 0, 0, 0, 0, 233, 0, '44372'); + +-- update equipment +DELETE FROM `creature_equip_template` WHERE `CreatureID` = 23504; +INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES +(23504, 1, 5292, 0, 0, 50664); + +SET @NPC := 12828; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `wander_distance`=0,`MovementType`=2 WHERE `guid`=@NPC; +UPDATE `creature_addon` SET `path_id` = @PATH, `emote` = 0 WHERE `guid` = @NPC; +DELETE FROM `waypoint_data` WHERE `id`=@PATH; +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH,1,-5221.1157,-478.54193,386.97256,NULL,0,0,0,100,0), +(@PATH,2,-5221.1157,-478.54193,386.97256,NULL,25000,0,0,100,0), +(@PATH,3,-5221.1157,-478.54193,386.97256,NULL,0,0,0,100,0), +(@PATH,4,-5210.8853,-465.23352,387.57217,NULL,25000,0,0,100,0), +(@PATH,5,-5210.8853,-465.23352,387.57217,NULL,0,0,0,100,0), +(@PATH,6,-5216.8687,-472.79004,386.83,NULL,0,0,0,100,0); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -12828); +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 +(-12828, 0, 1000, 0, 108, 0, 100, 0, 2, 0, 0, 0, 0, 0, 17, 234, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 2 of Path Any Reached - Set Emote State 234'), +(-12828, 0, 1001, 0, 108, 0, 100, 0, 3, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 3 of Path Any Reached - Set Emote State 0'), +(-12828, 0, 1002, 0, 108, 0, 100, 0, 4, 0, 0, 0, 0, 0, 17, 234, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 4 of Path Any Reached - Set Emote State 234'), +(-12828, 0, 1003, 0, 108, 0, 100, 0, 5, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 5 of Path Any Reached - Set Emote State 0'); + +SET @NPC := 12821; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `wander_distance`=0,`MovementType`=2,`position_x`=-5179.5845,`position_y`=-554.1431,`position_z`=397.27936 WHERE `guid`=@NPC; +UPDATE `creature_addon` SET `path_id` = @PATH, `emote` = 0 WHERE `guid` = @NPC; +DELETE FROM `waypoint_data` WHERE `id`=@PATH; +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH,1 ,-5179.5845,-554.1431,397.27936,NULL,0,0,0,100,0), +(@PATH,2 ,-5179.5845,-554.1431,397.27936,1.186823844909667968,20000,0,0,100,0), +(@PATH,3 ,-5179.5845,-554.1431,397.27936,0,0,0,0,100,0), +(@PATH,4 ,-5174.075,-559.6432,397.27936,NULL,0,0,0,100,0), +(@PATH,5 ,-5164.4526,-578.34515,397.30118,NULL,0,0,0,100,0), +(@PATH,6 ,-5152.449,-586.9136,397.4418,NULL,0,0,0,100,0), +(@PATH,7 ,-5136.8228,-594.1225,397.30118,NULL,0,0,0,100,0), +(@PATH,8 ,-5127.86,-593.34924,397.30118,NULL,0,0,0,100,0), +(@PATH,9 ,-5126.536,-586.53815,397.30118,NULL,0,0,0,100,0), +(@PATH,10,-5130.469,-588.1358,397.30118,NULL,20000,0,0,100,0), +(@PATH,11,-5130.469,-588.1358,397.30118,NULL,0,0,0,100,0), +(@PATH,12,-5131.538,-596.21716,397.30118,NULL,0,0,0,100,0), +(@PATH,13,-5152.9185,-587.6705,397.30118,NULL,0,0,0,100,0), +(@PATH,14,-5161.316,-577.31525,397.30118,NULL,0,0,0,100,0), +(@PATH,15,-5161.492,-570.673,397.30118,NULL,0,0,0,100,0), +(@PATH,16,-5158.0684,-569.75946,397.30118,NULL,0,0,0,100,0); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -12821); +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 +(-12821, 0, 1000, 0, 108, 0, 100, 0, 2, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 2 of Path Any Reached - Set Emote State 133'), +(-12821, 0, 1001, 0, 108, 0, 100, 0, 3, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 3 of Path Any Reached - Set Emote State 0'), +(-12821, 0, 1002, 0, 108, 0, 100, 0, 10, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 10 of Path Any Reached - Set Emote State 133'), +(-12821, 0, 1003, 0, 108, 0, 100, 0, 11, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 11 of Path Any Reached - Set Emote State 0'); + +SET @NPC := 12822; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `wander_distance`=0,`MovementType`=2,`position_x`=-5172.882,`position_y`=-622.4076,`position_z`=397.30118 WHERE `guid`=@NPC; +UPDATE `creature_addon` SET `path_id` = @PATH, `emote` = 0 WHERE `guid` = @NPC; +DELETE FROM `waypoint_data` WHERE `id`=@PATH; +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH,1 ,-5172.882,-622.4076,397.30118,NULL,10000,0,0,100,0), +(@PATH,2 ,-5172.882,-622.4076,397.30118,NULL,0,0,0,100,0), +(@PATH,3 ,-5153.764,-618.47894,398.19446,NULL,0,0,0,100,0), +(@PATH,4 ,-5143.7505,-617.6986,398.0995,NULL,0,0,0,100,0), +(@PATH,5 ,-5141.4756,-614.8408,398.0995,NULL,0,0,0,100,0), +(@PATH,6 ,-5135.3057,-591.59015,397.30118,NULL,15000,0,0,100,0), +(@PATH,7 ,-5135.3057,-591.59015,397.30118,NULL,0,0,0,100,0), +(@PATH,8 ,-5142.6113,-632.1305,397.2245,NULL,60000,0,0,100,0), +(@PATH,9 ,-5142.6113,-632.1305,397.2245,NULL,0,0,0,100,0), +(@PATH,10,-5149.8955,-618.4285,398.20056,NULL,0,0,0,100,0), +(@PATH,11,-5167.732,-619.2291,397.3063,NULL,0,0,0,100,0); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -12822); +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 +(-12822, 0, 1000, 0, 108, 0, 100, 0, 1, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 1 of Path Any Reached - Set Emote State 133'), +(-12822, 0, 1001, 0, 108, 0, 100, 0, 2, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 2 of Path Any Reached - Set Emote State 0'), +(-12822, 0, 1002, 0, 108, 0, 100, 0, 6, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 6 of Path Any Reached - Set Emote State 133'), +(-12822, 0, 1003, 0, 108, 0, 100, 0, 7, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 7 of Path Any Reached - Set Emote State 0'), +(-12822, 0, 1004, 0, 108, 0, 100, 0, 8, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 8 of Path Any Reached - Set Emote State 133'), +(-12822, 0, 1005, 0, 108, 0, 100, 0, 9, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 9 of Path Any Reached - Set Emote State 0'); + +-- creature texts +DELETE FROM `creature_text` WHERE (`CreatureID` = 23504) AND (`GroupID` = 0) AND (`ID` IN (0, 1, 2, 3, 4)); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23504, 0, 0, 'Brewfest is almost here!', 12, 0, 100.0, 0, 0, 0, 21966, 0, 'Brewfest Setup Crew'), +(23504, 0, 1, 'Can\'t you see I\'ve got work to do here?', 12, 0, 100.0, 0, 0, 0, 21967, 0, 'Brewfest Setup Crew'), +(23504, 0, 2, 'Won\'t be long now until the Brewfest starts! Come back later and check to see if we\'re done.', 12, 0, 100.0, 0, 0, 0, 21968, 0, 'Brewfest Setup Crew'), +(23504, 0, 3, 'I can\'t wait until we\'re done setting up. Then I can kick back and enjoy the festivities.', 12, 0, 100.0, 0, 0, 0, 21969, 0, 'Brewfest Setup Crew'), +(23504, 0, 4, 'Brewfest is a non-stop party. Setting up for it, though, is non-stop work!', 12, 0, 100.0, 0, 0, 0, 21970, 0, 'Brewfest Setup Crew'); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23504; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23504); +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 +(23504, 0, 0, 0, 101, 0, 100, 0, 1, 14, 0, 6000, 36000, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On 1 or More Players in Range - Say Line 0'); From 8161ef90b4f9a7035e8e96f6ceb8312dee7e0f47 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 31 Jan 2026 20:37:20 +0000 Subject: [PATCH 008/335] chore(DB): import pending files Referenced commit(s): a151c9a8941d63be725f856828a0a83ceae7fd12 --- .../rev_1769462581164552400.sql => db_world/2026_01_31_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1769462581164552400.sql => db_world/2026_01_31_02.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1769462581164552400.sql b/data/sql/updates/db_world/2026_01_31_02.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1769462581164552400.sql rename to data/sql/updates/db_world/2026_01_31_02.sql index c686b416a..d0b61ec93 100644 --- a/data/sql/updates/pending_db_world/rev_1769462581164552400.sql +++ b/data/sql/updates/db_world/2026_01_31_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_01_31_01 -> 2026_01_31_02 -- update game event UPDATE `game_event` SET `description` = "Brewfest Building (Ironforge)" WHERE `eventEntry` = 70; From 2935ec6d7f2d076fd4e20d2df028e73c88ccbb88 Mon Sep 17 00:00:00 2001 From: sudlud Date: Sat, 31 Jan 2026 22:19:36 +0100 Subject: [PATCH 009/335] fix(DB/game_event): implement 'Brewfest Building (Orgrimmar)' (#24517) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Co-authored-by: Gultask <100873791+Gultask@users.noreply.github.com> --- .../rev_1769350900893801100.sql | 313 ++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1769350900893801100.sql diff --git a/data/sql/updates/pending_db_world/rev_1769350900893801100.sql b/data/sql/updates/pending_db_world/rev_1769350900893801100.sql new file mode 100644 index 000000000..ec74ea3a6 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769350900893801100.sql @@ -0,0 +1,313 @@ +-- add game event +DELETE FROM `game_event` WHERE `eventEntry` = 91; +INSERT INTO `game_event` (`eventEntry`, `start_time`, `end_time`, `occurence`, `length`, `holiday`, `holidayStage`, `description`, `world_event`, `announce`) VALUES +(91, NULL, NULL, 525600, 4320, 372, 1, 'Brewfest Building (Orgrimmar)', 0, 2); + +-- Update gameobject 'Brewfest Building (Orgrimmar)' with sniffed values +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (178666, 179967, 179968, 179969, 179970, 179972, 179973, 179977, 180007, 180026, 180046, 180047, 180052, 180353, 186217, 186683, 186717, 186737)) AND (`guid` IN (3763, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777, 3778, 3779, 3780, 3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, 3800, 3801, 3802, 3803, 3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835, 3836, 3837, 3838)); +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 +(3763, 178666, 1, 0, 0, 1, 1, 1202.3385009765625, -4316.4853515625, 21.29575347900390625, 5.602506637573242187, 0, 0, -0.33380699157714843, 0.942641437053680419, 120, 255, 1, "", 50664, NULL), +(3764, 178666, 1, 0, 0, 1, 1, 1206.2276611328125, -4298.7412109375, 21.19341850280761718, 3.281238555908203125, 0, 0, -0.99756336212158203, 0.069766148924827575, 120, 255, 1, "", 50664, NULL), +(3765, 178666, 1, 0, 0, 1, 1, 1218.361572265625, -4312.39990234375, 21.25751113891601562, 1.239183306694030761, 0, 0, 0.580702781677246093, 0.814115643501281738, 120, 255, 1, "", 50664, NULL), +(3766, 179967, 1, 0, 0, 1, 1, 1181.3587646484375, -4306.2392578125, 21.29250717163085937, 2.338739633560180664, 0, 0, 0.920504570007324218, 0.3907318115234375, 120, 255, 1, "", 50664, NULL), +(3767, 179967, 1, 0, 0, 1, 1, 1182.9071044921875, -4270.123046875, 21.1916351318359375, 3.176533222198486328, 0, 0, -0.999847412109375, 0.017469281330704689, 120, 255, 1, "", 50664, NULL), +(3768, 179967, 1, 0, 0, 1, 1, 1183.828125, -4268.48974609375, 21.1916351318359375, 3.316144466400146484, 0, 0, -0.99619388580322265, 0.087165042757987976, 120, 255, 1, "", 50664, NULL), +(3769, 179967, 1, 0, 0, 1, 1, 1184.5753173828125, -4308.984375, 21.27497291564941406, 6.03883981704711914, 0, 0, -0.12186908721923828, 0.9925462007522583, 120, 255, 1, "", 50664, NULL), +(3770, 179967, 1, 0, 0, 1, 1, 1226.517578125, -4288.00048828125, 21.19730567932128906, 2.879789113998413085, 0, 0, 0.991444587707519531, 0.130528271198272705, 120, 255, 1, "", 50664, NULL), +(3771, 179967, 1, 0, 0, 1, 1, 1228.411376953125, -4286.20263671875, 21.20341873168945312, 1.797688722610473632, 0, 0, 0.7826080322265625, 0.622514784336090087, 120, 255, 1, "", 50664, NULL), +(3772, 179967, 1, 0, 0, 1, 1, 1230.6875, -4287.712890625, 21.42551231384277343, 3.752462387084960937, 0, 0, -0.95371627807617187, 0.300707906484603881, 120, 255, 1, "", 50664, NULL), +(3773, 179968, 1, 0, 0, 1, 1, 1176.49658203125, -4354.158203125, 21.29612922668457031, 5.637413978576660156, 0, 0, -0.31730461120605468, 0.948323667049407958, 120, 255, 1, "", 50664, NULL), +(3774, 179968, 1, 0, 0, 1, 1, 1176.6446533203125, -4356.86376953125, 21.29608726501464843, 1.535889506340026855, 0, 0, 0.694658279418945312, 0.719339847564697265, 120, 255, 1, "", 50664, NULL), +(3775, 179968, 1, 0, 0, 1, 1, 1177.674072265625, -4360.3642578125, 21.29608726501464843, 3.700104713439941406, 0, 0, -0.96126079559326171, 0.275640487670898437, 120, 255, 1, "", 50664, NULL), +(3776, 179968, 1, 0, 0, 1, 1, 1178.9898681640625, -4304.6591796875, 21.27920722961425781, 0.104719325900077819, 0, 0, 0.052335739135742187, 0.998629570007324218, 120, 255, 1, "", 50664, NULL), +(3777, 179968, 1, 0, 0, 1, 1, 1249.4190673828125, -4282.4267578125, 24.33323478698730468, 2.042035102844238281, 0, 0, 0.852640151977539062, 0.522498607635498046, 120, 255, 1, "", 50664, NULL), +(3778, 179968, 1, 0, 0, 1, 1, 1258.6126708984375, -4282.35791015625, 24.33774757385253906, 1.204277276992797851, 0, 0, 0.56640625, 0.824126183986663818, 120, 255, 1, "", 50664, NULL), +(3779, 179968, 1, 0, 0, 1, 1, 1259.698486328125, -4279.69140625, 24.33773994445800781, 0.314158439636230468, 0, 0, 0.156434059143066406, 0.987688362598419189, 120, 255, 1, "", 50664, NULL), +(3780, 179969, 1, 0, 0, 1, 1, 1181.0904541015625, -4304.39013671875, 21.28094863891601562, 0.959929943084716796, 0, 0, 0.461748123168945312, 0.887011110782623291, 120, 255, 1, "", 50664, NULL), +(3781, 179969, 1, 0, 0, 1, 1, 1181.6207275390625, -4273.7109375, 21.19163703918457031, 6.178466320037841796, 0, 0, -0.05233573913574218, 0.998629570007324218, 120, 255, 1, "", 50664, NULL), +(3782, 179969, 1, 0, 0, 1, 1, 1186.4869384765625, -4269.5849609375, 21.1916351318359375, 4.345870018005371093, 0, 0, -0.82412624359130859, 0.566406130790710449, 120, 255, 1, "", 50664, NULL), +(3783, 179969, 1, 0, 0, 1, 1, 1202.6749267578125, -4274.52880859375, 21.19633865356445312, 1.972219824790954589, 0, 0, 0.83388519287109375, 0.55193793773651123, 120, 255, 1, "", 50664, NULL), +(3784, 179969, 1, 0, 0, 1, 1, 1233.4163818359375, -4296.3173828125, 21.59285545349121093, 5.462882041931152343, 0, 0, -0.39874839782714843, 0.917060375213623046, 120, 255, 1, "", 50664, NULL), +(3785, 179970, 1, 0, 0, 1, 1, 1180.06640625, -4306.89892578125, 21.29009628295898437, 3.054326534271240234, 0, 0, 0.999048233032226562, 0.043619260191917419, 120, 255, 1, "", 50664, NULL), +(3786, 179970, 1, 0, 0, 1, 1, 1183.764404296875, -4308.08447265625, 21.26527976989746093, 1.378809213638305664, 0, 0, 0.636077880859375, 0.771624863147735595, 120, 255, 1, "", 50664, NULL), +(3787, 179970, 1, 0, 0, 1, 1, 1202.457275390625, -4344.73681640625, 21.29608535766601562, 2.600535154342651367, 0, 0, 0.963629722595214843, 0.26724100112915039, 120, 255, 1, "", 50664, NULL), +(3788, 179970, 1, 0, 0, 1, 1, 1203.825927734375, -4347.09130859375, 21.29608535766601562, 5.84685373306274414, 0, 0, -0.21643924713134765, 0.976296067237854003, 120, 255, 1, "", 50664, NULL), +(3789, 179970, 1, 0, 0, 1, 1, 1204.73291015625, -4273.06103515625, 21.19443893432617187, 2.234017848968505859, 0, 0, 0.898793220520019531, 0.438372820615768432, 120, 255, 1, "", 50664, NULL), +(3790, 179970, 1, 0, 0, 1, 1, 1232.15185546875, -4295.35498046875, 21.5887298583984375, 5.201082706451416015, 0, 0, -0.51503753662109375, 0.857167601585388183, 120, 255, 1, "", 50664, NULL), +(3791, 179972, 1, 0, 0, 1, 1, 1179.7274169921875, -4356.68798828125, 21.29611015319824218, 2.268925428390502929, 0, 0, 0.906307220458984375, 0.422619491815567016, 120, 255, 1, "", 50664, NULL), +(3792, 179972, 1, 0, 0, 1, 1, 1181.4752197265625, -4308.53759765625, 21.27838134765625, 4.607671737670898437, 0, 0, -0.74314403533935546, 0.669131457805633544, 120, 255, 1, "", 50664, NULL), +(3793, 179972, 1, 0, 0, 1, 1, 1200.46044921875, -4275.783203125, 21.19213485717773437, 2.565631866455078125, 0, 0, 0.958819389343261718, 0.284016460180282592, 120, 255, 1, "", 50664, NULL), +(3794, 179972, 1, 0, 0, 1, 1, 1202.5386962890625, -4341.82373046875, 21.29608535766601562, 1.448621988296508789, 0, 0, 0.662619590759277343, 0.748956084251403808, 120, 255, 1, "", 50664, NULL), +(3795, 179972, 1, 0, 0, 1, 1, 1226.129150390625, -4284.15185546875, 21.19164466857910156, 2.426007747650146484, 0, 0, 0.936672210693359375, 0.350207358598709106, 120, 255, 1, "", 50664, NULL), +(3796, 179972, 1, 0, 0, 1, 1, 1236.142822265625, -4297.2216796875, 21.42418479919433593, 0.907570242881774902, 0, 0, 0.438370704650878906, 0.898794233798980712, 120, 255, 1, "", 50664, NULL), +(3797, 179973, 1, 0, 0, 1, 1, 1183.474365234375, -4306.56103515625, 21.27122688293457031, 3.22885894775390625, 0, 0, -0.99904823303222656, 0.043619260191917419, 120, 255, 1, "", 50664, NULL), +(3798, 179973, 1, 0, 0, 1, 1, 1200.45068359375, -4273.451171875, 21.2135467529296875, 5.096362113952636718, 0, 0, -0.55919265747070312, 0.829037725925445556, 120, 255, 1, "", 50664, NULL), +(3799, 179973, 1, 0, 0, 1, 1, 1203.6002197265625, -4271.92041015625, 21.20084762573242187, 3.508116960525512695, 0, 0, -0.98325443267822265, 0.182238012552261352, 120, 255, 1, "", 50664, NULL), +(3800, 179973, 1, 0, 0, 1, 1, 1204.311767578125, -4344.8759765625, 21.29608726501464843, 3.124123096466064453, 0, 0, 0.99996185302734375, 0.008734640665352344, 120, 255, 1, "", 50664, NULL), +(3801, 179973, 1, 0, 0, 1, 1, 1224.6070556640625, -4286.3173828125, 21.19164466857910156, 5.288348197937011718, 0, 0, -0.4771585464477539, 0.878817260265350341, 120, 255, 1, "", 50664, NULL), +(3802, 179973, 1, 0, 0, 1, 1, 1234.0435791015625, -4294.390625, 21.73000335693359375, 1.815141916275024414, 0, 0, 0.788010597229003906, 0.615661680698394775, 120, 255, 1, "", 50664, NULL), +(3803, 179977, 1, 0, 0, 1, 1, 1185.3365478515625, -4307.01416015625, 21.25037002563476562, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 50664, NULL), +(3804, 179977, 1, 0, 0, 1, 1, 1192.3175048828125, -4272.1376953125, 21.19159317016601562, 2.932138919830322265, 0, 0, 0.994521141052246093, 0.104535527527332305, 120, 255, 1, "", 50664, NULL), +(3805, 179977, 1, 0, 0, 1, 1, 1206.531982421875, -4343.76220703125, 21.29608535766601562, 6.056293010711669921, 0, 0, -0.11320304870605468, 0.993571877479553222, 120, 255, 1, "", 50664, NULL), +(3806, 180007, 1, 0, 0, 1, 1, 1176.6636962890625, -4256.9140625, 21.97882270812988281, 5.864306926727294921, 0, 0, -0.20791149139404296, 0.978147625923156738, 120, 255, 1, "", 50664, NULL), +(3807, 180007, 1, 0, 0, 1, 1, 1179.6297607421875, -4376.29150390625, 26.23531532287597656, 2.076939344406127929, 0, 0, 0.861628532409667968, 0.50753939151763916, 120, 255, 1, "", 50664, NULL), +(3808, 180007, 1, 0, 0, 1, 1, 1179.998291015625, -4283.64404296875, 21.14358901977539062, 5.253442287445068359, 0, 0, -0.49242305755615234, 0.870355963706970214, 120, 255, 1, "", 50664, NULL), +(3809, 180007, 1, 0, 0, 1, 1, 1183.0694580078125, -4333.74853515625, 21.24088096618652343, 4.747295856475830078, 0, 0, -0.69465827941894531, 0.719339847564697265, 120, 255, 1, "", 50664, NULL), +(3810, 180007, 1, 0, 0, 1, 1, 1191.7110595703125, -4381.18310546875, 23.86879730224609375, 2.967041015625, 0, 0, 0.996193885803222656, 0.087165042757987976, 120, 255, 1, "", 50664, NULL), +(3811, 180007, 1, 0, 0, 1, 1, 1210.21826171875, -4260.98681640625, 21.19163894653320312, 2.111847877502441406, 0, 0, 0.870355606079101562, 0.492423713207244873, 120, 255, 1, "", 50664, NULL), +(3812, 180007, 1, 0, 0, 1, 1, 1235.71533203125, -4307.68212890625, 21.12670326232910156, 2.426007747650146484, 0, 0, 0.936672210693359375, 0.350207358598709106, 120, 255, 1, "", 50664, NULL), +(3813, 180007, 1, 0, 0, 1, 1, 1260.8443603515625, -4376.15087890625, 28.54974746704101562, 3.071766138076782226, 0, 0, 0.999390602111816406, 0.034906134009361267, 120, 255, 1, "", 50664, NULL), +(3814, 180026, 1, 0, 0, 1, 1, 1179.9296875, -4392.0830078125, 22.49359703063964843, 2.687806606292724609, 0, 0, 0.974370002746582031, 0.224951311945915222, 120, 255, 1, "", 50664, NULL), +(3815, 180026, 1, 0, 0, 1, 1, 1245.5703125, -4391.6962890625, 28.22939872741699218, 3.298687219619750976, 0, 0, -0.99691677093505859, 0.078466430306434631, 120, 255, 1, "", 50664, NULL), +(3816, 180046, 1, 0, 0, 1, 1, 1179.8936767578125, -4315.935546875, 21.29486846923828125, 4.991643905639648437, 0, 0, -0.60181427001953125, 0.798636078834533691, 120, 255, 1, "", 50664, NULL), +(3817, 180046, 1, 0, 0, 1, 1, 1193.9249267578125, -4272.9072265625, 21.19159507751464843, 4.171337604522705078, 0, 0, -0.87035560607910156, 0.492423713207244873, 120, 255, 1, "", 50664, NULL), +(3818, 180046, 1, 0, 0, 1, 1, 1204.724853515625, -4313.37353515625, 21.28537750244140625, 0.750490784645080566, 0, 0, 0.3665008544921875, 0.93041771650314331, 120, 255, 1, "", 50664, NULL), +(3819, 180046, 1, 0, 0, 1, 1, 1206.8466796875, -4301.72998046875, 21.24626922607421875, 4.293513298034667968, 0, 0, -0.8386697769165039, 0.544640243053436279, 120, 255, 1, "", 50664, NULL), +(3820, 180047, 1, 0, 0, 1, 1, 1178.5738525390625, -4327.244140625, 21.29608726501464843, 3.78736734390258789, 0, 0, -0.94832324981689453, 0.317305892705917358, 120, 255, 1, "", 50664, NULL), +(3821, 180047, 1, 0, 0, 1, 1, 1204.7349853515625, -4301.52587890625, 21.23160934448242187, 5.148722648620605468, 0, 0, -0.53729915618896484, 0.843391716480255126, 120, 255, 1, "", 50664, NULL), +(3822, 180052, 1, 0, 0, 1, 1, 1182.305419921875, -4272.55908203125, 21.19163703918457031, 2.914689540863037109, 0, 0, 0.993571281433105468, 0.113208353519439697, 120, 255, 1, "", 50664, NULL), +(3823, 180353, 1, 0, 0, 1, 1, 1174.0538330078125, -4265.5224609375, 21.27764320373535156, 2.879789113998413085, 0, 0, 0.991444587707519531, 0.130528271198272705, 120, 255, 1, "", 50664, NULL), +(3824, 180353, 1, 0, 0, 1, 1, 1177.5828857421875, -4393.173828125, 22.46704292297363281, 0.226892471313476562, 0, 0, 0.113203048706054687, 0.993571877479553222, 120, 255, 1, "", 50664, NULL), +(3825, 180353, 1, 0, 0, 1, 1, 1179.5260009765625, -4326.048828125, 21.24143218994140625, 4.014260292053222656, 0, 0, -0.90630722045898437, 0.422619491815567016, 120, 255, 1, "", 50664, NULL), +(3826, 180353, 1, 0, 0, 1, 1, 1212.866943359375, -4260.33251953125, 21.30665397644042968, 4.59021615982055664, 0, 0, -0.74895572662353515, 0.662620067596435546, 120, 255, 1, "", 50664, NULL), +(3827, 180353, 1, 0, 0, 1, 1, 1224.5260009765625, -4349.67041015625, 21.22219657897949218, 5.969027042388916015, 0, 0, -0.1564340591430664, 0.987688362598419189, 120, 255, 1, "", 50664, NULL), +(3828, 180353, 1, 0, 0, 1, 1, 1236.6822509765625, -4301.87353515625, 21.16509056091308593, 4.258606910705566406, 0, 0, -0.84804725646972656, 0.529920578002929687, 120, 255, 1, "", 50664, NULL), +(3829, 180353, 1, 0, 0, 1, 1, 1246.6956787109375, -4390.35205078125, 28.30716514587402343, 5.288348197937011718, 0, 0, -0.4771585464477539, 0.878817260265350341, 120, 255, 1, "", 50664, NULL), +(3830, 186217, 1, 0, 0, 1, 1, 1179.482421875, -4391.8017578125, 22.47848320007324218, 4.956737518310546875, 0, 0, -0.61566066741943359, 0.788011372089385986, 120, 255, 1, "", 50664, NULL), +(3831, 186217, 1, 0, 0, 1, 1, 1245.63720703125, -4392.46826171875, 28.18994903564453125, 2.129300594329833984, 0, 0, 0.874619483947753906, 0.484810054302215576, 120, 255, 1, "", 50664, NULL), +(3832, 186683, 1, 0, 0, 1, 1, 1225.5863037109375, -4276.587890625, 21.19164466857910156, 5.148722648620605468, 0, 0, -0.53729915618896484, 0.843391716480255126, 120, 255, 1, "", 50664, NULL), +(3833, 186717, 1, 0, 0, 1, 1, 1182.5052490234375, -4391.01904296875, 22.70993804931640625, 4.904376029968261718, 0, 0, -0.636077880859375, 0.771624863147735595, 120, 255, 1, "", 50664, NULL), +(3834, 186717, 1, 0, 0, 1, 1, 1243.0361328125, -4392.20703125, 28.09830284118652343, 5.235987663269042968, 0, 0, -0.5, 0.866025388240814208, 120, 255, 1, "", 50664, NULL), +(3835, 186717, 1, 0, 0, 1, 1, 1302.564208984375, -4501.88916015625, 23.39440536499023437, 2.234017848968505859, 0, 0, 0.898793220520019531, 0.438372820615768432, 120, 255, 1, "", 50664, NULL), +(3836, 186717, 1, 0, 0, 1, 1, 1315.9405517578125, -4397.97119140625, 26.30713844299316406, 1.919861555099487304, 0, 0, 0.819151878356933593, 0.573576688766479492, 120, 255, 1, "", 50664, NULL), +(3837, 186737, 1, 0, 0, 1, 1, 1172.0546875, -4308.54443359375, 21.22587776184082031, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 50664, NULL), +(3838, 186737, 1, 0, 0, 1, 1, 1192.3134765625, -4266.04443359375, 21.19163703918457031, 1.151916384696960449, 0, 0, 0.544638633728027343, 0.838670849800109863, 120, 255, 1, "", 50664, NULL); + +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 91) AND (`guid` IN (3763, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777, 3778, 3779, 3780, 3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, 3800, 3801, 3802, 3803, 3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835, 3836, 3837, 3838)); +INSERT INTO `game_event_gameobject` (`eventEntry`,`guid`) VALUES +(91, 3763), +(91, 3764), +(91, 3765), +(91, 3766), +(91, 3767), +(91, 3768), +(91, 3769), +(91, 3770), +(91, 3771), +(91, 3772), +(91, 3773), +(91, 3774), +(91, 3775), +(91, 3776), +(91, 3777), +(91, 3778), +(91, 3779), +(91, 3780), +(91, 3781), +(91, 3782), +(91, 3783), +(91, 3784), +(91, 3785), +(91, 3786), +(91, 3787), +(91, 3788), +(91, 3789), +(91, 3790), +(91, 3791), +(91, 3792), +(91, 3793), +(91, 3794), +(91, 3795), +(91, 3796), +(91, 3797), +(91, 3798), +(91, 3799), +(91, 3800), +(91, 3801), +(91, 3802), +(91, 3803), +(91, 3804), +(91, 3805), +(91, 3806), +(91, 3807), +(91, 3808), +(91, 3809), +(91, 3810), +(91, 3811), +(91, 3812), +(91, 3813), +(91, 3814), +(91, 3815), +(91, 3816), +(91, 3817), +(91, 3818), +(91, 3819), +(91, 3820), +(91, 3821), +(91, 3822), +(91, 3823), +(91, 3824), +(91, 3825), +(91, 3826), +(91, 3827), +(91, 3828), +(91, 3829), +(91, 3830), +(91, 3831), +(91, 3832), +(91, 3833), +(91, 3834), +(91, 3835), +(91, 3836), +(91, 3837), +(91, 3838); + +-- despawn mobs in the area +DELETE FROM `game_event_creature` WHERE (`eventEntry` = -91) AND (`guid` IN (12372, 24976, 22473, 6507, 6509, 6510, 6511, 12369, 12379, 21020, 21022, 21024, 21026, 21034, 21036, 7369, 7370, 12386, 22181, 22188, 22451)); +INSERT INTO `game_event_creature` (`eventEntry`,`guid`) VALUES +-- Adder +(-91, 12372), +(-91, 24976), +-- Corrupted Bloodtalon Scythemaw +(-91, 22473), +-- Elder Mottled Boar +(-91, 6507), +(-91, 6509), +(-91, 6510), +(-91, 6511), +(-91, 12369), +(-91, 12379), +(-91, 21020), +(-91, 21022), +(-91, 21024), +(-91, 21026), +(-91, 21034), +(-91, 21036), +-- Venomtail Scorpid +(-91, 7369), +(-91, 7370), +(-91, 12386), +(-91, 22181), +(-91, 22188), +-- Corrupted Mottled Boar +(-91, 22451); + +-- Update creature 'Brewfest Building (Orgrimmar)' with sniffed values +-- new spawns +DELETE FROM `creature` WHERE (`id1` IN (23504)) AND (`guid` IN (12768, 12769, 12770, 12771, 12772, 12773, 12774, 12775, 12776)); +INSERT INTO `creature` (`guid`, `id1`, `map`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(12768, 23504, 1, 1, 1, 1, 1176.0369873046875, -4255.9814453125, 22.21631431579589843, 5.270894527435302734, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL), +(12769, 23504, 1, 1, 1, 1, 1179.4427490234375, -4284.61474609375, 21.28194046020507812, 1.029744267463684082, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL), +(12770, 23504, 1, 1, 1, 1, 1180.81787109375, -4376.79443359375, 26.24557113647460937, 2.832220315933227539, 120, 0, 0, 0, 0, 0, "", 50664, 1, "GUID SAI"), +(12771, 23504, 1, 1, 1, 0, 1181.4923095703125, -4355.63916015625, 21.42108535766601562, 4.023062705993652343, 120, 0, 0, 0, 0, 0, "", 50664, 1, "GUID SAI"), +(12772, 23504, 1, 1, 1, 1, 1182.0416259765625, -4332.8818359375, 21.37387275695800781, 5.759586334228515625, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL), +(12773, 23504, 1, 1, 1, 0, 1183.577880859375, -4304.1298828125, 21.31663703918457031, 4.184878826141357421, 120, 0, 0, 0, 0, 0, "", 50664, 1, "GUID SAI"), +(12774, 23504, 1, 1, 1, 1, 1209.23681640625, -4261.87890625, 21.27497291564941406, 0.92502450942993164, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL), +(12775, 23504, 1, 1, 1, 1, 1234.40283203125, -4307.765625, 21.25117683410644531, 6.143558979034423828, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL), +(12776, 23504, 1, 1, 1, 1, 1259.862548828125, -4377.77001953125, 28.61495018005371093, 1.047197580337524414, 120, 0, 0, 0, 0, 0, "", 50664, 1, NULL); + +DELETE FROM `game_event_creature` WHERE (`eventEntry` = 91) AND (`guid` IN (12768, 12769, 12770, 12771, 12772, 12773, 12774, 12775, 12776)); +INSERT INTO `game_event_creature` (`eventEntry`,`guid`) VALUES +(91, 12768), +(91, 12769), +(91, 12770), +(91, 12771), +(91, 12772), +(91, 12773), +(91, 12774), +(91, 12775), +(91, 12776); + +-- update auras +DELETE FROM `creature_addon` WHERE (`guid` IN (12768, 12769, 12770, 12771, 12772, 12773, 12774, 12775, 12776)); +INSERT INTO `creature_addon` (`guid`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(12768, 0, 0, 0, 0, 234, 0, '43992'), +(12769, 0, 0, 0, 0, 234, 0, '43992'), +(12770, 0, 0, 0, 0, 0, 0, '43992'), +(12771, 0, 0, 0, 0, 0, 0, '43992'), +(12772, 0, 0, 0, 0, 234, 0, '43992'), +(12773, 0, 0, 0, 0, 0, 0, '43992'), +(12774, 0, 0, 0, 0, 234, 0, '43992'), +(12775, 0, 0, 0, 0, 234, 0, '43992'), +(12776, 0, 0, 0, 0, 234, 0, '43992'); + +-- update equipment +DELETE FROM `creature_equip_template` WHERE `CreatureID` = 23504; +INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES +(23504, 1, 5292, 0, 0, 50664); + +-- Pathing for Entry: 23504 +SET @NPC := 12771; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `wander_distance`=0,`MovementType`=2 WHERE `guid`=@NPC; +UPDATE `creature_addon` SET `path_id` = @PATH WHERE `guid` = @NPC; +DELETE FROM `waypoint_data` WHERE `id`=@PATH; +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH,1 ,1220.4547,-4334.2886,21.31665,NULL,0,0,0,100,0), +(@PATH,2 ,1227.7362,-4310.514,21.316643,NULL,0,0,0,100,0), +(@PATH,3 ,1233.6675,-4298.053,21.441637,NULL,15000,0,0,100,0), +(@PATH,4 ,1233.6675,-4298.053,21.441637,NULL,0,0,0,100,0), +(@PATH,5 ,1224.0404,-4319.1245,21.316643,NULL,0,0,0,100,0), +(@PATH,6 ,1203.6339,-4335.0293,21.31665,NULL,0,0,0,100,0), +(@PATH,7 ,1191.6898,-4343.2666,21.421085,NULL,0,0,0,100,0), +(@PATH,8 ,1181.4923,-4355.639,21.421085,NULL,10000,0,0,100,0), +(@PATH,9 ,1181.4923,-4355.639,21.421085,NULL,0,0,0,100,0), +(@PATH,10,1204.1326,-4348.952,21.31665,NULL,0,0,0,100,0), +(@PATH,11,1204.1326,-4348.952,21.31665,1.762782573699951171,20000,0,0,100,0), +(@PATH,12,1204.1326,-4348.952,21.31665,1.762782573699951171,0,0,0,100,0); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -12771); +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 +(-12771, 0, 1000, 0, 108, 0, 100, 0, 3, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 3 of Path Any Reached - Set Emote State 133'), +(-12771, 0, 1001, 0, 108, 0, 100, 0, 4, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 4 of Path Any Reached - Set Emote State 0'), +(-12771, 0, 1002, 0, 108, 0, 100, 0, 8, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 8 of Path Any Reached - Set Emote State 133'), +(-12771, 0, 1003, 0, 108, 0, 100, 0, 9, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 9 of Path Any Reached - Set Emote State 0'), +(-12771, 0, 1004, 0, 108, 0, 100, 0, 11, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 11 of Path Any Reached - Set Emote State 133'), +(-12771, 0, 1005, 0, 108, 0, 100, 0, 12, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 12 of Path Any Reached - Set Emote State 0'); + +SET @NPC := 12773; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `wander_distance`=0,`MovementType`=2 WHERE `guid`=@NPC; +UPDATE `creature_addon` SET `path_id` = @PATH WHERE `guid` = @NPC; +DELETE FROM `waypoint_data` WHERE `id`=@PATH; +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH,1 ,1183.3735,-4283.522,21.270655,NULL,0,0,0,100,0), +(@PATH,2 ,1191.225,-4284.0986,21.270655,NULL,0,0,0,100,0), +(@PATH,3 ,1199.2571,-4277.2163,21.270655,NULL,15000,0,0,100,0), +(@PATH,4 ,1199.2571,-4277.2163,21.270655,NULL,0,0,0,100,0), +(@PATH,5 ,1183.5779,-4304.13,21.316637,NULL,20000,0,0,100,0), +(@PATH,6 ,1183.5779,-4304.13,21.316637,NULL,0,0,0,100,0), +(@PATH,7 ,1184.7842,-4284.5176,21.270655,NULL,0,0,0,100,0), +(@PATH,8 ,1179.4281,-4278.2236,21.270655,NULL,0,0,0,100,0), +(@PATH,9 ,1180.4791,-4275.776,21.270655,NULL,15000,0,0,100,0), +(@PATH,10,1180.4791,-4275.776,21.270655,NULL,0,0,0,100,0); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -12773); +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 +(-12773, 0, 1000, 0, 108, 0, 100, 0, 3, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 3 of Path Any Reached - Set Emote State 133'), +(-12773, 0, 1001, 0, 108, 0, 100, 0, 4, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 4 of Path Any Reached - Set Emote State 0'), +(-12773, 0, 1002, 0, 108, 0, 100, 0, 5, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 5 of Path Any Reached - Set Emote State 133'), +(-12773, 0, 1003, 0, 108, 0, 100, 0, 6, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 6 of Path Any Reached - Set Emote State 0'), +(-12773, 0, 1004, 0, 108, 0, 100, 0, 9, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 9 of Path Any Reached - Set Emote State 133'), +(-12773, 0, 1005, 0, 108, 0, 100, 0, 10, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 10 of Path Any Reached - Set Emote State 0'); + +SET @NPC := 12770; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `wander_distance`=0,`MovementType`=2 WHERE `guid`=@NPC; +UPDATE `creature_addon` SET `path_id` = @PATH WHERE `guid` = @NPC; +DELETE FROM `waypoint_data` WHERE `id`=@PATH; +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH,1,1193.0723,-4380.715,24.006937,NULL,30000,0,0,100,0), +(@PATH,2,1193.0723,-4380.715,24.006937,NULL,0,0,0,100,0), +(@PATH,3,1180.8179,-4376.7944,26.245571,NULL,30000,0,0,100,0), +(@PATH,4,1180.8179,-4376.7944,26.245571,NULL,0,0,0,100,0); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -12770); +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 +(-12770, 0, 1000, 1001, 108, 0, 100, 0, 1, 0, 0, 0, 0, 0, 17, 234, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 1 of Path Any Reached - Set Emote State 234'), +(-12770, 0, 1001, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 20, 180007, 10, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 1 of Path Any Reached - Set Orientation Closest Gameobject \'Excavation Stake\''), +(-12770, 0, 1002, 0, 108, 0, 100, 0, 2, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 2 of Path Any Reached - Set Emote State 0'), +(-12770, 0, 1003, 1004, 108, 0, 100, 0, 3, 0, 0, 0, 0, 0, 17, 234, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 3 of Path Any Reached - Set Emote State 234'), +(-12770, 0, 1004, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 20, 180007, 10, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 3 of Path Any Reached - Set Orientation Closest Gameobject \'Excavation Stake\''), +(-12770, 0, 1005, 0, 108, 0, 100, 0, 4, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brewfest Setup Crew - On Point 4 of Path Any Reached - Set Emote State 0'); From 621b2d26554fd31d8ec777edf8ab03211273a14b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 31 Jan 2026 21:20:42 +0000 Subject: [PATCH 010/335] chore(DB): import pending files Referenced commit(s): 2935ec6d7f2d076fd4e20d2df028e73c88ccbb88 --- .../rev_1769350900893801100.sql => db_world/2026_01_31_03.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1769350900893801100.sql => db_world/2026_01_31_03.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1769350900893801100.sql b/data/sql/updates/db_world/2026_01_31_03.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1769350900893801100.sql rename to data/sql/updates/db_world/2026_01_31_03.sql index ec74ea3a6..c7f749f9b 100644 --- a/data/sql/updates/pending_db_world/rev_1769350900893801100.sql +++ b/data/sql/updates/db_world/2026_01_31_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_01_31_02 -> 2026_01_31_03 -- add game event DELETE FROM `game_event` WHERE `eventEntry` = 91; INSERT INTO `game_event` (`eventEntry`, `start_time`, `end_time`, `occurence`, `length`, `holiday`, `holidayStage`, `description`, `world_event`, `announce`) VALUES From 154a4a076115acdae60447304d461a7ca6d95f68 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sat, 31 Jan 2026 20:12:37 -0300 Subject: [PATCH 011/335] fix(CI/Codestyle): Ignore backtick checks in comments (#24573) --- apps/codestyle/codestyle-sql.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/codestyle/codestyle-sql.py b/apps/codestyle/codestyle-sql.py index 9fad940e9..eb36033a1 100644 --- a/apps/codestyle/codestyle-sql.py +++ b/apps/codestyle/codestyle-sql.py @@ -191,7 +191,7 @@ def insert_delete_safety_check(file: io, file_path: str) -> None: # Parse all the file for line_number, line in enumerate(file, start = 1): - if line.startswith("--"): + if line.strip().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 notify a maintainer") @@ -323,11 +323,13 @@ def backtick_check(file: io, file_path: str) -> None: for line_number, line in enumerate(file, start=1): # Ignore comments - if line.startswith('--'): + if line.strip().startswith('--'): continue # Sanitize single- and doublequotes to prevent false positives sanitized_line = quote_pattern.sub('', line) + # Strip inline comments (safe to do after removing quoted strings) + sanitized_line = re.sub(r'--.*$', '', sanitized_line) matches = pattern.findall(sanitized_line) for clause, content in matches: From f27a1e2619df875bb47af24344016040b895882f Mon Sep 17 00:00:00 2001 From: sogladev Date: Sun, 1 Feb 2026 16:59:52 +0100 Subject: [PATCH 012/335] fix(Scripts/Naxxramas): Sapphiron flight phase animation (#24535) --- src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp index 50c51861e..c7407f554 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp @@ -128,6 +128,7 @@ public: spawnTimer = 0; currentTarget.Clear(); blockList.clear(); + me->SetAnimTier(AnimTier::Fly); } void EnterCombatSelfFunction() @@ -291,7 +292,7 @@ public: me->AttackStop(); float x, y, z, o; me->GetHomePosition(x, y, z, o); - me->GetMotionMaster()->MovePoint(POINT_CENTER, x, y, z); + me->GetMotionMaster()->MovePoint(POINT_CENTER, x, y, z, FORCED_MOVEMENT_NONE, 0.f, o); return; case EVENT_FLIGHT_LIFTOFF: Talk(EMOTE_AIR_PHASE); From 6dfe65304e3eeaa1fa6192987de5ab56aa9a5f93 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sun, 1 Feb 2026 13:09:41 -0300 Subject: [PATCH 013/335] fix(Scripts/HyjalSummit): Prevent Hyjal Bosses from talking when talking when dead (#24572) --- .../CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp | 2 +- .../Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp | 2 +- .../CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp | 2 +- .../CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp index 8695236f0..c83ca2043 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp @@ -117,7 +117,7 @@ public: void KilledUnit(Unit* victim) override { - if (!_recentlySpoken && victim->IsPlayer()) + if (!_recentlySpoken && victim->IsPlayer() && me->IsAlive()) { Talk(SAY_ONSLAY); _recentlySpoken = true; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp index 673765564..63a1a3a6c 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp @@ -91,7 +91,7 @@ public: void KilledUnit(Unit * victim) override { - if (!_recentlySpoken && victim->IsPlayer()) + if (!_recentlySpoken && victim->IsPlayer() && me->IsAlive()) { Talk(SAY_ONSLAY); _recentlySpoken = true; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp index 925616c15..a5d03d912 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp @@ -111,7 +111,7 @@ public: void KilledUnit(Unit * victim) override { - if (!_recentlySpoken && victim->IsPlayer()) + if (!_recentlySpoken && victim->IsPlayer() && me->IsAlive()) { Talk(SAY_ONSLAY); _recentlySpoken = true; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp index f7900d5c5..a2ce47ff3 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp @@ -121,7 +121,7 @@ public: void KilledUnit(Unit* victim) override { - if (!_recentlySpoken && victim->IsPlayer()) + if (!_recentlySpoken && victim->IsPlayer() && me->IsAlive()) { Talk(SAY_ONSLAY); _recentlySpoken = true; From 364e16579da0f85261d9ee9902de78ef0028385e Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sun, 1 Feb 2026 13:09:59 -0300 Subject: [PATCH 014/335] fix(DB/SmartAI): Improve targeting for Spectral Stable Hand (#24574) --- .../rev_1769901941611666300.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1769901941611666300.sql diff --git a/data/sql/updates/pending_db_world/rev_1769901941611666300.sql b/data/sql/updates/pending_db_world/rev_1769901941611666300.sql new file mode 100644 index 000000000..1d5648117 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769901941611666300.sql @@ -0,0 +1,17 @@ +-- +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 15551); +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 +(15551, 0, 0, 0, 4, 0, 30, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Spectral Stable Hand - On Aggro - Say Line 0'), +(15551, 0, 1, 0, 6, 0, 50, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Spectral Stable Hand - On Just Died - Say Line 1'), +(15551, 0, 2, 0, 1, 0, 60, 0, 0, 70000, 80000, 190000, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Spectral Stable Hand - Out of Combat - Say Line 2'), +(15551, 0, 3, 0, 0, 0, 100, 0, 2000, 11000, 12000, 21000, 0, 0, 11, 18812, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Spectral Stable Hand - In Combat - Cast \'Knockdown\''), +(15551, 0, 4, 0, 0, 0, 100, 0, 2000, 15000, 17000, 28000, 0, 0, 11, 6016, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Spectral Stable Hand - In Combat - Cast \'Pierce Armor\''), +(15551, 0, 5, 0, 14, 0, 100, 0, 10000, 40, 12000, 22000, 0, 0, 11, 29339, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Spectral Stable Hand - Friendly Missing 10k HP and Near a Valid Target - Cast \'Healing Touch\''), +(15551, 0, 6, 0, 0, 0, 100, 0, 2000, 15000, 21000, 38000, 0, 0, 11, 29340, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Spectral Stable Hand - In Combat and Near a Valid Target - Cast \'Whip Rage\''); + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 22) AND (`SourceGroup` IN (6, 7)) AND (`SourceEntry` = 15551) AND (`ConditionTypeOrReference` = 29); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22, 6, 15551, 0, 0, 29, 1, 15547, 20, 0, 0, 0, 0, '', 'Spectral Stable Hand Healing Touch (29339) Requires Valid Target Nearby'), +(22, 6, 15551, 0, 1, 29, 1, 15548, 20, 0, 0, 0, 0, '', 'Spectral Stable Hand Healing Touch (29339) Requires Valid Target Nearby'), +(22, 7, 15551, 0, 0, 29, 1, 15547, 20, 0, 0, 0, 0, '', 'Spectral Stable Hand Whip Rage (29340) Requires Valid Target Nearby'), +(22, 7, 15551, 0, 1, 29, 1, 15548, 20, 0, 0, 0, 0, '', 'Spectral Stable Hand Whip Rage (29340) Requires Valid Target Nearby'); From 7621cef2a496401251005d160db8f513e3fff6f1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 1 Feb 2026 16:10:48 +0000 Subject: [PATCH 015/335] chore(DB): import pending files Referenced commit(s): 6dfe65304e3eeaa1fa6192987de5ab56aa9a5f93 --- .../rev_1769901941611666300.sql => db_world/2026_02_01_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1769901941611666300.sql => db_world/2026_02_01_00.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1769901941611666300.sql b/data/sql/updates/db_world/2026_02_01_00.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1769901941611666300.sql rename to data/sql/updates/db_world/2026_02_01_00.sql index 1d5648117..9b833d907 100644 --- a/data/sql/updates/pending_db_world/rev_1769901941611666300.sql +++ b/data/sql/updates/db_world/2026_02_01_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_01_31_03 -> 2026_02_01_00 -- DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 15551); INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES From ad804805c0f161c4d96669520b65c8a1bab7b80f Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Sun, 1 Feb 2026 19:13:33 +0100 Subject: [PATCH 016/335] fix(DB/Creature): Set Wyrmrest Protector emote to 0. (#24579) --- data/sql/updates/pending_db_world/Wyrmrest_Protector.sql | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 data/sql/updates/pending_db_world/Wyrmrest_Protector.sql diff --git a/data/sql/updates/pending_db_world/Wyrmrest_Protector.sql b/data/sql/updates/pending_db_world/Wyrmrest_Protector.sql new file mode 100644 index 000000000..1ffdc1b11 --- /dev/null +++ b/data/sql/updates/pending_db_world/Wyrmrest_Protector.sql @@ -0,0 +1,3 @@ + +-- Set Emote to 0 +UPDATE `creature_addon` SET `emote` = 0 WHERE (`guid` IN (131012, 131014, 131015, 131016, 131020, 131021, 131022, 131023, 131026, 131027)); From 6bbcb225586a71c99109d92f45baa2669e8bf28e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 1 Feb 2026 18:14:36 +0000 Subject: [PATCH 017/335] chore(DB): import pending files Referenced commit(s): ad804805c0f161c4d96669520b65c8a1bab7b80f --- .../Wyrmrest_Protector.sql => db_world/2026_02_01_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/Wyrmrest_Protector.sql => db_world/2026_02_01_01.sql} (78%) diff --git a/data/sql/updates/pending_db_world/Wyrmrest_Protector.sql b/data/sql/updates/db_world/2026_02_01_01.sql similarity index 78% rename from data/sql/updates/pending_db_world/Wyrmrest_Protector.sql rename to data/sql/updates/db_world/2026_02_01_01.sql index 1ffdc1b11..1b8c5d2f2 100644 --- a/data/sql/updates/pending_db_world/Wyrmrest_Protector.sql +++ b/data/sql/updates/db_world/2026_02_01_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_01_00 -> 2026_02_01_01 -- Set Emote to 0 UPDATE `creature_addon` SET `emote` = 0 WHERE (`guid` IN (131012, 131014, 131015, 131016, 131020, 131021, 131022, 131023, 131026, 131027)); From 396a6be5cfdcd61e1929818259027c3912837bad Mon Sep 17 00:00:00 2001 From: sudlud Date: Sun, 1 Feb 2026 21:05:33 +0100 Subject: [PATCH 018/335] fix(DB/SAI): fix talk timer for 'Brewfest Setup Crew' (#24583) --- data/sql/updates/pending_db_world/rev_1769941593477952100.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1769941593477952100.sql diff --git a/data/sql/updates/pending_db_world/rev_1769941593477952100.sql b/data/sql/updates/pending_db_world/rev_1769941593477952100.sql new file mode 100644 index 000000000..477269e53 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769941593477952100.sql @@ -0,0 +1,2 @@ +-- fix talk timer for 'Brewfest Setup Crew' +UPDATE `smart_scripts` SET `event_param4` = 60000, `event_param5` = 360000 WHERE `entryorguid` = 23504 AND `source_type` = 0 AND `id` = 0 AND `link` = 0; From b6f1169e60a652c195052b323a8d9364a2096caa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 1 Feb 2026 20:06:43 +0000 Subject: [PATCH 019/335] chore(DB): import pending files Referenced commit(s): 396a6be5cfdcd61e1929818259027c3912837bad --- .../rev_1769941593477952100.sql => db_world/2026_02_01_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1769941593477952100.sql => db_world/2026_02_01_02.sql} (81%) diff --git a/data/sql/updates/pending_db_world/rev_1769941593477952100.sql b/data/sql/updates/db_world/2026_02_01_02.sql similarity index 81% rename from data/sql/updates/pending_db_world/rev_1769941593477952100.sql rename to data/sql/updates/db_world/2026_02_01_02.sql index 477269e53..abd8084c8 100644 --- a/data/sql/updates/pending_db_world/rev_1769941593477952100.sql +++ b/data/sql/updates/db_world/2026_02_01_02.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_01_01 -> 2026_02_01_02 -- fix talk timer for 'Brewfest Setup Crew' UPDATE `smart_scripts` SET `event_param4` = 60000, `event_param5` = 360000 WHERE `entryorguid` = 23504 AND `source_type` = 0 AND `id` = 0 AND `link` = 0; From 261afd8854a66bdb1a0ffe978c7de5c38504e3ee Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sun, 1 Feb 2026 22:28:26 -0300 Subject: [PATCH 020/335] fix(DB/Loot): Rewrite TBC Raid BoE Loot and Recipes (#24586) --- .../rev_1769967751468801600.sql | 603 ++++++++++++++++++ 1 file changed, 603 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1769967751468801600.sql diff --git a/data/sql/updates/pending_db_world/rev_1769967751468801600.sql b/data/sql/updates/pending_db_world/rev_1769967751468801600.sql new file mode 100644 index 000000000..3b33b7297 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769967751468801600.sql @@ -0,0 +1,603 @@ +-- Karazhan: Chances increase as you go up the tower from ~0.4% to ~1% +DELETE FROM `reference_loot_template` WHERE (`Entry` = 1532000); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1532000, 30641, 0, 0, 0, 1, 1, 1, 1, 'Boots of Elusion'), +(1532000, 30642, 0, 0, 0, 1, 1, 1, 1, 'Drape of the Righteous'), +(1532000, 30643, 0, 0, 0, 1, 1, 1, 1, 'Belt of the Tracker'), +(1532000, 30644, 0, 0, 0, 1, 1, 1, 1, 'Grips of Deftness'), +(1532000, 30666, 0, 0, 0, 1, 1, 1, 1, 'Ritssyn\'s Lost Pendant'), +(1532000, 30667, 0, 0, 0, 1, 1, 1, 1, 'Ring of Unrelenting Storms'), +(1532000, 30668, 0, 0, 0, 1, 1, 1, 1, 'Grasp of the Dead'), +(1532000, 30673, 0, 0, 0, 1, 1, 1, 1, 'Inferno Waist Cord'), +(1532000, 30674, 0, 0, 0, 1, 1, 1, 1, 'Zierhut\'s Lost Treads'); + +DELETE FROM `creature_loot_template` WHERE `Item` IN (30641,30642,30643,30644,30666,30667,30668,30673,30674) AND `Entry` IN (16488,16409,16468,16491,16492,16170,16173,16539,16178,15551,16175,16176,16389,16406,16407,16411,16412,16415,16424,16425,16525,16530,16540,16171,16177,16174,16410,16414,16459,16460,16461,16470,16473,16489,16526,16529,16544,15547,15548,16408,16472,16481,16482,16545,16595,16471,16485,16504,16596); +DELETE FROM `creature_loot_template` WHERE `Reference` = 1532000 AND `Entry` IN (16488,16409,16468,16491,16492,16170,16173,16539,16178,15551,16175,16176,16389,16406,16407,16411,16412,16415,16424,16425,16525,16530,16540,16171,16177,16174,16410,16414,16459,16460,16461,16470,16473,16489,16526,16529,16544,15547,15548,16408,16472,16481,16482,16545,16595,16471,16485,16504,16596); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(16488, 1532000, 1532000, 0.2, 'Arcane Anomaly - Karazhan Epic BoEs'), +(16409, 1532000, 1532000, 0.2, 'Phantom Guest - Karazhan Epic BoEs'), +(16468, 1532000, 1532000, 0.4, 'Spectral Patron - Karazhan Epic BoEs'), +(16491, 1532000, 1532000, 0.4, 'Mana Feeder - Karazhan Epic BoEs'), +(16492, 1532000, 1532000, 0.4, 'Syphoner - Karazhan Epic BoEs'), +(16539, 1532000, 1532000, 0.4, 'Homunculus - Karazhan Epic BoEs'), +(15551, 1532000, 1532000, 0.4, 'Spectral Stable Hand - Karazhan Epic BoEs'), +(16389, 1532000, 1532000, 0.4, 'Spectral Apprentice - Karazhan Epic BoEs'), +(16406, 1532000, 1532000, 0.4, 'Phantom Attendant - Karazhan Epic BoEs'), +(16407, 1532000, 1532000, 0.4, 'Spectral Servant - Karazhan Epic BoEs'), +(16411, 1532000, 1532000, 0.4, 'Spectral Chef - Karazhan Epic BoEs'), +(16412, 1532000, 1532000, 0.4, 'Ghostly Baker - Karazhan Epic BoEs'), +(16415, 1532000, 1532000, 0.4, 'Skeletal Waiter - Karazhan Epic BoEs'), +(16424, 1532000, 1532000, 0.4, 'Spectral Sentry - Karazhan Epic BoEs'), +(16425, 1532000, 1532000, 0.4, 'Phantom Guardsman - Karazhan Epic BoEs'), +(16525, 1532000, 1532000, 1, 'Spell Shade - Karazhan Epic BoEs'), +(16530, 1532000, 1532000, 0.4, 'Mana Warp - Karazhan Epic BoEs'), +(16540, 1532000, 1532000, 1, 'Shadow Pillager - Karazhan Epic BoEs'), +(16410, 1532000, 1532000, 0.4, 'Spectral Retainer - Karazhan Epic BoEs'), +(16414, 1532000, 1532000, 0.4, 'Ghostly Steward - Karazhan Epic BoEs'), +(16459, 1532000, 1532000, 0.4, 'Wanton Hostess - Karazhan Epic BoEs'), +(16460, 1532000, 1532000, 0.4, 'Night Mistress - Karazhan Epic BoEs'), +(16461, 1532000, 1532000, 0.4, 'Concubine - Karazhan Epic BoEs'), +(16470, 1532000, 1532000, 0.4, 'Ghostly Philanthropist - Karazhan Epic BoEs'), +(16473, 1532000, 1532000, 0.4, 'Spectral Performer - Karazhan Epic BoEs'), +(16489, 1532000, 1532000, 1, 'Chaotic Sentience - Karazhan Epic BoEs'), +(16526, 1532000, 1532000, 1, 'Sorcerous Shade - Karazhan Epic BoEs'), +(16529, 1532000, 1532000, 0.4, 'Magical Horror - Karazhan Epic BoEs'), +(16544, 1532000, 1532000, 1, 'Ethereal Thief - Karazhan Epic BoEs'), +(15547, 1532000, 1532000, 0.4, 'Spectral Charger - Karazhan Epic BoEs'), +(15548, 1532000, 1532000, 0.4, 'Spectral Stallion - Karazhan Epic BoEs'), +(16408, 1532000, 1532000, 0.4, 'Phantom Valet - Karazhan Epic BoEs'), +(16472, 1532000, 1532000, 0.4, 'Phantom Stagehand - Karazhan Epic BoEs'), +(16481, 1532000, 1532000, 1, 'Ghastly Haunt - Karazhan Epic BoEs'), +(16482, 1532000, 1532000, 1, 'Trapped Soul - Karazhan Epic BoEs'), +(16545, 1532000, 1532000, 1, 'Ethereal Spellfilcher - Karazhan Epic BoEs'), +(16595, 1532000, 1532000, 1, 'Fleshbeast - Karazhan Epic BoEs'), +(16471, 1532000, 1532000, 0.4, 'Skeletal Usher - Karazhan Epic BoEs'), +(16485, 1532000, 1532000, 2, 'Arcane Watchman - Karazhan Epic BoEs'), +(16504, 1532000, 1532000, 2, 'Arcane Protector - Karazhan Epic BoEs'), +(16596, 1532000, 1532000, 2, 'Greater Fleshbeast - Karazhan Epic BoEs'); + +-- SSC +DELETE FROM `reference_loot_template` WHERE (`Entry` = 1548000); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1548000, 30021, 0, 0, 0, 1, 1, 1, 1, 'Wildfury Greatstaff'), +(1548000, 30022, 0, 0, 0, 1, 1, 1, 1, 'Pendant of the Perilous'), +(1548000, 30023, 0, 0, 0, 1, 1, 1, 1, 'Totem of the Maelstrom'), +(1548000, 30027, 0, 0, 0, 1, 1, 1, 1, 'Boots of Courage Unending'), +(1548000, 30620, 0, 0, 0, 1, 1, 1, 1, 'Spyglass of the Hidden Fleet'); + +DELETE FROM `creature_loot_template` WHERE `Item` IN (30021,30022,30023,30027,30620) AND `Entry` IN (21263,21246,21863,21220,21224,21225,21226,21227,21228,21229,21230,21231,21232,21298,21299,21301,21339,21218,21221,21251); +DELETE FROM `creature_loot_template` WHERE `Reference` = 1548000 AND `Entry` IN (21263,21246,21863,21220,21224,21225,21226,21227,21228,21229,21230,21231,21232,21298,21299,21301,21339,21218,21221,21251); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(21263, 1548000, 1548000, 1, 'Greyheart Technician - Serpentshrine Cavern BoEs'), +(21246, 1548000, 1548000, 2, 'Serpentshrine Sporebat - Serpentshrine Cavern BoEs'), +(21863, 1548000, 1548000, 2, 'Serpentshrine Lurker - Serpentshrine Cavern BoEs'), +(21220, 1548000, 1548000, 2, 'Coilfang Priestess - Serpentshrine Cavern BoEs'), +(21224, 1548000, 1548000, 2, 'Tidewalker Depth-Seer - Serpentshrine Cavern BoEs'), +(21225, 1548000, 1548000, 2, 'Tidewalker Warrior - Serpentshrine Cavern BoEs'), +(21226, 1548000, 1548000, 2, 'Tidewalker Shaman - Serpentshrine Cavern BoEs'), +(21227, 1548000, 1548000, 2, 'Tidewalker Harpooner - Serpentshrine Cavern BoEs'), +(21228, 1548000, 1548000, 2, 'Tidewalker Hydromancer - Serpentshrine Cavern BoEs'), +(21229, 1548000, 1548000, 2, 'Greyheart Tidecaller - Serpentshrine Cavern BoEs'), +(21230, 1548000, 1548000, 2, 'Greyheart Nether-Mage - Serpentshrine Cavern BoEs'), +(21231, 1548000, 1548000, 2, 'Greyheart Shield-Bearer - Serpentshrine Cavern BoEs'), +(21232, 1548000, 1548000, 2, 'Greyheart Skulker - Serpentshrine Cavern BoEs'), +(21298, 1548000, 1548000, 2, 'Coilfang Serpentguard - Serpentshrine Cavern BoEs'), +(21299, 1548000, 1548000, 2, 'Coilfang Fathom-Witch - Serpentshrine Cavern BoEs'), +(21301, 1548000, 1548000, 2, 'Coilfang Shatterer - Serpentshrine Cavern BoEs'), +(21339, 1548000, 1548000, 2, 'Coilfang Hate-Screamer - Serpentshrine Cavern BoEs'), +(21218, 1548000, 1548000, 2, 'Vashj\'ir Honor Guard - Serpentshrine Cavern BoEs'), +(21221, 1548000, 1548000, 2, 'Coilfang Beast-Tamer - Serpentshrine Cavern BoEs'), +(21251, 1548000, 1548000, 5, 'Underbog Colossus - Serpentshrine Cavern BoEs'); + +-- The Eye +DELETE FROM `reference_loot_template` WHERE (`Entry` = 1550000); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1550000, 30029, 0, 0, 0, 1, 1, 1, 1, 'Bark-Gloves of Ancient Wisdom'), +(1550000, 30020, 0, 0, 0, 1, 1, 1, 1, 'Fire-Cord of the Magus'), +(1550000, 30030, 0, 0, 0, 1, 1, 1, 1, 'Girdle of Fallen Stars'), +(1550000, 30024, 0, 0, 0, 1, 1, 1, 1, 'Mantle of the Elven Kings'), +(1550000, 30026, 0, 0, 0, 1, 1, 1, 1, 'Bands of the Celestial Archer'), +(1550000, 30028, 0, 0, 0, 1, 1, 1, 1, 'Seventh Ring of the Tirisfalen'); + +DELETE FROM `creature_loot_template` WHERE `Reference` = 55500 AND `Entry` IN (20043,20044,20038,20031,20033,20034,20036,20037,20042,20047,20048,20052,20032,20035,20041,20045,20046,20049,20050,20039,20040); +DELETE FROM `creature_loot_template` WHERE `Item` IN (30029,30020,30030,30024,30026,30028) AND `Entry` IN (20043,20044,20038,20031,20033,20034,20036,20037,20042,20047,20048,20052,20032,20035,20041,20045,20046,20049,20050,20039,20040); +DELETE FROM `creature_loot_template` WHERE `Reference` = 1550000 AND `Entry` IN (20043,20044,20038,20031,20033,20034,20036,20037,20042,20047,20048,20052,20032,20035,20041,20045,20046,20049,20050,20039,20040); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(20043, 1550000, 1550000, 0.4, 'Apprentice Star Scryer - The Eye BoEs'), +(20044, 1550000, 1550000, 0.4, 'Novice Astromancer - The Eye BoEs'), +(20038, 1550000, 1550000, 2, 'Phoenix-Hawk Hatchling - The Eye BoEs'), +(20031, 1550000, 1550000, 2, 'Bloodwarder Legionnaire - The Eye BoEs'), +(20033, 1550000, 1550000, 2, 'Astromancer - The Eye BoEs'), +(20034, 1550000, 1550000, 2, 'Star Scryer - The Eye BoEs'), +(20036, 1550000, 1550000, 2, 'Bloodwarder Squire - The Eye BoEs'), +(20037, 1550000, 1550000, 2, 'Tempest Falconer - The Eye BoEs'), +(20042, 1550000, 1550000, 2, 'Tempest-Smith - The Eye BoEs'), +-- (20047, 1550000, 1550000, 2, 'Crimson Hand Battle Mage - The Eye BoEs'), +(20048, 1550000, 1550000, 2, 'Crimson Hand Centurion - The Eye BoEs'), +(20052, 1550000, 1550000, 2, 'Crystalcore Mechanic - The Eye BoEs'), +(20032, 1550000, 1550000, 2, 'Bloodwarder Vindicator - The Eye BoEs'), +(20035, 1550000, 1550000, 2, 'Bloodwarder Marshal - The Eye BoEs'), +(20041, 1550000, 1550000, 2, 'Crystalcore Sentinel - The Eye BoEs'), +(20045, 1550000, 1550000, 2, 'Nether Scryer - The Eye BoEs'), +(20046, 1550000, 1550000, 2, 'Astromancer Lord - The Eye BoEs'), +(20049, 1550000, 1550000, 2, 'Crimson Hand Blood Knight - The Eye BoEs'), +(20050, 1550000, 1550000, 2, 'Crimson Hand Inquisitor - The Eye BoEs'), +(20039, 1550000, 1550000, 5, 'Phoenix-Hawk - The Eye BoEs'), +(20040, 1550000, 1550000, 5, 'Crystalcore Devastator - The Eye BoEs'); + +-- Phase 2 Recipes +DELETE FROM `reference_loot_template` WHERE (`Entry` = 1548001); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1548001, 30280, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Belt of Blasting'), +(1548001, 30281, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Belt of the Long Road'), +(1548001, 30282, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Boots of Blasting'), +(1548001, 30283, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Boots of the Long Road'), +(1548001, 30301, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Belt of Natural Power'), +(1548001, 30302, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Belt of Deep Shadow'), +(1548001, 30303, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Belt of the Black Eagle'), +(1548001, 30304, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Monsoon Belt'), +(1548001, 30305, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Boots of Natural Grace'), +(1548001, 30306, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Boots of Utter Darkness'), +(1548001, 30307, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Boots of the Crimson Hawk'), +(1548001, 30308, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Hurricane Boots'), +(1548001, 30321, 0, 0, 0, 1, 1, 1, 1, 'Plans: Belt of the Guardian'), +(1548001, 30322, 0, 0, 0, 1, 1, 1, 1, 'Plans: Red Belt of Battle'), +(1548001, 30323, 0, 0, 0, 1, 1, 1, 1, 'Plans: Boots of the Protector'), +(1548001, 30324, 0, 0, 0, 1, 1, 1, 1, 'Plans: Red Havoc Boots'); + +DELETE FROM `creature_loot_template` WHERE `Reference` = 34052 AND `Entry` IN (21263,21246,21863,21220,21224,21225,21226,21227,21228,21229,21230,21231,21232,21298,21299,21301,21339,21218,21221,21251,20043,20044,20038,20031,20033,20034,20036,20037,20042,20047,20048,20052,20032,20035,20041,20045,20046,20049,20050,20039,20040); +DELETE FROM `creature_loot_template` WHERE `Item` IN (30280,30281,30282,30283,30301,30302,30303,30304,30305,30306,30307,30308,30321,30322,30323,30324) AND `Entry` IN (21263,21246,21863,21220,21224,21225,21226,21227,21228,21229,21230,21231,21232,21298,21299,21301,21339,21218,21221,21251,20043,20044,20038,20031,20033,20034,20036,20037,20042,20047,20048,20052,20032,20035,20041,20045,20046,20049,20050,20039,20040); +DELETE FROM `creature_loot_template` WHERE `Reference` = 1548001 AND `Entry` IN (21263,21246,21863,21220,21224,21225,21226,21227,21228,21229,21230,21231,21232,21298,21299,21301,21339,21218,21221,21251,20043,20044,20038,20031,20033,20034,20036,20037,20042,20047,20048,20052,20032,20035,20041,20045,20046,20049,20050,20039,20040); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(21263, 1548001, 1548001, 0.4, 'Greyheart Technician - TBC Phase 2 BoE Recipes'), +(21246, 1548001, 1548001, 2.4, 'Serpentshrine Sporebat - TBC Phase 2 BoE Recipes'), +(21863, 1548001, 1548001, 2.4, 'Serpentshrine Lurker - TBC Phase 2 BoE Recipes'), +(21220, 1548001, 1548001, 2.4, 'Coilfang Priestess - TBC Phase 2 BoE Recipes'), +(21224, 1548001, 1548001, 2.4, 'Tidewalker Depth-Seer - TBC Phase 2 BoE Recipes'), +(21225, 1548001, 1548001, 2.4, 'Tidewalker Warrior - TBC Phase 2 BoE Recipes'), +(21226, 1548001, 1548001, 2.4, 'Tidewalker Shaman - TBC Phase 2 BoE Recipes'), +(21227, 1548001, 1548001, 2.4, 'Tidewalker Harpooner - TBC Phase 2 BoE Recipes'), +(21228, 1548001, 1548001, 2.4, 'Tidewalker Hydromancer - TBC Phase 2 BoE Recipes'), +(21229, 1548001, 1548001, 2.4, 'Greyheart Tidecaller - TBC Phase 2 BoE Recipes'), +(21230, 1548001, 1548001, 2.4, 'Greyheart Nether-Mage - TBC Phase 2 BoE Recipes'), +(21231, 1548001, 1548001, 2.4, 'Greyheart Shield-Bearer - TBC Phase 2 BoE Recipes'), +(21232, 1548001, 1548001, 2.4, 'Greyheart Skulker - TBC Phase 2 BoE Recipes'), +(21298, 1548001, 1548001, 2.4, 'Coilfang Serpentguard - TBC Phase 2 BoE Recipes'), +(21299, 1548001, 1548001, 2.4, 'Coilfang Fathom-Witch - TBC Phase 2 BoE Recipes'), +(21301, 1548001, 1548001, 2.4, 'Coilfang Shatterer - TBC Phase 2 BoE Recipes'), +(21339, 1548001, 1548001, 2.4, 'Coilfang Hate-Screamer - TBC Phase 2 BoE Recipes'), +(21218, 1548001, 1548001, 2.4, 'Vashj\'ir Honor Guard - TBC Phase 2 BoE Recipes'), +(21221, 1548001, 1548001, 2.4, 'Coilfang Beast-Tamer - TBC Phase 2 BoE Recipes'), +(21251, 1548001, 1548001, 2.4, 'Underbog Colossus - TBC Phase 2 BoE Recipes'), +(20043, 1548001, 1548001, 0.4, 'Apprentice Star Scryer - TBC Phase 2 BoE Recipes'), +(20044, 1548001, 1548001, 0.4, 'Novice Astromancer - TBC Phase 2 BoE Recipes'), +(20038, 1548001, 1548001, 2.4, 'Phoenix-Hawk Hatchling - TBC Phase 2 BoE Recipes'), +(20031, 1548001, 1548001, 2.4, 'Bloodwarder Legionnaire - TBC Phase 2 BoE Recipes'), +(20033, 1548001, 1548001, 2.4, 'Astromancer - TBC Phase 2 BoE Recipes'), +(20034, 1548001, 1548001, 2.4, 'Star Scryer - TBC Phase 2 BoE Recipes'), +(20036, 1548001, 1548001, 2.4, 'Bloodwarder Squire - TBC Phase 2 BoE Recipes'), +(20037, 1548001, 1548001, 2.4, 'Tempest Falconer - TBC Phase 2 BoE Recipes'), +(20042, 1548001, 1548001, 2.4, 'Tempest-Smith - TBC Phase 2 BoE Recipes'), +-- (20047, 1548001, 1548001, 2.4, 'Crimson Hand Battle Mage - TBC Phase 2 BoE Recipes'), +(20048, 1548001, 1548001, 2.4, 'Crimson Hand Centurion - TBC Phase 2 BoE Recipes'), +(20052, 1548001, 1548001, 2.4, 'Crystalcore Mechanic - TBC Phase 2 BoE Recipes'), +(20032, 1548001, 1548001, 2.4, 'Bloodwarder Vindicator - TBC Phase 2 BoE Recipes'), +(20035, 1548001, 1548001, 2.4, 'Bloodwarder Marshal - TBC Phase 2 BoE Recipes'), +(20041, 1548001, 1548001, 2.4, 'Crystalcore Sentinel - TBC Phase 2 BoE Recipes'), +(20045, 1548001, 1548001, 2.4, 'Nether Scryer - TBC Phase 2 BoE Recipes'), +(20046, 1548001, 1548001, 2.4, 'Astromancer Lord - TBC Phase 2 BoE Recipes'), +(20049, 1548001, 1548001, 2.4, 'Crimson Hand Blood Knight - TBC Phase 2 BoE Recipes'), +(20050, 1548001, 1548001, 2.4, 'Crimson Hand Inquisitor - TBC Phase 2 BoE Recipes'), +(20039, 1548001, 1548001, 2.4, 'Phoenix-Hawk - TBC Phase 2 BoE Recipes'), +(20040, 1548001, 1548001, 2.4, 'Crystalcore Devastator - TBC Phase 2 BoE Recipes'); + +-- Hyjal Summit +DELETE FROM `reference_loot_template` WHERE (`Entry` = 1534000); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1534000, 32589, 0, 0, 0, 1, 1, 1, 1, 'Hellfire-Encased Pendant'), +(1534000, 32590, 0, 0, 0, 1, 1, 1, 1, 'Nethervoid Cloak'), +(1534000, 32591, 0, 0, 0, 1, 1, 1, 1, 'Choker of Serrated Blades'), +(1534000, 32592, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of Relentless Storms'), +(1534000, 32609, 0, 0, 0, 1, 1, 1, 1, 'Boots of the Divine Light'), +(1534000, 32945, 0, 4.5, 0, 1, 1, 1, 1, 'Fist of Molten Fury'), +(1534000, 32946, 0, 4.5, 0, 1, 1, 1, 1, 'Claw of Molten Fury'), +(1534000, 34009, 0, 0, 0, 1, 1, 1, 1, 'Hammer of Judgement'), +(1534000, 34010, 0, 0, 0, 1, 1, 1, 1, 'Pepe\'s Shroud of Pacification'); + +DELETE FROM `creature_loot_template` WHERE `Reference` = 39534 AND `Entry` IN (17895,17897,17898,17899,17905,17906,17907,17908,17916); +DELETE FROM `creature_loot_template` WHERE `Item` IN (32589,32590,32591,32592,32609,32945,32946,34009,34010) AND `Entry` IN (17895,17897,17898,17899,17905,17906,17907,17908,17916); +DELETE FROM `creature_loot_template` WHERE `Reference` = 1534000 AND `Entry` IN (17895,17897,17898,17899,17905,17906,17907,17908,17916); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(17895, 1534000, 1534000, 4, 'Ghoul - Hyjal Summit BoEs'), +(17897, 1534000, 1534000, 4, 'Crypt Fiend - Hyjal Summit BoEs'), +(17898, 1534000, 1534000, 4, 'Abomination - Hyjal Summit BoEs'), +(17899, 1534000, 1534000, 4, 'Shadowy Necromancer - Hyjal Summit BoEs'), +(17905, 1534000, 1534000, 4, 'Banshee - Hyjal Summit BoEs'), +(17906, 1534000, 1534000, 4, 'Gargoyle - Hyjal Summit BoEs'), +(17907, 1534000, 1534000, 4, 'Frost Wyrm - Hyjal Summit BoEs'), +(17908, 1534000, 1534000, 4, 'Giant Infernal - Hyjal Summit BoEs'), +(17916, 1534000, 1534000, 4, 'Fel Stalker - Hyjal Summit BoEs'); + +-- Black Temple +DELETE FROM `reference_loot_template` WHERE (`Entry` = 1564000); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1564000, 32526, 0, 0, 0, 1, 1, 1, 1, 'Band of Devastation'), +(1564000, 32527, 0, 0, 0, 1, 1, 1, 1, 'Ring of Ancient Knowledge'), +(1564000, 32528, 0, 0, 0, 1, 1, 1, 1, 'Blessed Band of Karabor'), +(1564000, 32593, 0, 0, 0, 1, 1, 1, 1, 'Treads of the Den Mother'), +(1564000, 32606, 0, 0, 0, 1, 1, 1, 1, 'Girdle of the Lightbearer'), +(1564000, 32608, 0, 0, 0, 1, 1, 1, 1, 'Pillager\'s Gauntlets'), +(1564000, 32943, 0, 0, 0, 1, 1, 1, 1, 'Swiftsteel Bludgeon'), +(1564000, 34011, 0, 0, 0, 1, 1, 1, 1, 'Illidari Runeshield'), +(1564000, 34012, 0, 0, 0, 1, 1, 1, 1, 'Shroud of the Final Stand'); + +DELETE FROM `creature_loot_template` WHERE `Reference` = 14099 AND `Entry` IN (22883,22939,22955,22963,23147,23223,23047,22946,22848,22849,22881,22885,23232,22945,22965,23403,22845,22846,22847,22853,22869,22874,22875,22876,22877,22879,22882,22959,23028,23235,23236,23237,23339,23374,23400,23402,22960,23018,23030,23172,23330,22873,23337,23397,22844,22880,22953,22956,22964,23049,23222,23239,22855,22878,22884,22954,22957,22962,23196,23394); +DELETE FROM `creature_loot_template` WHERE `Item` IN (32526,32527,32528,32593,32606,32608,32943,34011,34012) AND `Entry` IN (22883,22939,22955,22963,23147,23223,23047,22946,22848,22849,22881,22885,23232,22945,22965,23403,22845,22846,22847,22853,22869,22874,22875,22876,22877,22879,22882,22959,23028,23235,23236,23237,23339,23374,23400,23402,22960,23018,23030,23172,23330,22873,23337,23397,22844,22880,22953,22956,22964,23049,23222,23239,22855,22878,22884,22954,22957,22962,23196,23394); +DELETE FROM `creature_loot_template` WHERE `Reference` = 1564000 AND `Entry` IN (22883,22939,22955,22963,23147,23223,23047,22946,22848,22849,22881,22885,23232,22945,22965,23403,22845,22846,22847,22853,22869,22874,22875,22876,22877,22879,22882,22959,23028,23235,23236,23237,23339,23374,23400,23402,22960,23018,23030,23172,23330,22873,23337,23397,22844,22880,22953,22956,22964,23049,23222,23239,22855,22878,22884,22954,22957,22962,23196,23394); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(22939, 1564000, 1564000, 0.4, 'Temple Concubine - Black Temple BoEs'), +(22955, 1564000, 1564000, 0.4, 'Charming Courtesan - Black Temple BoEs'), +(22963, 1564000, 1564000, 0.4, 'Bonechewer Worker - Black Temple BoEs'), +(23147, 1564000, 1564000, 0.4, 'Shadowmoon Grunt - Black Temple BoEs'), +(23223, 1564000, 1564000, 0.4, 'Bonechewer Spectator - Black Temple BoEs'), +(23047, 1564000, 1564000, 0.4, 'Shadowmoon Soldier - Black Temple BoEs'), +(22946, 1564000, 1564000, 0.4, 'Shadowmoon War Hound - Black Temple BoEs'), +(22848, 1564000, 1564000, 0.4, 'Storm Fury - Black Temple BoEs'), +(22849, 1564000, 1564000, 0.4, 'Ashtongue Feral Spirit - Black Temple BoEs'), +(22881, 1564000, 1564000, 0.4, 'Aqueous Surger - Black Temple BoEs'), +(22885, 1564000, 1564000, 0.4, 'Dragon Turtle - Black Temple BoEs'), +(23232, 1564000, 1564000, 0.4, 'Mutant War Hound - Black Temple BoEs'), +(22945, 1564000, 1564000, 2, 'Shadowmoon Blood Mage - Black Temple BoEs'), +(22965, 1564000, 1564000, 0.4, 'Enslaved Servant - Black Temple BoEs'), +(23403, 1564000, 1564000, 2, 'Illidari Assassin - Black Temple BoEs'), +(22845, 1564000, 1564000, 2, 'Ashtongue Mystic - Black Temple BoEs'), +(22846, 1564000, 1564000, 2, 'Ashtongue Stormcaller - Black Temple BoEs'), +(22847, 1564000, 1564000, 2, 'Ashtongue Primalist - Black Temple BoEs'), +(22853, 1564000, 1564000, 2, 'Illidari Defiler - Black Temple BoEs'), +(22869, 1564000, 1564000, 2, 'Illidari Boneslicer - Black Temple BoEs'), +(22874, 1564000, 1564000, 2, 'Coilskar Harpooner - Black Temple BoEs'), +(22875, 1564000, 1564000, 2, 'Coilskar Sea-Caller - Black Temple BoEs'), +(22876, 1564000, 1564000, 2, 'Coilskar Soothsayer - Black Temple BoEs'), +(22877, 1564000, 1564000, 2, 'Coilskar Wrangler - Black Temple BoEs'), +(22879, 1564000, 1564000, 2, 'Shadowmoon Reaver - Black Temple BoEs'), +(22882, 1564000, 1564000, 2, 'Shadowmoon Deathshaper - Black Temple BoEs'), +(22959, 1564000, 1564000, 2, 'Spellbound Attendant - Black Temple BoEs'), +(23028, 1564000, 1564000, 2, 'Bonechewer Taskmaster - Black Temple BoEs'), +(23235, 1564000, 1564000, 2, 'Bonechewer Blade Fury - Black Temple BoEs'), +(23236, 1564000, 1564000, 2, 'Bonechewer Shield Disciple - Black Temple BoEs'), +(23237, 1564000, 1564000, 2, 'Bonechewer Blood Prophet - Black Temple BoEs'), +(23339, 1564000, 1564000, 2, 'Illidari Heartseeker - Black Temple BoEs'), +(23374, 1564000, 1564000, 2, 'Ashtongue Stalker - Black Temple BoEs'), +(23400, 1564000, 1564000, 2, 'Illidari Archon - Black Temple BoEs'), +(23402, 1564000, 1564000, 2, 'Illidari Battle-mage - Black Temple BoEs'), +(22960, 1564000, 1564000, 2, 'Dragonmaw Wyrmcaller - Black Temple BoEs'), +(23018, 1564000, 1564000, 2, 'Shadowmoon Houndmaster - Black Temple BoEs'), +(23030, 1564000, 1564000, 2, 'Dragonmaw Sky Stalker - Black Temple BoEs'), +(23172, 1564000, 1564000, 2, 'Hand of Gorefiend - Black Temple BoEs'), +(23330, 1564000, 1564000, 2, 'Dragonmaw Wind Reaver - Black Temple BoEs'), +(22873, 1564000, 1564000, 2, 'Coilskar General - Black Temple BoEs'), +(23337, 1564000, 1564000, 2, 'Illidari Centurion - Black Temple BoEs'), +(23397, 1564000, 1564000, 2, 'Illidari Blood Lord - Black Temple BoEs'), +(22844, 1564000, 1564000, 2, 'Ashtongue Battlelord - Black Temple BoEs'), +(22880, 1564000, 1564000, 2, 'Shadowmoon Champion - Black Temple BoEs'), +(22953, 1564000, 1564000, 2, 'Wrathbone Flayer - Black Temple BoEs'), +(22956, 1564000, 1564000, 2, 'Sister of Pain - Black Temple BoEs'), +(22964, 1564000, 1564000, 2, 'Sister of Pleasure - Black Temple BoEs'), +(23049, 1564000, 1564000, 2, 'Shadowmoon Weapon Master - Black Temple BoEs'), +(23222, 1564000, 1564000, 2, 'Bonechewer Brawler - Black Temple BoEs'), +(23239, 1564000, 1564000, 2, 'Bonechewer Combatant - Black Temple BoEs'), +(22855, 1564000, 1564000, 2, 'Illidari Nightlord - Black Temple BoEs'), +(22878, 1564000, 1564000, 2, 'Aqueous Lord - Black Temple BoEs'), +(22884, 1564000, 1564000, 2, 'Leviathan - Black Temple BoEs'), +(22954, 1564000, 1564000, 2, 'Illidari Fearbringer - Black Temple BoEs'), +(22957, 1564000, 1564000, 2, 'Priestess of Dementia - Black Temple BoEs'), +(22962, 1564000, 1564000, 2, 'Priestess of Delight - Black Temple BoEs'), +(23196, 1564000, 1564000, 2, 'Bonechewer Behemoth - Black Temple BoEs'), +(23394, 1564000, 1564000, 2, 'Promenade Sentinel - Black Temple BoEs'); + +-- Phase 3 Recipes +DELETE FROM `reference_loot_template` WHERE (`Entry` = 1564001); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1564001, 32736, 0, 0, 0, 1, 1, 1, 1, 'Plans: Swiftsteel Bracers'), +(1564001, 32738, 0, 0, 0, 1, 1, 1, 1, 'Plans: Dawnsteel Bracers'), +(1564001, 32744, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Bracers of Renewed Life'), +(1564001, 32746, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Swiftstrike Bracers'), +(1564001, 32748, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Bindings of Lightning Reflexes'), +(1564001, 32750, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Living Earth Bindings'), +(1564001, 32752, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Swiftheal Wraps'), +(1564001, 32754, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Bracers of Nimble Thought'); + +DELETE FROM `creature_loot_template` WHERE `Reference` IN (34069, 39534) AND `Entry` IN (22939,22955,22963,23147,23223,23047,22946,22848,22849,22881,22885,23232,22945,22965,23403,22845,22846,22847,22853,22869,22874,22875,22876,22877,22879,22882,22959,23028,23235,23236,23237,23339,23374,23400,23402,22960,23018,23030,23172,23330,22873,23337,23397,22844,22880,22953,22956,22964,23049,23222,23239,22855,22878,22884,22954,22957,22962,23196,23394,17895,17897,17898,17899,17905,17906,17907,17908,17916); +DELETE FROM `creature_loot_template` WHERE `Item` IN (32736,32738,32744,32746,32748,32750,32752,32754) AND `Entry` IN (22939,22955,22963,23147,23223,23047,22946,22848,22849,22881,22885,23232,22945,22965,23403,22845,22846,22847,22853,22869,22874,22875,22876,22877,22879,22882,22959,23028,23235,23236,23237,23339,23374,23400,23402,22960,23018,23030,23172,23330,22873,23337,23397,22844,22880,22953,22956,22964,23049,23222,23239,22855,22878,22884,22954,22957,22962,23196,23394,17895,17897,17898,17899,17905,17906,17907,17908,17916); +DELETE FROM `creature_loot_template` WHERE `Reference` = 1564001 AND `Entry` IN (22939,22955,22963,23147,23223,23047,22946,22848,22849,22881,22885,23232,22945,22965,23403,22845,22846,22847,22853,22869,22874,22875,22876,22877,22879,22882,22959,23028,23235,23236,23237,23339,23374,23400,23402,22960,23018,23030,23172,23330,22873,23337,23397,22844,22880,22953,22956,22964,23049,23222,23239,22855,22878,22884,22954,22957,22962,23196,23394,17895,17897,17898,17899,17905,17906,17907,17908,17916); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(22939, 1564001, 1564001, 0.4, 'Temple Concubine - Phase 3 BoE Recipes'), +(22955, 1564001, 1564001, 0.4, 'Charming Courtesan - Phase 3 BoE Recipes'), +(22963, 1564001, 1564001, 0.4, 'Bonechewer Worker - Phase 3 BoE Recipes'), +(23147, 1564001, 1564001, 0.4, 'Shadowmoon Grunt - Phase 3 BoE Recipes'), +(23223, 1564001, 1564001, 0.4, 'Bonechewer Spectator - Phase 3 BoE Recipes'), +(23047, 1564001, 1564001, 0.4, 'Shadowmoon Soldier - Phase 3 BoE Recipes'), +(22946, 1564001, 1564001, 0.4, 'Shadowmoon War Hound - Phase 3 BoE Recipes'), +(22848, 1564001, 1564001, 0.4, 'Storm Fury - Phase 3 BoE Recipes'), +(22849, 1564001, 1564001, 0.4, 'Ashtongue Feral Spirit - Phase 3 BoE Recipes'), +(22881, 1564001, 1564001, 0.4, 'Aqueous Surger - Phase 3 BoE Recipes'), +(22885, 1564001, 1564001, 0.4, 'Dragon Turtle - Phase 3 BoE Recipes'), +(23232, 1564001, 1564001, 0.4, 'Mutant War Hound - Phase 3 BoE Recipes'), +(22945, 1564001, 1564001, 2.4, 'Shadowmoon Blood Mage - Phase 3 BoE Recipes'), +(22965, 1564001, 1564001, 0.4, 'Enslaved Servant - Phase 3 BoE Recipes'), +(23403, 1564001, 1564001, 2.4, 'Illidari Assassin - Phase 3 BoE Recipes'), +(22845, 1564001, 1564001, 2.4, 'Ashtongue Mystic - Phase 3 BoE Recipes'), +(22846, 1564001, 1564001, 2.4, 'Ashtongue Stormcaller - Phase 3 BoE Recipes'), +(22847, 1564001, 1564001, 2.4, 'Ashtongue Primalist - Phase 3 BoE Recipes'), +(22853, 1564001, 1564001, 2.4, 'Illidari Defiler - Phase 3 BoE Recipes'), +(22869, 1564001, 1564001, 2.4, 'Illidari Boneslicer - Phase 3 BoE Recipes'), +(22874, 1564001, 1564001, 2.4, 'Coilskar Harpooner - Phase 3 BoE Recipes'), +(22875, 1564001, 1564001, 2.4, 'Coilskar Sea-Caller - Phase 3 BoE Recipes'), +(22876, 1564001, 1564001, 2.4, 'Coilskar Soothsayer - Phase 3 BoE Recipes'), +(22877, 1564001, 1564001, 2.4, 'Coilskar Wrangler - Phase 3 BoE Recipes'), +(22879, 1564001, 1564001, 2.4, 'Shadowmoon Reaver - Phase 3 BoE Recipes'), +(22882, 1564001, 1564001, 2.4, 'Shadowmoon Deathshaper - Phase 3 BoE Recipes'), +(22959, 1564001, 1564001, 2.4, 'Spellbound Attendant - Phase 3 BoE Recipes'), +(23028, 1564001, 1564001, 2.4, 'Bonechewer Taskmaster - Phase 3 BoE Recipes'), +(23235, 1564001, 1564001, 2.4, 'Bonechewer Blade Fury - Phase 3 BoE Recipes'), +(23236, 1564001, 1564001, 2.4, 'Bonechewer Shield Disciple - Phase 3 BoE Recipes'), +(23237, 1564001, 1564001, 2.4, 'Bonechewer Blood Prophet - Phase 3 BoE Recipes'), +(23339, 1564001, 1564001, 2.4, 'Illidari Heartseeker - Phase 3 BoE Recipes'), +(23374, 1564001, 1564001, 2.4, 'Ashtongue Stalker - Phase 3 BoE Recipes'), +(23400, 1564001, 1564001, 2.4, 'Illidari Archon - Phase 3 BoE Recipes'), +(23402, 1564001, 1564001, 2.4, 'Illidari Battle-mage - Phase 3 BoE Recipes'), +(22960, 1564001, 1564001, 2.4, 'Dragonmaw Wyrmcaller - Phase 3 BoE Recipes'), +(23018, 1564001, 1564001, 2.4, 'Shadowmoon Houndmaster - Phase 3 BoE Recipes'), +(23030, 1564001, 1564001, 2.4, 'Dragonmaw Sky Stalker - Phase 3 BoE Recipes'), +(23172, 1564001, 1564001, 2.4, 'Hand of Gorefiend - Phase 3 BoE Recipes'), +(23330, 1564001, 1564001, 2.4, 'Dragonmaw Wind Reaver - Phase 3 BoE Recipes'), +(22873, 1564001, 1564001, 2.4, 'Coilskar General - Phase 3 BoE Recipes'), +(23337, 1564001, 1564001, 2.4, 'Illidari Centurion - Phase 3 BoE Recipes'), +(23397, 1564001, 1564001, 2.4, 'Illidari Blood Lord - Phase 3 BoE Recipes'), +(22844, 1564001, 1564001, 2.4, 'Ashtongue Battlelord - Phase 3 BoE Recipes'), +(22880, 1564001, 1564001, 2.4, 'Shadowmoon Champion - Phase 3 BoE Recipes'), +(22953, 1564001, 1564001, 2.4, 'Wrathbone Flayer - Phase 3 BoE Recipes'), +(22956, 1564001, 1564001, 2.4, 'Sister of Pain - Phase 3 BoE Recipes'), +(22964, 1564001, 1564001, 2.4, 'Sister of Pleasure - Phase 3 BoE Recipes'), +(23049, 1564001, 1564001, 2.4, 'Shadowmoon Weapon Master - Phase 3 BoE Recipes'), +(23222, 1564001, 1564001, 2.4, 'Bonechewer Brawler - Phase 3 BoE Recipes'), +(23239, 1564001, 1564001, 2.4, 'Bonechewer Combatant - Phase 3 BoE Recipes'), +(22855, 1564001, 1564001, 2.4, 'Illidari Nightlord - Phase 3 BoE Recipes'), +(22878, 1564001, 1564001, 2.4, 'Aqueous Lord - Phase 3 BoE Recipes'), +(22884, 1564001, 1564001, 2.4, 'Leviathan - Phase 3 BoE Recipes'), +(22954, 1564001, 1564001, 2.4, 'Illidari Fearbringer - Phase 3 BoE Recipes'), +(22957, 1564001, 1564001, 2.4, 'Priestess of Dementia - Phase 3 BoE Recipes'), +(22962, 1564001, 1564001, 2.4, 'Priestess of Delight - Phase 3 BoE Recipes'), +(23196, 1564001, 1564001, 2.4, 'Bonechewer Behemoth - Phase 3 BoE Recipes'), +(23394, 1564001, 1564001, 2.4, 'Promenade Sentinel - Phase 3 BoE Recipes'), +(17895, 1564001, 1564001, 2.4, 'Ghoul - Phase 3 BoE Recipes'), +(17897, 1564001, 1564001, 2.4, 'Crypt Fiend - Phase 3 BoE Recipes'), +(17898, 1564001, 1564001, 2.4, 'Abomination - Phase 3 BoE Recipes'), +(17899, 1564001, 1564001, 2.4, 'Shadowy Necromancer - Phase 3 BoE Recipes'), +(17905, 1564001, 1564001, 2.4, 'Banshee - Phase 3 BoE Recipes'), +(17906, 1564001, 1564001, 2.4, 'Gargoyle - Phase 3 BoE Recipes'), +(17907, 1564001, 1564001, 2.4, 'Frost Wyrm - Phase 3 BoE Recipes'), +(17908, 1564001, 1564001, 2.4, 'Giant Infernal - Phase 3 BoE Recipes'), +(17916, 1564001, 1564001, 2.4, 'Fel Stalker - Phase 3 BoE Recipes'); + +-- Sunwell Plateau +-- Epic BoE +DELETE FROM `reference_loot_template` WHERE (`Entry` = 1580000); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1580000, 34183, 0, 0, 0, 1, 1, 1, 1, 'Shivering Felspine'), +(1580000, 34346, 0, 0, 0, 1, 1, 1, 1, 'Mounting Vengeance'), +(1580000, 34347, 0, 0, 0, 1, 1, 1, 1, 'Wand of the Demonsoul'), +(1580000, 34348, 0, 0, 0, 1, 1, 1, 1, 'Wand of Cleansing Light'), +(1580000, 34349, 0, 0, 0, 1, 1, 1, 1, 'Blade of Life\'s Inevitability'), +(1580000, 34350, 0, 0, 0, 1, 1, 1, 1, 'Gauntlets of the Ancient Shadowmoon'), +(1580000, 34351, 0, 0, 0, 1, 1, 1, 1, 'Tranquil Majesty Wraps'), +(1580000, 35733, 0, 0, 0, 1, 1, 1, 1, 'Ring of Harmonic Beauty'); + +DELETE FROM `creature_loot_template` WHERE `Reference` = 34094 AND `Entry` IN (25867,25363,25367,25368,25369,25370,25371,25483,25484,25486,25506,25509,25591,25597,25837,25592,25593,25507,25595,25599); +DELETE FROM `creature_loot_template` WHERE `Item` IN (34183,34346,34347,34348,34349,34350,34351,35733) AND `Entry` IN (25867,25363,25367,25368,25369,25370,25371,25483,25484,25486,25506,25509,25591,25597,25837,25592,25593,25507,25595,25599); +DELETE FROM `creature_loot_template` WHERE `Reference` = 1580000 AND `Entry` IN (25867,25363,25367,25368,25369,25370,25371,25483,25484,25486,25506,25509,25591,25597,25837,25592,25593,25507,25595,25599); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(25867, 1580000, 1580000, 2, 'Sunblade Dragonhawk - Sunwell Plateau BoEs'), +-- (25363, 1580000, 1580000, 2, 'Sunblade Cabalist - Sunwell Plateau BoEs'), +-- (25367, 1580000, 1580000, 2, 'Sunblade Arch Mage - Sunwell Plateau BoEs'), +-- (25368, 1580000, 1580000, 2, 'Sunblade Slayer - Sunwell Plateau BoEs'), +-- (25369, 1580000, 1580000, 2, 'Sunblade Vindicator - Sunwell Plateau BoEs'), +-- (25370, 1580000, 1580000, 2, 'Sunblade Dusk Priest - Sunwell Plateau BoEs'), +-- (25371, 1580000, 1580000, 2, 'Sunblade Dawn Priest - Sunwell Plateau BoEs'), +-- (25483, 1580000, 1580000, 2, 'Shadowsword Manafiend - Sunwell Plateau BoEs'), +-- (25484, 1580000, 1580000, 2, 'Shadowsword Assassin - Sunwell Plateau BoEs'), +-- (25486, 1580000, 1580000, 2, 'Shadowsword Vanquisher - Sunwell Plateau BoEs'), +-- (25506, 1580000, 1580000, 2, 'Shadowsword Lifeshaper - Sunwell Plateau BoEs'), +-- (25509, 1580000, 1580000, 2, 'Priestess of Torment - Sunwell Plateau BoEs'), +-- (25591, 1580000, 1580000, 2, 'Painbringer - Sunwell Plateau BoEs'), +-- (25597, 1580000, 1580000, 2, 'Oblivion Mage - Sunwell Plateau BoEs'), +-- (25837, 1580000, 1580000, 2, 'Shadowsword Commander - Sunwell Plateau BoEs'), +-- (25592, 1580000, 1580000, 2, 'Doomfire Destroyer - Sunwell Plateau BoEs'), +(25593, 1580000, 1580000, 2, 'Apocalypse Guard - Sunwell Plateau BoEs'), +-- (25507, 1580000, 1580000, 2, 'Sunblade Protector - Sunwell Plateau BoEs'), +(25595, 1580000, 1580000, 2, 'Chaos Gazer - Sunwell Plateau BoEs'), +(25599, 1580000, 1580000, 2, 'Cataclysm Hound - Sunwell Plateau BoEs'); + +-- SWP Recipes +DELETE FROM `reference_loot_template` WHERE (`Entry` = 1580001); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1580001, 35186, 0, 0, 0, 1, 1, 1, 1, 'Schematic: Annihilator Holo-Gogs'), +(1580001, 35187, 0, 0, 0, 1, 1, 1, 1, 'Schematic: Justicebringer 3000 Specs'), +(1580001, 35189, 0, 0, 0, 1, 1, 1, 1, 'Schematic: Powerheal 9000 Lens'), +(1580001, 35190, 0, 0, 0, 1, 1, 1, 1, 'Schematic: Hyper-Magnified Moon'), +(1580001, 35191, 0, 0, 0, 1, 1, 1, 1, 'Schematic: Wonderheal XT68 Shades'), +(1580001, 35192, 0, 0, 0, 1, 1, 1, 1, 'Schematic: Primal-Attuned Goggles'), +(1580001, 35193, 0, 0, 0, 1, 1, 1, 1, 'Schematic: Lightning Etched Specs'), +(1580001, 35194, 0, 0, 0, 1, 1, 1, 1, 'Schematic: Surestrike Goggles v3.0'), +(1580001, 35195, 0, 0, 0, 1, 1, 1, 1, 'Schematic: Mayhem Projection Goggles'), +(1580001, 35196, 0, 0, 0, 1, 1, 1, 1, 'Schematic: Hard Khorium Goggles'), +(1580001, 35197, 0, 0, 0, 1, 1, 1, 1, 'Schematic: Quad Deathblow X44 Goggles'), +(1580001, 35201, 0, 0, 0, 1, 1, 1, 1, 'Design: Pendant of Sunfire'), +(1580001, 35202, 0, 0, 0, 1, 1, 1, 1, 'Design: Amulet of Flowing Life'), +(1580001, 35203, 0, 0, 0, 1, 1, 1, 1, 'Design: Hard Khorium Choker'), +(1580001, 35206, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Sunfire Robe'), +(1580001, 35207, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Robe of Eternal Light'), +(1580001, 35210, 0, 0, 0, 1, 1, 1, 1, 'Plans: Sunblessed Breastplate'), +(1580001, 35211, 0, 0, 0, 1, 1, 1, 1, 'Plans: Hard Khorium Battleplate'), +(1580001, 35216, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Leather Chestguard of the Sun'), +(1580001, 35217, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Embrace of the Phoenix'), +(1580001, 35218, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Carapace of Sun and Shadow'), +(1580001, 35219, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Sun-Drenched Scale Chestguard'), +(1580001, 35198, 0, 0, 0, 1, 1, 1, 1, 'Design: Loop of Forged Power'), +(1580001, 35199, 0, 0, 0, 1, 1, 1, 1, 'Design: Ring of Flowing Life'), +(1580001, 35200, 0, 0, 0, 1, 1, 1, 1, 'Design: Hard Khorium Band'), +(1580001, 35204, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Sunfire Handwraps'), +(1580001, 35205, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Hands of Eternal Light'), +(1580001, 35208, 0, 0, 0, 1, 1, 1, 1, 'Plans: Sunblessed Gauntlets'), +(1580001, 35209, 0, 0, 0, 1, 1, 1, 1, 'Plans: Hard Khorium Battlefists'), +(1580001, 35212, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Leather Gauntlets of the Sun'), +(1580001, 35213, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Fletcher\'s Gloves of the Phoenix'), +(1580001, 35214, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Gloves of Immortal Dusk'), +(1580001, 35215, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Sun-Drenched Scale Gloves'), +(1580001, 35273, 0, 0, 0, 1, 1, 1, 1, 'Study of Advanced Smelting'); + +DELETE FROM `creature_loot_template` WHERE `Reference` = 34091 AND `Entry` IN (25867,25363,25367,25368,25369,25370,25371,25483,25484,25486,25506,25509,25591,25597,25837,25592,25593,25507,25595,25599); +DELETE FROM `creature_loot_template` WHERE `Item` IN (35186,35187,35189,35190,35191,35192,35193,35194,35195,35196,35197,35201,35202,35203,35206,35207,35210,35211,35216,35217,35218,35219,35198,35199,35200,35204,35205,35208,35209,35212,35213,35214,35215,35273) AND `Entry` IN (25867,25363,25367,25368,25369,25370,25371,25483,25484,25486,25506,25509,25591,25597,25837,25592,25593,25507,25595,25599); +DELETE FROM `creature_loot_template` WHERE `Reference` = 1580001 AND `Entry` IN (25867,25363,25367,25368,25369,25370,25371,25483,25484,25486,25506,25509,25591,25597,25837,25592,25593,25507,25595,25599); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(25867, 1580001, 1580001, 1, 'Sunblade Dragonhawk - Sunwell Plateau Recipes'), +-- (25363, 1580001, 1580001, 1, 'Sunblade Cabalist - Sunwell Plateau Recipes'), +-- (25367, 1580001, 1580001, 1, 'Sunblade Arch Mage - Sunwell Plateau Recipes'), +-- (25368, 1580001, 1580001, 1, 'Sunblade Slayer - Sunwell Plateau Recipes'), +-- (25369, 1580001, 1580001, 1, 'Sunblade Vindicator - Sunwell Plateau Recipes'), +-- (25370, 1580001, 1580001, 1, 'Sunblade Dusk Priest - Sunwell Plateau Recipes'), +-- (25371, 1580001, 1580001, 1, 'Sunblade Dawn Priest - Sunwell Plateau Recipes'), +-- (25483, 1580001, 1580001, 1, 'Shadowsword Manafiend - Sunwell Plateau Recipes'), +-- (25484, 1580001, 1580001, 1, 'Shadowsword Assassin - Sunwell Plateau Recipes'), +-- (25486, 1580001, 1580001, 1, 'Shadowsword Vanquisher - Sunwell Plateau Recipes'), +-- (25506, 1580001, 1580001, 1, 'Shadowsword Lifeshaper - Sunwell Plateau Recipes'), +-- (25509, 1580001, 1580001, 1, 'Priestess of Torment - Sunwell Plateau Recipes'), +-- (25591, 1580001, 1580001, 1, 'Painbringer - Sunwell Plateau Recipes'), +-- (25597, 1580001, 1580001, 1, 'Oblivion Mage - Sunwell Plateau Recipes'), +-- (25837, 1580001, 1580001, 1, 'Shadowsword Commander - Sunwell Plateau Recipes'), +-- (25592, 1580001, 1580001, 1, 'Doomfire Destroyer - Sunwell Plateau Recipes'), +(25593, 1580001, 1580001, 1, 'Apocalypse Guard - Sunwell Plateau Recipes'), +-- (25507, 1580001, 1580001, 1, 'Sunblade Protector - Sunwell Plateau Recipes'), +(25595, 1580001, 1580001, 1, 'Chaos Gazer - Sunwell Plateau Recipes'), +(25599, 1580001, 1580001, 1, 'Cataclysm Hound - Sunwell Plateau Recipes'); + +DELETE FROM `creature_loot_template` WHERE `Item` = 35273 AND `Entry` IN (25867,25363,25367,25368,25369,25370,25371,25483,25484,25486,25506,25509,25591,25597,25837,25592,25593,25507,25595,25599); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(25867, 35273, 0, 1, 'Sunblade Dragonhawk - Study of Advanced Smelting'), +-- (25363, 35273, 0, 1, 'Sunblade Cabalist - Study of Advanced Smelting'), +-- (25367, 35273, 0, 1, 'Sunblade Arch Mage - Study of Advanced Smelting'), +-- (25368, 35273, 0, 1, 'Sunblade Slayer - Study of Advanced Smelting'), +-- (25369, 35273, 0, 1, 'Sunblade Vindicator - Study of Advanced Smelting'), +-- (25370, 35273, 0, 1, 'Sunblade Dusk Priest - Study of Advanced Smelting'), +-- (25371, 35273, 0, 1, 'Sunblade Dawn Priest - Study of Advanced Smelting'), +-- (25483, 35273, 0, 1, 'Shadowsword Manafiend - Study of Advanced Smelting'), +-- (25484, 35273, 0, 1, 'Shadowsword Assassin - Study of Advanced Smelting'), +-- (25486, 35273, 0, 1, 'Shadowsword Vanquisher - Study of Advanced Smelting'), +-- (25506, 35273, 0, 1, 'Shadowsword Lifeshaper - Study of Advanced Smelting'), +-- (25509, 35273, 0, 1, 'Priestess of Torment - Study of Advanced Smelting'), +-- (25591, 35273, 0, 1, 'Painbringer - Study of Advanced Smelting'), +-- (25597, 35273, 0, 1, 'Oblivion Mage - Study of Advanced Smelting'), +-- (25837, 35273, 0, 1, 'Shadowsword Commander - Study of Advanced Smelting'), +-- (25592, 35273, 0, 1, 'Doomfire Destroyer - Study of Advanced Smelting'), +(25593, 35273, 0, 1, 'Apocalypse Guard - Study of Advanced Smelting'), +-- (25507, 35273, 0, 1, 'Sunblade Protector - Study of Advanced Smelting'), +(25595, 35273, 0, 1, 'Chaos Gazer - Study of Advanced Smelting'), +(25599, 35273, 0, 1, 'Cataclysm Hound - Study of Advanced Smelting'); + +-- BT + SWP Gems +DELETE FROM `reference_loot_template` WHERE (`Entry` = 1564002); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1564002, 32227, 0, 0, 0, 1, 1, 1, 1, 'Crimson Spinel'), +(1564002, 32228, 0, 0, 0, 1, 1, 1, 1, 'Empyrean Sapphire'), +(1564002, 32229, 0, 0, 0, 1, 1, 1, 1, 'Lionseye'), +(1564002, 32230, 0, 0, 0, 1, 1, 1, 1, 'Shadowsong Amethyst'), +(1564002, 32231, 0, 0, 0, 1, 1, 1, 1, 'Pyrestone'), +(1564002, 32249, 0, 0, 0, 1, 1, 1, 1, 'Seaspray Emerald'); + +DELETE FROM `creature_loot_template` WHERE `Reference` IN (10005, 12903, 34093) AND `Entry` IN (22939,22955,22963,23147,23223,23047,22946,22848,22849,22881,22885,23232,22945,22965,23403,22845,22846,22847,22853,22869,22874,22875,22876,22877,22879,22882,22959,23028,23235,23236,23237,23339,23374,23400,23402,22960,23018,23030,23172,23330,22873,23337,23397,22844,22880,22953,22956,22964,23049,23222,23239,22855,22878,22884,22954,22957,22962,23196,23394,25867,25363,25367,25368,25369,25370,25371,25483,25484,25486,25506,25509,25591,25597,25837,25592,25593,25507,25595,25599); +DELETE FROM `creature_loot_template` WHERE `Item` IN (32227,32228,32229,32230,32231,32249) AND `Entry` IN (22939,22955,22963,23147,23223,23047,22946,22848,22849,22881,22885,23232,22945,22965,23403,22845,22846,22847,22853,22869,22874,22875,22876,22877,22879,22882,22959,23028,23235,23236,23237,23339,23374,23400,23402,22960,23018,23030,23172,23330,22873,23337,23397,22844,22880,22953,22956,22964,23049,23222,23239,22855,22878,22884,22954,22957,22962,23196,23394,25867,25363,25367,25368,25369,25370,25371,25483,25484,25486,25506,25509,25591,25597,25837,25592,25593,25507,25595,25599); +DELETE FROM `creature_loot_template` WHERE `Reference` = 1564002 AND `Entry` IN (22939,22955,22963,23147,23223,23047,22946,22848,22849,22881,22885,23232,22945,22965,23403,22845,22846,22847,22853,22869,22874,22875,22876,22877,22879,22882,22959,23028,23235,23236,23237,23339,23374,23400,23402,22960,23018,23030,23172,23330,22873,23337,23397,22844,22880,22953,22956,22964,23049,23222,23239,22855,22878,22884,22954,22957,22962,23196,23394,25867,25363,25367,25368,25369,25370,25371,25483,25484,25486,25506,25509,25591,25597,25837,25592,25593,25507,25595,25599); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(22939, 1564002, 1564002, 3, 'Temple Concubine - TBC Epic Gems'), +(22955, 1564002, 1564002, 3, 'Charming Courtesan - TBC Epic Gems'), +(22963, 1564002, 1564002, 3, 'Bonechewer Worker - TBC Epic Gems'), +(23147, 1564002, 1564002, 3, 'Shadowmoon Grunt - TBC Epic Gems'), +(23223, 1564002, 1564002, 3, 'Bonechewer Spectator - TBC Epic Gems'), +(23047, 1564002, 1564002, 3, 'Shadowmoon Soldier - TBC Epic Gems'), +(22946, 1564002, 1564002, 3, 'Shadowmoon War Hound - TBC Epic Gems'), +(22848, 1564002, 1564002, 3, 'Storm Fury - TBC Epic Gems'), +(22849, 1564002, 1564002, 3, 'Ashtongue Feral Spirit - TBC Epic Gems'), +(22881, 1564002, 1564002, 3, 'Aqueous Surger - TBC Epic Gems'), +(22885, 1564002, 1564002, 3, 'Dragon Turtle - TBC Epic Gems'), +(23232, 1564002, 1564002, 3, 'Mutant War Hound - TBC Epic Gems'), +(22945, 1564002, 1564002, 12, 'Shadowmoon Blood Mage - TBC Epic Gems'), +(22965, 1564002, 1564002, 3, 'Enslaved Servant - TBC Epic Gems'), +(23403, 1564002, 1564002, 12, 'Illidari Assassin - TBC Epic Gems'), +(22845, 1564002, 1564002, 12, 'Ashtongue Mystic - TBC Epic Gems'), +(22846, 1564002, 1564002, 12, 'Ashtongue Stormcaller - TBC Epic Gems'), +(22847, 1564002, 1564002, 12, 'Ashtongue Primalist - TBC Epic Gems'), +(22853, 1564002, 1564002, 12, 'Illidari Defiler - TBC Epic Gems'), +(22869, 1564002, 1564002, 12, 'Illidari Boneslicer - TBC Epic Gems'), +(22874, 1564002, 1564002, 12, 'Coilskar Harpooner - TBC Epic Gems'), +(22875, 1564002, 1564002, 12, 'Coilskar Sea-Caller - TBC Epic Gems'), +(22876, 1564002, 1564002, 12, 'Coilskar Soothsayer - TBC Epic Gems'), +(22877, 1564002, 1564002, 12, 'Coilskar Wrangler - TBC Epic Gems'), +(22879, 1564002, 1564002, 12, 'Shadowmoon Reaver - TBC Epic Gems'), +(22882, 1564002, 1564002, 12, 'Shadowmoon Deathshaper - TBC Epic Gems'), +(22959, 1564002, 1564002, 12, 'Spellbound Attendant - TBC Epic Gems'), +(23028, 1564002, 1564002, 12, 'Bonechewer Taskmaster - TBC Epic Gems'), +(23235, 1564002, 1564002, 12, 'Bonechewer Blade Fury - TBC Epic Gems'), +(23236, 1564002, 1564002, 12, 'Bonechewer Shield Disciple - TBC Epic Gems'), +(23237, 1564002, 1564002, 12, 'Bonechewer Blood Prophet - TBC Epic Gems'), +(23339, 1564002, 1564002, 12, 'Illidari Heartseeker - TBC Epic Gems'), +(23374, 1564002, 1564002, 12, 'Ashtongue Stalker - TBC Epic Gems'), +(23400, 1564002, 1564002, 12, 'Illidari Archon - TBC Epic Gems'), +(23402, 1564002, 1564002, 12, 'Illidari Battle-mage - TBC Epic Gems'), +(22960, 1564002, 1564002, 12, 'Dragonmaw Wyrmcaller - TBC Epic Gems'), +(23018, 1564002, 1564002, 12, 'Shadowmoon Houndmaster - TBC Epic Gems'), +(23030, 1564002, 1564002, 12, 'Dragonmaw Sky Stalker - TBC Epic Gems'), +(23172, 1564002, 1564002, 12, 'Hand of Gorefiend - TBC Epic Gems'), +(23330, 1564002, 1564002, 12, 'Dragonmaw Wind Reaver - TBC Epic Gems'), +(22873, 1564002, 1564002, 12, 'Coilskar General - TBC Epic Gems'), +(23337, 1564002, 1564002, 12, 'Illidari Centurion - TBC Epic Gems'), +(23397, 1564002, 1564002, 12, 'Illidari Blood Lord - TBC Epic Gems'), +(22844, 1564002, 1564002, 12, 'Ashtongue Battlelord - TBC Epic Gems'), +(22880, 1564002, 1564002, 12, 'Shadowmoon Champion - TBC Epic Gems'), +(22953, 1564002, 1564002, 12, 'Wrathbone Flayer - TBC Epic Gems'), +(22956, 1564002, 1564002, 12, 'Sister of Pain - TBC Epic Gems'), +(22964, 1564002, 1564002, 12, 'Sister of Pleasure - TBC Epic Gems'), +(23049, 1564002, 1564002, 12, 'Shadowmoon Weapon Master - TBC Epic Gems'), +(23222, 1564002, 1564002, 12, 'Bonechewer Brawler - TBC Epic Gems'), +(23239, 1564002, 1564002, 12, 'Bonechewer Combatant - TBC Epic Gems'), +(22855, 1564002, 1564002, 12, 'Illidari Nightlord - TBC Epic Gems'), +(22878, 1564002, 1564002, 12, 'Aqueous Lord - TBC Epic Gems'), +(22884, 1564002, 1564002, 12, 'Leviathan - TBC Epic Gems'), +(22954, 1564002, 1564002, 12, 'Illidari Fearbringer - TBC Epic Gems'), +(22957, 1564002, 1564002, 12, 'Priestess of Dementia - TBC Epic Gems'), +(22962, 1564002, 1564002, 12, 'Priestess of Delight - TBC Epic Gems'), +(23196, 1564002, 1564002, 12, 'Bonechewer Behemoth - TBC Epic Gems'), +(23394, 1564002, 1564002, 12, 'Promenade Sentinel - TBC Epic Gems'), +(25867, 1564002, 1564002, 12, 'Sunblade Dragonhawk - TBC Epic Gems'), +-- (25363, 1564002, 1564002, 12, 'Sunblade Cabalist - TBC Epic Gems'), +-- (25367, 1564002, 1564002, 12, 'Sunblade Arch Mage - TBC Epic Gems'), +-- (25368, 1564002, 1564002, 12, 'Sunblade Slayer - TBC Epic Gems'), +-- (25369, 1564002, 1564002, 12, 'Sunblade Vindicator - TBC Epic Gems'), +-- (25370, 1564002, 1564002, 12, 'Sunblade Dusk Priest - TBC Epic Gems'), +-- (25371, 1564002, 1564002, 12, 'Sunblade Dawn Priest - TBC Epic Gems'), +-- (25483, 1564002, 1564002, 12, 'Shadowsword Manafiend - TBC Epic Gems'), +-- (25484, 1564002, 1564002, 12, 'Shadowsword Assassin - TBC Epic Gems'), +-- (25486, 1564002, 1564002, 12, 'Shadowsword Vanquisher - TBC Epic Gems'), +-- (25506, 1564002, 1564002, 12, 'Shadowsword Lifeshaper - TBC Epic Gems'), +-- (25509, 1564002, 1564002, 12, 'Priestess of Torment - TBC Epic Gems'), +-- (25591, 1564002, 1564002, 12, 'Painbringer - TBC Epic Gems'), +-- (25597, 1564002, 1564002, 12, 'Oblivion Mage - TBC Epic Gems'), +-- (25837, 1564002, 1564002, 12, 'Shadowsword Commander - TBC Epic Gems'), +-- (25592, 1564002, 1564002, 12, 'Doomfire Destroyer - TBC Epic Gems'), +(25593, 1564002, 1564002, 12, 'Apocalypse Guard - TBC Epic Gems'), +-- (25507, 1564002, 1564002, 12, 'Sunblade Protector - TBC Epic Gems'), +(25595, 1564002, 1564002, 12, 'Chaos Gazer - TBC Epic Gems'), +(25599, 1564002, 1564002, 12, 'Cataclysm Hound - TBC Epic Gems'); + +DELETE FROM `reference_loot_template` WHERE `Entry` IN (14099, 34091, 34093, 34094, 39534, 55500); +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 1 AND `ConditionTypeOrReference` = 7 AND `SourceEntry` IN (30280,30281,30282,30283,30301,30302,30303,30304,30305,30306,30307,30308,30321,30322,30323,30324,32736,32738,32744,32746,32748,32750,32752,32754); +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 10 AND `SourceGroup` = 34091; From 9bf77e86604a0cf0342370393e72cba4adc6b256 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 2 Feb 2026 01:29:31 +0000 Subject: [PATCH 021/335] chore(DB): import pending files Referenced commit(s): 261afd8854a66bdb1a0ffe978c7de5c38504e3ee --- .../rev_1769967751468801600.sql => db_world/2026_02_02_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1769967751468801600.sql => db_world/2026_02_02_00.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1769967751468801600.sql b/data/sql/updates/db_world/2026_02_02_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1769967751468801600.sql rename to data/sql/updates/db_world/2026_02_02_00.sql index 3b33b7297..5b3627257 100644 --- a/data/sql/updates/pending_db_world/rev_1769967751468801600.sql +++ b/data/sql/updates/db_world/2026_02_02_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_01_02 -> 2026_02_02_00 -- Karazhan: Chances increase as you go up the tower from ~0.4% to ~1% DELETE FROM `reference_loot_template` WHERE (`Entry` = 1532000); INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES From 3f4c5d0e9ad4279c81b5309ead0ce2e96a6db90c Mon Sep 17 00:00:00 2001 From: sudlud Date: Mon, 2 Feb 2026 10:43:57 +0100 Subject: [PATCH 022/335] fix(DB/Gameobject): Sniffed Values for 'Broken Cart' spawns (#24587) --- .../sql/updates/pending_db_world/rev_1770019001799459700.sql | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770019001799459700.sql diff --git a/data/sql/updates/pending_db_world/rev_1770019001799459700.sql b/data/sql/updates/pending_db_world/rev_1770019001799459700.sql new file mode 100644 index 000000000..45d6bca57 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770019001799459700.sql @@ -0,0 +1,5 @@ +-- Update gameobject 'Broken Cart' with sniffed values +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (186807)) AND (`guid` IN (171)); +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 +(171, 186807, 1, 0, 0, 1, 1, 828.43792724609375, -4508.498046875, 6.702891826629638671, 3.94444584846496582, 0, 0, -0.92050457000732421, 0.3907318115234375, 120, 255, 1, "", 45613, NULL); From 54445357a7a93d6de17a4c4535a9b9a50ad94775 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 2 Feb 2026 09:45:03 +0000 Subject: [PATCH 023/335] chore(DB): import pending files Referenced commit(s): 3f4c5d0e9ad4279c81b5309ead0ce2e96a6db90c --- .../rev_1770019001799459700.sql => db_world/2026_02_02_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1770019001799459700.sql => db_world/2026_02_02_01.sql} (93%) diff --git a/data/sql/updates/pending_db_world/rev_1770019001799459700.sql b/data/sql/updates/db_world/2026_02_02_01.sql similarity index 93% rename from data/sql/updates/pending_db_world/rev_1770019001799459700.sql rename to data/sql/updates/db_world/2026_02_02_01.sql index 45d6bca57..1e7682890 100644 --- a/data/sql/updates/pending_db_world/rev_1770019001799459700.sql +++ b/data/sql/updates/db_world/2026_02_02_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_02_00 -> 2026_02_02_01 -- Update gameobject 'Broken Cart' with sniffed values -- new spawns DELETE FROM `gameobject` WHERE (`id` IN (186807)) AND (`guid` IN (171)); From 3d9e58b3d6fbfedf618f7c215c6b865030f954dc Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 3 Feb 2026 06:29:31 -0300 Subject: [PATCH 024/335] chore(Core/Handlers): Clear debug leftovers (#24603) --- src/server/game/Handlers/BankHandler.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/server/game/Handlers/BankHandler.cpp b/src/server/game/Handlers/BankHandler.cpp index 313872719..2aa6a8ae9 100644 --- a/src/server/game/Handlers/BankHandler.cpp +++ b/src/server/game/Handlers/BankHandler.cpp @@ -156,8 +156,6 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPackets::Bank::BuyBankSlot& buyB // next slot ++slot; - LOG_INFO("network", "PLAYER: Buy bank bag slot, slot number = {}", slot); - BankBagSlotPricesEntry const* slotEntry = sBankBagSlotPricesStore.LookupEntry(slot); if (!slotEntry) From 14ebaae275aae61b2fab8c4da056d23058804a9e Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Tue, 3 Feb 2026 11:26:50 -0600 Subject: [PATCH 025/335] fix(Core/GameObject): Use quaternion rotation directly instead of orientation hackfix (#24602) Co-authored-by: blinkysc Co-authored-by: zergtmn --- .../rev_1770075577120661993.sql | 6 +++ .../rev_1770127062954420379.sql | 5 ++ .../game/Entities/GameObject/GameObject.cpp | 46 ++++++------------- .../game/Entities/GameObject/GameObjectData.h | 14 ++++++ src/server/game/Globals/ObjectMgr.cpp | 15 ++++-- 5 files changed, 51 insertions(+), 35 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1770075577120661993.sql create mode 100644 data/sql/updates/pending_db_world/rev_1770127062954420379.sql diff --git a/data/sql/updates/pending_db_world/rev_1770075577120661993.sql b/data/sql/updates/pending_db_world/rev_1770075577120661993.sql new file mode 100644 index 000000000..0a9e9b7d3 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770075577120661993.sql @@ -0,0 +1,6 @@ +-- Add parent rotation columns to gameobject_addon table for transport rotation support +ALTER TABLE `gameobject_addon` + ADD COLUMN `parent_rotation0` FLOAT NOT NULL DEFAULT 0 AFTER `guid`, + ADD COLUMN `parent_rotation1` FLOAT NOT NULL DEFAULT 0 AFTER `parent_rotation0`, + ADD COLUMN `parent_rotation2` FLOAT NOT NULL DEFAULT 0 AFTER `parent_rotation1`, + ADD COLUMN `parent_rotation3` FLOAT NOT NULL DEFAULT 1 AFTER `parent_rotation2`; diff --git a/data/sql/updates/pending_db_world/rev_1770127062954420379.sql b/data/sql/updates/pending_db_world/rev_1770127062954420379.sql new file mode 100644 index 000000000..86b77b06e --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770127062954420379.sql @@ -0,0 +1,5 @@ +-- DB/Gameobject: Update "Dangerous!" sign with sniffed values +-- Closes https://github.com/azerothcore/azerothcore-wotlk/issues/16834 +DELETE FROM `gameobject` WHERE `guid` = 17154 AND `id` = 2008; +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 +(17154, 2008, 0, 267, 272, 1, 1, -19.4826393127441406, -935.3038330078125, 58.09708786010742187, 2.65289926528930664, -0.04655265808105468, 0.011606216430664062, 0.969178199768066406, 0.241643846035003662, 120, 255, 1, 42328); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index aa07590f6..d093eb4a1 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -38,6 +38,11 @@ #include #include +bool QuaternionData::IsUnit() const +{ + return fabs(x * x + y * y + z * z + w * w - 1.0f) < 1e-5f; +} + GameObject::GameObject() : WorldObject(), MovableMapObject(), m_model(nullptr), m_goValue(), m_AI(nullptr) { @@ -293,35 +298,14 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u return false; } - GameObjectAddon const* addon = sObjectMgr->GetGameObjectAddon(GetSpawnId()); + SetLocalRotation(rotation); - // hackfix for the hackfix down below - switch (goinfo->entry) - { - // excluded ids from the hackfix below - // used switch since there should be more - case 181233: // maexxna portal effect - case 181575: // maexxna portal - case 20992: // theramore black shield - case 21042: // theramore guard badge - SetLocalRotation(rotation); - break; - default: - // xinef: hackfix - but make it possible to use original WorldRotation (using special gameobject addon data) - // pussywizard: temporarily calculate WorldRotation from orientation, do so until values in db are correct - if (addon && addon->invisibilityType == INVISIBILITY_GENERAL && addon->InvisibilityValue == 0) - { - SetLocalRotation(rotation); - } - else - { - SetLocalRotationAngles(NormalizeOrientation(GetOrientation()), 0.0f, 0.0f); - } - break; - } + GameObjectAddon const* gameObjectAddon = sObjectMgr->GetGameObjectAddon(GetSpawnId()); + QuaternionData parentRotation; + if (gameObjectAddon) + parentRotation = gameObjectAddon->ParentRotation; - // pussywizard: no PathRotation for normal gameobjects - SetTransportPathRotation(0.0f, 0.0f, 0.0f, 1.0f); + SetTransportPathRotation(parentRotation.x, parentRotation.y, parentRotation.z, parentRotation.w); SetObjectScale(goinfo->size); @@ -403,12 +387,12 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u break; } - if (addon) + if (gameObjectAddon) { - if (addon->InvisibilityValue) + if (gameObjectAddon->InvisibilityValue) { - m_invisibility.AddFlag(addon->invisibilityType); - m_invisibility.AddValue(addon->invisibilityType, addon->InvisibilityValue); + m_invisibility.AddFlag(gameObjectAddon->invisibilityType); + m_invisibility.AddValue(gameObjectAddon->invisibilityType, gameObjectAddon->InvisibilityValue); } } diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h index 7615dbbbe..eafe70a9d 100644 --- a/src/server/game/Entities/GameObject/GameObjectData.h +++ b/src/server/game/Entities/GameObject/GameObjectData.h @@ -678,9 +678,23 @@ struct GameObjectLocale std::vector CastBarCaption; }; +struct AC_GAME_API QuaternionData +{ + float x; + float y; + float z; + float w; + + QuaternionData() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) { } + QuaternionData(float X, float Y, float Z, float W) : x(X), y(Y), z(Z), w(W) { } + + [[nodiscard]] bool IsUnit() const; +}; + // `gameobject_addon` table struct GameObjectAddon { + QuaternionData ParentRotation; InvisibilityType invisibilityType; uint32 InvisibilityValue; }; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 175bdd7c2..977d5436d 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1355,8 +1355,8 @@ void ObjectMgr::LoadGameObjectAddons() { uint32 oldMSTime = getMSTime(); - // 0 1 2 - QueryResult result = WorldDatabase.Query("SELECT guid, invisibilityType, invisibilityValue FROM gameobject_addon"); + // 0 1 2 3 4 5 6 + QueryResult result = WorldDatabase.Query("SELECT guid, parent_rotation0, parent_rotation1, parent_rotation2, parent_rotation3, invisibilityType, invisibilityValue FROM gameobject_addon"); if (!result) { @@ -1380,8 +1380,9 @@ void ObjectMgr::LoadGameObjectAddons() } GameObjectAddon& gameObjectAddon = _gameObjectAddonStore[guid]; - gameObjectAddon.invisibilityType = InvisibilityType(fields[1].Get()); - gameObjectAddon.InvisibilityValue = fields[2].Get(); + gameObjectAddon.ParentRotation = QuaternionData(fields[1].Get(), fields[2].Get(), fields[3].Get(), fields[4].Get()); + gameObjectAddon.invisibilityType = InvisibilityType(fields[5].Get()); + gameObjectAddon.InvisibilityValue = fields[6].Get(); if (gameObjectAddon.invisibilityType >= TOTAL_INVISIBILITY_TYPES) { @@ -1396,6 +1397,12 @@ void ObjectMgr::LoadGameObjectAddons() gameObjectAddon.InvisibilityValue = 1; } + if (!gameObjectAddon.ParentRotation.IsUnit()) + { + LOG_ERROR("sql.sql", "GameObject (GUID: {}) has invalid parent rotation in `gameobject_addon`, set to default", guid); + gameObjectAddon.ParentRotation = QuaternionData(); + } + ++count; } while (result->NextRow()); From 871163b1cc22d246b4f6bec09a31116e1a0e5dcf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 3 Feb 2026 17:27:56 +0000 Subject: [PATCH 026/335] chore(DB): import pending files Referenced commit(s): 14ebaae275aae61b2fab8c4da056d23058804a9e --- .../rev_1770075577120661993.sql => db_world/2026_02_03_00.sql} | 1 + .../rev_1770127062954420379.sql => db_world/2026_02_03_01.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1770075577120661993.sql => db_world/2026_02_03_00.sql} (90%) rename data/sql/updates/{pending_db_world/rev_1770127062954420379.sql => db_world/2026_02_03_01.sql} (94%) diff --git a/data/sql/updates/pending_db_world/rev_1770075577120661993.sql b/data/sql/updates/db_world/2026_02_03_00.sql similarity index 90% rename from data/sql/updates/pending_db_world/rev_1770075577120661993.sql rename to data/sql/updates/db_world/2026_02_03_00.sql index 0a9e9b7d3..ee034f9d0 100644 --- a/data/sql/updates/pending_db_world/rev_1770075577120661993.sql +++ b/data/sql/updates/db_world/2026_02_03_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_02_01 -> 2026_02_03_00 -- Add parent rotation columns to gameobject_addon table for transport rotation support ALTER TABLE `gameobject_addon` ADD COLUMN `parent_rotation0` FLOAT NOT NULL DEFAULT 0 AFTER `guid`, diff --git a/data/sql/updates/pending_db_world/rev_1770127062954420379.sql b/data/sql/updates/db_world/2026_02_03_01.sql similarity index 94% rename from data/sql/updates/pending_db_world/rev_1770127062954420379.sql rename to data/sql/updates/db_world/2026_02_03_01.sql index 86b77b06e..88975bda2 100644 --- a/data/sql/updates/pending_db_world/rev_1770127062954420379.sql +++ b/data/sql/updates/db_world/2026_02_03_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_03_00 -> 2026_02_03_01 -- DB/Gameobject: Update "Dangerous!" sign with sniffed values -- Closes https://github.com/azerothcore/azerothcore-wotlk/issues/16834 DELETE FROM `gameobject` WHERE `guid` = 17154 AND `id` = 2008; From 0efc2b3179f010853f5aa2f67600e7fd87cf7962 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Tue, 3 Feb 2026 20:30:11 -0300 Subject: [PATCH 027/335] fix(Core/Unit): Ignore Armor Calculation for spells with SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS (#24592) --- src/server/game/Entities/Unit/Unit.cpp | 2 +- src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f87548d18..f37d493ec 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1345,7 +1345,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama } int32 cleanDamage = 0; - if (Unit::IsDamageReducedByArmor(damageSchoolMask, spellInfo)) + if (!spellInfo->HasAttribute(SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS) && Unit::IsDamageReducedByArmor(damageSchoolMask, spellInfo)) { int32 oldDamage = damage; damage = Unit::CalcArmorReducedDamage(this, victim, damage, spellInfo, 0, attackType); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp index 7076ab750..c57bc427e 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp @@ -256,7 +256,7 @@ class spell_gluth_decimate : public SpellScript return; } - GetCaster()->CastSpell(unitTarget, SPELL_DECIMATE_DAMAGE); + GetCaster()->CastSpell(unitTarget, SPELL_DECIMATE_DAMAGE, true); } } @@ -271,7 +271,7 @@ class spell_gluth_decimate_damage : public SpellScript { PrepareSpellScript(spell_gluth_decimate_damage) - void RecalculateDamage() + void HandleDamage(SpellEffIndex /*effIndex*/) { Unit* target = GetHitUnit(); if (!target) @@ -291,7 +291,7 @@ class spell_gluth_decimate_damage : public SpellScript void Register() override { - OnHit += SpellHitFn(spell_gluth_decimate_damage::RecalculateDamage); + OnEffectHitTarget += SpellEffectFn(spell_gluth_decimate_damage::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); } }; From 5e8555210893232d23db1e72ce4b5e6a30b7c6ac Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Tue, 3 Feb 2026 21:19:11 -0300 Subject: [PATCH 028/335] fix(DB/SAI): Astromancer Lord should use Domination like Star Scryer (#24593) --- .../updates/pending_db_world/rev_1770048466853054600.sql | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770048466853054600.sql diff --git a/data/sql/updates/pending_db_world/rev_1770048466853054600.sql b/data/sql/updates/pending_db_world/rev_1770048466853054600.sql new file mode 100644 index 000000000..6a08746aa --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770048466853054600.sql @@ -0,0 +1,8 @@ +-- +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 20046); +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 +(20046, 0, 0, 0, 0, 0, 100, 0, 1000, 3000, 5500, 7500, 0, 0, 11, 37110, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Astromancer Lord - In Combat - Cast \'Fire Blast\''), +(20046, 0, 1, 0, 0, 0, 100, 0, 4000, 8000, 15000, 17000, 0, 0, 11, 37289, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Astromancer Lord - In Combat - Cast \'Dragon\'s Breath\''), +(20046, 0, 2, 0, 0, 0, 100, 0, 15000, 16000, 15000, 24000, 0, 0, 11, 37109, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Astromancer Lord - In Combat - Cast \'Fireball Volley\''), +(20046, 0, 3, 0, 0, 0, 100, 1, 0, 1000, 0, 0, 0, 0, 11, 38732, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Astromancer Lord - In Combat - Cast \'Fire Shield\' (No Repeat)'), +(20046, 0, 4, 0, 0, 0, 100, 0, 9700, 19800, 10900, 23800, 0, 0, 11, 37122, 32, 0, 0, 0, 0, 6, 20, 1, 0, 37122, 0, 0, 0, 0, 'Astromancer Lord - In Combat - Cast \'Domination\''); From 606a40e09ceb024caa903c5101ca11bd36bf73d6 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Tue, 3 Feb 2026 21:19:27 -0300 Subject: [PATCH 029/335] fix(DB/SAI): Implement Unstable Shroom Script (#24601) --- .../rev_1770072989817102600.sql | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770072989817102600.sql diff --git a/data/sql/updates/pending_db_world/rev_1770072989817102600.sql b/data/sql/updates/pending_db_world/rev_1770072989817102600.sql new file mode 100644 index 000000000..3cf74d8ce --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770072989817102600.sql @@ -0,0 +1,36 @@ +-- +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 19734); +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 +(19734, 0, 0, 1, 0, 0, 100, 1, 8000, 12000, 0, 0, 0, 0, 11, 35256, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Fungal Giant - In Combat - Cast \'Serverside - Summon Unstable Mushroom\' (No Repeat)'), +(19734, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Fungal Giant - In Combat - Say Line 0 (No Repeat)'); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 19734); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(19734, 0, 0, '%s throws a mushroom spore at $n.', 16, 0, 100, 0, 0, 0, 18913, 0, 'Fungal Giant Unstable Shroom'); + +DELETE FROM `creature_template_movement` WHERE (`CreatureId` = 20479); +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`, `InteractionPauseTimer`) VALUES +(20479, 0, 0, 0, 1, 0, 0, 0); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 20479); +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 +(20479, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2047900, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - On Just Summoned - Run Script'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2047900); +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 +(2047900, 9, 0 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Set Reactstate Passive'), +(2047900, 9, 1 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 31690, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Putrid Mushroom\''), +(2047900, 9, 2 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 31691, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Shrink\''), +(2047900, 9, 3 , 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 31698, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Grow\''), +(2047900, 9, 4 , 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 31698, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Grow\''), +(2047900, 9, 5 , 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 31698, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Grow\''), +(2047900, 9, 6 , 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 31698, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Grow\''), +(2047900, 9, 7 , 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 31698, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Grow\''), +(2047900, 9, 8 , 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 31698, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Grow\''), +(2047900, 9, 9 , 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 31698, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Grow\''), +(2047900, 9, 10, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 31698, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Grow\''), +(2047900, 9, 11, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 31698, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Grow\''), +(2047900, 9, 12, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 35362, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Unstable Mushroom Visual\''), +(2047900, 9, 13, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 35252, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Cast \'Unstable Cloud\''), +(2047900, 9, 14, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 28, 31698, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Remove Aura \'Grow\''), +(2047900, 9, 15, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Unstable Shroom - Actionlist - Despawn Instant'); From 37e5fc7d48af4ae991946fc296d5b373c3118c55 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 00:20:14 +0000 Subject: [PATCH 030/335] chore(DB): import pending files Referenced commit(s): 5e8555210893232d23db1e72ce4b5e6a30b7c6ac --- .../rev_1770048466853054600.sql => db_world/2026_02_04_00.sql} | 1 + .../rev_1770072989817102600.sql => db_world/2026_02_04_01.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1770048466853054600.sql => db_world/2026_02_04_00.sql} (97%) rename data/sql/updates/{pending_db_world/rev_1770072989817102600.sql => db_world/2026_02_04_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1770048466853054600.sql b/data/sql/updates/db_world/2026_02_04_00.sql similarity index 97% rename from data/sql/updates/pending_db_world/rev_1770048466853054600.sql rename to data/sql/updates/db_world/2026_02_04_00.sql index 6a08746aa..f58bbc042 100644 --- a/data/sql/updates/pending_db_world/rev_1770048466853054600.sql +++ b/data/sql/updates/db_world/2026_02_04_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_03_01 -> 2026_02_04_00 -- DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 20046); 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 diff --git a/data/sql/updates/pending_db_world/rev_1770072989817102600.sql b/data/sql/updates/db_world/2026_02_04_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1770072989817102600.sql rename to data/sql/updates/db_world/2026_02_04_01.sql index 3cf74d8ce..ab605380c 100644 --- a/data/sql/updates/pending_db_world/rev_1770072989817102600.sql +++ b/data/sql/updates/db_world/2026_02_04_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_04_00 -> 2026_02_04_01 -- DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 19734); INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES From 1a05906598e0f7134b54b58a7f3b8b26c1805340 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Tue, 3 Feb 2026 19:21:48 -0500 Subject: [PATCH 031/335] fix(DB/Creature): Correct model probabilities for various trigger creatures. (#24610) --- .../updates/pending_db_world/trigger-npcs.sql | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 data/sql/updates/pending_db_world/trigger-npcs.sql diff --git a/data/sql/updates/pending_db_world/trigger-npcs.sql b/data/sql/updates/pending_db_world/trigger-npcs.sql new file mode 100644 index 000000000..e40881bd1 --- /dev/null +++ b/data/sql/updates/pending_db_world/trigger-npcs.sql @@ -0,0 +1,18 @@ +DELETE FROM `creature_template_model` WHERE `CreatureID` IN (17168, 17169, 17170, 17171, 17172, 17173, 17174, 17175, 17176, 25739); +INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES +(17168, 0, 15435, 1, 1, 51831), +(17168, 1, 1126, 1, 0, 51831), +(17169, 0, 15435, 1, 1, 51831), +(17169, 1, 1126, 1, 0, 51831), +(17170, 0, 15435, 1, 1, 51831), +(17170, 1, 1126, 1, 0, 51831), +(17171, 0, 15435, 1, 1, 51831), +(17171, 1, 1126, 1, 0, 51831), +(17172, 0, 15435, 1, 1, 51831), +(17172, 1, 1126, 1, 0, 51831), +(17173, 0, 15435, 1, 1, 51831), +(17174, 0, 15435, 1, 1, 51831), +(17175, 0, 15435, 1, 0, 51831), +(17176, 0, 15435, 1, 0, 51831), +(25739, 0, 169, 1, 0, 51831), +(25739, 1, 23343, 1, 1, 51831); From 924c1f3daf49964a2ccc028921ef225327925f5b Mon Sep 17 00:00:00 2001 From: Ryan Turner <16946913+TheSCREWEDSoftware@users.noreply.github.com> Date: Wed, 4 Feb 2026 00:22:21 +0000 Subject: [PATCH 032/335] fix(DB/Loot): Removes "Warsong Report" and "Battered Junkbox" from "Battered Junkbox" (#24588) Co-authored-by: FlyingArowana --- data/sql/updates/pending_db_world/rev_1770028284372314400.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770028284372314400.sql diff --git a/data/sql/updates/pending_db_world/rev_1770028284372314400.sql b/data/sql/updates/pending_db_world/rev_1770028284372314400.sql new file mode 100644 index 000000000..080dd439d --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770028284372314400.sql @@ -0,0 +1,2 @@ +-- Removes "Warsong Report" and "Battered Junkbox" (yes remove itself from itself) from "Battered Junkbox" +DELETE FROM `item_loot_template` WHERE `Entry` = 16882 AND `Item` IN (16746, 16882); From 37019a250033aed826a8ff3ac1ad331a42babb50 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 00:23:02 +0000 Subject: [PATCH 033/335] chore(DB): import pending files Referenced commit(s): 1a05906598e0f7134b54b58a7f3b8b26c1805340 --- .../rev_1770028284372314400.sql => db_world/2026_02_04_02.sql} | 1 + .../trigger-npcs.sql => db_world/2026_02_04_03.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1770028284372314400.sql => db_world/2026_02_04_02.sql} (81%) rename data/sql/updates/{pending_db_world/trigger-npcs.sql => db_world/2026_02_04_03.sql} (94%) diff --git a/data/sql/updates/pending_db_world/rev_1770028284372314400.sql b/data/sql/updates/db_world/2026_02_04_02.sql similarity index 81% rename from data/sql/updates/pending_db_world/rev_1770028284372314400.sql rename to data/sql/updates/db_world/2026_02_04_02.sql index 080dd439d..1c41a6dde 100644 --- a/data/sql/updates/pending_db_world/rev_1770028284372314400.sql +++ b/data/sql/updates/db_world/2026_02_04_02.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_04_01 -> 2026_02_04_02 -- Removes "Warsong Report" and "Battered Junkbox" (yes remove itself from itself) from "Battered Junkbox" DELETE FROM `item_loot_template` WHERE `Entry` = 16882 AND `Item` IN (16746, 16882); diff --git a/data/sql/updates/pending_db_world/trigger-npcs.sql b/data/sql/updates/db_world/2026_02_04_03.sql similarity index 94% rename from data/sql/updates/pending_db_world/trigger-npcs.sql rename to data/sql/updates/db_world/2026_02_04_03.sql index e40881bd1..124332b4d 100644 --- a/data/sql/updates/pending_db_world/trigger-npcs.sql +++ b/data/sql/updates/db_world/2026_02_04_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_04_02 -> 2026_02_04_03 DELETE FROM `creature_template_model` WHERE `CreatureID` IN (17168, 17169, 17170, 17171, 17172, 17173, 17174, 17175, 17176, 25739); INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES (17168, 0, 15435, 1, 1, 51831), From 4f5a63f1d174fd868eacbe558f8d71cd440a5c3d Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Tue, 3 Feb 2026 20:42:26 -0600 Subject: [PATCH 034/335] fix(Core/Guild): Fix rare guild bank bug (#24614) Co-authored-by: blinkysc --- src/server/game/Guilds/Guild.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index d38838121..7ca122b9d 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -1715,19 +1715,23 @@ bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool sScriptMgr->OnGuildMemberWitdrawMoney(this, player, amount, repair); CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); - // Add money to player (if required) + + if (!_ModifyBankMoney(trans, amount, false)) + return false; + if (!repair) { if (!player->ModifyMoney(amount)) + { + _ModifyBankMoney(trans, amount, true); return false; + } player->SaveGoldToDB(trans); } // Update remaining money amount member->UpdateBankWithdrawValue(trans, GUILD_BANK_MAX_TABS, amount); - // Remove money from bank - _ModifyBankMoney(trans, amount, false); // Log guild bank event _LogBankEvent(trans, repair ? GUILD_BANK_LOG_REPAIR_MONEY : GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), player->GetGUID(), amount); From 193da38f749ad9eff4bb39fcb5febe1d3ddca131 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 6 Feb 2026 05:48:33 -0600 Subject: [PATCH 035/335] fix(Commands): .go creature and .appear support transports (#23969) Co-authored-by: blinkysc Co-authored-by: sudlud --- src/server/scripts/Commands/cs_go.cpp | 85 ++++++++++++++++++++++++- src/server/scripts/Commands/cs_misc.cpp | 35 ++++++++-- 2 files changed, 115 insertions(+), 5 deletions(-) diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 2e59bf7cf..88a7df172 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -23,6 +23,7 @@ #include "ObjectMgr.h" #include "Player.h" #include "TicketMgr.h" +#include "Transport.h" #include "boost/algorithm/string.hpp" #include @@ -66,7 +67,11 @@ public: if (mapId == MAPID_INVALID) mapId = player->GetMapId(); - if (!MapMgr::IsValidMapCoord(mapId, pos) || sObjectMgr->IsTransportMap(mapId)) + + if (sObjectMgr->IsTransportMap(mapId)) + return DoTeleportToTransport(handler, pos, mapId); + + if (!MapMgr::IsValidMapCoord(mapId, pos)) { handler->SendErrorMessage(LANG_INVALID_TARGET_COORD, pos.GetPositionX(), pos.GetPositionY(), mapId); return false; @@ -86,6 +91,84 @@ public: return true; } + static bool DoTeleportToTransport(ChatHandler* handler, Position pos, uint32 transportMapId) + { + Player* player = handler->GetSession()->GetPlayer(); + + uint32 transportEntry = 0; + for (auto const& [entry, goTemplate] : *sObjectMgr->GetGameObjectTemplates()) + { + if (goTemplate.type == GAMEOBJECT_TYPE_MO_TRANSPORT && goTemplate.moTransport.mapID == transportMapId) + { + transportEntry = entry; + break; + } + } + + if (!transportEntry) + { + handler->SendErrorMessage(LANG_INVALID_TARGET_COORD, pos.GetPositionX(), pos.GetPositionY(), transportMapId); + return false; + } + + MotionTransport* transport = nullptr; + sMapMgr->DoForAllMaps([&](Map* map) + { + if (transport) + return; + + for (Transport* t : map->GetAllTransports()) + { + if (MotionTransport* mt = t->ToMotionTransport()) + { + if (mt->GetEntry() == transportEntry) + { + transport = mt; + return; + } + } + } + }); + + if (!transport) + { + handler->SendErrorMessage(LANG_INVALID_TARGET_COORD, pos.GetPositionX(), pos.GetPositionY(), transportMapId); + return false; + } + + if (player->IsInFlight()) + { + player->GetMotionMaster()->MovementExpired(); + player->CleanupAfterTaxiFlight(); + } + else + player->SaveRecallPosition(); + + if (Transport* oldTransport = player->GetTransport()) + oldTransport->RemovePassenger(player, true); + + float const localX = pos.GetPositionX(); + float const localY = pos.GetPositionY(); + float const localZ = pos.GetPositionZ(); + float const localO = pos.GetOrientation(); + + player->SetTransport(transport); + player->m_movementInfo.transport.guid = transport->GetGUID(); + player->m_movementInfo.transport.pos.Relocate(localX, localY, localZ, localO); + player->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); + + float worldX = localX; + float worldY = localY; + float worldZ = localZ; + float worldO = localO; + transport->CalculatePassengerPosition(worldX, worldY, worldZ, &worldO); + + transport->AddPassenger(player, false); + + player->TeleportTo(transport->GetMapId(), worldX, worldY, worldZ, worldO, TELE_TO_NOT_LEAVE_TRANSPORT); + return true; + } + static bool HandleGoCreatureCIdCommand(ChatHandler* handler, Variant, uint32> cId, Optional _pos) { uint32 pos = 1; diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 6c53573b6..559b6eb67 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -46,6 +46,7 @@ #include "SpellAuras.h" #include "TargetedMovementGenerator.h" #include "Tokenize.h" +#include "Transport.h" #include "WeatherMgr.h" #include "WorldSessionMgr.h" @@ -877,13 +878,39 @@ public: _player->CleanupAfterTaxiFlight(); } else // save only in non-flight case - { _player->SaveRecallPosition(); - } - if (_player->TeleportTo(targetPlayer->GetMapId(), targetPlayer->GetPositionX(), targetPlayer->GetPositionY(), targetPlayer->GetPositionZ() + 0.25f, _player->GetOrientation(), TELE_TO_GM_MODE, targetPlayer)) + if (Transport* transport = targetPlayer->GetTransport()) { - _player->SetPhaseMask(targetPlayer->GetPhaseMask() | 1, false); + if (Transport* oldTransport = _player->GetTransport()) + oldTransport->RemovePassenger(_player, true); + + float x; + float y; + float z; + float o; + targetPlayer->m_movementInfo.transport.pos.GetPosition(x, y, z, o); + + _player->SetTransport(transport); + _player->m_movementInfo.transport.guid = transport->GetGUID(); + _player->m_movementInfo.transport.pos.Relocate(x, y, z, o); + _player->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); + + float worldX = x; + float worldY = y; + float worldZ = z; + float worldO = o; + transport->CalculatePassengerPosition(worldX, worldY, worldZ, &worldO); + + transport->AddPassenger(_player, false); + + if (_player->TeleportTo(transport->GetMapId(), worldX, worldY, worldZ + 0.25f, worldO, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_GM_MODE, targetPlayer)) + _player->SetPhaseMask(targetPlayer->GetPhaseMask() | 1, false); + } + else + { + if (_player->TeleportTo(targetPlayer->GetMapId(), targetPlayer->GetPositionX(), targetPlayer->GetPositionY(), targetPlayer->GetPositionZ() + 0.25f, _player->GetOrientation(), TELE_TO_GM_MODE, targetPlayer)) + _player->SetPhaseMask(targetPlayer->GetPhaseMask() | 1, false); } } else From 9f5f3d1290c59f0dff52ce8858aed5aee8e17412 Mon Sep 17 00:00:00 2001 From: sogladev Date: Fri, 6 Feb 2026 14:48:22 +0100 Subject: [PATCH 036/335] fix(DB/Creature): Update gossip menus and options for select trainers (#24596) --- .../pending_db_world/rev_1770056617264027961.sql | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770056617264027961.sql diff --git a/data/sql/updates/pending_db_world/rev_1770056617264027961.sql b/data/sql/updates/pending_db_world/rev_1770056617264027961.sql new file mode 100644 index 000000000..a64a74d78 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770056617264027961.sql @@ -0,0 +1,13 @@ +-- +UPDATE `creature_template` SET `gossip_menu_id` = 8760 WHERE (`entry` = 18752); +UPDATE `creature_template` SET `gossip_menu_id` = 8760 WHERE (`entry` = 18753); +UPDATE `creature_template` SET `gossip_menu_id` = 7816 WHERE (`entry` = 18771); +UPDATE `creature_template` SET `gossip_menu_id` = 10365 WHERE (`entry` = 33676); +UPDATE `creature_template` SET `gossip_menu_id` = 9879 WHERE (`entry` = 33679); +UPDATE `creature_template` SET `gossip_menu_id` = 8646 WHERE (`entry` = 33680); +UPDATE `creature_template` SET `gossip_menu_id` = 10351 WHERE (`entry` = 33682); + +DELETE FROM `gossip_menu_option` WHERE `MenuID` = 8760; +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES +(8760, 0, 3, 'Train me.', 3266, 5, 16, 0, 0, 0, 0, '', 0, 0), +(8760, 1, 1, 'Let me browse your goods.', 8097, 3, 128, 0, 0, 0, 0, '', 0, 0); From 58d6fedefe7911d315ddb3169bd9b681dda91ac9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 6 Feb 2026 13:49:28 +0000 Subject: [PATCH 037/335] chore(DB): import pending files Referenced commit(s): 9f5f3d1290c59f0dff52ce8858aed5aee8e17412 --- .../rev_1770056617264027961.sql => db_world/2026_02_06_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1770056617264027961.sql => db_world/2026_02_06_00.sql} (95%) diff --git a/data/sql/updates/pending_db_world/rev_1770056617264027961.sql b/data/sql/updates/db_world/2026_02_06_00.sql similarity index 95% rename from data/sql/updates/pending_db_world/rev_1770056617264027961.sql rename to data/sql/updates/db_world/2026_02_06_00.sql index a64a74d78..0deb612ee 100644 --- a/data/sql/updates/pending_db_world/rev_1770056617264027961.sql +++ b/data/sql/updates/db_world/2026_02_06_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_04_03 -> 2026_02_06_00 -- UPDATE `creature_template` SET `gossip_menu_id` = 8760 WHERE (`entry` = 18752); UPDATE `creature_template` SET `gossip_menu_id` = 8760 WHERE (`entry` = 18753); From d4124b1470bdb1a3c58942aab6e5be9a659df898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Borz=C3=AC?= Date: Fri, 6 Feb 2026 17:21:21 +0100 Subject: [PATCH 038/335] docs: init CLAUDE.md (#24630) --- CLAUDE.md | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..b2d126823 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,120 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +AzerothCore is an open-source MMORPG server emulator for World of Warcraft patch 3.3.5a (Wrath of the Lich King). It's a C++ project built with CMake, using MySQL for data storage. Licensed under GNU GPL v2. + +## Build Commands + +### Configure and build (out-of-source build required) + +```bash +# Create build directory and configure +mkdir -p build && cd build +cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/azeroth-server -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DSCRIPTS=static -DMODULES=static + +# Build (use appropriate core count) +make -j$(nproc) +make install +``` + +### Key CMake options + +- `SCRIPTS`: none, static, dynamic, minimal-static, minimal-dynamic (default: static) +- `MODULES`: none, static, dynamic (default: static) +- `APPS_BUILD`: none, all, auth-only, world-only (default: all) +- `TOOLS_BUILD`: none, all, db-only, maps-only (default: none) +- `BUILD_TESTING`: Enable unit tests (default: OFF) +- `USE_COREPCH` / `USE_SCRIPTPCH`: Precompiled headers (default: ON) + +### Unit tests + +```bash +# Configure with testing enabled +cmake .. -DBUILD_TESTING=ON +make -j$(nproc) + +# Run tests +./src/test/unit_tests +# or +ctest +``` + +Tests use Google Test and live in `src/test/`. The test binary links against the `game` library. + +## Architecture + +### Two server executables +- **authserver** (`src/server/apps/authserver/`): Handles authentication and realm selection (port 3724) +- **worldserver** (`src/server/apps/worldserver/`): Main game server handling all gameplay (port 8085) + +### Source layout (`src/`) + +- **`src/common/`** - Shared libraries: networking (Asio), cryptography, configuration, logging, threading, collision detection, utilities +- **`src/server/game/`** - Core game logic (~52 subsystems), the heart of the worldserver +- **`src/server/scripts/`** - Content scripts (bosses, spells, commands, instances) +- **`src/server/database/`** - Database abstraction layer and schema updater +- **`src/server/shared/`** - Code shared between auth and world servers (packets, network, realm definitions) +- **`src/test/`** - Unit tests (Google Test) + +### Key game subsystems (`src/server/game/`) + +- **Entities/** - Core game objects: `Player`, `Creature`, `Unit`, `Item`, `GameObject` +- **Spells/** - Spell mechanics, aura system, spell effects +- **Maps/** - Map management, grid system, instancing +- **Handlers/** - Client packet handlers (one file per system: `MovementHandler.cpp`, `SpellHandler.cpp`, etc.). These are methods on `WorldSession` +- **AI/** - Creature AI framework +- **Scripting/** - Script system with typed base classes (`ScriptObject` subclasses: `CreatureScript`, `SpellScript`, `InstanceMapScript`, `GameObjectScript`, `CommandScript`, etc.) +- **Server/** - `WorldSession` (per-player connection), `World` (global state), opcode definitions + +### Scripting system + +Scripts follow a registration pattern: +1. Define a class inheriting from `SpellScript`, `CreatureScript`, etc. +2. Implement an `AddSC_*()` function that calls `RegisterSpellScript(ClassName)` (or similar) +3. The `AddSC_*()` is declared and called from the regional `*_script_loader.cpp` +4. Script loaders per region: `spells_script_loader.cpp`, `eastern_kingdoms_script_loader.cpp`, `northrend_script_loader.cpp`, etc. +5. Spell script files are organized by class: `spell_dk.cpp`, `spell_mage.cpp`, `spell_generic.cpp`, etc. + +### Three databases +- **acore_auth** - Accounts, realm list, bans (`data/sql/base/db_auth/`) +- **acore_characters** - Character data, inventories, progress (`data/sql/base/db_characters/`) +- **acore_world** - Game content: creatures, items, quests, spells, loot (`data/sql/base/db_world/`) + +SQL updates go in `data/sql/updates/` with separate subdirectories per database. + +### Module system + +External modules are loaded from the `modules/` directory. Each module is a subdirectory with its own `CMakeLists.txt`. Disable specific modules with `-DDISABLED_AC_MODULES="mod1;mod2"`. Module skeleton: https://github.com/azerothcore/skeleton-module/ + +### Dependencies + +Bundled in `deps/`: boost, MySQL client, OpenSSL, zlib, recastnavigation (pathfinding), g3dlite (geometry), fmt, argon2, jemalloc, and others. + +## Commit Message Format + +Uses Conventional Commits: +``` +Type(Scope/Subscope): Short description (max 50 chars) +``` + +- **Types**: feat, fix, refactor, style, docs, test, chore +- **Scopes**: Core (C++ changes), DB (SQL changes) +- **Examples**: `fix(Core/Spells): Fix damage calculation for Fireball`, `fix(DB/SAI): Missing spell to NPC Hogger` + +## Code Style + +- 4-space indentation for C++ (no tabs) +- 2-space indentation for JSON, YAML, shell scripts +- UTF-8 encoding, LF line endings +- Max 80 character line length +- CI enforces code style checks and compiles with `-Werror` + +## PR Requirements + +- AI tool usage must be disclosed in PRs +- In-game testing expected +- Changes to generic code require regression testing of related systems From 653136e311fb552edd49ce889d581b4af87b3491 Mon Sep 17 00:00:00 2001 From: sudlud Date: Fri, 6 Feb 2026 21:39:29 +0100 Subject: [PATCH 039/335] fix(Scripts/SunkenTemple): sniffed values for 'Idol of Hakkar' spawn (#24606) --- .../EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp b/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp index 142bdaea1..8ac630307 100644 --- a/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp +++ b/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp @@ -92,7 +92,8 @@ public: break; case GO_ATALAI_IDOL: if (_statuePhase == MAX_STATUE_PHASE) - gameobject->SummonGameObject(GO_IDOL_OF_HAKKAR, -480.08f, 94.29f, -189.72f, 1.571f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + gameobject->SummonGameObject(GO_IDOL_OF_HAKKAR, -476.269317626953125f, 94.4119873046875f, -189.729660034179687f, 1.588248729705810546f, 0.0f, 0.0f, 0.713250160217285156f, 0.700909554958343505f, 0); // VerifiedBuild 50250 + break; case GO_IDOL_OF_HAKKAR: if (_encounters[TYPE_ATAL_ALARION] == DONE) @@ -165,7 +166,8 @@ public: case DATA_STATUES: ++_statuePhase; if (_statuePhase == MAX_STATUE_PHASE) - instance->SummonGameObject(GO_IDOL_OF_HAKKAR, -480.08f, 94.29f, -189.72f, 1.571f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + instance->SummonGameObject(GO_IDOL_OF_HAKKAR, -476.269317626953125f, 94.4119873046875f, -189.729660034179687f, 1.588248729705810546f, 0.0f, 0.0f, 0.713250160217285156f, 0.700909554958343505f, 0); // VerifiedBuild 50250 + break; } } From 9b63cde7cbfcf3dc6a80e3412c63162b155b5cfc Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 6 Feb 2026 14:41:08 -0600 Subject: [PATCH 040/335] fix(DB/Gameobject): Recalculate quaternion rotation values from orientation (#24617) --- .../rev_1770209139010970104.sql | 2 + .../rev_1770210647797541306.sql | 67 +++++++++++++++++++ src/server/game/Battlefield/Battlefield.cpp | 3 +- .../game/Entities/GameObject/GameObject.cpp | 54 +++++++-------- .../game/Entities/GameObject/GameObject.h | 12 ++-- src/server/game/Entities/Object/Object.cpp | 2 +- .../game/Entities/Transport/Transport.cpp | 4 +- src/server/scripts/Commands/cs_gobject.cpp | 2 +- 8 files changed, 105 insertions(+), 41 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1770209139010970104.sql create mode 100644 data/sql/updates/pending_db_world/rev_1770210647797541306.sql diff --git a/data/sql/updates/pending_db_world/rev_1770209139010970104.sql b/data/sql/updates/pending_db_world/rev_1770209139010970104.sql new file mode 100644 index 000000000..453b1e3b1 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770209139010970104.sql @@ -0,0 +1,2 @@ +-- Recalculate quaternion rotation from orientation for unverified gameobjects +UPDATE `gameobject` SET `rotation2` = SIN(`orientation` / 2), `rotation3` = COS(`orientation` / 2) WHERE `rotation0` = 0 AND `rotation1` = 0 AND (`VerifiedBuild` IS NULL OR `VerifiedBuild` = 0); diff --git a/data/sql/updates/pending_db_world/rev_1770210647797541306.sql b/data/sql/updates/pending_db_world/rev_1770210647797541306.sql new file mode 100644 index 000000000..4bea5e778 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770210647797541306.sql @@ -0,0 +1,67 @@ +-- Add transport parent_rotation values (from TrinityCore/UDB) +DELETE FROM `gameobject_addon` WHERE `guid` IN (14139,16760,16761,16871,20505,24055,24074,24075,25138,34057,35693,35694,55230,56744,56937,56954,56961,57132,57133,57140,57141,57799,57992,57993,57994,57995,57996,58299,58304,58305,58306,58310,58782,58824,58935,59160,59328,59336,59343,59350,59386,59762,59763,59764,59765,59766,59779,59780,59781,59782,59783,60421,60463,61053,65435,65436,65438,65439,65520,66717,67873,67874,67875,67876); +INSERT INTO `gameobject_addon` (`guid`,`parent_rotation0`,`parent_rotation1`,`parent_rotation2`,`parent_rotation3`,`invisibilityType`,`invisibilityValue`) VALUES +(14139,0,0,1,-0.0000000437114,0,0), +(16760,0,0,-0.378575,0.92557,0,0), +(16761,0,0,-0.378575,0.92557,0,0), +(16871,0,0,0.694658,0.71934,0,0), +(20505,0,0,-0.694658,0.71934,0,0), +(24055,0,0,-0.526214,0.850352,0,0), +(24074,0,0,-0.526214,0.850352,0,0), +(24075,0,0,-0.526214,0.850352,0,0), +(25138,0,0,0.45399,0.891007,0,0), +(34057,0,0,0.000000325841,1,0,0), +(35693,0,0,0.989651,0.143493,0,0), +(35694,0,0,0.989651,0.143493,0,0), +(55230,0,0,0.999048,0.0436193,0,0), +(56744,0,0,0.951057,0.309017,0,0), +(56937,0,0,0.951057,0.309017,0,0), +(56954,0,0,0.951057,0.309017,0,0), +(56961,0,0,0.999048,0.0436193,0,0), +(57132,-0.00276125,-0.00551835,-0.370553,0.928791,0,0), +(57133,0.00544418,-0.00290476,0.918772,0.394739,0,0), +(57140,-0.00276125,-0.00551835,-0.370553,0.928791,0,0), +(57141,0.00544418,-0.00290476,0.918772,0.394739,0,0), +(57799,0,0,0.999048,0.0436193,0,0), +(57992,0,0,-0.370557,0.92881,0,0), +(57993,0,0,-0.760406,0.649448,0,0), +(57994,0,0,0.915312,0.402747,0,0), +(57995,0,0,-0.748956,0.66262,0,0), +(57996,0,0,0.995805,0.0915015,0,0), +(58299,0,0,0.999048,0.0436193,0,0), +(58304,0,0,-0.263031,0.964787,0,0), +(58305,0,0,0.522499,0.85264,0,0), +(58306,0,0,0.996917,-0.0784592,0,0), +(58310,0,0,0.333807,0.942641,0,0), +(58782,0,0,0.333807,0.942641,0,0), +(58824,0,0,0.333807,0.942641,0,0), +(58935,0,0,0.932008,-0.362438,0,0), +(59160,0,0,0.99999,0.00436324,0,0), +(59328,0,0,0.99999,-0.00436333,0,0), +(59336,0,0,0.99999,-0.00436333,0,0), +(59343,0,0,0.99999,-0.00436333,0,0), +(59350,0,0,0.99999,-0.00436333,0,0), +(59386,0,0,0.99999,-0.00436333,0,0), +(59762,0,0,-0.370557,0.92881,0,0), +(59763,0,0,-0.760406,0.649448,0,0), +(59764,0,0,0.915312,0.402747,0,0), +(59765,0,0,-0.748956,0.66262,0,0), +(59766,0,0,0.995805,0.0915015,0,0), +(59779,0,0,-0.370557,0.92881,0,0), +(59780,0,0,-0.760406,0.649448,0,0), +(59781,0,0,0.915312,0.402747,0,0), +(59782,0,0,-0.748956,0.66262,0,0), +(59783,0,0,0.995805,0.0915015,0,0), +(60421,0,0,0.99999,0.00436324,0,0), +(60463,0,0,0.999048,0.0436193,0,0), +(61053,0,0,0.999048,0.0436193,0,0), +(65435,0,0,0.915312,0.402747,0,0), +(65436,0,0,0.99999,0.00436324,0,0), +(65438,0,0,0.915312,0.402747,0,0), +(65439,0,0,0.915312,0.402747,0,0), +(65520,0,0,0.99999,0.00436324,0,0), +(66717,0,0,0.999657,0.0261769,0,0), +(67873,-0.00276125,-0.00551835,-0.370553,0.928791,0,0), +(67874,0.00544418,-0.00290476,0.918772,0.394739,0,0), +(67875,-0.00276125,-0.00551835,-0.370553,0.928791,0,0), +(67876,0.00544418,-0.00290476,0.918772,0.394739,0,0); diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 9ad1a9c9a..7a52fb9c1 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -840,7 +840,8 @@ GameObject* Battlefield::SpawnGameObject(uint32 entry, float x, float y, float z // Create gameobject GameObject* go = sObjectMgr->IsGameObjectStaticTransport(entry) ? new StaticTransport() : new GameObject(); - if (!go->Create(map->GenerateLowGuid(), entry, map, PHASEMASK_NORMAL, x, y, z, o, G3D::Quat(), 100, GO_STATE_READY)) + G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), o); + if (!go->Create(map->GenerateLowGuid(), entry, map, PHASEMASK_NORMAL, x, y, z, o, rotation, 100, GO_STATE_READY)) { LOG_ERROR("sql.sql", "Battlefield::SpawnGameObject: Gameobject template {} not found in database! Battlefield not created!", entry); LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Cannot create gameobject template {}! Battlefield not created!", entry); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index d093eb4a1..fd6049057 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -298,7 +298,7 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u return false; } - SetLocalRotation(rotation); + SetWorldRotation(rotation); GameObjectAddon const* gameObjectAddon = sObjectMgr->GetGameObjectAddon(GetSpawnId()); QuaternionData parentRotation; @@ -1038,7 +1038,7 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask, bool data.posY = GetPositionY(); data.posZ = GetPositionZ(); data.orientation = GetOrientation(); - data.rotation = m_localRotation; + data.rotation = WorldRotation; data.spawntimesecs = m_spawnedByDefault ? m_respawnDelayTime : -(int32)m_respawnDelayTime; data.animprogress = GetGoAnimProgress(); data.go_state = GetGoState(); @@ -1064,10 +1064,10 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask, bool stmt->SetData(index++, GetPositionY()); stmt->SetData(index++, GetPositionZ()); stmt->SetData(index++, GetOrientation()); - stmt->SetData(index++, m_localRotation.x); - stmt->SetData(index++, m_localRotation.y); - stmt->SetData(index++, m_localRotation.z); - stmt->SetData(index++, m_localRotation.w); + stmt->SetData(index++, WorldRotation.x); + stmt->SetData(index++, WorldRotation.y); + stmt->SetData(index++, WorldRotation.z); + stmt->SetData(index++, WorldRotation.w); stmt->SetData(index++, int32(m_respawnDelayTime)); stmt->SetData(index++, GetGoAnimProgress()); stmt->SetData(index++, uint8(GetGoState())); @@ -2199,24 +2199,18 @@ void GameObject::UpdatePackedRotation() static const int32 PACK_X = PACK_YZ << 1; static const int32 PACK_YZ_MASK = (PACK_YZ << 1) - 1; static const int32 PACK_X_MASK = (PACK_X << 1) - 1; - int8 w_sign = (m_localRotation.w >= 0.f ? 1 : -1); - int64 x = int32(m_localRotation.x * PACK_X) * w_sign & PACK_X_MASK; - int64 y = int32(m_localRotation.y * PACK_YZ) * w_sign & PACK_YZ_MASK; - int64 z = int32(m_localRotation.z * PACK_YZ) * w_sign & PACK_YZ_MASK; + int8 w_sign = (WorldRotation.w >= 0.f ? 1 : -1); + int64 x = int32(WorldRotation.x * PACK_X) * w_sign & PACK_X_MASK; + int64 y = int32(WorldRotation.y * PACK_YZ) * w_sign & PACK_YZ_MASK; + int64 z = int32(WorldRotation.z * PACK_YZ) * w_sign & PACK_YZ_MASK; m_packedRotation = z | (y << 21) | (x << 42); } -void GameObject::SetLocalRotation(G3D::Quat const& rot) +void GameObject::SetWorldRotation(G3D::Quat const& rot) { - G3D::Quat rotation; - // Temporary solution for gameobjects that have no rotation data in DB: - if (G3D::fuzzyEq(rot.z, 0.f) && G3D::fuzzyEq(rot.w, 0.f)) - rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), GetOrientation()); - else - rotation = rot; - + G3D::Quat rotation = rot; rotation.unitize(); - m_localRotation = rotation; + WorldRotation = rotation; UpdatePackedRotation(); } @@ -2228,26 +2222,26 @@ void GameObject::SetTransportPathRotation(float qx, float qy, float qz, float qw SetFloatValue(GAMEOBJECT_PARENTROTATION + 3, qw); } -void GameObject::SetLocalRotationAngles(float z_rot, float y_rot, float x_rot) +void GameObject::SetWorldRotationAngles(float z_rot, float y_rot, float x_rot) { - SetLocalRotation(G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(z_rot, y_rot, x_rot))); + SetWorldRotation(G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(z_rot, y_rot, x_rot))); } -G3D::Quat GameObject::GetWorldRotation() const +G3D::Quat GameObject::GetFinalWorldRotation() const { - G3D::Quat localRotation = GetLocalRotation(); + G3D::Quat worldRotation = GetWorldRotation(); if (Transport* transport = GetTransport()) { - G3D::Quat worldRotation = transport->GetWorldRotation(); + G3D::Quat transportRotation = transport->GetWorldRotation(); + G3D::Quat transportRotationQuat(transportRotation.x, transportRotation.y, transportRotation.z, transportRotation.w); G3D::Quat worldRotationQuat(worldRotation.x, worldRotation.y, worldRotation.z, worldRotation.w); - G3D::Quat localRotationQuat(localRotation.x, localRotation.y, localRotation.z, localRotation.w); - G3D::Quat resultRotation = localRotationQuat * worldRotationQuat; + G3D::Quat resultRotation = worldRotationQuat * transportRotationQuat; return G3D::Quat(resultRotation.x, resultRotation.y, resultRotation.z, resultRotation.w); } - return localRotation; + return worldRotation; } void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= nullptr*/, uint32 spellId /*= 0*/) @@ -2967,10 +2961,10 @@ bool GameObject::IsAtInteractDistance(Position const& pos, float radius) const float maxY = displayInfo->maxY * scale + radius; float maxZ = displayInfo->maxZ * scale + radius; - G3D::Quat worldRotation = GetWorldRotation(); - G3D::Quat worldRotationQuat(worldRotation.x, worldRotation.y, worldRotation.z, worldRotation.w); + G3D::Quat finalRotation = GetFinalWorldRotation(); + G3D::Quat finalRotationQuat(finalRotation.x, finalRotation.y, finalRotation.z, finalRotation.w); - return G3D::CoordinateFrame {{worldRotationQuat}, {GetPositionX(), GetPositionY(), GetPositionZ()}}.toWorldSpace(G3D::Box {{minX, minY, minZ}, {maxX, maxY, maxZ}}).contains({pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()}); + return G3D::CoordinateFrame {{finalRotationQuat}, {GetPositionX(), GetPositionY(), GetPositionZ()}}.toWorldSpace(G3D::Box {{minX, minY, minZ}, {maxX, maxY, maxZ}}).contains({pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()}); } return GetExactDist(&pos) <= radius; diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 12154547e..efcb66249 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -144,12 +144,12 @@ public: [[nodiscard]] ObjectGuid::LowType GetSpawnId() const { return m_spawnId; } // z_rot, y_rot, x_rot - rotation angles around z, y and x axes - void SetLocalRotationAngles(float z_rot, float y_rot, float x_rot); - void SetLocalRotation(G3D::Quat const& rot); + void SetWorldRotationAngles(float z_rot, float y_rot, float x_rot); + void SetWorldRotation(G3D::Quat const& rot); void SetTransportPathRotation(float qx, float qy, float qz, float qw); - [[nodiscard]] G3D::Quat const& GetLocalRotation() const { return m_localRotation; } - [[nodiscard]] int64 GetPackedLocalRotation() const { return m_packedRotation; } - [[nodiscard]] G3D::Quat GetWorldRotation() const; + [[nodiscard]] G3D::Quat const& GetWorldRotation() const { return WorldRotation; } + [[nodiscard]] int64 GetPackedWorldRotation() const { return m_packedRotation; } + [[nodiscard]] G3D::Quat GetFinalWorldRotation() const; // overwrite WorldObject function for proper name localization [[nodiscard]] std::string const& GetNameForLocaleIdx(LocaleConstant locale_idx) const override; @@ -394,7 +394,7 @@ protected: bool m_allowModifyDestructibleBuilding; int64 m_packedRotation; - G3D::Quat m_localRotation; + G3D::Quat WorldRotation; Position m_stationaryPosition; ObjectGuid m_lootRecipient; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 73ced5874..8df600651 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -479,7 +479,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const // 0x200 if (flags & UPDATEFLAG_ROTATION) { - *data << int64(ToGameObject()->GetPackedLocalRotation()); + *data << int64(ToGameObject()->GetPackedWorldRotation()); } } diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index cb1987920..dbe068d14 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -99,7 +99,7 @@ bool MotionTransport::CreateMoTrans(ObjectGuid::LowType guidlow, uint32 entry, u SetName(goinfo->name); // pussywizard: no WorldRotation for MotionTransports - SetLocalRotation(G3D::Quat()); + SetWorldRotation(G3D::Quat()); // pussywizard: no PathRotation for MotionTransports SetTransportPathRotation(0.0f, 0.0f, 0.0f, 1.0f); @@ -768,7 +768,7 @@ bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* m // pussywizard: temporarily calculate WorldRotation from orientation, do so until values in db are correct //SetWorldRotation( /*for StaticTransport we need 2 rotation Quats in db for World- and Path- Rotation*/ ); - SetLocalRotationAngles(NormalizeOrientation(GetOrientation()), 0.0f, 0.0f); + SetWorldRotationAngles(NormalizeOrientation(GetOrientation()), 0.0f, 0.0f); // pussywizard: PathRotation for StaticTransport (only StaticTransports have PathRotation) SetTransportPathRotation(rotation.x, rotation.y, rotation.z, rotation.w); diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index e4f1615b9..e41d93d07 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -332,7 +332,7 @@ public: Map* map = object->GetMap(); object->Relocate(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), *oz); - object->SetLocalRotationAngles(*oz, oy.value_or(0.0f), ox.value_or(0.0f)); + object->SetWorldRotationAngles(*oz, oy.value_or(0.0f), ox.value_or(0.0f)); object->SaveToDB(); // Generate a completely new spawn with new guid From f21a447bf1437f316c140a353e1f2670b2916ca4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 6 Feb 2026 20:42:20 +0000 Subject: [PATCH 041/335] chore(DB): import pending files Referenced commit(s): 9b63cde7cbfcf3dc6a80e3412c63162b155b5cfc --- .../rev_1770209139010970104.sql => db_world/2026_02_06_01.sql} | 1 + .../rev_1770210647797541306.sql => db_world/2026_02_06_02.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1770209139010970104.sql => db_world/2026_02_06_01.sql} (86%) rename data/sql/updates/{pending_db_world/rev_1770210647797541306.sql => db_world/2026_02_06_02.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1770209139010970104.sql b/data/sql/updates/db_world/2026_02_06_01.sql similarity index 86% rename from data/sql/updates/pending_db_world/rev_1770209139010970104.sql rename to data/sql/updates/db_world/2026_02_06_01.sql index 453b1e3b1..ff11150b6 100644 --- a/data/sql/updates/pending_db_world/rev_1770209139010970104.sql +++ b/data/sql/updates/db_world/2026_02_06_01.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_06_00 -> 2026_02_06_01 -- Recalculate quaternion rotation from orientation for unverified gameobjects UPDATE `gameobject` SET `rotation2` = SIN(`orientation` / 2), `rotation3` = COS(`orientation` / 2) WHERE `rotation0` = 0 AND `rotation1` = 0 AND (`VerifiedBuild` IS NULL OR `VerifiedBuild` = 0); diff --git a/data/sql/updates/pending_db_world/rev_1770210647797541306.sql b/data/sql/updates/db_world/2026_02_06_02.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1770210647797541306.sql rename to data/sql/updates/db_world/2026_02_06_02.sql index 4bea5e778..a30e48b6b 100644 --- a/data/sql/updates/pending_db_world/rev_1770210647797541306.sql +++ b/data/sql/updates/db_world/2026_02_06_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_06_01 -> 2026_02_06_02 -- Add transport parent_rotation values (from TrinityCore/UDB) DELETE FROM `gameobject_addon` WHERE `guid` IN (14139,16760,16761,16871,20505,24055,24074,24075,25138,34057,35693,35694,55230,56744,56937,56954,56961,57132,57133,57140,57141,57799,57992,57993,57994,57995,57996,58299,58304,58305,58306,58310,58782,58824,58935,59160,59328,59336,59343,59350,59386,59762,59763,59764,59765,59766,59779,59780,59781,59782,59783,60421,60463,61053,65435,65436,65438,65439,65520,66717,67873,67874,67875,67876); INSERT INTO `gameobject_addon` (`guid`,`parent_rotation0`,`parent_rotation1`,`parent_rotation2`,`parent_rotation3`,`invisibilityType`,`invisibilityValue`) VALUES From a924aa6c240ef568e818151e371caa0d3778bc62 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:04:02 -0300 Subject: [PATCH 042/335] fix(Core/Movement): Exclude Players and Player-controlled units from pet pathing cancellations (#24552) --- .../Movement/MovementGenerators/TargetedMovementGenerator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 8b6e2efcd..4f593795e 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -109,7 +109,8 @@ bool ChaseMovementGenerator::DispatchSplineToPosition(T* owner, float x, floa bool pathFailed = !success || (pathType & PATHFIND_NOPATH); // For pets, treat incomplete paths as failures to avoid clipping through geometry - if (cOwner && (cOwner->IsPet() || cOwner->IsControlledByPlayer())) + // Players and Player-controlled units have more erratic movement, skip failure + if (cOwner && (cOwner->IsPet() || cOwner->IsControlledByPlayer()) && !i_target.getTarget()->IsCharmedOwnedByPlayerOrPlayer()) if (pathType & PATHFIND_INCOMPLETE) pathFailed = true; From 64bcc4de72655678aab6996cc6c98a05183e6190 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:05:09 -0300 Subject: [PATCH 043/335] fix(DB/Creature): Adjust Field Values to Creature Flame Wave II (22228) (#24598) --- .../updates/pending_db_world/rev_1770063321798974800.sql | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770063321798974800.sql diff --git a/data/sql/updates/pending_db_world/rev_1770063321798974800.sql b/data/sql/updates/pending_db_world/rev_1770063321798974800.sql new file mode 100644 index 000000000..549437421 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770063321798974800.sql @@ -0,0 +1,7 @@ +-- +UPDATE `creature_template` SET `faction` = 1692 WHERE (`entry` = 22228); +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|128 WHERE (`entry` IN (19381, 22228)); + +DELETE FROM `creature_template_addon` WHERE (`entry` = 22228); +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(22228, 0, 0, 0, 0, 0, 0, '38608'); From b521a3927d411f3d9757e37f2cb6f921a5253d9d Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:05:14 -0300 Subject: [PATCH 044/335] fix(Scripts/StormPeaks): Rewrite Time-Lost Proto Drake (#24497) --- .../rev_1769117901544014100.sql | 131 ++++++++++++++++++ .../scripts/Northrend/zone_storm_peaks.cpp | 108 +++++---------- 2 files changed, 164 insertions(+), 75 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1769117901544014100.sql diff --git a/data/sql/updates/pending_db_world/rev_1769117901544014100.sql b/data/sql/updates/pending_db_world/rev_1769117901544014100.sql new file mode 100644 index 000000000..48c35cd78 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769117901544014100.sql @@ -0,0 +1,131 @@ +-- Vyragosa +UPDATE `creature_template` SET `speed_run` = 1.142857, `unit_flags` = `unit_flags`|64|32768 WHERE (`entry` = 32630); +UPDATE `creature_model_info` SET `CombatReach` = 15 WHERE `DisplayID` = 28110; +-- Time-Lost Proto Drake +UPDATE `creature_template` SET `speed_walk` = 1.44444, `speed_run` = 1.5873, `unit_flags` = `unit_flags`|64|32768 WHERE (`entry` = 32491); +UPDATE `creature_model_info` SET `BoundingRadius` = 0.300000011920928955, `CombatReach` = 5 WHERE `DisplayID` = 26711; + +DELETE FROM `script_waypoint` WHERE `entry` = 32491; + +SET @GUID := 39203; + +DELETE FROM `waypoint_data` WHERE `id` IN ((@GUID)*10, (@GUID+1)*10, (@GUID+2)*10, (@GUID+3)*10); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`) VALUES +-- This is the one in which Time-Lost was found +((@GUID)*10, 1 , 6748.211, -1664.3069, 919.3118 , NULL, 0, 1), +((@GUID)*10, 2 , 6913.308, -1725.2614, 954.7917 , NULL, 0, 1), +((@GUID)*10, 3 , 7167.578, -1501.6945, 962.5693 , NULL, 0, 1), +((@GUID)*10, 4 , 7440.402, -1295.8611, 997.2911 , NULL, 0, 1), +((@GUID)*10, 5 , 7210.9585, -1046.8922, 1006.1796, NULL, 0, 1), +((@GUID)*10, 6 , 6998.4653, -1076.8466, 1024.8191, NULL, 0, 1), +((@GUID)*10, 7 , 6874.249, -1097.3822, 927.736 , NULL, 0, 1), +((@GUID)*10, 8 , 6614.7915, -875.7547, 812.7645 , NULL, 0, 1), +((@GUID)*10, 9 , 6563.2754, -811.7673, 749.87573 , NULL, 0, 1), +((@GUID)*10, 10, 6299.502, -797.57697, 529.12573 , NULL, 0, 1), +((@GUID)*10, 11, 6194.549, -1013.1437, 501.54242 , NULL, 0, 1), +((@GUID)*10, 12, 6319.2544, -1251.6613, 468.6258 , NULL, 0, 1), +((@GUID)*10, 13, 6309.161, -1537.8574, 615.0423 , NULL, 0, 1), + +((@GUID+1)*10, 1 , 6455.723, -562.87396, 814.643 , NULL, 0, 1), +((@GUID+1)*10, 2 , 6552.79, -672.2307, 835.29645 , NULL, 0, 1), +((@GUID+1)*10, 3 , 6649.857, -781.58746, 855.9499 , NULL, 0, 1), +((@GUID+1)*10, 4 , 6952.5728, -758.1678, 807.22784 , NULL, 0, 1), +((@GUID+1)*10, 5 , 7057.876, -690.5854, 807.22784 , NULL, 0, 1), +((@GUID+1)*10, 6 , 7070.7056, -460.4938, 821.33875 , NULL, 0, 1), +((@GUID+1)*10, 7 , 7083.6943, -252.1965, 817.78326 , NULL, 0, 1), +((@GUID+1)*10, 8 , 6910.3896, -164.06386, 821.42194, NULL, 0, 1), +((@GUID+1)*10, 9 , 6754.1, -16.06277, 805.08875 , NULL, 0, 1), +((@GUID+1)*10, 10, 6525.3613, -70.11849, 808.1164 , NULL, 0, 1), +((@GUID+1)*10, 11, 6400.468, -192.77023, 704.8667 , NULL, 0, 1), +((@GUID+1)*10, 12, 6312.018, -498.71994, 704.8667 , NULL, 0, 1), +((@GUID+1)*10, 13, 6481.932, -689.96844, 770.06104 , NULL, 0, 1), +((@GUID+1)*10, 14, 6649.857, -781.58746, 855.9499 , NULL, 0, 1), +((@GUID+1)*10, 15, 6952.5728, -758.1678, 807.22784 , NULL, 0, 1), + +((@GUID+2)*10, 1 , 6481.932, -689.96844, 770.06104 , NULL, 0, 1), +((@GUID+2)*10, 2 , 6649.857, -781.58746, 855.9499 , NULL, 0, 1), +((@GUID+2)*10, 3 , 6952.5728, -758.1678, 807.22784 , NULL, 0, 1), +((@GUID+2)*10, 4 , 7057.876, -690.5854, 807.22784 , NULL, 0, 1), +((@GUID+2)*10, 5 , 7070.7056, -460.4938, 821.33875 , NULL, 0, 1), +((@GUID+2)*10, 6 , 7083.6943, -252.1965, 817.78326 , NULL, 0, 1), +((@GUID+2)*10, 7 , 6910.3896, -164.06386, 821.42194, NULL, 0, 1), +((@GUID+2)*10, 8 , 6754.1, -16.06277, 805.08875 , NULL, 0, 1), +((@GUID+2)*10, 9 , 6525.3613, -70.11849, 808.1164 , NULL, 0, 1), +((@GUID+2)*10, 10, 6400.468, -192.77023, 704.8667 , NULL, 0, 1), +((@GUID+2)*10, 11, 6312.018, -498.71994, 704.8667 , NULL, 0, 1), + +((@GUID+3)*10, 1 , 6954.7627, -472.37695, 997.65027, NULL, 0, 1), +((@GUID+3)*10, 2 , 6903.07, -363.67593, 992.3348 , NULL, 0, 1), +((@GUID+3)*10, 3 , 7002.2744, -270.31137, 908.9182 , NULL, 0, 1), +((@GUID+3)*10, 4 , 7150.6274, -142.2627, 859.1961 , NULL, 0, 1), +((@GUID+3)*10, 5 , 7316.008, -35.80534, 859.1961 , NULL, 0, 1), +((@GUID+3)*10, 6 , 7542.2666, -97.61708, 878.5572 , NULL, 0, 1), +((@GUID+3)*10, 7 , 7667.518, -102.67128, 899.2793 , NULL, 0, 1), +((@GUID+3)*10, 8 , 7794.171, -209.65338, 925.02905 , NULL, 0, 1), +((@GUID+3)*10, 9 , 7899.086, -401.56662, 928.9456 , NULL, 0, 1), +((@GUID+3)*10, 10, 7997.539, -546.96466, 949.58435 , NULL, 0, 1), +((@GUID+3)*10, 11, 8143.803, -636.999, 999.3811 , NULL, 0, 1), +((@GUID+3)*10, 12, 8245.65, -775.7319, 999.3811 , NULL, 0, 1), +((@GUID+3)*10, 13, 8238.106, -987.4192, 983.9922 , NULL, 0, 1), +((@GUID+3)*10, 14, 7946.1025, -1003.7714, 1088.5669, NULL, 0, 1), +((@GUID+3)*10, 15, 7586.955, -1071.2095, 1054.2891 , NULL, 0, 1), +((@GUID+3)*10, 16, 7313.6016, -857.4793, 987.2056 , NULL, 0, 1), +((@GUID+3)*10, 17, 7143.3037, -697.4054, 969.9835 , NULL, 0, 1); + +DELETE FROM `creature` WHERE (`id1` = 32491) AND `guid` = 1975840; +DELETE FROM `creature` WHERE `id1` IN (32491, 32630) AND `guid` BETWEEN @GUID AND @GUID+7; +INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `MovementType`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(@GUID+0, 32491, 571, 67, 511, 6748.211, -1664.3069, 919.3118, 0, 2700, 2, 58558, 1, NULL), +(@GUID+1, 32491, 571, 67, 511, 6455.723, -562.87396, 814.643, 0, 2700, 2, 58558, 1, NULL), +(@GUID+2, 32491, 571, 67, 511, 6481.932, -689.96844, 770.06104, 0, 2700, 2, 58558, 1, NULL), +(@GUID+3, 32491, 571, 67, 511, 6954.7627, -472.37695, 997.65027, 0, 2700, 2, 58558, 1, NULL), + +(@GUID+4, 32630, 571, 67, 511, 6748.211, -1664.3069, 919.3118, 0, 2700, 2, 58558, 1, NULL), +(@GUID+5, 32630, 571, 67, 511, 6455.723, -562.87396, 814.643, 0, 2700, 2, 58558, 1, NULL), +(@GUID+6, 32630, 571, 67, 511, 6481.932, -689.96844, 770.06104, 0, 2700, 2, 58558, 1, NULL), +(@GUID+7, 32630, 571, 67, 511, 6954.7627, -472.37695, 997.65027, 0, 2700, 2, 58558, 1, NULL); + +DELETE FROM `pool_template` WHERE `entry` = 32491; +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(32491, 1, 'Time-Lost Proto Drake / Vyragosa'); + +DELETE FROM `pool_template` WHERE `entry` BETWEEN 32492 AND 32495; +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(32492, 1, 'Time-Lost Proto Drake / Vyragosa - Path 1'), +(32493, 1, 'Time-Lost Proto Drake / Vyragosa - Path 2'), +(32494, 1, 'Time-Lost Proto Drake / Vyragosa - Path 3'), +(32495, 1, 'Time-Lost Proto Drake / Vyragosa - Path 4'); + +DELETE FROM `pool_pool` WHERE `mother_pool` = 32491; +INSERT INTO `pool_pool` (`pool_id`, `mother_pool`, `chance`, `description`) VALUES +(32492, 32491, 0, 'Time-Lost Proto Drake / Vyragosa - Path 1'), +(32493, 32491, 0, 'Time-Lost Proto Drake / Vyragosa - Path 2'), +(32494, 32491, 0, 'Time-Lost Proto Drake / Vyragosa - Path 3'), +(32495, 32491, 0, 'Time-Lost Proto Drake / Vyragosa - Path 4'); + +DELETE FROM `pool_creature` WHERE `pool_entry` BETWEEN 32491 AND 32495; +INSERT INTO `pool_creature` (`guid`, `pool_entry`, `chance`, `description`) VALUES +-- Seen Time-Lost 1 in 12 sniffs +(@GUID, 32492, 10, 'Time-Lost Proto Drake - Path 1'), +(@GUID+4, 32492, 0, 'Vyragosa - Path 1'), + +(@GUID+1, 32493, 10, 'Time-Lost Proto Drake - Path 2'), +(@GUID+5, 32493, 0, 'Vyragosa - Path 2'), + +(@GUID+2, 32494, 10, 'Time-Lost Proto Drake - Path 3'), +(@GUID+6, 32494, 0, 'Vyragosa - Path 3'), + +(@GUID+3, 32495, 10, 'Time-Lost Proto Drake - Path 4'), +(@GUID+7, 32495, 0, 'Vyragosa - Path 4'); + +DELETE FROM `creature_addon` WHERE `guid` BETWEEN @GUID+0 AND @GUID+7; +INSERT INTO `creature_addon` (`guid`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(@GUID+0, (@GUID+0)*10, 0, 0, 0, 0, 0, ''), +(@GUID+1, (@GUID+1)*10, 0, 0, 0, 0, 0, ''), +(@GUID+2, (@GUID+2)*10, 0, 0, 0, 0, 0, ''), +(@GUID+3, (@GUID+3)*10, 0, 0, 0, 0, 0, ''), + +(@GUID+4, (@GUID+0)*10, 0, 0, 0, 0, 0, ''), +(@GUID+5, (@GUID+1)*10, 0, 0, 0, 0, 0, ''), +(@GUID+6, (@GUID+2)*10, 0, 0, 0, 0, 0, ''), +(@GUID+7, (@GUID+3)*10, 0, 0, 0, 0, 0, ''); diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index 2bdf9dba9..3317d63ca 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -203,109 +203,67 @@ public: enum eTimeLost { - NPC_TIME_LOST_PROTO_DRAKE = 32491, - NPC_VYRAGOSA = 32630, + NPC_TIME_LOST_PROTO_DRAKE = 32491, + NPC_VYRAGOSA = 32630, - SPELL_TIME_SHIFT = 61084, - SPELL_TIME_LAPSE = 51020, - SPELL_FROST_BREATH = 47425, - SPELL_FROST_CLEAVE = 51857, + SPELL_TIME_SHIFT = 61084, + SPELL_TIME_LAPSE = 51020, + SPELL_FROST_BREATH = 47425, + SPELL_FROST_CLEAVE = 51857, }; class npc_time_lost_proto_drake : public CreatureScript { public: - npc_time_lost_proto_drake() : CreatureScript("npc_time_lost_proto_drake") { } + npc_time_lost_proto_drake() : CreatureScript("npc_time_lost_proto_drake") {} - struct npc_time_lost_proto_drakeAI : public npc_escortAI + struct npc_time_lost_proto_drakeAI : public ScriptedAI { - npc_time_lost_proto_drakeAI(Creature* creature) : npc_escortAI(creature) + npc_time_lost_proto_drakeAI(Creature* creature) : ScriptedAI(creature) {} + + void InitializeAI() override { - rollPath = false; - setVisible = false; + ScriptedAI::InitializeAI(); + me->SetAnimTier(AnimTier::Fly); me->setActive(true); me->SetVisible(false); + + me->m_Events.AddEventAtOffset([&] { + me->SetVisible(true); + }, Hours(urand(6, 22))); } - EventMap events; - bool rollPath; - bool setVisible; - - void Reset() override + void JustEngagedWith(Unit* who) override { - npc_escortAI::Reset(); - if (me->HasUnitState(UNIT_STATE_EVADE)) - return; - me->SetVisible(false); // pussywizard: zeby nie dostawali info o npc w miejscu spawna (kampienie z addonem npc scan) - rollPath = true; - } + ScriptedAI::JustEngagedWith(who); - void RollPath() - { - me->SetEntry(NPC_TIME_LOST_PROTO_DRAKE); - Start(true, ObjectGuid::Empty, 0, false, true, true); - SetNextWaypoint(urand(0, 250), true); - me->UpdateEntry(roll_chance_i(25) ? NPC_TIME_LOST_PROTO_DRAKE : NPC_VYRAGOSA, 0, false); - } - - void WaypointReached(uint32 /*pointId*/) override { } - - void JustEngagedWith(Unit*) override - { - events.Reset(); if (me->GetEntry() == NPC_TIME_LOST_PROTO_DRAKE) { - events.ScheduleEvent(SPELL_TIME_SHIFT, 10s); - events.ScheduleEvent(SPELL_TIME_LAPSE, 5s); + ScheduleTimedEvent(5s, [&] { + DoCastVictim(SPELL_TIME_LAPSE); + }, 12s); + ScheduleTimedEvent(10s, [&] { + DoCastSelf(SPELL_TIME_SHIFT); + }, 18s); } else { - events.ScheduleEvent(SPELL_FROST_BREATH, 8s); - events.ScheduleEvent(SPELL_FROST_CLEAVE, 5s); + ScheduleTimedEvent(5s, [&] { + DoCastVictim(SPELL_FROST_CLEAVE); + }, 8s); + ScheduleTimedEvent(8s, [&] { + DoCastVictim(SPELL_FROST_BREATH); + }, 12s); } } - void UpdateEscortAI(uint32 diff) override + void UpdateAI(uint32 diff) override { - if (rollPath) - { - RollPath(); - rollPath = false; - setVisible = true; - return; - } - - if (setVisible) - { - me->SetVisible(true); - setVisible = false; - } - if (!UpdateVictim()) return; - events.Update(diff); - switch (events.ExecuteEvent()) - { - case SPELL_TIME_SHIFT: - me->CastSpell(me, SPELL_TIME_SHIFT, false); - events.Repeat(18s); - break; - case SPELL_TIME_LAPSE: - me->CastSpell(me->GetVictim(), SPELL_TIME_LAPSE, false); - events.Repeat(12s); - break; - case SPELL_FROST_BREATH: - me->CastSpell(me->GetVictim(), SPELL_FROST_BREATH, false); - events.Repeat(12s); - break; - case SPELL_FROST_CLEAVE: - me->CastSpell(me->GetVictim(), SPELL_FROST_CLEAVE, false); - events.Repeat(8s); - break; - } - DoMeleeAttackIfReady(); + scheduler.Update(diff); } }; From c1cbc8bfed76c284e9dd8f88ebb5cb3c023b3fa2 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:05:26 -0300 Subject: [PATCH 045/335] fix(Scripts/MagistersTerrace): Prevent Splitting Delrissa and Helpers on Aggro (#24560) --- .../MagistersTerrace/boss_priestess_delrissa.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp index aeb35cbf3..fcb89df18 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp @@ -129,6 +129,10 @@ struct boss_priestess_delrissa : public BossAI Talk(SAY_AGGRO); _JustEngagedWith(); + // Prevent Splitting + DoZoneInCombat(); + summons.DoZoneInCombat(); + ScheduleTimedEvent(15s, [&] { if (Unit* target = DoSelectLowestHpFriendly(40.0f, 1000)) DoCast(target, SPELL_FLASH_HEAL); From c74e1567d737817dc4fa25e191bcbcbdaa5ec4c1 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:05:37 -0300 Subject: [PATCH 046/335] fix(Core/SmartAI): Ranged Creatures should have relaxed stances while outside melee range (#24623) --- src/server/game/AI/SmartScripts/SmartAI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index e1f58ad5d..d28029e49 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -859,7 +859,7 @@ void SmartAI::AttackStart(Unit* who) return; } - if (who && me->Attack(who, me->IsWithinMeleeRange(who) || _currentRangeMode)) + if (who && me->Attack(who, me->IsWithinMeleeRange(who))) { if (!me->HasUnitState(UNIT_STATE_NO_COMBAT_MOVEMENT)) { From 8249ca51edcbaca37034a3900e50cc3f8c2422a5 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:05:48 -0300 Subject: [PATCH 047/335] fix(Scripts/TempestKeep): Add Teleport Position to Astromancer Solarian and Threat Reset (#24622) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../sql/updates/pending_db_world/rev_1770249033416011200.sql | 4 ++++ .../scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1770249033416011200.sql diff --git a/data/sql/updates/pending_db_world/rev_1770249033416011200.sql b/data/sql/updates/pending_db_world/rev_1770249033416011200.sql new file mode 100644 index 000000000..c7e7f30a1 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770249033416011200.sql @@ -0,0 +1,4 @@ +-- +DELETE FROM `spell_target_position` WHERE `ID` = 33244 AND `EffectIndex` = 0; +INSERT INTO `spell_target_position` (`ID`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `VerifiedBuild`) VALUES +(33244, 0, 550, 432.74, -373.645, 18.0138, 1.39626, 50791); diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp index 94e300720..749763428 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp @@ -40,7 +40,7 @@ enum Spells SPELL_PSYCHIC_SCREAM = 34322, SPELL_VOID_BOLT = 39329, SPELL_TRUE_BEAM = 33365, - SPELL_TELEPORT_START_POSITION = 33244, + SPELL_TELEPORT_START_POSITION = 33244, // Serverside }; enum Misc @@ -153,7 +153,7 @@ struct boss_high_astromancer_solarian : public BossAI { me->SetReactState(REACT_PASSIVE); scheduler.DelayAll(22s); - // blink to room center in this line using SPELL_TELEPORT_START_POSITION and START_POSITION_X, START_POSITION_Y, START_POSITION_Z + DoCastSelf(SPELL_TELEPORT_START_POSITION); scheduler.Schedule(1s, [this](TaskContext) { for (uint8 i = 0; i < 3; ++i) @@ -198,6 +198,7 @@ struct boss_high_astromancer_solarian : public BossAI }); }).Schedule(23s, [this](TaskContext) { + me->GetThreatMgr().ClearAllThreat(); me->SetReactState(REACT_AGGRESSIVE); summons.DoForAllSummons([&](WorldObject* summon) { From f87752de248dd2a84f58c69f5b1d5632783b68de Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:05:59 -0300 Subject: [PATCH 048/335] fix(Core/SmartScript): Change AREA_CASTING to align with VICTIM_CASTING on timer recalculation (#24563) --- .../rev_1769891519807069500.sql | 81 +++++++++++++++++++ .../game/AI/SmartScripts/SmartScript.cpp | 6 +- 2 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1769891519807069500.sql diff --git a/data/sql/updates/pending_db_world/rev_1769891519807069500.sql b/data/sql/updates/pending_db_world/rev_1769891519807069500.sql new file mode 100644 index 000000000..45af183dd --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769891519807069500.sql @@ -0,0 +1,81 @@ +-- +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=16867 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Defias Pathstalker - In Combat - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=1036 AND `source_type`=0 AND `id`=3 AND `link`=0; -- Kul Tiras Marine - In Combat - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=3192 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Artifact Seeker - In Combat - Cast 'Spell Lock' (Phase 1) (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=23760 AND `source_type`=0 AND `id`=2 AND `link`=0; -- Kul Tiras Marine - Target Casting - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=4328 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Syndicate Sentry - In Combat - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=18556 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Refuge Pointe Defender - In Combat - Cast 'Shield Bash' (No Repeat) (Normal Dungeon) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=17146 AND `source_type`=0 AND `id`=2 AND `link`=0; -- Marcel Dabyrie - In Combat - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=18117 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Stonevault Bonesnapper - In Combat - Cast 'Pummel' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=18123 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Jailor Borhuin - In Combat - Cast 'Pummel' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=3393 AND `source_type`=0 AND `id`=2 AND `link`=0; -- Frostpaw Warrior - Target Casting - Cast 'Pummel' (Phase 1) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=2547 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Overseer Gorthak - In Combat - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=9545 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Warsong Grunt - In Combat - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=16964 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Dashel Stonefist - Target Casting - Cast 'Pummel' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=9164 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Otto - In Combat - Cast 'Pummel' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=12380 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Brittle Revenant - Target Casting - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=7113 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Shadowforge Ambusher - In Combat - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=1540 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Bloodscalp Warrior - Target Casting - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=10391 AND `source_type`=0 AND `id`=3 AND `link`=0; -- Jlarborn the Strategist - In Combat - Cast Shield Bash +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=16904 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Yorus the Flesh Harvester - In Combat - Cast Shield Bash +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=17672 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Dreadbone Sentinel - In Combat - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=1664 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Mirdoran the Fallen - In Combat - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=1491 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Fel Guardhound - In Combat - Cast 'Spell Lock' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=667 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Cast Counterspell on Target Spellcast +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=19320 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Dullgrom Dredger - In Combat - Cast '34802' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=20723 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Quel'dorei Magewraith - In Combat - Cast 'Counterspell' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=26965 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Marauding Skeleton - In Combat - Cast Shield Bash +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=29096 AND `source_type`=0 AND `id`=3 AND `link`=0; -- Anub'ar Champion - Target Casting - Cast 'Pummel' (Phase 1) (No Repeat) (Dungeon) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=30865 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Dragonflayer Huscarl - Target Casting - Cast 'Pummel' (Phase 1) (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=17401 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Shadowsworn Thug - In Combat - Cast 'Kick' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=2584 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Shadowforge Ruffian - In Combat - Cast 'Kick' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=29062 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Grimtotem Bandit - In Combat - Cast '34802' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=22143 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Nethergarde Soldier - In Combat - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=22342 AND `source_type`=0 AND `id`=4 AND `link`=0; -- Pyrewood Sentry - In Combat - Cast Shield Bash +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=23665 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Bloodsail Swashbuckler - In Combat - Cast 'Kick' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=18498 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Scalebane Captain - In Combat - Cast 'Pummel' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=449 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Muckrake - In Combat - Cast 'Pummel' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=3739 AND `source_type`=0 AND `id`=2 AND `link`=0; -- Theramore Marine - In Combat - Cast '72' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=9605 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Skeletal Archmage - On Target Casting - Cast Counterspell +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=12369 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Anvilrage Enforcer - In Combat - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=18429 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Deathforge Guardian - In Combat - Cast 'Shield Bash' (Phase 1) (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=20878 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Arcane Fiend - On Target Cast - Cast Counterspell +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=24819 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Lord Kragaru - On Victim Casting 'null' - Cast 'Pummel' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=31779 AND `source_type`=0 AND `id`=3 AND `link`=0; -- Blackrock Raider - Target Casting - Cast 'Pummel' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=3385 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Saltspittle Warrior - Target Casting - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=2421 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Defias Knuckleduster - In Combat - Cast 'Pummel' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=745 AND `source_type`=0 AND `id`=2 AND `link`=0; -- Unliving Soldier - In Combat - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=1563 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Winterskorn Raider - Target Casting - Cast 'Kick' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=1894 AND `source_type`=0 AND `id`=4 AND `link`=0; -- Deathshadow Spellbinder - In Combat - Cast 'Counterspell' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=5999 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Gordunni Back-Breaker - In Combat - Cast 'Kick' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=10758 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Anub'ar Champion - On Hostile Casting in Range - Cast 'Pummel' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=4845 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Stromgarde Defender - In Combat - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=6005 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Felhound Manastalker - In Combat - Cast Spell Lock +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=27260 AND `source_type`=0 AND `id`=5 AND `link`=0; -- Shandaral Warrior Spirit - Target Casting - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=29096 AND `source_type`=0 AND `id`=2 AND `link`=0; -- Anub'ar Champion - Target Casting - Cast 'Pummel' (Phase 1) (No Repeat) (Dungeon) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=10952 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Tormented Drakkari - Target Casting - Cast 'Kick' (Phase 1) (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=17612 AND `source_type`=0 AND `id`=13 AND `link`=0; -- Korgaah - In Combat - Cast '11978' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=21254 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Argent Protector - In Combat - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=30180 AND `source_type`=0 AND `id`=11 AND `link`=0; -- Skullsplitter Warrior - In Combat - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=18642 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Zanzil Naga - In Combat - Cast 'Pummel' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=16250 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Captain Vachon - In Combat - Cast '72' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=16305 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Deadwind Villager - In Combat - Cast 'Kick' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=24214 AND `source_type`=0 AND `id`=4 AND `link`=0; -- Unyielding Footman - In Combat - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=24215 AND `source_type`=0 AND `id`=4 AND `link`=0; -- Skeletal Berserker - Victim Casting - Cast Pummel +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=587 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Scarlet Vanguard - In Combat - Cast '72' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=7091 AND `source_type`=0 AND `id`=2 AND `link`=0; -- Jaedenar Guardian - In Combat - Cast '11972' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=30160 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Unliving Resident - In Combat - Cast 'Kick' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=2599 AND `source_type`=0 AND `id`=2 AND `link`=0; -- Elder Diemetradon - In Combat - Cast 'Pummel' (Normal Dungeon) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=4961 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Warlord Morkh - In Combat - Cast 'Kick' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=11682 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Grim Patron - In Combat - Cast 'Kick' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=17304 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Ironpatch - In Combat - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=26357 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Captain Fairmount - Target Casting - Cast 'Pummel' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=2431 AND `source_type`=0 AND `id`=2 AND `link`=0; -- Wrekt Slave - In Combat - Cast 'Kick' (Phase 1) (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=2893 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Ango'rosh Ogre - In Combat - Cast 'Kick' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=4481 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Kil'sorrow Spellbinder - Target Casting - Cast 'Counterspell' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=10696 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Phasing Soldier - Target Casting - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=2243 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Firemane Scalebane - In Combat - Cast Shield Bash +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=3129 AND `source_type`=0 AND `id`=0 AND `link`=0; -- Forsaken Plaguebringer - In Combat - Cast 'Kick' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=19852 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Lieutenant Benedict - Target Casting - Cast 'Shield Bash' +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=3129 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Dragonmaw Centurion - In Combat - Cast 'Shield Bash' (No Repeat) +UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=121 AND `source_type`=0 AND `id`=2 AND `link`=0; -- Shattered Hand Grunt - In Combat - Cast 'Kick' (Phase 2) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index e199cbc09..e366560c9 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -4790,12 +4790,10 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); return; } - - // If no targets are found and it's off cooldown, check again in 1200ms - RecalcTimer(e, 1200, 1200); - break; } + // No targets found + RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); break; } case SMART_EVENT_AREA_RANGE: From ebe11235d2a5c41f0fa8d1daad4e38e26ef3d3b6 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:06:13 -0300 Subject: [PATCH 049/335] fix(Core/Pet): Allow Pets to attack players from any angle (#24580) --- src/server/game/AI/CoreAI/PetAI.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index c4a39d663..1c8222126 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -634,9 +634,11 @@ void PetAI::DoAttack(Unit* target, bool chase) if (_canMeleeAttack()) { - float angle = combatRange == 0.f && !target->IsPlayer() && !target->IsPet() ? float(M_PI) : 0.f; - float tolerance = combatRange == 0.f ? float(M_PI_4) : float(M_PI * 2); - me->GetMotionMaster()->MoveChase(target, ChaseRange(0.f, combatRange), ChaseAngle(angle, tolerance)); + std::optional chaseAngle; + if (combatRange == 0.f && !target->IsPlayer() && !target->IsPet()) + chaseAngle.emplace(float(M_PI), float(M_PI_4)); + + me->GetMotionMaster()->MoveChase(target, ChaseRange(0.f, combatRange), chaseAngle); } } else // (Stay && ((Aggressive || Defensive) && In Melee Range))) From 5949d54f0ef2f371959dc41dc6c7b756ba43946b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 6 Feb 2026 21:06:34 +0000 Subject: [PATCH 050/335] chore(DB): import pending files Referenced commit(s): b521a3927d411f3d9757e37f2cb6f921a5253d9d --- .../rev_1769117901544014100.sql => db_world/2026_02_06_03.sql} | 1 + .../rev_1769891519807069500.sql => db_world/2026_02_06_04.sql} | 1 + .../rev_1770063321798974800.sql => db_world/2026_02_06_05.sql} | 1 + .../rev_1770249033416011200.sql => db_world/2026_02_06_06.sql} | 1 + 4 files changed, 4 insertions(+) rename data/sql/updates/{pending_db_world/rev_1769117901544014100.sql => db_world/2026_02_06_03.sql} (99%) rename data/sql/updates/{pending_db_world/rev_1769891519807069500.sql => db_world/2026_02_06_04.sql} (99%) rename data/sql/updates/{pending_db_world/rev_1770063321798974800.sql => db_world/2026_02_06_05.sql} (90%) rename data/sql/updates/{pending_db_world/rev_1770249033416011200.sql => db_world/2026_02_06_06.sql} (86%) diff --git a/data/sql/updates/pending_db_world/rev_1769117901544014100.sql b/data/sql/updates/db_world/2026_02_06_03.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1769117901544014100.sql rename to data/sql/updates/db_world/2026_02_06_03.sql index 48c35cd78..f6d12cbba 100644 --- a/data/sql/updates/pending_db_world/rev_1769117901544014100.sql +++ b/data/sql/updates/db_world/2026_02_06_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_06_02 -> 2026_02_06_03 -- Vyragosa UPDATE `creature_template` SET `speed_run` = 1.142857, `unit_flags` = `unit_flags`|64|32768 WHERE (`entry` = 32630); UPDATE `creature_model_info` SET `CombatReach` = 15 WHERE `DisplayID` = 28110; diff --git a/data/sql/updates/pending_db_world/rev_1769891519807069500.sql b/data/sql/updates/db_world/2026_02_06_04.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1769891519807069500.sql rename to data/sql/updates/db_world/2026_02_06_04.sql index 45af183dd..514789c42 100644 --- a/data/sql/updates/pending_db_world/rev_1769891519807069500.sql +++ b/data/sql/updates/db_world/2026_02_06_04.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_06_03 -> 2026_02_06_04 -- UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=16867 AND `source_type`=0 AND `id`=1 AND `link`=0; -- Defias Pathstalker - In Combat - Cast 'Shield Bash' (No Repeat) UPDATE `smart_scripts` SET `event_chance`=25 WHERE `entryorguid`=1036 AND `source_type`=0 AND `id`=3 AND `link`=0; -- Kul Tiras Marine - In Combat - Cast 'Shield Bash' (No Repeat) diff --git a/data/sql/updates/pending_db_world/rev_1770063321798974800.sql b/data/sql/updates/db_world/2026_02_06_05.sql similarity index 90% rename from data/sql/updates/pending_db_world/rev_1770063321798974800.sql rename to data/sql/updates/db_world/2026_02_06_05.sql index 549437421..abecd7f68 100644 --- a/data/sql/updates/pending_db_world/rev_1770063321798974800.sql +++ b/data/sql/updates/db_world/2026_02_06_05.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_06_04 -> 2026_02_06_05 -- UPDATE `creature_template` SET `faction` = 1692 WHERE (`entry` = 22228); UPDATE `creature_template` SET `flags_extra` = `flags_extra`|128 WHERE (`entry` IN (19381, 22228)); diff --git a/data/sql/updates/pending_db_world/rev_1770249033416011200.sql b/data/sql/updates/db_world/2026_02_06_06.sql similarity index 86% rename from data/sql/updates/pending_db_world/rev_1770249033416011200.sql rename to data/sql/updates/db_world/2026_02_06_06.sql index c7e7f30a1..2b2d9fd40 100644 --- a/data/sql/updates/pending_db_world/rev_1770249033416011200.sql +++ b/data/sql/updates/db_world/2026_02_06_06.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_06_05 -> 2026_02_06_06 -- DELETE FROM `spell_target_position` WHERE `ID` = 33244 AND `EffectIndex` = 0; INSERT INTO `spell_target_position` (`ID`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `VerifiedBuild`) VALUES From cda6e619d049703dbbfbf8608bf9df86a277c34b Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:07:27 -0300 Subject: [PATCH 051/335] fix(Core/Threat): Melee creatures should only target units they can attack when rooted (#24526) --- src/server/game/Combat/ThreatMgr.cpp | 3 +++ .../BlackrockMountain/MoltenCore/boss_ragnaros.cpp | 1 + .../Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp | 5 ----- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/server/game/Combat/ThreatMgr.cpp b/src/server/game/Combat/ThreatMgr.cpp index 59da5a32a..432c0b396 100644 --- a/src/server/game/Combat/ThreatMgr.cpp +++ b/src/server/game/Combat/ThreatMgr.cpp @@ -468,6 +468,9 @@ bool ThreatContainer::IsPreferredTarget(Creature* attacker, Unit* target) const if (target->HasAuraTypeWithCaster(SPELL_AURA_IGNORED, attacker->GetGUID())) return false; + if (attacker->HasUnitState(UNIT_STATE_ROOT) && attacker->IsCombatMovementAllowed() && !attacker->IsWithinMeleeRange(target)) + return false; + return true; } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp index b5d3ece2d..a0d2f2b50 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp @@ -254,6 +254,7 @@ public: bool CanAIAttack(Unit const* victim) const override { + // Used for Magma Blast handling to force EnterEvadeMode if there are no melee targets return me->IsWithinMeleeRange(victim); } diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp index 649b5e579..60feacbce 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp @@ -85,11 +85,6 @@ struct boss_murmur : public BossAI }, 3600ms, 10900ms, GROUP_OOC_CAST); } - bool CanAIAttack(Unit const* victim) const override - { - return me->IsWithinMeleeRange(victim); - } - void EnterEvadeMode(EvadeReason why) override { if (me->GetThreatMgr().GetThreatList().empty()) From c09ee1ddf395f8f34628c36ff36a57a6c10612ba Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:08:27 -0300 Subject: [PATCH 052/335] fix(Core/Movement): Prevent Follow predictions from clipping through walls and add teleport as last resort (#24287) --- .../TargetedMovementGenerator.cpp | 53 ++++++++++++++++--- .../TargetedMovementGenerator.h | 2 +- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 4f593795e..915124257 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -461,8 +461,7 @@ static Optional GetVelocity(Unit* owner, Unit* target, G3D::Vector3 const static Position const PredictPosition(Unit* target) { Position pos = target->GetPosition(); - - // 0.5 - it's time (0.5 sec) between starting movement opcode (e.g. MSG_MOVE_START_FORWARD) and MSG_MOVE_HEARTBEAT sent by client + // 0.5 - it's time (0.5 sec) between starting movement opcode (e.g. MSG_MOVE_START_FORWARD) and MSG_MOVE_HEARTBEAT sent by client float speed = target->GetSpeed(Movement::SelectSpeedType(target->GetUnitMovementFlags())) * 0.5f; float orientation = target->GetOrientation(); @@ -491,6 +490,20 @@ static Position const PredictPosition(Unit* target) return pos; } +static bool IsValidPredictedPosition(Unit* target, Position const& predicted) +{ + Position current = target->GetPosition(); + + if (current.GetExactDist2d(&predicted) > 15.0f) + return false; + + // Check line of sight from current to predicted to avoid clipping through geometry + if (!target->IsWithinLOS(predicted.GetPositionX(), predicted.GetPositionY(), predicted.GetPositionZ())) + return false; + + return true; +} + template bool FollowMovementGenerator::PositionOkay(Unit* target, bool isPlayerPet, bool& targetIsMoving, uint32 diff) { @@ -571,7 +584,10 @@ bool FollowMovementGenerator::DoUpdate(T* owner, uint32 time_diff) ; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to bool targetIsMoving = false; - if (PositionOkay(target, owner->IsGuardian() && target->IsPlayer(), targetIsMoving, time_diff)) + bool isPlayerPet = owner->IsGuardian() && target->IsPlayer(); + bool isFollowingPlayer = target->IsPlayer(); + + if (PositionOkay(target, isPlayerPet, targetIsMoving, time_diff)) { if (owner->HasUnitState(UNIT_STATE_FOLLOW_MOVE) && owner->movespline->Finalized()) { @@ -599,14 +615,23 @@ bool FollowMovementGenerator::DoUpdate(T* owner, uint32 time_diff) if (_lastPredictedPosition && _lastPredictedPosition->GetExactDistSq(&predictedPosition) < 0.25f) return true; - _lastPredictedPosition = predictedPosition; - targetPosition = predictedPosition; - i_recheckPredictedDistance = true; + if (IsValidPredictedPosition(target, predictedPosition)) + { + _lastPredictedPosition = predictedPosition; + targetPosition = predictedPosition; + i_recheckPredictedDistance = true; + } + else + { + _lastPredictedPosition.reset(); + i_recheckPredictedDistance = false; + } } else { i_recheckPredictedDistance = false; i_recheckPredictedDistanceTimer.Reset(0); + _lastPredictedPosition.reset(); } if (!i_path) @@ -628,6 +653,22 @@ bool FollowMovementGenerator::DoUpdate(T* owner, uint32 time_diff) if (!owner->IsStopped()) owner->StopMoving(); + // Teleport if stuck and too far away + if (cOwner && isFollowingPlayer) + { + float distance = owner->GetDistance(target); + if (distance > 20.f) + { + float teleX; + float teleY; + float teleZ; + + target->GetClosePoint(teleX, teleY, teleZ, owner->GetCombatReach()); + owner->NearTeleportTo(teleX, teleY, teleZ, target->GetOrientation()); + _lastTargetPosition.reset(); + _lastPredictedPosition.reset(); + } + } return true; } diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 4e7721be3..913738a92 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -91,7 +91,7 @@ class FollowMovementGenerator : public MovementGeneratorMedium Date: Fri, 6 Feb 2026 17:10:02 -0500 Subject: [PATCH 053/335] feat(Core/Config): Add configuration options for point multipliers for arena team brackets. (#24631) --- src/server/apps/worldserver/worldserver.conf.dist | 14 ++++++++++++++ src/server/game/Battlegrounds/ArenaTeam.cpp | 4 ++-- src/server/game/World/WorldConfig.cpp | 2 ++ src/server/game/World/WorldConfig.h | 2 ++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index b445450e1..67db345c7 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -2501,6 +2501,20 @@ Arena.LegacyArenaPoints = 0 Rate.ArenaPoints = 1 +# +# Rate.ArenaPoints2v2 +# Description: Arena points gain rate for 2v2 bracket. +# Default: 0.76 + +Rate.ArenaPoints2v2 = 0.76 + +# +# Rate.ArenaPoints3v3 +# Description: Arena points gain rate for 3v3 bracket. +# Default: 0.88 + +Rate.ArenaPoints3v3 = 0.88 + # # PvPToken.Enable # Description: Character will receive a token after defeating another character that yields diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index 985193f9d..2b6265e7c 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -671,9 +671,9 @@ uint32 ArenaTeam::GetPoints(uint32 memberRating) // Type penalties for teams < 5v5 if (Type == ARENA_TEAM_2v2) - points *= 0.76f; + points *= sWorld->getRate(RATE_ARENA_POINTS_2V2); else if (Type == ARENA_TEAM_3v3) - points *= 0.88f; + points *= sWorld->getRate(RATE_ARENA_POINTS_3V3); sScriptMgr->OnGetArenaPoints(this, points); diff --git a/src/server/game/World/WorldConfig.cpp b/src/server/game/World/WorldConfig.cpp index 1936df510..81a55435b 100644 --- a/src/server/game/World/WorldConfig.cpp +++ b/src/server/game/World/WorldConfig.cpp @@ -117,6 +117,8 @@ void WorldConfig::BuildConfigCache() SetConfigValue(RATE_AUCTION_CUT, "Rate.Auction.Cut", 1.0f); SetConfigValue(RATE_HONOR, "Rate.Honor", 1.0f); SetConfigValue(RATE_ARENA_POINTS, "Rate.ArenaPoints", 1.0f); + SetConfigValue(RATE_ARENA_POINTS_2V2, "Rate.ArenaPoints2v2", 0.76f); + SetConfigValue(RATE_ARENA_POINTS_3V3, "Rate.ArenaPoints3v3", 0.88f); SetConfigValue(RATE_INSTANCE_RESET_TIME, "Rate.InstanceResetTime", 1.0f); SetConfigValue(RATE_MISS_CHANCE_MULTIPLIER_TARGET_CREATURE, "Rate.MissChanceMultiplier.TargetCreature", 11.0f); diff --git a/src/server/game/World/WorldConfig.h b/src/server/game/World/WorldConfig.h index 21efea51b..dabe2e222 100644 --- a/src/server/game/World/WorldConfig.h +++ b/src/server/game/World/WorldConfig.h @@ -471,6 +471,8 @@ enum ServerConfigs RATE_AUCTION_CUT, RATE_HONOR, RATE_ARENA_POINTS, + RATE_ARENA_POINTS_2V2, + RATE_ARENA_POINTS_3V3, RATE_TALENT, RATE_TALENT_PET, RATE_CORPSE_DECAY_LOOTED, From dfc5ebbbab5e6093d16c914eafbd47c95e92e2bb Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 6 Feb 2026 16:18:59 -0600 Subject: [PATCH 054/335] fix(Core/Handlers): Handle vehicle and possess spells in CMSG_REQUEST_PET_INFO (#24575) Co-authored-by: blinkysc Co-authored-by: Faq --- src/server/game/Handlers/MiscHandler.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index c6485d813..c8af95af2 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1560,8 +1560,15 @@ void WorldSession::HandleRequestPetInfo(WorldPackets::Pet::RequestPetInfo& /*pac if (_player->GetPet()) _player->PetSpellInitialize(); - else if (_player->GetCharm()) - _player->CharmSpellInitialize(); + else if (Unit* charm = _player->GetCharm()) + { + if (charm->HasUnitState(UNIT_STATE_POSSESSED)) + _player->PossessSpellInitialize(); + else if (charm->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED) && charm->HasUnitFlag(UNIT_FLAG_POSSESSED)) + _player->VehicleSpellInitialize(); + else + _player->CharmSpellInitialize(); + } } void WorldSession::HandleSetTaxiBenchmarkOpcode(WorldPacket& recv_data) From fe71aca4153ddc7100b0426176e8bb1194828830 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 19:19:07 -0300 Subject: [PATCH 055/335] fix(DB/SAI): Rewrite Terokk's Downfall with Sniffed data (#24627) --- .../rev_1770302622700625500.sql | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770302622700625500.sql diff --git a/data/sql/updates/pending_db_world/rev_1770302622700625500.sql b/data/sql/updates/pending_db_world/rev_1770302622700625500.sql new file mode 100644 index 000000000..b18ea9c5c --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770302622700625500.sql @@ -0,0 +1,125 @@ +-- +UPDATE `creature_template` SET `unit_flags` = `unit_flags`|64|32768 WHERE (`entry` = 21838); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 21838); +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 +(21838, 0, 0, 0, 0, 0, 100, 0, 4000, 7000, 10000, 15000, 0, 0, 11, 40721, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - In Combat - Cast \'Shadow Bolt Volley\''), +(21838, 0, 1, 0, 0, 0, 100, 0, 6000, 9000, 7000, 9000, 0, 0, 11, 15284, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - In Combat - Cast \'Cleave\''), +(21838, 0, 2, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2183800, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - On Just Summoned - Run Script'), +(21838, 0, 3, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 112, 97, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - On Aggro - Start Skyguard Ace Event'), +(21838, 0, 4, 0, 0, 0, 100, 0, 18000, 30000, 16000, 32000, 0, 0, 80, 2183801, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - In Combat and Outside \'Divine Shield\' Phase - Run Chosen One Script'), -- Only Outside Divine Shield +(21838, 0, 5, 6, 0, 0, 100, 0, 45000, 60000, 45000, 75000, 0, 0, 11, 40733, 32, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - In Combat - Cast \'Divine Shield\''), +(21838, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - On \'Divine Shield\' Cast - Say Line 1'), +(21838, 0, 7, 8, 32, 0, 100, 0, 0, 1000000, 0, 0, 0, 0, 28, 40733, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - On Damaged by \'Ancient Flames\' - Remove Aura \'Divine Shield\' (Phase 1)'), -- Only with Divine Shield +(21838, 0, 8, 9, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - On Spellhit \'Ancient Flames\' - Say Line 2'), +(21838, 0, 9, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 28747, 34, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - On Spellhit \'Ancient Flames\' - Cast \'Frenzy\''), +(21838, 0, 10, 11, 7, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 2, 0, 0, 0, 0, 0, 10, 12478, 23377, 0, 0, 0, 0, 0, 0, 'Terokk - On Evade - Do Action on Skyguard Ace Retreat'), +(21838, 0, 11, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - On Evade - Despawn Instant'), +(21838, 0, 12, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 10, 12478, 23377, 0, 0, 0, 0, 0, 0, 'Terokk - On Just Died - Do Action Terokk Dead'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2183800); +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 +(2183800, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - Actionlist - Set Flags Immune To Players & Immune To NPC\'s'), +(2183800, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 24240, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - Actionlist - Cast \'Spawn - Red Lightning\''), +(2183800, 9, 2, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 39579, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - Actionlist - Cast \'Shadowform\''), +(2183800, 9, 3, 0, 0, 0, 100, 0, 400, 400, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - Actionlist - Say Line 3'), +(2183800, 9, 4, 0, 0, 0, 100, 0, 10000, 10000, 0, 0, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - Actionlist - Remove Flags Immune To Players & Immune To NPC\'s'), +(2183800, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - Actionlist - Start Attacking'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2183801); +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 +(2183801, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 0, 'Terokk - Actionlist - Store Targetlist'), +(2183801, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 1, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Terokk - Actionlist - Say Line 4'), +(2183801, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 40726, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Terokk - Actionlist - Cast \'Chosen One\''), +(2183801, 9, 3, 0, 0, 0, 100, 0, 500, 500, 0, 0, 0, 0, 11, 40722, 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Terokk - Actionlist - Cast \'Will of the Arakkoa God\''); + +DELETE FROM `game_event` WHERE `eventEntry` = 97; +INSERT INTO `game_event` (`eventEntry`, `start_time`, `end_time`, `occurence`, `length`, `holiday`, `holidayStage`, `description`, `world_event`, `announce`) VALUES +(97, NULL, NULL, 5184000, 2592000, 0, 0, 'Terokk Boss Event', 0, 2); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -12478); +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 +(-12478, 0, 1000, 0, 60, 0, 100, 0, 10000, 10000, 20000, 30000, 0, 0, 11, 40655, 0, 0, 0, 0, 0, 19, 21838, 60, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Update - Cast \'Skyguard Flare\''), +(-12478, 0, 1001, 0, 17, 0, 100, 0, 23277, 0, 0, 0, 0, 0, 11, 40657, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Summoning Skyguard Target - Cast \'Ancient Flames\''), +(-12478, 0, 1002, 0, 17, 0, 100, 0, 23277, 0, 0, 0, 0, 0, 41, 30000, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Summoning Skyguard Target - Despawn Summon in 30s'), +(-12478, 0, 1003, 0, 17, 0, 100, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Summoning Skyguard Target - Say Line 1'), +(-12478, 0, 1004, 0, 109, 0, 100, 0, 0, 124781, 0, 0, 0, 0, 80, 2337700, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Path Arrive Finished - Run Script'), +(-12478, 0, 1005, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 124781, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Respawn - Start Path Arrive'), +(-12478, 0, 1006, 1008, 72, 0, 100, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Success - Say Line 3'), +(-12478, 0, 1007, 1008, 72, 0, 100, 0, 2, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Quest Fail - Say Line 4'), +(-12478, 0, 1008, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 124783, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Quest Success or Fail - Start Path Leave'), +(-12478, 0, 1009, 0, 109, 0, 100, 0, 0, 124783, 0, 0, 0, 0, 111, 97, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Path Leave Finished - End Terokk Boss Event'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2337700); +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 +(2337700, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - Actionlist - Say Line 2'), +(2337700, 9, 1, 0, 0, 0, 100, 0, 1200, 1200, 0, 0, 0, 0, 232, 124782, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - Actionlist - Start Path Circle'); + +UPDATE `creature_template` SET `unit_flags` = 2, `flags_extra` = `flags_extra`|134217728 WHERE (`entry` = 23377); +UPDATE `creature_template` SET `speed_run` = 1.71428 WHERE (`entry` = 23377); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23377); +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 +(23377, 0, 0, 0, 37, 0, 100, 0, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Initialize - Set Active On'), +(23377, 0, 1, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Respawn - Set Run On'), +(23377, 0, 2, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Ace - On Respawn - Set Reactstate Passive'); + +UPDATE `creature_template_addon` SET `auras` = '40656' WHERE (`entry` = 23277); +UPDATE `creature_template` SET `AIName` = 'NullCreatureAI' WHERE `entry` = 23277; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23277); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 21838) AND (`GroupID` IN (4)); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(21838, 4, 0, 'Show me what you\'re made of, $n!', 14, 0, 100, 0, 0, 0, 21327, 0, 'Terokk Chosen One'); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 23377) AND (`GroupID` IN (4)); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23377, 4, 0, 'Abort mission! Our ground forces have been defeated.', 14, 0, 100, 0, 0, 0, 21438, 0, 'Skyguard Ace Defeat'); + +DELETE FROM `waypoint_data` WHERE `id` IN (124781, 124782, 124783); +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`move_type`) VALUES +-- Skyguard Enter +(124781, 1, -3335.223, 3431.9473, 426.38644, NULL, 2), +(124781, 2, -3548.365, 3463.0986, 365.91205, NULL, 2), +(124781, 3, -3548.365, 3463.0986, 365.91205, NULL, 2), +(124781, 4, -3548.365, 3463.0986, 365.91205, NULL, 2), +-- Skyguard Circle +(124782, 1, -3761.507, 3494.25, 305.43765 , NULL, 2), +(124782, 2, -3746.0168, 3524.3342, 304.60434, NULL, 2), +(124782, 3, -3779.0083, 3555.692, 304.3266 , NULL, 2), +(124782, 4, -3821.4905, 3536.9502, 304.38208, NULL, 2), +(124782, 5, -3830.6106, 3503.1016, 303.99332, NULL, 2), +(124782, 6, -3805.376, 3480.2854, 302.40988 , NULL, 2), +(124782, 7, -3774.9329, 3484.5464, 305.43765, NULL, 2), +-- Skyguard Leave +(124783, 1, -3697.9067, 3470.4912, 315.2088 , NULL, 2), +(124783, 2, -3668.2097, 3478.07, 330.95886 , NULL, 2), +(124783, 3, -3632.0579, 3477.3137, 339.87555, NULL, 2), +(124783, 4, -3586.6597, 3462.7095, 351.9589 , NULL, 2); + +DELETE FROM `creature` WHERE `guid` IN (12478, 12479, 12480) AND `id1` = 23377; +INSERT INTO `creature` (`guid`, `id1`, `map`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(12478, 23377, 530, 1, -3335.223, 3431.9473, 426.38644, 0, 300, 52237, 1, 'Skyguard Ace from Terokk Boss Event'), +(12479, 23377, 530, 1, -3335.223, 3431.9473, 426.38644, 0, 300, 52237, 1, 'Skyguard Ace from Terokk Boss Event'), +(12480, 23377, 530, 1, -3335.223, 3431.9473, 426.38644, 0, 300, 52237, 1, 'Skyguard Ace from Terokk Boss Event'); + +DELETE FROM `creature_formations` WHERE (`leaderGUID` = 12478); +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(12478, 12478, 0, 0, 512, 0, 0), +(12478, 12479, 6, 120, 512, 0, 0), +(12478, 12480, 6, 240, 512, 0, 0); + +DELETE FROM `game_event_creature` WHERE `eventEntry` = 97; +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES +(97, 12478), +(97, 12479), +(97, 12480); + +UPDATE `event_scripts` SET `x`=-3788.8564, `y`=3507.526, `z`=286.88455, `o`=3.159045934677124023 WHERE `id`=15014; + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 22) AND (`SourceGroup` = 5) AND (`SourceEntry` = 21838) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 1) AND (`ConditionTarget` = 1) AND (`ConditionValue1` = 40733) AND (`ConditionValue2` = 0) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22, 5, 21838, 0, 0, 1, 1, 40733, 0, 0, 1, 0, 0, '', 'Only use Chosen One script when outside Divine Shield phase'); +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 22) AND (`SourceGroup` = 8) AND (`SourceEntry` = 21838) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 1) AND (`ConditionTarget` = 1) AND (`ConditionValue1` = 40733) AND (`ConditionValue2` = 0) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22, 8, 21838, 0, 0, 1, 1, 40733, 0, 0, 0, 0, 0, '', 'Only remove Divine Shield during the Divine Shield phase'); From 57090a530288d1cb32c63287494b66b7f0257576 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 6 Feb 2026 19:19:23 -0300 Subject: [PATCH 056/335] fix(Scripts/SSC): Rewrite Coilfang Water Handling (#24559) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../rev_1769808422811823800.sql | 124 ++++++++++++++++++ .../SerpentShrine/instance_serpent_shrine.cpp | 77 ++++++----- .../SerpentShrine/serpent_shrine.h | 12 +- 3 files changed, 174 insertions(+), 39 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1769808422811823800.sql diff --git a/data/sql/updates/pending_db_world/rev_1769808422811823800.sql b/data/sql/updates/pending_db_world/rev_1769808422811823800.sql new file mode 100644 index 000000000..e29d906e8 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769808422811823800.sql @@ -0,0 +1,124 @@ +-- +DELETE FROM `spell_area` WHERE `spell` = 37280 AND `area` = 3607; +INSERT INTO `spell_area` (`spell`, `area`, `quest_start`, `quest_end`, `aura_spell`, `racemask`, `gender`, `autocast`, `quest_start_status`, `quest_end_status`) VALUES +(37280, 3607, 0, 0, 0, 0, 2, 1, 64, 11); + +DELETE FROM `spell_script_names` WHERE `spell_id`=37025 AND `ScriptName`='spell_serpentshrine_cavern_coilfang_water'; +DELETE FROM `spell_script_names` WHERE `spell_id`=37280 AND `ScriptName`='spell_serpentshrine_cavern_coilfang_water'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(37280, 'spell_serpentshrine_cavern_coilfang_water'); + +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|134217728 WHERE (`entry` IN (21218, 21220, 21263, 21301)); + +DELETE FROM `smart_scripts` WHERE `action_type` = 34 AND `action_param1` IN (20, 21) AND `entryorguid` IN (21220, 21301) AND `source_type` = 0; + +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `id` IN (1004, 1005) AND `action_type` = 34 AND `entryorguid` IN (-153022,-153023,-153024,-153025,-153026,-153027,-153028,-153029,-153030,-153031,-153032,-153033,-153034,-153035,-153036,-153037,-153038,-153039,-153040,-153041,-153042,-153043,-153044,-153045,-153046,-153047,-153048,-153049,-153050,-153051,-153052,-153053,-153054,-153055,-153056,-153057,-153058,-153059,-153060,-153061,-153062,-153063,-153064,-153065,-153066,-153067,-153068,-153069,-153070,-153071,-153072,-153073,-153074,-153075); +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 +(-153022, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153022, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153023, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153023, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153024, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153024, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153025, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153025, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153026, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153026, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153027, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153027, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153028, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153028, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153029, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153029, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153030, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153030, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153031, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153031, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153032, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153032, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153033, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153033, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153034, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153034, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153035, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153035, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153036, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153036, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153037, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153037, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153038, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153038, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153039, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153039, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153040, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153040, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153041, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153041, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153042, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153042, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153043, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153043, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153044, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153044, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153045, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153045, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153046, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153046, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153047, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153047, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153048, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153048, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153049, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153049, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153050, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153050, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153051, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153051, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153052, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153052, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153053, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153053, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153054, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153054, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153055, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153055, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153056, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153056, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153057, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153057, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153058, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153058, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153059, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153059, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153060, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153060, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153061, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153061, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153062, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153062, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153063, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153063, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153064, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153064, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153065, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153065, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153066, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153066, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153067, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153067, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153068, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153068, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153069, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153069, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153070, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153070, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153071, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153071, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153072, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153072, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153073, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153073, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153074, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153074, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'), +(-153075, 0, 1004, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 20, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Respawn - Set Instance Data 20 to 1'), +(-153075, 0, 1005, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 34, 21, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Keeper Trash - On Just Died - Set Instance Data 21 to 1'); diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp index a587630f2..af78127f1 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp @@ -89,6 +89,7 @@ public: LoadSummonData(summonData); _aliveKeepersCount = 0; + _frenzyCount = 0; } bool SetBossState(uint32 type, EncounterState state) override @@ -129,11 +130,6 @@ public: { switch (creature->GetEntry()) { - case NPC_COILFANG_SHATTERER: - case NPC_COILFANG_PRIESTESS: - if (creature->GetPositionX() > 190.0f) - --_aliveKeepersCount; - break; case NPC_CYCLONE_KARATHRESS: creature->GetMotionMaster()->MoveRandom(50.0f); break; @@ -141,12 +137,27 @@ public: creature->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); creature->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); break; + case NPC_COILFANG_FRENZY: + if (!creature->IsInWater() || _frenzyCount >= MAX_FRENZY_COUNT) + creature->DespawnOrUnsummon(); + else + ++_frenzyCount; + break; default: break; } InstanceScript::OnCreatureCreate(creature); } + void OnCreatureRemove(Creature* creature) override + { + if (creature->GetEntry() == NPC_COILFANG_FRENZY) + if (_frenzyCount > 0) + --_frenzyCount; + + InstanceScript::OnCreatureRemove(creature); + } + void SetData(uint32 type, uint32 /*data*/) override { switch (type) @@ -185,7 +196,8 @@ public: private: ObjectGuid _shieldGeneratorGUID[4]; - int32 _aliveKeepersCount; + uint32 _aliveKeepersCount; + uint32 _frenzyCount; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override @@ -269,53 +281,46 @@ class spell_serpentshrine_cavern_coilfang_water : public AuraScript { PrepareAuraScript(spell_serpentshrine_cavern_coilfang_water); - void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (InstanceScript* instance = GetUnitOwner()->GetInstanceScript()) - if (instance->GetBossState(DATA_THE_LURKER_BELOW) != DONE) - if (instance->GetData(DATA_ALIVE_KEEPERS) == 0) - GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_SCALDING_WATER, true); - } - - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { GetUnitOwner()->RemoveAurasDueToSpell(SPELL_SCALDING_WATER); } - void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& isPeriodic, int32& amplitude) - { - InstanceScript* instance = GetUnitOwner()->GetInstanceScript(); - if (!instance || instance->GetBossState(DATA_THE_LURKER_BELOW) == DONE) - return; - - isPeriodic = true; - amplitude = 8 * IN_MILLISECONDS; - } - - void HandlePeriodic(AuraEffect const* /*aurEff*/) + void HandlePeriodic(AuraEffect const* /*aurEff*/) { PreventDefaultAction(); + InstanceScript* instance = GetUnitOwner()->GetInstanceScript(); if (!instance || GetUnitOwner()->GetMapId() != MAP_COILFANG_SERPENTSHRINE_CAVERN) { - SetDuration(0); + GetAura()->SetDuration(1); return; } - if (instance->GetBossState(DATA_THE_LURKER_BELOW) == DONE || instance->GetData(DATA_ALIVE_KEEPERS) == 0 || GetUnitOwner()->GetPositionZ() > -20.5f || !GetUnitOwner()->IsInWater()) - return; + if (instance->GetBossState(DATA_THE_LURKER_BELOW) != DONE && GetUnitOwner()->IsInWater()) + { + if (instance->GetData(DATA_ALIVE_KEEPERS) > 0) + for (uint8 i = 0; i < urand(2, 3); ++i) + GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_SERVERSIDE_SUMMON_FRENZY, true); - for (uint8 i = 0; i < 3; ++i) - GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_FRENZY_WATER, true); + if (instance->GetData(DATA_ALIVE_KEEPERS) <= 0 && !GetUnitOwner()->HasAura(SPELL_SCALDING_WATER)) + GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_SCALDING_WATER, true); + + return; + } + else if (instance->GetBossState(DATA_THE_LURKER_BELOW) == DONE) + { + GetAura()->SetDuration(1); + return; + } + + GetUnitOwner()->RemoveAurasDueToSpell(SPELL_SCALDING_WATER); } void Register() override { - AfterEffectApply += AuraEffectApplyFn(spell_serpentshrine_cavern_coilfang_water::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_serpentshrine_cavern_coilfang_water::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - - DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_serpentshrine_cavern_coilfang_water::CalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY); - OnEffectPeriodic += AuraEffectPeriodicFn(spell_serpentshrine_cavern_coilfang_water::HandlePeriodic, EFFECT_0, SPELL_AURA_DUMMY); + AfterEffectRemove += AuraEffectRemoveFn(spell_serpentshrine_cavern_coilfang_water::HandleEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_serpentshrine_cavern_coilfang_water::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); } }; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h index 722bb475b..d1a83adf3 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h @@ -69,6 +69,7 @@ enum SSNPCs NPC_COILFANG_STRIDER = 22056, NPC_TAINTED_ELEMENTAL = 22009, NPC_TOXIC_SPOREBAT = 22140, + NPC_COILFANG_FRENZY = 21508, GO_LADY_VASHJ_BRIDGE_CONSOLE = 184568, GO_COILFANG_BRIDGE1 = 184203, @@ -88,13 +89,18 @@ enum SSSpells SPELL_SUMMON_SERPENTSHRINE_PARASITE = 39045, SPELL_RAMPART_INFECTION = 39042, SPELL_SCALDING_WATER = 37284, - SPELL_FRENZY_WATER = 37026 + + // SPELL_SERVERSIDE_COILFANG_WATER = 37025, // Dummy Aura, unused + SPELL_SERVERSIDE_SUMMON_FRENZY = 37026, + SPELL_SERVERSIDE_FRENZY_WATER_PERIODIC = 37280 }; -enum KeeperCount +enum SSNPCCount { MIN_KEEPER_COUNT = 0, - MAX_KEEPER_COUNT = 24 + MAX_KEEPER_COUNT = 54, + + MAX_FRENZY_COUNT = 50 }; template From 29be3483b696e272d1647ee2bdbc1959b15ee1c1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 6 Feb 2026 22:46:48 +0000 Subject: [PATCH 057/335] chore(DB): import pending files Referenced commit(s): dfc5ebbbab5e6093d16c914eafbd47c95e92e2bb --- .../rev_1769808422811823800.sql => db_world/2026_02_06_07.sql} | 1 + .../rev_1770302622700625500.sql => db_world/2026_02_06_08.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1769808422811823800.sql => db_world/2026_02_06_07.sql} (99%) rename data/sql/updates/{pending_db_world/rev_1770302622700625500.sql => db_world/2026_02_06_08.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1769808422811823800.sql b/data/sql/updates/db_world/2026_02_06_07.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1769808422811823800.sql rename to data/sql/updates/db_world/2026_02_06_07.sql index e29d906e8..1e71f08d8 100644 --- a/data/sql/updates/pending_db_world/rev_1769808422811823800.sql +++ b/data/sql/updates/db_world/2026_02_06_07.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_06_06 -> 2026_02_06_07 -- DELETE FROM `spell_area` WHERE `spell` = 37280 AND `area` = 3607; INSERT INTO `spell_area` (`spell`, `area`, `quest_start`, `quest_end`, `aura_spell`, `racemask`, `gender`, `autocast`, `quest_start_status`, `quest_end_status`) VALUES diff --git a/data/sql/updates/pending_db_world/rev_1770302622700625500.sql b/data/sql/updates/db_world/2026_02_06_08.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1770302622700625500.sql rename to data/sql/updates/db_world/2026_02_06_08.sql index b18ea9c5c..42e232d40 100644 --- a/data/sql/updates/pending_db_world/rev_1770302622700625500.sql +++ b/data/sql/updates/db_world/2026_02_06_08.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_06_07 -> 2026_02_06_08 -- UPDATE `creature_template` SET `unit_flags` = `unit_flags`|64|32768 WHERE (`entry` = 21838); From 896f762cceceb322b54fc318f0feaf41b2125bf0 Mon Sep 17 00:00:00 2001 From: sogladev Date: Sat, 7 Feb 2026 00:58:05 +0100 Subject: [PATCH 058/335] fix(Scripts/Spells): some LW drums cannot affect targets lvl80 or higher (#24611) --- .../rev_1770159397406092393.sql | 10 ++++++++ src/server/scripts/Spells/spell_generic.cpp | 23 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770159397406092393.sql diff --git a/data/sql/updates/pending_db_world/rev_1770159397406092393.sql b/data/sql/updates/pending_db_world/rev_1770159397406092393.sql new file mode 100644 index 000000000..012eb15d8 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770159397406092393.sql @@ -0,0 +1,10 @@ +-- +-- 35475 Drums of War +-- 35476 Drums of Battle +-- 35478 Drums of Restoration +-- 'Cannot affect targets level 80 or higher.' +DELETE FROM `spell_script_names` WHERE `spell_id` IN (35475, 35476, 35478); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(35475, 'spell_gen_filter_party_level_80'), +(35476, 'spell_gen_filter_party_level_80'), +(35478, 'spell_gen_filter_party_level_80'); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index f5ff6e968..55186ba5e 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -5696,6 +5696,28 @@ class spell_gen_whisper_to_controller : public SpellScript } }; +// 35475 Drums of War +// 35476 Drums of Battle +// 35478 Drums of Restoration +class spell_gen_filter_party_level_80 : public SpellScript +{ + PrepareSpellScript(spell_gen_filter_party_level_80); + + void FilterTargets(std::list& targets) + { + targets.remove_if([&](WorldObject* target) -> bool + { + Unit* unit = target->ToUnit(); + return unit && unit->GetLevel() >= 80; + }); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gen_filter_party_level_80::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_PARTY); + } +}; + void AddSC_generic_spell_scripts() { RegisterSpellScript(spell_silithyst); @@ -5871,4 +5893,5 @@ void AddSC_generic_spell_scripts() RegisterSpellScript(spell_gen_bm_on); RegisterSpellScript(spell_gen_bm_off); RegisterSpellScript(spell_gen_whisper_to_controller); + RegisterSpellScript(spell_gen_filter_party_level_80); } From 008a6199d97991d3695fd37dc3f9d412bb739350 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 6 Feb 2026 23:59:11 +0000 Subject: [PATCH 059/335] chore(DB): import pending files Referenced commit(s): 896f762cceceb322b54fc318f0feaf41b2125bf0 --- .../rev_1770159397406092393.sql => db_world/2026_02_06_09.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1770159397406092393.sql => db_world/2026_02_06_09.sql} (90%) diff --git a/data/sql/updates/pending_db_world/rev_1770159397406092393.sql b/data/sql/updates/db_world/2026_02_06_09.sql similarity index 90% rename from data/sql/updates/pending_db_world/rev_1770159397406092393.sql rename to data/sql/updates/db_world/2026_02_06_09.sql index 012eb15d8..aa898bdbe 100644 --- a/data/sql/updates/pending_db_world/rev_1770159397406092393.sql +++ b/data/sql/updates/db_world/2026_02_06_09.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_06_08 -> 2026_02_06_09 -- -- 35475 Drums of War -- 35476 Drums of Battle From 4bda3ca1a98045680023f9d6aed78c58e6f4a995 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 7 Feb 2026 15:48:05 -0300 Subject: [PATCH 060/335] refactor(Scripts/ObsidianSanctum): Modernize script files (#24632) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../ObsidianSanctum/boss_sartharion.cpp | 1615 ++++++++--------- .../ObsidianSanctum/obsidian_sanctum.h | 2 + 2 files changed, 709 insertions(+), 908 deletions(-) diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp index a45be95fd..bec4a8d4d 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp @@ -253,493 +253,438 @@ const uint32 dragons[MAX_DRAGONS] = { DATA_TENEBRON, DATA_VESPERON, DATA_SHADRON // SARTHARION ///////////////////////////// -class boss_sartharion : public CreatureScript +struct boss_sartharion : public BossAI { -public: - boss_sartharion() : CreatureScript("boss_sartharion") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_sartharion(Creature* creature) : BossAI(creature, DATA_SARTHARION), + dragonsCount(0), + lastLavaSide(LAVA_RIGHT_SIDE), + usedBerserk(false), + below11PctReached(false) { - return GetObsidianSanctumAI (pCreature); } - struct boss_sartharionAI : public BossAI + void Reset() override { - boss_sartharionAI(Creature* pCreature) : BossAI(pCreature, DATA_SARTHARION), - dragonsCount(0), - lastLavaSide(LAVA_RIGHT_SIDE), - usedBerserk(false), - below11PctReached(false) + _Reset(); + extraEvents.Reset(); + RespawnDragons(false); + SummonStartingTriggers(); + usedBerserk = false; + below11PctReached = false; + dragonsCount = 0; + volcanoBlows.clear(); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_SHIFT); + } + + void DoAction(int32 param) override + { + if (param == ACTION_DRAKE_DIED) + DoCastSelf(SPELL_SARTHARION_TWILIGHT_REVENGE, true); + } + + void JustEngagedWith(Unit* who) override + { + if (who && !IsTargetInBounds(who)) { + EnterEvadeMode(); + return; } - void Reset() override + _JustEngagedWith(); + DoCastSelf(SPELL_SARTHARION_PYROBUFFET, true); + Talk(SAY_SARTHARION_AGGRO); + + // Combat events + events.ScheduleEvent(EVENT_SARTHARION_CAST_CLEAVE, 7s); + events.ScheduleEvent(EVENT_SARTHARION_CAST_FLAME_BREATH, 15s); + events.ScheduleEvent(EVENT_SARTHARION_CAST_TAIL_LASH, 11s); + + // Extra events + extraEvents.ScheduleEvent(EVENT_SARTHARION_SUMMON_LAVA, 20s); + extraEvents.ScheduleEvent(EVENT_SARTHARION_LAVA_STRIKE, 5s); + extraEvents.ScheduleEvent(EVENT_SARTHARION_BERSERK, 15min); + extraEvents.ScheduleEvent(EVENT_SARTHARION_BOUNDARY, 250ms); + + // Store dragons + for (uint8 i = 0; i < MAX_DRAGONS; ++i) { - _Reset(); - extraEvents.Reset(); - RespawnDragons(false); - SummonStartingTriggers(); - usedBerserk = false; - below11PctReached = false; - dragonsCount = 0; - volcanoBlows.clear(); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_SHIFT); - } + Creature* dragon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(dragons[i])); + if (!dragon || !dragon->IsAlive() || instance->GetBossState(dragons[i]) == DONE) + continue; - void DoAction(int32 param) override - { - if (param == ACTION_DRAKE_DIED) + dragon->SetImmuneToNPC(true); + dragon->SetFullHealth(); + + ++dragonsCount; + me->AddLootMode(1 << dragonsCount); + + switch (dragons[i]) { - DoCastSelf(SPELL_SARTHARION_TWILIGHT_REVENGE, true); - } - } - - void JustEngagedWith(Unit* pWho) override - { - if (pWho && !IsTargetInBounds(pWho)) - { - EnterEvadeMode(); - return; - } - - _JustEngagedWith(); - DoCastSelf(SPELL_SARTHARION_PYROBUFFET, true); - Talk(SAY_SARTHARION_AGGRO); - - // Combat events - events.ScheduleEvent(EVENT_SARTHARION_CAST_CLEAVE, 7s); - events.ScheduleEvent(EVENT_SARTHARION_CAST_FLAME_BREATH, 15s); - events.ScheduleEvent(EVENT_SARTHARION_CAST_TAIL_LASH, 11s); - - // Extra events - extraEvents.ScheduleEvent(EVENT_SARTHARION_SUMMON_LAVA, 20s); - extraEvents.ScheduleEvent(EVENT_SARTHARION_LAVA_STRIKE, 5s); - extraEvents.ScheduleEvent(EVENT_SARTHARION_BERSERK, 15min); - extraEvents.ScheduleEvent(EVENT_SARTHARION_BOUNDARY, 250ms); - - // Store dragons - for (uint8 i = 0; i < MAX_DRAGONS; ++i) - { - Creature* dragon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(dragons[i])); - if (!dragon || !dragon->IsAlive() || instance->GetBossState(dragons[i]) == DONE) + case DATA_TENEBRON: { - continue; - } - - dragon->SetImmuneToNPC(true); - dragon->SetFullHealth(); - - ++dragonsCount; - me->AddLootMode(1 << dragonsCount); - - switch (dragons[i]) - { - case DATA_TENEBRON: - { - dragon->CastSpell(dragon, SPELL_POWER_OF_TENEBRON, true); - extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_TENEBRON, 10s); - break; - } - case DATA_SHADRON: - { - dragon->CastSpell(dragon, SPELL_POWER_OF_SHADRON, true); - extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_SHADRON, 65s); - break; - } - case DATA_VESPERON: - { - dragon->CastSpell(dragon, SPELL_POWER_OF_VESPERON, true); - extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_VESPERON, 115s); - break; - } - } - } - - if (dragonsCount) - { - DoCastSelf(SPELL_WILL_OF_SARTHARION, true); - } - - me->CallForHelp(500.0f); - } - - void JustDied(Unit* /*killer*/) override - { - RespawnDragons(true); - _JustDied(); - Talk(SAY_SARTHARION_DEATH); - } - - void SetData(uint32 type, uint32 data) override - { - if (type == DATA_VOLCANO_BLOWS && data) - { - if (!volcanoBlows.empty() && std::find(volcanoBlows.begin(), volcanoBlows.end(), data) != volcanoBlows.end()) - { - return; - } - - volcanoBlows.push_back(data); - } - } - - uint32 GetData(uint32 dataOrGuid) const override - { - // it means we want dragons count - if (dataOrGuid == DATA_ACHIEVEMENT_DRAGONS_COUNT) - { - return dragonsCount; - } - - // otherwise it is guid to check if player was hit by lava strike :) - if (!volcanoBlows.empty() && std::find(volcanoBlows.begin(), volcanoBlows.end(), dataOrGuid) != volcanoBlows.end()) - { - return 1; - } - - return 0; - } - - void KilledUnit(Unit* pVictim) override - { - if (!urand(0, 2) && pVictim->IsPlayer()) - { - Talk(SAY_SARTHARION_SLAY); - } - } - - void JustSummoned(Creature* summon) override - { - switch (summon->GetEntry()) - { - case NPC_FLAME_TSUNAMI: - { - summon->SetSpeed(MOVE_FLIGHT, 1.5f); + dragon->CastSpell(dragon, SPELL_POWER_OF_TENEBRON, true); + extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_TENEBRON, 10s); break; } - case NPC_FIRE_CYCLONE: + case DATA_SHADRON: { - summon->GetMotionMaster()->MoveRandom(5.0f); + dragon->CastSpell(dragon, SPELL_POWER_OF_SHADRON, true); + extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_SHADRON, 65s); + break; + } + case DATA_VESPERON: + { + dragon->CastSpell(dragon, SPELL_POWER_OF_VESPERON, true); + extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_VESPERON, 115s); break; } } - - summons.Summon(summon); } - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*dmgType*/, SpellSchoolMask /*school*/) override + if (dragonsCount) + DoCastSelf(SPELL_WILL_OF_SARTHARION, true); + + me->CallForHelp(500.0f); + } + + void JustDied(Unit* /*killer*/) override + { + RespawnDragons(true); + _JustDied(); + Talk(SAY_SARTHARION_DEATH); + } + + void SetData(uint32 type, uint32 data) override + { + if (type == DATA_VOLCANO_BLOWS && data) { - // Temporal hack, by some case some melee spells can bypass this aura damage reduction - if (me->HasAura(SPELL_GIFT_OF_TWILIGHT_FIRE)) - { - damage = 0; + if (!volcanoBlows.empty() && std::find(volcanoBlows.begin(), volcanoBlows.end(), data) != volcanoBlows.end()) return; - } - if (!usedBerserk && me->HealthBelowPctDamaged(30, damage)) - { - DoCastSelf(SPELL_SARTHARION_BERSERK, true); - usedBerserk = true; - return; - } - - // Soft enrage - if (!below11PctReached && me->HealthBelowPctDamaged(10, damage)) - { - summons.RemoveNotExisting(); - if (!summons.empty()) - { - for (ObjectGuid const& summonGuid : summons) - { - Creature* summon = ObjectAccessor::GetCreature(*me, summonGuid); - if (summon && summon->GetEntry() == NPC_FIRE_CYCLONE) - { - summon->CastSpell(summon, SPELL_CYCLONE_AURA_PERIODIC, true); - } - } - } - Talk(SAY_SARTHARION_BERSERK); - below11PctReached = true; - } + volcanoBlows.push_back(data); } + } - void UpdateAI(uint32 diff) override + uint32 GetData(uint32 dataOrGuid) const override + { + // it means we want dragons count + if (dataOrGuid == DATA_ACHIEVEMENT_DRAGONS_COUNT) + return dragonsCount; + + // otherwise it is guid to check if player was hit by lava strike :) + if (!volcanoBlows.empty() && std::find(volcanoBlows.begin(), volcanoBlows.end(), dataOrGuid) != volcanoBlows.end()) + return 1; + + return 0; + } + + void KilledUnit(Unit* victim) override + { + if (!urand(0, 2) && victim->IsPlayer()) + Talk(SAY_SARTHARION_SLAY); + } + + void JustSummoned(Creature* summon) override + { + switch (summon->GetEntry()) { - if (!UpdateVictim()) + case NPC_FLAME_TSUNAMI: { - return; + summon->SetSpeed(MOVE_FLIGHT, 1.5f); + break; } - - extraEvents.Update(diff); - - // Special events which needs to be fired immidiately - while (uint32 const eventId = extraEvents.ExecuteEvent()) + case NPC_FIRE_CYCLONE: { - switch (eventId) - { - case EVENT_SARTHARION_BOUNDARY: - { - if (!IsTargetInBounds(me->GetVictim())) - { - EnterEvadeMode(); - } - else - { - extraEvents.Repeat(250ms); - } - break; - } - case EVENT_SARTHARION_SUMMON_LAVA: - { - if (!urand(0, 3)) - { - Talk(SAY_SARTHARION_SPECIAL); - } - - SummonLavaWaves(); - extraEvents.Repeat(25s); - return; - } - case EVENT_SARTHARION_START_LAVA: - { - SendLavaWaves(true); - return; - } - case EVENT_SARTHARION_FINISH_LAVA: - { - SendLavaWaves(false); - return; - } - // Handling of Drakes Events - // Dragon Calls - case EVENT_SARTHARION_CALL_TENEBRON: - { - Talk(SAY_SARTHARION_CALL_TENEBRON); - if (Creature* tenebron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TENEBRON))) - { - tenebron->AI()->DoAction(ACTION_CALL_DRAGON); - } - break; - } - case EVENT_SARTHARION_CALL_SHADRON: - { - Talk(SAY_SARTHARION_CALL_SHADRON); - if (Creature* shadron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SHADRON))) - { - shadron->AI()->DoAction(ACTION_CALL_DRAGON); - } - break; - } - case EVENT_SARTHARION_CALL_VESPERON: - { - Talk(SAY_SARTHARION_CALL_VESPERON); - if (Creature* vesperon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VESPERON))) - { - vesperon->AI()->DoAction(ACTION_CALL_DRAGON); - } - - break; - } - } + summon->GetMotionMaster()->MoveRandom(5.0f); + break; } - - // Handle Sartharion combat abbilities - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - { - return; - } - - while (uint32 const eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SARTHARION_CAST_CLEAVE: - { - DoCastVictim(SPELL_SARTHARION_CLEAVE, false); - events.Repeat(10s); - break; - } - case EVENT_SARTHARION_CAST_FLAME_BREATH: - { - DoCastVictim(SPELL_SARTHARION_FLAME_BREATH, false); - events.Repeat(20s); - break; - } - case EVENT_SARTHARION_CAST_TAIL_LASH: - { - DoCastSelf(SPELL_SARTHARION_TAIL_LASH, false); - events.Repeat(18s); - break; - } - case EVENT_SARTHARION_LAVA_STRIKE: - { - if (!urand(0, 2)) - { - Talk(SAY_SARTHARION_SPECIAL_4); - } - - summons.RemoveNotExisting(); - uint8 rand = urand(0, MAX_CYCLONE_COUNT - 1); // 5 - numer of cyclones - uint8 iter = 0; - if (!summons.empty()) - { - for (ObjectGuid const& summonGuid : summons) - { - Creature* summon = ObjectAccessor::GetCreature(*me, summonGuid); - if (summon && summon->GetEntry() == NPC_FIRE_CYCLONE && iter == rand) - { - summon->CastSpell(summon, SPELL_CYCLONE_AURA_PERIODIC, true); - ++iter; - } - } - } - - events.Repeat((below11PctReached ? randtime(1400ms, 2s) : randtime(5s, 20s))); - break; - } - case EVENT_SARTHARION_BERSERK: - { - summons.DespawnEntry(NPC_SAFE_AREA_TRIGGER); - break; - } - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - { - return; - } - } - - DoMeleeAttackIfReady(); } - private: - void SummonStartingTriggers() + summons.Summon(summon); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*dmgType*/, SpellSchoolMask /*school*/) override + { + // Temporal hack, by some case some melee spells can bypass this aura damage reduction + if (me->HasAura(SPELL_GIFT_OF_TWILIGHT_FIRE)) { - for (uint8 i = 0; i < MAX_CYCLONE_COUNT; ++i) - { - me->SummonCreature(NPC_FIRE_CYCLONE, CycloneSummonPos[i]); - } - - for (uint8 i = 0; i < MAX_AREA_TRIGGER_COUNT; ++i) - { - me->SummonCreature(NPC_SAFE_AREA_TRIGGER, AreaTriggerSummonPos[i]); - } + damage = 0; + return; } - void SummonLavaWaves() + if (!usedBerserk && me->HealthBelowPctDamaged(30, damage)) + { + DoCastSelf(SPELL_SARTHARION_BERSERK, true); + usedBerserk = true; + return; + } + + // Soft enrage + if (!below11PctReached && me->HealthBelowPctDamaged(10, damage)) { summons.RemoveNotExisting(); - Talk(WHISPER_LAVA_CHURN); - extraEvents.ScheduleEvent(EVENT_SARTHARION_START_LAVA, 3600ms); - extraEvents.ScheduleEvent(EVENT_SARTHARION_FINISH_LAVA, 11s); - - // Send wave from left - if (lastLavaSide == LAVA_RIGHT_SIDE) + if (!summons.empty()) { - for (uint8 i = 0; i < MAX_LEFT_LAVA_TSUNAMIS; ++i) + for (ObjectGuid const& summonGuid : summons) { - Creature* tsunami = me->SummonCreature(NPC_FLAME_TSUNAMI, 3211.0f, FlameTsunamiLeftOffsets[i], 57.083332f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 13500); - - if (((i - 2) % 3 == 0) && tsunami) // If center of wave - tsunami->CastSpell(tsunami, SPELL_FLAME_TSUNAMI_VISUAL, true); + Creature* summon = ObjectAccessor::GetCreature(*me, summonGuid); + if (summon && summon->GetEntry() == NPC_FIRE_CYCLONE) + summon->CastSpell(summon, SPELL_CYCLONE_AURA_PERIODIC, true); } - - lastLavaSide = LAVA_LEFT_SIDE; - } - // from right - else - { - for (uint8 i = 0; i < MAX_RIGHT_LAVA_TSUNAMIS; ++i) - { - Creature* tsunami = me->SummonCreature(NPC_FLAME_TSUNAMI, 3286.0f, FlameTsunamiRightOffsets[i], 57.083332f, 3.14f, TEMPSUMMON_TIMED_DESPAWN, 13500); - - if (((i - 2) % 3 == 0) && tsunami) // If center of wave - tsunami->CastSpell(tsunami, SPELL_FLAME_TSUNAMI_VISUAL, true); - } - - lastLavaSide = LAVA_RIGHT_SIDE; } + Talk(SAY_SARTHARION_BERSERK); + below11PctReached = true; } + } - void SendLavaWaves(bool start) + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + extraEvents.Update(diff); + + // Special events which needs to be fired immediately + while (uint32 const eventId = extraEvents.ExecuteEvent()) { - if (summons.empty()) - return; - - for (ObjectGuid const& guid : summons) + switch (eventId) { - Creature* tsunami = ObjectAccessor::GetCreature(*me, guid); - if (!tsunami || tsunami->GetEntry() != NPC_FLAME_TSUNAMI) - continue; - - if (start) // Movement possibly simplified from official, ideally reevaluate in the future. + case EVENT_SARTHARION_BOUNDARY: { - tsunami->CastSpell(tsunami, SPELL_FLAME_TSUNAMI_DAMAGE_AURA, true); - tsunami->GetMotionMaster()->MovePoint(0, ((tsunami->GetPositionX() < 3250.0f) ? 3286.0f : 3211.0f), tsunami->GetPositionY(), tsunami->GetPositionZ()); + if (!IsTargetInBounds(me->GetVictim())) + EnterEvadeMode(); + else + extraEvents.Repeat(250ms); + break; } - else + case EVENT_SARTHARION_SUMMON_LAVA: { - tsunami->RemoveAura(SPELL_FLAME_TSUNAMI_DAMAGE_AURA); - tsunami->SetObjectScale(0.1f); + if (!urand(0, 3)) + Talk(SAY_SARTHARION_SPECIAL); + + SummonLavaWaves(); + extraEvents.Repeat(25s); + return; + } + case EVENT_SARTHARION_START_LAVA: + { + SendLavaWaves(true); + return; + } + case EVENT_SARTHARION_FINISH_LAVA: + { + SendLavaWaves(false); + return; + } + // Handling of Drakes Events + // Dragon Calls + case EVENT_SARTHARION_CALL_TENEBRON: + { + Talk(SAY_SARTHARION_CALL_TENEBRON); + if (Creature* tenebron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TENEBRON))) + tenebron->AI()->DoAction(ACTION_CALL_DRAGON); + break; + } + case EVENT_SARTHARION_CALL_SHADRON: + { + Talk(SAY_SARTHARION_CALL_SHADRON); + if (Creature* shadron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SHADRON))) + shadron->AI()->DoAction(ACTION_CALL_DRAGON); + break; + } + case EVENT_SARTHARION_CALL_VESPERON: + { + Talk(SAY_SARTHARION_CALL_VESPERON); + if (Creature* vesperon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VESPERON))) + vesperon->AI()->DoAction(ACTION_CALL_DRAGON); + + break; } } } - void RespawnDragons(bool checkCombat) - { - for (uint8 i = 0; i < MAX_DRAGONS; ++i) - { - if (instance->GetBossState(dragons[i]) == DONE) - { - continue; - } + // Handle Sartharion combat abilities + events.Update(diff); - if (Creature* dragon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(dragons[i]))) + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 const eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SARTHARION_CAST_CLEAVE: { - if (checkCombat && dragon->IsInCombat()) + DoCastVictim(SPELL_SARTHARION_CLEAVE, false); + events.Repeat(10s); + break; + } + case EVENT_SARTHARION_CAST_FLAME_BREATH: + { + DoCastVictim(SPELL_SARTHARION_FLAME_BREATH, false); + events.Repeat(20s); + break; + } + case EVENT_SARTHARION_CAST_TAIL_LASH: + { + DoCastSelf(SPELL_SARTHARION_TAIL_LASH, false); + events.Repeat(18s); + break; + } + case EVENT_SARTHARION_LAVA_STRIKE: + { + if (!urand(0, 2)) + Talk(SAY_SARTHARION_SPECIAL_4); + + summons.RemoveNotExisting(); + uint8 rand = urand(0, MAX_CYCLONE_COUNT - 1); // 5 - number of cyclones + uint8 iter = 0; + if (!summons.empty()) { - continue; + for (ObjectGuid const& summonGuid : summons) + { + Creature* summon = ObjectAccessor::GetCreature(*me, summonGuid); + if (summon && summon->GetEntry() == NPC_FIRE_CYCLONE && iter == rand) + { + summon->CastSpell(summon, SPELL_CYCLONE_AURA_PERIODIC, true); + ++iter; + } + } } - dragon->DespawnOrUnsummon(); - dragon->SetRespawnTime(5); + events.Repeat((below11PctReached ? randtime(1400ms, 2s) : randtime(5s, 20s))); + break; + } + case EVENT_SARTHARION_BERSERK: + { + summons.DespawnEntry(NPC_SAFE_AREA_TRIGGER); + break; } } - dragonsCount = 0; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } - bool IsTargetInBounds(Unit const* victim) const + DoMeleeAttackIfReady(); + } + +private: + void SummonStartingTriggers() + { + for (uint8 i = 0; i < MAX_CYCLONE_COUNT; ++i) { - if (!victim || victim->GetPositionX() < SartharionBoundary[0] || victim->GetPositionX() > SartharionBoundary[1] || victim->GetPositionY() > SartharionBoundary[3]) - { - return false; - } - - // Big island handling - if (victim->GetPositionY() < SartharionBoundary[2]) - { - return victim->GetDistance(bigIslandMiddlePos) <= 6.0f; - } - - return true; + me->SummonCreature(NPC_FIRE_CYCLONE, CycloneSummonPos[i]); } - EventMap extraEvents; - std::list volcanoBlows; - uint8 dragonsCount; - uint8 lastLavaSide; // 0 = left, 1 = right - bool usedBerserk; - bool below11PctReached; - }; + for (uint8 i = 0; i < MAX_AREA_TRIGGER_COUNT; ++i) + { + me->SummonCreature(NPC_SAFE_AREA_TRIGGER, AreaTriggerSummonPos[i]); + } + } + + void SummonLavaWaves() + { + summons.RemoveNotExisting(); + Talk(WHISPER_LAVA_CHURN); + extraEvents.ScheduleEvent(EVENT_SARTHARION_START_LAVA, 3600ms); + extraEvents.ScheduleEvent(EVENT_SARTHARION_FINISH_LAVA, 11s); + + // Send wave from left + if (lastLavaSide == LAVA_RIGHT_SIDE) + { + for (uint8 i = 0; i < MAX_LEFT_LAVA_TSUNAMIS; ++i) + { + Creature* tsunami = me->SummonCreature(NPC_FLAME_TSUNAMI, 3211.0f, FlameTsunamiLeftOffsets[i], 57.083332f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 13500); + + if (((i - 2) % 3 == 0) && tsunami) // If center of wave + tsunami->CastSpell(tsunami, SPELL_FLAME_TSUNAMI_VISUAL, true); + } + + lastLavaSide = LAVA_LEFT_SIDE; + } + // from right + else + { + for (uint8 i = 0; i < MAX_RIGHT_LAVA_TSUNAMIS; ++i) + { + Creature* tsunami = me->SummonCreature(NPC_FLAME_TSUNAMI, 3286.0f, FlameTsunamiRightOffsets[i], 57.083332f, 3.14f, TEMPSUMMON_TIMED_DESPAWN, 13500); + + if (((i - 2) % 3 == 0) && tsunami) // If center of wave + tsunami->CastSpell(tsunami, SPELL_FLAME_TSUNAMI_VISUAL, true); + } + + lastLavaSide = LAVA_RIGHT_SIDE; + } + } + + void SendLavaWaves(bool start) + { + if (summons.empty()) + return; + + for (ObjectGuid const& guid : summons) + { + Creature* tsunami = ObjectAccessor::GetCreature(*me, guid); + if (!tsunami || tsunami->GetEntry() != NPC_FLAME_TSUNAMI) + continue; + + if (start) // Movement possibly simplified from official, ideally reevaluate in the future. + { + tsunami->CastSpell(tsunami, SPELL_FLAME_TSUNAMI_DAMAGE_AURA, true); + tsunami->GetMotionMaster()->MovePoint(0, ((tsunami->GetPositionX() < 3250.0f) ? 3286.0f : 3211.0f), tsunami->GetPositionY(), tsunami->GetPositionZ()); + } + else + { + tsunami->RemoveAura(SPELL_FLAME_TSUNAMI_DAMAGE_AURA); + tsunami->SetObjectScale(0.1f); + } + } + } + + void RespawnDragons(bool checkCombat) + { + for (uint8 i = 0; i < MAX_DRAGONS; ++i) + { + if (instance->GetBossState(dragons[i]) == DONE) + continue; + + if (Creature* dragon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(dragons[i]))) + { + if (checkCombat && dragon->IsInCombat()) + continue; + + dragon->DespawnOrUnsummon(); + dragon->SetRespawnTime(5); + } + } + + dragonsCount = 0; + } + + bool IsTargetInBounds(Unit const* victim) const + { + if (!victim || victim->GetPositionX() < SartharionBoundary[0] || victim->GetPositionX() > SartharionBoundary[1] || victim->GetPositionY() > SartharionBoundary[3]) + return false; + + // Big island handling + if (victim->GetPositionY() < SartharionBoundary[2]) + return victim->GetDistance(bigIslandMiddlePos) <= 6.0f; + + return true; + } + + EventMap extraEvents; + std::list volcanoBlows; + uint8 dragonsCount; + uint8 lastLavaSide; // 0 = left, 1 = right + bool usedBerserk; + bool below11PctReached; }; struct boss_sartharion_dragonAI : public BossAI { - boss_sartharion_dragonAI(Creature* pCreature, uint32 bossId) : BossAI(pCreature, bossId), isCalledBySartharion(false) + boss_sartharion_dragonAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId), isCalledBySartharion(false) { } @@ -778,34 +723,26 @@ struct boss_sartharion_dragonAI : public BossAI void MovementInform(uint32 type, uint32 pointId) final { if (type != WAYPOINT_MOTION_TYPE) - { return; - } switch (me->GetEntry()) { case NPC_TENEBRON: { if (pointId != POINT_FINAL_TENEBRON) - { return; - } break; } case NPC_SHADRON: { if (pointId != POINT_FINAL_SHADRON) - { return; - } break; } case NPC_VESPERON: { if (pointId != POINT_FINAL_VESPERON) - { return; - } break; } } @@ -820,9 +757,7 @@ struct boss_sartharion_dragonAI : public BossAI if (isCalledBySartharion && instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) { if (Creature* sartharion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SARTHARION))) - { sartharion->AI()->JustSummoned(summon); - } } BossAI::JustSummoned(summon); @@ -863,16 +798,12 @@ struct boss_sartharion_dragonAI : public BossAI } if (isCalledBySartharion || instance->GetBossState(DATA_SARTHARION) == DONE) - { me->SetLootMode(0); - } if (isCalledBySartharion) { if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 0, 500, true, false)) - { AttackStart(target); - } } } @@ -883,9 +814,7 @@ struct boss_sartharion_dragonAI : public BossAI // Despawn minions only if not called by Sartharion if (!isCalledBySartharion) - { summons.DespawnAll(); - } switch (me->GetEntry()) { @@ -893,9 +822,7 @@ struct boss_sartharion_dragonAI : public BossAI { Talk(SAY_TENEBRON_DEATH); if (!isCalledBySartharion || instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) - { instance->SetBossState(DATA_TENEBRON, DONE); - } break; } case NPC_SHADRON: @@ -904,15 +831,11 @@ struct boss_sartharion_dragonAI : public BossAI if (isCalledBySartharion) { if (Creature* sartharion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SARTHARION))) - { sartharion->RemoveAura(SPELL_GIFT_OF_TWILIGHT_FIRE); - } } if (!isCalledBySartharion || instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) - { instance->SetBossState(DATA_SHADRON, DONE); - } break; } case NPC_VESPERON: @@ -920,32 +843,24 @@ struct boss_sartharion_dragonAI : public BossAI Talk(SAY_VESPERON_DEATH); instance->DoAction(ACTION_CLEAR_PORTAL); if (!isCalledBySartharion || instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) - { instance->SetBossState(DATA_VESPERON, DONE); - } break; } } if (!isCalledBySartharion) - { ClearInstance(); - } else { if (Creature* sartharion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SARTHARION))) - { sartharion->AI()->DoAction(ACTION_DRAKE_DIED); - } } } void KilledUnit(Unit* victim) final { if (!victim->IsPlayer() || urand(0, 2)) - { return; - } switch (me->GetEntry()) { @@ -976,25 +891,19 @@ struct boss_sartharion_dragonAI : public BossAI } if (!UpdateVictim()) - { return; - } events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) - { return; - } while (uint32 const eventId = events.ExecuteEvent()) { ExecuteEvent(eventId); if (me->HasUnitState(UNIT_STATE_CASTING)) - { return; - } } DoMeleeAttackIfReady(); @@ -1016,9 +925,7 @@ protected: if (portalGUID) { if (GameObject* gobj = me->GetMap()->GetGameObject(portalGUID)) - { gobj->Delete(); - } portalGUID.Clear(); } @@ -1033,502 +940,402 @@ protected: // TENEBRON ///////////////////////////// -class boss_sartharion_tenebron : public CreatureScript +struct boss_sartharion_tenebron : public boss_sartharion_dragonAI { -public: - boss_sartharion_tenebron() : CreatureScript("boss_sartharion_tenebron") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_sartharion_tenebron(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_TENEBRON), summons2(creature) { - return GetObsidianSanctumAI(pCreature); } - struct boss_sartharion_tenebronAI : public boss_sartharion_dragonAI + void Reset() override { - boss_sartharion_tenebronAI(Creature* pCreature) : boss_sartharion_dragonAI(pCreature, DATA_TENEBRON), summons2(pCreature) - { - } - - void Reset() override - { - boss_sartharion_dragonAI::Reset(); - if (!isCalledBySartharion) - { - summons2.DespawnAll(); - } - - events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_FISSURE, 20s); - events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_BREATH, 10s); - events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 15s); - } - - void JustSummoned(Creature* summon) override - { - if (summon->GetEntry() != NPC_TWILIGHT_EGG) - { - summons.Summon(summon); - } - // Summons to Sartharion are linked manually - } - - void JustDied(Unit* killer) override - { - if (!isCalledBySartharion) - { - summons2.DespawnAll(); - } - - boss_sartharion_dragonAI::JustDied(killer); - } - - void HandleExtraEvent(uint32 const eventId) override - { - if (eventId == EVENT_MINIDRAKE_SPEECH) - { - Talk(SAY_TENEBRON_RESPOND); - me->SetCanFly(true); - me->SetSpeed(MOVE_FLIGHT, 3.0f); - me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false); - } - } - - void ExecuteEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_MINIBOSS_SHADOW_BREATH: - { - if (!urand(0, 10)) - { - Talk(SAY_TENEBRON_BREATH); - } - DoCastVictim(SPELL_SHADOW_BREATH, false); - events.Repeat(17500ms); - break; - } - case EVENT_MINIBOSS_SHADOW_FISSURE: - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - { - DoCast(target, SPELL_SHADOW_FISSURE, false); - } - events.Repeat(22500ms); - break; - } - case EVENT_MINIBOSS_OPEN_PORTAL: - { - Talk(WHISPER_OPEN_PORTAL); - Talk(SAY_TENEBRON_SPECIAL); - - if (!isCalledBySartharion) - { - if (GameObject* Portal = me->GetVictim()->SummonGameObject(GO_TWILIGHT_PORTAL, portalPos[DATA_TENEBRON].GetPositionX(), portalPos[DATA_TENEBRON].GetPositionY(), portalPos[DATA_TENEBRON].GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) - { - portalGUID = Portal->GetGUID(); - } - } - else - { - instance->DoAction(ACTION_ADD_PORTAL); - } - - events.ScheduleEvent(EVENT_MINIBOSS_SPAWN_HELPERS, 2s); - events.Repeat(60s); - break; - } - case EVENT_MINIBOSS_SPAWN_HELPERS: - { - Talk(WHISPER_HATCH_EGGS); - for (uint8 i = 0; i < MAX_TENEBORN_EGGS_SUMMONS; ++i) - { - if (Creature* egg = me->SummonCreature(NPC_TWILIGHT_EGG, TenebronEggsPos[isCalledBySartharion ? 1 : 0][i], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000)) - { - summons.Summon(egg); - if (isCalledBySartharion && instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) - { - if (Creature* sartharion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SARTHARION))) - { - sartharion->AI()->JustSummoned(egg); - } - } - egg->SetPhaseMask(16, true); - } - } - - events.ScheduleEvent(EVENT_MINIBOSS_HATCH_EGGS, 25s); - break; - } - case EVENT_MINIBOSS_HATCH_EGGS: - { - summons.RemoveNotExisting(); - summons.DespawnEntry(NPC_TWILIGHT_WHELP); - for (ObjectGuid const& summonGuid : summons) - { - Creature const* summon = ObjectAccessor::GetCreature(*me, summonGuid); - if (!summon || !summon->IsAlive() || summon->GetEntry() != NPC_TWILIGHT_EGG) - { - continue; - } - - if (Creature* whelp = me->SummonCreature(NPC_TWILIGHT_WHELP, summon->GetPosition(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000)) - { - summons2.Summon(whelp); - if (isCalledBySartharion && instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) - { - if (Creature* sartharion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SARTHARION))) - { - sartharion->AI()->JustSummoned(whelp); - } - } - } - } - - if (!isCalledBySartharion) - { - // Remove phase shift - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_SHIFT); - RemoveTwilightPortal(); - } - else - { - instance->DoAction(ACTION_CLEAR_PORTAL); - } - - EntryCheckPredicate pred(NPC_TWILIGHT_EGG); - summons.DoAction(ACTION_SWITCH_PHASE, pred); - break; - } - } - } - - void ClearInstance() override - { - boss_sartharion_dragonAI::ClearInstance(); + boss_sartharion_dragonAI::Reset(); + if (!isCalledBySartharion) summons2.DespawnAll(); - } - private: - SummonList summons2; - }; + events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_FISSURE, 20s); + events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_BREATH, 10s); + events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 15s); + } + + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() != NPC_TWILIGHT_EGG) + summons.Summon(summon); + // Summons to Sartharion are linked manually + } + + void JustDied(Unit* killer) override + { + if (!isCalledBySartharion) + summons2.DespawnAll(); + + boss_sartharion_dragonAI::JustDied(killer); + } + + void HandleExtraEvent(uint32 const eventId) override + { + if (eventId == EVENT_MINIDRAKE_SPEECH) + { + Talk(SAY_TENEBRON_RESPOND); + me->SetCanFly(true); + me->SetSpeed(MOVE_FLIGHT, 3.0f); + me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false); + } + } + + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) + { + case EVENT_MINIBOSS_SHADOW_BREATH: + { + if (!urand(0, 10)) + Talk(SAY_TENEBRON_BREATH); + DoCastVictim(SPELL_SHADOW_BREATH, false); + events.Repeat(17500ms); + break; + } + case EVENT_MINIBOSS_SHADOW_FISSURE: + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random)) + DoCast(target, SPELL_SHADOW_FISSURE, false); + events.Repeat(22500ms); + break; + } + case EVENT_MINIBOSS_OPEN_PORTAL: + { + Talk(WHISPER_OPEN_PORTAL); + Talk(SAY_TENEBRON_SPECIAL); + + if (!isCalledBySartharion) + { + if (GameObject* Portal = me->GetVictim()->SummonGameObject(GO_TWILIGHT_PORTAL, portalPos[DATA_TENEBRON].GetPositionX(), portalPos[DATA_TENEBRON].GetPositionY(), portalPos[DATA_TENEBRON].GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) + portalGUID = Portal->GetGUID(); + } + else + instance->DoAction(ACTION_ADD_PORTAL); + + events.ScheduleEvent(EVENT_MINIBOSS_SPAWN_HELPERS, 2s); + events.Repeat(60s); + break; + } + case EVENT_MINIBOSS_SPAWN_HELPERS: + { + Talk(WHISPER_HATCH_EGGS); + for (uint8 i = 0; i < MAX_TENEBORN_EGGS_SUMMONS; ++i) + { + if (Creature* egg = me->SummonCreature(NPC_TWILIGHT_EGG, TenebronEggsPos[isCalledBySartharion ? 1 : 0][i], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000)) + { + summons.Summon(egg); + if (isCalledBySartharion && instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) + { + if (Creature* sartharion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SARTHARION))) + sartharion->AI()->JustSummoned(egg); + } + egg->SetPhaseMask(16, true); + } + } + + events.ScheduleEvent(EVENT_MINIBOSS_HATCH_EGGS, 25s); + break; + } + case EVENT_MINIBOSS_HATCH_EGGS: + { + summons.RemoveNotExisting(); + summons.DespawnEntry(NPC_TWILIGHT_WHELP); + for (ObjectGuid const& summonGuid : summons) + { + Creature const* summon = ObjectAccessor::GetCreature(*me, summonGuid); + if (!summon || !summon->IsAlive() || summon->GetEntry() != NPC_TWILIGHT_EGG) + continue; + + if (Creature* whelp = me->SummonCreature(NPC_TWILIGHT_WHELP, summon->GetPosition(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000)) + { + summons2.Summon(whelp); + if (isCalledBySartharion && instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) + { + if (Creature* sartharion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SARTHARION))) + sartharion->AI()->JustSummoned(whelp); + } + } + } + + if (!isCalledBySartharion) + { + // Remove phase shift + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_SHIFT); + RemoveTwilightPortal(); + } + else + instance->DoAction(ACTION_CLEAR_PORTAL); + + EntryCheckPredicate pred(NPC_TWILIGHT_EGG); + summons.DoAction(ACTION_SWITCH_PHASE, pred); + break; + } + } + } + + void ClearInstance() override + { + boss_sartharion_dragonAI::ClearInstance(); + summons2.DespawnAll(); + } + +private: + SummonList summons2; }; ///////////////////////////// // SHADRON ///////////////////////////// -class boss_sartharion_shadron : public CreatureScript +struct boss_sartharion_shadron : public boss_sartharion_dragonAI { -public: - boss_sartharion_shadron() : CreatureScript("boss_sartharion_shadron") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_sartharion_shadron(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_SHADRON) { - return GetObsidianSanctumAI(pCreature); } - struct boss_sartharion_shadronAI : public boss_sartharion_dragonAI + void Reset() override { - boss_sartharion_shadronAI(Creature* pCreature) : boss_sartharion_dragonAI(pCreature, DATA_SHADRON) + boss_sartharion_dragonAI::Reset(); + events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_FISSURE, 20s); + events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_BREATH, 10s); + events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 15s); + } + + void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override + { + if (isCalledBySartharion) { + // Acolytes are dead + if (!summons.HasEntry(NPC_ACOLYTE_OF_SHADRON)) + instance->DoAction(ACTION_CLEAR_PORTAL); + + if (Creature* sartharion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SARTHARION))) + sartharion->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGHT_FIRE); + } + else + { + ClearInstance(); + me->RemoveAura(SPELL_GIFT_OF_TWILIGHT_SHADOW); } - void Reset() override - { - boss_sartharion_dragonAI::Reset(); - events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_FISSURE, 20s); - events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_BREATH, 10s); - events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 15s); - } + events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s); + } - void SummonedCreatureDies(Creature* /*summon*/, Unit* /*summon*/) override + void HandleExtraEvent(uint32 const eventId) override + { + if (eventId == EVENT_MINIDRAKE_SPEECH) { - if (isCalledBySartharion) + Talk(SAY_SHADRON_RESPOND); + me->SetCanFly(true); + me->SetSpeed(MOVE_FLIGHT, 3.0f); + me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false); + } + } + + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) + { + case EVENT_MINIBOSS_SHADOW_BREATH: { - // Acolytes are dead - if (!summons.HasEntry(NPC_ACOLYTE_OF_SHADRON)) + if (!urand(0, 10)) + Talk(SAY_SHADRON_BREATH); + + DoCastVictim(SPELL_SHADOW_BREATH, false); + events.Repeat(17500ms); + break; + } + case EVENT_MINIBOSS_SHADOW_FISSURE: + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random)) + DoCast(target, SPELL_SHADOW_FISSURE, false); + events.Repeat(22500ms); + break; + } + case EVENT_MINIBOSS_OPEN_PORTAL: + { + Talk(WHISPER_OPEN_PORTAL); + Talk(SAY_SHADRON_SPECIAL); + if (!isCalledBySartharion) { - instance->DoAction(ACTION_CLEAR_PORTAL); + if (GameObject* Portal = me->GetVictim()->SummonGameObject(GO_TWILIGHT_PORTAL, portalPos[DATA_SHADRON].GetPositionX(), portalPos[DATA_SHADRON].GetPositionY(), portalPos[DATA_SHADRON].GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) + portalGUID = Portal->GetGUID(); + } + else + instance->DoAction(ACTION_ADD_PORTAL); + + events.ScheduleEvent(EVENT_MINIBOSS_SPAWN_HELPERS, 2s); + break; + } + case EVENT_MINIBOSS_SPAWN_HELPERS: + { + Talk(WHISPER_SUMMON_DICIPLE); + DoCastAOE(static_cast((isCalledBySartharion ? SPELL_GIFT_OF_TWILIGHT_FIRE : SPELL_GIFT_OF_TWILIGHT_SHADOW)), true); + + if (Creature* acolyte = me->SummonCreature((isCalledBySartharion ? NPC_ACOLYTE_OF_SHADRON : NPC_DISCIPLE_OF_SHADRON), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation())) + { + /// @todo: inspect JustSummoned + summons.Summon(acolyte); + acolyte->SetPhaseMask(16, true); } - if (Creature* sartharion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SARTHARION))) - { - sartharion->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGHT_FIRE); - } - } - else - { - ClearInstance(); - me->RemoveAura(SPELL_GIFT_OF_TWILIGHT_SHADOW); - } - - events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s); - } - - void HandleExtraEvent(uint32 const eventId) override - { - if (eventId == EVENT_MINIDRAKE_SPEECH) - { - Talk(SAY_SHADRON_RESPOND); - me->SetCanFly(true); - me->SetSpeed(MOVE_FLIGHT, 3.0f); - me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false); + break; } } - - void ExecuteEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_MINIBOSS_SHADOW_BREATH: - { - if (!urand(0, 10)) - { - Talk(SAY_SHADRON_BREATH); - } - - DoCastVictim(SPELL_SHADOW_BREATH, false); - events.Repeat(17500ms); - break; - } - case EVENT_MINIBOSS_SHADOW_FISSURE: - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - { - DoCast(target, SPELL_SHADOW_FISSURE, false); - } - events.Repeat(22500ms); - break; - } - case EVENT_MINIBOSS_OPEN_PORTAL: - { - Talk(WHISPER_OPEN_PORTAL); - Talk(SAY_SHADRON_SPECIAL); - if (!isCalledBySartharion) - { - if (GameObject* Portal = me->GetVictim()->SummonGameObject(GO_TWILIGHT_PORTAL, portalPos[DATA_SHADRON].GetPositionX(), portalPos[DATA_SHADRON].GetPositionY(), portalPos[DATA_SHADRON].GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) - { - portalGUID = Portal->GetGUID(); - } - } - else - { - instance->DoAction(ACTION_ADD_PORTAL); - } - - events.ScheduleEvent(EVENT_MINIBOSS_SPAWN_HELPERS, 2s); - break; - } - case EVENT_MINIBOSS_SPAWN_HELPERS: - { - Talk(WHISPER_SUMMON_DICIPLE); - DoCastAOE(static_cast((isCalledBySartharion ? SPELL_GIFT_OF_TWILIGHT_FIRE : SPELL_GIFT_OF_TWILIGHT_SHADOW)), true); - - if (Creature* acolyte = me->SummonCreature((isCalledBySartharion ? NPC_ACOLYTE_OF_SHADRON : NPC_DISCIPLE_OF_SHADRON), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation())) - { - /// @todo: inpect JustSummoned - summons.Summon(acolyte); - acolyte->SetPhaseMask(16, true); - } - - break; - } - } - } - }; + } }; ///////////////////////////// // VESPERON ///////////////////////////// -class boss_sartharion_vesperon : public CreatureScript +struct boss_sartharion_vesperon : public boss_sartharion_dragonAI { -public: - boss_sartharion_vesperon() : CreatureScript("boss_sartharion_vesperon") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_sartharion_vesperon(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_VESPERON) { - return GetObsidianSanctumAI(pCreature); } - struct boss_sartharion_vesperonAI : public boss_sartharion_dragonAI + void Reset() override { - boss_sartharion_vesperonAI(Creature* pCreature) : boss_sartharion_dragonAI(pCreature, DATA_VESPERON) + boss_sartharion_dragonAI::Reset(); + events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_FISSURE, 20s); + events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_BREATH, 10s); + events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s); + } + + void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override + { + if (!isCalledBySartharion) + ClearInstance(); + else { - } - - void Reset() override - { - boss_sartharion_dragonAI::Reset(); - events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_FISSURE, 20s); - events.ScheduleEvent(EVENT_MINIBOSS_SHADOW_BREATH, 10s); - events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s); - } - - void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override - { - if (!isCalledBySartharion) - { - ClearInstance(); - } - else - { - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_TORMENT_SARTHARION); - instance->DoAction(ACTION_CLEAR_PORTAL); - } - - events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s); - } - - void HandleExtraEvent(uint32 const eventId) override - { - if (eventId == EVENT_MINIDRAKE_SPEECH) - { - Talk(SAY_SHADRON_RESPOND); - me->SetCanFly(true); - me->SetSpeed(MOVE_FLIGHT, 3.0f); - me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false); - } - } - - void ExecuteEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_MINIBOSS_SHADOW_BREATH: - { - if (!urand(0, 10)) - { - Talk(SAY_SHADRON_BREATH); - } - - DoCastVictim(SPELL_SHADOW_BREATH, false); - events.Repeat(17s + 500ms); - break; - } - case EVENT_MINIBOSS_SHADOW_FISSURE: - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - { - DoCast(target, SPELL_SHADOW_FISSURE, false); - } - - events.Repeat(22s + 500ms); - break; - } - case EVENT_MINIBOSS_OPEN_PORTAL: - { - Talk(WHISPER_OPEN_PORTAL); - Talk(SAY_VESPERON_SPECIAL); - if (!isCalledBySartharion) - { - if (GameObject* Portal = me->GetVictim()->SummonGameObject(GO_TWILIGHT_PORTAL, portalPos[DATA_VESPERON].GetPositionX(), portalPos[DATA_VESPERON].GetPositionY(), portalPos[DATA_VESPERON].GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) - { - portalGUID = Portal->GetGUID(); - } - } - else - { - instance->DoAction(ACTION_ADD_PORTAL); - } - - events.ScheduleEvent(EVENT_MINIBOSS_SPAWN_HELPERS, 2s); - break; - } - case EVENT_MINIBOSS_SPAWN_HELPERS: - { - Talk(WHISPER_SUMMON_DICIPLE); - DoCastSelf(isCalledBySartharion ? static_cast(SPELL_TWILIGHT_TORMENT_SARTHARION) : static_cast(SPELL_TWILIGHT_TORMENT_VESPERON), true); - if (Creature* acolyte = me->SummonCreature((isCalledBySartharion ? NPC_ACOLYTE_OF_VESPERON : NPC_DISCIPLE_OF_VESPERON), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation())) - { - summons.Summon(acolyte); - acolyte->SetPhaseMask(16, true); - } - - break; - } - } - } - - private: - void ClearInstance() override - { - boss_sartharion_dragonAI::ClearInstance(); - - // Remove phase shift - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_TORMENT_VESPERON); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_TORMENT_SARTHARION); + instance->DoAction(ACTION_CLEAR_PORTAL); } - }; + + events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s); + } + + void HandleExtraEvent(uint32 const eventId) override + { + if (eventId == EVENT_MINIDRAKE_SPEECH) + { + Talk(SAY_SHADRON_RESPOND); + me->SetCanFly(true); + me->SetSpeed(MOVE_FLIGHT, 3.0f); + me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false); + } + } + + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) + { + case EVENT_MINIBOSS_SHADOW_BREATH: + { + if (!urand(0, 10)) + Talk(SAY_SHADRON_BREATH); + + DoCastVictim(SPELL_SHADOW_BREATH, false); + events.Repeat(17s + 500ms); + break; + } + case EVENT_MINIBOSS_SHADOW_FISSURE: + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random)) + DoCast(target, SPELL_SHADOW_FISSURE, false); + + events.Repeat(22s + 500ms); + break; + } + case EVENT_MINIBOSS_OPEN_PORTAL: + { + Talk(WHISPER_OPEN_PORTAL); + Talk(SAY_VESPERON_SPECIAL); + if (!isCalledBySartharion) + { + if (GameObject* Portal = me->GetVictim()->SummonGameObject(GO_TWILIGHT_PORTAL, portalPos[DATA_VESPERON].GetPositionX(), portalPos[DATA_VESPERON].GetPositionY(), portalPos[DATA_VESPERON].GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) + portalGUID = Portal->GetGUID(); + } + else + instance->DoAction(ACTION_ADD_PORTAL); + + events.ScheduleEvent(EVENT_MINIBOSS_SPAWN_HELPERS, 2s); + break; + } + case EVENT_MINIBOSS_SPAWN_HELPERS: + { + Talk(WHISPER_SUMMON_DICIPLE); + DoCastSelf(isCalledBySartharion ? static_cast(SPELL_TWILIGHT_TORMENT_SARTHARION) : static_cast(SPELL_TWILIGHT_TORMENT_VESPERON), true); + if (Creature* acolyte = me->SummonCreature((isCalledBySartharion ? NPC_ACOLYTE_OF_VESPERON : NPC_DISCIPLE_OF_VESPERON), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation())) + { + summons.Summon(acolyte); + acolyte->SetPhaseMask(16, true); + } + + break; + } + } + } + +private: + void ClearInstance() override + { + boss_sartharion_dragonAI::ClearInstance(); + + // Remove phase shift + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_TORMENT_VESPERON); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_TORMENT_SARTHARION); + } }; // other -class npc_twilight_summon : public CreatureScript +struct npc_twilight_summon : public ScriptedAI { -public: - npc_twilight_summon() : CreatureScript("npc_twilight_summon") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_twilight_summon(Creature* creature) : ScriptedAI(creature), + fadeArmorTimer(urand(0, 15000)) { - return GetObsidianSanctumAI(pCreature); } - struct npc_twilight_summonAI : public ScriptedAI + void Reset() override { - npc_twilight_summonAI(Creature* pCreature) : ScriptedAI(pCreature), - fadeArmorTimer(urand(0, 15000)) - { - } + fadeArmorTimer = urand(0, 15000); + if (me->GetEntry() == NPC_TWILIGHT_EGG) + me->SetControlled(true, UNIT_STATE_STUNNED); + else + me->SetInCombatWithZone(); + } - void Reset() override + void DoAction(int32 param) override + { + if (param == ACTION_SWITCH_PHASE) + me->DespawnOrUnsummon(1ms); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() || me->GetEntry() == NPC_TWILIGHT_EGG) + return; + + fadeArmorTimer += diff; + if (fadeArmorTimer >= 15000) { - fadeArmorTimer = urand(0, 15000); - if (me->GetEntry() == NPC_TWILIGHT_EGG) - { - me->SetControlled(true, UNIT_STATE_STUNNED); - } + if (Aura* aur = me->GetVictim()->GetAura(SPELL_FADE_ARMOR)) + aur->ModStackAmount(1); else - { - me->SetInCombatWithZone(); - } + DoCastVictim(SPELL_FADE_ARMOR, false); + + fadeArmorTimer = 0; } - void DoAction(int32 param) override - { - if (param == ACTION_SWITCH_PHASE) - { - me->DespawnOrUnsummon(1ms); - } - } + DoMeleeAttackIfReady(); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() || me->GetEntry() == NPC_TWILIGHT_EGG) - { - return; - } - - fadeArmorTimer += diff; - if (fadeArmorTimer >= 15000) - { - if (Aura* aur = me->GetVictim()->GetAura(SPELL_FADE_ARMOR)) - { - aur->ModStackAmount(1); - } - else - { - DoCastVictim(SPELL_FADE_ARMOR, false); - } - - fadeArmorTimer = 0; - } - - DoMeleeAttackIfReady(); - } - - private: - uint32 fadeArmorTimer; - }; +private: + uint32 fadeArmorTimer; }; class spell_sartharion_lava_strike : public SpellScript @@ -1549,9 +1356,7 @@ class spell_sartharion_lava_strike : public SpellScript void HandleDummy(SpellEffIndex /*effIndex*/) { if (!GetCaster() || !GetHitUnit()) - { return; - } GetCaster()->CastSpell(GetHitUnit()->GetPositionX(), GetHitUnit()->GetPositionY(), GetHitUnit()->GetPositionZ(), SPELL_LAVA_STRIKE_DUMMY_TRIGGER, true); } @@ -1559,9 +1364,7 @@ class spell_sartharion_lava_strike : public SpellScript void HandleSchoolDamage(SpellEffIndex /*effIndex*/) { if (!GetCaster() || !GetHitUnit() || _spawned) - { return; - } if (InstanceScript* instance = GetCaster()->GetInstanceScript()) { @@ -1577,13 +1380,9 @@ class spell_sartharion_lava_strike : public SpellScript void Register() override { if (m_scriptSpellId == SPELL_LAVA_STRIKE_DUMMY) - { OnEffectHitTarget += SpellEffectFn(spell_sartharion_lava_strike::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } else - { OnEffectHitTarget += SpellEffectFn(spell_sartharion_lava_strike::HandleSchoolDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - } } private: @@ -1637,11 +1436,11 @@ class spell_obsidian_sanctum_flame_tsunami_leap : public SpellScript void AddSC_boss_sartharion() { - new boss_sartharion(); - new boss_sartharion_shadron(); - new boss_sartharion_tenebron(); - new boss_sartharion_vesperon(); - new npc_twilight_summon(); + RegisterObsidianSanctumCreatureAI(boss_sartharion); + RegisterObsidianSanctumCreatureAI(boss_sartharion_shadron); + RegisterObsidianSanctumCreatureAI(boss_sartharion_tenebron); + RegisterObsidianSanctumCreatureAI(boss_sartharion_vesperon); + RegisterObsidianSanctumCreatureAI(npc_twilight_summon); RegisterSpellScript(spell_sartharion_lava_strike); RegisterSpellScript(spell_obsidian_sanctum_flame_tsunami); RegisterSpellScript(spell_obsidian_sanctum_flame_tsunami_leap); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h index c92d28754..02c6b3983 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h @@ -66,4 +66,6 @@ inline AI* GetObsidianSanctumAI(T* obj) return GetInstanceAI(obj, ObsidianSanctumScriptName); } +#define RegisterObsidianSanctumCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetObsidianSanctumAI) + #endif From 3b8ac391d9d90c4ad1e3784510d0cf2d1db2ed0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Borz=C3=AC?= Date: Sat, 7 Feb 2026 21:22:58 +0100 Subject: [PATCH 061/335] fix(Core/Scripts): apply safety improvements (#24635) --- src/server/game/Maps/Map.cpp | 2 +- .../Northrend/Naxxramas/boss_four_horsemen.cpp | 12 ++++++++---- .../scripts/Northrend/Naxxramas/boss_thaddius.cpp | 3 ++- src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp | 3 ++- .../scripts/Outland/BlackTemple/boss_illidan.cpp | 3 ++- src/server/scripts/World/scourge_invasion.cpp | 3 ++- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 0ea47ff8a..13b3ee3b5 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -568,7 +568,7 @@ void Map::AddObjectToPendingUpdateList(WorldObject* obj) return; UpdatableMapObject* mapUpdatableObject = dynamic_cast(obj); - if (mapUpdatableObject->GetUpdateState() != UpdatableMapObject::UpdateState::NotUpdating) + if (!mapUpdatableObject || mapUpdatableObject->GetUpdateState() != UpdatableMapObject::UpdateState::NotUpdating) return; _pendingAddUpdatableObjectList.insert(obj); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp index d73579c25..ba777b91e 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp @@ -169,10 +169,14 @@ public: { if (why == EVADE_REASON_BOUNDARY) { - instance->GetCreature(DATA_BARON_RIVENDARE_BOSS)->AI()->EnterEvadeMode(EVADE_REASON_OTHER); - instance->GetCreature(DATA_LADY_BLAUMEUX_BOSS)->AI()->EnterEvadeMode(EVADE_REASON_OTHER); - instance->GetCreature(DATA_SIR_ZELIEK_BOSS)->AI()->EnterEvadeMode(EVADE_REASON_OTHER); - instance->GetCreature(DATA_THANE_KORTHAZZ_BOSS)->AI()->EnterEvadeMode(EVADE_REASON_OTHER); + if (Creature* cr = instance->GetCreature(DATA_BARON_RIVENDARE_BOSS)) + cr->AI()->EnterEvadeMode(EVADE_REASON_OTHER); + if (Creature* cr = instance->GetCreature(DATA_LADY_BLAUMEUX_BOSS)) + cr->AI()->EnterEvadeMode(EVADE_REASON_OTHER); + if (Creature* cr = instance->GetCreature(DATA_SIR_ZELIEK_BOSS)) + cr->AI()->EnterEvadeMode(EVADE_REASON_OTHER); + if (Creature* cr = instance->GetCreature(DATA_THANE_KORTHAZZ_BOSS)) + cr->AI()->EnterEvadeMode(EVADE_REASON_OTHER); } BossAI::EnterEvadeMode(); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp index f0831da05..d2e7dd1da 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp @@ -391,7 +391,8 @@ public: me->SetControlled(false, UNIT_STATE_STUNNED); if (why == EVADE_REASON_BOUNDARY) - instance->GetCreature(DATA_THADDIUS_BOSS)->AI()->EnterEvadeMode(EVADE_REASON_BOUNDARY); + if (Creature* thaddius = instance->GetCreature(DATA_THADDIUS_BOSS)) + thaddius->AI()->EnterEvadeMode(EVADE_REASON_BOUNDARY); ScriptedAI::EnterEvadeMode(why); } diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp index 57bdb8d5d..77bf4b4fa 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp @@ -142,7 +142,8 @@ void OutdoorPvPTF::ResetZoneToTeamControlled(TeamId team) for (auto& [guid, tower] : _capturePoints) { - dynamic_cast(tower)->ResetToTeamControlled(team); + if (auto* capturePoint = dynamic_cast(tower)) + capturePoint->ResetToTeamControlled(team); } SendUpdateWorldState(WORLD_STATE_OPVP_TF_UI_TOWER_COUNT_H, m_HordeTowersControlled); diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index 5e6dfac6e..4fe7fc412 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -1000,7 +1000,8 @@ struct npc_akama_illidan : public ScriptedAI void JustReachedHome() override { // Minions Event - if (instance->GetBossState(DATA_ILLIDAN_STORMRAGE) == IN_PROGRESS && !instance->GetCreature(DATA_ILLIDAN_STORMRAGE)->HasAura(SPELL_DEATH)) + Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE); + if (illidan && instance->GetBossState(DATA_ILLIDAN_STORMRAGE) == IN_PROGRESS && !illidan->HasAura(SPELL_DEATH)) { me->SetReactState(REACT_PASSIVE); me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); diff --git a/src/server/scripts/World/scourge_invasion.cpp b/src/server/scripts/World/scourge_invasion.cpp index 4eafd5306..eb7565780 100644 --- a/src/server/scripts/World/scourge_invasion.cpp +++ b/src/server/scripts/World/scourge_invasion.cpp @@ -238,7 +238,8 @@ struct npc_necropolis_health : public ScriptedAI if (spellInfo->Id == SPELL_DESPAWNER_OTHER && target->GetEntry() == NPC_NECROPOLIS) { DespawnNecropolis(); - dynamic_cast(target)->DespawnOrUnsummon(); + if (Creature* creature = target->ToCreature()) + creature->DespawnOrUnsummon(); me->DespawnOrUnsummon(); } } From 28f91949ea13de47ecf3aa6d14fdf58ee722b566 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 7 Feb 2026 18:30:13 -0300 Subject: [PATCH 062/335] chore: Update ClaudeAI SQL updates directory instructions (#24640) --- CLAUDE.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index b2d126823..5ddfc3343 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -84,7 +84,8 @@ Scripts follow a registration pattern: - **acore_characters** - Character data, inventories, progress (`data/sql/base/db_characters/`) - **acore_world** - Game content: creatures, items, quests, spells, loot (`data/sql/base/db_world/`) -SQL updates go in `data/sql/updates/` with separate subdirectories per database. +SQL updates go in `data/sql/updates/pending_*` with separate subdirectories per database until pull request is merged. +SQL updates go in `data/sql/updates/` with separate subdirectories per database after their pull request is merged. ### Module system @@ -111,6 +112,8 @@ Type(Scope/Subscope): Short description (max 50 chars) - 2-space indentation for JSON, YAML, shell scripts - UTF-8 encoding, LF line endings - Max 80 character line length +- No braces around single-line statements +- Use {} to parse variables into output instead of %u etc. - CI enforces code style checks and compiles with `-Werror` ## PR Requirements From 50aa26bef9260ead87ddc28ed129506b22c2cc59 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Sat, 7 Feb 2026 23:32:04 +0100 Subject: [PATCH 063/335] fix(Core/SmartScript): Start Closest Waypoint can handle both wp tables. (#24638) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../pending_db_world/Scarlet_Ghouls_WP.sql | 110 ++++++++++++++++++ .../game/AI/SmartScripts/SmartScript.cpp | 31 ++++- .../game/AI/SmartScripts/SmartScriptMgr.h | 1 + 3 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 data/sql/updates/pending_db_world/Scarlet_Ghouls_WP.sql diff --git a/data/sql/updates/pending_db_world/Scarlet_Ghouls_WP.sql b/data/sql/updates/pending_db_world/Scarlet_Ghouls_WP.sql new file mode 100644 index 000000000..ddfd71a4c --- /dev/null +++ b/data/sql/updates/pending_db_world/Scarlet_Ghouls_WP.sql @@ -0,0 +1,110 @@ + +-- Move waypoints to waypoint_data +DELETE FROM `waypoints` WHERE `entry` IN (2889700, 2889701, 2889702, 2889703, 2889704, 2889705, 2889706); +DELETE FROM `waypoint_data` WHERE `id` IN (2889700, 2889701, 2889702, 2889703, 2889704, 2889705, 2889706); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(2889700, 1, 2195.3638, -6096.684, 1.9554013, NULL, 0, 0, 0, 100, 0), +(2889700, 2, 2134.17, -6095.6626, 6.1250257, NULL, 0, 0, 0, 100, 0), +(2889700, 3, 2093.4673, -6034.3447, 9.515682, NULL, 0, 0, 0, 100, 0), +(2889700, 4, 2071.7117, -6016.3516, 12.850294, NULL, 0, 0, 0, 100, 0), +(2889700, 5, 2055.4822, -6009.923, 18.771358, NULL, 0, 0, 0, 100, 0), +(2889700, 6, 2039.4476, -6003.6445, 26.167065, NULL, 0, 0, 0, 100, 0), +(2889700, 7, 2031.4705, -6000.2095, 32.67357, NULL, 0, 0, 0, 100, 0), +(2889700, 8, 2027.7562, -6003.44, 37.135815, NULL, 0, 0, 0, 100, 0), +(2889700, 9, 2011.0663, -5996.0796, 44.111214, NULL, 0, 0, 0, 100, 0), +(2889700, 10, 1997.2365, -5990.1543, 54.388668, NULL, 0, 0, 0, 100, 0), +(2889700, 11, 1982.8765, -5984.335, 66.13348, NULL, 0, 0, 0, 100, 0), +(2889700, 12, 1969.1548, -5978.072, 77.45486, NULL, 0, 0, 0, 100, 0), +(2889700, 13, 1956.6283, -5972.649, 88.85666, NULL, 0, 0, 0, 100, 0), +(2889700, 14, 1941.6298, -5965.9805, 100.383446, NULL, 0, 0, 0, 100, 0), +(2889700, 15, 1916.4559, -5952.4526, 101.24492, NULL, 0, 0, 0, 100, 0), +(2889700, 16, 1882.0538, -5938.461, 103.13395, NULL, 0, 0, 0, 100, 0), +(2889700, 17, 1830.4075, -5918.2676, 109.342636, NULL, 0, 0, 0, 100, 0), +(2889701, 1, 2134.17, -6095.6626, 6.1250257, NULL, 0, 0, 0, 100, 0), +(2889701, 2, 2093.4673, -6034.3447, 9.515682, NULL, 0, 0, 0, 100, 0), +(2889701, 3, 2071.7117, -6016.3516, 12.850294, NULL, 0, 0, 0, 100, 0), +(2889701, 4, 2055.4822, -6009.923, 18.771358, NULL, 0, 0, 0, 100, 0), +(2889701, 5, 2039.4476, -6003.6445, 26.167065, NULL, 0, 0, 0, 100, 0), +(2889701, 6, 2031.4705, -6000.2095, 32.67357, NULL, 0, 0, 0, 100, 0), +(2889701, 7, 2027.7562, -6003.44, 37.135815, NULL, 0, 0, 0, 100, 0), +(2889701, 8, 2011.0663, -5996.0796, 44.111214, NULL, 0, 0, 0, 100, 0), +(2889701, 9, 1997.2365, -5990.1543, 54.388668, NULL, 0, 0, 0, 100, 0), +(2889701, 10, 1982.8765, -5984.335, 66.13348, NULL, 0, 0, 0, 100, 0), +(2889701, 11, 1969.1548, -5978.072, 77.45486, NULL, 0, 0, 0, 100, 0), +(2889701, 12, 1956.6283, -5972.649, 88.85666, NULL, 0, 0, 0, 100, 0), +(2889701, 13, 1941.6298, -5965.9805, 100.383446, NULL, 0, 0, 0, 100, 0), +(2889701, 14, 1932.219, -5938.6284, 102.60785, NULL, 0, 0, 0, 100, 0), +(2889701, 15, 1922.8248, -5911.5547, 101.57721, NULL, 0, 0, 0, 100, 0), +(2889701, 16, 1904.4485, -5886.1274, 101.34244, NULL, 0, 0, 0, 100, 0), +(2889701, 17, 1885.0721, -5868.9033, 102.31583, NULL, 0, 0, 0, 100, 0), +(2889701, 18, 1865.0361, -5856.944, 102.96336, NULL, 0, 0, 0, 100, 0), +(2889701, 19, 1845.4574, -5845.153, 102.1159, NULL, 0, 0, 0, 100, 0), +(2889701, 20, 1827.5663, -5833.8936, 102.35004, NULL, 0, 0, 0, 100, 0), +(2889701, 21, 1815.0728, -5826.0312, 104.49583, NULL, 0, 0, 0, 100, 0), +(2889701, 22, 1803.1136, -5819.4585, 108.53935, NULL, 0, 0, 0, 100, 0), +(2889702, 1, 2149.137, -5851.649, 101.358665, NULL, 0, 0, 0, 100, 0), +(2889702, 2, 2053.9631, -5848.3438, 102.19084, NULL, 0, 0, 0, 100, 0), +(2889702, 3, 1979.5673, -5854.149, 100.74358, NULL, 0, 0, 0, 100, 0), +(2889702, 4, 1892.4893, -5856.9663, 101.901276, NULL, 0, 0, 0, 100, 0), +(2889702, 5, 1876.3115, -5847.535, 102.11675, NULL, 0, 0, 0, 100, 0), +(2889702, 6, 1854.0287, -5836.069, 101.78623, NULL, 0, 0, 0, 100, 0), +(2889702, 7, 1835.2474, -5825.923, 100.77055, NULL, 0, 0, 0, 100, 0), +(2889702, 8, 1819.5686, -5818.2095, 104.0615, NULL, 0, 0, 0, 100, 0), +(2889702, 9, 1804.9038, -5811.438, 108.21074, NULL, 0, 0, 0, 100, 0), +(2889703, 1, 2137.5742, -5793.847, 99.60594, NULL, 0, 0, 0, 100, 0), +(2889703, 2, 2061.7412, -5811.5776, 103.39335, NULL, 0, 0, 0, 100, 0), +(2889703, 3, 1981.0283, -5807.502, 101.002556, NULL, 0, 0, 0, 100, 0), +(2889703, 4, 1912.7769, -5768.238, 103.644135, NULL, 0, 0, 0, 100, 0), +(2889703, 5, 1904.1472, -5806.2334, 100.84862, NULL, 0, 0, 0, 100, 0), +(2889703, 6, 1896.8984, -5836.7305, 101.094154, NULL, 0, 0, 0, 100, 0), +(2889703, 7, 1892.4893, -5856.9663, 101.901276, NULL, 0, 0, 0, 100, 0), +(2889703, 8, 1887.3644, -5884.821, 102.246506, NULL, 0, 0, 0, 100, 0), +(2889703, 9, 1871.814, -5893.7964, 103.64108, NULL, 0, 0, 0, 100, 0), +(2889703, 10, 1857.1747, -5902.0386, 104.01655, NULL, 0, 0, 0, 100, 0), +(2889703, 11, 1830.3524, -5917.68, 109.23609, NULL, 0, 0, 0, 100, 0), +(2889704, 1, 2135.5713, -5917.6436, 99.79425, NULL, 0, 0, 0, 100, 0), +(2889704, 2, 2128.1082, -5918.4746, 102.57842, NULL, 0, 0, 0, 100, 0), +(2889704, 3, 2119.8977, -5919.75, 104.845924, NULL, 0, 0, 0, 100, 0), +(2889704, 4, 2106.674, -5921.8564, 105.8994, NULL, 0, 0, 0, 100, 0), +(2889704, 5, 2098.4468, -5923.068, 106.78917, NULL, 0, 0, 0, 100, 0), +(2889704, 6, 2085.5823, -5925.1177, 105.65261, NULL, 0, 0, 0, 100, 0), +(2889704, 7, 2072.7903, -5927.2314, 106.47965, NULL, 0, 0, 0, 100, 0), +(2889704, 8, 2058.0674, -5929.905, 105.883446, NULL, 0, 0, 0, 100, 0), +(2889704, 9, 1993.3854, -5934.4653, 103.23653, NULL, 0, 0, 0, 100, 0), +(2889704, 10, 1914.4014, -5934.455, 103.03427, NULL, 0, 0, 0, 100, 0), +(2889704, 11, 1897.3982, -5930.1514, 103.310394, NULL, 0, 0, 0, 100, 0), +(2889704, 12, 1879.5057, -5926.649, 104.29986, NULL, 0, 0, 0, 100, 0), +(2889704, 13, 1859.5677, -5922.3164, 104.62177, NULL, 0, 0, 0, 100, 0), +(2889704, 14, 1844.7861, -5919.962, 106.564575, NULL, 0, 0, 0, 100, 0), +(2889704, 15, 1830.4172, -5918.243, 109.36247, NULL, 0, 0, 0, 100, 0), +(2889705, 1, 2339.3877, -5872.3906, 102.40258, NULL, 0, 0, 0, 100, 0), +(2889705, 2, 2277.8735, -5881.4644, 100.51856, NULL, 0, 0, 0, 100, 0), +(2889705, 3, 2237.9512, -5908.162, 100.5426, NULL, 0, 0, 0, 100, 0), +(2889705, 4, 2179.2607, -5916.5723, 100.833466, NULL, 0, 0, 0, 100, 0), +(2889705, 5, 2135.5713, -5917.6436, 99.79425, NULL, 0, 0, 0, 100, 0), +(2889705, 6, 2128.1082, -5918.4746, 102.57842, NULL, 0, 0, 0, 100, 0), +(2889705, 7, 2119.8977, -5919.75, 104.845924, NULL, 0, 0, 0, 100, 0), +(2889705, 8, 2106.674, -5921.8564, 105.8994, NULL, 0, 0, 0, 100, 0), +(2889705, 9, 2098.4468, -5923.068, 106.78917, NULL, 0, 0, 0, 100, 0), +(2889705, 10, 2085.5823, -5925.1177, 105.65261, NULL, 0, 0, 0, 100, 0), +(2889705, 11, 2072.7903, -5927.2314, 106.47965, NULL, 0, 0, 0, 100, 0), +(2889705, 12, 2058.0674, -5929.905, 105.883446, NULL, 0, 0, 0, 100, 0), +(2889705, 13, 1993.3854, -5934.4653, 103.23653, NULL, 0, 0, 0, 100, 0), +(2889705, 14, 1914.4014, -5934.455, 103.03427, NULL, 0, 0, 0, 100, 0), +(2889705, 15, 1897.3982, -5930.1514, 103.310394, NULL, 0, 0, 0, 100, 0), +(2889705, 16, 1879.5057, -5926.649, 104.29986, NULL, 0, 0, 0, 100, 0), +(2889705, 17, 1859.5677, -5922.3164, 104.62177, NULL, 0, 0, 0, 100, 0), +(2889705, 18, 1844.7861, -5919.962, 106.564575, NULL, 0, 0, 0, 100, 0), +(2889705, 19, 1830.4172, -5918.243, 109.36247, NULL, 0, 0, 0, 100, 0), +(2889706, 1, 2278.1655, -5838.218, 100.934555, NULL, 0, 0, 0, 100, 0), +(2889706, 2, 2226.8245, -5841.505, 101.31162, NULL, 0, 0, 0, 100, 0), +(2889706, 3, 2172.0278, -5844.5312, 101.348076, NULL, 0, 0, 0, 100, 0), +(2889706, 4, 2149.137, -5851.649, 101.358665, NULL, 0, 0, 0, 100, 0), +(2889706, 5, 2053.9631, -5848.3438, 102.19084, NULL, 0, 0, 0, 100, 0), +(2889706, 6, 1979.5673, -5854.149, 100.74358, NULL, 0, 0, 0, 100, 0), +(2889706, 7, 1892.4893, -5856.9663, 101.901276, NULL, 0, 0, 0, 100, 0), +(2889706, 8, 1876.3115, -5847.535, 102.11675, NULL, 0, 0, 0, 100, 0), +(2889706, 9, 1854.0287, -5836.069, 101.78623, NULL, 0, 0, 0, 100, 0), +(2889706, 10, 1835.2474, -5825.923, 100.77055, NULL, 0, 0, 0, 100, 0), +(2889706, 11, 1819.5686, -5818.2095, 104.0615, NULL, 0, 0, 0, 100, 0), +(2889706, 12, 1804.9038, -5811.438, 108.21074, NULL, 0, 0, 0, 100, 0); diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index e366560c9..ff41ef0ed 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2506,6 +2506,15 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } case SMART_ACTION_START_CLOSEST_WAYPOINT: { + PathSource pathSource = static_cast(e.action.startClosestWaypoint.pathSource); + + if (pathSource != PathSource::WAYPOINT_MGR && pathSource != PathSource::SMART_WAYPOINT_MGR) + { + LOG_ERROR("scripts.ai.sai", "SmartScript::ProcessAction: SMART_ACTION_START_CLOSEST_WAYPOINT: Invalid PathSource {} for entryOrGuid {} source_type {} event_id {} link {}", + static_cast(pathSource), e.entryOrGuid, e.source_type, e.event_id, e.link); + break; + } + float distanceToClosest = std::numeric_limits::max(); uint32 closestWpId = 0; @@ -2515,21 +2524,33 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { if (IsSmart(creature)) { - for (uint32 wp = e.action.startClosestWaypoint.pathId1; wp <= e.action.startClosestWaypoint.pathId2; ++wp) + for (uint32 pathId = e.action.startClosestWaypoint.pathId1; pathId <= e.action.startClosestWaypoint.pathId2; ++pathId) { - WaypointPath* path = sSmartWaypointMgr->GetPath(wp); + WaypointPath const* path = nullptr; + + switch (pathSource) + { + case PathSource::SMART_WAYPOINT_MGR: + path = sSmartWaypointMgr->GetPath(pathId); + break; + case PathSource::WAYPOINT_MGR: + path = sWaypointMgr->GetPath(pathId); + break; + } + if (!path || path->empty()) continue; auto itrWp = path->find(1); if (itrWp != path->end()) { - WaypointData& wpData = itrWp->second; + WaypointData const& wpData = itrWp->second; float distToThisPath = creature->GetExactDistSq(wpData.x, wpData.y, wpData.z); + if (distToThisPath < distanceToClosest) { distanceToClosest = distToThisPath; - closestWpId = wp; + closestWpId = pathId; } } } @@ -2539,7 +2560,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u bool repeat = e.action.startClosestWaypoint.repeat; ForcedMovement forcedMovement = static_cast(e.action.startClosestWaypoint.forcedMovement); - CAST_AI(SmartAI, creature->AI())->StartPath(forcedMovement, closestWpId, repeat); + CAST_AI(SmartAI, creature->AI())->StartPath(forcedMovement, closestWpId, repeat, nullptr, pathSource); } } } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 08d454663..8296d38d3 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1282,6 +1282,7 @@ struct SmartAction uint32 pathId2; uint32 repeat; uint32 forcedMovement; + PathSource pathSource; } startClosestWaypoint; struct From afe92f5f44715a323f3ae2cac607896dfc8d5463 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 7 Feb 2026 22:38:12 +0000 Subject: [PATCH 064/335] chore(DB): import pending files Referenced commit(s): 50aa26bef9260ead87ddc28ed129506b22c2cc59 --- .../Scarlet_Ghouls_WP.sql => db_world/2026_02_07_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/Scarlet_Ghouls_WP.sql => db_world/2026_02_07_00.sql} (99%) diff --git a/data/sql/updates/pending_db_world/Scarlet_Ghouls_WP.sql b/data/sql/updates/db_world/2026_02_07_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/Scarlet_Ghouls_WP.sql rename to data/sql/updates/db_world/2026_02_07_00.sql index ddfd71a4c..57d00c2c8 100644 --- a/data/sql/updates/pending_db_world/Scarlet_Ghouls_WP.sql +++ b/data/sql/updates/db_world/2026_02_07_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_06_09 -> 2026_02_07_00 -- Move waypoints to waypoint_data DELETE FROM `waypoints` WHERE `entry` IN (2889700, 2889701, 2889702, 2889703, 2889704, 2889705, 2889706); From e5a3f5abfe84a7e17869ce63a1ca2c80580175cd Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sun, 8 Feb 2026 05:28:27 -0300 Subject: [PATCH 065/335] fix(DB/Creature): Set Correct Speed to Illidan DB Target (23070) (#24647) --- data/sql/updates/pending_db_world/rev_1770513266735075300.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770513266735075300.sql diff --git a/data/sql/updates/pending_db_world/rev_1770513266735075300.sql b/data/sql/updates/pending_db_world/rev_1770513266735075300.sql new file mode 100644 index 000000000..1654d398a --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770513266735075300.sql @@ -0,0 +1,2 @@ +-- Up from 0.9 +UPDATE `creature_template` SET `speed_run` = 1.142857 WHERE (`entry` = 23070); From e0b50798a0d2c31efd977ebf3c24fcaf8dbb5120 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 8 Feb 2026 08:29:30 +0000 Subject: [PATCH 066/335] chore(DB): import pending files Referenced commit(s): e5a3f5abfe84a7e17869ce63a1ca2c80580175cd --- .../rev_1770513266735075300.sql => db_world/2026_02_08_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1770513266735075300.sql => db_world/2026_02_08_00.sql} (68%) diff --git a/data/sql/updates/pending_db_world/rev_1770513266735075300.sql b/data/sql/updates/db_world/2026_02_08_00.sql similarity index 68% rename from data/sql/updates/pending_db_world/rev_1770513266735075300.sql rename to data/sql/updates/db_world/2026_02_08_00.sql index 1654d398a..2301108e4 100644 --- a/data/sql/updates/pending_db_world/rev_1770513266735075300.sql +++ b/data/sql/updates/db_world/2026_02_08_00.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_07_00 -> 2026_02_08_00 -- Up from 0.9 UPDATE `creature_template` SET `speed_run` = 1.142857 WHERE (`entry` = 23070); From 2b563fc0e40cbe76ea0a4ce2f21fe67d7b1a0711 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 8 Feb 2026 08:36:35 -0300 Subject: [PATCH 067/335] feat(Scripts/Commands): Implement npc/gameobject load commands (#24644) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- .../pending_db_world/rev_1738958242619.sql | 5 + src/server/game/Globals/ObjectMgr.cpp | 280 ++++++++++++++++++ src/server/game/Globals/ObjectMgr.h | 30 ++ src/server/scripts/Commands/cs_gobject.cpp | 59 ++++ src/server/scripts/Commands/cs_npc.cpp | 54 ++++ 5 files changed, 428 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1738958242619.sql diff --git a/data/sql/updates/pending_db_world/rev_1738958242619.sql b/data/sql/updates/pending_db_world/rev_1738958242619.sql new file mode 100644 index 000000000..d62e49c51 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1738958242619.sql @@ -0,0 +1,5 @@ +-- +DELETE FROM `command` WHERE `name` IN ('npc load', 'gobject load'); +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('npc load', 3, 'Syntax: .npc load #spawnId\nLoad a creature spawn from the database into the world by its GUID.'), +('gobject load', 3, 'Syntax: .gobject load #spawnId\nLoad a gameobject spawn from the database into the world by its GUID.'); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 977d5436d..70164e6d9 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2422,6 +2422,164 @@ void ObjectMgr::LoadCreatures() LOG_INFO("server.loading", " "); } +// Loads a single creature spawn from DB into the cache. +// Creature::LoadCreatureFromDB() reads from cache (GetCreatureData()), not from DB directly, +// so this must be called first for spawns not loaded at startup. +CreatureData const* ObjectMgr::LoadCreatureDataFromDB(ObjectGuid::LowType spawnId) +{ + CreatureData const* data = GetCreatureData(spawnId); + if (data) + return data; + + QueryResult result = WorldDatabase.Query("SELECT creature.guid, id1, id2, id3, map, equipment_id, " + "position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, " + "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, " + "creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.ScriptName " + "FROM creature WHERE creature.guid = {}", spawnId); + + if (!result) + return nullptr; + + Field* fields = result->Fetch(); + uint32 id1 = fields[1].Get(); + uint32 id2 = fields[2].Get(); + uint32 id3 = fields[3].Get(); + + CreatureTemplate const* cInfo = GetCreatureTemplate(id1); + if (!cInfo) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non-existing creature entry {} in id1 field, skipped.", spawnId, id1); + return nullptr; + } + + if (id2 && !GetCreatureTemplate(id2)) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non-existing creature entry {} in id2 field, skipped.", spawnId, id2); + return nullptr; + } + + if (id3 && !GetCreatureTemplate(id3)) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non-existing creature entry {} in id3 field, skipped.", spawnId, id3); + return nullptr; + } + + if (!id2 && id3) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with creature entry {} in id3 field but no entry in id2 field, skipped.", spawnId, id3); + return nullptr; + } + + CreatureData& creatureData = _creatureDataStore[spawnId]; + creatureData.id1 = id1; + creatureData.id2 = id2; + creatureData.id3 = id3; + creatureData.mapid = fields[4].Get(); + creatureData.equipmentId = fields[5].Get(); + creatureData.posX = fields[6].Get(); + creatureData.posY = fields[7].Get(); + creatureData.posZ = fields[8].Get(); + creatureData.orientation = fields[9].Get(); + creatureData.spawntimesecs = fields[10].Get(); + creatureData.wander_distance = fields[11].Get(); + creatureData.currentwaypoint = fields[12].Get(); + creatureData.curhealth = fields[13].Get(); + creatureData.curmana = fields[14].Get(); + creatureData.movementType = fields[15].Get(); + creatureData.spawnMask = fields[16].Get(); + creatureData.phaseMask = fields[17].Get(); + creatureData.npcflag = fields[18].Get(); + creatureData.unit_flags = fields[19].Get(); + creatureData.dynamicflags = fields[20].Get(); + creatureData.ScriptId = GetScriptId(fields[21].Get()); + + if (!creatureData.ScriptId) + creatureData.ScriptId = cInfo->ScriptID; + + MapEntry const* mapEntry = sMapStore.LookupEntry(creatureData.mapid); + if (!mapEntry) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) that spawned at non-existing map (Id: {}), skipped.", spawnId, creatureData.mapid); + _creatureDataStore.erase(spawnId); + return nullptr; + } + + if (mapEntry->IsRaid() && creatureData.spawntimesecs >= 7 * DAY && creatureData.spawntimesecs < 14 * DAY) + creatureData.spawntimesecs = 14 * DAY; + + bool ok = true; + for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff) + { + if (_difficultyEntries[diff].find(id1) != _difficultyEntries[diff].end() || + _difficultyEntries[diff].find(id2) != _difficultyEntries[diff].end() || + _difficultyEntries[diff].find(id3) != _difficultyEntries[diff].end()) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) that is listed as difficulty {} template (Entries: {}, {}, {}) in `creature_template`, skipped.", + spawnId, diff + 1, id1, id2, id3); + ok = false; + } + } + + if (!ok) + { + _creatureDataStore.erase(spawnId); + return nullptr; + } + + if (creatureData.equipmentId != 0) + { + if (!GetEquipmentInfo(id1, creatureData.equipmentId) || + (id2 && !GetEquipmentInfo(id2, creatureData.equipmentId)) || + (id3 && !GetEquipmentInfo(id3, creatureData.equipmentId))) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (Entries: {}, {}, {}) with equipment_id {} not found in table `creature_equip_template`, set to no equipment.", + id1, id2, id3, creatureData.equipmentId); + creatureData.equipmentId = 0; + } + } + + if (creatureData.movementType >= MAX_DB_MOTION_TYPE) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with wrong movement generator type ({}), set to IDLE.", + spawnId, id1, id2, id3, creatureData.movementType); + creatureData.movementType = IDLE_MOTION_TYPE; + } + + if (creatureData.wander_distance < 0.0f) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `wander_distance`< 0, set to 0.", + spawnId, id1, id2, id3); + creatureData.wander_distance = 0.0f; + } + else if (creatureData.movementType == RANDOM_MOTION_TYPE) + { + if (creatureData.wander_distance == 0.0f) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `MovementType`=1 (random movement) but with `wander_distance`=0, replace by idle movement type (0).", + spawnId, id1, id2, id3); + creatureData.movementType = IDLE_MOTION_TYPE; + } + } + else if (creatureData.movementType == IDLE_MOTION_TYPE) + { + if (creatureData.wander_distance != 0.0f) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `MovementType`=0 (idle) have `wander_distance`<>0, set to 0.", + spawnId, id1, id2, id3); + creatureData.wander_distance = 0.0f; + } + } + + if (creatureData.phaseMask == 0) + { + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `phaseMask`=0 (not visible for anyone), set to 1.", + spawnId, id1, id2, id3); + creatureData.phaseMask = 1; + } + + return &creatureData; +} + void ObjectMgr::LoadCreatureSparring() { uint32 oldMSTime = getMSTime(); @@ -2764,6 +2922,128 @@ void ObjectMgr::LoadGameobjects() LOG_INFO("server.loading", " "); } +// Loads a single gameobject spawn from DB into the cache. +// GameObject::LoadGameObjectFromDB() reads from cache (GetGameObjectData()), not from DB directly, +// so this must be called first for spawns not loaded at startup. +GameObjectData const* ObjectMgr::LoadGameObjectDataFromDB(ObjectGuid::LowType spawnId) +{ + GameObjectData const* data = GetGameObjectData(spawnId); + if (data) + return data; + + QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, " + "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, " + "ScriptName " + "FROM gameobject WHERE gameobject.guid = {}", spawnId); + + if (!result) + return nullptr; + + Field* fields = result->Fetch(); + uint32 entry = fields[1].Get(); + + GameObjectTemplate const* gInfo = GetGameObjectTemplate(entry); + if (!gInfo) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {}) with non-existing gameobject entry {}, skipped.", spawnId, entry); + return nullptr; + } + + if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId)) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry {} GoType: {}) with an invalid displayId ({}), not loaded.", + spawnId, entry, gInfo->type, gInfo->displayId); + return nullptr; + } + + GameObjectData& goData = _gameObjectDataStore[spawnId]; + goData.id = entry; + goData.mapid = fields[2].Get(); + goData.posX = fields[3].Get(); + goData.posY = fields[4].Get(); + goData.posZ = fields[5].Get(); + goData.orientation = fields[6].Get(); + goData.rotation.x = fields[7].Get(); + goData.rotation.y = fields[8].Get(); + goData.rotation.z = fields[9].Get(); + goData.rotation.w = fields[10].Get(); + goData.spawntimesecs = fields[11].Get(); + goData.animprogress = fields[12].Get(); + goData.artKit = 0; + goData.ScriptId = GetScriptId(fields[16].Get()); + + if (!goData.ScriptId) + goData.ScriptId = gInfo->ScriptId; + + MapEntry const* mapEntry = sMapStore.LookupEntry(goData.mapid); + if (!mapEntry) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existing map (Id: {}), skipped.", spawnId, entry, goData.mapid); + _gameObjectDataStore.erase(spawnId); + return nullptr; + } + + if (goData.spawntimesecs == 0 && gInfo->IsDespawnAtAction()) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `spawntimesecs` (0) value, but the gameobject is marked as despawnable at action.", spawnId, entry); + } + + uint32 go_state = fields[13].Get(); + if (go_state >= MAX_GO_STATE) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skipped.", spawnId, entry, go_state); + _gameObjectDataStore.erase(spawnId); + return nullptr; + } + goData.go_state = GOState(go_state); + + goData.spawnMask = fields[14].Get(); + goData.phaseMask = fields[15].Get(); + + if (goData.rotation.x < -1.0f || goData.rotation.x > 1.0f) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skipped.", spawnId, entry, goData.rotation.x); + _gameObjectDataStore.erase(spawnId); + return nullptr; + } + + if (goData.rotation.y < -1.0f || goData.rotation.y > 1.0f) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skipped.", spawnId, entry, goData.rotation.y); + _gameObjectDataStore.erase(spawnId); + return nullptr; + } + + if (goData.rotation.z < -1.0f || goData.rotation.z > 1.0f) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skipped.", spawnId, entry, goData.rotation.z); + _gameObjectDataStore.erase(spawnId); + return nullptr; + } + + if (goData.rotation.w < -1.0f || goData.rotation.w > 1.0f) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skipped.", spawnId, entry, goData.rotation.w); + _gameObjectDataStore.erase(spawnId); + return nullptr; + } + + if (!MapMgr::IsValidMapCoord(goData.mapid, goData.posX, goData.posY, goData.posZ, goData.orientation)) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skipped.", spawnId, entry); + _gameObjectDataStore.erase(spawnId); + return nullptr; + } + + if (goData.phaseMask == 0) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.", spawnId, entry); + goData.phaseMask = 1; + } + + return &goData; +} + void ObjectMgr::AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData const* data) { uint8 mask = data->spawnMask; diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 4ac1e33b6..d9f458293 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1226,6 +1226,21 @@ public: [[nodiscard]] CreatureSparringContainer const& GetSparringData() const { return _creatureSparringStore; } CreatureData& NewOrExistCreatureData(ObjectGuid::LowType spawnId) { return _creatureDataStore[spawnId]; } + /** + * @brief Loads a single creature spawn entry from the database into the data store cache. + * + * This is needed as a prerequisite for Creature::LoadCreatureFromDB(), which reads + * from the in-memory cache (via GetCreatureData()) rather than querying the DB itself. + * For spawns not loaded during server startup, this method populates the cache so that + * Creature::LoadCreatureFromDB() can then create the live entity. + * + * Returns the cached data if already loaded, or nullptr if the spawn doesn't exist + * or fails validation. + * + * @param spawnId The creature spawn GUID to load. + * @return Pointer to the cached CreatureData, or nullptr on failure. + */ + CreatureData const* LoadCreatureDataFromDB(ObjectGuid::LowType spawnId); void DeleteCreatureData(ObjectGuid::LowType spawnId); [[nodiscard]] ObjectGuid GetLinkedRespawnGuid(ObjectGuid guid) const { @@ -1311,6 +1326,21 @@ public: [[nodiscard]] QuestGreeting const* GetQuestGreeting(TypeID type, uint32 id) const; GameObjectData& NewGOData(ObjectGuid::LowType guid) { return _gameObjectDataStore[guid]; } + /** + * @brief Loads a single gameobject spawn entry from the database into the data store cache. + * + * This is needed as a prerequisite for GameObject::LoadGameObjectFromDB(), which reads + * from the in-memory cache (via GetGameObjectData()) rather than querying the DB itself. + * For spawns not loaded during server startup, this method populates the cache so that + * GameObject::LoadGameObjectFromDB() can then create the live entity. + * + * Returns the cached data if already loaded, or nullptr if the spawn doesn't exist + * or fails validation. + * + * @param spawnId The gameobject spawn GUID to load. + * @return Pointer to the cached GameObjectData, or nullptr on failure. + */ + GameObjectData const* LoadGameObjectDataFromDB(ObjectGuid::LowType spawnId); void DeleteGOData(ObjectGuid::LowType guid); [[nodiscard]] ModuleString const* GetModuleString(std::string module, uint32 id) const diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index e41d93d07..46db7cf4c 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -50,6 +50,7 @@ public: { "turn", HandleGameObjectTurnCommand, SEC_ADMINISTRATOR, Console::No }, { "add temp", HandleGameObjectAddTempCommand, SEC_GAMEMASTER, Console::No }, { "add", HandleGameObjectAddCommand, SEC_ADMINISTRATOR, Console::No }, + { "load", HandleGameObjectLoadCommand, SEC_ADMINISTRATOR, Console::Yes }, { "set phase", HandleGameObjectSetPhaseCommand, SEC_ADMINISTRATOR, Console::No }, { "set state", HandleGameObjectSetStateCommand, SEC_ADMINISTRATOR, Console::No }, { "respawn", HandleGameObjectRespawn, SEC_GAMEMASTER, Console::No } @@ -144,6 +145,64 @@ public: return true; } + static bool HandleGameObjectLoadCommand(ChatHandler* handler, GameObjectSpawnId spawnId) + { + if (!spawnId) + return false; + + if (sObjectMgr->GetGameObjectData(spawnId)) + { + handler->SendErrorMessage("Gameobject spawn {} is already loaded.", uint32(spawnId)); + return false; + } + + GameObjectData const* data = sObjectMgr->LoadGameObjectDataFromDB(spawnId); + if (!data) + { + handler->SendErrorMessage("Gameobject spawn {} not found in the database.", uint32(spawnId)); + return false; + } + + if (sPoolMgr->IsPartOfAPool(spawnId)) + { + handler->SendErrorMessage("Gameobject spawn {} is part of a pool and cannot be manually loaded.", uint32(spawnId)); + return false; + } + + QueryResult eventResult = WorldDatabase.Query("SELECT guid FROM game_event_gameobject WHERE guid = {}", uint32(spawnId)); + if (eventResult) + { + handler->SendErrorMessage("Gameobject spawn {} is managed by the game event system and cannot be manually loaded.", uint32(spawnId)); + return false; + } + + Map* map = sMapMgr->FindBaseNonInstanceMap(data->mapid); + if (!map) + { + handler->SendErrorMessage("Gameobject spawn {} is on a non-continent map (ID: {}). Only continent maps are supported.", uint32(spawnId), data->mapid); + return false; + } + + GameObjectTemplate const* objectInfo = sObjectMgr->GetGameObjectTemplate(data->id); + if (!objectInfo) + { + handler->SendErrorMessage("Gameobject template not found for entry {}.", data->id); + return false; + } + + GameObject* object = sObjectMgr->IsGameObjectStaticTransport(objectInfo->entry) ? new StaticTransport() : new GameObject(); + if (!object->LoadGameObjectFromDB(spawnId, map, true)) + { + delete object; + handler->SendErrorMessage("Failed to load gameobject spawn {}.", uint32(spawnId)); + return false; + } + + sObjectMgr->AddGameobjectToGrid(spawnId, data); + handler->PSendSysMessage("Gameobject spawn {} loaded successfully.", uint32(spawnId)); + return true; + } + // add go, temp only static bool HandleGameObjectAddTempCommand(ChatHandler* handler, GameObjectEntry objectId, Optional spawntime) { diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 66c50537e..e933d4be1 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -21,9 +21,11 @@ #include "CreatureGroups.h" #include "GameTime.h" #include "Language.h" +#include "MapMgr.h" #include "ObjectMgr.h" #include "Pet.h" #include "Player.h" +#include "PoolMgr.h" #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand #include "Transport.h" #include @@ -192,6 +194,7 @@ public: { "add", npcAddCommandTable }, { "delete", npcDeleteCommandTable }, { "follow", npcFollowCommandTable }, + { "load", HandleNpcLoadCommand, SEC_ADMINISTRATOR, Console::Yes }, { "set", npcSetCommandTable } }; static ChatCommandTable commandTable = @@ -260,6 +263,57 @@ public: return true; } + static bool HandleNpcLoadCommand(ChatHandler* handler, CreatureSpawnId spawnId) + { + if (!spawnId) + return false; + + if (sObjectMgr->GetCreatureData(spawnId)) + { + handler->SendErrorMessage("Creature spawn {} is already loaded.", uint32(spawnId)); + return false; + } + + CreatureData const* data = sObjectMgr->LoadCreatureDataFromDB(spawnId); + if (!data) + { + handler->SendErrorMessage("Creature spawn {} not found in the database.", uint32(spawnId)); + return false; + } + + if (sPoolMgr->IsPartOfAPool(spawnId)) + { + handler->SendErrorMessage("Creature spawn {} is part of a pool and cannot be manually loaded.", uint32(spawnId)); + return false; + } + + QueryResult eventResult = WorldDatabase.Query("SELECT guid FROM game_event_creature WHERE guid = {}", uint32(spawnId)); + if (eventResult) + { + handler->SendErrorMessage("Creature spawn {} is managed by the game event system and cannot be manually loaded.", uint32(spawnId)); + return false; + } + + Map* map = sMapMgr->FindBaseNonInstanceMap(data->mapid); + if (!map) + { + handler->SendErrorMessage("Creature spawn {} is on a non-continent map (ID: {}). Only continent maps are supported.", uint32(spawnId), data->mapid); + return false; + } + + Creature* creature = new Creature(); + if (!creature->LoadCreatureFromDB(spawnId, map, true, true)) + { + delete creature; + handler->SendErrorMessage("Failed to load creature spawn {}.", uint32(spawnId)); + return false; + } + + sObjectMgr->AddCreatureToGrid(spawnId, data); + handler->PSendSysMessage("Creature spawn {} loaded successfully.", uint32(spawnId)); + return true; + } + //add item in vendorlist static bool HandleNpcAddVendorItemCommand(ChatHandler* handler, ItemTemplate const* item, Optional mc, Optional it, Optional ec, Optional addMulti) { From c883eb578a2d0bf373e001490097f9e4e3cbb56d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 8 Feb 2026 11:37:44 +0000 Subject: [PATCH 068/335] chore(DB): import pending files Referenced commit(s): 2b563fc0e40cbe76ea0a4ce2f21fe67d7b1a0711 --- .../rev_1738958242619.sql => db_world/2026_02_08_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1738958242619.sql => db_world/2026_02_08_01.sql} (89%) diff --git a/data/sql/updates/pending_db_world/rev_1738958242619.sql b/data/sql/updates/db_world/2026_02_08_01.sql similarity index 89% rename from data/sql/updates/pending_db_world/rev_1738958242619.sql rename to data/sql/updates/db_world/2026_02_08_01.sql index d62e49c51..c8f56fb38 100644 --- a/data/sql/updates/pending_db_world/rev_1738958242619.sql +++ b/data/sql/updates/db_world/2026_02_08_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_08_00 -> 2026_02_08_01 -- DELETE FROM `command` WHERE `name` IN ('npc load', 'gobject load'); INSERT INTO `command` (`name`, `security`, `help`) VALUES From 7571ada7671c809f4e029d7135585c8f7fe4951f Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sun, 8 Feb 2026 15:48:21 +0100 Subject: [PATCH 069/335] fix(Script/Quest): Kodo Roundup (#24241) --- .../rev_1766978833232988900.sql | 6 ++ src/server/scripts/Kalimdor/zone_desolace.cpp | 89 +++++++++---------- src/server/scripts/Spells/spell_quest.cpp | 51 +++++++++++ 3 files changed, 100 insertions(+), 46 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1766978833232988900.sql diff --git a/data/sql/updates/pending_db_world/rev_1766978833232988900.sql b/data/sql/updates/pending_db_world/rev_1766978833232988900.sql new file mode 100644 index 000000000..ebabbeb62 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1766978833232988900.sql @@ -0,0 +1,6 @@ +-- +DELETE FROM `spell_script_names` WHERE `spell_id`=18153 AND `ScriptName`='spell_q5561_kodo_roundup_kodo_kombobulator'; +DELETE FROM `spell_script_names` WHERE `spell_id`=18269 AND `ScriptName`='spell_q5561_kodo_roundup_kodo_kombobulator_despawn'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(18153, 'spell_q5561_kodo_roundup_kodo_kombobulator'), +(18269, 'spell_q5561_kodo_roundup_kodo_kombobulator_despawn'); diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp index 51b37790e..ebe78fe89 100644 --- a/src/server/scripts/Kalimdor/zone_desolace.cpp +++ b/src/server/scripts/Kalimdor/zone_desolace.cpp @@ -428,77 +428,74 @@ enum DyingKodo SPELL_KODO_KOMBO_GOSSIP = 18362 }; -class npc_aged_dying_ancient_kodo : public CreatureScript +struct npc_aged_dying_ancient_kodo : public ScriptedAI { -public: - npc_aged_dying_ancient_kodo() : CreatureScript("npc_aged_dying_ancient_kodo") { } + npc_aged_dying_ancient_kodo(Creature* creature) : ScriptedAI(creature) {} - struct npc_aged_dying_ancient_kodoAI : public ScriptedAI + void JustRespawned() override { - npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) {} + me->UpdateEntry(RAND(NPC_AGED_KODO, NPC_DYING_KODO, NPC_ANCIENT_KODO)); + } - void JustRespawned() override + void MoveInLineOfSight(Unit* who) override + { + if (who->GetEntry() == NPC_SMEED && me->IsWithinDistInMap(who, 10.0f) && !me->HasAura(SPELL_KODO_KOMBO_GOSSIP)) { - me->UpdateEntry(RAND(NPC_AGED_KODO, NPC_DYING_KODO, NPC_ANCIENT_KODO), nullptr, false); + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveIdle(); + + DoCast(me, SPELL_KODO_KOMBO_GOSSIP, true); + if (Creature* smeed = who->ToCreature()) + smeed->AI()->Talk(SAY_SMEED_HOME); } + } - void MoveInLineOfSight(Unit* who) override + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + if (spell->Id == SPELL_KODO_KOMBO_ITEM) { - if (who->GetEntry() == NPC_SMEED && me->IsWithinDistInMap(who, 10.0f) && !me->HasAura(SPELL_KODO_KOMBO_GOSSIP)) - { - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveIdle(); + me->UpdateEntry(NPC_TAMED_KODO, nullptr, false); + EnterEvadeMode(); + me->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, me->GetFollowAngle()); - DoCast(me, SPELL_KODO_KOMBO_GOSSIP, true); - if (Creature* smeed = who->ToCreature()) - smeed->AI()->Talk(SAY_SMEED_HOME); - } + caster->CastSpell(caster, SPELL_KODO_KOMBO_PLAYER_BUFF); + DoCastSelf(SPELL_KODO_KOMBO_DESPAWN_BUFF, true); } - - void SpellHit(Unit* caster, SpellInfo const* spell) override + else if (spell->Id == SPELL_KODO_KOMBO_GOSSIP) { - if (spell->Id == SPELL_KODO_KOMBO_ITEM) + me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); + me->DespawnOrUnsummon(60s); + } + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) + { + if (Group* group = player->GetGroup()) { - if (!(caster->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) || me->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) - && (me->GetEntry() == NPC_AGED_KODO || me->GetEntry() == NPC_DYING_KODO || me->GetEntry() == NPC_ANCIENT_KODO)) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { - me->UpdateEntry(NPC_TAMED_KODO, nullptr, false); - EnterEvadeMode(); - me->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, me->GetFollowAngle()); - - caster->CastSpell(caster, SPELL_KODO_KOMBO_PLAYER_BUFF, true); - DoCast(me, SPELL_KODO_KOMBO_DESPAWN_BUFF, true); + Player* grpPlayer = itr->GetSource(); + if (grpPlayer->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF)) + grpPlayer->TalkedToCreature(creature->GetEntry(), ObjectGuid::Empty); } } - else if (spell->Id == SPELL_KODO_KOMBO_GOSSIP) - { - me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); - me->DespawnOrUnsummon(60s); - } - } - }; + else + if (player->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF)) + player->TalkedToCreature(creature->GetEntry(), ObjectGuid::Empty); - bool OnGossipHello(Player* player, Creature* creature) override - { - if (player->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) && creature->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) - { - player->TalkedToCreature(creature->GetEntry(), ObjectGuid::Empty); player->RemoveAurasDueToSpell(SPELL_KODO_KOMBO_PLAYER_BUFF); } SendGossipMenuFor(player, NPC_TEXT_KODO, creature->GetGUID()); return true; } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_aged_dying_ancient_kodoAI(creature); - } }; void AddSC_desolace() { new npc_cork_gizelton(); - new npc_aged_dying_ancient_kodo(); + RegisterCreatureAI(npc_aged_dying_ancient_kodo); } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 4e1b56333..230f9f975 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -32,6 +32,55 @@ * Scriptnames of files in this file should be prefixed with "spell_q#questID_". */ +// Aged Dying Ancient Kodo +std::vector kodoEntry{ 4700, 4701, 4702 }; +class spell_q5561_kodo_roundup_kodo_kombobulator : public SpellScript +{ + PrepareSpellScript(spell_q5561_kodo_roundup_kodo_kombobulator); + + SpellCastResult CheckCast() + { + if (Unit* caster = GetCaster()) + if (Player* player = caster->ToPlayer()) + if (player->HasAura(18172)) // Kodo Kombobulator + return SPELL_FAILED_NOT_READY; + + bool ok = false; + if (Unit* target = GetExplTargetUnit()) + if (Creature* creature = target->ToCreature()) + for (uint32 cid : kodoEntry) + if (creature->GetEntry() == cid) + ok = true; + + if (!ok) + return SPELL_FAILED_BAD_TARGETS; + + return SPELL_CAST_OK; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_q5561_kodo_roundup_kodo_kombobulator::CheckCast); + } +}; + +class spell_q5561_kodo_roundup_kodo_kombobulator_despawn : public SpellScript +{ + PrepareSpellScript(spell_q5561_kodo_roundup_kodo_kombobulator_despawn); + + void HandleDummyEffect(SpellEffIndex /*effIndex*/) + { + if (Unit* caster = GetCaster()) + if (Creature* creature = caster->ToCreature()) + creature->DespawnOrUnsummon(); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_q5561_kodo_roundup_kodo_kombobulator_despawn::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + class spell_q11065_wrangle_some_aether_rays : public SpellScript { PrepareSpellScript(spell_q11065_wrangle_some_aether_rays); @@ -2472,6 +2521,8 @@ class spell_q9847_a_spirit_ally : public SpellScript void AddSC_quest_spell_scripts() { + RegisterSpellScript(spell_q5561_kodo_roundup_kodo_kombobulator); + RegisterSpellScript(spell_q5561_kodo_roundup_kodo_kombobulator_despawn); RegisterSpellAndAuraScriptPair(spell_q11065_wrangle_some_aether_rays, spell_q11065_wrangle_some_aether_rays_aura); RegisterSpellScript(spell_image_of_drakuru_reagent_check); RegisterSpellScript(spell_q12014_steady_as_a_rock); From 3ffbbe981f9a94377b6e13761da45fdd405448d9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 8 Feb 2026 14:49:27 +0000 Subject: [PATCH 070/335] chore(DB): import pending files Referenced commit(s): 7571ada7671c809f4e029d7135585c8f7fe4951f --- .../rev_1766978833232988900.sql => db_world/2026_02_08_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1766978833232988900.sql => db_world/2026_02_08_02.sql} (90%) diff --git a/data/sql/updates/pending_db_world/rev_1766978833232988900.sql b/data/sql/updates/db_world/2026_02_08_02.sql similarity index 90% rename from data/sql/updates/pending_db_world/rev_1766978833232988900.sql rename to data/sql/updates/db_world/2026_02_08_02.sql index ebabbeb62..8b9cfcb89 100644 --- a/data/sql/updates/pending_db_world/rev_1766978833232988900.sql +++ b/data/sql/updates/db_world/2026_02_08_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_08_01 -> 2026_02_08_02 -- DELETE FROM `spell_script_names` WHERE `spell_id`=18153 AND `ScriptName`='spell_q5561_kodo_roundup_kodo_kombobulator'; DELETE FROM `spell_script_names` WHERE `spell_id`=18269 AND `ScriptName`='spell_q5561_kodo_roundup_kodo_kombobulator_despawn'; From d71c749586cafa2bd9f73f85e531fc161fa69a65 Mon Sep 17 00:00:00 2001 From: Apatia <107246426+Apathyxia@users.noreply.github.com> Date: Mon, 9 Feb 2026 15:43:43 +0100 Subject: [PATCH 071/335] fix(DB/Creature): Adds and adjusts money loot for various NPCs (#24643) --- .../updates/pending_db_world/moneyloot.sql | 429 ++++++++++++++++++ 1 file changed, 429 insertions(+) create mode 100644 data/sql/updates/pending_db_world/moneyloot.sql diff --git a/data/sql/updates/pending_db_world/moneyloot.sql b/data/sql/updates/pending_db_world/moneyloot.sql new file mode 100644 index 000000000..71c1ea9dd --- /dev/null +++ b/data/sql/updates/pending_db_world/moneyloot.sql @@ -0,0 +1,429 @@ +-- +-- Updates more accurate moneyloot values to various NCPs +UPDATE `creature_template` SET `mingold` = 463, `maxgold` = 1391 WHERE `entry` = 16519; -- Shadowy Executioner +UPDATE `creature_template` SET `mingold` = 495, `maxgold` = 1485 WHERE `entry` = 16805; -- Broken Skeleton +UPDATE `creature_template` SET `mingold` = 377, `maxgold` = 1133 WHERE `entry` = 16846; -- Mag'har Grunt +UPDATE `creature_template` SET `mingold` = 302, `maxgold` = 906 WHERE `entry` = 16847; -- Debilitated Mag'har Grunt +UPDATE `creature_template` SET `mingold` = 379, `maxgold` = 1137 WHERE `entry` = 16867; -- Shattered Hand Grunt +UPDATE `creature_template` SET `mingold` = 439, `maxgold` = 1319 WHERE `entry` = 16870; -- Shattered Hand Captain +UPDATE `creature_template` SET `mingold` = 439, `maxgold` = 1317 WHERE `entry` = 16911; -- Mag'har Watcher +UPDATE `creature_template` SET `mingold` = 433, `maxgold` = 1301 WHERE `entry` = 16912; -- Mag'har Hunter +UPDATE `creature_template` SET `mingold` = 377, `maxgold` = 1133 WHERE `entry` = 16927; -- Stonescythe Whelp +UPDATE `creature_template` SET `mingold` = 404, `maxgold` = 1214 WHERE `entry` = 16928; -- Stonescythe Ambusher +UPDATE `creature_template` SET `mingold` = 406, `maxgold` = 1218 WHERE `entry` = 16929; -- Stonescythe Alpha +UPDATE `creature_template` SET `mingold` = 163, `maxgold` = 491 WHERE `entry` = 16938; -- Dreghood Brute +UPDATE `creature_template` SET `mingold` = 433, `maxgold` = 1301 WHERE `entry` = 16966; -- Haal'eshi Windwalker +UPDATE `creature_template` SET `mingold` = 434, `maxgold` = 1304 WHERE `entry` = 16967; -- Haal'eshi Talonguard +UPDATE `creature_template` SET `mingold` = 436, `maxgold` = 1310 WHERE `entry` = 17084; -- Avruu +UPDATE `creature_template` SET `mingold` = 461, `maxgold` = 1385 WHERE `entry` = 17088; -- Shadowy Summoner +UPDATE `creature_template` SET `mingold` = 432, `maxgold` = 1298 WHERE `entry` = 17142; -- Wrekt Warrior +UPDATE `creature_template` SET `mingold` = 437, `maxgold` = 1313 WHERE `entry` = 17143; -- Wrekt Seer +UPDATE `creature_template` SET `mingold` = 377, `maxgold` = 1133 WHERE `entry` = 18077; -- Umbrafen Oracle +UPDATE `creature_template` SET `mingold` = 378, `maxgold` = 1136 WHERE `entry` = 18079; -- Umbrafen Seer +UPDATE `creature_template` SET `mingold` = 401, `maxgold` = 1205 WHERE `entry` = 18080; -- Kataru +UPDATE `creature_template` SET `mingold` = 434, `maxgold` = 1304 WHERE `entry` = 18086; -- Darkcrest Taskmaster +UPDATE `creature_template` SET `mingold` = 433, `maxgold` = 1301 WHERE `entry` = 18087; -- Darkcrest Siren +UPDATE `creature_template` SET `mingold` = 466, `maxgold` = 1398 WHERE `entry` = 18088; -- Bloodscale Enchantress +UPDATE `creature_template` SET `mingold` = 464, `maxgold` = 1394 WHERE `entry` = 18089; -- Bloodscale Slavedriver +UPDATE `creature_template` SET `mingold` = 406, `maxgold` = 1218 WHERE `entry` = 18113; -- Feralfen Hunter +UPDATE `creature_template` SET `mingold` = 405, `maxgold` = 1217 WHERE `entry` = 18114; -- Feralfen Mystic +UPDATE `creature_template` SET `mingold` = 435, `maxgold` = 1305 WHERE `entry` = 18115; -- Daggerfen Muckdweller +UPDATE `creature_template` SET `mingold` = 438, `maxgold` = 1314 WHERE `entry` = 18116; -- Daggerfen Assassin +UPDATE `creature_template` SET `mingold` = 434, `maxgold` = 1304 WHERE `entry` = 18117; -- Ango'rosh Ogre +UPDATE `creature_template` SET `mingold` = 435, `maxgold` = 1305 WHERE `entry` = 18118; -- Ango'rosh Shaman +UPDATE `creature_template` SET `mingold` = 431, `maxgold` = 1295 WHERE `entry` = 18119; -- Ango'rosh Brute +UPDATE `creature_template` SET `mingold` = 466, `maxgold` = 1398 WHERE `entry` = 18120; -- Ango'rosh Mauler +UPDATE `creature_template` SET `mingold` = 464, `maxgold` = 1392 WHERE `entry` = 18121; -- Ango'rosh Souleater +UPDATE `creature_template` SET `mingold` = 285, `maxgold` = 855 WHERE `entry` = 18123; -- Wrekt Slave +UPDATE `creature_template` SET `mingold` = 438, `maxgold` = 1314 WHERE `entry` = 18159; -- Boss Grog'ak +UPDATE `creature_template` SET `mingold` = 462, `maxgold` = 1388 WHERE `entry` = 18160; -- Overlord Gorefist +UPDATE `creature_template` SET `mingold` = 523, `maxgold` = 1571 WHERE `entry` = 18238; -- Murkblood Invader +UPDATE `creature_template` SET `mingold` = 494, `maxgold` = 1484 WHERE `entry` = 18260; -- Boulderfist Invader +UPDATE `creature_template` SET `mingold` = 561, `maxgold` = 1685 WHERE `entry` = 18298; -- Gava'xi +UPDATE `creature_template` SET `mingold` = 434, `maxgold` = 1304 WHERE `entry` = 18340; -- Steam Pump Overseer +UPDATE `creature_template` SET `mingold` = 607, `maxgold` = 1823 WHERE `entry` = 18351; -- Lump +UPDATE `creature_template` SET `mingold` = 525, `maxgold` = 1575 WHERE `entry` = 18352; -- Boulderfist Hunter +UPDATE `creature_template` SET `mingold` = 516, `maxgold` = 1548 WHERE `entry` = 18413; -- Zorbo the Advisor +UPDATE `creature_template` SET `mingold` = 434, `maxgold` = 1302 WHERE `entry` = 18449; -- Shienor Talonite +UPDATE `creature_template` SET `mingold` = 434, `maxgold` = 1304 WHERE `entry` = 18450; -- Shienor Sorcerer +UPDATE `creature_template` SET `mingold` = 436, `maxgold` = 1308 WHERE `entry` = 18451; -- Shienor Wing Guard +UPDATE `creature_template` SET `mingold` = 464, `maxgold` = 1392 WHERE `entry` = 18452; -- Skithian Dreadhawk +UPDATE `creature_template` SET `mingold` = 463, `maxgold` = 1389 WHERE `entry` = 18453; -- Skithian Windripper +UPDATE `creature_template` SET `mingold` = 494, `maxgold` = 1484 WHERE `entry` = 18454; -- Shalassi Talonguard +UPDATE `creature_template` SET `mingold` = 495, `maxgold` = 1485 WHERE `entry` = 18455; -- Shalassi Oracle +UPDATE `creature_template` SET `mingold` = 440, `maxgold` = 1320 WHERE `entry` = 18456; -- Tuurem Scavenger +UPDATE `creature_template` SET `mingold` = 437, `maxgold` = 1313 WHERE `entry` = 18457; -- Tuurem Hunter +UPDATE `creature_template` SET `mingold` = 496, `maxgold` = 1490 WHERE `entry` = 18460; -- Lost Spirit +UPDATE `creature_template` SET `mingold` = 438, `maxgold` = 1316 WHERE `entry` = 18539; -- Ashkaz +UPDATE `creature_template` SET `mingold` = 434, `maxgold` = 1304 WHERE `entry` = 18540; -- Ayit +UPDATE `creature_template` SET `mingold` = 436, `maxgold` = 1310 WHERE `entry` = 18541; -- Urdak +UPDATE `creature_template` SET `mingold` = 469, `maxgold` = 1409 WHERE `entry` = 18583; -- Lisaile Fireweaver +UPDATE `creature_template` SET `mingold` = 433, `maxgold` = 1301 WHERE `entry` = 18595; -- Warped Peon +UPDATE `creature_template` SET `mingold` = 530, `maxgold` = 1592 WHERE `entry` = 18684; -- Bro'Gaz the Clanless +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 18697; -- Chief Engineer Lorthander +UPDATE `creature_template` SET `mingold` = 503, `maxgold` = 1511 WHERE `entry` = 18718; -- Shadowy Hunter +UPDATE `creature_template` SET `mingold` = 490, `maxgold` = 1470 WHERE `entry` = 18720; -- Shadowmaster Grieve +UPDATE `creature_template` SET `mingold` = 590, `maxgold` = 1770 WHERE `entry` = 18850; -- Sunfury Guardsman +UPDATE `creature_template` SET `mingold` = 591, `maxgold` = 1775 WHERE `entry` = 18872; -- Disembodied Vindicator +UPDATE `creature_template` SET `mingold` = 595, `maxgold` = 1787 WHERE `entry` = 18873; -- Disembodied Protector +UPDATE `creature_template` SET `mingold` = 593, `maxgold` = 1781 WHERE `entry` = 18875; -- Zaxxis Raider +UPDATE `creature_template` SET `mingold` = 457, `maxgold` = 1373 WHERE `entry` = 18992; -- Captain Krosh +UPDATE `creature_template` SET `mingold` = 432, `maxgold` = 1296 WHERE `entry` = 19174; -- Chieftain Mummaki +UPDATE `creature_template` SET `mingold` = 374, `maxgold` = 1122 WHERE `entry` = 19263; -- Warboss Nekrogg +UPDATE `creature_template` SET `mingold` = 377, `maxgold` = 1131 WHERE `entry` = 19295; -- Shattered Hand Grenadier +UPDATE `creature_template` SET `mingold` = 431, `maxgold` = 1295 WHERE `entry` = 19410; -- Shattered Hand Neophyte +UPDATE `creature_template` SET `mingold` = 431, `maxgold` = 1293 WHERE `entry` = 19411; -- Shattered Hand Warlock +UPDATE `creature_template` SET `mingold` = 406, `maxgold` = 1218 WHERE `entry` = 19413; -- Shattered Hand Mage +UPDATE `creature_template` SET `mingold` = 403, `maxgold` = 1211 WHERE `entry` = 19414; -- Shattered Hand Guard +UPDATE `creature_template` SET `mingold` = 406, `maxgold` = 1220 WHERE `entry` = 19415; -- Shattered Hand Acolyte +UPDATE `creature_template` SET `mingold` = 375, `maxgold` = 1127 WHERE `entry` = 19442; -- Worg Master Kruush +UPDATE `creature_template` SET `mingold` = 592, `maxgold` = 1776 WHERE `entry` = 19593; -- Spellbinder Maryana +UPDATE `creature_template` SET `mingold` = 591, `maxgold` = 1773 WHERE `entry` = 19635; -- Captain Arathyn +UPDATE `creature_template` SET `mingold` = 593, `maxgold` = 1779 WHERE `entry` = 19642; -- Zaxxis Stalker +UPDATE `creature_template` SET `mingold` = 657, `maxgold` = 1971 WHERE `entry` = 19657; -- Summoner Kanthin +UPDATE `creature_template` SET `mingold` = 628, `maxgold` = 1886 WHERE `entry` = 19705; -- Master Daellis Dawnstrike +UPDATE `creature_template` SET `mingold` = 591, `maxgold` = 1775 WHERE `entry` = 19707; -- Sunfury Archer +UPDATE `creature_template` SET `mingold` = 441, `maxgold` = 1323 WHERE `entry` = 19732; -- Ango'rosh Warlock +UPDATE `creature_template` SET `mingold` = 164, `maxgold` = 492 WHERE `entry` = 19733; -- Daggerfen Servant +UPDATE `creature_template` SET `mingold` = 322, `maxgold` = 968 WHERE `entry` = 19762; -- Coilskar Defender +UPDATE `creature_template` SET `mingold` = 321, `maxgold` = 963 WHERE `entry` = 19765; -- Coilskar Myrmidon +UPDATE `creature_template` SET `mingold` = 318, `maxgold` = 956 WHERE `entry` = 19767; -- Coilskar Sorceress +UPDATE `creature_template` SET `mingold` = 318, `maxgold` = 954 WHERE `entry` = 19768; -- Coilskar Siren +UPDATE `creature_template` SET `mingold` = 318, `maxgold` = 954 WHERE `entry` = 19788; -- Coilskar Muckwatcher +UPDATE `creature_template` SET `mingold` = 316, `maxgold` = 950 WHERE `entry` = 19789; -- Coilskar Waterkeeper +UPDATE `creature_template` SET `mingold` = 628, `maxgold` = 1886 WHERE `entry` = 19792; -- Eclipsion Centurion +UPDATE `creature_template` SET `mingold` = 628, `maxgold` = 1884 WHERE `entry` = 19795; -- Eclipsion Blood Knight +UPDATE `creature_template` SET `mingold` = 626, `maxgold` = 1880 WHERE `entry` = 19796; -- Eclipsion Archmage +UPDATE `creature_template` SET `mingold` = 658, `maxgold` = 1974 WHERE `entry` = 19806; -- Eclipsion Bloodwarder +UPDATE `creature_template` SET `mingold` = 566, `maxgold` = 1700 WHERE `entry` = 19825; -- Dark Conclave Talonite +UPDATE `creature_template` SET `mingold` = 590, `maxgold` = 1770 WHERE `entry` = 19826; -- Dark Conclave Shadowmancer +UPDATE `creature_template` SET `mingold` = 589, `maxgold` = 1767 WHERE `entry` = 19827; -- Dark Conclave Ravenguard +UPDATE `creature_template` SET `mingold` = 568, `maxgold` = 1704 WHERE `entry` = 19830; -- Arcanist Ardonis +UPDATE `creature_template` SET `mingold` = 591, `maxgold` = 1773 WHERE `entry` = 19831; -- Commander Dawnforge +UPDATE `creature_template` SET `mingold` = 589, `maxgold` = 1767 WHERE `entry` = 19926; -- Spellreaver Marathelle +UPDATE `creature_template` SET `mingold` = 531, `maxgold` = 1595 WHERE `entry` = 19943; -- Lashh'an Talonite +UPDATE `creature_template` SET `mingold` = 524, `maxgold` = 1572 WHERE `entry` = 19944; -- Lashh'an Wing Guard +UPDATE `creature_template` SET `mingold` = 528, `maxgold` = 1586 WHERE `entry` = 19945; -- Lashh'an Windwalker +UPDATE `creature_template` SET `mingold` = 528, `maxgold` = 1584 WHERE `entry` = 19948; -- Bloodmaul Skirmisher +UPDATE `creature_template` SET `mingold` = 527, `maxgold` = 1581 WHERE `entry` = 19952; -- Bloodmaul Geomancer +UPDATE `creature_template` SET `mingold` = 528, `maxgold` = 1584 WHERE `entry` = 19957; -- Bloodmaul Brewmaster +UPDATE `creature_template` SET `mingold` = 520, `maxgold` = 1562 WHERE `entry` = 19982; -- Vekh'nir Keeneye +UPDATE `creature_template` SET `mingold` = 526, `maxgold` = 1580 WHERE `entry` = 19983; -- Vekh'nir Stormcaller +UPDATE `creature_template` SET `mingold` = 525, `maxgold` = 1575 WHERE `entry` = 19984; -- Vekh'nir Dreadhawk +UPDATE `creature_template` SET `mingold` = 562, `maxgold` = 1688 WHERE `entry` = 19985; -- Ruuan'ok Cloudgazer +UPDATE `creature_template` SET `mingold` = 561, `maxgold` = 1685 WHERE `entry` = 19986; -- Ruuan'ok Skyfury +UPDATE `creature_template` SET `mingold` = 560, `maxgold` = 1680 WHERE `entry` = 19987; -- Ruuan'ok Ravenguard +UPDATE `creature_template` SET `mingold` = 587, `maxgold` = 1761 WHERE `entry` = 19988; -- Grishna Falconwing +UPDATE `creature_template` SET `mingold` = 593, `maxgold` = 1781 WHERE `entry` = 19989; -- Grishna Harbinger +UPDATE `creature_template` SET `mingold` = 589, `maxgold` = 1769 WHERE `entry` = 19990; -- Grishna Scorncrow +UPDATE `creature_template` SET `mingold` = 522, `maxgold` = 1566 WHERE `entry` = 19991; -- Bloodmaul Brute +UPDATE `creature_template` SET `mingold` = 525, `maxgold` = 1577 WHERE `entry` = 19992; -- Bloodmaul Shaman +UPDATE `creature_template` SET `mingold` = 531, `maxgold` = 1593 WHERE `entry` = 19993; -- Bloodmaul Mauler +UPDATE `creature_template` SET `mingold` = 525, `maxgold` = 1577 WHERE `entry` = 19994; -- Bloodmaul Warlock +UPDATE `creature_template` SET `mingold` = 526, `maxgold` = 1578 WHERE `entry` = 19995; -- Bladespire Brute +UPDATE `creature_template` SET `mingold` = 525, `maxgold` = 1577 WHERE `entry` = 19998; -- Bladespire Shaman +UPDATE `creature_template` SET `mingold` = 464, `maxgold` = 1394 WHERE `entry` = 20088; -- Bloodscale Overseer +UPDATE `creature_template` SET `mingold` = 464, `maxgold` = 1394 WHERE `entry` = 20089; -- Bloodscale Wavecaller +UPDATE `creature_template` SET `mingold` = 533, `maxgold` = 1599 WHERE `entry` = 20113; -- Lashh'an Matriarch +UPDATE `creature_template` SET `mingold` = 378, `maxgold` = 1134 WHERE `entry` = 20115; -- Umbrafen Witchdoctor +UPDATE `creature_template` SET `mingold` = 590, `maxgold` = 1770 WHERE `entry` = 20134; -- Sunfury Arcanist +UPDATE `creature_template` SET `mingold` = 592, `maxgold` = 1776 WHERE `entry` = 20135; -- Sunfury Arch Mage +UPDATE `creature_template` SET `mingold` = 593, `maxgold` = 1779 WHERE `entry` = 20136; -- Sunfury Researcher +UPDATE `creature_template` SET `mingold` = 625, `maxgold` = 1877 WHERE `entry` = 20139; -- Sunfury Conjurer +UPDATE `creature_template` SET `mingold` = 630, `maxgold` = 1892 WHERE `entry` = 20140; -- Sunfury Centurion +UPDATE `creature_template` SET `mingold` = 517, `maxgold` = 1553 WHERE `entry` = 20161; -- Vekh'nir Matriarch +UPDATE `creature_template` SET `mingold` = 626, `maxgold` = 1878 WHERE `entry` = 20207; -- Sunfury Bowman +UPDATE `creature_template` SET `mingold` = 591, `maxgold` = 1775 WHERE `entry` = 20210; -- Shaleskin Flayer +UPDATE `creature_template` SET `mingold` = 563, `maxgold` = 1689 WHERE `entry` = 20211; -- Ruuan'ok Matriarch +UPDATE `creature_template` SET `mingold` = 593, `maxgold` = 1781 WHERE `entry` = 20221; -- Sunfury Flamekeeper +UPDATE `creature_template` SET `mingold` = 665, `maxgold` = 1995 WHERE `entry` = 20248; -- Sunfury Nethermancer +UPDATE `creature_template` SET `mingold` = 405, `maxgold` = 1215 WHERE `entry` = 20270; -- Feralfen Druid +UPDATE `creature_template` SET `mingold` = 567, `maxgold` = 1703 WHERE `entry` = 20329; -- Grishna Matriarch +UPDATE `creature_template` SET `mingold` = 530, `maxgold` = 1590 WHERE `entry` = 20334; -- Bladespire Cook +UPDATE `creature_template` SET `mingold` = 589, `maxgold` = 1767 WHERE `entry` = 20397; -- Overseer Seylanna +UPDATE `creature_template` SET `mingold` = 626, `maxgold` = 1880 WHERE `entry` = 20409; -- Kirin'Var Apprentice +UPDATE `creature_template` SET `mingold` = 589, `maxgold` = 1769 WHERE `entry` = 20416; -- Overseer Theredis +UPDATE `creature_template` SET `mingold` = 575, `maxgold` = 1727 WHERE `entry` = 20435; -- Overseer Athanel +UPDATE `creature_template` SET `mingold` = 465, `maxgold` = 1397 WHERE `entry` = 20442; -- Captain Bo'kar +UPDATE `creature_template` SET `mingold` = 436, `maxgold` = 1308 WHERE `entry` = 20443; -- Ango'rosh Sentry +UPDATE `creature_template` SET `mingold` = 468, `maxgold` = 1404 WHERE `entry` = 20444; -- Ango'rosh Shadowmage +UPDATE `creature_template` SET `mingold` = 632, `maxgold` = 1896 WHERE `entry` = 20452; -- Ethereum Assassin +UPDATE `creature_template` SET `mingold` = 623, `maxgold` = 1871 WHERE `entry` = 20453; -- Ethereum Shocktrooper +UPDATE `creature_template` SET `mingold` = 658, `maxgold` = 1976 WHERE `entry` = 20456; -- Ethereum Researcher +UPDATE `creature_template` SET `mingold` = 669, `maxgold` = 2007 WHERE `entry` = 20458; -- Ethereum Archon +UPDATE `creature_template` SET `mingold` = 664, `maxgold` = 1992 WHERE `entry` = 20459; -- Ethereum Overlord +UPDATE `creature_template` SET `mingold` = 661, `maxgold` = 1983 WHERE `entry` = 20474; -- Ethereum Nexus-Stalker +UPDATE `creature_template` SET `mingold` = 587, `maxgold` = 1761 WHERE `entry` = 20601; -- Razaani Raider +UPDATE `creature_template` SET `mingold` = 597, `maxgold` = 1791 WHERE `entry` = 20609; -- Razaani Nexus Stalker +UPDATE `creature_template` SET `mingold` = 588, `maxgold` = 1766 WHERE `entry` = 20614; -- Razaani Spell-Thief +UPDATE `creature_template` SET `mingold` = 318, `maxgold` = 956 WHERE `entry` = 20684; -- Lady Shav'rar +UPDATE `creature_template` SET `mingold` = 535, `maxgold` = 1605 WHERE `entry` = 20726; -- Mugdorg +UPDATE `creature_template` SET `mingold` = 658, `maxgold` = 1974 WHERE `entry` = 20727; -- Captain Zovax +UPDATE `creature_template` SET `mingold` = 547, `maxgold` = 1641 WHERE `entry` = 20731; -- Droggam +UPDATE `creature_template` SET `mingold` = 574, `maxgold` = 1722 WHERE `entry` = 20732; -- Gorr'Dim +UPDATE `creature_template` SET `mingold` = 532, `maxgold` = 1598 WHERE `entry` = 20753; -- Dorgok +UPDATE `creature_template` SET `mingold` = 556, `maxgold` = 1670 WHERE `entry` = 20765; -- Bladespire Crusher +UPDATE `creature_template` SET `mingold` = 553, `maxgold` = 1661 WHERE `entry` = 20766; -- Bladespire Mystic +UPDATE `creature_template` SET `mingold` = 661, `maxgold` = 1983 WHERE `entry` = 20770; -- Warden Icoshock +UPDATE `creature_template` SET `mingold` = 622, `maxgold` = 1868 WHERE `entry` = 20872; -- Deathforge Summoner +UPDATE `creature_template` SET `mingold` = 629, `maxgold` = 1887 WHERE `entry` = 20878; -- Deathforge Guardian +UPDATE `creature_template` SET `mingold` = 595, `maxgold` = 1787 WHERE `entry` = 21046; -- Boulder'mok Brute +UPDATE `creature_template` SET `mingold` = 588, `maxgold` = 1764 WHERE `entry` = 21047; -- Boulder'mok Shaman +UPDATE `creature_template` SET `mingold` = 579, `maxgold` = 1739 WHERE `entry` = 21048; -- Boulder'mok Chieftain +UPDATE `creature_template` SET `mingold` = 596, `maxgold` = 1788 WHERE `entry` = 21058; -- Disembodied Exarch +UPDATE `creature_template` SET `mingold` = 661, `maxgold` = 1983 WHERE `entry` = 21089; -- Sunfury Blood Knight +UPDATE `creature_template` SET `mingold` = 663, `maxgold` = 1989 WHERE `entry` = 21179; -- Demon Hunter Supplicant +UPDATE `creature_template` SET `mingold` = 660, `maxgold` = 1980 WHERE `entry` = 21180; -- Demon Hunter Initiate +UPDATE `creature_template` SET `mingold` = 557, `maxgold` = 1673 WHERE `entry` = 21189; -- Crystal Flayer +UPDATE `creature_template` SET `mingold` = 663, `maxgold` = 1989 WHERE `entry` = 21196; -- Ravenous Flayer +UPDATE `creature_template` SET `mingold` = 465, `maxgold` = 1395 WHERE `entry` = 21198; -- Deathtalon Spirit +UPDATE `creature_template` SET `mingold` = 466, `maxgold` = 1398 WHERE `entry` = 21200; -- Screeching Spirit +UPDATE `creature_template` SET `mingold` = 527, `maxgold` = 1583 WHERE `entry` = 21238; -- Bloodmaul Drudger +UPDATE `creature_template` SET `mingold` = 522, `maxgold` = 1566 WHERE `entry` = 21284; -- Auchenai Initiate +UPDATE `creature_template` SET `mingold` = 527, `maxgold` = 1583 WHERE `entry` = 21296; -- Bladespire Champion +UPDATE `creature_template` SET `mingold` = 447, `maxgold` = 1341 WHERE `entry` = 21300; -- Fel Corrupter +UPDATE `creature_template` SET `mingold` = 560, `maxgold` = 1682 WHERE `entry` = 21302; -- Shadow Council Warlock +UPDATE `creature_template` SET `mingold` = 497, `maxgold` = 1493 WHERE `entry` = 21368; -- Ethereal Plunderer +UPDATE `creature_template` SET `mingold` = 493, `maxgold` = 1481 WHERE `entry` = 21370; -- Ethereal Nethermancer +UPDATE `creature_template` SET `mingold` = 590, `maxgold` = 1772 WHERE `entry` = 21382; -- Wyrmcult Zealot +UPDATE `creature_template` SET `mingold` = 591, `maxgold` = 1775 WHERE `entry` = 21383; -- Wyrmcult Acolyte +UPDATE `creature_template` SET `mingold` = 594, `maxgold` = 1782 WHERE `entry` = 21384; -- Dark Conclave Harbinger +UPDATE `creature_template` SET `mingold` = 594, `maxgold` = 1782 WHERE `entry` = 21385; -- Dark Conclave Scorncrow +UPDATE `creature_template` SET `mingold` = 558, `maxgold` = 1674 WHERE `entry` = 21386; -- Dark Conclave Hawkeye +UPDATE `creature_template` SET `mingold` = 584, `maxgold` = 1752 WHERE `entry` = 21387; -- Wyrmcult Blackwhelp +UPDATE `creature_template` SET `mingold` = 495, `maxgold` = 1485 WHERE `entry` = 21405; -- Ethereal Arcanist +UPDATE `creature_template` SET `mingold` = 623, `maxgold` = 1871 WHERE `entry` = 21477; -- Rocknail Flayer +UPDATE `creature_template` SET `mingold` = 622, `maxgold` = 1868 WHERE `entry` = 21478; -- Rocknail Ripper +UPDATE `creature_template` SET `mingold` = 591, `maxgold` = 1775 WHERE `entry` = 21492; -- Wyrmcult Blessed +UPDATE `creature_template` SET `mingold` = 660, `maxgold` = 1980 WHERE `entry` = 21503; -- Sunfury Warlock +UPDATE `creature_template` SET `mingold` = 668, `maxgold` = 2004 WHERE `entry` = 21505; -- Sunfury Summoner +UPDATE `creature_template` SET `mingold` = 491, `maxgold` = 1473 WHERE `entry` = 21636; -- Vengeful Draenei +UPDATE `creature_template` SET `mingold` = 589, `maxgold` = 1769 WHERE `entry` = 21637; -- Wyrmcult Scout +UPDATE `creature_template` SET `mingold` = 491, `maxgold` = 1475 WHERE `entry` = 21640; -- Trogma +UPDATE `creature_template` SET `mingold` = 692, `maxgold` = 2076 WHERE `entry` = 21649; -- Skettis Windwalker +UPDATE `creature_template` SET `mingold` = 668, `maxgold` = 2004 WHERE `entry` = 21650; -- Skettis Talonite +UPDATE `creature_template` SET `mingold` = 463, `maxgold` = 1389 WHERE `entry` = 21660; -- Cabal Abjurist +UPDATE `creature_template` SET `mingold` = 434, `maxgold` = 1304 WHERE `entry` = 21661; -- Cabal Skirmisher +UPDATE `creature_template` SET `mingold` = 463, `maxgold` = 1389 WHERE `entry` = 21662; -- Cabal Tomb-Raider +UPDATE `creature_template` SET `mingold` = 522, `maxgold` = 1566 WHERE `entry` = 21663; -- Oronu the Elder +UPDATE `creature_template` SET `mingold` = 625, `maxgold` = 1877 WHERE `entry` = 21717; -- Dragonmaw Wrangler +UPDATE `creature_template` SET `mingold` = 632, `maxgold` = 1896 WHERE `entry` = 21718; -- Dragonmaw Subjugator +UPDATE `creature_template` SET `mingold` = 615, `maxgold` = 1845 WHERE `entry` = 21719; -- Dragonmaw Drake-Rider +UPDATE `creature_template` SET `mingold` = 633, `maxgold` = 1899 WHERE `entry` = 21720; -- Dragonmaw Shaman +UPDATE `creature_template` SET `mingold` = 594, `maxgold` = 1782 WHERE `entry` = 21742; -- Sunfury Eradicator +UPDATE `creature_template` SET `mingold` = 583, `maxgold` = 1751 WHERE `entry` = 21743; -- Sunfury Blood Lord +UPDATE `creature_template` SET `mingold` = 589, `maxgold` = 1769 WHERE `entry` = 21784; -- Ghostrider of Karabor +UPDATE `creature_template` SET `mingold` = 627, `maxgold` = 1881 WHERE `entry` = 21788; -- Shadowmoon Zealot +UPDATE `creature_template` SET `mingold` = 629, `maxgold` = 1889 WHERE `entry` = 21795; -- Shadowmoon Harbinger +UPDATE `creature_template` SET `mingold` = 560, `maxgold` = 1682 WHERE `entry` = 21809; -- Wyrmcult Poacher +UPDATE `creature_template` SET `mingold` = 558, `maxgold` = 1674 WHERE `entry` = 21810; -- Wyrmcult Hewer +UPDATE `creature_template` SET `mingold` = 662, `maxgold` = 1988 WHERE `entry` = 21815; -- Cleric of Karabor +UPDATE `creature_template` SET `mingold` = 435, `maxgold` = 1305 WHERE `entry` = 21902; -- Cabal Spell-weaver +UPDATE `creature_template` SET `mingold` = 434, `maxgold` = 1304 WHERE `entry` = 21907; -- Cabal Initiate +UPDATE `creature_template` SET `mingold` = 697, `maxgold` = 2091 WHERE `entry` = 21911; -- Skettis Soulcaller +UPDATE `creature_template` SET `mingold` = 662, `maxgold` = 1986 WHERE `entry` = 22016; -- Eclipsion Soldier +UPDATE `creature_template` SET `mingold` = 659, `maxgold` = 1977 WHERE `entry` = 22017; -- Eclipsion Spellbinder +UPDATE `creature_template` SET `mingold` = 660, `maxgold` = 1980 WHERE `entry` = 22018; -- Eclipsion Cavalier +UPDATE `creature_template` SET `mingold` = 521, `maxgold` = 1565 WHERE `entry` = 22045; -- Vengeful Husk +UPDATE `creature_template` SET `mingold` = 576, `maxgold` = 1730 WHERE `entry` = 22099; -- Wyrmcult Provisioner +UPDATE `creature_template` SET `mingold` = 518, `maxgold` = 1556 WHERE `entry` = 22160; -- Bloodmaul Taskmaster +UPDATE `creature_template` SET `mingold` = 156, `maxgold` = 468 WHERE `entry` = 22252; -- Dragonmaw Peon +UPDATE `creature_template` SET `mingold` = 738, `maxgold` = 2214 WHERE `entry` = 22254; -- Wrath Corruptor +UPDATE `creature_template` SET `mingold` = 558, `maxgold` = 1674 WHERE `entry` = 22308; -- Wyrmcult Hunter +UPDATE `creature_template` SET `mingold` = 700, `maxgold` = 2102 WHERE `entry` = 22341; -- Deathshadow Acolyte +UPDATE `creature_template` SET `mingold` = 697, `maxgold` = 2091 WHERE `entry` = 22342; -- Deathshadow Spellbinder +UPDATE `creature_template` SET `mingold` = 696, `maxgold` = 2090 WHERE `entry` = 22363; -- Deathshadow Warlock +UPDATE `creature_template` SET `mingold` = 497, `maxgold` = 1493 WHERE `entry` = 22378; -- Cabal Interrogator +UPDATE `creature_template` SET `mingold` = 533, `maxgold` = 1599 WHERE `entry` = 22384; -- Bloodmaul Soothsayer +UPDATE `creature_template` SET `mingold` = 494, `maxgold` = 1482 WHERE `entry` = 22387; -- Lithic Oracle +UPDATE `creature_template` SET `mingold` = 460, `maxgold` = 1380 WHERE `entry` = 22388; -- Lithic Talonguard +UPDATE `creature_template` SET `mingold` = 694, `maxgold` = 2084 WHERE `entry` = 23066; -- Talonpriest Ishaal +UPDATE `creature_template` SET `mingold` = 681, `maxgold` = 2045 WHERE `entry` = 23068; -- Talonpriest Zellek +UPDATE `creature_template` SET `mingold` = 626, `maxgold` = 1880 WHERE `entry` = 23188; -- Dragonmaw Transporter +UPDATE `creature_template` SET `mingold` = 950, `maxgold` = 2850 WHERE `entry` = 23643; -- Unstable Mur'ghoul +UPDATE `creature_template` SET `mingold` = 1200, `maxgold` = 3600 WHERE `entry` = 23644; -- Mur'ghoul Flesheater +UPDATE `creature_template` SET `mingold` = 1000, `maxgold` = 3000 WHERE `entry` = 23645; -- Mur'ghoul Corrupter +UPDATE `creature_template` SET `mingold` = 450, `maxgold` = 1350 WHERE `entry` = 23934; -- North Fleet Salvager +UPDATE `creature_template` SET `mingold` = 950, `maxgold` = 2850 WHERE `entry` = 23983; -- North Fleet Marine +UPDATE `creature_template` SET `mingold` = 470, `maxgold` = 1410 WHERE `entry` = 24013; -- Deathless Watcher +UPDATE `creature_template` SET `mingold` = 405, `maxgold` = 1215 WHERE `entry` = 24073; -- Fearsome Horror +UPDATE `creature_template` SET `mingold` = 495, `maxgold` = 1485 WHERE `entry` = 24116; -- Winterskorn Scout +UPDATE `creature_template` SET `mingold` = 1050, `maxgold` = 3150 WHERE `entry` = 24169; -- Dragonflayer Lieutenant +UPDATE `creature_template` SET `mingold` = 1100, `maxgold` = 3300 WHERE `entry` = 24334; -- Binder Murdis +UPDATE `creature_template` SET `mingold` = 1300, `maxgold` = 3900 WHERE `entry` = 24485; -- Servitor Shade +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 24546; -- Rotgill +UPDATE `creature_template` SET `mingold` = 320, `maxgold` = 960 WHERE `entry` = 24562; -- Nerub'ar Invader +UPDATE `creature_template` SET `mingold` = 1000, `maxgold` = 3000 WHERE `entry` = 24789; -- Forlorn Soul +UPDATE `creature_template` SET `mingold` = 340, `maxgold` = 1020 WHERE `entry` = 24871; -- Risen Vrykul Ancestor +UPDATE `creature_template` SET `mingold` = 663, `maxgold` = 1991 WHERE `entry` = 24918; -- Felblood Initiate +UPDATE `creature_template` SET `mingold` = 500, `maxgold` = 1500 WHERE `entry` = 25216; -- Winterfin Oracle +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 25224; -- Vengeful Kvaldir Spirit +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 25350; -- Risen Longrunner +UPDATE `creature_template` SET `mingold` = 355, `maxgold` = 1065 WHERE `entry` = 25383; -- En'kilah Abomination +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 25386; -- En'kilah Crypt Fiend +UPDATE `creature_template` SET `mingold` = 1050, `maxgold` = 3150 WHERE `entry` = 25392; -- High Priest Andorath +UPDATE `creature_template` SET `mingold` = 950, `maxgold` = 2850 WHERE `entry` = 25393; -- En'kilah Ghoul +UPDATE `creature_template` SET `mingold` = 1000, `maxgold` = 3000 WHERE `entry` = 25396; -- Naxxanar Skeletal Mage +UPDATE `creature_template` SET `mingold` = 550, `maxgold` = 1650 WHERE `entry` = 25427; -- Kaganishu +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 25448; -- Curator Insivius +UPDATE `creature_template` SET `mingold` = 950, `maxgold` = 2850 WHERE `entry` = 25520; -- Skadir Runecaster +UPDATE `creature_template` SET `mingold` = 1200, `maxgold` = 3600 WHERE `entry` = 25523; -- Skadir Mariner +UPDATE `creature_template` SET `mingold` = 950, `maxgold` = 2850 WHERE `entry` = 25619; -- Nerub'ar Warrior +UPDATE `creature_template` SET `mingold` = 700, `maxgold` = 2100 WHERE `entry` = 25650; -- Plagued Scavenger +UPDATE `creature_template` SET `mingold` = 1100, `maxgold` = 3300 WHERE `entry` = 25660; -- Festering Ghoul +UPDATE `creature_template` SET `mingold` = 800, `maxgold` = 2400 WHERE `entry` = 25684; -- Talramas Abomination +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 25717; -- Coldarra Scalesworn +UPDATE `creature_template` SET `mingold` = 1200, `maxgold` = 3600 WHERE `entry` = 25722; -- Coldarra Spellweaver +UPDATE `creature_template` SET `mingold` = 425, `maxgold` = 1275 WHERE `entry` = 25728; -- Coldarra Wyrmkin +UPDATE `creature_template` SET `mingold` = 700, `maxgold` = 2100 WHERE `entry` = 25843; -- Northsea Thug +UPDATE `creature_template` SET `mingold` = 1000, `maxgold` = 3000 WHERE `entry` = 25981; -- Scourged Footman +UPDATE `creature_template` SET `mingold` = 445, `maxgold` = 1335 WHERE `entry` = 26076; -- High Priest Naferset +UPDATE `creature_template` SET `mingold` = 355, `maxgold` = 1065 WHERE `entry` = 26202; -- Ziggurat Defender +UPDATE `creature_template` SET `mingold` = 1050, `maxgold` = 3150 WHERE `entry` = 26266; -- Heigarr the Horrible +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 26336; -- Indu'le Mystic +UPDATE `creature_template` SET `mingold` = 410, `maxgold` = 1230 WHERE `entry` = 26343; -- Indu'le Fisherman +UPDATE `creature_template` SET `mingold` = 1000, `maxgold` = 3000 WHERE `entry` = 26344; -- Indu'le Warrior +UPDATE `creature_template` SET `mingold` = 1150, `maxgold` = 3450 WHERE `entry` = 26349; -- Goramosh +UPDATE `creature_template` SET `mingold` = 750, `maxgold` = 2250 WHERE `entry` = 26451; -- Ragnar Drakkarlund +UPDATE `creature_template` SET `mingold` = 500, `maxgold` = 1500 WHERE `entry` = 26455; -- Moonrest Highborne +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 26457; -- Diseased Drakkari +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 26461; -- Scourge Corpserender +UPDATE `creature_template` SET `mingold` = 1350, `maxgold` = 4050 WHERE `entry` = 26492; -- Wastes Digger +UPDATE `creature_template` SET `mingold` = 1050, `maxgold` = 3150 WHERE `entry` = 26496; -- Wind Trader Mu'fah +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 26605; -- Anub'ar Underlord +UPDATE `creature_template` SET `mingold` = 475, `maxgold` = 1425 WHERE `entry` = 26606; -- Anub'ar Slayer +UPDATE `creature_template` SET `mingold` = 750, `maxgold` = 2250 WHERE `entry` = 26658; -- Reckless Scavenger +UPDATE `creature_template` SET `mingold` = 500, `maxgold` = 1500 WHERE `entry` = 26769; -- Anok'ra the Manipulator +UPDATE `creature_template` SET `mingold` = 700, `maxgold` = 2100 WHERE `entry` = 26770; -- Tivax the Breaker +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 26771; -- Sinok the Shadowrager +UPDATE `creature_template` SET `mingold` = 650, `maxgold` = 1950 WHERE `entry` = 26891; -- Undead Miner +UPDATE `creature_template` SET `mingold` = 1450, `maxgold` = 4350 WHERE `entry` = 26946; -- Reanimated Drakkari Tribesman +UPDATE `creature_template` SET `mingold` = 1050, `maxgold` = 3150 WHERE `entry` = 26948; -- Hulking Atrocity +UPDATE `creature_template` SET `mingold` = 1350, `maxgold` = 4050 WHERE `entry` = 27007; -- Iceshatter +UPDATE `creature_template` SET `mingold` = 950, `maxgold` = 2850 WHERE `entry` = 27122; -- Overseer Deathgaze +UPDATE `creature_template` SET `mingold` = 950, `maxgold` = 2850 WHERE `entry` = 27210; -- High General Abbendis +UPDATE `creature_template` SET `mingold` = 390, `maxgold` = 1170 WHERE `entry` = 27220; -- Forgotten Captain +UPDATE `creature_template` SET `mingold` = 950, `maxgold` = 2850 WHERE `entry` = 27224; -- Forgotten Knight +UPDATE `creature_template` SET `mingold` = 800, `maxgold` = 2400 WHERE `entry` = 27225; -- Forgotten Rifleman +UPDATE `creature_template` SET `mingold` = 1100, `maxgold` = 3300 WHERE `entry` = 27226; -- Forgotten Peasant +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 27229; -- Forgotten Footman +UPDATE `creature_template` SET `mingold` = 850, `maxgold` = 2550 WHERE `entry` = 27233; -- Onslaught Deckhand +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 27235; -- Lead Cannoneer Zierhut +UPDATE `creature_template` SET `mingold` = 1050, `maxgold` = 3150 WHERE `entry` = 27272; -- Risen Villager +UPDATE `creature_template` SET `mingold` = 500, `maxgold` = 1500 WHERE `entry` = 27283; -- Risen Wintergarde Mage +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 27284; -- Risen Wintergarde Defender +UPDATE `creature_template` SET `mingold` = 1150, `maxgold` = 3450 WHERE `entry` = 27286; -- Dreadbone Invader +UPDATE `creature_template` SET `mingold` = 850, `maxgold` = 2550 WHERE `entry` = 27287; -- Mindless Wight +UPDATE `creature_template` SET `mingold` = 435, `maxgold` = 1305 WHERE `entry` = 27360; -- Smoldering Skeleton +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 27362; -- Smoldering Construct +UPDATE `creature_template` SET `mingold` = 1200, `maxgold` = 3600 WHERE `entry` = 27363; -- Smoldering Geist +UPDATE `creature_template` SET `mingold` = 800, `maxgold` = 2400 WHERE `entry` = 27370; -- Vengeful Geist +UPDATE `creature_template` SET `mingold` = 1150, `maxgold` = 3450 WHERE `entry` = 27401; -- Risen Wintergarde Miner +UPDATE `creature_template` SET `mingold` = 650, `maxgold` = 1950 WHERE `entry` = 27410; -- Scourge Siegesmith +UPDATE `creature_template` SET `mingold` = 950, `maxgold` = 2850 WHERE `entry` = 27533; -- Frigid Geist +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 27551; -- Enraged Apparition +UPDATE `creature_template` SET `mingold` = 1000, `maxgold` = 3000 WHERE `entry` = 27552; -- Reanimated Noble +UPDATE `creature_template` SET `mingold` = 500, `maxgold` = 1500 WHERE `entry` = 27680; -- Dahlia Suntouch +UPDATE `creature_template` SET `mingold` = 650, `maxgold` = 1950 WHERE `entry` = 27797; -- Tattered Abomination +UPDATE `creature_template` SET `mingold` = 1300, `maxgold` = 3900 WHERE `entry` = 27799; -- Scourge Technician +UPDATE `creature_template` SET `mingold` = 750, `maxgold` = 2250 WHERE `entry` = 27800; -- Leprous Servant +UPDATE `creature_template` SET `mingold` = 420, `maxgold` = 1260 WHERE `entry` = 27823; -- Naxxramas Dreadguard +UPDATE `creature_template` SET `mingold` = 1000, `maxgold` = 3000 WHERE `entry` = 27824; -- Naxxramas Shade +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 27835; -- Dreadbone Construct +UPDATE `creature_template` SET `mingold` = 390, `maxgold` = 1170 WHERE `entry` = 27836; -- Wailing Soul +UPDATE `creature_template` SET `mingold` = 1150, `maxgold` = 3450 WHERE `entry` = 27941; -- Drakkari Plague Spreader +UPDATE `creature_template` SET `mingold` = 1200, `maxgold` = 3600 WHERE `entry` = 28026; -- Rampaging Geist +UPDATE `creature_template` SET `mingold` = 550, `maxgold` = 1650 WHERE `entry` = 28101; -- Blighted Corpse +UPDATE `creature_template` SET `mingold` = 1450, `maxgold` = 4350 WHERE `entry` = 28108; -- Bonescythe Ravager +UPDATE `creature_template` SET `mingold` = 1200, `maxgold` = 3600 WHERE `entry` = 28158; -- Withered Argent Footman +UPDATE `creature_template` SET `mingold` = 1200, `maxgold` = 3600 WHERE `entry` = 28255; -- Malas the Corrupter +UPDATE `creature_template` SET `mingold` = 500, `maxgold` = 1500 WHERE `entry` = 28257; -- Hath'ar Necromagus +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 28412; -- Hath'ar Broodmaster +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 28495; -- Gawanil +UPDATE `creature_template` SET `mingold` = 500, `maxgold` = 1500 WHERE `entry` = 28519; -- Withered Troll +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 28564; -- Putrid Abomination +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 28565; -- Decaying Ghoul +UPDATE `creature_template` SET `mingold` = 1350, `maxgold` = 4050 WHERE `entry` = 28603; -- Blightguard +UPDATE `creature_template` SET `mingold` = 435, `maxgold` = 1305 WHERE `entry` = 28641; -- Blighted Corpse +UPDATE `creature_template` SET `mingold` = 1550, `maxgold` = 4650 WHERE `entry` = 28747; -- Quetz'lun Worshipper +UPDATE `creature_template` SET `mingold` = 310, `maxgold` = 930 WHERE `entry` = 28748; -- Serpent-Touched Berserker +UPDATE `creature_template` SET `mingold` = 850, `maxgold` = 2550 WHERE `entry` = 28802; -- Servant of Drakuru +UPDATE `creature_template` SET `mingold` = 750, `maxgold` = 2250 WHERE `entry` = 28843; -- Bloated Abomination +UPDATE `creature_template` SET `mingold` = 310, `maxgold` = 930 WHERE `entry` = 29129; -- Lost Drakkari Spirit +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 29133; -- Disturbed Soul +UPDATE `creature_template` SET `mingold` = 465, `maxgold` = 1395 WHERE `entry` = 29449; -- Vargul Deathwaker +UPDATE `creature_template` SET `mingold` = 1500, `maxgold` = 4500 WHERE `entry` = 29450; -- Vargul Runelord +UPDATE `creature_template` SET `mingold` = 1550, `maxgold` = 4650 WHERE `entry` = 29451; -- Vargul Slayer +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 29518; -- Overseer Syra +UPDATE `creature_template` SET `mingold` = 1450, `maxgold` = 4350 WHERE `entry` = 29553; -- Garm Watcher +UPDATE `creature_template` SET `mingold` = 1350, `maxgold` = 4050 WHERE `entry` = 29554; -- Snowblind Devotee +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 29646; -- Banshee Soulclaimer +UPDATE `creature_template` SET `mingold` = 1150, `maxgold` = 3450 WHERE `entry` = 29652; -- Stormforged Tracker +UPDATE `creature_template` SET `mingold` = 1450, `maxgold` = 4350 WHERE `entry` = 29654; -- Drakuru Blood Drinker +UPDATE `creature_template` SET `mingold` = 750, `maxgold` = 2250 WHERE `entry` = 29656; -- Drakuru Berserker +UPDATE `creature_template` SET `mingold` = 550, `maxgold` = 1650 WHERE `entry` = 29695; -- Tracker Thulin +UPDATE `creature_template` SET `mingold` = 1500, `maxgold` = 4500 WHERE `entry` = 29697; -- Drakuru Prophet +UPDATE `creature_template` SET `mingold` = 1550, `maxgold` = 4650 WHERE `entry` = 29719; -- Morbid Carcass +UPDATE `creature_template` SET `mingold` = 1300, `maxgold` = 3900 WHERE `entry` = 29720; -- Vault Geist +UPDATE `creature_template` SET `mingold` = 750, `maxgold` = 2250 WHERE `entry` = 29722; -- Rabid Cannibal +UPDATE `creature_template` SET `mingold` = 650, `maxgold` = 1950 WHERE `entry` = 29738; -- Death Knight Master +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 29794; -- Sirana Iceshriek +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 29862; -- Stormforged Monitor +UPDATE `creature_template` SET `mingold` = 1750, `maxgold` = 5250 WHERE `entry` = 29875; -- Icemane Yeti +UPDATE `creature_template` SET `mingold` = 1500, `maxgold` = 4500 WHERE `entry` = 29915; -- Instructor Hroegar +UPDATE `creature_template` SET `mingold` = 700, `maxgold` = 2100 WHERE `entry` = 29974; -- Niffelem Forefather +UPDATE `creature_template` SET `mingold` = 1550, `maxgold` = 4650 WHERE `entry` = 30135; -- Restless Frostborn Warrior +UPDATE `creature_template` SET `mingold` = 1150, `maxgold` = 3450 WHERE `entry` = 30144; -- Restless Frostborn Ghost +UPDATE `creature_template` SET `mingold` = 495, `maxgold` = 1485 WHERE `entry` = 30202; -- Reanimated Crusader +UPDATE `creature_template` SET `mingold` = 1600, `maxgold` = 4800 WHERE `entry` = 30205; -- Forgotten Depths Acolyte +UPDATE `creature_template` SET `mingold` = 370, `maxgold` = 1110 WHERE `entry` = 30333; -- Forgotten Depths Slayer +UPDATE `creature_template` SET `mingold` = 550, `maxgold` = 1650 WHERE `entry` = 30409; -- Apprentice Osterkilgr +UPDATE `creature_template` SET `mingold` = 1350, `maxgold` = 4050 WHERE `entry` = 30541; -- Forgotten Depths Underking +UPDATE `creature_template` SET `mingold` = 1400, `maxgold` = 4200 WHERE `entry` = 30543; -- Forgotten Depths High Priest +UPDATE `creature_template` SET `mingold` = 550, `maxgold` = 1650 WHERE `entry` = 30597; -- Spiked Ghoul +UPDATE `creature_template` SET `mingold` = 950, `maxgold` = 2850 WHERE `entry` = 30687; -- Skeletal Constructor +UPDATE `creature_template` SET `mingold` = 800, `maxgold` = 2400 WHERE `entry` = 30689; -- Chained Abomination +UPDATE `creature_template` SET `mingold` = 1650, `maxgold` = 4950 WHERE `entry` = 30696; -- Corpulent Horror +UPDATE `creature_template` SET `mingold` = 1050, `maxgold` = 3150 WHERE `entry` = 30701; -- Vile Creeper +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 30746; -- Master Summoner Zarod +UPDATE `creature_template` SET `mingold` = 1550, `maxgold` = 4650 WHERE `entry` = 30831; -- High Priest Yath'amon +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 30863; -- Shandaral Druid Spirit +UPDATE `creature_template` SET `mingold` = 1750, `maxgold` = 5250 WHERE `entry` = 30864; -- Shandaral Hunter Spirit +UPDATE `creature_template` SET `mingold` = 375, `maxgold` = 1125 WHERE `entry` = 30865; -- Shandaral Warrior Spirit +UPDATE `creature_template` SET `mingold` = 800, `maxgold` = 2400 WHERE `entry` = 30894; -- Lithe Stalker +UPDATE `creature_template` SET `mingold` = 800, `maxgold` = 2400 WHERE `entry` = 30921; -- Skeletal Runesmith +UPDATE `creature_template` SET `mingold` = 450, `maxgold` = 1350 WHERE `entry` = 30922; -- Umbral Brute +UPDATE `creature_template` SET `mingold` = 1550, `maxgold` = 4650 WHERE `entry` = 30951; -- Restless Lookout +UPDATE `creature_template` SET `mingold` = 1750, `maxgold` = 5250 WHERE `entry` = 30960; -- Risen Soldier +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 31037; -- Forgotten Depths High Priest +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 31039; -- Forgotten Depths Underking +UPDATE `creature_template` SET `mingold` = 500, `maxgold` = 1500 WHERE `entry` = 31043; -- Reanimated Crusader +UPDATE `creature_template` SET `mingold` = 2100, `maxgold` = 6300 WHERE `entry` = 31139; -- Pustulent Horror +UPDATE `creature_template` SET `mingold` = 1050, `maxgold` = 3150 WHERE `entry` = 31140; -- Hulking Abomination +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 31152; -- Undying Minion +UPDATE `creature_template` SET `mingold` = 1400, `maxgold` = 4200 WHERE `entry` = 31155; -- Malefic Necromancer +UPDATE `creature_template` SET `mingold` = 850, `maxgold` = 2550 WHERE `entry` = 31226; -- Lumbering Atrocity +UPDATE `creature_template` SET `mingold` = 1050, `maxgold` = 3150 WHERE `entry` = 31231; -- Lost Shandaral Spirit +UPDATE `creature_template` SET `mingold` = 800, `maxgold` = 2400 WHERE `entry` = 31263; -- Carrion Hunter +UPDATE `creature_template` SET `mingold` = 800, `maxgold` = 2400 WHERE `entry` = 31320; -- Umbral Brute +UPDATE `creature_template` SET `mingold` = 750, `maxgold` = 2250 WHERE `entry` = 31321; -- Skeletal Runesmith +UPDATE `creature_template` SET `mingold` = 500, `maxgold` = 1500 WHERE `entry` = 31396; -- Val'kyr Taskmistress +UPDATE `creature_template` SET `mingold` = 1050, `maxgold` = 3150 WHERE `entry` = 31411; -- Hulking Horror +UPDATE `creature_template` SET `mingold` = 1600, `maxgold` = 4800 WHERE `entry` = 31413; -- Hulking Horror +UPDATE `creature_template` SET `mingold` = 1700, `maxgold` = 5100 WHERE `entry` = 31693; -- Stormforged Saboteur +UPDATE `creature_template` SET `mingold` = 1850, `maxgold` = 5550 WHERE `entry` = 31783; -- Vrykul Necrolord +UPDATE `creature_template` SET `mingold` = 1600, `maxgold` = 4800 WHERE `entry` = 31843; -- Reanimated Miner +UPDATE `creature_template` SET `mingold` = 1150, `maxgold` = 3450 WHERE `entry` = 31847; -- Scavenging Geist +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 31900; -- Scourge Banner-Bearer +UPDATE `creature_template` SET `mingold` = 1100, `maxgold` = 3300 WHERE `entry` = 32149; -- Fallen Hero's Spirit +UPDATE `creature_template` SET `mingold` = 1350, `maxgold` = 4050 WHERE `entry` = 32164; -- Skeletal Craftsman +UPDATE `creature_template` SET `mingold` = 1650, `maxgold` = 4950 WHERE `entry` = 32255; -- Converted Hero +UPDATE `creature_template` SET `mingold` = 1050, `maxgold` = 3150 WHERE `entry` = 32257; -- Scourge Converter +UPDATE `creature_template` SET `mingold` = 600, `maxgold` = 1800 WHERE `entry` = 32267; -- Animated Laborer +UPDATE `creature_template` SET `mingold` = 1250, `maxgold` = 3750 WHERE `entry` = 32278; -- Harbinger of Horror +UPDATE `creature_template` SET `mingold` = 1750, `maxgold` = 5250 WHERE `entry` = 32505; -- Vargul Wanderer +UPDATE `creature_template` SET `mingold` = 1400, `maxgold` = 4200 WHERE `entry` = 32507; -- Cultist Acolyte +UPDATE `creature_template` SET `mingold` = 900, `maxgold` = 2700 WHERE `entry` = 32572; -- Dragonblight Mage Hunter +UPDATE `creature_template` SET `mingold` = 405, `maxgold` = 1215 WHERE `entry` = 34838; -- Kvaldir Reaver +UPDATE `creature_template` SET `mingold` = 1450, `maxgold` = 4350 WHERE `entry` = 34839; -- Kvaldir Mist Binder +UPDATE `creature_template` SET `mingold` = 385, `maxgold` = 1155 WHERE `entry` = 38032; -- Crown Sprayer From d914d61acb1e6cee8df21c0147971888d73041a4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 9 Feb 2026 14:58:32 +0000 Subject: [PATCH 072/335] chore(DB): import pending files Referenced commit(s): d71c749586cafa2bd9f73f85e531fc161fa69a65 --- .../moneyloot.sql => db_world/2026_02_09_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/moneyloot.sql => db_world/2026_02_09_00.sql} (99%) diff --git a/data/sql/updates/pending_db_world/moneyloot.sql b/data/sql/updates/db_world/2026_02_09_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/moneyloot.sql rename to data/sql/updates/db_world/2026_02_09_00.sql index 71c1ea9dd..45e2ffa36 100644 --- a/data/sql/updates/pending_db_world/moneyloot.sql +++ b/data/sql/updates/db_world/2026_02_09_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_08_02 -> 2026_02_09_00 -- -- Updates more accurate moneyloot values to various NCPs UPDATE `creature_template` SET `mingold` = 463, `maxgold` = 1391 WHERE `entry` = 16519; -- Shadowy Executioner From 54d145499e17c379c1cc552a759b88bd39e14e3e Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Mon, 9 Feb 2026 20:07:23 -0600 Subject: [PATCH 073/335] fix(Core/GameObject): Handle zero quaternion rotation for dynamically spawned gameobjects (#24662) Co-authored-by: blinkysc Co-authored-by: zergtmn --- .../rev_1770672746227329103.sql | 30 +++++++++++++++++++ .../rev_1770676693634619814.sql | 13 ++++++++ .../game/Entities/GameObject/GameObject.cpp | 4 +++ .../game/Entities/Transport/Transport.cpp | 10 ++++--- src/server/game/Globals/ObjectMgr.cpp | 14 +++++++++ 5 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1770672746227329103.sql create mode 100644 data/sql/updates/pending_db_world/rev_1770676693634619814.sql diff --git a/data/sql/updates/pending_db_world/rev_1770672746227329103.sql b/data/sql/updates/pending_db_world/rev_1770672746227329103.sql new file mode 100644 index 000000000..e4ac075b6 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770672746227329103.sql @@ -0,0 +1,30 @@ +-- Fix gameobject spawns with non-unit rotation quaternions (sniffed values) + +-- Barbershop Chairs +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = -0.66261959075927734, `rotation3` = 0.748956084251403808 WHERE `guid` = 4718; -- 190699 +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = -0.99496841430664062, `rotation3` = 0.100189015269279479 WHERE `guid` = 4958; -- 190697 +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = 0.83388519287109375, `rotation3` = 0.55193793773651123 WHERE `guid` = 5136; -- 190698 +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = -0.85035133361816406, `rotation3` = 0.52621537446975708 WHERE `guid` = 5496; -- 190704 + +-- Legends of the Earth (2657) +UPDATE `gameobject` SET `rotation0` = 0.177045822143554687, `rotation1` = -0.68458366394042968, `rotation2` = -0.66014003753662109, `rotation3` = 0.253407031297683715 WHERE `guid` = 12007; + +-- Battered Chest (106318) +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = 0.99965667724609375, `rotation3` = 0.026201646775007247 WHERE `guid` = 26916; +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = 0.6883544921875, `rotation3` = 0.725374460220336914 WHERE `guid` = 85745; +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = -0.19936752319335937, `rotation3` = 0.979924798011779785 WHERE `guid` = 85756; +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = 0.477158546447753906, `rotation3` = 0.878817260265350341 WHERE `guid` = 85879; + +-- Water Well Cleansing Aura (2904) +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = 0.374606132507324218, `rotation3` = 0.927184045314788818 WHERE `guid` = 46424; +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = 0.034898757934570312, `rotation3` = 0.999390840530395507 WHERE `guid` = 46425; +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = 0.99965667724609375, `rotation3` = 0.026201646775007247 WHERE `guid` = 46429; + +-- Frostwyrm Waterfall Door (181225, Naxxramas) +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = -0.77439212799072265, `rotation3` = 0.632705986499786376 WHERE `guid` = 67868; + +-- Axxarien Crystal (185056) +UPDATE `gameobject` SET `rotation0` = 0.045565605163574218, `rotation1` = 0.100982666015625, `rotation2` = 0.293343544006347656, `rotation3` = 0.949566125869750976 WHERE `guid` = 99796; + +-- Cage (185474, Serpentshrine Cavern) - normalized from (0, 0, 0.7, -0.7) +UPDATE `gameobject` SET `rotation0` = 0, `rotation1` = 0, `rotation2` = -0.70710678118654752, `rotation3` = 0.70710678118654752 WHERE `guid` = 265632; diff --git a/data/sql/updates/pending_db_world/rev_1770676693634619814.sql b/data/sql/updates/pending_db_world/rev_1770676693634619814.sql new file mode 100644 index 000000000..a7e101d5e --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770676693634619814.sql @@ -0,0 +1,13 @@ +-- Add missing static transport parent_rotation values +DELETE FROM `gameobject_addon` WHERE `guid` IN (2837,6946,18802,18803,18804,18805,18806,18807,56162,56163); +INSERT INTO `gameobject_addon` (`guid`,`parent_rotation0`,`parent_rotation1`,`parent_rotation2`,`parent_rotation3`,`invisibilityType`,`invisibilityValue`) VALUES +(2837,0,0,0.996917,-0.078459,0,0), +(6946,0,0,0.992005,-0.126199,0,0), +(18802,0,0,1,0,0,0), +(18803,0,0,1,0,0,0), +(18804,0,0,1,0,0,0), +(18805,0,0,1,0,0,0), +(18806,0,0,1,0,0,0), +(18807,0,0,1,0,0,0), +(56162,0,0,1,-4.37114e-08,0,0), +(56163,0,0,1,-4.37114e-08,0,0); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index fd6049057..7979eeb21 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2209,6 +2209,10 @@ void GameObject::UpdatePackedRotation() void GameObject::SetWorldRotation(G3D::Quat const& rot) { G3D::Quat rotation = rot; + // If the quaternion is zero (e.g. dynamically spawned GOs with no rotation), + // fall back to computing rotation from orientation to avoid NaN from unitize() + if (G3D::fuzzyEq(rotation.magnitude(), 0.0f)) + rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), GetOrientation()); rotation.unitize(); WorldRotation = rotation; UpdatePackedRotation(); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index dbe068d14..ec12d2572 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -766,11 +766,13 @@ bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* m return false; } - // pussywizard: temporarily calculate WorldRotation from orientation, do so until values in db are correct - //SetWorldRotation( /*for StaticTransport we need 2 rotation Quats in db for World- and Path- Rotation*/ ); SetWorldRotationAngles(NormalizeOrientation(GetOrientation()), 0.0f, 0.0f); - // pussywizard: PathRotation for StaticTransport (only StaticTransports have PathRotation) - SetTransportPathRotation(rotation.x, rotation.y, rotation.z, rotation.w); + + // Prefer gameobject_addon parent_rotation for path rotation, fall back to gameobject.rotation + if (GameObjectAddon const* addon = sObjectMgr->GetGameObjectAddon(GetSpawnId())) + SetTransportPathRotation(addon->ParentRotation.x, addon->ParentRotation.y, addon->ParentRotation.z, addon->ParentRotation.w); + else + SetTransportPathRotation(rotation.x, rotation.y, rotation.z, rotation.w); SetObjectScale(goinfo->size); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 70164e6d9..1d0b5bdfe 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2888,6 +2888,13 @@ void ObjectMgr::LoadGameobjects() continue; } + if (fabs(data.rotation.x * data.rotation.x + data.rotation.y * data.rotation.y + + data.rotation.z * data.rotation.z + data.rotation.w * data.rotation.w - 1.0f) >= 1e-5f) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotation quaternion (non-unit), defaulting to orientation on Z axis only", guid, data.id); + data.rotation = G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(data.orientation, 0.0f, 0.0f)); + } + if (!MapMgr::IsValidMapCoord(data.mapid, data.posX, data.posY, data.posZ, data.orientation)) { LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skip", guid, data.id); @@ -3028,6 +3035,13 @@ GameObjectData const* ObjectMgr::LoadGameObjectDataFromDB(ObjectGuid::LowType sp return nullptr; } + if (fabs(goData.rotation.x * goData.rotation.x + goData.rotation.y * goData.rotation.y + + goData.rotation.z * goData.rotation.z + goData.rotation.w * goData.rotation.w - 1.0f) >= 1e-5f) + { + LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotation quaternion (non-unit), defaulting to orientation on Z axis only", spawnId, entry); + goData.rotation = G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(goData.orientation, 0.0f, 0.0f)); + } + if (!MapMgr::IsValidMapCoord(goData.mapid, goData.posX, goData.posY, goData.posZ, goData.orientation)) { LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skipped.", spawnId, entry); From 5e75f7a23fbd32ead0d1ffa024d1d712b8b0d604 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 10 Feb 2026 02:08:30 +0000 Subject: [PATCH 074/335] chore(DB): import pending files Referenced commit(s): 54d145499e17c379c1cc552a759b88bd39e14e3e --- .../rev_1770672746227329103.sql => db_world/2026_02_10_00.sql} | 1 + .../rev_1770676693634619814.sql => db_world/2026_02_10_01.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1770672746227329103.sql => db_world/2026_02_10_00.sql} (98%) rename data/sql/updates/{pending_db_world/rev_1770676693634619814.sql => db_world/2026_02_10_01.sql} (93%) diff --git a/data/sql/updates/pending_db_world/rev_1770672746227329103.sql b/data/sql/updates/db_world/2026_02_10_00.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1770672746227329103.sql rename to data/sql/updates/db_world/2026_02_10_00.sql index e4ac075b6..69d671858 100644 --- a/data/sql/updates/pending_db_world/rev_1770672746227329103.sql +++ b/data/sql/updates/db_world/2026_02_10_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_09_00 -> 2026_02_10_00 -- Fix gameobject spawns with non-unit rotation quaternions (sniffed values) -- Barbershop Chairs diff --git a/data/sql/updates/pending_db_world/rev_1770676693634619814.sql b/data/sql/updates/db_world/2026_02_10_01.sql similarity index 93% rename from data/sql/updates/pending_db_world/rev_1770676693634619814.sql rename to data/sql/updates/db_world/2026_02_10_01.sql index a7e101d5e..21f950e76 100644 --- a/data/sql/updates/pending_db_world/rev_1770676693634619814.sql +++ b/data/sql/updates/db_world/2026_02_10_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_10_00 -> 2026_02_10_01 -- Add missing static transport parent_rotation values DELETE FROM `gameobject_addon` WHERE `guid` IN (2837,6946,18802,18803,18804,18805,18806,18807,56162,56163); INSERT INTO `gameobject_addon` (`guid`,`parent_rotation0`,`parent_rotation1`,`parent_rotation2`,`parent_rotation3`,`invisibilityType`,`invisibilityValue`) VALUES From 5b278c7118b1e7342933686575b279dded45a7da Mon Sep 17 00:00:00 2001 From: sogladev Date: Tue, 10 Feb 2026 04:26:20 +0100 Subject: [PATCH 075/335] fix(Scripts/Naxxramas): Mr. Bigglesworth and Critter Bites interaction (#24671) --- src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index 901464636..918853184 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -741,10 +741,10 @@ private: bool _horsemanAchievement; }; -class npc_mr_bigglesworth : public NullCreatureAI +class npc_mr_bigglesworth : public CritterAI { public: - npc_mr_bigglesworth(Creature* c) : NullCreatureAI(c) { } + npc_mr_bigglesworth(Creature* c) : CritterAI(c) { } void JustDied(Unit* /*killer*/) override { From 1ec68348a9bc0b617ab0c270825ac79179f507a0 Mon Sep 17 00:00:00 2001 From: sogladev Date: Tue, 10 Feb 2026 04:26:37 +0100 Subject: [PATCH 076/335] fix(Scripts/World): Lower engineering specialization swap requirements (#24670) --- src/server/scripts/World/npc_professions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/World/npc_professions.cpp b/src/server/scripts/World/npc_professions.cpp index b0d57fa75..a4c203ef8 100644 --- a/src/server/scripts/World/npc_professions.cpp +++ b/src/server/scripts/World/npc_professions.cpp @@ -1234,7 +1234,7 @@ public: bool OnGossipHello(Player* player, GameObject* gameobject) override { //ENGINEERING SPEC - if (player->HasSkill(SKILL_ENGINEERING) && player->GetBaseSkillValue(SKILL_ENGINEERING) >= 225 && player->GetLevel() >= 35) + if (player->HasSkill(SKILL_ENGINEERING) && player->GetBaseSkillValue(SKILL_ENGINEERING) >= 200 && player->GetLevel() >= 30) { if (player->GetQuestRewardStatus(3643) || player->GetQuestRewardStatus(3641) || player->GetQuestRewardStatus(3639)) { From 1c5c28b6f820f5f205cd7464aaefd5e73879608d Mon Sep 17 00:00:00 2001 From: Tereneckla Date: Tue, 10 Feb 2026 03:26:54 +0000 Subject: [PATCH 077/335] fix(DB/Spells): add stack rule for love is in the air perfumes/colognes (#24659) --- data/sql/updates/pending_db_world/rev_1770632566390126542.sql | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770632566390126542.sql diff --git a/data/sql/updates/pending_db_world/rev_1770632566390126542.sql b/data/sql/updates/pending_db_world/rev_1770632566390126542.sql new file mode 100644 index 000000000..96a723808 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770632566390126542.sql @@ -0,0 +1,3 @@ +-- +DELETE FROM `spell_group_stack_rules` WHERE `group_id` = 1114; +INSERT INTO `spell_group_stack_rules` (`group_id`,`stack_rule`, `description`) VALUES (1114, 1, 'Love is in the Air Flasks'); From 4c1e559f5428e0fc7672d17bc96e26578472f0ed Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 10 Feb 2026 00:27:18 -0300 Subject: [PATCH 078/335] refactor(Scripts/EoE): Modernize scripts (#24634) --- .../Nexus/EyeOfEternity/boss_malygos.cpp | 530 ++++++++---------- .../Nexus/EyeOfEternity/eye_of_eternity.h | 26 +- .../instance_eye_of_eternity.cpp | 325 +++++------ 3 files changed, 402 insertions(+), 479 deletions(-) diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 744b60477..1ed35c6e6 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -17,6 +17,7 @@ #include "CombatAI.h" #include "CreatureScript.h" +#include "GameObjectAI.h" #include "GameObjectScript.h" #include "MoveSplineInit.h" #include "Opcodes.h" @@ -177,7 +178,6 @@ enum Phases #define MAX_NEXUS_LORDS DUNGEON_MODE(2, 4) #define MAX_SCIONS_OF_ETERNITY DUNGEON_MODE(4, 8) -#define AREA_EYE_OF_ETERNITY 4500 enum MalygosLightOverrides { @@ -211,6 +211,7 @@ struct boss_malygos : public BossAI IntroCounter = 0; bLockHealthCheck = false; + SetInvincibility(true); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED); me->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE); @@ -222,72 +223,70 @@ struct boss_malygos : public BossAI void MovementInform(uint32 type, uint32 id) override { - if (type == POINT_MOTION_TYPE) - { - switch (id) - { - case MI_POINT_INTRO_SIDE_0: - case MI_POINT_INTRO_SIDE_1: - case MI_POINT_INTRO_SIDE_2: - case MI_POINT_INTRO_SIDE_3: - { - float angle = me->GetOrientation(); - float dist = 75.0f; - if (Creature* c = me->SummonCreature(NPC_PORTAL, me->GetPositionX() + cos(angle) * dist, me->GetPositionY() + std::sin(angle) * dist, me->GetPositionZ(), FourSidesPos[id].GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 13000)) - me->CastSpell(c, SPELL_PORTAL_BEAM, false); - timer2 = INTRO_MOVEMENT_INTERVAL - 10000; - } - break; + if (type != POINT_MOTION_TYPE) + return; - case MI_POINT_INTRO_CENTER_AIR: - events.RescheduleEvent(EVENT_INTRO_LAND, 0ms, 1); - break; - case MI_POINT_VORTEX_CENTER: - if (Creature* c = me->SummonCreature(NPC_WORLD_TRIGGER_LAOI, CenterPos, TEMPSUMMON_TIMED_DESPAWN, 15000)) - c->CastSpell(c, SPELL_VORTEX_VISUAL, true); - events.RescheduleEvent(EVENT_START_VORTEX_REAL, 1s, 1); - break; - case MI_POINT_CENTER_GROUND_PH_2: - events.RescheduleEvent(EVENT_START_PHASE_2_FLY_UP, 0ms, 1); - break; - case MI_POINT_CIRCLE_OUTSIDE_PH_2: - events.RescheduleEvent(EVENT_RESUME_FLYING_CIRCLES_PH_2, 0ms, 1); - break; - case MI_POINT_SURGE_OF_POWER_CENTER: - events.RescheduleEvent(EVENT_SURGE_OF_POWER_WARNING, 0ms, 1); - break; - case MI_POINT_INTRO_LAND: - me->SetDisableGravity(false); - events.RescheduleEvent(EVENT_START_FIGHT, 0ms, 1); - break; - case MI_POINT_VORTEX_TAKEOFF: - events.RescheduleEvent(EVENT_VORTEX_FLY_TO_CENTER, 0ms, 1); - break; - case MI_POINT_VORTEX_LAND: - me->SetDisableGravity(false); - events.RescheduleEvent(EVENT_VORTEX_LAND_1, 0ms, 1); - break; - case MI_POINT_CENTER_AIR_PH_2: - me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_ARCANE_RUNES, 5s); - break; - case MI_POINT_PH_3_FIGHT_POSITION: - events.RescheduleEvent(EVENT_START_PHASE_3, 6s, 1); - break; - } + switch (id) + { + case MI_POINT_INTRO_SIDE_0: + case MI_POINT_INTRO_SIDE_1: + case MI_POINT_INTRO_SIDE_2: + case MI_POINT_INTRO_SIDE_3: + { + float angle = me->GetOrientation(); + float dist = 75.0f; + if (Creature* c = me->SummonCreature(NPC_PORTAL, me->GetPositionX() + cos(angle) * dist, me->GetPositionY() + std::sin(angle) * dist, me->GetPositionZ(), FourSidesPos[id].GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 13000)) + me->CastSpell(c, SPELL_PORTAL_BEAM, false); + timer2 = INTRO_MOVEMENT_INTERVAL - 10000; + } + break; + + case MI_POINT_INTRO_CENTER_AIR: + events.RescheduleEvent(EVENT_INTRO_LAND, 0ms, 1); + break; + case MI_POINT_VORTEX_CENTER: + if (Creature* c = me->SummonCreature(NPC_WORLD_TRIGGER_LAOI, CenterPos, TEMPSUMMON_TIMED_DESPAWN, 15000)) + c->CastSpell(c, SPELL_VORTEX_VISUAL, true); + events.RescheduleEvent(EVENT_START_VORTEX_REAL, 1s, 1); + break; + case MI_POINT_CENTER_GROUND_PH_2: + events.RescheduleEvent(EVENT_START_PHASE_2_FLY_UP, 0ms, 1); + break; + case MI_POINT_CIRCLE_OUTSIDE_PH_2: + events.RescheduleEvent(EVENT_RESUME_FLYING_CIRCLES_PH_2, 0ms, 1); + break; + case MI_POINT_SURGE_OF_POWER_CENTER: + events.RescheduleEvent(EVENT_SURGE_OF_POWER_WARNING, 0ms, 1); + break; + case MI_POINT_INTRO_LAND: + me->SetDisableGravity(false); + events.RescheduleEvent(EVENT_START_FIGHT, 0ms, 1); + break; + case MI_POINT_VORTEX_TAKEOFF: + events.RescheduleEvent(EVENT_VORTEX_FLY_TO_CENTER, 0ms, 1); + break; + case MI_POINT_VORTEX_LAND: + me->SetDisableGravity(false); + events.RescheduleEvent(EVENT_VORTEX_LAND_1, 0ms, 1); + break; + case MI_POINT_CENTER_AIR_PH_2: + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_ARCANE_RUNES, 5s); + break; + case MI_POINT_PH_3_FIGHT_POSITION: + events.RescheduleEvent(EVENT_START_PHASE_3, 6s, 1); + break; } } void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override { - if (spell->Id == SPELL_POWER_SPARK_MALYGOS_BUFF) - { - if (!bLockHealthCheck) - { - Talk(SAY_BUFFED_BY_SPARK); - } - else - me->RemoveAura(SPELL_POWER_SPARK_MALYGOS_BUFF); - } + if (spell->Id != SPELL_POWER_SPARK_MALYGOS_BUFF) + return; + + if (!bLockHealthCheck) + Talk(SAY_BUFFED_BY_SPARK); + else + me->RemoveAura(SPELL_POWER_SPARK_MALYGOS_BUFF); } void JustEngagedWith(Unit* /*who*/) override @@ -317,13 +316,9 @@ struct boss_malygos : public BossAI } } - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override { - if (damage >= me->GetHealth() && !me->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) // allow dying only in phase 3! - { - damage = 0; - return; - } + BossAI::DamageTaken(attacker, damage, damagetype, damageSchoolMask); if (!bLockHealthCheck && me->HealthBelowPctDamaged(50, damage)) { @@ -351,7 +346,6 @@ struct boss_malygos : public BossAI case EVENT_BERSERK: me->CastSpell(me, SPELL_BERSERK, true); Talk(EMOTE_BERSERK); - break; case EVENT_INTRO_MOVE_CENTER: { @@ -368,10 +362,8 @@ struct boss_malygos : public BossAI break; } case EVENT_INTRO_LAND: - { me->GetMotionMaster()->MovePoint(MI_POINT_INTRO_LAND, me->GetPositionX(), me->GetPositionY(), CenterPos.GetPositionZ(), FORCED_MOVEMENT_RUN, 0.f, 0.f, true, true, MOTION_SLOT_ACTIVE, AnimTier::Ground); break; - } case EVENT_START_FIGHT: { instance->SetData(DATA_HIDE_IRIS_AND_PORTAL, 0); @@ -406,7 +398,7 @@ struct boss_malygos : public BossAI c->CastSpell(c, SPELL_PORTAL_BEAM, false); if (Creature* c = me->SummonCreature(NPC_POWER_SPARK, FourSidesPos[random], TEMPSUMMON_MANUAL_DESPAWN, 0)) { - c->AI()->DoAction(1); + c->AI()->DoAction(ACTION_POWER_SPARK_FOLLOW); c->AI()->Talk(EMOTE_POWER_SPARK); } @@ -418,7 +410,7 @@ struct boss_malygos : public BossAI bLockHealthCheck = true; Talk(SAY_MAGIC_BLAST); EntryCheckPredicate pred(NPC_POWER_SPARK); - summons.DoAction(2, pred); // stop following + summons.DoAction(ACTION_POWER_SPARK_STOP, pred); me->SetUnitFlag(UNIT_FLAG_PACIFIED); me->SendMeleeAttackStop(me->GetVictim()); @@ -452,52 +444,49 @@ struct boss_malygos : public BossAI { vp->SetDisableGravity(true); - Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers(); - if (!PlayerList.IsEmpty()) - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - if (Player* pPlayer = i->GetSource()) + me->GetMap()->DoForAllPlayers([&](Player* pPlayer) + { + if (!pPlayer->IsAlive() || pPlayer->IsGameMaster()) + return; + + Position plrpos; + float playerAngle = CenterPos.GetAngle(pPlayer); + plrpos.m_positionX = CenterPos.GetPositionX() + cos(playerAngle) * 5.0f; + plrpos.m_positionY = CenterPos.GetPositionY() + std::sin(playerAngle) * 5.0f; + plrpos.m_positionZ = CenterPos.GetPositionZ() + 18.0f; + plrpos.SetOrientation(plrpos.GetAngle(&CenterPos)); + + if (Creature* c = me->SummonCreature(NPC_VORTEX, plrpos, TEMPSUMMON_TIMED_DESPAWN, 15000)) + { + pPlayer->CastSpell(pPlayer, SPELL_FREEZE_ANIM, true); + pPlayer->CastSpell(c, SPELL_VORTEX_CONTROL_VEHICLE, true); + if (!pPlayer->GetVehicle()) // didn't work somehow, try again with a different way, if fails - break { - if (!pPlayer->IsAlive() || pPlayer->IsGameMaster()) - continue; - - Position plrpos; - float playerAngle = CenterPos.GetAngle(pPlayer); - plrpos.m_positionX = CenterPos.GetPositionX() + cos(playerAngle) * 5.0f; - plrpos.m_positionY = CenterPos.GetPositionY() + std::sin(playerAngle) * 5.0f; - plrpos.m_positionZ = CenterPos.GetPositionZ() + 18.0f; - plrpos.SetOrientation(plrpos.GetAngle(&CenterPos)); - - if (Creature* c = me->SummonCreature(NPC_VORTEX, plrpos, TEMPSUMMON_TIMED_DESPAWN, 15000)) - { - pPlayer->CastSpell(pPlayer, SPELL_FREEZE_ANIM, true); - pPlayer->CastSpell(c, SPELL_VORTEX_CONTROL_VEHICLE, true); - if (!pPlayer->GetVehicle()) // didn't work somehow, try again with a different way, if fails - break - { - pPlayer->EnterVehicle(c, 0); - if (!pPlayer->GetVehicle()) - continue; - } - //pPlayer->ClearUnitState(UNIT_STATE_ONVEHICLE); - - Movement::MoveSplineInit init(pPlayer); // TODO: has to be removed and handled with vehicle exit and vehicle enter code - init.MoveTo(CenterPos.GetPositionX(), CenterPos.GetPositionY(), CenterPos.GetPositionZ()); - init.SetFacing(pPlayer->GetOrientation()); - init.SetTransportExit(); - init.Launch(); - - pPlayer->SetUnitMovementFlags(MOVEMENTFLAG_NONE); - pPlayer->SetDisableGravity(true); - - WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); - data << pPlayer->GetPackGUID(); - pPlayer->SendMessageToSet(&data, true); - - sScriptMgr->AnticheatSetUnderACKmount(pPlayer); - - pPlayer->SetGuidValue(PLAYER_FARSIGHT, vp->GetGUID()); - c->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - } + pPlayer->EnterVehicle(c, 0); + if (!pPlayer->GetVehicle()) + return; } + //pPlayer->ClearUnitState(UNIT_STATE_ONVEHICLE); + + Movement::MoveSplineInit init(pPlayer); // TODO: has to be removed and handled with vehicle exit and vehicle enter code + init.MoveTo(CenterPos.GetPositionX(), CenterPos.GetPositionY(), CenterPos.GetPositionZ()); + init.SetFacing(pPlayer->GetOrientation()); + init.SetTransportExit(); + init.Launch(); + + pPlayer->SetUnitMovementFlags(MOVEMENTFLAG_NONE); + pPlayer->SetDisableGravity(true); + + WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); + data << pPlayer->GetPackGUID(); + pPlayer->SendMessageToSet(&data, true); + + sScriptMgr->AnticheatSetUnderACKmount(pPlayer); + + pPlayer->SetGuidValue(PLAYER_FARSIGHT, vp->GetGUID()); + c->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + } + }); } events.RescheduleEvent(EVENT_VORTEX_LAND_0, 11s, 1); @@ -505,19 +494,14 @@ struct boss_malygos : public BossAI } case EVENT_VORTEX_LAND_0: me->GetMotionMaster()->MovePoint(MI_POINT_VORTEX_LAND, CenterPos, FORCED_MOVEMENT_RUN, 0.f, true, true, AnimTier::Ground); - break; case EVENT_VORTEX_LAND_1: { bLockHealthCheck = false; EntryCheckPredicate pred(NPC_POWER_SPARK); - summons.DoAction(1, pred); // resume following + summons.DoAction(ACTION_POWER_SPARK_FOLLOW, pred); me->RemoveUnitFlag(UNIT_FLAG_PACIFIED); - if (Unit* target = me->GetVictim()) - { - AttackStart(target); - me->GetMotionMaster()->MoveChase(target); - } + me->ResumeChasingVictim(); events.RescheduleEvent(EVENT_START_VORTEX_0, 60s, 1); break; } @@ -533,7 +517,6 @@ struct boss_malygos : public BossAI events.CancelEventGroup(1); // don't cancel berserk (group 0) break; case EVENT_START_PHASE_2_FLY_UP: - { me->SendMeleeAttackStop(me->GetVictim()); me->GetMotionMaster()->MoveIdle(); me->DisableSpline(); @@ -541,7 +524,6 @@ struct boss_malygos : public BossAI me->GetMotionMaster()->MovePoint(MI_POINT_CENTER_AIR_PH_2, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 32.0f, FORCED_MOVEMENT_RUN, 0.f, 0.f, true, true, MOTION_SLOT_ACTIVE, AnimTier::Fly); events.RescheduleEvent(EVENT_START_PHASE_2_MOVE_TO_SIDE, 22s + 500ms, 1); break; - } case EVENT_START_PHASE_2_MOVE_TO_SIDE: Talk(SAY_PHASE_2); me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED); @@ -559,7 +541,7 @@ struct boss_malygos : public BossAI if (Creature* c = me->SummonCreature(NPC_NEXUS_LORD, *disk, TEMPSUMMON_MANUAL_DESPAWN, 0)) { c->EnterVehicle(disk, 0); - disk->AI()->DoAction(1); // start moving + disk->AI()->DoAction(ACTION_DISK_START_MOVING); } } for (int i = 0; i < MAX_SCIONS_OF_ETERNITY; i++) @@ -570,7 +552,7 @@ struct boss_malygos : public BossAI if (Creature* c = me->SummonCreature(NPC_SCION_OF_ETERNITY, *disk, TEMPSUMMON_MANUAL_DESPAWN, 0)) { c->EnterVehicle(disk, 0); - disk->AI()->DoAction(1); // start moving + disk->AI()->DoAction(ACTION_DISK_START_MOVING); } } @@ -628,7 +610,6 @@ struct boss_malygos : public BossAI me->SetTarget(); break; case EVENT_CHECK_TRASH_DEAD: - { if (me->FindNearestCreature(NPC_SCION_OF_ETERNITY, 250.0f, true) || me->FindNearestCreature(NPC_NEXUS_LORD, 250.0f, true)) events.Repeat(3s); else @@ -646,8 +627,7 @@ struct boss_malygos : public BossAI events.RescheduleEvent(EVENT_LIGHT_DIMENSION_CHANGE, 1s, 1); events.RescheduleEvent(EVENT_DESTROY_PLATFORM_0, 10s, 1); } - } - break; + break; case EVENT_LIGHT_DIMENSION_CHANGE: me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_CHANGE_DIMENSIONS, 2s); break; @@ -687,6 +667,7 @@ struct boss_malygos : public BossAI break; case EVENT_START_PHASE_3: events.SetPhase(PHASE_THREE); + SetInvincibility(false); me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_OBSCURE_ARCANE_RUNES, 1s); me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); me->SetUnitFlag(UNIT_FLAG_PACIFIED | UNIT_FLAG_DISABLE_MOVE); @@ -800,18 +781,17 @@ struct boss_malygos : public BossAI #define VORTEX_DEFAULT_DIFF 250 #define VORTEX_TRAVEL_TIME 3000 -//#define VORTEX_RADIUS 25.0f struct npc_vortex_ride : public VehicleAI { npc_vortex_ride(Creature* pCreature) : VehicleAI(pCreature) { - VORTEX_RADIUS = urand(22, 28); + vortexRadius = urand(22, 28); float h = urand(15, 30); float angle = CenterPos.GetAngle(me); Position pos; - pos.m_positionX = CenterPos.GetPositionX() + VORTEX_RADIUS * cos(angle); - pos.m_positionY = CenterPos.GetPositionY() + VORTEX_RADIUS * std::sin(angle); + pos.m_positionX = CenterPos.GetPositionX() + vortexRadius * cos(angle); + pos.m_positionY = CenterPos.GetPositionY() + vortexRadius * std::sin(angle); pos.m_positionZ = CenterPos.GetPositionZ() + h; pos.SetOrientation(pos.GetAngle(&CenterPos)); me->SetPosition(pos); @@ -823,29 +803,26 @@ struct npc_vortex_ride : public VehicleAI uint32 timer; uint32 despawnTimer; bool bUpdatedFlying; - float VORTEX_RADIUS; + float vortexRadius; void PassengerBoarded(Unit* pass, int8 /*seat*/, bool apply) override { - if (pass && !apply && pass->IsPlayer()) - { - Player* plr = pass->ToPlayer(); - float speed = plr->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()) / (1.0f * 0.001f); - plr->SetDisableGravity(false); // packet only would lead to issues elsewhere - plr->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), speed); - plr->RemoveAura(SPELL_FREEZE_ANIM); - plr->SetGuidValue(PLAYER_FARSIGHT, ObjectGuid::Empty); + if (!pass || apply || !pass->IsPlayer()) + return; - sScriptMgr->AnticheatSetCanFlybyServer(plr, false); - sScriptMgr->AnticheatSetUnderACKmount(plr); - } + Player* plr = pass->ToPlayer(); + float speed = plr->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()) / (1.0f * 0.001f); + plr->SetDisableGravity(false); // packet only would lead to issues elsewhere + plr->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), speed); + plr->RemoveAura(SPELL_FREEZE_ANIM); + plr->SetGuidValue(PLAYER_FARSIGHT, ObjectGuid::Empty); + + sScriptMgr->AnticheatSetCanFlybyServer(plr, false); + sScriptMgr->AnticheatSetUnderACKmount(plr); } void UpdateAI(uint32 diff) override { - /* here: if player has some aura that should make him exit vehicle (eg. ice block) -> exit - or make it another way (dunno how) */ - if (despawnTimer <= diff) { despawnTimer = 0; @@ -865,21 +842,23 @@ struct npc_vortex_ride : public VehicleAI float newangle = angle + 2 * M_PI / ((float)VORTEX_TRAVEL_TIME / VORTEX_DEFAULT_DIFF); if (newangle >= 2 * M_PI) newangle -= 2 * M_PI; - float newx = CenterPos.GetPositionX() + VORTEX_RADIUS * cos(newangle); - float newy = CenterPos.GetPositionY() + VORTEX_RADIUS * std::sin(newangle); + float newx = CenterPos.GetPositionX() + vortexRadius * cos(newangle); + float newy = CenterPos.GetPositionY() + vortexRadius * std::sin(newangle); float arcangle = me->GetAngle(newx, newy); float dist = 2 * me->GetDistance2d(newx, newy); - if (me->GetVehicleKit()) if (Unit* pass = me->GetVehicleKit()->GetPassenger(0)) if (Player* plr = pass->ToPlayer()) - { - if (!bUpdatedFlying && timer) - { - bUpdatedFlying = true; - plr->SetDisableGravity(true); - } + if (me->GetVehicleKit()) + if (Unit* pass = me->GetVehicleKit()->GetPassenger(0)) + if (Player* plr = pass->ToPlayer()) + { + if (!bUpdatedFlying && timer) + { + bUpdatedFlying = true; + plr->SetDisableGravity(true); + } - plr->SendMonsterMove(me->GetPositionX() + dist * cos(arcangle), me->GetPositionY() + dist * std::sin(arcangle), me->GetPositionZ(), VORTEX_DEFAULT_DIFF * 2, SPLINEFLAG_FLYING); - me->Relocate(newx, newy); - } + plr->SendMonsterMove(me->GetPositionX() + dist * cos(arcangle), me->GetPositionY() + dist * std::sin(arcangle), me->GetPositionZ(), VORTEX_DEFAULT_DIFF * 2, SPLINEFLAG_FLYING); + me->Relocate(newx, newy); + } timer = (diff - timer <= VORTEX_DEFAULT_DIFF) ? VORTEX_DEFAULT_DIFF - (diff - timer) : 0; } @@ -910,10 +889,10 @@ struct npc_power_spark : public NullCreatureAI { switch (param) { - case 1: + case ACTION_POWER_SPARK_FOLLOW: MoveTimer = 1; break; - case 2: + case ACTION_POWER_SPARK_STOP: MoveTimer = 0; me->GetMotionMaster()->MoveIdle(); me->DisableSpline(); @@ -924,21 +903,21 @@ struct npc_power_spark : public NullCreatureAI void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override { - if (damage >= me->GetHealth()) - { - damage = 0; - if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - { - MoveTimer = 0; - me->GetMotionMaster()->MoveIdle(); - me->DisableSpline(); - me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), CenterPos.GetPositionZ(), FORCED_MOVEMENT_NONE, 100.0f); - me->ReplaceAllUnitFlags(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); - me->RemoveAura(SPELL_POWER_SPARK_VISUAL); - me->CastSpell(me, SPELL_POWER_SPARK_GROUND_BUFF, true); - me->DespawnOrUnsummon(60s); - } - } + if (damage < me->GetHealth()) + return; + + damage = 0; + if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) + return; + + MoveTimer = 0; + me->GetMotionMaster()->MoveIdle(); + me->DisableSpline(); + me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), CenterPos.GetPositionZ(), FORCED_MOVEMENT_NONE, 100.0f); + me->ReplaceAllUnitFlags(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + me->RemoveAura(SPELL_POWER_SPARK_VISUAL); + me->CastSpell(me, SPELL_POWER_SPARK_GROUND_BUFF, true); + me->DespawnOrUnsummon(60s); } void UpdateAI(uint32 diff) override @@ -981,22 +960,24 @@ struct npc_nexus_lord : public ScriptedAI npc_nexus_lord(Creature* pCreature) : ScriptedAI(pCreature) { me->SetReactState(REACT_PASSIVE); - pInstance = me->GetInstanceScript(); timer = 0; - events.Reset(); - events.RescheduleEvent(EVENT_TELEPORT_VISUAL, 0ms); + me->CastSpell(me, SPELL_TELEPORT_VISUAL, true); } - InstanceScript* pInstance; - EventMap events; uint16 timer; void JustEngagedWith(Unit* /*who*/) override { DoZoneInCombat(); - events.Reset(); - events.RescheduleEvent(EVENT_NEXUS_LORD_ARCANE_SHOCK, 3s, 10s); - events.RescheduleEvent(EVENT_NEXUS_LORD_HASTE, 8s, 14s); + ScheduleTimedEvent(3s, 10s, [&] + { + if (Unit* victim = me->GetVictim()) + me->CastSpell(victim, SPELL_ARCANE_SHOCK); + }, 10s, 15s); + ScheduleTimedEvent(8s, 14s, [&] + { + me->CastSpell(me, SPELL_HASTE); + }, 20s, 30s); } void AttackStart(Unit* victim) override @@ -1025,28 +1006,10 @@ struct npc_nexus_lord : public ScriptedAI timer -= diff; } - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) + scheduler.Update(diff, [this] { - case 0: - break; - case EVENT_TELEPORT_VISUAL: - me->CastSpell(me, SPELL_TELEPORT_VISUAL, true); - break; - case EVENT_NEXUS_LORD_ARCANE_SHOCK: - if (Unit* victim = me->GetVictim()) - me->CastSpell(victim, SPELL_ARCANE_SHOCK); - events.Repeat(10s, 15s); - break; - case EVENT_NEXUS_LORD_HASTE: - me->CastSpell(me, SPELL_HASTE); - events.Repeat(20s, 30s); - break; - } + return me->HasUnitState(UNIT_STATE_CASTING); + }); DoMeleeAttackIfReady(); } @@ -1063,53 +1026,27 @@ struct npc_scion_of_eternity : public ScriptedAI npc_scion_of_eternity(Creature* pCreature) : ScriptedAI(pCreature) { me->SetReactState(REACT_PASSIVE); - pInstance = me->GetInstanceScript(); - events.Reset(); - events.RescheduleEvent(EVENT_TELEPORT_VISUAL, 0ms); - events.RescheduleEvent(EVENT_SCION_OF_ETERNITY_ARCANE_BARRAGE, 20s, 25s); - } - - InstanceScript* pInstance; - EventMap events; - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_TELEPORT_VISUAL: - me->CastSpell(me, SPELL_TELEPORT_VISUAL, true); - break; - case EVENT_SCION_OF_ETERNITY_ARCANE_BARRAGE: + me->CastSpell(me, SPELL_TELEPORT_VISUAL, true); + ScheduleTimedEvent(20s, 25s, [&] { GuidVector guids; - Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers(); - if (!PlayerList.IsEmpty()) - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - if (Player* pPlayer = i->GetSource()) - { - if (pPlayer->IsAlive()) - { - if (!pPlayer->GetVehicle()) - { - guids.push_back(pPlayer->GetGUID()); - } - } - } + me->GetMap()->DoForAllPlayers([&](Player* pPlayer) + { + if (pPlayer->IsAlive() && !pPlayer->GetVehicle()) + guids.push_back(pPlayer->GetGUID()); + }); if (!guids.empty()) if (Player* plr = ObjectAccessor::GetPlayer(*me, guids.at(urand(0, guids.size() - 1)))) me->CastSpell(plr, SPELL_SCION_ARCANE_BARRAGE); + }, 5s, 8s); + } - events.Repeat(5s, 8s); - } - break; - } + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff, [this] + { + return me->HasUnitState(UNIT_STATE_CASTING); + }); } void JustDied(Unit* killer) override @@ -1130,11 +1067,9 @@ struct npc_hover_disk : public VehicleAI { npc_hover_disk(Creature* pCreature) : VehicleAI(pCreature) { - pInstance = me->GetInstanceScript(); events.Reset(); } - InstanceScript* pInstance; EventMap events; void PassengerBoarded(Unit* who, int8 /*seat*/, bool apply) override @@ -1209,7 +1144,7 @@ struct npc_hover_disk : public VehicleAI { switch (param) { - case 1: // move to next point + case ACTION_DISK_START_MOVING: if (Vehicle* v = me->GetVehicleKit()) if (Unit* pass = v->GetPassenger(0)) switch (pass->GetEntry()) @@ -1248,7 +1183,7 @@ struct npc_hover_disk : public VehicleAI case 0: break; case EVENT_DISK_MOVE_NEXT_POINT: - DoAction(1); + DoAction(ACTION_DISK_START_MOVING); break; } } @@ -1261,48 +1196,37 @@ struct npc_alexstrasza : public ScriptedAI { npc_alexstrasza(Creature* pCreature) : ScriptedAI(pCreature) { - events.Reset(); - events.ScheduleEvent(1, 9s); me->SetCanFly(true); me->SetDisableGravity(true); - } - EventMap events; + ScheduleUniqueTimedEvent(9s, [&] + { + me->CastSpell(AlexstraszaGiftPos.GetPositionX(), AlexstraszaGiftPos.GetPositionY(), AlexstraszaGiftPos.GetPositionZ(), SPELL_ALEXSTRASZA_GIFT, true); + if (GameObject* chest = me->SummonGameObject(ALEXSTRASZA_GIFT, AlexstraszaGiftPos.GetPositionX(), AlexstraszaGiftPos.GetPositionY(), AlexstraszaGiftPos.GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) + chest->SetLootRecipient(me->GetMap()); + + if (GameObject* heart = me->SummonGameObject(HEART_OF_MAGIC, HeartOfMagicPos.GetPositionX(), HeartOfMagicPos.GetPositionY(), HeartOfMagicPos.GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) + heart->SetLootRecipient(me->GetMap()); + + Talk(SAY_ALEXSTRASZA_ONE); + ScheduleUniqueTimedEvent(6s, [&] + { + Talk(SAY_ALEXSTRASZA_TWO); + ScheduleUniqueTimedEvent(5s, [&] + { + Talk(SAY_ALEXSTRASZA_THREE); + ScheduleUniqueTimedEvent(22s, [&] + { + Talk(SAY_ALEXSTRASZA_FOUR); + }, EVENT_ALEXSTRASZA_SAY_FOUR); + }, EVENT_ALEXSTRASZA_SAY_THREE); + }, EVENT_ALEXSTRASZA_SAY_TWO); + }, EVENT_ALEXSTRASZA_GIFT); + } void UpdateAI(uint32 diff) override { - events.Update(diff); - switch (events.ExecuteEvent()) - { - case 0: - break; - case 1: - me->CastSpell(773.98f, 1285.97f, 266.254f, SPELL_ALEXSTRASZA_GIFT, true); - if (GameObject* chest = me->SummonGameObject(ALEXSTRASZA_GIFT, 773.98f, 1285.97f, 266.254f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) - { - chest->SetLootRecipient(me->GetMap()); - } - - if (GameObject* heart = me->SummonGameObject(HEART_OF_MAGIC, 773.98f, 1275.97f, 266.254f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) - { - heart->SetLootRecipient(me->GetMap()); - } - - Talk(SAY_ALEXSTRASZA_ONE); - events.RescheduleEvent(2, 6s); - break; - case 2: - Talk(SAY_ALEXSTRASZA_TWO); - events.RescheduleEvent(3, 5s); - break; - case 3: - Talk(SAY_ALEXSTRASZA_THREE); - events.RescheduleEvent(4, 22s); - break; - case 4: - Talk(SAY_ALEXSTRASZA_FOUR); - break; - } + scheduler.Update(diff); } void MoveInLineOfSight(Unit* /*who*/) override {} @@ -1315,14 +1239,14 @@ struct npc_eoe_wyrmrest_skytalon : public VehicleAI void IsSummonedBy(WorldObject* summoner) override { - if (summoner && summoner->IsPlayer()) - { - ObjectGuid summonerGUID = summoner->GetGUID(); - me->m_Events.AddEventAtOffset([summonerGUID, this] { - if (Player* rider = ObjectAccessor::GetPlayer(*me, summonerGUID)) - DoCast(rider, SPELL_RIDE_RED_DRAGON, true); - }, 2s); - } + if (!summoner || !summoner->IsPlayer()) + return; + + ObjectGuid summonerGUID = summoner->GetGUID(); + me->m_Events.AddEventAtOffset([summonerGUID, this] { + if (Player* rider = ObjectAccessor::GetPlayer(*me, summonerGUID)) + DoCast(rider, SPELL_RIDE_RED_DRAGON, true); + }, 2s); } void PassengerBoarded(Unit* pass, int8 /*seat*/, bool apply) override @@ -1346,17 +1270,13 @@ struct npc_eoe_wyrmrest_skytalon : public VehicleAI } }; -class go_the_focusing_iris : public GameObjectScript +struct go_the_focusing_iris : public GameObjectAI { -public: - go_the_focusing_iris() : GameObjectScript("go_the_focusing_iris") { } + go_the_focusing_iris(GameObject* go) : GameObjectAI(go) { } - bool OnGossipHello(Player* user, GameObject* go) override + bool GossipHello(Player* /*user*/, bool /*reportUse*/) override { - if (!user || !go) - return true; - - if (InstanceScript* pInstance = go->GetInstanceScript()) + if (InstanceScript* pInstance = me->GetInstanceScript()) pInstance->SetData(DATA_IRIS_ACTIVATED, 0); return true; @@ -1455,7 +1375,7 @@ void AddSC_boss_malygos() RegisterEoECreatureAI(npc_power_spark); RegisterEoECreatureAI(npc_vortex_ride); RegisterEoECreatureAI(npc_alexstrasza); - new go_the_focusing_iris(); + RegisterGameObjectAI(go_the_focusing_iris); RegisterEoECreatureAI(npc_nexus_lord); RegisterEoECreatureAI(npc_scion_of_eternity); RegisterEoECreatureAI(npc_hover_disk); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h index 2b3ddfd38..bbbdc5779 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h @@ -18,7 +18,6 @@ #ifndef DEF_EYE_OF_ETERNITY_H #define DEF_EYE_OF_ETERNITY_H -#include "Chat.h" #include "CreatureAIImpl.h" #define DataHeader "EOE" @@ -91,13 +90,29 @@ enum eAchiev enum EoEMisc : uint32 { - EVENT_IRIS_ACTIVATED = 20158 + AREA_EYE_OF_ETERNITY = 4500, + EVENT_IRIS_ACTIVATED = 20158, + PLATFORM_DESTROY_DAMAGE = 6500000, + INTRO_MOVEMENT_INTERVAL = 25000, +}; + +enum EoEActions +{ + ACTION_POWER_SPARK_FOLLOW = 1, + ACTION_POWER_SPARK_STOP = 2, + ACTION_DISK_START_MOVING = 1, +}; + +enum AlexstraszaEvents +{ + EVENT_ALEXSTRASZA_GIFT = 1, + EVENT_ALEXSTRASZA_SAY_TWO = 2, + EVENT_ALEXSTRASZA_SAY_THREE = 3, + EVENT_ALEXSTRASZA_SAY_FOUR = 4, }; /*** POSITIONS/WAYPOINTS BELOW ***/ -#define INTRO_MOVEMENT_INTERVAL 25000 - const Position CenterPos = {754.395f, 1301.27f, 266.10f, 0.0f}; const Position FourSidesPos[] = @@ -110,6 +125,9 @@ const Position FourSidesPos[] = const Position Phase2NorthPos = {837.22f, 1301.676f, 296.10f, M_PI}; +const Position AlexstraszaGiftPos = {773.98f, 1285.97f, 266.254f, 0.0f}; +const Position HeartOfMagicPos = {773.98f, 1275.97f, 266.254f, 0.0f}; + const uint32 MalygosIntroIntervals[] = {18000, 19000, 21000, 18000, 15000}; template diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index 42788ec50..590836726 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -21,193 +21,178 @@ #include "Vehicle.h" #include "eye_of_eternity.h" -class instance_eye_of_eternity : public InstanceMapScript +struct instance_eye_of_eternity : public InstanceScript { -public: - instance_eye_of_eternity() : InstanceMapScript("instance_eye_of_eternity", MAP_THE_EYE_OF_ETERNITY) { } + instance_eye_of_eternity(Map* pMap) : InstanceScript(pMap) { Initialize(); } - struct instance_eye_of_eternity_InstanceMapScript : public InstanceScript + ObjectGuid NPC_MalygosGUID; + ObjectGuid GO_IrisGUID; + ObjectGuid GO_ExitPortalGUID; + ObjectGuid GO_PlatformGUID; + bool bPokeAchiev; + + void Initialize() override { - instance_eye_of_eternity_InstanceMapScript(Map* pMap) : InstanceScript(pMap) { Initialize(); } + SetHeaders(DataHeader); + SetBossNumber(EncounterCount); + bPokeAchiev = false; + } - ObjectGuid NPC_MalygosGUID; - ObjectGuid GO_IrisGUID; - ObjectGuid GO_ExitPortalGUID; - ObjectGuid GO_PlatformGUID; - bool bPokeAchiev; + void OnPlayerEnter(Player* player) override + { + if (GetBossState(DATA_MALYGOS) != DONE) + return; - void Initialize() override + ProcessEvent(nullptr, EVENT_IRIS_ACTIVATED); + if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) + if (go->GetPhaseMask() != 2) + go->SetPhaseMask(2, true); + + if (player && player->IsAlive()) + player->CastSpell(player, SPELL_SUMMON_RED_DRAGON_BUDDY, true); + } + + void OnCreatureCreate(Creature* creature) override + { + switch (creature->GetEntry()) { - SetHeaders(DataHeader); - SetBossNumber(EncounterCount); - bPokeAchiev = false; + case NPC_MALYGOS: + NPC_MalygosGUID = creature->GetGUID(); + break; } + } - void OnPlayerEnter(Player* player) override + void OnGameObjectCreate(GameObject* go) override + { + switch (go->GetEntry()) { - if (GetBossState(DATA_MALYGOS) == DONE) - { - // destroy platform, hide iris (actually ensure, done at loading, but doesn't always work - ProcessEvent(nullptr, EVENT_IRIS_ACTIVATED); - if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) - if (go->GetPhaseMask() != 2) - go->SetPhaseMask(2, true); - - // no floor, so put players on drakes - if (player && player->IsAlive()) - player->CastSpell(player, SPELL_SUMMON_RED_DRAGON_BUDDY, true); - } - } - - void OnCreatureCreate(Creature* creature) override - { - switch (creature->GetEntry()) - { - case NPC_MALYGOS: - NPC_MalygosGUID = creature->GetGUID(); - break; - } - } - - void OnGameObjectCreate(GameObject* go) override - { - switch (go->GetEntry()) - { - case GO_IRIS_N: - case GO_IRIS_H: - GO_IrisGUID = go->GetGUID(); - - if (GetBossState(DATA_MALYGOS) == DONE) - go->SetPhaseMask(2, true); - break; - case GO_EXIT_PORTAL: - GO_ExitPortalGUID = go->GetGUID(); - break; - case GO_NEXUS_PLATFORM: - GO_PlatformGUID = go->GetGUID(); - if (GetBossState(DATA_MALYGOS) == DONE) - { - go->ModifyHealth(-6500000); // We have HP 6 million in the database... So we have to do at least that - go->EnableCollision(false); - } - break; - } - } - - void SetData(uint32 type, uint32 /*data*/) override - { - switch (type) - { - case DATA_IRIS_ACTIVATED: - if (GetBossState(DATA_MALYGOS) == NOT_STARTED) - if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) - if (Player* plr = c->SelectNearestPlayer(250.0f)) - c->AI()->AttackStart(plr); - break; - case DATA_SET_IRIS_INACTIVE: - if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) - { - HandleGameObject(GO_IrisGUID, true, go); - if (Creature* c = go->SummonCreature(NPC_WORLD_TRIGGER_LAOI, *go, TEMPSUMMON_TIMED_DESPAWN, 10000)) - c->CastSpell(c, SPELL_IRIS_ACTIVATED, true); - } - break; - case DATA_HIDE_IRIS_AND_PORTAL: - if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) - go->SetPhaseMask(2, true); - if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) - go->SetPhaseMask(2, true); - break; - } - } - - bool SetBossState(uint32 type, EncounterState state) override - { - if (!InstanceScript::SetBossState(type, state)) - return false; - - if (type == DATA_MALYGOS) - { - switch (state) + case GO_IRIS_N: + case GO_IRIS_H: + GO_IrisGUID = go->GetGUID(); + if (GetBossState(DATA_MALYGOS) == DONE) + go->SetPhaseMask(2, true); + break; + case GO_EXIT_PORTAL: + GO_ExitPortalGUID = go->GetGUID(); + break; + case GO_NEXUS_PLATFORM: + GO_PlatformGUID = go->GetGUID(); + if (GetBossState(DATA_MALYGOS) == DONE) { - case NOT_STARTED: - bPokeAchiev = false; - if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) - { - go->SetPhaseMask(1, true); - HandleGameObject(GO_IrisGUID, false, go); - } - if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) - go->SetPhaseMask(1, true); - if (GameObject* go = instance->GetGameObject(GO_PlatformGUID)) - { - go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, nullptr, true); - go->EnableCollision(true); - } - break; - case IN_PROGRESS: - bPokeAchiev = (instance->GetPlayersCountExceptGMs() < (instance->GetSpawnMode() == 0 ? (uint32)9 : (uint32)21)); - break; - case DONE: - bPokeAchiev = false; - if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) - go->SetPhaseMask(1, true); - if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) - if (c->SummonCreature(NPC_ALEXSTRASZA, 798.0f, 1268.0f, 299.0f, 2.45f, TEMPSUMMON_TIMED_DESPAWN, 604800000)) - break; - break; - default: - break; + go->ModifyHealth(-int32(PLATFORM_DESTROY_DAMAGE)); + go->EnableCollision(false); } - } - - return true; + break; } + } - ObjectGuid GetGuidData(uint32 type) const override - { - switch (type) - { - case DATA_MALYGOS_GUID: - return NPC_MalygosGUID; - } - - return ObjectGuid::Empty; - } - - void ProcessEvent(WorldObject* /*unit*/, uint32 eventId) override - { - if (eventId == EVENT_IRIS_ACTIVATED) - if (GameObject* go = instance->GetGameObject(GO_PlatformGUID)) - if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) - { - go->ModifyHealth(-6500000, c); // We have HP 6 million in the database... So we have to do at least that - go->EnableCollision(false); - } - } - - bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* /*target*/, uint32 /*miscvalue1*/) override - { - switch (criteria_id) - { - case ACHIEV_CRITERIA_A_POKE_IN_THE_EYE_10: - case ACHIEV_CRITERIA_A_POKE_IN_THE_EYE_25: - return bPokeAchiev; - case ACHIEV_CRITERIA_DENYIN_THE_SCION_10: - case ACHIEV_CRITERIA_DENYIN_THE_SCION_25: - return (source && source->GetVehicle() && source->GetVehicle()->GetVehicleInfo()->m_ID == 224); - } - return false; - } - }; - - InstanceScript* GetInstanceScript(InstanceMap* map) const override + void SetData(uint32 type, uint32 /*data*/) override { - return new instance_eye_of_eternity_InstanceMapScript(map); + switch (type) + { + case DATA_IRIS_ACTIVATED: + if (GetBossState(DATA_MALYGOS) == NOT_STARTED) + if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) + if (Player* plr = c->SelectNearestPlayer(250.0f)) + c->AI()->AttackStart(plr); + break; + case DATA_SET_IRIS_INACTIVE: + if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) + { + HandleGameObject(GO_IrisGUID, true, go); + if (Creature* c = go->SummonCreature(NPC_WORLD_TRIGGER_LAOI, *go, TEMPSUMMON_TIMED_DESPAWN, 10000)) + c->CastSpell(c, SPELL_IRIS_ACTIVATED, true); + } + break; + case DATA_HIDE_IRIS_AND_PORTAL: + if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) + go->SetPhaseMask(2, true); + if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) + go->SetPhaseMask(2, true); + break; + } + } + + bool SetBossState(uint32 type, EncounterState state) override + { + if (!InstanceScript::SetBossState(type, state)) + return false; + + if (type == DATA_MALYGOS) + { + switch (state) + { + case NOT_STARTED: + bPokeAchiev = false; + if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) + { + go->SetPhaseMask(1, true); + HandleGameObject(GO_IrisGUID, false, go); + } + if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) + go->SetPhaseMask(1, true); + if (GameObject* go = instance->GetGameObject(GO_PlatformGUID)) + { + go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, nullptr, true); + go->EnableCollision(true); + } + break; + case IN_PROGRESS: + bPokeAchiev = (instance->GetPlayersCountExceptGMs() < (instance->GetSpawnMode() == 0 ? (uint32)9 : (uint32)21)); + break; + case DONE: + bPokeAchiev = false; + if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) + go->SetPhaseMask(1, true); + if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) + c->SummonCreature(NPC_ALEXSTRASZA, 798.0f, 1268.0f, 299.0f, 2.45f, TEMPSUMMON_MANUAL_DESPAWN); + break; + default: + break; + } + } + + return true; + } + + ObjectGuid GetGuidData(uint32 type) const override + { + switch (type) + { + case DATA_MALYGOS_GUID: + return NPC_MalygosGUID; + } + + return ObjectGuid::Empty; + } + + void ProcessEvent(WorldObject* /*unit*/, uint32 eventId) override + { + if (eventId == EVENT_IRIS_ACTIVATED) + if (GameObject* go = instance->GetGameObject(GO_PlatformGUID)) + if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) + { + go->ModifyHealth(-int32(PLATFORM_DESTROY_DAMAGE), c); + go->EnableCollision(false); + } + } + + bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* /*target*/, uint32 /*miscvalue1*/) override + { + switch (criteria_id) + { + case ACHIEV_CRITERIA_A_POKE_IN_THE_EYE_10: + case ACHIEV_CRITERIA_A_POKE_IN_THE_EYE_25: + return bPokeAchiev; + case ACHIEV_CRITERIA_DENYIN_THE_SCION_10: + case ACHIEV_CRITERIA_DENYIN_THE_SCION_25: + return source && source->GetVehicle() && source->GetVehicle()->GetVehicleInfo()->m_ID == 224; + } + return false; } }; void AddSC_instance_eye_of_eternity() { - new instance_eye_of_eternity(); + RegisterInstanceScript(instance_eye_of_eternity, MAP_THE_EYE_OF_ETERNITY); } From 8199d59b7e5f96ff8d15ea6130eb732745321ffb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 10 Feb 2026 03:27:24 +0000 Subject: [PATCH 079/335] chore(DB): import pending files Referenced commit(s): 5b278c7118b1e7342933686575b279dded45a7da --- .../rev_1770632566390126542.sql => db_world/2026_02_10_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1770632566390126542.sql => db_world/2026_02_10_02.sql} (81%) diff --git a/data/sql/updates/pending_db_world/rev_1770632566390126542.sql b/data/sql/updates/db_world/2026_02_10_02.sql similarity index 81% rename from data/sql/updates/pending_db_world/rev_1770632566390126542.sql rename to data/sql/updates/db_world/2026_02_10_02.sql index 96a723808..106b893e4 100644 --- a/data/sql/updates/pending_db_world/rev_1770632566390126542.sql +++ b/data/sql/updates/db_world/2026_02_10_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_10_01 -> 2026_02_10_02 -- DELETE FROM `spell_group_stack_rules` WHERE `group_id` = 1114; INSERT INTO `spell_group_stack_rules` (`group_id`,`stack_rule`, `description`) VALUES (1114, 1, 'Love is in the Air Flasks'); From 125f6cb748e0f7fb96e630fea79d029cb33718c9 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 10 Feb 2026 00:27:42 -0300 Subject: [PATCH 080/335] =?UTF-8?q?fix(Scripts/Naxxramas):=20Thaddius=20ca?= =?UTF-8?q?sting=20Ball=20Lightning=20shouldn't=20pr=E2=80=A6=20(#24624)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Northrend/Naxxramas/boss_thaddius.cpp | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp index d2e7dd1da..7fb48d6d1 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp @@ -92,9 +92,8 @@ enum Events EVENT_THADDIUS_INIT = 5, EVENT_THADDIUS_ENTER_COMBAT = 6, EVENT_THADDIUS_CHAIN_LIGHTNING = 7, - EVENT_THADDIUS_BERSERK = 8, - EVENT_THADDIUS_POLARITY_SHIFT = 9, - EVENT_ALLOW_BALL_LIGHTNING = 10 + EVENT_THADDIUS_POLARITY_SHIFT = 8, + EVENT_ALLOW_BALL_LIGHTNING = 9 }; enum Misc @@ -119,11 +118,9 @@ public: struct boss_thaddiusAI : public BossAI { - explicit boss_thaddiusAI(Creature* c) : BossAI(c, BOSS_THADDIUS), summons(me), ballLightningEnabled(false) + explicit boss_thaddiusAI(Creature* c) : BossAI(c, BOSS_THADDIUS), ballLightningEnabled(false) {} - EventMap events; - SummonList summons; uint32 summonTimer{}; uint32 reviveTimer{}; uint32 resetTimer{}; @@ -238,7 +235,7 @@ public: if (resetTimer > 1000) { resetTimer = 0; - me->CastSpell(me, SPELL_THADDIUS_SPAWN_STUN, true); + DoCastSelf(SPELL_THADDIUS_SPAWN_STUN, true); } return; } @@ -247,17 +244,15 @@ public: reviveTimer += diff; if (reviveTimer >= 12000) { - for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) + summons.DoForAllSummons([this](WorldObject* summon) { - if (Creature* cr = ObjectAccessor::GetCreature(*me, (*itr))) + if (summon->GetEntry() == NPC_TESLA_COIL) { - if (cr->GetEntry() == NPC_TESLA_COIL) - { - cr->AI()->Talk(EMOTE_TESLA_OVERLOAD); - cr->CastSpell(me, SPELL_SHOCK_VISUAL, true); - } + summon->ToCreature()->AI()->Talk(EMOTE_TESLA_OVERLOAD); + summon->ToCreature()->CastSpell(me, SPELL_SHOCK_VISUAL, true); } - } + }); + reviveTimer = 0; events.ScheduleEvent(EVENT_THADDIUS_INIT, 750ms); } @@ -268,8 +263,6 @@ public: return; events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; if (summonTimer) // Revive { @@ -287,25 +280,19 @@ public: { me->RemoveAllAuras(); me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) + summons.DoForAllSummons([](WorldObject* summon) { - if (Creature* cr = ObjectAccessor::GetCreature(*me, (*itr))) - { - if (cr->GetEntry() == NPC_TESLA_COIL) - { - Unit::Kill(cr, cr); - } - } - } + if (summon->GetEntry() == NPC_TESLA_COIL) + summon->ToCreature()->KillSelf(); + }); + if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_LEFT, 100.0f)) - { go->SetGoState(GO_STATE_READY); - } + if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_RIGHT, 100.0f)) - { go->SetGoState(GO_STATE_READY); - } - me->CastSpell(me, SPELL_THADDIUS_VISUAL_LIGHTNING, true); + + DoCastSelf(SPELL_THADDIUS_VISUAL_LIGHTNING, true); events.ScheduleEvent(EVENT_THADDIUS_ENTER_COMBAT, 1s); break; } @@ -316,19 +303,32 @@ public: me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); me->SetControlled(false, UNIT_STATE_ROOT); events.ScheduleEvent(EVENT_THADDIUS_CHAIN_LIGHTNING, 14s); - events.ScheduleEvent(EVENT_THADDIUS_BERSERK, 6min); events.ScheduleEvent(EVENT_THADDIUS_POLARITY_SHIFT, 20s); events.ScheduleEvent(EVENT_ALLOW_BALL_LIGHTNING, 5s); + ScheduleEnrageTimer(SPELL_BERSERK, 6min); return; - case EVENT_THADDIUS_BERSERK: - me->CastSpell(me, SPELL_BERSERK, true); - break; case EVENT_THADDIUS_CHAIN_LIGHTNING: - me->CastSpell(me->GetVictim(), SPELL_CHAIN_LIGHTNING, false); + if (me->HasUnitState(UNIT_STATE_CASTING)) + { + events.Repeat(1s); + ballLightningEnabled = false; + return; + } + + DoCastVictim(SPELL_CHAIN_LIGHTNING); + events.ScheduleEvent(EVENT_ALLOW_BALL_LIGHTNING, 1s); events.Repeat(15s); break; case EVENT_THADDIUS_POLARITY_SHIFT: - me->CastSpell(me, SPELL_POLARITY_SHIFT, false); + if (me->HasUnitState(UNIT_STATE_CASTING)) + { + events.Repeat(1s); + ballLightningEnabled = false; + return; + } + + DoCastAOE(SPELL_POLARITY_SHIFT); + events.ScheduleEvent(EVENT_ALLOW_BALL_LIGHTNING, 3s); events.Repeat(30s); break; case EVENT_ALLOW_BALL_LIGHTNING: @@ -338,7 +338,7 @@ public: if (IsAnyPlayerInMeleeRange()) DoMeleeAttackIfReady(); - else if (ballLightningEnabled && !IsAnyPlayerInMeleeRange()) + else if (ballLightningEnabled && !IsAnyPlayerInMeleeRange() && !me->HasUnitState(UNIT_STATE_CASTING)) if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat)) me->CastSpell(target, SPELL_BALL_LIGHTNING, false); } From fb2a3b2fbf0492fdd180e7ea62aab5a2d64f77a2 Mon Sep 17 00:00:00 2001 From: sogladev Date: Tue, 10 Feb 2026 04:28:12 +0100 Subject: [PATCH 081/335] fix(DB/Vendor): Updates vendor lists for reagents and poisons (#24594) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../rev_1770051839734739329.sql | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770051839734739329.sql diff --git a/data/sql/updates/pending_db_world/rev_1770051839734739329.sql b/data/sql/updates/pending_db_world/rev_1770051839734739329.sql new file mode 100644 index 000000000..bceab1daa --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770051839734739329.sql @@ -0,0 +1,82 @@ +-- +-- 'Jeeves' +-- 'Scrapbot' +-- Add Mind-numbing Poison and limited poisons +SET @INCRTIME := 600; +DELETE FROM `npc_vendor` WHERE (`entry` IN (29561, 35642)) AND (`item` IN (43233, 43235, 43237, 3775, 5237, 43231)); +INSERT INTO `npc_vendor` (`entry`, `slot`, `item`, `maxcount`, `incrtime`, `ExtendedCost`, `VerifiedBuild`) VALUES +(29561, 0, 43233, 30, @INCRTIME, 0, 0), +(29561, 0, 43235, 30, @INCRTIME, 0, 0), +(29561, 0, 43237, 10, @INCRTIME, 0, 0), +(29561, 0, 3775, 10, @INCRTIME, 0, 0), +(29561, 0, 5237, 0, 0, 0, 0), +(29561, 0, 43231, 30, @INCRTIME, 0, 0), +(35642, 0, 43233, 30, @INCRTIME, 0, 0), +(35642, 0, 43235, 30, @INCRTIME, 0, 0), +(35642, 0, 43237, 10, @INCRTIME, 0, 0), +(35642, 0, 3775, 10, @INCRTIME, 0, 0), +(35642, 0, 5237, 0, 0, 0, 0), +(35642, 0, 43231, 30, @INCRTIME, 0, 0); + +-- Remove 'Simple Wood' +DELETE FROM `npc_vendor` WHERE (`entry` IN (32639, 32641, 30438, 30345, 30825, 31115)) AND (`item` = 4470); + +-- Add 'Wild Spineleaf', 'Starleaf Seed', and 'Devout Candle' +DELETE FROM `npc_vendor` WHERE (`entry` IN (1257, 1275, 1308, 1351, 3335, 3351, 3562, 4220, 4575, 5110, 5151, 16612, 16706, 16757)) AND (`item` IN (44605, 44614, 44615)); +INSERT INTO `npc_vendor` (`entry`, `slot`, `item`, `maxcount`, `incrtime`, `ExtendedCost`, `VerifiedBuild`) VALUES +-- 'Keldric Boucher ' +(1257, 0, 44605, 0, 0, 0, 0), +(1257, 0, 44614, 0, 0, 0, 0), +(1257, 0, 44615, 0, 0, 0, 0), +-- 'Kyra Boucher ' +(1275, 0, 44605, 0, 0, 0, 0), +(1275, 0, 44614, 0, 0, 0, 0), +(1275, 0, 44615, 0, 0, 0, 0), +-- 'Owen Vaughn ' +(1308, 0, 44605, 0, 0, 0, 0), +(1308, 0, 44614, 0, 0, 0, 0), +(1308, 0, 44615, 0, 0, 0, 0), +-- 'Brother Cassius ' +(1351, 0, 44605, 0, 0, 0, 0), +(1351, 0, 44614, 0, 0, 0, 0), +(1351, 0, 44615, 0, 0, 0, 0), +-- 'Hagrus ' +(3335, 0, 44605, 0, 0, 0, 0), +(3335, 0, 44614, 0, 0, 0, 0), +(3335, 0, 44615, 0, 0, 0, 0), +-- 'Magenius ' +(3351, 0, 44605, 0, 0, 0, 0), +(3351, 0, 44614, 0, 0, 0, 0), +(3351, 0, 44615, 0, 0, 0, 0), +-- 'Alaindia ' +(3562, 0, 44605, 0, 0, 0, 0), +(3562, 0, 44614, 0, 0, 0, 0), +(3562, 0, 44615, 0, 0, 0, 0), +-- 'Cyroen ' +(4220, 0, 44605, 0, 0, 0, 0), +(4220, 0, 44614, 0, 0, 0, 0), +(4220, 0, 44615, 0, 0, 0, 0), +-- 'Hannah Akeley ' +(4575, 0, 44605, 0, 0, 0, 0), +(4575, 0, 44614, 0, 0, 0, 0), +(4575, 0, 44615, 0, 0, 0, 0), +-- 'Barim Jurgenstaad ' +(5110, 0, 44605, 0, 0, 0, 0), +(5110, 0, 44614, 0, 0, 0, 0), +(5110, 0, 44615, 0, 0, 0, 0), +-- 'Ginny Longberry ' +(5151, 0, 44605, 0, 0, 0, 0), +(5151, 0, 44614, 0, 0, 0, 0), +(5151, 0, 44615, 0, 0, 0, 0), +-- 'Velanni ' +(16612, 0, 44605, 0, 0, 0, 0), +(16612, 0, 44614, 0, 0, 0, 0), +(16612, 0, 44615, 0, 0, 0, 0), +-- 'Musal ' +(16706, 0, 44605, 0, 0, 0, 0), +(16706, 0, 44614, 0, 0, 0, 0), +(16706, 0, 44615, 0, 0, 0, 0), +-- 'Bildine ' +(16757, 0, 44605, 0, 0, 0, 0), +(16757, 0, 44614, 0, 0, 0, 0), +(16757, 0, 44615, 0, 0, 0, 0); From 22cf31365e8430bd41b383b8d7f292086d2ac72f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 10 Feb 2026 03:28:21 +0000 Subject: [PATCH 082/335] chore(DB): import pending files Referenced commit(s): 4c1e559f5428e0fc7672d17bc96e26578472f0ed --- .../rev_1770051839734739329.sql => db_world/2026_02_10_03.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1770051839734739329.sql => db_world/2026_02_10_03.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1770051839734739329.sql b/data/sql/updates/db_world/2026_02_10_03.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1770051839734739329.sql rename to data/sql/updates/db_world/2026_02_10_03.sql index bceab1daa..45b82325f 100644 --- a/data/sql/updates/pending_db_world/rev_1770051839734739329.sql +++ b/data/sql/updates/db_world/2026_02_10_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_10_02 -> 2026_02_10_03 -- -- 'Jeeves' -- 'Scrapbot' From f0e5f32b4e7c769ff0cae76391d16f46207051b2 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Mon, 9 Feb 2026 21:28:44 -0600 Subject: [PATCH 083/335] fix(Core/Battlegrounds): remove unused ApplyPhaseMask from Arathi Basin (#24582) Co-authored-by: blinkysc --- .../Battlegrounds/Zones/BattlegroundAB.cpp | 21 +------------------ .../game/Battlegrounds/Zones/BattlegroundAB.h | 1 - 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index cff3ec3ff..ca02782cc 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -180,9 +180,8 @@ void BattlegroundAB::AddPlayer(Player* player) PlayerScores.emplace(player->GetGUID().GetCounter(), new BattlegroundABScore(player->GetGUID())); } -void BattlegroundAB::RemovePlayer(Player* player) +void BattlegroundAB::RemovePlayer(Player* /*player*/) { - player->SetPhaseMask(1, false); } void BattlegroundAB::HandleAreaTrigger(Player* player, uint32 trigger) @@ -269,7 +268,6 @@ void BattlegroundAB::SendNodeUpdate(uint8 node) void BattlegroundAB::NodeOccupied(uint8 node) { - ApplyPhaseMask(); AddSpiritGuide(node, BG_AB_SpiritGuidePos[node][0], BG_AB_SpiritGuidePos[node][1], BG_AB_SpiritGuidePos[node][2], BG_AB_SpiritGuidePos[node][3], _capturePointInfo[node]._ownerTeamId); ++_controlledPoints[_capturePointInfo[node]._ownerTeamId]; @@ -392,7 +390,6 @@ void BattlegroundAB::EventPlayerClickedOnFlag(Player* player, GameObject* gameOb _capturePointInfo[node]._state = static_cast(BG_AB_NODE_STATE_ALLY_CONTESTED) + player->GetTeamId(); - ApplyPhaseMask(); _bgEvents.RescheduleEvent(BG_AB_EVENT_CAPTURE_STABLE + node, BG_AB_FLAG_CAPTURING_TIME); sound = player->GetTeamId() == TEAM_ALLIANCE ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE; @@ -547,19 +544,3 @@ bool BattlegroundAB::AllNodesConrolledByTeam(TeamId teamId) const { return _controlledPoints[teamId] == BG_AB_DYNAMIC_NODES_COUNT; } - -void BattlegroundAB::ApplyPhaseMask() -{ - uint32 phaseMask = 1; - for (uint32 i = BG_AB_NODE_STABLES; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) - if (_capturePointInfo[i]._ownerTeamId != TEAM_NEUTRAL) - phaseMask |= 1 << (i * 2 + 1 + _capturePointInfo[i]._ownerTeamId); - - const BattlegroundPlayerMap& bgPlayerMap = GetPlayers(); - - for (auto const& itr : bgPlayerMap) - { - itr.second->SetPhaseMask(phaseMask, false); - itr.second->UpdateObjectVisibility(true, false); - } -} diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h index 72932386a..230292aa4 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h @@ -278,7 +278,6 @@ private: void SendNodeUpdate(uint8 node); void NodeOccupied(uint8 node); void NodeDeoccupied(uint8 node); - void ApplyPhaseMask(); struct CapturePointInfo { From c73cf6b0199d7c2932d87ba76a56278f4da1beca Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Mon, 9 Feb 2026 22:28:59 -0500 Subject: [PATCH 084/335] feat(Core/Handlers): Make use of a few billing plan flags for authentication response. (#24569) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/server/game/Handlers/AuthHandler.cpp | 8 +++--- src/server/game/Server/WorldSession.cpp | 31 ++++++++++++++++++++++++ src/server/game/Server/WorldSession.h | 5 ++++ src/server/game/World/World.h | 12 ++++----- 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/server/game/Handlers/AuthHandler.cpp b/src/server/game/Handlers/AuthHandler.cpp index 52dcffdec..99506a786 100644 --- a/src/server/game/Handlers/AuthHandler.cpp +++ b/src/server/game/Handlers/AuthHandler.cpp @@ -23,10 +23,10 @@ void WorldSession::SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos) { WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1 + (shortForm ? 0 : (4 + 1))); packet << uint8(code); - packet << uint32(0); // BillingTimeRemaining - packet << uint8(0); // BillingPlanFlags - packet << uint32(0); // BillingTimeRested - uint8 exp = Expansion(); // 0 - normal, 1 - TBC, 2 - WOTLK, must be set in database manually for each account + packet << uint32(0); // BillingTimeRemaining + packet << GetBillingPlanFlags(); + packet << uint32(0); // BillingTimeRested + uint8 exp = Expansion(); // 0 - normal, 1 - TBC, 2 - WotLK, must be set in database manually for each account if (exp >= MAX_EXPANSIONS) exp = MAX_EXPANSIONS - 1; diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 254328b80..208835067 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -208,6 +208,37 @@ bool WorldSession::IsGMAccount() const return GetSecurity() >= SEC_GAMEMASTER; } +bool WorldSession::IsTrialAccount() const +{ + return HasAccountFlag(ACCOUNT_FLAG_TRIAL); +} + +bool WorldSession::IsInternetGameRoomAccount() const +{ + return HasAccountFlag(ACCOUNT_FLAG_IGR); +} + +bool WorldSession::IsRecurringBillingAccount() const +{ + return HasAccountFlag(ACCOUNT_FLAG_RECURRING_BILLING); +} + +uint8 WorldSession::GetBillingPlanFlags() const +{ + uint8 flags = SESSION_NONE; + + if (IsRecurringBillingAccount()) + flags |= SESSION_RECURRING_BILL; + + if (IsTrialAccount()) + flags |= SESSION_FREE_TRIAL; + + if (IsInternetGameRoomAccount()) + flags |= SESSION_IGR; + + return flags; +} + std::string const& WorldSession::GetPlayerName() const { return _player ? _player->GetName() : DefaultPlayerName; diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 6a1c554ca..4a113d881 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -383,6 +383,11 @@ public: void ValidateAccountFlags(); bool IsGMAccount() const; + bool IsTrialAccount() const; + bool IsInternetGameRoomAccount() const; + bool IsRecurringBillingAccount() const; + + uint8 GetBillingPlanFlags() const; bool PlayerLoading() const { return m_playerLoading; } bool PlayerLogout() const { return m_playerLogout; } diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 942665b4d..d792b4d8c 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -73,14 +73,14 @@ enum WorldTimers enum BillingPlanFlags { SESSION_NONE = 0x00, - SESSION_UNUSED = 0x01, + SESSION_UNUSED = 0x01, // Unk, NYI SESSION_RECURRING_BILL = 0x02, SESSION_FREE_TRIAL = 0x04, - SESSION_IGR = 0x08, - SESSION_USAGE = 0x10, - SESSION_TIME_MIXTURE = 0x20, - SESSION_RESTRICTED = 0x40, - SESSION_ENABLE_CAIS = 0x80, + SESSION_IGR = 0x08, // Internet Game Room + SESSION_USAGE = 0x10, // Unk, NYI + SESSION_TIME_MIXTURE = 0x20, // Unk, NYI + SESSION_RESTRICTED = 0x40, // Unk, NYI + SESSION_ENABLE_CAIS = 0x80, // Unk, NYI, possibly account play time limit related for China? }; enum RealmZone From a890f55b5506bfcb4b5a70ec9da970c1833113d2 Mon Sep 17 00:00:00 2001 From: sogladev Date: Tue, 10 Feb 2026 13:42:43 +0100 Subject: [PATCH 085/335] fix(Core/Creature): implement SUMMON_PROP_FLAG_USE_SUMMONER_FACTION (#24674) --- src/server/game/Entities/Creature/TemporarySummon.cpp | 5 +++++ src/server/shared/DataStores/DBCEnums.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp index 6d9049558..5eceb9e53 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.cpp +++ b/src/server/game/Entities/Creature/TemporarySummon.cpp @@ -245,6 +245,11 @@ void TempSummon::InitStats(uint32 duration) if (m_Properties->Faction) SetFaction(m_Properties->Faction); + else if (m_Properties->Flags & SUMMON_PROP_FLAG_USE_SUMMONER_FACTION) + { + if (owner) + SetFaction(owner->GetFaction()); + } else if (IsVehicle() && owner) // properties should be vehicle SetFaction(owner->GetFaction()); } diff --git a/src/server/shared/DataStores/DBCEnums.h b/src/server/shared/DataStores/DBCEnums.h index 9d73f761e..c33b862c7 100644 --- a/src/server/shared/DataStores/DBCEnums.h +++ b/src/server/shared/DataStores/DBCEnums.h @@ -433,7 +433,7 @@ enum SummonPropFlags SUMMON_PROP_FLAG_JOIN_SUMMONER_SPAWN_GROUP = 0x00000200, /// @todo: NYI 51 spells in 3.0.3, something defensive SUMMON_PROP_FLAG_DO_NOT_TOGGLE = 0x00000400, /// @todo: NYI 3 spells, requires something near? SUMMON_PROP_FLAG_DESPAWN_WHEN_EXPIRED = 0x00000800, /// @todo: NYI 30 spells in 3.0.3, no idea - SUMMON_PROP_FLAG_USE_SUMMONER_FACTION = 0x00001000, /// @todo: NYI Lightwell, Jeeves, Gnomish Alarm-o-bot, Build vehicles(wintergrasp) + SUMMON_PROP_FLAG_USE_SUMMONER_FACTION = 0x00001000, /// Lightwell, Jeeves, Gnomish Alarm-o-bot, Build vehicles(wintergrasp) SUMMON_PROP_FLAG_DO_NOT_FOLLOW_MOUNTED_SUMMONER = 0x00002000, /// @todo: NYI Guides, player follows SUMMON_PROP_FLAG_SAVE_PET_AUTOCAST = 0x00004000, /// @todo: NYI Force of Nature, Shadowfiend, Feral Spirit, Summon Water Elemental SUMMON_PROP_FLAG_IGNORE_SUMMONER_PHASE = 0x00008000, /// @todo: NYI Light/Dark Bullet, Soul/Fiery Consumption, Twisted Visage, Twilight Whelp. Phase related? From 48223145ebd3acc108e5f87982764ae5ddc1b948 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Wed, 11 Feb 2026 02:32:46 -0500 Subject: [PATCH 086/335] fix(DB/Creature): Adjust unit flags for Lightwell creature. (#24678) --- data/sql/updates/pending_db_world/lightwell-unit-flags.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 data/sql/updates/pending_db_world/lightwell-unit-flags.sql diff --git a/data/sql/updates/pending_db_world/lightwell-unit-flags.sql b/data/sql/updates/pending_db_world/lightwell-unit-flags.sql new file mode 100644 index 000000000..97ff71cea --- /dev/null +++ b/data/sql/updates/pending_db_world/lightwell-unit-flags.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `unit_flags` = 520, `unit_flags2` = 32 WHERE `entry` IN (31883, 31893, 31894, 31895, 31896, 31897); From f9de1062306a48eb165b2d6b78d2ce4c4751e42f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 11 Feb 2026 07:33:52 +0000 Subject: [PATCH 087/335] chore(DB): import pending files Referenced commit(s): 48223145ebd3acc108e5f87982764ae5ddc1b948 --- .../lightwell-unit-flags.sql => db_world/2026_02_11_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/lightwell-unit-flags.sql => db_world/2026_02_11_00.sql} (74%) diff --git a/data/sql/updates/pending_db_world/lightwell-unit-flags.sql b/data/sql/updates/db_world/2026_02_11_00.sql similarity index 74% rename from data/sql/updates/pending_db_world/lightwell-unit-flags.sql rename to data/sql/updates/db_world/2026_02_11_00.sql index 97ff71cea..c785d0ecf 100644 --- a/data/sql/updates/pending_db_world/lightwell-unit-flags.sql +++ b/data/sql/updates/db_world/2026_02_11_00.sql @@ -1 +1,2 @@ +-- DB update 2026_02_10_03 -> 2026_02_11_00 UPDATE `creature_template` SET `unit_flags` = 520, `unit_flags2` = 32 WHERE `entry` IN (31883, 31893, 31894, 31895, 31896, 31897); From b2d212c0a160fe51cafba9fbbb7329bf66235efd Mon Sep 17 00:00:00 2001 From: sogladev Date: Wed, 11 Feb 2026 08:34:18 +0100 Subject: [PATCH 088/335] fix(Core/Spells): Lady Blaumeux and Sir Zeliek's cast uninterruptable (#24534) --- src/server/game/Spells/SpellInfoCorrections.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index 382a423f1..3abafbc05 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -5190,6 +5190,16 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Effects[EFFECT_0].MiscValueB = 64; }); + ApplySpellFix({ + 57374, // Shadow Bolt (Lady Blaumeux 10m) + 57464, // Shadow Bolt (Lady Blaumeux 25m) + 57376, // Holy Bolt (Sir Zeliek 10m) + 57465, // Holy Bolt (Sir Zeliek 25m) + }, [](SpellInfo* spellInfo) + { + spellInfo->InterruptFlags &= ~SPELL_INTERRUPT_FLAG_INTERRUPT; + }); + for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i) { SpellInfo* spellInfo = mSpellInfoMap[i]; From d597e4590b41d81e16103e578d41079f7b84b3f0 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Wed, 11 Feb 2026 14:49:29 -0300 Subject: [PATCH 089/335] fix(DB/Creature): Improve Stockades Entrance (#24676) Co-authored-by: sudlud --- .../rev_1770753510757017400.sql | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770753510757017400.sql diff --git a/data/sql/updates/pending_db_world/rev_1770753510757017400.sql b/data/sql/updates/pending_db_world/rev_1770753510757017400.sql new file mode 100644 index 000000000..a1d830ffb --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770753510757017400.sql @@ -0,0 +1,107 @@ +-- Pathing for Entry: 5042 +SET @NPC := 90458; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `wander_distance`=0,`MovementType`=2,`position_x`=-8760.21,`position_y`=811.9198,`position_z`=97.793724 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`visibilityDistanceType`,`auras`) VALUES (@NPC,@PATH,0,0,1,0,0, ''); +DELETE FROM `waypoint_data` WHERE `id`=@PATH; +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH,1,-8760.21,811.9198,97.793724,NULL,0,0,0,100,0), +(@PATH,2,-8763.192,810.93536,97.74572,NULL,0,0,0,100,0), +(@PATH,3,-8763.192,810.93536,97.74572,2.199114799499511718,12000,0,0,100,0), +(@PATH,4,-8769.179,814.3151,97.8737,NULL,0,0,0,100,0), +(@PATH,5,-8755.52,814.1872,97.88151,NULL,0,0,0,100,0), +(@PATH,6,-8755.52,814.1872,97.88151,3.839724302291870117,12000,0,0,100,0), +(@PATH,7,-8766.348,820.14746,97.870056,NULL,0,0,0,100,0), +(@PATH,8,-8766.348,820.14746,97.870056,3.874630928039550781,12000,0,0,100,0); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 5042; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 5042); +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 +(5042, 0, 0, 0, 108, 0, 100, 0, 3, 0, 0, 0, 0, 0, 80, 504200, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nurse Lillian - On Point 3 of Path Any Reached - Run Script'), +(5042, 0, 1, 0, 108, 0, 100, 0, 6, 0, 0, 0, 0, 0, 80, 504200, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nurse Lillian - On Point 6 of Path Any Reached - Run Script'), +(5042, 0, 2, 0, 108, 0, 100, 0, 8, 0, 0, 0, 0, 0, 80, 504200, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nurse Lillian - On Point 8 of Path Any Reached - Run Script'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 504200); +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 +(504200, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 90, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nurse Lillian - Actionlist - Set Flag Standstate Kneel'), +(504200, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nurse Lillian - Actionlist - Say Line'); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 5042); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(5042, 0, 0, 'You\'re going to be just fine.', 12, 7, 100, 1, 0, 0, 1682, 0, 'Nurse Lillian'), +(5042, 0, 1, 'Drink this, it will help.', 12, 7, 100, 1, 0, 0, 1679, 0, 'Nurse Lillian'), +(5042, 0, 2, 'Let me help you with those.', 12, 7, 100, 1, 0, 0, 1685, 0, 'Nurse Lillian'), +(5042, 0, 3, 'Feeling better I see.', 12, 7, 100, 1, 0, 0, 1678, 0, 'Nurse Lillian'), +(5042, 0, 4, 'Some of this ointment should help.', 12, 7, 100, 1, 0, 0, 1681, 0, 'Nurse Lillian'), +(5042, 0, 5, 'Take this, drink it down.', 12, 7, 100, 1, 0, 0, 1683, 0, 'Nurse Lillian'), +(5042, 0, 6, 'This should ease the pain.', 12, 7, 100, 1, 0, 0, 1680, 0, 'Nurse Lillian'), +(5042, 0, 7, 'You will keep all your fingers and toes, not to worry.', 12, 7, 100, 1, 0, 0, 1684, 0, 'Nurse Lillian'), +(5042, 0, 8, 'You\'re going to be just fine.', 12, 7, 100, 1, 0, 0, 1682, 0, 'Nurse Lillian'); + +SET @GUID := 12837; + +DELETE FROM `creature` WHERE `guid` BETWEEN @GUID AND @GUID+13 AND `id1` IN (5043, 4996, 6237, 4995); +DELETE FROM `creature` WHERE `guid` IN (79522,79550,79558,79580,90453,90454,90455,90456,90457,90472,90473,90474,90475,120726,120727,120728,120756,120757,120758,120759,120762) AND `id1` IN (5043, 4996, 6237, 4995); +INSERT INTO `creature` (`guid`, `id1`, `map`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(@GUID+0 , 4996, 0, 0, -8757.4443359375, 812.39703369140625, 97.71795654296875, 2.286381244659423828, 120, 45327, 1, ''), +(@GUID+1 , 4996, 0, 0, -8762.8095703125, 812.35577392578125, 97.71795654296875, 0.715584993362426757, 120, 45327, 1, ''), +(@GUID+2 , 4996, 0, 0, -8756.3095703125, 813.4608154296875, 97.71795654296875, 2.443460941314697265, 120, 45327, 1, ''), +(@GUID+3 , 4996, 0, 0, -8767.583984375, 819.58966064453125, 97.71795654296875, 5.009094715118408203, 120, 45327, 1, ''), +(@GUID+4 , 4996, 0, 0, -8764.927734375, 815.26214599609375, 97.71795654296875, 0.593411922454833984, 120, 45327, 1, ''), +(@GUID+5 , 4996, 0, 0, -8763.865234375, 813.7657470703125, 97.71795654296875, 0.645771801471710205, 120, 45327, 1, ''), +(@GUID+6 , 6237, 0, 1, -8779.48828125, 823.29180908203125, 97.71795654296875, 1.471759438514709472, 120, 45327, 1, ''), +(@GUID+7 , 6237, 0, 1, -8791.2314453125, 835.568603515625, 97.71795654296875, 6.113029003143310546, 120, 45327, 1, ''), +(@GUID+8 , 6237, 0, 1, -8792.388671875, 831.44061279296875, 97.72733306884765625, 0.211701273918151855, 120, 45327, 1, ''), +(@GUID+9 , 6237, 0, 1, -8786.2099609375, 822.29278564453125, 97.7254180908203125, 1.109707117080688476, 120, 45327, 1, ''), +(@GUID+10, 4995, 0, 1, -8785.0107421875, 826.6419677734375, 97.75400543212890625, 0.820304751396179199, 120, 45327, 1, ''), +(@GUID+11, 4995, 0, 1, -8782.9091796875, 826.6568603515625, 97.57006072998046875, 1.064650893211364746, 120, 45327, 1, ''), +(@GUID+12, 4995, 0, 1, -8787.681640625, 832.94757080078125, 97.455596923828125, 0.261799395084381103, 120, 45327, 1, ''), +(@GUID+13, 4995, 0, 1, -8787.1953125, 829.95263671875, 97.75400543212890625, 0.796267867088317871, 120, 45327, 1, ''); + +DELETE FROM `creature_formations` WHERE (`leaderGUID` = @GUID+3); +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(@GUID+3, @GUID+0, 0, 0, 3, 0, 0), +(@GUID+3, @GUID+1, 0, 0, 3, 0, 0), +(@GUID+3, @GUID+2, 0, 0, 3, 0, 0), +(@GUID+3, @GUID+3, 0, 0, 3, 0, 0), +(@GUID+3, @GUID+4, 0, 0, 3, 0, 0), +(@GUID+3, @GUID+5, 0, 0, 3, 0, 0), +(@GUID+3, @GUID+6, 0, 0, 3, 0, 0), +(@GUID+3, @GUID+7, 0, 0, 3, 0, 0); + +UPDATE `creature` SET `position_x` = -8799.5703125, `position_y` = 828.39599609375, `position_z` = 97.753997802734375, `orientation` = 0.9686967134475708, `CreateObject` = 1, `VerifiedBuild` = 45327 WHERE `guid` = 89325 AND `id1` = 1719; + +DELETE FROM `creature_addon` WHERE (`guid` IN (79522, 79550, 79558, 79580, 90457)); +DELETE FROM `creature_addon` WHERE (`guid` BETWEEN @GUID AND @GUID+13); +INSERT INTO `creature_addon` (`guid`, `bytes1`) VALUES +(@GUID+0, 1), +(@GUID+1, 3), +(@GUID+2, 1), +(@GUID+3, 1), +(@GUID+4, 3), +(@GUID+5, 3); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 6237; +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 6237) AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(6237, 0, 0, 0, 0, 0, 100, 0, 0, 3000, 3000, 6000, 0, 0, 11, 6660, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Stockade Archer - In Combat - Cast \'Shoot\''); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 1719); +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 +(1719, 0, 0, 0, 1, 0, 100, 0, 0, 0, 20000, 43000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Warden Thelwater - Out of Combat - Say Line'), +(1719, 0, 1, 0, 1, 0, 100, 512, 0, 0, 1800000, 1800000, 0, 0, 107, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Warden Thelwater - Out of Combat - Summon Creature Group \'Defias Rioter\''), +(1719, 0, 2, 0, 17, 0, 100, 512, 5043, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, -8785.28, 829.17, 97.5, 0, 'Warden Thelwater - On Summoned Unit - Move To Position'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 171900); + +DELETE FROM `creature_summon_groups` WHERE `summonerId` = 1719 AND `summonerType` = 0 AND `entry` = 5043; +INSERT INTO `creature_summon_groups` (`summonerId`, `summonerType`, `groupId`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `summonType`, `summonTime`, `Comment`) VALUES +(1719, 0, 0, 5043, -8762.42578125, 842.49249267578125, 87.6991729736328125, 0.942477762699127197, 4, 30000, 'Defias Rioter'), +(1719, 0, 0, 5043, -8763.640625, 843.8431396484375, 87.74048614501953125, 1.134464025497436523, 4, 30000, 'Defias Rioter'), +(1719, 0, 0, 5043, -8763.9404296875, 842.83203125, 88.064422607421875, 5.497786998748779296, 4, 30000, 'Defias Rioter'), +(1719, 0, 0, 5043, -8764.96484375, 845.6055908203125, 87.71747589111328125, 3.228859186172485351, 4, 30000, 'Defias Rioter'), +(1719, 0, 0, 5043, -8765.03125, 843.9947509765625, 88.11328125, 0.331612557172775268, 4, 30000, 'Defias Rioter'), +(1719, 0, 0, 5043, -8766.08203125, 846.09759521484375, 87.93059539794921875, 5.567600250244140625, 4, 30000, 'Defias Rioter'), +(1719, 0, 0, 5043, -8766.8154296875, 848.52008056640625, 87.59954071044921875, 4.433136463165283203, 4, 30000, 'Defias Rioter'), +(1719, 0, 0, 5043, -8766.833984375, 846.41839599609375, 88.07654571533203125, 3.647738218307495117, 4, 30000, 'Defias Rioter'); From fb1d6d973964cd12fd06cd64ef476ef81912a222 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 11 Feb 2026 17:50:41 +0000 Subject: [PATCH 090/335] chore(DB): import pending files Referenced commit(s): d597e4590b41d81e16103e578d41079f7b84b3f0 --- .../rev_1770753510757017400.sql => db_world/2026_02_11_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1770753510757017400.sql => db_world/2026_02_11_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1770753510757017400.sql b/data/sql/updates/db_world/2026_02_11_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1770753510757017400.sql rename to data/sql/updates/db_world/2026_02_11_01.sql index a1d830ffb..279bb6bf3 100644 --- a/data/sql/updates/pending_db_world/rev_1770753510757017400.sql +++ b/data/sql/updates/db_world/2026_02_11_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_11_00 -> 2026_02_11_01 -- Pathing for Entry: 5042 SET @NPC := 90458; SET @PATH := @NPC * 10; From 2520bed648a1e15b5837d355f7ec4faf4d9bdbc4 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Thu, 12 Feb 2026 09:53:04 -0300 Subject: [PATCH 091/335] fix(DB/Creature): Reduce General Lightsbane (29851) default DamageModifier (#24682) --- data/sql/updates/pending_db_world/rev_1770862687925401600.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770862687925401600.sql diff --git a/data/sql/updates/pending_db_world/rev_1770862687925401600.sql b/data/sql/updates/pending_db_world/rev_1770862687925401600.sql new file mode 100644 index 000000000..ad2e55784 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770862687925401600.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template` SET `DamageModifier` = 1.5 WHERE (`entry` = 29851); From fe1296c3ec047c71cb725b164954e7c4d4b2e366 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 12 Feb 2026 12:56:50 +0000 Subject: [PATCH 092/335] chore(DB): import pending files Referenced commit(s): 2520bed648a1e15b5837d355f7ec4faf4d9bdbc4 --- .../rev_1770862687925401600.sql => db_world/2026_02_12_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1770862687925401600.sql => db_world/2026_02_12_00.sql} (65%) diff --git a/data/sql/updates/pending_db_world/rev_1770862687925401600.sql b/data/sql/updates/db_world/2026_02_12_00.sql similarity index 65% rename from data/sql/updates/pending_db_world/rev_1770862687925401600.sql rename to data/sql/updates/db_world/2026_02_12_00.sql index ad2e55784..226ef4c57 100644 --- a/data/sql/updates/pending_db_world/rev_1770862687925401600.sql +++ b/data/sql/updates/db_world/2026_02_12_00.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_11_01 -> 2026_02_12_00 -- UPDATE `creature_template` SET `DamageModifier` = 1.5 WHERE (`entry` = 29851); From eeeaa080889145b7aa922667614a2b780ff0d7ed Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Thu, 12 Feb 2026 14:18:33 -0300 Subject: [PATCH 093/335] fix(DB/SAI): Rewrite Last Rites in SmartAI (#24680) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../rev_1770760522596716100.sql | 238 +++++++ .../scripts/Northrend/zone_borean_tundra.cpp | 662 ------------------ 2 files changed, 238 insertions(+), 662 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1770760522596716100.sql diff --git a/data/sql/updates/pending_db_world/rev_1770760522596716100.sql b/data/sql/updates/pending_db_world/rev_1770760522596716100.sql new file mode 100644 index 000000000..219f98859 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770760522596716100.sql @@ -0,0 +1,238 @@ +-- +DELETE FROM `creature_equip_template` WHERE (`CreatureID` = 25301); +INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES +(25301, 1, 23240, 0, 0, 62044); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 25301); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(25301, 0, 0, 'Our troops, general, consist mostly of villagers and peasants. Good men, but not quite rid of the prejudices and superstitions of their upbringing. They\'re not ready to fight alongside our more exotic allies.', 12, 7, 100, 1, 0, 0, 24789, 0, 'Counselor Talbot'), +(25301, 1, 0, 'My liege, the infiltration and control of the Alliance power structure by our cultists is well underway.', 12, 0, 100, 0, 0, 14211, 25357, 0, 'Talbot - Last Rites'), +(25301, 2, 0, 'The power you\'ve bestowed upon me has granted me great mental influence over human minds. I bear these offerings as proof of my progress.', 12, 0, 100, 0, 0, 14212, 25358, 0, 'Talbot - Last Rites'), +(25301, 3, 0, 'Allow me to take care of the intruders, lord. I will feed their entrails to the maggots.', 12, 0, 100, 1, 0, 14213, 25361, 0, 'Talbot - Last Rites'), +(25301, 4, 0, 'Yes, my lord!', 12, 0, 100, 1, 0, 14214, 25365, 0, 'Talbot - Last Rites'); + +-- Duplicated to not create issues after UpdateEntry +DELETE FROM `creature_text` WHERE (`CreatureID` = 28189); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(28189, 0, 0, 'Our troops, general, consist mostly of villagers and peasants. Good men, but not quite rid of the prejudices and superstitions of their upbringing. They\'re not ready to fight alongside our more exotic allies.', 12, 7, 100, 1, 0, 0, 24789, 0, 'Prince Valanar'), +(28189, 1, 0, 'My liege, the infiltration and control of the Alliance power structure by our cultists is well underway.', 12, 0, 100, 0, 0, 14211, 25357, 0, 'Prince Valanar - Last Rites'), +(28189, 2, 0, 'The power you\'ve bestowed upon me has granted me great mental influence over human minds. I bear these offerings as proof of my progress.', 12, 0, 100, 0, 0, 14212, 25358, 0, 'Prince Valanar - Last Rites'), +(28189, 3, 0, 'Allow me to take care of the intruders, lord. I will feed their entrails to the maggots.', 12, 0, 100, 1, 0, 14213, 25361, 0, 'Prince Valanar - Last Rites'), +(28189, 4, 0, 'Yes, my lord!', 12, 0, 100, 1, 0, 14214, 25365, 0, 'Prince Valanar - Last Rites'); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 26203); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(26203, 0, 0, 'Your progress in this region has been impressive, blood prince. I am pleased.', 12, 0, 100, 0, 0, 14756, 25362, 0, 'thassarian SAY_LICH_1'), +(26203, 1, 0, 'Now this is a surprise, Thassarian. I hadn\'t heard from Mograine or the other death knights for months. You\'ve come to rejoin the Scourge, I take it?', 12, 0, 100, 0, 0, 14757, 25363, 0, 'thassarian SAY_LICH_2'), +(26203, 2, 0, 'Do not fail me, San\'layn. Return to Icecrown with this fool\'s head or do not bother to return.', 12, 0, 100, 1, 0, 14758, 25364, 0, 'thassarian SAY_LICH_3'); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 26170) AND (`GroupID` IN (2)); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(26170, 2, 0, 'I would sooner slit my own throat. You will pay for what you did to your own men, Arthas... for what you did to me! I swear it.', 12, 0, 100, 53, 0, 14666, 25366, 0, 'thassarian SAY_THASSARIAN_3'); + +UPDATE `creature` SET `ScriptName` = '' WHERE `guid` IN (101136, 101303) AND `id1` = 26170; + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 26170; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 26170); +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 +(26170, 0, 0, 0, 60, 0, 100, 0, 5000, 5000, 5000, 5000, 0, 0, 11, 50995, 32, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Update - Cast \'Empowered Blood Presence\''), +(26170, 0, 1, 0, 0, 0, 100, 0, 10000, 20000, 10000, 20000, 0, 0, 11, 52374, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - In Combat - Cast \'Blood Strike\''), +(26170, 0, 2, 0, 0, 0, 100, 0, 10000, 20000, 10000, 20000, 0, 0, 11, 52372, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - In Combat - Cast \'Icy Touch\''), +(26170, 0, 3, 0, 0, 0, 100, 0, 10000, 20000, 10000, 20000, 0, 0, 11, 50668, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - In Combat - Cast \'Death Coil\''); + +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|134217728 WHERE (`entry` = 26170); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -101136); +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 +(-101136, 0, 1000, 0, 1, 0, 100, 0, 1000, 1000, 3600, 3600, 0, 0, 11, 46685, 32, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Out of Combat - Cast \'Borean Tundra - Quest - Thassarian Flay\''); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -101303); +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 +(-101303, 0, 1000, 0, 62, 0, 100, 0, 9417, 0, 0, 0, 0, 0, 80, 2617001, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Gossip Option Selected - Run Script: Initiate Quest Last Rites'), +(-101303, 0, 1001, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2617000, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Respawn - Run Cleanup Script'), +(-101303, 0, 1002, 0, 109, 0, 100, 0, 0, 261701, 0, 0, 0, 0, 80, 2617002, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Path Finished - Run Script: Last Rites RP Part 1'), +(-101303, 0, 1003, 0, 77, 0, 100, 0, 1, 2, 0, 0, 0, 0, 80, 2617003, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Lich King and Talbot Finished Pathing - Run Script: Last Rites RP Part 2'), +(-101303, 0, 1004, 0, 77, 0, 100, 0, 1, 4, 0, 0, 0, 0, 80, 2617004, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Leryssa and Arlos Finished Pathing - Run Script: Last Rites RP Part 3'), +(-101303, 0, 1005, 0, 34, 0, 100, 0, 8, 1, 0, 0, 0, 0, 80, 2617005, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Reached Point - Run Script: Last Rites RP Part 4'), +(-101303, 0, 1006, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Just Died - Despawn Instant'), +(-101303, 0, 1007, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 10, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Just Died - Despawn Instant'), +(-101303, 0, 1008, 0, 72, 0, 100, 0, 1, 0, 0, 0, 0, 0, 63, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Action Received - Increment Counter'), +(-101303, 0, 1009, 0, 72, 0, 100, 0, 2, 0, 0, 0, 0, 0, 80, 2617006, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Event Received from Leryssa - Run Cleanup Script'), +(-101303, 0, 1010, 0, 17, 0, 100, 0, 25301, 0, 0, 0, 0, 0, 64, 2, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Summoned Unit - Store Talbot'), +(-101303, 0, 1011, 0, 17, 0, 100, 0, 26203, 0, 0, 0, 0, 0, 64, 3, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - On Summoned Unit - Store Lich King'); + +-- Respawn +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2617000); +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 +(2617000, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 63, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Reset Counter'), +(2617000, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Despawn Instant'), +(2617000, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 2, 1974, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Set Faction 1974'), +(2617000, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 91, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Remove StandState Kneel'), +(2617000, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Reset EmoteState'), +(2617000, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Remove Npc Flags Questgiver'), +(2617000, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Add Npc Flags Gossip'), +(2617000, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Set Active Off'); +-- Gossip Option Selected +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2617001); +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 +(2617001, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Store Player Party'), +(2617001, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Set Active On'), +(2617001, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 63, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Reset Counter'), +(2617001, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Remove Npc Flags Gossip'), +(2617001, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 261701, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Start Path 261701'); +-- First Path Finished +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2617002); +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 +(2617002, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 17, 333, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Set Emote State 333'), +(2617002, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 107, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Summon Creature Group 0: Talbot and Lich King'); +-- On Talbot and Image of the Lich King Finished their paths (Counter 2) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2617003); +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 +(2617003, 9, 0, 0, 0, 0, 100, 0, 1200, 1200, 0, 0, 0, 0, 2, 974, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Set Faction 974'), +(2617003, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 36, 28189, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Update Template To \'Prince Valanar\''), +(2617003, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 124, 1, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Load Equipment Id 1'), +(2617003, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Set Flags Immune To Players & Immune To NPC\'s'), +(2617003, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 12, 3, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Lich King Say Line 0'), +(2617003, 9, 5, 0, 0, 0, 100, 0, 8200, 8200, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Talbot Say Line 1'), +(2617003, 9, 6, 0, 0, 0, 100, 0, 8600, 8600, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Summon Creature Group 1: Arlos and Leryssa'), +(2617003, 9, 7, 0, 0, 0, 100, 0, 5500, 5500, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Talbot Say Line 2'); +-- On Arlos and Leryssa finished their paths (Counter 4) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2617004); +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 +(2617004, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Say Line 0'), +(2617004, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 3722.5269, 3567.258, 477.57098, 0, 'Thassarian - Actionlist - Move To Position'); +-- On Reached Pos +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2617005); +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 +(2617005, 9, 0 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Say Line 1'), +(2617005, 9, 1 , 0, 0, 0, 100, 0, 1200, 1200, 0, 0, 0, 0, 231, 2, 0, 0, 0, 0, 0, 12, 3, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Set Lich King Orientation'), +(2617005, 9, 2 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 91, 8, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Talbot Set Flag Standstate Stand Up'), +(2617005, 9, 3 , 0, 0, 0, 100, 0, 4200, 4200, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 12, 3, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Lich King Say Line 1'), +(2617005, 9, 4 , 0, 0, 0, 100, 0, 17800, 17800, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Say Line 2'), +(2617005, 9, 5 , 0, 0, 0, 100, 0, 9600, 9600, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Talbot Say Line 3'), +(2617005, 9, 6 , 0, 0, 0, 100, 0, 6400, 6400, 0, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 12, 3, 0, 0, 0, 0, 0, 0, 1.4356470108032227, 'Thassarian - Actionlist - Set Lich King Orientation'), +(2617005, 9, 7 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 12, 3, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Lich King Say Line 2'), +(2617005, 9, 8 , 0, 0, 0, 100, 0, 4400, 4400, 0, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 12, 3, 0, 0, 0, 0, 0, 0, 3.006659984588623, 'Thassarian - Actionlist - Set Lich King Orientation'), +(2617005, 9, 9 , 0, 0, 0, 100, 0, 400, 400, 0, 0, 0, 0, 5, 25, 0, 0, 0, 0, 0, 12, 3, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Lich King Play Emote 25'), +(2617005, 9, 10, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 4800, 0, 0, 0, 0, 0, 12, 3, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Lich King Despawn In 4800 ms'), +(2617005, 9, 11, 0, 0, 0, 100, 0, 6600, 6600, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Talbot Say Line 4'), +(2617005, 9, 12, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 2, 1988, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Talbot Set Faction 1988'), +(2617005, 9, 13, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 768, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Talbot Remove Flags Immune To Players & Immune To NPC\'s'), +(2617005, 9, 14, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 86, 9613, 2, 12, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Talbot Cross Cast \'Shadow Bolt\''), +(2617005, 9, 15, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Set Home Position'); +-- Talbot Dead -> Leryssa takes over +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2525101); +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 +(2525101, 9, 0, 0, 0, 0, 100, 0, 5200, 5200, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Say Line 0'), +(2525101, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Reset Emote State'), +(2525101, 9, 2, 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 3726.4373, 3568.1, 477.54553, 0, 'Leryssa - Actionlist - Move To Thassarian'), +(2525101, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 19, 26170, 50, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Thassarian Say Line 3'), +(2525101, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 90, 8, 0, 0, 0, 0, 0, 19, 26170, 50, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Set Thassarian Standstate Kneel'), +(2525101, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 82, 2, 0, 0, 0, 0, 0, 19, 26170, 50, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Set Thassarian as Questgiver'); +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2525102); +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 +(2525102, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Set Flag Standstate Sit Down'), +(2525102, 9, 1, 0, 0, 0, 100, 0, 100, 100, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Say Line 1'), +(2525102, 9, 2, 0, 0, 0, 100, 0, 7200, 7200, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 19, 26170, 20, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Thassarian Say Line 4'), +(2525102, 9, 3, 0, 0, 0, 100, 0, 6900, 6900, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Say Line 2'), +(2525102, 9, 4, 0, 0, 0, 100, 0, 14200, 14200, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 19, 26170, 20, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Thassarian Say Line 5'), +(2525102, 9, 5, 0, 0, 0, 100, 0, 10000, 10000, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Say Line 3'), +(2525102, 9, 6, 0, 0, 0, 100, 0, 14200, 14200, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 19, 26170, 20, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Thassarian Say Line 6'), +(2525102, 9, 7, 0, 0, 0, 100, 0, 30000, 30000, 0, 0, 0, 0, 223, 2, 0, 0, 0, 0, 0, 19, 26170, 20, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Send Action to Thassarian, Cleanup Quest Event'); +-- Despawn All +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2617006); +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 +(2617006, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Despawn Instant'), +(2617006, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 10, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Thassarian - Actionlist - Despawn Instant'); + +DELETE FROM `creature_summon_groups` WHERE `summonerId` = 26170 AND `summonerType` = 0; +INSERT INTO `creature_summon_groups` (`summonerId`, `summonerType`, `groupId`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `summonType`, `summonTime`, `Comment`) VALUES +(26170, 0, 0, 25301, 3748.7627, 3614.0374, 473.4048, 4.55531, 6, 30000, 'Last Rites - Counselor Talbot (25301)'), +(26170, 0, 0, 26203, 3729.4614, 3520.386, 473.4048, 1.362439, 6, 30000, 'Last Rites - Image of the Lich King (26203)'), + +(26170, 0, 1, 25251, 3750.8022, 3611.4067, 473.4192, 4.62829, 6, 30000, 'Last Rites - Leryssa (25251)'), +(26170, 0, 1, 25250, 3745.2783, 3613.004, 473.42523, 4.42246, 6, 30000, 'Last Rites - General Arlos (25250)'); + +DELETE FROM `waypoint_data` WHERE `id` IN (261701, 253011, 262031, 252511, 252501); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `move_type`) VALUES +-- Thassarian +(261701, 1, 3695.3281, 3576.184, 473.95667, NULL, 0), +(261701, 2, 3701.8281, 3574.434, 473.95667, NULL, 0), +(261701, 3, 3708.717, 3572.3823, 477.50854, NULL, 0), +(261701, 4, 3713.3604, 3570.719, 477.5991 , NULL, 0), +-- Talbot +(253011, 1, 3746.9602, 3607.5066, 473.43402, NULL, 0), +(253011, 2, 3745.358, 3600.3086, 477.3036 , NULL, 0), +(253011, 3, 3742.5251, 3586.4634, 477.68497, NULL, 0), +(253011, 4, 3738.2366, 3570.346, 477.63406 , NULL, 0), +-- Lich King +(262031, 1, 3732.6357, 3535.3997, 477.41446, NULL, 0), +(262031, 2, 3733.244, 3538.2766, 477.50858 , NULL, 0), +(262031, 3, 3736.5, 3556.1492, 477.63403 , NULL, 0), +(262031, 4, 3737.5396, 3565.22, 477.63403 , NULL, 0), +-- Arlos +(252501, 1, 3744.8464, 3611.5564, 473.42465, NULL, 0), +(252501, 2, 3742.4666, 3598.8833, 477.52597, NULL, 0), +(252501, 3, 3739.2288, 3587.0754, 477.62778, NULL, 0), +(252501, 4, 3735.5715, 3572.422, 477.62778 , NULL, 0), +-- Leryssa +(252511, 1, 3750.0989, 3603.0605, 474.33777, NULL, 0), +(252511, 2, 3747.6184, 3591.2925, 477.62778, NULL, 0), +(252511, 3, 3741.9653, 3571.4446, 477.62778, NULL, 0), +(252511, 4, 3741.9653, 3571.4446, 477.62778, 4.537856101989746093, 0); + +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE (`entry` = 25301); +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 25301); +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 +(25301, 0, 0, 0, 0, 0, 100, 0, 0, 500, 3000, 3500, 0, 0, 11, 51016, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Counselor Talbot - In Combat - Cast \'Vampiric Bolt\''), +(25301, 0, 1, 0, 0, 0, 100, 0, 15000, 43000, 45000, 73000, 0, 0, 11, 50992, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Counselor Talbot - In Combat - Cast \'Soul Blast\''), +(25301, 0, 2, 0, 0, 0, 100, 0, 10000, 20000, 10000, 20000, 0, 0, 11, 51009, 32, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Counselor Talbot - In Combat - Cast \'Soul Deflection\''), +(25301, 0, 3, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 253011, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Counselor Talbot - On Just Summoned - Start Path'), +(25301, 0, 4, 0, 109, 0, 100, 0, 0, 253011, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 10, 101303, 26170, 0, 0, 0, 0, 0, 0, 'Counselor Talbot - On Path Finished - Send Action to Thassarian'), +(25301, 0, 5, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 19, 25250, 100, 0, 0, 0, 0, 0, 0, 'Counselor Talbot - On Just Died - Send Event to General Arlos'), +(25301, 0, 6, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 19, 25251, 100, 0, 0, 0, 0, 0, 0, 'Counselor Talbot - On Just Died - Send Event to Leryssa'), +(25301, 0, 7, 0, 109, 0, 100, 0, 0, 253011, 0, 0, 0, 0, 90, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Counselor Talbot - On Path Finished - Set Flag Standstate Kneel'), +(25301, 0, 8, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Counselor Talbot - On Respawn - Deload Equipment'); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 26203; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 26203); +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 +(26203, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 262031, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Image of the Lich King - On Just Summoned - Start Path'), +(26203, 0, 1, 0, 109, 0, 100, 0, 0, 262031, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 10, 101303, 26170, 0, 0, 0, 0, 0, 0, 'Image of the Lich King - On Path Finished - Send Action to Thassarian'); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 25250; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 25250); +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 +(25250, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2525000, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - On Just Summoned - Run Script'), +(25250, 0, 1, 0, 72, 0, 100, 0, 1, 0, 0, 0, 0, 0, 80, 2525001, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - On Action 1 Done - Run Script'), +(25250, 0, 2, 0, 109, 0, 100, 0, 0, 252501, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 10, 101303, 26170, 0, 0, 0, 0, 0, 0, 'General Arlos - On Path Finished - Send Event to Thassarian'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2525000); +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 +(2525000, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - Actionlist - Set Flags Immune To Players & Immune To NPC\'s'), +(2525000, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 17, 64, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - Actionlist - Set Emote State 64'), +(2525000, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 252501, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - Actionlist - Start Path'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2525001); +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 +(2525001, 9, 0, 0, 0, 0, 100, 0, 1200, 1200, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - Actionlist - Say Line 0'), +(2525001, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - Actionlist - Play Emote 0'), +(2525001, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 90, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - Actionlist - Set Flag Standstate Kneel'), +(2525001, 9, 3, 0, 0, 0, 100, 0, 3800, 3800, 0, 0, 0, 0, 91, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - Actionlist - Set Flag Standstate Kneel'), +(2525001, 9, 4, 0, 0, 0, 100, 0, 200, 200, 0, 0, 0, 0, 90, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - Actionlist - Set Flag Standstate Dead'), +(2525001, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - Actionlist - Say Line 1'), +(2525001, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 40000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'General Arlos - Actionlist - Despawn In 40000 ms'); + +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE (`entry` = 25251); +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 25251); +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 +(25251, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2525100, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - On Just Summoned - Run Script'), +(25251, 0, 1, 0, 72, 0, 100, 0, 1, 0, 0, 0, 0, 0, 80, 2525101, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - On Talbot Died - Run Script'), +(25251, 0, 2, 0, 34, 0, 100, 0, 8, 1, 0, 0, 0, 0, 80, 2525102, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - On Reached Thassarian - Run Script'), +(25251, 0, 3, 0, 109, 0, 100, 0, 0, 252511, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 10, 101303, 26170, 0, 0, 0, 0, 0, 0, 'Leryssa - On Path Finished - Send Event to Thassarian'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2525100); +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 +(2525100, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Set Flags Immune To Players & Immune To NPC\'s'), +(2525100, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 17, 64, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Set Emote State 64'), +(2525100, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 252511, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Leryssa - Actionlist - Start Path'); diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index 960e72b15..af5491db7 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -1290,664 +1290,6 @@ public: } }; -/*###### -## Quest 12019: Last Rites -######*/ - -// NPC 26170: Thassarian -enum Thassarian -{ - EVENT_THASSARIAN_SCRIPT_1 = 1, - EVENT_THASSARIAN_SCRIPT_2 = 2, - EVENT_THASSARIAN_SCRIPT_3 = 3, - EVENT_THASSARIAN_SCRIPT_4 = 4, - EVENT_THASSARIAN_SCRIPT_5 = 5, - EVENT_THASSARIAN_SCRIPT_6 = 6, - EVENT_THASSARIAN_SCRIPT_7 = 7, - EVENT_THASSARIAN_SCRIPT_8 = 8, - EVENT_THASSARIAN_SCRIPT_9 = 9, - EVENT_THASSARIAN_SCRIPT_10 = 10, - EVENT_THASSARIAN_SCRIPT_11 = 11, - EVENT_THASSARIAN_SCRIPT_12 = 12, - EVENT_THASSARIAN_SCRIPT_13 = 13, - EVENT_THASSARIAN_SCRIPT_14 = 14, - EVENT_THASSARIAN_SCRIPT_15 = 15, - EVENT_THASSARIAN_SCRIPT_16 = 16, - EVENT_THASSARIAN_SCRIPT_17 = 17, - EVENT_THASSARIAN_SCRIPT_18 = 18, - EVENT_THASSARIAN_SCRIPT_19 = 19, - EVENT_THASSARIAN_SCRIPT_20 = 20, - EVENT_THASSARIAN_SCRIPT_21 = 21, - EVENT_THASSARIAN_SCRIPT_22 = 22, - EVENT_THASSARIAN_SCRIPT_23 = 23, - EVENT_THASSARIAN_SCRIPT_24 = 24, - EVENT_THASSARIAN_SCRIPT_25 = 25, - EVENT_THASSARIAN_SCRIPT_26 = 26, - EVENT_THASSARIAN_SCRIPT_27 = 27, - EVENT_THASSARIAN_SCRIPT_28 = 28, - EVENT_THASSARIAN_SCRIPT_29 = 29, - EVENT_THASSARIAN_CAST = 30, - NPC_IMAGE_LICH_KING = 26203, - NPC_COUNSELOR_TALBOT = 25301, - NPC_PRINCE_VALANAR = 28189, - NPC_GENERAL_ARLOS = 25250, - NPC_LERYSSA = 25251, - NPC_TANATHAL = 26173, - SPELL_THASSARIAN_FLAY = 46685, - SPELL_TRANSFORM_VALANAR = 46753, - SPELL_BLOOD_PRESENCE = 50995, - SAY_THASSARIAN_1 = 0, - SAY_THASSARIAN_2 = 1, - SAY_THASSARIAN_3 = 2, - SAY_THASSARIAN_4 = 3, - SAY_THASSARIAN_5 = 4, - SAY_THASSARIAN_6 = 5, - SAY_THASSARIAN_7 = 6, - SAY_TALBOT_1 = 0, - SAY_TALBOT_2 = 1, - SAY_TALBOT_3 = 2, - SAY_TALBOT_4 = 3, - SAY_LICH_1 = 0, - SAY_LICH_2 = 1, - SAY_LICH_3 = 2, - SAY_ARLOS_1 = 0, - SAY_ARLOS_2 = 1, - SAY_LERYSSA_1 = 0, - SAY_LERYSSA_2 = 1, - SAY_LERYSSA_3 = 2, - SAY_LERYSSA_4 = 3, - PATH_THASSARIAN = 1013030, - PATH_ARTHAS = 1013031, - PATH_TALBOT = 1013032, - PATH_ARLOS = 1013033, - PATH_LERYSSA = 1013034 -}; - -class npc_thassarian : public CreatureScript -{ -public: - npc_thassarian() : CreatureScript("npc_thassarian") {} - - struct npc_thassarianAI : public ScriptedAI - { - npc_thassarianAI(Creature* creature) : ScriptedAI(creature){} - - void Reset() override - { - me->SetImmuneToAll(true); - _events.ScheduleEvent(EVENT_THASSARIAN_CAST, 1s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - if (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_THASSARIAN_CAST: - { - if (Unit* tanathal = me->FindNearestCreature(NPC_TANATHAL, 10.0f)) - { - me->CastSpell(tanathal, SPELL_THASSARIAN_FLAY); - } - } - } - } - } - private: - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_thassarianAI(creature); - } -}; - -class npc_thassarian2 : public CreatureScript -{ -public: - npc_thassarian2() : CreatureScript("npc_thassarian2") {} - - struct npc_thassarian2AI : public ScriptedAI - { - npc_thassarian2AI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - _arthasGUID.Clear(); - _talbotGUID.Clear(); - _leryssaGUID.Clear(); - _arlosGUID.Clear(); - } - - void Reset() override - { - me->SetFaction(FACTION_VALIANCE_EXPEDITION_7); - me->SetStandState(UNIT_STAND_STATE_STAND); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); - me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); - Initialize(); - } - - void SetData(uint32 /*type*/, uint32 data) override - { - switch (data) - { - case NPC_LERYSSA: - { - if (Creature* arlos = ObjectAccessor::GetCreature(*me, _arlosGUID)) - { - arlos->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); - } - if (Creature* leryssa = ObjectAccessor::GetCreature(*me, _leryssaGUID)) - { - leryssa->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); - leryssa->SetOrientation(4.537856f); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_8, 1s); - break; - } - case NPC_COUNSELOR_TALBOT: - { - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_18, 0ms); - } - break; - default: - break; - } - } - - void MovementInform(uint32 type, uint32 param) override - { - if (type == WAYPOINT_MOTION_TYPE && param == 3) - { - me->SetWalk(false); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H); - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_1, 2s); - } - else if (type == POINT_MOTION_TYPE && param == 0) - { - if (Creature* talbot = ObjectAccessor::GetCreature(*me, _talbotGUID)) - me->SetFacingToObject(talbot); - } - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - if (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_THASSARIAN_SCRIPT_1: - // Summon Arthas and Talbot - if (Creature* arthas = me->SummonCreature(NPC_IMAGE_LICH_KING, 3729.4614f, 3520.386f, 473.4048f, 1.361f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000)) - { - _arthasGUID = arthas->GetGUID(); - arthas->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - arthas->SetReactState(REACT_PASSIVE); - arthas->SetWalk(true); - } - if (Creature* talbot = me->SummonCreature(NPC_COUNSELOR_TALBOT, 3748.7627f, 3614.0374f, 473.4048f, 4.5553f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000)) - { - _talbotGUID = talbot->GetGUID(); - talbot->SetWalk(true); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_2, 1s); - break; - case EVENT_THASSARIAN_SCRIPT_2: - // Arthas load path - if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) - { - arthas->GetMotionMaster()->MoveWaypoint(PATH_ARTHAS, false); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_3, 1s); - break; - case EVENT_THASSARIAN_SCRIPT_3: - // Talbot load path - if (Creature* talbot = ObjectAccessor::GetCreature(*me, _talbotGUID)) - { - talbot->GetMotionMaster()->MoveWaypoint(PATH_TALBOT, false); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_4, 20s); - break; - case EVENT_THASSARIAN_SCRIPT_4: - // Talbot transform and knell - if (Creature* talbot = ObjectAccessor::GetCreature(*me, _talbotGUID)) - { - talbot->CastSpell(talbot, SPELL_TRANSFORM_VALANAR); - talbot->UpdateEntry(NPC_PRINCE_VALANAR); - talbot->SetFullHealth(); - talbot->SetFaction(FACTION_UNDEAD_SCOURGE); - talbot->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - talbot->SetReactState(REACT_PASSIVE); - talbot->SetStandState(UNIT_STAND_STATE_KNEEL); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_5, 7s); - break; - case EVENT_THASSARIAN_SCRIPT_5: - // Talbot say text 1 - if (Creature* talbot = ObjectAccessor::GetCreature(*me, _talbotGUID)) - { - talbot->AI()->Talk(SAY_TALBOT_1); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_6, 9s); - break; - case EVENT_THASSARIAN_SCRIPT_6: - // Summon General Arlos and Leryssa - if (Creature* arlos = me->SummonCreature(NPC_GENERAL_ARLOS, 3746.2825f, 3616.3699f, 473.4048f, 4.5029f, TEMPSUMMON_CORPSE_TIMED_DESPAWN)) - { - _arlosGUID = arlos->GetGUID(); - arlos->SetWalk(true); - arlos->SetImmuneToAll(true); - arlos->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); - arlos->GetMotionMaster()->MoveWaypoint(PATH_ARLOS, false); - } - if (Creature* leryssa = me->SummonCreature(NPC_LERYSSA, 3751.0986f, 3614.9219f, 473.4048f, 4.5029f, TEMPSUMMON_CORPSE_TIMED_DESPAWN)) - { - _leryssaGUID = leryssa->GetGUID(); - leryssa->SetWalk(true); - leryssa->SetImmuneToAll(true); - leryssa->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); - leryssa->GetMotionMaster()->MoveWaypoint(PATH_LERYSSA, false); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_7, 7s); - break; - case EVENT_THASSARIAN_SCRIPT_7: - // Talbot say text 2 - if (Creature* talbot = ObjectAccessor::GetCreature(*me, _talbotGUID)) - { - talbot->AI()->Talk(SAY_TALBOT_2); - } - break; - case EVENT_THASSARIAN_SCRIPT_8: - // Thassarian say text 1 and move to location - Talk(SAY_THASSARIAN_1); - me->SetWalk(false); - me->GetMotionMaster()->MovePoint(0, 3722.527f, 3567.2583f, 477.44086f); - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_9, 7s); - break; - case EVENT_THASSARIAN_SCRIPT_9: - // Thassarian say text 2 - Talk(SAY_THASSARIAN_2); - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_10, 6s); - break; - case EVENT_THASSARIAN_SCRIPT_10: - // Arthas turn to Thassarian and Talbot stand - if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) - { - arthas->SetFacingToObject(me); - } - if (Creature* talbot = ObjectAccessor::GetCreature(*me, _talbotGUID)) - { - talbot->SetStandState(UNIT_STAND_STATE_STAND); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_11, 4s); - break; - case EVENT_THASSARIAN_SCRIPT_11: - // Arthas say text 2 - if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) - { - arthas->AI()->Talk(SAY_LICH_2); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_12, 18s); - break; - case EVENT_THASSARIAN_SCRIPT_12: - // Thassarian say text 3 - Talk(SAY_THASSARIAN_3); - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_13, 10s); - break; - case EVENT_THASSARIAN_SCRIPT_13: - // Talbot say text 3 - if (Creature* talbot = ObjectAccessor::GetCreature(*me, _talbotGUID)) - { - talbot->AI()->Talk(SAY_TALBOT_3); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_14, 5s); - break; - case EVENT_THASSARIAN_SCRIPT_14: - // Arthas turn to Talbot say text 3 - if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) - { - if (Creature* talbot = ObjectAccessor::GetCreature(*me, _talbotGUID)) - { - arthas->SetFacingToObject(talbot); - } - arthas->AI()->Talk(SAY_LICH_3); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_15, 5s); - break; - case EVENT_THASSARIAN_SCRIPT_15: - // Arthas turn to me and emote - if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) - { - arthas->SetFacingToObject(me); - arthas->HandleEmoteCommand(EMOTE_ONESHOT_POINT); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_16, 5s); - break; - case EVENT_THASSARIAN_SCRIPT_16: - // Arthas despawn - if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) - { - arthas->RemoveFromWorld(); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_17, 3s); - break; - case EVENT_THASSARIAN_SCRIPT_17: - // Talbot say text 4 and attack - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - if (Creature* talbot = ObjectAccessor::GetCreature(*me, _talbotGUID)) - { - talbot->AI()->Talk(SAY_TALBOT_4); - talbot->SetFaction(FACTION_UNDEAD_SCOURGE_9); - talbot->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - talbot->SetReactState(REACT_AGGRESSIVE); - talbot->Attack(me, false); - } - break; - case EVENT_THASSARIAN_SCRIPT_18: - // Arlos say text 1 - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H); - if (Creature* arlos = ObjectAccessor::GetCreature(*me, _arlosGUID)) - { - arlos->AI()->Talk(SAY_ARLOS_1); - arlos->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); - arlos->SetStandState(UNIT_STAND_STATE_KNEEL); - } - if (Creature* leryssa = ObjectAccessor::GetCreature(*me, _leryssaGUID)) - { - leryssa->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_19, 3s); - break; - case EVENT_THASSARIAN_SCRIPT_19: - // Leryssa set facing to me - me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - me->SetNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); - if (Creature* leryssa = me->FindNearestCreature(NPC_LERYSSA, 50.0f, true)) - { - _leryssaGUID = leryssa->GetGUID(); - leryssa->SetFacingToObject(me); - me->SetFacingToObject(leryssa); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_20, 3s); - break; - case EVENT_THASSARIAN_SCRIPT_20: - // Arlos say text 2 and die. Leryssa say text 1 - if (Creature* arlos = me->FindNearestCreature(NPC_GENERAL_ARLOS, 50.0f, true)) - { - _arlosGUID = arlos->GetGUID(); - arlos->AI()->Talk(SAY_ARLOS_2); - arlos->SetStandState(UNIT_STAND_STATE_DEAD); - } - if (Creature* leryssa = ObjectAccessor::GetCreature(*me, _leryssaGUID)) - { - leryssa->AI()->Talk(SAY_LERYSSA_1); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_21, 5s); - break; - case EVENT_THASSARIAN_SCRIPT_21: - // Thassarian say text 4 - me->SetStandState(UNIT_STAND_STATE_KNEEL); - Talk(SAY_THASSARIAN_4); - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_22, 3s); - break; - case EVENT_THASSARIAN_SCRIPT_22: - // Leryssa run to Thassarian - if (Creature* leryssa = ObjectAccessor::GetCreature(*me, _leryssaGUID)) - { - leryssa->SetWalk(false); - leryssa->GetMotionMaster()->MovePoint(0, 3726.751f, 3568.1633f, 477.44086f, FORCED_MOVEMENT_RUN); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_23, 2s); - break; - case EVENT_THASSARIAN_SCRIPT_23: - // Leryssa say text 2 - if (Creature* leryssa = ObjectAccessor::GetCreature(*me, _leryssaGUID)) - { - leryssa->AI()->Talk(SAY_LERYSSA_2); - leryssa->SetStandState(UNIT_STAND_STATE_SIT); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_24, 5s); - break; - case EVENT_THASSARIAN_SCRIPT_24: - // Thassarian say text 5 - Talk(SAY_THASSARIAN_5); - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_25, 10s); - break; - case EVENT_THASSARIAN_SCRIPT_25: - // Leryssa say text 3 - if (Creature* leryssa = ObjectAccessor::GetCreature(*me, _leryssaGUID)) - { - leryssa->AI()->Talk(SAY_LERYSSA_3); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_26, 12s); - break; - case EVENT_THASSARIAN_SCRIPT_26: - // Thassarian say text 6 - Talk(SAY_THASSARIAN_6); - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_27, 11s); - break; - case EVENT_THASSARIAN_SCRIPT_27: - // Leryssa say text 4 - if (Creature* leryssa = ObjectAccessor::GetCreature(*me, _leryssaGUID)) - { - leryssa->AI()->Talk(SAY_LERYSSA_4); - } - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_28, 12s); - break; - case EVENT_THASSARIAN_SCRIPT_28: - // Thassarian say text 7 - Talk(SAY_THASSARIAN_7); - _events.ScheduleEvent(EVENT_THASSARIAN_SCRIPT_29, 35s); - break; - case EVENT_THASSARIAN_SCRIPT_29: - Cleanup(); - me->DespawnOrUnsummon(30s, 120s); - break; - default: - break; - } - } - - if (!UpdateVictim()) - { - return; - } - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) override - { - Cleanup(); - me->DespawnOrUnsummon(1s, 120s); - } - - void Cleanup() - { - if (Creature* talbot = ObjectAccessor::GetCreature(*me, _talbotGUID)) - { - talbot->RemoveFromWorld(); - } - - if (Creature* leryssa = ObjectAccessor::GetCreature(*me, _leryssaGUID)) - { - leryssa->RemoveFromWorld(); - } - - if (Creature* arlos = ObjectAccessor::GetCreature(*me, _arlosGUID)) - { - arlos->RemoveFromWorld(); - } - - if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) - { - arthas->RemoveFromWorld(); - } - } - - void sGossipHello(Player* /*player*/) override - { - if (!me->HasAura(SPELL_BLOOD_PRESENCE)) - { - DoCastSelf(SPELL_BLOOD_PRESENCE); - } - } - - void sGossipSelect(Player* player, uint32 /*sender*/, uint32 action) override - { - if (action == 0) - { - me->setActive(true); - _playerGUID = player->GetGUID(); - CloseGossipMenuFor(player); - me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - me->GetMotionMaster()->MoveWaypoint(PATH_THASSARIAN, false); - } - } - - private: - EventMap _events; - ObjectGuid _playerGUID; - ObjectGuid _arthasGUID; - ObjectGuid _talbotGUID; - ObjectGuid _leryssaGUID; - ObjectGuid _arlosGUID; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_thassarian2AI(creature); - } -}; - -// NPC 25251: Leryssa -class npc_leryssa : public CreatureScript -{ -public: - npc_leryssa() : CreatureScript("npc_leryssa") {} - - struct npc_leryssaAI : public ScriptedAI - { - npc_leryssaAI(Creature* creature) : ScriptedAI(creature) {} - - void MovementInform(uint32 type, uint32 param) override - { - if (type == WAYPOINT_MOTION_TYPE && param == 3) - { - if (me->IsSummon()) - { - if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit()) - { - summoner->ToCreature()->AI()->SetData(1, NPC_LERYSSA); - } - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_leryssaAI(creature); - } -}; - -// NPC 25301: Counselor Talbot -enum CounselorTalbot -{ - SPELL_DEFLECTION = 51009, - SPELL_SOUL_BLAST = 50992, - SPELL_VAMPIRIC_BOLT = 51016, - EVENT_DEFLECTION = 1, - EVENT_SOUL_BLAST = 2, - EVENT_VAMPIRIC_BOLT = 3 -}; - -class npc_counselor_talbot : public CreatureScript -{ -public: - npc_counselor_talbot() : CreatureScript("npc_counselor_talbot") {} - - struct npc_counselor_talbotAI : public ScriptedAI - { - npc_counselor_talbotAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() override {} - - void JustEngagedWith(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_DEFLECTION, 10s, 20s); - _events.ScheduleEvent(EVENT_SOUL_BLAST, 4s, 6s); - _events.ScheduleEvent(EVENT_VAMPIRIC_BOLT, 0ms); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - { - return; - } - - if (me->GetAreaId() == AREA_NAXXANAR) - { - _events.Update(diff); - - if (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_DEFLECTION: - DoCastSelf(SPELL_DEFLECTION); - _events.ScheduleEvent(EVENT_DEFLECTION, 10s, 20s); - break; - case EVENT_SOUL_BLAST: - DoCastVictim(SPELL_SOUL_BLAST); - _events.ScheduleEvent(EVENT_SOUL_BLAST, 4s, 6s); - break; - case EVENT_VAMPIRIC_BOLT: - DoCastVictim(SPELL_VAMPIRIC_BOLT); - _events.ScheduleEvent(EVENT_VAMPIRIC_BOLT, 3s, 4s); - break; - default: - break; - } - } - } - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) override - { - if (me->IsSummon()) - { - if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit()) - { - summoner->ToCreature()->AI()->SetData(1, NPC_COUNSELOR_TALBOT); - } - } - } - - private: - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_counselor_talbotAI(creature); - } -}; - // 45612 - Necropolis Beam class spell_necropolis_beam: public SpellScript { @@ -2032,10 +1374,6 @@ class spell_bloodspore_haze : public SpellScript void AddSC_borean_tundra() { RegisterSpellScript(spell_q11919_q11940_drake_hunt_aura); - new npc_thassarian(); - new npc_thassarian2(); - new npc_leryssa(); - new npc_counselor_talbot(); new npc_sinkhole_kill_credit(); new npc_khunok_the_behemoth(); new npc_iruk(); From 4bce87e4476e52fbf7c05246271665ad309b5f6b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 12 Feb 2026 17:22:43 +0000 Subject: [PATCH 094/335] chore(DB): import pending files Referenced commit(s): eeeaa080889145b7aa922667614a2b780ff0d7ed --- .../rev_1770760522596716100.sql => db_world/2026_02_12_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1770760522596716100.sql => db_world/2026_02_12_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1770760522596716100.sql b/data/sql/updates/db_world/2026_02_12_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1770760522596716100.sql rename to data/sql/updates/db_world/2026_02_12_01.sql index 219f98859..ced342f97 100644 --- a/data/sql/updates/pending_db_world/rev_1770760522596716100.sql +++ b/data/sql/updates/db_world/2026_02_12_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_12_00 -> 2026_02_12_01 -- DELETE FROM `creature_equip_template` WHERE (`CreatureID` = 25301); INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES From 504f5a186e001b77e0bcc11f70ab557e712e6f70 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 13 Feb 2026 00:01:40 -0600 Subject: [PATCH 095/335] fix(CI): correct unit_tests binary path in linux-build action (#24697) Co-authored-by: blinkysc --- .github/actions/linux-build/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/linux-build/action.yml b/.github/actions/linux-build/action.yml index 42938553f..43d6fd29f 100644 --- a/.github/actions/linux-build/action.yml +++ b/.github/actions/linux-build/action.yml @@ -213,8 +213,8 @@ runs: - name: Run unit tests shell: bash run: | - if [[ -f build/obj/src/test/unit_tests ]]; then - build/obj/src/test/unit_tests + if [[ -f build/src/test/unit_tests ]]; then + build/src/test/unit_tests else exit 0 fi From 7fc57744d965af2bb79c73aba66b52ef02f66dc3 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 13 Feb 2026 02:42:13 -0600 Subject: [PATCH 096/335] fix(Scripts/Commands): Re-spawn pool quests after reload quest starters (#24696) Co-authored-by: blinkysc --- src/server/game/Pools/PoolMgr.cpp | 14 + src/server/game/Pools/PoolMgr.h | 2 + src/server/scripts/Commands/cs_reload.cpp | 4 + .../server/game/Pools/PoolQuestReloadTest.cpp | 299 ++++++++++++++++++ 4 files changed, 319 insertions(+) create mode 100644 src/test/server/game/Pools/PoolQuestReloadTest.cpp diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index 479fd6ede..efcd9e360 100644 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -1038,6 +1038,20 @@ void PoolMgr::ChangeWeeklyQuests() SaveQuestsToDB(false, true, false); } +void PoolMgr::ReSpawnPoolQuests() +{ + for (auto& [questId, poolId] : mQuestSearchMap) + { + if (IsSpawnedObject(questId)) + { + PoolObject tempObj(questId, 0.0f); + auto it = mPoolQuestGroups.find(poolId); + if (it != mPoolQuestGroups.end()) + it->second.Spawn1Object(&tempObj); + } + } +} + // Call to spawn a pool, if cache if true the method will spawn only if cached entry is different // If it's same, the creature is respawned only (added back to map) template<> diff --git a/src/server/game/Pools/PoolMgr.h b/src/server/game/Pools/PoolMgr.h index cf251352c..447d3a5be 100644 --- a/src/server/game/Pools/PoolMgr.h +++ b/src/server/game/Pools/PoolMgr.h @@ -130,10 +130,12 @@ public: void ChangeDailyQuests(); void ChangeWeeklyQuests(); + void ReSpawnPoolQuests(); PooledQuestRelation mQuestCreatureRelation; PooledQuestRelation mQuestGORelation; + friend class PoolQuestReloadFixTest; private: template void SpawnPool(uint32 pool_id, uint32 db_guid_or_pool_id); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 03ce1d185..01db0d650 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -30,6 +30,7 @@ #include "MapMgr.h" #include "MotdMgr.h" #include "ObjectMgr.h" +#include "PoolMgr.h" #include "ScriptMgr.h" #include "ServerMailMgr.h" #include "SkillDiscovery.h" @@ -270,6 +271,7 @@ public: LOG_INFO("server.loading", "Reloading Quests Relations..."); sObjectMgr->LoadQuestStartersAndEnders(); + sPoolMgr->ReSpawnPoolQuests(); handler->SendGlobalGMSysMessage("DB tables `*_queststarter` and `*_questender` reloaded."); return true; } @@ -490,6 +492,7 @@ public: { LOG_INFO("server.loading", "Loading Quests Relations... (`creature_queststarter`)"); sObjectMgr->LoadCreatureQuestStarters(); + sPoolMgr->ReSpawnPoolQuests(); handler->SendGlobalGMSysMessage("DB table `creature_queststarter` reloaded."); return true; } @@ -532,6 +535,7 @@ public: { LOG_INFO("server.loading", "Loading Quests Relations... (`gameobject_queststarter`)"); sObjectMgr->LoadGameobjectQuestStarters(); + sPoolMgr->ReSpawnPoolQuests(); handler->SendGlobalGMSysMessage("DB table `gameobject_queststarter` reloaded."); return true; } diff --git a/src/test/server/game/Pools/PoolQuestReloadTest.cpp b/src/test/server/game/Pools/PoolQuestReloadTest.cpp new file mode 100644 index 000000000..8cb97cc0e --- /dev/null +++ b/src/test/server/game/Pools/PoolQuestReloadTest.cpp @@ -0,0 +1,299 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/* + * Regression test for pool quest reload bug. + * + * When `.reload creature_queststarter` is executed, LoadQuestRelationsHelper() + * clears the creature quest relation map (_creatureQuestRelations) which + * contains the active pooled daily quest. It repopulates the pool mapping + * (mQuestCreatureRelation) but never calls Spawn1Object() to re-insert the + * active quest into the creature relation map. This causes ALL pool-based + * daily quests (Dalaran cooking, fishing, jewelcrafting, etc.) to vanish + * from their NPCs. + */ + +#include "ObjectMgr.h" +#include "PoolMgr.h" +#include "QuestDef.h" +#include "gtest/gtest.h" + +namespace +{ + +// Test IDs chosen to avoid collisions with real data +static constexpr uint32 TEST_QUEST_ID = 99998; +static constexpr uint32 TEST_CREATURE_ID = 99999; + +class PoolQuestReloadTest : public ::testing::Test +{ +protected: + void SetUp() override + { + creatureQuestMap = sObjectMgr->GetCreatureQuestRelationMap(); + + // Establish the pool-side mapping: quest -> creature + // This is what LoadQuestRelationsHelper populates for pooled quests + sPoolMgr->mQuestCreatureRelation.insert( + PooledQuestRelation::value_type(TEST_QUEST_ID, TEST_CREATURE_ID)); + } + + void TearDown() override + { + // Clean up: remove test entries from both maps + auto range = sPoolMgr->mQuestCreatureRelation.equal_range(TEST_QUEST_ID); + sPoolMgr->mQuestCreatureRelation.erase(range.first, range.second); + + // Remove any test entries left in creature quest relations + auto crRange = creatureQuestMap->equal_range(TEST_CREATURE_ID); + for (auto it = crRange.first; it != crRange.second; ) + { + if (it->second == TEST_QUEST_ID) + it = creatureQuestMap->erase(it); + else + ++it; + } + } + + /// Helper: count how many times quest appears on a creature in the quest relation map + uint32 CountQuestOnCreature(uint32 creatureId, uint32 questId) + { + uint32 count = 0; + auto range = creatureQuestMap->equal_range(creatureId); + for (auto it = range.first; it != range.second; ++it) + if (it->second == questId) + ++count; + return count; + } + + /// Simulate what Spawn1Object does: copy the active pool quest + /// from mQuestCreatureRelation into the creature quest relation map + void SimulateSpawn1Object(uint32 questId) + { + PoolGroup poolGroup; + PoolObject obj(questId, 0.0f); + poolGroup.Spawn1Object(&obj); + } + + /// Simulate what LoadQuestRelationsHelper does on reload: + /// 1. Clear the creature quest relation map + /// 2. Clear and repopulate mQuestCreatureRelation + /// Non-pooled quests would be re-added to the creature map, but + /// pooled quests only go into mQuestCreatureRelation. + void SimulateReload() + { + // Step 1: map.clear() — line 8589 of ObjectMgr.cpp + creatureQuestMap->clear(); + + // Step 2: poolRelationMap->clear() — line 8604 of ObjectMgr.cpp + sPoolMgr->mQuestCreatureRelation.clear(); + + // Step 3: Repopulate poolRelationMap from DB + // (In the real code this re-reads creature_queststarter LEFT JOIN pool_quest) + sPoolMgr->mQuestCreatureRelation.insert( + PooledQuestRelation::value_type(TEST_QUEST_ID, TEST_CREATURE_ID)); + + // NOTE: The real reload handler does NOT call Spawn1Object here. + // That is the bug. + } + + QuestRelations* creatureQuestMap = nullptr; +}; + +// ------------------------------------------------------------------ +// Baseline: Spawn1Object correctly adds pooled quest to NPC +// ------------------------------------------------------------------ +// cppcheck-suppress syntaxError +TEST_F(PoolQuestReloadTest, Spawn1ObjectAddsQuestToCreatureRelationMap) +{ + // Initially the quest should NOT be on the creature + EXPECT_EQ(CountQuestOnCreature(TEST_CREATURE_ID, TEST_QUEST_ID), 0u) + << "Quest should not be on creature before Spawn1Object"; + + // Spawn1Object reads from mQuestCreatureRelation and inserts into + // the creature quest relation map + SimulateSpawn1Object(TEST_QUEST_ID); + + EXPECT_EQ(CountQuestOnCreature(TEST_CREATURE_ID, TEST_QUEST_ID), 1u) + << "Quest should appear on creature after Spawn1Object"; +} + +// ------------------------------------------------------------------ +// BUG: Reload clears pooled quest without re-spawning it +// ------------------------------------------------------------------ +TEST_F(PoolQuestReloadTest, ReloadCreatureQuestStarterRemovesPooledQuest) +{ + // 1. Spawn the pool quest onto the NPC (normal startup behavior) + SimulateSpawn1Object(TEST_QUEST_ID); + ASSERT_EQ(CountQuestOnCreature(TEST_CREATURE_ID, TEST_QUEST_ID), 1u) + << "Precondition: quest must be on creature before reload"; + + // 2. Simulate `.reload creature_queststarter` + SimulateReload(); + + // 3. THE BUG: quest is gone from the NPC even though it's still + // the active daily in the pool + EXPECT_EQ(CountQuestOnCreature(TEST_CREATURE_ID, TEST_QUEST_ID), 0u) + << "BUG: After reload, pooled quest vanishes from creature " + "because Spawn1Object is never called"; + + // 4. Verify mQuestCreatureRelation still has the mapping + // (the pool system KNOWS about the quest, it's just not on the NPC) + auto range = sPoolMgr->mQuestCreatureRelation.equal_range(TEST_QUEST_ID); + EXPECT_NE(range.first, range.second) + << "Pool mapping should still exist after reload"; +} + +// ------------------------------------------------------------------ +// Calling Spawn1Object after reload would fix the problem +// ------------------------------------------------------------------ +TEST_F(PoolQuestReloadTest, Spawn1ObjectAfterReloadRestoresQuest) +{ + // Setup: spawn, reload (quest disappears) + SimulateSpawn1Object(TEST_QUEST_ID); + SimulateReload(); + ASSERT_EQ(CountQuestOnCreature(TEST_CREATURE_ID, TEST_QUEST_ID), 0u) + << "Precondition: quest must be missing after reload"; + + // Fix: call Spawn1Object again for the active pool quest + SimulateSpawn1Object(TEST_QUEST_ID); + + EXPECT_EQ(CountQuestOnCreature(TEST_CREATURE_ID, TEST_QUEST_ID), 1u) + << "Spawn1Object after reload should restore the quest on the NPC"; +} + +// ------------------------------------------------------------------ +// Non-pooled quests survive reload (contrast with pooled quests) +// ------------------------------------------------------------------ +TEST_F(PoolQuestReloadTest, NonPooledQuestSurvivesReload) +{ + static constexpr uint32 REGULAR_QUEST_ID = 99990; + + // A non-pooled quest is added directly to the creature quest map + // (this is what LoadQuestRelationsHelper does for quests without pool_entry) + creatureQuestMap->insert(QuestRelations::value_type(TEST_CREATURE_ID, REGULAR_QUEST_ID)); + + // Simulate reload: clear and repopulate + creatureQuestMap->clear(); + // Non-pooled quests get re-inserted directly (simulating the DB reload) + creatureQuestMap->insert(QuestRelations::value_type(TEST_CREATURE_ID, REGULAR_QUEST_ID)); + + EXPECT_EQ(CountQuestOnCreature(TEST_CREATURE_ID, REGULAR_QUEST_ID), 1u) + << "Non-pooled quests survive reload because they are re-inserted directly"; + + // Cleanup + auto range = creatureQuestMap->equal_range(TEST_CREATURE_ID); + for (auto it = range.first; it != range.second; ) + { + if (it->second == REGULAR_QUEST_ID) + it = creatureQuestMap->erase(it); + else + ++it; + } +} + +} // namespace + +// ------------------------------------------------------------------ +// PoolQuestReloadFixTest: exercises the actual ReSpawnPoolQuests() fix +// by setting up PoolMgr private state (friend class access). +// Must be at global scope to match the friend declaration in PoolMgr. +// ------------------------------------------------------------------ +class PoolQuestReloadFixTest : public ::testing::Test +{ +protected: + void SetUp() override + { + creatureQuestMap = sObjectMgr->GetCreatureQuestRelationMap(); + + // Set up pool infrastructure (private members via friend access) + sPoolMgr->mPoolTemplate[TEST_POOL_ID].MaxLimit = 1; + + // Create the pool group entry (Spawn1Object doesn't use pool group + // internals, it only reads mQuestCreatureRelation) + sPoolMgr->mPoolQuestGroups[TEST_POOL_ID].SetPoolId(TEST_POOL_ID); + + sPoolMgr->mQuestSearchMap[TEST_QUEST_ID] = TEST_POOL_ID; + + // Mark the quest as active/spawned + sPoolMgr->mSpawnedData.ActivateObject(TEST_QUEST_ID, TEST_POOL_ID); + + // Set up pool-side mapping: quest -> creature + sPoolMgr->mQuestCreatureRelation.insert( + PooledQuestRelation::value_type(TEST_QUEST_ID, TEST_CREATURE_ID)); + } + + void TearDown() override + { + // Clean up all test state from the singletons + sPoolMgr->mPoolTemplate.erase(TEST_POOL_ID); + sPoolMgr->mPoolQuestGroups.erase(TEST_POOL_ID); + sPoolMgr->mQuestSearchMap.erase(TEST_QUEST_ID); + sPoolMgr->mSpawnedData.RemoveObject(TEST_QUEST_ID, TEST_POOL_ID); + + auto range = sPoolMgr->mQuestCreatureRelation.equal_range(TEST_QUEST_ID); + sPoolMgr->mQuestCreatureRelation.erase(range.first, range.second); + + auto crRange = creatureQuestMap->equal_range(TEST_CREATURE_ID); + for (auto it = crRange.first; it != crRange.second; ) + { + if (it->second == TEST_QUEST_ID) + it = creatureQuestMap->erase(it); + else + ++it; + } + } + + static constexpr uint32 TEST_QUEST_ID = 99998; + static constexpr uint32 TEST_CREATURE_ID = 99999; + static constexpr uint32 TEST_POOL_ID = 99997; + + QuestRelations* creatureQuestMap = nullptr; +}; + +TEST_F(PoolQuestReloadFixTest, ReSpawnPoolQuestsRestoresQuestAfterReload) +{ + // 1. Spawn the quest onto the NPC (simulates normal startup) + PoolGroup poolGroup; + PoolObject obj(TEST_QUEST_ID, 0.0f); + poolGroup.Spawn1Object(&obj); + + auto count = [&]() { + uint32 n = 0; + auto range = creatureQuestMap->equal_range(TEST_CREATURE_ID); + for (auto it = range.first; it != range.second; ++it) + if (it->second == TEST_QUEST_ID) + ++n; + return n; + }; + + ASSERT_EQ(count(), 1u) << "Quest should be on creature before reload"; + + // 2. Simulate reload: clear creature quest map and repopulate pool mapping + creatureQuestMap->clear(); + sPoolMgr->mQuestCreatureRelation.clear(); + sPoolMgr->mQuestCreatureRelation.insert( + PooledQuestRelation::value_type(TEST_QUEST_ID, TEST_CREATURE_ID)); + + ASSERT_EQ(count(), 0u) << "Quest should be gone after reload clears the map"; + + // 3. THE FIX: ReSpawnPoolQuests re-inserts active pool quests + sPoolMgr->ReSpawnPoolQuests(); + + EXPECT_EQ(count(), 1u) + << "ReSpawnPoolQuests should restore active pool quests after reload"; +} From 6bb76401ba188d1db4b887d1efe650973f4a2e94 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Fri, 13 Feb 2026 09:53:38 +0100 Subject: [PATCH 097/335] fix(DB/Spell): Set Avenging Fury range effect to 2 yards. (#24683) Co-authored-by: Nyeriah --- data/sql/updates/pending_db_world/Avenging_Fury.sql | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 data/sql/updates/pending_db_world/Avenging_Fury.sql diff --git a/data/sql/updates/pending_db_world/Avenging_Fury.sql b/data/sql/updates/pending_db_world/Avenging_Fury.sql new file mode 100644 index 000000000..8ed95612a --- /dev/null +++ b/data/sql/updates/pending_db_world/Avenging_Fury.sql @@ -0,0 +1,12 @@ + +-- Set Avenging Fury target on self +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 30680; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 30680) 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 +(30680, 0, 3, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 57742, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Brood General - On Just Died - Cast \'Avenging Fury\''); + +-- Set Condition +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 3) AND (`SourceEntry` = 57742) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 35) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 1) AND (`ConditionValue2` = 2) AND (`ConditionValue3` = 4); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 3, 57742, 0, 0, 35, 0, 1, 2, 4, 0, 0, 0, '', 'Avenging Fury (57742) - Only hit targets within 2 yards of caster'); From a262273eced40c306d14d0bd5d588fd7b1c6e5b7 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Fri, 13 Feb 2026 05:53:59 -0300 Subject: [PATCH 098/335] fix(Scripts/Naxxramas): Fix Undying/Immortal credit (#24694) --- .../Naxxramas/instance_naxxramas.cpp | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index 918853184..a6498b867 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -426,20 +426,49 @@ public: 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_UNDYING_THE_FOUR_HORSEMEN: case ACHIEV_CRITERIA_THE_IMMORTAL_THE_FOUR_HORSEMEN: + case ACHIEV_CRITERIA_THE_UNDYING_MAEXXNA: case ACHIEV_CRITERIA_THE_IMMORTAL_MAEXXNA: + case ACHIEV_CRITERIA_THE_UNDYING_LOATHEB: case ACHIEV_CRITERIA_THE_IMMORTAL_LOATHEB: + case ACHIEV_CRITERIA_THE_UNDYING_THADDIUS: case ACHIEV_CRITERIA_THE_IMMORTAL_THADDIUS: - for (int i = 0; i < MAX_ENCOUNTERS; ++i) - if (GetBossState(i) != DONE) + { + uint32 currentBoss; + switch (criteria_id) + { + case ACHIEV_CRITERIA_THE_UNDYING_KELTHUZAD: + case ACHIEV_CRITERIA_THE_IMMORTAL_KELTHUZAD: + currentBoss = BOSS_KELTHUZAD; + break; + case ACHIEV_CRITERIA_THE_UNDYING_THE_FOUR_HORSEMEN: + case ACHIEV_CRITERIA_THE_IMMORTAL_THE_FOUR_HORSEMEN: + currentBoss = BOSS_HORSEMAN; + break; + case ACHIEV_CRITERIA_THE_UNDYING_MAEXXNA: + case ACHIEV_CRITERIA_THE_IMMORTAL_MAEXXNA: + currentBoss = BOSS_MAEXXNA; + break; + case ACHIEV_CRITERIA_THE_UNDYING_LOATHEB: + case ACHIEV_CRITERIA_THE_IMMORTAL_LOATHEB: + currentBoss = BOSS_LOATHEB; + break; + case ACHIEV_CRITERIA_THE_UNDYING_THADDIUS: + case ACHIEV_CRITERIA_THE_IMMORTAL_THADDIUS: + currentBoss = BOSS_THADDIUS; + break; + default: + return false; + } + + for (uint32 i = 0; i < MAX_ENCOUNTERS; ++i) + if (i != currentBoss && GetBossState(i) != DONE) return false; return !GetPersistentData(PERSISTENT_DATA_IMMORTAL_FAIL); + } default: return false; } From 6ebc6c9f2a2e83d4e82313480edcd8447a6320f7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 13 Feb 2026 09:01:08 +0000 Subject: [PATCH 099/335] chore(DB): import pending files Referenced commit(s): 6bb76401ba188d1db4b887d1efe650973f4a2e94 --- .../Avenging_Fury.sql => db_world/2026_02_13_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/Avenging_Fury.sql => db_world/2026_02_13_00.sql} (97%) diff --git a/data/sql/updates/pending_db_world/Avenging_Fury.sql b/data/sql/updates/db_world/2026_02_13_00.sql similarity index 97% rename from data/sql/updates/pending_db_world/Avenging_Fury.sql rename to data/sql/updates/db_world/2026_02_13_00.sql index 8ed95612a..12ddd64d0 100644 --- a/data/sql/updates/pending_db_world/Avenging_Fury.sql +++ b/data/sql/updates/db_world/2026_02_13_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_12_01 -> 2026_02_13_00 -- Set Avenging Fury target on self UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 30680; From 0e50b3dedefeab138170ece1dad66638465c7b1f Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 13 Feb 2026 06:02:52 -0300 Subject: [PATCH 100/335] fix(Core/Movement): Don't take height into consideration for follow teleports (#24690) --- .../Movement/MovementGenerators/TargetedMovementGenerator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 915124257..7c979f98e 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -656,7 +656,7 @@ bool FollowMovementGenerator::DoUpdate(T* owner, uint32 time_diff) // Teleport if stuck and too far away if (cOwner && isFollowingPlayer) { - float distance = owner->GetDistance(target); + float const distance = owner->GetDistance2d(target); if (distance > 20.f) { float teleX; @@ -664,6 +664,7 @@ bool FollowMovementGenerator::DoUpdate(T* owner, uint32 time_diff) float teleZ; target->GetClosePoint(teleX, teleY, teleZ, owner->GetCombatReach()); + teleZ = owner->GetMapHeight(teleX, teleY, teleZ); owner->NearTeleportTo(teleX, teleY, teleZ, target->GetOrientation()); _lastTargetPosition.reset(); _lastPredictedPosition.reset(); From 36a1f31c2911e312a894c7a02027b98c1af79dbc Mon Sep 17 00:00:00 2001 From: sogladev Date: Fri, 13 Feb 2026 12:17:21 +0100 Subject: [PATCH 101/335] fix(Core/ObjectMgr): update npc_vendor.maxcount to u32 from u8 (#24685) --- .../updates/pending_db_world/rev_1770900184961304377.sql | 8 ++++++++ src/server/game/Globals/ObjectMgr.cpp | 8 ++++---- src/server/game/Globals/ObjectMgr.h | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1770900184961304377.sql diff --git a/data/sql/updates/pending_db_world/rev_1770900184961304377.sql b/data/sql/updates/pending_db_world/rev_1770900184961304377.sql new file mode 100644 index 000000000..d155998d1 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770900184961304377.sql @@ -0,0 +1,8 @@ +-- +-- uint8 to uint32 conversion for maxcount in npc_vendor +-- game_event_npc_vendor does not need to be updated +ALTER TABLE `npc_vendor` MODIFY COLUMN `maxcount` int unsigned DEFAULT 0 NOT NULL; + +DELETE FROM `npc_vendor` WHERE (`entry` = 29561) AND (`item` IN (21177)); +INSERT INTO `npc_vendor` (`entry`, `slot`, `item`, `maxcount`, `incrtime`, `ExtendedCost`, `VerifiedBuild`) VALUES +(29561, 0, 21177, 300, 600, 0, 0); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 1d0b5bdfe..d2e3c8ee5 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -9799,7 +9799,7 @@ int ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, std::set* s count += LoadReferenceVendor(vendor, -item_id, skip_vendors); else { - int32 maxcount = fields[1].Get(); + uint32 maxcount = fields[1].Get(); uint32 incrtime = fields[2].Get(); uint32 ExtendedCost = fields[3].Get(); @@ -9849,7 +9849,7 @@ void ObjectMgr::LoadVendors() count += LoadReferenceVendor(entry, -item_id, &skip_vendors); else { - uint32 maxcount = fields[2].Get(); + uint32 maxcount = fields[2].Get(); uint32 incrtime = fields[3].Get(); uint32 ExtendedCost = fields[4].Get(); @@ -9998,7 +9998,7 @@ void ObjectMgr::LoadGossipMenuItems() LOG_INFO("server.loading", " "); } -void ObjectMgr::AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, bool persist /*= true*/) +void ObjectMgr::AddVendorItem(uint32 entry, uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedCost, bool persist /*= true*/) { VendorItemData& vList = _cacheVendorItemStore[entry]; vList.AddItem(item, maxcount, incrtime, extendedCost); @@ -10039,7 +10039,7 @@ bool ObjectMgr::RemoveVendorItem(uint32 entry, uint32 item, bool persist /*= tru return true; } -bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 item_id, int32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* player, std::set* /*skip_vendors*/, uint32 /*ORnpcflag*/) const +bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* player, std::set* /*skip_vendors*/, uint32 /*ORnpcflag*/) const { /* CreatureTemplate const* cInfo = GetCreatureTemplate(vendor_entry); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index d9f458293..0afcfdc5b 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1417,9 +1417,9 @@ public: return &iter->second; } - void AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, bool persist = true); // for event + void AddVendorItem(uint32 entry, uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedCost, bool persist = true); // for event bool RemoveVendorItem(uint32 entry, uint32 item, bool persist = true); // for event - bool IsVendorItemValid(uint32 vendor_entry, uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* player = nullptr, std::set* skip_vendors = nullptr, uint32 ORnpcflag = 0) const; + bool IsVendorItemValid(uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* player = nullptr, std::set* skip_vendors = nullptr, uint32 ORnpcflag = 0) const; void LoadScriptNames(); ScriptNameContainer& GetScriptNames() { return _scriptNamesStore; } From 8cbc8b081e7af478d82b61fef723dd1b3669f04e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 13 Feb 2026 11:42:23 +0000 Subject: [PATCH 102/335] chore(DB): import pending files Referenced commit(s): 36a1f31c2911e312a894c7a02027b98c1af79dbc --- .../rev_1770900184961304377.sql => db_world/2026_02_13_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1770900184961304377.sql => db_world/2026_02_13_01.sql} (90%) diff --git a/data/sql/updates/pending_db_world/rev_1770900184961304377.sql b/data/sql/updates/db_world/2026_02_13_01.sql similarity index 90% rename from data/sql/updates/pending_db_world/rev_1770900184961304377.sql rename to data/sql/updates/db_world/2026_02_13_01.sql index d155998d1..c7d1dfc11 100644 --- a/data/sql/updates/pending_db_world/rev_1770900184961304377.sql +++ b/data/sql/updates/db_world/2026_02_13_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_13_00 -> 2026_02_13_01 -- -- uint8 to uint32 conversion for maxcount in npc_vendor -- game_event_npc_vendor does not need to be updated From 2473f3513d309b6ae3fb92d9aa932bccaabbc890 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Fri, 13 Feb 2026 08:49:24 -0300 Subject: [PATCH 103/335] feat(Scripts/Commands): Show boss name in instance boss state (#24698) --- .../updates/pending_db_world/rev_1883243.sql | 3 ++ src/server/scripts/Commands/cs_instance.cpp | 44 ++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 data/sql/updates/pending_db_world/rev_1883243.sql diff --git a/data/sql/updates/pending_db_world/rev_1883243.sql b/data/sql/updates/pending_db_world/rev_1883243.sql new file mode 100644 index 000000000..e0d868cad --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1883243.sql @@ -0,0 +1,3 @@ +DELETE FROM `acore_string` WHERE `entry` = 5058; +INSERT INTO `acore_string` (`entry`, `content_default`, `locale_koKR`, `locale_frFR`, `locale_deDE`, `locale_zhCN`, `locale_zhTW`, `locale_esES`, `locale_esMX`, `locale_ruRU`) VALUES +(5058,'Boss id {} ({}) state is {} ({}).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp index a6ee3bc5c..078594a8a 100644 --- a/src/server/scripts/Commands/cs_instance.cpp +++ b/src/server/scripts/Commands/cs_instance.cpp @@ -17,11 +17,13 @@ #include "Chat.h" #include "CommandScript.h" +#include "DBCStores.h" #include "GameTime.h" #include "InstanceSaveMgr.h" #include "InstanceScript.h" #include "Language.h" #include "MapMgr.h" +#include "ObjectMgr.h" #include "Player.h" using namespace Acore::ChatCommands; @@ -230,11 +232,51 @@ public: return false; } + // Build a map of encounterIndex -> encounterName from DBC data + std::unordered_map encounterNames; + Difficulty difficulty = map->GetDifficulty(); + + // For heroic ICC/Ruby Sanctum, encounters are only defined + // for normal difficulty in the DBC, use the same fallback + // pattern as Map::UpdateEncounterState + DungeonEncounterList const* encounters = nullptr; + if ((map->GetId() == 631 || map->GetId() == 724) + && map->IsHeroic()) + { + encounters = sObjectMgr->GetDungeonEncounterList( + map->GetId(), + !map->Is25ManRaid() + ? RAID_DIFFICULTY_10MAN_NORMAL + : RAID_DIFFICULTY_25MAN_NORMAL); + } + else + { + Difficulty diffFixed = IsSharedDifficultyMap(map->GetId()) + ? Difficulty(difficulty % 2) + : difficulty; + encounters = sObjectMgr->GetDungeonEncounterList( + map->GetId(), diffFixed); + } + + if (encounters) + { + for (auto const* encounter : *encounters) + encounterNames[encounter->dbcEntry->encounterIndex] + = encounter->dbcEntry->encounterName[0]; + } + for (uint8 i = 0; i < map->GetInstanceScript()->GetEncounterCount(); ++i) { uint32 state = map->GetInstanceScript()->GetBossState(i); std::string stateName = InstanceScript::GetBossStateName(state); - handler->PSendSysMessage(LANG_COMMAND_INST_GET_BOSS_STATE, i, state, stateName); + + auto it = encounterNames.find(i); + std::string bossName = (it != encounterNames.end() + && it->second) ? it->second : "Unknown"; + + handler->PSendSysMessage( + LANG_COMMAND_INST_GET_BOSS_STATE, + i, bossName, state, stateName); } return true; From 854a53ca45f0dd9c8148eab5b4948fba6b8fc9a8 Mon Sep 17 00:00:00 2001 From: Billy Jones Date: Fri, 13 Feb 2026 11:50:10 +0000 Subject: [PATCH 104/335] fix(DB/Quest): "Speak with Ruga" missing quest starters (#24677) --- data/sql/updates/pending_db_world/rev_1770763543728544590.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770763543728544590.sql diff --git a/data/sql/updates/pending_db_world/rev_1770763543728544590.sql b/data/sql/updates/pending_db_world/rev_1770763543728544590.sql new file mode 100644 index 000000000..014c975c5 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770763543728544590.sql @@ -0,0 +1,4 @@ +DELETE FROM `creature_queststarter` WHERE (`quest` = 1823) AND (`id` IN (3041, 4595)); +INSERT INTO `creature_queststarter` (`id`, `quest`) VALUES +(3041, 1823), +(4595, 1823); From 64448d550f556734ee02184033aabed184202bad Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 13 Feb 2026 11:50:47 +0000 Subject: [PATCH 105/335] chore(DB): import pending files Referenced commit(s): 8cbc8b081e7af478d82b61fef723dd1b3669f04e --- .../rev_1770763543728544590.sql => db_world/2026_02_13_02.sql} | 1 + .../rev_1883243.sql => db_world/2026_02_13_03.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1770763543728544590.sql => db_world/2026_02_13_02.sql} (79%) rename data/sql/updates/{pending_db_world/rev_1883243.sql => db_world/2026_02_13_03.sql} (87%) diff --git a/data/sql/updates/pending_db_world/rev_1770763543728544590.sql b/data/sql/updates/db_world/2026_02_13_02.sql similarity index 79% rename from data/sql/updates/pending_db_world/rev_1770763543728544590.sql rename to data/sql/updates/db_world/2026_02_13_02.sql index 014c975c5..872cad573 100644 --- a/data/sql/updates/pending_db_world/rev_1770763543728544590.sql +++ b/data/sql/updates/db_world/2026_02_13_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_13_01 -> 2026_02_13_02 DELETE FROM `creature_queststarter` WHERE (`quest` = 1823) AND (`id` IN (3041, 4595)); INSERT INTO `creature_queststarter` (`id`, `quest`) VALUES (3041, 1823), diff --git a/data/sql/updates/pending_db_world/rev_1883243.sql b/data/sql/updates/db_world/2026_02_13_03.sql similarity index 87% rename from data/sql/updates/pending_db_world/rev_1883243.sql rename to data/sql/updates/db_world/2026_02_13_03.sql index e0d868cad..e42be4dfa 100644 --- a/data/sql/updates/pending_db_world/rev_1883243.sql +++ b/data/sql/updates/db_world/2026_02_13_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_13_02 -> 2026_02_13_03 DELETE FROM `acore_string` WHERE `entry` = 5058; INSERT INTO `acore_string` (`entry`, `content_default`, `locale_koKR`, `locale_frFR`, `locale_deDE`, `locale_zhCN`, `locale_zhTW`, `locale_esES`, `locale_esMX`, `locale_ruRU`) VALUES (5058,'Boss id {} ({}) state is {} ({}).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); From c251b468920328e00e9ab0e99fc756cfffd4201c Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Fri, 13 Feb 2026 10:34:59 -0300 Subject: [PATCH 106/335] chore: Update SQL update guidelines in CLAUDE.md (#24700) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- CLAUDE.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 5ddfc3343..08a09ab39 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -84,8 +84,9 @@ Scripts follow a registration pattern: - **acore_characters** - Character data, inventories, progress (`data/sql/base/db_characters/`) - **acore_world** - Game content: creatures, items, quests, spells, loot (`data/sql/base/db_world/`) -SQL updates go in `data/sql/updates/pending_*` with separate subdirectories per database until pull request is merged. -SQL updates go in `data/sql/updates/` with separate subdirectories per database after their pull request is merged. +- SQL updates go in `data/sql/updates/pending_*` with separate subdirectories per database until pull request is merged. Pending SQL files are assigned random names. +- SQL updates go in `data/sql/updates/` with separate subdirectories per database after their pull request is merged. +- SQL files outside the `data/sql/updates/pending_*` folders should never be updated. ### Module system From 24f5f289f0da072d7c28e53fe21a83e2928a5b56 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Fri, 13 Feb 2026 09:22:45 -0500 Subject: [PATCH 107/335] refactor(Core/Packets): Rewrite various instance packets to modern class. (#22762) --- src/server/game/Entities/Player/Player.h | 9 +- .../game/Entities/Player/PlayerMisc.cpp | 52 ++++---- src/server/game/Groups/Group.cpp | 4 +- src/server/game/Handlers/MiscHandler.cpp | 42 +++--- src/server/game/Server/Packets/AllPackets.h | 1 + .../game/Server/Packets/InstancePackets.cpp | 73 +++++++++++ .../game/Server/Packets/InstancePackets.h | 123 ++++++++++++++++++ src/server/game/Server/WorldSession.h | 16 ++- 8 files changed, 258 insertions(+), 62 deletions(-) create mode 100644 src/server/game/Server/Packets/InstancePackets.cpp create mode 100644 src/server/game/Server/Packets/InstancePackets.h diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 92b42d735..0e75edaf6 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -794,6 +794,13 @@ enum InstanceResetWarningType RAID_INSTANCE_EXPIRED = 5 }; +enum InstanceResetFailureReason : uint32 +{ + INSTANCE_RESET_FAILED = 0, // Cannot reset %s. There are players still inside the instance. + INSTANCE_RESET_FAILED_OFFLINE = 1, // Cannot reset %s. There are players offline in your party. + INSTANCE_RESET_FAILED_ZONING = 2, // Cannot reset %s. There are players in your party attempting to zone into an instance. +}; + class InstanceSave; enum RestFlag @@ -2010,7 +2017,7 @@ public: void SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty = -1); static void ResetInstances(ObjectGuid guid, uint8 method, bool isRaid); void SendResetInstanceSuccess(uint32 MapId); - void SendResetInstanceFailed(uint32 reason, uint32 MapId); + void SendResetInstanceFailed(InstanceResetFailureReason reason, uint32 MapId); void SendResetFailedNotify(uint32 mapid); bool UpdatePosition(float x, float y, float z, float orientation, bool teleport = false) override; diff --git a/src/server/game/Entities/Player/PlayerMisc.cpp b/src/server/game/Entities/Player/PlayerMisc.cpp index 0d3311a6c..91459d848 100644 --- a/src/server/game/Entities/Player/PlayerMisc.cpp +++ b/src/server/game/Entities/Player/PlayerMisc.cpp @@ -17,6 +17,7 @@ #include "AccountMgr.h" #include "GameTime.h" +#include "InstancePackets.h" #include "MapMgr.h" #include "Player.h" #include "ScriptMgr.h" @@ -166,29 +167,25 @@ void Player::SendExplorationExperience(uint32 Area, uint32 Experience) void Player::SendDungeonDifficulty(bool IsInGroup) { - uint8 val = 0x00000001; - WorldPacket data(MSG_SET_DUNGEON_DIFFICULTY, 12); - data << (uint32)GetDungeonDifficulty(); - data << uint32(val); - data << uint32(IsInGroup); - SendDirectMessage(&data); + WorldPackets::Instance::SetDungeonDifficulty setDungeonDifficulty; + setDungeonDifficulty.Difficulty = GetDungeonDifficulty(); + setDungeonDifficulty.IsInGroup = IsInGroup; + SendDirectMessage(setDungeonDifficulty.Write()); } void Player::SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty) { - uint8 val = 0x00000001; - WorldPacket data(MSG_SET_RAID_DIFFICULTY, 12); - data << uint32(forcedDifficulty == -1 ? GetRaidDifficulty() : forcedDifficulty); - data << uint32(val); - data << uint32(IsInGroup); - SendDirectMessage(&data); + WorldPackets::Instance::SetRaidDifficulty setRaidDifficulty; + setRaidDifficulty.Difficulty = (forcedDifficulty == -1 ? GetRaidDifficulty() : forcedDifficulty); + setRaidDifficulty.IsInGroup = IsInGroup; + SendDirectMessage(setRaidDifficulty.Write()); } void Player::SendResetFailedNotify(uint32 mapid) { - WorldPacket data(SMSG_RESET_FAILED_NOTIFY, 4); - data << uint32(mapid); - SendDirectMessage(&data); + WorldPackets::Instance::ResetFailedNotify resetFailedNotify; + resetFailedNotify.MapId = mapid; + SendDirectMessage(resetFailedNotify.Write()); } /// Reset all solo instances and optionally send a message on success for each @@ -220,7 +217,7 @@ void Player::ResetInstances(ObjectGuid guid, uint8 method, bool isRaid) } else { - p->SendResetInstanceFailed(0, instanceSave->GetMapId()); + p->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId()); } sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId()); @@ -255,7 +252,7 @@ void Player::ResetInstances(ObjectGuid guid, uint8 method, bool isRaid) } else { - p->SendResetInstanceFailed(0, instanceSave->GetMapId()); + p->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId()); } sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId()); @@ -325,22 +322,17 @@ void Player::ResetInstances(ObjectGuid guid, uint8 method, bool isRaid) void Player::SendResetInstanceSuccess(uint32 MapId) { - WorldPacket data(SMSG_INSTANCE_RESET, 4); - data << uint32(MapId); - SendDirectMessage(&data); + WorldPackets::Instance::InstanceReset instanceReset; + instanceReset.MapId = MapId; + SendDirectMessage(instanceReset.Write()); } -void Player::SendResetInstanceFailed(uint32 reason, uint32 MapId) +void Player::SendResetInstanceFailed(InstanceResetFailureReason reason, uint32 MapId) { - /*reasons for instance reset failure: - // 0: There are players inside the instance. - // 1: There are players offline in your party. - // 2>: There are players in your party attempting to zone into an instance. - */ - WorldPacket data(SMSG_INSTANCE_RESET_FAILED, 4); - data << uint32(reason); - data << uint32(MapId); - SendDirectMessage(&data); + WorldPackets::Instance::InstanceResetFailed instanceResetFailed; + instanceResetFailed.Reason = reason; + instanceResetFailed.MapId = MapId; + SendDirectMessage(instanceResetFailed.Write()); } /*********************************************************/ diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index d2338ca81..548c4787f 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -2150,7 +2150,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* leader) } else { - leader->SendResetInstanceFailed(0, instanceSave->GetMapId()); + leader->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId()); } sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId()); @@ -2178,7 +2178,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* leader) } else { - leader->SendResetInstanceFailed(0, instanceSave->GetMapId()); + leader->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId()); } sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId()); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index c8af95af2..4c3ba5502 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -29,6 +29,7 @@ #include "GossipDef.h" #include "Group.h" #include "GuildMgr.h" +#include "InstancePackets.h" #include "InstanceScript.h" #include "Language.h" #include "Log.h" @@ -1240,7 +1241,7 @@ void WorldSession::HandleSetTitleOpcode(WorldPacket& recv_data) GetPlayer()->SetUInt32Value(PLAYER_CHOSEN_TITLE, title); } -void WorldSession::HandleResetInstancesOpcode(WorldPacket& /*recv_data*/) +void WorldSession::HandleResetInstancesOpcode(WorldPackets::Instance::ResetInstances& /*packet*/) { LOG_DEBUG("network", "WORLD: CMSG_RESET_INSTANCES"); @@ -1253,17 +1254,14 @@ void WorldSession::HandleResetInstancesOpcode(WorldPacket& /*recv_data*/) Player::ResetInstances(_player->GetGUID(), INSTANCE_RESET_ALL, false); } -void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data) +void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPackets::Instance::SetDungeonDifficultyClient& packet) { LOG_DEBUG("network", "MSG_SET_DUNGEON_DIFFICULTY"); - uint32 mode; - recv_data >> mode; - - if (mode >= MAX_DUNGEON_DIFFICULTY) + if (packet.Mode >= MAX_DUNGEON_DIFFICULTY) return; - if (Difficulty(mode) == _player->GetDungeonDifficulty()) + if (Difficulty(packet.Mode) == _player->GetDungeonDifficulty()) return; Group* group = _player->GetGroup(); @@ -1291,7 +1289,7 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data) } group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, _player); - group->SetDungeonDifficulty(Difficulty(mode)); + group->SetDungeonDifficulty(Difficulty(packet.Mode)); } } else @@ -1302,21 +1300,18 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data) return; } Player::ResetInstances(_player->GetGUID(), INSTANCE_RESET_CHANGE_DIFFICULTY, false); - _player->SetDungeonDifficulty(Difficulty(mode)); + _player->SetDungeonDifficulty(Difficulty(packet.Mode)); } } -void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recv_data) +void WorldSession::HandleSetRaidDifficultyOpcode(WorldPackets::Instance::SetRaidDifficultyClient& packet) { LOG_DEBUG("network", "MSG_SET_RAID_DIFFICULTY"); - uint32 mode; - recv_data >> mode; - - if (mode >= MAX_RAID_DIFFICULTY) + if (packet.Mode >= MAX_RAID_DIFFICULTY) return; - if (Difficulty(mode) == _player->GetRaidDifficulty()) + if (Difficulty(packet.Mode) == _player->GetRaidDifficulty()) return; Group* group = _player->GetGroup(); @@ -1357,7 +1352,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recv_data) return; } - if (IsSharedDifficultyMap(groupGuy->GetMap()->GetId()) && (uint32(mode % 2) == uint32(_player->GetRaidDifficulty() % 2)) && group->isRaidGroup()) + if (IsSharedDifficultyMap(groupGuy->GetMap()->GetId()) && (uint32(packet.Mode % 2) == uint32(_player->GetRaidDifficulty() % 2)) && group->isRaidGroup()) { if (!currMap) currMap = groupGuy->GetMap(); @@ -1371,7 +1366,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recv_data) if (!groupGuy->IsAlive() || groupGuy->IsInCombat() || groupGuy->GetVictim() || groupGuy->m_mover != groupGuy || groupGuy->IsNonMeleeSpellCast(true) || (!groupGuy->GetMotionMaster()->empty() && groupGuy->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE) || !groupGuy->movespline->Finalized() || !groupGuy->GetMap()->ToInstanceMap() || !groupGuy->GetMap()->ToInstanceMap()->GetInstanceScript() || groupGuy->GetMap()->ToInstanceMap()->GetInstanceScript()->IsEncounterInProgress() - || !groupGuy->Satisfy(sObjectMgr->GetAccessRequirement(groupGuy->GetMap()->GetId(), Difficulty(mode)), groupGuy->GetMap()->GetId(), false)) + || !groupGuy->Satisfy(sObjectMgr->GetAccessRequirement(groupGuy->GetMap()->GetId(), Difficulty(packet.Mode)), groupGuy->GetMap()->GetId(), false)) { _player->SendRaidDifficulty(group != nullptr); return; @@ -1443,12 +1438,12 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recv_data) if (!anyoneInside) // pussywizard: don't reset if changing ICC/RS difficulty while inside group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true, _player); - group->SetRaidDifficulty(Difficulty(mode)); + group->SetRaidDifficulty(Difficulty(packet.Mode)); group->SetDifficultyChangePrevention(DIFFICULTY_PREVENTION_CHANGE_RECENTLY_CHANGED); for (std::map::iterator itr = playerTeleport.begin(); itr != playerTeleport.end(); ++itr) { - itr->first->SetRaidDifficulty(Difficulty(mode)); // needed for teleport not to fail + itr->first->SetRaidDifficulty(Difficulty(packet.Mode)); // needed for teleport not to fail if (!itr->first->TeleportTo(*(foundMaps.begin()), itr->second.GetPositionX(), itr->second.GetPositionY(), itr->second.GetPositionZ(), itr->second.GetOrientation())) itr->first->GetSession()->KickPlayer("HandleSetRaidDifficultyOpcode 2"); } @@ -1462,7 +1457,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recv_data) return; } Player::ResetInstances(_player->GetGUID(), INSTANCE_RESET_CHANGE_DIFFICULTY, true); - _player->SetRaidDifficulty(Difficulty(mode)); + _player->SetRaidDifficulty(Difficulty(packet.Mode)); } } @@ -1698,11 +1693,8 @@ void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recv_data*/) _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation()); } -void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket) +void WorldSession::HandleInstanceLockResponse(WorldPackets::Instance::InstanceLockResponse& packet) { - uint8 accept; - recvPacket >> accept; - if (!_player->HasPendingBind() || _player->GetPendingBind() != _player->GetInstanceId() || (_player->GetGroup() && _player->GetGroup()->isLFGGroup() && _player->GetGroup()->IsLfgRandomInstance())) { LOG_DEBUG("network.opcode", "InstanceLockResponse: Player {} ({}) tried to bind himself/teleport to graveyard without a pending bind!", @@ -1710,7 +1702,7 @@ void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket) return; } - if (accept) + if (packet.Accept) _player->BindToInstance(); else _player->RepopAtGraveyard(); diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index 0f2774836..8cdbc7cda 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -25,6 +25,7 @@ #include "CombatLogPackets.h" #include "CombatPackets.h" #include "GuildPackets.h" +#include "InstancePackets.h" #include "ItemPackets.h" #include "LFGPackets.h" #include "MiscPackets.h" diff --git a/src/server/game/Server/Packets/InstancePackets.cpp b/src/server/game/Server/Packets/InstancePackets.cpp new file mode 100644 index 000000000..9a344f807 --- /dev/null +++ b/src/server/game/Server/Packets/InstancePackets.cpp @@ -0,0 +1,73 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "InstancePackets.h" + +WorldPacket const* WorldPackets::Instance::InstanceReset::Write() +{ + _worldPacket << MapId; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Instance::InstanceResetFailed::Write() +{ + _worldPacket << Reason; + _worldPacket << MapId; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Instance::SetDungeonDifficulty::Write() +{ + _worldPacket << Difficulty; + _worldPacket << Unk; + _worldPacket << IsInGroup; + + return &_worldPacket; +} + +void WorldPackets::Instance::SetDungeonDifficultyClient::Read() +{ + _worldPacket >> Mode; +} + +WorldPacket const* WorldPackets::Instance::ResetFailedNotify::Write() +{ + _worldPacket << MapId; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Instance::SetRaidDifficulty::Write() +{ + _worldPacket << Difficulty; + _worldPacket << Unk; + _worldPacket << IsInGroup; + + return &_worldPacket; +} + +void WorldPackets::Instance::SetRaidDifficultyClient::Read() +{ + _worldPacket >> Mode; +} + +void WorldPackets::Instance::InstanceLockResponse::Read() +{ + _worldPacket >> Accept; +} diff --git a/src/server/game/Server/Packets/InstancePackets.h b/src/server/game/Server/Packets/InstancePackets.h new file mode 100644 index 000000000..3f95b6242 --- /dev/null +++ b/src/server/game/Server/Packets/InstancePackets.h @@ -0,0 +1,123 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef InstancePackets_h__ +#define InstancePackets_h__ + +#include "Packet.h" +#include "Player.h" + +namespace WorldPackets +{ + namespace Instance + { + class InstanceReset final : public ServerPacket + { + public: + InstanceReset() : ServerPacket(SMSG_INSTANCE_RESET, 4) {} + + WorldPacket const* Write() override; + + uint32 MapId = 0; + }; + + class InstanceResetFailed final : public ServerPacket + { + public: + InstanceResetFailed() : ServerPacket(SMSG_INSTANCE_RESET_FAILED, 4 + 4) {} + + WorldPacket const* Write() override; + + InstanceResetFailureReason Reason = INSTANCE_RESET_FAILED; + uint32 MapId = 0; + }; + + class SetDungeonDifficulty final : public ServerPacket + { + public: + SetDungeonDifficulty() : ServerPacket(MSG_SET_DUNGEON_DIFFICULTY, 12) {} + + WorldPacket const* Write() override; + + uint32 Difficulty = -1; // @TODO: Check if cast to Dungeon type will cause problems (SetRaidDifficulty() too) + uint32 Unk = 0x00000001; + uint32 IsInGroup = 0; + }; + + class SetDungeonDifficultyClient final : public ClientPacket + { + public: + SetDungeonDifficultyClient(WorldPacket&& packet) : ClientPacket(MSG_SET_DUNGEON_DIFFICULTY, std::move(packet)) {} + + void Read() override; + + uint32 Mode = DUNGEON_DIFFICULTY_NORMAL; + }; + + class ResetFailedNotify final : public ServerPacket + { + public: + ResetFailedNotify() : ServerPacket(SMSG_RESET_FAILED_NOTIFY, 4) {} + + WorldPacket const* Write() override; + + uint32 MapId = 0; + }; + + class SetRaidDifficulty final : public ServerPacket + { + public: + SetRaidDifficulty() : ServerPacket(MSG_SET_RAID_DIFFICULTY, 12) {} + + WorldPacket const* Write() override; + + uint32 Difficulty = -1; + uint32 Unk = 0x00000001; + uint32 IsInGroup = 0; + }; + + class SetRaidDifficultyClient final : public ClientPacket + { + public: + SetRaidDifficultyClient(WorldPacket&& packet) : ClientPacket(MSG_SET_RAID_DIFFICULTY, std::move(packet)) {} + + void Read() override; + + uint32 Mode = RAID_DIFFICULTY_10MAN_NORMAL; + }; + + class ResetInstances final : public ClientPacket + { + public: + ResetInstances(WorldPacket&& packet) : ClientPacket(CMSG_RESET_INSTANCES, std::move(packet)) {} + + void Read() override {}; + }; + + class InstanceLockResponse final : public ClientPacket + { + public: + InstanceLockResponse(WorldPacket&& packet) : ClientPacket(CMSG_INSTANCE_LOCK_RESPONSE, std::move(packet)) {} + + void Read() override; + + uint8 Accept = 0; + }; + } +} + +#endif // InstancePackets_h__ diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 4a113d881..1ea355538 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -204,6 +204,14 @@ namespace WorldPackets class Hello; class TrainerBuySpell; } + + namespace Instance + { + class SetDungeonDifficultyClient; + class SetRaidDifficultyClient; + class ResetInstances; + class InstanceLockResponse; + } } enum AccountDataType @@ -988,16 +996,16 @@ public: // opcodes handlers void HandleMinimapPingOpcode(WorldPackets::Misc::MinimapPingClient& packet); void HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet); void HandleFarSightOpcode(WorldPacket& recvData); - void HandleSetDungeonDifficultyOpcode(WorldPacket& recvData); - void HandleSetRaidDifficultyOpcode(WorldPacket& recvData); + void HandleSetDungeonDifficultyOpcode(WorldPackets::Instance::SetDungeonDifficultyClient& packet); + void HandleSetRaidDifficultyOpcode(WorldPackets::Instance::SetRaidDifficultyClient& packet); void HandleMoveFlagChangeOpcode(WorldPacket& recvData); void HandleSetTitleOpcode(WorldPacket& recvData); void HandleRealmSplitOpcode(WorldPacket& recvData); void HandleTimeSyncResp(WorldPacket& recvData); void HandleWhoisOpcode(WorldPacket& recvData); - void HandleResetInstancesOpcode(WorldPacket& recvData); + void HandleResetInstancesOpcode(WorldPackets::Instance::ResetInstances& packet); void HandleHearthAndResurrect(WorldPacket& recvData); - void HandleInstanceLockResponse(WorldPacket& recvPacket); + void HandleInstanceLockResponse(WorldPackets::Instance::InstanceLockResponse& packet); void HandleUpdateMissileTrajectory(WorldPacket& recvPacket); // Battlefield From 301b19c0f1a4ff54d86919690bb44699957e9bb7 Mon Sep 17 00:00:00 2001 From: sogladev Date: Fri, 13 Feb 2026 18:16:37 +0100 Subject: [PATCH 108/335] fix(Scripts/ObsidianSanctum): remove Sartharion's boss boundary (#24703) --- .../ObsidianSanctum/boss_sartharion.cpp | 39 +------------------ .../instance_obsidian_sanctum.cpp | 7 ---- 2 files changed, 1 insertion(+), 45 deletions(-) diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp index bec4a8d4d..adb3ccf57 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp @@ -145,7 +145,6 @@ enum Misc MAX_AREA_TRIGGER_COUNT = 2, MAX_CYCLONE_COUNT = 5, MAX_TENEBORN_EGGS_SUMMONS = 6, - MAX_BOUNDARY_POSITIONS = 4, }; enum Events @@ -173,7 +172,6 @@ enum Events EVENT_SARTHARION_CALL_SHADRON = 31, EVENT_SARTHARION_CALL_VESPERON = 32, - EVENT_SARTHARION_BOUNDARY = 33, EVENT_MINIDRAKE_SPEECH = 34, }; @@ -224,14 +222,6 @@ const Position AreaTriggerSummonPos[MAX_AREA_TRIGGER_COUNT] = { 3242.84f, 553.979f, 58.8272f, 0.0f }, }; -float const SartharionBoundary[MAX_BOUNDARY_POSITIONS] = -{ - 3218.86f, // South X - 3275.69f, // North X - 484.68f, // East Y - 572.4f // West Y -}; - float const FlameTsunamiLeftOffsets[MAX_LEFT_LAVA_TSUNAMIS] = { 476.0f, 484.0f, 492.0f, @@ -282,14 +272,8 @@ struct boss_sartharion : public BossAI DoCastSelf(SPELL_SARTHARION_TWILIGHT_REVENGE, true); } - void JustEngagedWith(Unit* who) override + void JustEngagedWith(Unit* /*who*/) override { - if (who && !IsTargetInBounds(who)) - { - EnterEvadeMode(); - return; - } - _JustEngagedWith(); DoCastSelf(SPELL_SARTHARION_PYROBUFFET, true); Talk(SAY_SARTHARION_AGGRO); @@ -303,7 +287,6 @@ struct boss_sartharion : public BossAI extraEvents.ScheduleEvent(EVENT_SARTHARION_SUMMON_LAVA, 20s); extraEvents.ScheduleEvent(EVENT_SARTHARION_LAVA_STRIKE, 5s); extraEvents.ScheduleEvent(EVENT_SARTHARION_BERSERK, 15min); - extraEvents.ScheduleEvent(EVENT_SARTHARION_BOUNDARY, 250ms); // Store dragons for (uint8 i = 0; i < MAX_DRAGONS; ++i) @@ -449,14 +432,6 @@ struct boss_sartharion : public BossAI { switch (eventId) { - case EVENT_SARTHARION_BOUNDARY: - { - if (!IsTargetInBounds(me->GetVictim())) - EnterEvadeMode(); - else - extraEvents.Repeat(250ms); - break; - } case EVENT_SARTHARION_SUMMON_LAVA: { if (!urand(0, 3)) @@ -662,18 +637,6 @@ private: dragonsCount = 0; } - bool IsTargetInBounds(Unit const* victim) const - { - if (!victim || victim->GetPositionX() < SartharionBoundary[0] || victim->GetPositionX() > SartharionBoundary[1] || victim->GetPositionY() > SartharionBoundary[3]) - return false; - - // Big island handling - if (victim->GetPositionY() < SartharionBoundary[2]) - return victim->GetDistance(bigIslandMiddlePos) <= 6.0f; - - return true; - } - EventMap extraEvents; std::list volcanoBlows; uint8 dragonsCount; diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp index 2b0364e1e..982a49c5d 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp @@ -15,18 +15,12 @@ * with this program. If not, see . */ -#include "AreaBoundary.h" #include "CreatureAIImpl.h" #include "InstanceMapScript.h" #include "Player.h" #include "ScriptedCreature.h" #include "obsidian_sanctum.h" -BossBoundaryData const boundaries = -{ - { DATA_SARTHARION, new RectangleBoundary(3218.86f, 3275.69f, 484.68f, 572.4f) } -}; - class instance_obsidian_sanctum : public InstanceMapScript { public: @@ -43,7 +37,6 @@ public: { SetHeaders(DataHeader); SetBossNumber(MAX_ENCOUNTERS); - LoadBossBoundaries(boundaries); } void OnCreatureCreate(Creature* pCreature) override From c908f443e9e523040be4be273ed30d2f0a7fc40a Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Fri, 13 Feb 2026 19:57:36 -0300 Subject: [PATCH 109/335] refactor(Scripts/Ulduar): Update Auriaya register methods (#24706) --- .../Northrend/Ulduar/Ulduar/boss_auriaya.cpp | 509 ++++++++---------- 1 file changed, 231 insertions(+), 278 deletions(-) diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp index f23da2ce3..b29cf2b26 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp @@ -26,7 +26,7 @@ enum AuriayaSpells { - // BASIC + // Auriaya SPELL_TERRIFYING_SCREECH = 64386, SPELL_SENTINEL_BLAST = 64389, SPELL_SONIC_SCREECH = 64422, @@ -56,15 +56,22 @@ enum AuriayaNPC enum AuriayaEvents { + // Auriaya EVENT_SUMMON_FERAL_DEFENDER = 1, EVENT_TERRIFYING_SCREECH = 2, EVENT_SONIC_SCREECH = 3, EVENT_GUARDIAN_SWARM = 4, EVENT_SENTINEL_BLAST = 5, EVENT_REMOVE_IMMUNE = 6, + EVENT_RESPAWN_FERAL_DEFENDER = 7, - EVENT_RESPAWN_FERAL_DEFENDER = 9, - EVENT_ENRAGE = 10, + // Sanctum Sentry + EVENT_SAVAGE_POUNCE = 8, + EVENT_RIP_FLESH = 9, + + // Feral Defender + EVENT_FERAL_RUSH = 10, + EVENT_FERAL_POUNCE = 11, }; enum Texts @@ -88,333 +95,279 @@ enum Misc DATA_NINE_LIVES = 11, }; -class boss_auriaya : public CreatureScript +struct boss_auriaya : public BossAI { -public: - boss_auriaya() : CreatureScript("boss_auriaya") { } + boss_auriaya(Creature* creature) : BossAI(creature, TYPE_AURIAYA) { } - CreatureAI* GetAI(Creature* pCreature) const override + bool _feralDied{false}; + bool _nineLives{false}; + + void Reset() override { - return GetUlduarAI(pCreature); + _feralDied = false; + _nineLives = false; + + EntryCheckPredicate pred(NPC_FERAL_DEFENDER); + summons.DoAction(ACTION_DESPAWN_ADDS, pred); + + BossAI::Reset(); + + for (uint8 i = 0; i < RAID_MODE(2, 4); ++i) + me->SummonCreature(NPC_SANCTUM_SENTRY, me->GetPositionX() + urand(4, 12), me->GetPositionY() + urand(4, 12), me->GetPositionZ()); + + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); } - struct boss_auriayaAI : public ScriptedAI + uint32 GetData(uint32 param) const override { - boss_auriayaAI(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature) + if (param == DATA_CRAZY_CAT) + return !_feralDied; + if (param == DATA_NINE_LIVES) + return _nineLives; + + return 0; + } + + void JustSummoned(Creature* cr) override + { + if (cr->GetEntry() == NPC_SANCTUM_SENTRY) + cr->GetMotionMaster()->MoveFollow(me, 6, rand_norm() * 2 * 3.14f); + else + cr->SetInCombatWithZone(); + + summons.Summon(cr); + } + + void SummonedCreatureDies(Creature* cr, Unit*) override + { + if (cr->GetEntry() == NPC_SANCTUM_SENTRY) + _feralDied = true; + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + Talk(SAY_AGGRO); + + events.ScheduleEvent(EVENT_TERRIFYING_SCREECH, 35s); + events.ScheduleEvent(EVENT_SONIC_SCREECH, 45s); + events.ScheduleEvent(EVENT_GUARDIAN_SWARM, 70s); + events.ScheduleEvent(EVENT_SUMMON_FERAL_DEFENDER, 60s); + events.ScheduleEvent(EVENT_SENTINEL_BLAST, 36s); + + ScheduleEnrageTimer(SPELL_ENRAGE, 10min, SAY_BERSERK); + } + + void KilledUnit(Unit* victim) override + { + if (!victim->IsPlayer() || urand(0, 2)) + return; + + Talk(SAY_SLAY); + } + + void JustDied(Unit* killer) override + { + EntryCheckPredicate pred(NPC_FERAL_DEFENDER); + summons.DoAction(ACTION_DESPAWN_ADDS, pred); + + BossAI::JustDied(killer); + Talk(EMOTE_DEATH); + } + + void DoAction(int32 param) override + { + if (param == ACTION_FERAL_DEATH_WITH_STACK) + events.ScheduleEvent(EVENT_RESPAWN_FERAL_DEFENDER, 25s); + else if (param == ACTION_FERAL_DEATH) + _nineLives = true; + } + + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) { - m_pInstance = pCreature->GetInstanceScript(); - } - - InstanceScript* m_pInstance; - EventMap events; - SummonList summons; - - bool _feralDied; - bool _nineLives; - - void Reset() override - { - _feralDied = false; - _nineLives = false; - - events.Reset(); - EntryCheckPredicate pred(NPC_FERAL_DEFENDER); - summons.DoAction(ACTION_DESPAWN_ADDS, pred); - summons.DespawnAll(); - - if (m_pInstance) - m_pInstance->SetData(TYPE_AURIAYA, NOT_STARTED); - - for (uint8 i = 0; i < RAID_MODE(2, 4); ++i) - me->SummonCreature(NPC_SANCTUM_SENTRY, me->GetPositionX() + urand(4, 12), me->GetPositionY() + urand(4, 12), me->GetPositionZ()); - - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); - } - - uint32 GetData(uint32 param) const override - { - if (param == DATA_CRAZY_CAT) - return !_feralDied; - else if (param == DATA_NINE_LIVES) - return _nineLives; - - return 0; - } - - void JustSummoned(Creature* cr) override - { - if (cr->GetEntry() == NPC_SANCTUM_SENTRY) - cr->GetMotionMaster()->MoveFollow(me, 6, rand_norm() * 2 * 3.14f); - else - cr->SetInCombatWithZone(); - - summons.Summon(cr); - } - - void SummonedCreatureDies(Creature* cr, Unit*) override - { - if (cr->GetEntry() == NPC_SANCTUM_SENTRY) - _feralDied = true; - } - - void JustReachedHome() override { me->setActive(false); } - - void JustEngagedWith(Unit* /*who*/) override - { - if (m_pInstance) - m_pInstance->SetData(TYPE_AURIAYA, IN_PROGRESS); - - events.ScheduleEvent(EVENT_TERRIFYING_SCREECH, 35s); - events.ScheduleEvent(EVENT_SONIC_SCREECH, 45s); - events.ScheduleEvent(EVENT_GUARDIAN_SWARM, 70s); - events.ScheduleEvent(EVENT_SUMMON_FERAL_DEFENDER, 60s); - events.ScheduleEvent(EVENT_SENTINEL_BLAST, 36s); - events.ScheduleEvent(EVENT_ENRAGE, 10min); - - summons.DoZoneInCombat(NPC_SANCTUM_SENTRY); - - Talk(SAY_AGGRO); - me->setActive(true); - } - - void KilledUnit(Unit* victim) override - { - if (!victim->IsPlayer() || urand(0, 2)) - return; - - Talk(SAY_SLAY); - } - - void JustDied(Unit* /*killer*/) override - { - if (m_pInstance) - m_pInstance->SetData(TYPE_AURIAYA, DONE); - - EntryCheckPredicate pred(NPC_FERAL_DEFENDER); - summons.DoAction(ACTION_DESPAWN_ADDS, pred); - summons.DespawnAll(); - Talk(EMOTE_DEATH); - } - - void DoAction(int32 param) override - { - if (param == ACTION_FERAL_DEATH_WITH_STACK) - events.ScheduleEvent(EVENT_RESPAWN_FERAL_DEFENDER, 25s); - else if (param == ACTION_FERAL_DEATH) - _nineLives = true; - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) + case EVENT_SUMMON_FERAL_DEFENDER: + Talk(EMOTE_DEFFENDER); + DoCastSelf(SPELL_ACTIVATE_FERAL_DEFENDER, true); + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true); + events.ScheduleEvent(EVENT_REMOVE_IMMUNE, 3s); + break; + case EVENT_REMOVE_IMMUNE: + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); + break; + case EVENT_TERRIFYING_SCREECH: + Talk(EMOTE_FEAR); + DoCastSelf(SPELL_TERRIFYING_SCREECH); + events.Repeat(35s); + break; + case EVENT_SONIC_SCREECH: + DoCastSelf(SPELL_SONIC_SCREECH); + events.Repeat(50s); + break; + case EVENT_GUARDIAN_SWARM: + DoCastVictim(SPELL_GUARDIAN_SWARM); + events.Repeat(40s); + break; + case EVENT_SENTINEL_BLAST: + DoCastSelf(SPELL_SENTINEL_BLAST); + events.Repeat(35s); + events.DelayEvents(5s, 0); + break; + case EVENT_RESPAWN_FERAL_DEFENDER: { - case EVENT_SUMMON_FERAL_DEFENDER: - Talk(EMOTE_DEFFENDER); - me->CastSpell(me, SPELL_ACTIVATE_FERAL_DEFENDER, true); - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true); - events.ScheduleEvent(EVENT_REMOVE_IMMUNE, 3s); - break; - case EVENT_REMOVE_IMMUNE: - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); - break; - case EVENT_TERRIFYING_SCREECH: - Talk(EMOTE_FEAR); - me->CastSpell(me, SPELL_TERRIFYING_SCREECH, false); - events.Repeat(35s); - break; - case EVENT_SONIC_SCREECH: - me->CastSpell(me, SPELL_SONIC_SCREECH, false); - events.Repeat(50s); - break; - case EVENT_GUARDIAN_SWARM: - me->CastSpell(me->GetVictim(), SPELL_GUARDIAN_SWARM, false); - events.Repeat(40s); - break; - case EVENT_SENTINEL_BLAST: - me->CastSpell(me, SPELL_SENTINEL_BLAST, false); - events.Repeat(35s); - events.DelayEvents(5s, 0); - break; - case EVENT_RESPAWN_FERAL_DEFENDER: - { - EntryCheckPredicate pred(NPC_FERAL_DEFENDER); - summons.DoAction(ACTION_FERAL_RESPAWN, pred); - break; - } - case EVENT_ENRAGE: - Talk(SAY_BERSERK); - me->CastSpell(me, SPELL_ENRAGE, true); - break; + EntryCheckPredicate pred(NPC_FERAL_DEFENDER); + summons.DoAction(ACTION_FERAL_RESPAWN, pred); + break; } - - DoMeleeAttackIfReady(); } - }; + } }; -class npc_auriaya_sanctum_sentry : public CreatureScript +struct npc_auriaya_sanctum_sentry : public ScriptedAI { -public: - npc_auriaya_sanctum_sentry() : CreatureScript("npc_auriaya_sanctum_sentry") { } + npc_auriaya_sanctum_sentry(Creature* creature) : ScriptedAI(creature) { } - CreatureAI* GetAI(Creature* pCreature) const override + void JustEngagedWith(Unit*) override { - return GetUlduarAI(pCreature); + if (me->GetInstanceScript()) + if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA))) + cr->SetInCombatWithZone(); + + events.ScheduleEvent(EVENT_SAVAGE_POUNCE, 5s); + events.ScheduleEvent(EVENT_RIP_FLESH, 10s); } - struct npc_auriaya_sanctum_sentryAI : public ScriptedAI + void Reset() override { - npc_auriaya_sanctum_sentryAI(Creature* pCreature) : ScriptedAI(pCreature) { } + events.Reset(); + me->CastSpell(me, SPELL_STRENGTH_OF_THE_PACK, true); + } - uint32 _savagePounceTimer; - uint32 _ripFleshTimer; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void JustEngagedWith(Unit*) override + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - if (me->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA))) - cr->SetInCombatWithZone(); - } - - void Reset() override - { - _savagePounceTimer = 5000; - _ripFleshTimer = 0; - - me->CastSpell(me, SPELL_STRENGTH_OF_THE_PACK, true); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _savagePounceTimer += diff; - _ripFleshTimer += diff; - - if (_savagePounceTimer >= 5000) + case EVENT_SAVAGE_POUNCE: { float dist = me->GetDistance(me->GetVictim()); if (dist >= 8 && dist < 25 && me->IsWithinLOSInMap(me->GetVictim())) { me->CastSpell(me->GetVictim(), SPELL_SAVAGE_POUNCE, false); - _savagePounceTimer = 0; - return; + events.Repeat(5s); + break; } - _savagePounceTimer = 200; + events.Repeat(200ms); + break; } - else if (_ripFleshTimer >= 10000) - { + case EVENT_RIP_FLESH: me->CastSpell(me->GetVictim(), SPELL_RIP_FLESH, false); - _ripFleshTimer = 0; - } - - DoMeleeAttackIfReady(); + events.Repeat(10s); + break; } - }; + + DoMeleeAttackIfReady(); + } }; -class npc_auriaya_feral_defender : public CreatureScript +struct npc_auriaya_feral_defender : public ScriptedAI { -public: - npc_auriaya_feral_defender() : CreatureScript("npc_auriaya_feral_defender") { } + npc_auriaya_feral_defender(Creature* creature) : ScriptedAI(creature), _summons(creature) { } - CreatureAI* GetAI(Creature* pCreature) const override + uint8 _feralEssenceStack{8}; + SummonList _summons; + + void Reset() override { - return GetUlduarAI(pCreature); + events.Reset(); + _summons.DespawnAll(); + _feralEssenceStack = 8; + + if (Aura* aur = me->AddAura(SPELL_FERAL_ESSENCE, me)) + aur->SetStackAmount(_feralEssenceStack); } - struct npc_auriaya_feral_defenderAI : public ScriptedAI + void JustEngagedWith(Unit*) override { - npc_auriaya_feral_defenderAI(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature) { } + events.ScheduleEvent(EVENT_FERAL_RUSH, 3s); + events.ScheduleEvent(EVENT_FERAL_POUNCE, 6s); + } - int32 _feralRushTimer; - int32 _feralPounceTimer; - uint8 _feralEssenceStack; - SummonList summons; + void JustDied(Unit*) override + { + if (me->GetInstanceScript()) + if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA))) + cr->AI()->DoAction(_feralEssenceStack ? ACTION_FERAL_DEATH_WITH_STACK : ACTION_FERAL_DEATH); - void Reset() override + if (_feralEssenceStack) { - summons.DespawnAll(); - _feralRushTimer = 3000; - _feralPounceTimer = 0; - _feralEssenceStack = 8; + if (Creature* cr = me->SummonCreature(NPC_SEEPING_FERAL_ESSENCE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.0f)) + _summons.Summon(cr); - if (Aura* aur = me->AddAura(SPELL_FERAL_ESSENCE, me)) - aur->SetStackAmount(_feralEssenceStack); + --_feralEssenceStack; } + } - void JustDied(Unit*) override + void DoAction(int32 param) override + { + if (param == ACTION_FERAL_RESPAWN) { - // inform about our death, start timer - if (me->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA))) - cr->AI()->DoAction(_feralEssenceStack ? ACTION_FERAL_DEATH_WITH_STACK : ACTION_FERAL_DEATH); + me->setDeathState(DeathState::JustRespawned); + + if (Player* target = SelectTargetFromPlayerList(200)) + AttackStart(target); + else + { + _summons.DespawnAll(); + me->DespawnOrUnsummon(1ms); + } if (_feralEssenceStack) - { - if (Creature* cr = me->SummonCreature(NPC_SEEPING_FERAL_ESSENCE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.0f)) - summons.Summon(cr); + if (Aura* aur = me->AddAura(SPELL_FERAL_ESSENCE, me)) + aur->SetStackAmount(_feralEssenceStack); - --_feralEssenceStack; - } + events.ScheduleEvent(EVENT_FERAL_RUSH, 3s); + events.ScheduleEvent(EVENT_FERAL_POUNCE, 6s); } + else if (param == ACTION_DESPAWN_ADDS) + _summons.DespawnAll(); + } - void DoAction(int32 param) override + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - if (param == ACTION_FERAL_RESPAWN) - { - me->setDeathState(DeathState::JustRespawned); - - if (Player* target = SelectTargetFromPlayerList(200)) - AttackStart(target); - else - { - summons.DespawnAll(); - me->DespawnOrUnsummon(1ms); - } - - if (_feralEssenceStack) - if (Aura* aur = me->AddAura(SPELL_FERAL_ESSENCE, me)) - aur->SetStackAmount(_feralEssenceStack); - } - else if (param == ACTION_DESPAWN_ADDS) - summons.DespawnAll(); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _feralRushTimer += diff; - _feralPounceTimer += diff; - - if (_feralRushTimer >= 6000) - { + case EVENT_FERAL_RUSH: DoResetThreatList(); if (!UpdateVictim()) return; - me->CastSpell(me->GetVictim(), SPELL_FERAL_RUSH, true); - _feralRushTimer = 0; - } - else if (_feralPounceTimer >= 6000) - { + events.Repeat(6s); + break; + case EVENT_FERAL_POUNCE: me->CastSpell(me->GetVictim(), SPELL_FERAL_POUNCE, false); - _feralPounceTimer = 0; - } - - DoMeleeAttackIfReady(); + events.Repeat(6s); + break; } - }; + + DoMeleeAttackIfReady(); + } }; class spell_auriaya_sentinel_blast : public SpellScript @@ -437,7 +390,7 @@ class achievement_auriaya_crazy_cat_lady : public AchievementCriteriaScript public: achievement_auriaya_crazy_cat_lady() : AchievementCriteriaScript("achievement_auriaya_crazy_cat_lady") {} - bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override + bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override { if (target) if (InstanceScript* instance = target->GetInstanceScript()) @@ -453,7 +406,7 @@ class achievement_auriaya_nine_lives : public AchievementCriteriaScript public: achievement_auriaya_nine_lives() : AchievementCriteriaScript("achievement_auriaya_nine_lives") {} - bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override + bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override { if (target) if (InstanceScript* instance = target->GetInstanceScript()) @@ -466,9 +419,9 @@ public: void AddSC_boss_auriaya() { - new boss_auriaya(); - new npc_auriaya_sanctum_sentry(); - new npc_auriaya_feral_defender(); + RegisterUlduarCreatureAI(boss_auriaya); + RegisterUlduarCreatureAI(npc_auriaya_sanctum_sentry); + RegisterUlduarCreatureAI(npc_auriaya_feral_defender); RegisterSpellScript(spell_auriaya_sentinel_blast); From 9e8a25c5d4b7a00101cc103702c8d2ea068a8506 Mon Sep 17 00:00:00 2001 From: Digid702 Date: Fri, 13 Feb 2026 15:58:00 -0800 Subject: [PATCH 110/335] fix(Scripts/Spell): 52308 Sample container clears Hydra Sputum (#23955) --- src/server/scripts/Spells/spell_quest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 230f9f975..2ec1a3891 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -1308,6 +1308,7 @@ class spell_q12683_take_sputum_sample : public SpellScript { uint32 spellId = GetSpellInfo()->Effects[EFFECT_0].CalcValue(); caster->CastSpell(caster, spellId, true, nullptr); + caster->RemoveAurasDueToSpell(reqAuraId); // consuming the sample clears Hydra Sputum } } From bdb0cfac6f8e04ff1b2dd59d30235da54749174b Mon Sep 17 00:00:00 2001 From: sogladev Date: Sat, 14 Feb 2026 08:31:58 +0100 Subject: [PATCH 111/335] feat(Core/Config): Add configurable XP rate for battleground objectives (#24672) --- src/server/apps/worldserver/worldserver.conf.dist | 7 +++++++ src/server/game/Entities/Player/Player.cpp | 2 +- src/server/game/World/WorldConfig.cpp | 1 + src/server/game/World/WorldConfig.h | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 67db345c7..1e8ffb11c 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -2421,6 +2421,13 @@ Rate.XP.BattlegroundKillEOTS = 1 Rate.XP.BattlegroundKillSOTA = 1 Rate.XP.BattlegroundKillIC = 1 +# +# Rate.XP.BattlegroundBonus +# Description: Experience rate multiplier for battleground objectives (flag captures, base assaults, etc.). +# Default: 1 + +Rate.XP.BattlegroundBonus = 1 + # # Rate.Pet.LevelXP # Description: Modifies the amount of experience required to level up a pet. diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ff26ef061..1414098af 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -6217,7 +6217,7 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool awar // Xinef: Only for BG activities if (!uVictim) { - uint32 xp = uint32(honor * (3 + GetLevel() * 0.30f)); + uint32 xp = static_cast(honor * (3 + GetLevel() * 0.30f) * sWorld->getRate(RATE_XP_BATTLEGROUND_BONUS)); sScriptMgr->OnPlayerGiveXP(this, xp, nullptr, PlayerXPSource::XPSOURCE_BATTLEGROUND); GiveXP(xp, nullptr); } diff --git a/src/server/game/World/WorldConfig.cpp b/src/server/game/World/WorldConfig.cpp index 81a55435b..d0bdfb48c 100644 --- a/src/server/game/World/WorldConfig.cpp +++ b/src/server/game/World/WorldConfig.cpp @@ -64,6 +64,7 @@ void WorldConfig::BuildConfigCache() SetConfigValue(RATE_XP_EXPLORE, "Rate.XP.Explore", 1.0f); SetConfigValue(RATE_XP_PET, "Rate.XP.Pet", 1.0f); SetConfigValue(RATE_XP_PET_NEXT_LEVEL, "Rate.Pet.LevelXP", 0.05f); + SetConfigValue(RATE_XP_BATTLEGROUND_BONUS, "Rate.XP.BattlegroundBonus", 1.0f); SetConfigValue(RATE_REPAIRCOST, "Rate.RepairCost", 1.0f, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value >= 0.0f; }, ">= 0"); SetConfigValue(RATE_SELLVALUE_ITEM_POOR, "Rate.SellValue.Item.Poor", 1.0f); diff --git a/src/server/game/World/WorldConfig.h b/src/server/game/World/WorldConfig.h index dabe2e222..e0408c7fd 100644 --- a/src/server/game/World/WorldConfig.h +++ b/src/server/game/World/WorldConfig.h @@ -437,6 +437,7 @@ enum ServerConfigs RATE_XP_EXPLORE, RATE_XP_PET, RATE_XP_PET_NEXT_LEVEL, + RATE_XP_BATTLEGROUND_BONUS, RATE_REPAIRCOST, RATE_REPUTATION_GAIN, RATE_REPUTATION_GAIN_AB, From 65d39b5187732ceff838649ff9019032a8e203a7 Mon Sep 17 00:00:00 2001 From: killerwife Date: Sat, 14 Feb 2026 16:55:15 +0100 Subject: [PATCH 112/335] fix(Core/Unit): Fix duplicate sending of hitinfo in SMSG_SPELLNONMELEEDAMAGELOG (#24711) --- src/server/game/Entities/Unit/Unit.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f37d493ec..018cbd47d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6569,7 +6569,6 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage* log) data << uint8 (log->unused); // unused data << uint32(log->blocked); // blocked data << uint32(log->HitInfo); - data << uint32(log->HitInfo); data << uint8(log->HitInfo & (SPELL_HIT_TYPE_CRIT_DEBUG | SPELL_HIT_TYPE_HIT_DEBUG | SPELL_HIT_TYPE_ATTACK_TABLE_DEBUG)); //if (log->HitInfo & SPELL_HIT_TYPE_CRIT_DEBUG) //{ From 8748a34eeec7a020e5e20c004854ab966526cde9 Mon Sep 17 00:00:00 2001 From: sogladev Date: Sat, 14 Feb 2026 20:47:24 +0100 Subject: [PATCH 113/335] fix(Scripts/ShadowfangKeep): fix Love is in the Air to start after reset (#24713) --- .../EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp index bdd001321..895fb283e 100644 --- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp +++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp @@ -113,6 +113,7 @@ public: me->SetFaction(FACTION_FRIENDLY); me->SummonCreatureGroup(1); me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); } void DoAction(int32 action) override From b2a85da5444f839b364123ac05ba8b89aaa4d9ee Mon Sep 17 00:00:00 2001 From: sogladev Date: Sun, 15 Feb 2026 00:04:26 +0100 Subject: [PATCH 114/335] fix(Core/Trade): correct packets, exchange checks, distance logic (#24710) Co-authored-by: Wyrserth Co-authored-by: Shauren Co-authored-by: Alan Deutscher Co-authored-by: Dehravor Co-authored-by: robinsch Co-authored-by: killerwife --- .../apps/worldserver/worldserver.conf.dist | 2 +- src/server/game/Entities/Player/Player.h | 25 +- .../game/Entities/Player/PlayerStorage.cpp | 213 ++++++++++++------ .../game/Entities/Player/PlayerUpdates.cpp | 3 - src/server/game/Entities/Player/TradeData.cpp | 33 +-- src/server/game/Entities/Player/TradeData.h | 18 +- src/server/game/Handlers/TradeHandler.cpp | 206 ++++++++++------- src/server/game/Server/WorldSession.h | 3 +- src/server/shared/SharedDefines.h | 6 +- 9 files changed, 321 insertions(+), 188 deletions(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 1e8ffb11c..16d333b21 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -2186,7 +2186,7 @@ Rate.MissChanceMultiplier.OnlyAffectsPlayer = 0 # # LevelReq.Trade -# Description: Level requirement for characters to be able to trade. +# Description: Level requirement for characters to be able to initiate a trade. # Default: 1 LevelReq.Trade = 1 diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 0e75edaf6..d6cb920ee 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1057,6 +1057,18 @@ struct EntryPointData [[nodiscard]] bool HasTaxiPath() const { return taxiPath[0] && taxiPath[1]; } }; +struct TradeStatusInfo +{ + TradeStatusInfo() = default; + + TradeStatus Status{TRADE_STATUS_BUSY}; + ObjectGuid TraderGuid{}; + InventoryResult Result{EQUIP_ERR_OK}; + bool IsTargetResult{false}; + uint32 ItemLimitedByLimitCategory{0}; + uint8 Slot{0}; +}; + struct PendingSpellCastRequest { uint32 spellId; @@ -1277,12 +1289,17 @@ public: bool CanNoReagentCast(SpellInfo const* spellInfo) const; [[nodiscard]] bool HasItemOrGemWithIdEquipped(uint32 item, uint32 count, uint8 except_slot = NULL_SLOT) const; [[nodiscard]] bool HasItemOrGemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count, uint8 except_slot = NULL_SLOT) const; - InventoryResult CanTakeMoreSimilarItems(Item* pItem) const { return CanTakeMoreSimilarItems(pItem->GetEntry(), pItem->GetCount(), pItem); } - [[nodiscard]] InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return CanTakeMoreSimilarItems(entry, count, nullptr); } + + InventoryResult CanTakeMoreSimilarItems(Item* item, uint32* itemLimitedByLimitCategory = nullptr) const + { + return CanTakeMoreSimilarItems(item->GetEntry(), item->GetCount(), item, nullptr, itemLimitedByLimitCategory); + } + InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, uint32* itemLimitedByLimitCategory = nullptr) const { return CanTakeMoreSimilarItems(entry, count, nullptr, nullptr, itemLimitedByLimitCategory); } InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = nullptr) const { return CanStoreItem(bag, slot, dest, item, count, nullptr, false, no_space_count); } + InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap = false) const { if (!pItem) @@ -1290,7 +1307,7 @@ public: uint32 count = pItem->GetCount(); return CanStoreItem(bag, slot, dest, pItem->GetEntry(), count, pItem, swap, nullptr); } - InventoryResult CanStoreItems(Item** pItem, int32 count) const; + InventoryResult CanStoreItems(Item** items, int count, uint32* itemLimitedByLimitCategory) const; InventoryResult CanEquipNewItem(uint8 slot, uint16& dest, uint32 item, bool swap) const; InventoryResult CanEquipItem(uint8 slot, uint16& dest, Item* pItem, bool swap, bool not_loading = true) const; @@ -1318,7 +1335,7 @@ public: void UpdateLootAchievements(LootItem* item, Loot* loot); void UpdateTitansGrip(); - InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = nullptr) const; + InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* item, uint32* no_space_count = nullptr, uint32* itemLimitCategory = nullptr) const; InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item* pItem = nullptr, bool swap = false, uint32* no_space_count = nullptr) const; void AddRefundReference(ObjectGuid itemGUID); diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index e8117aa58..213c3dbd9 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -799,7 +799,7 @@ bool Player::HasItemOrGemWithLimitCategoryEquipped(uint32 limitCategory, uint32 return false; } -InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count) const +InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* item, uint32* no_space_count /*= nullptr*/, uint32* itemLimitedByLimitCategory /*= nullptr*/) const { ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(entry); if (!pProto) @@ -809,13 +809,16 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } + if (item && item->m_lootGenerated) + return EQUIP_ERR_ALREADY_LOOTED; + // no maximum if ((pProto->MaxCount <= 0 && pProto->ItemLimitCategory == 0) || pProto->MaxCount == 2147483647) return EQUIP_ERR_OK; if (pProto->MaxCount > 0) { - uint32 curcount = GetItemCount(pProto->ItemId, true, pItem); + uint32 curcount = GetItemCount(pProto->ItemId, true, item); if (curcount + count > uint32(pProto->MaxCount)) { if (no_space_count) @@ -837,11 +840,13 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item if (limitEntry->mode == ITEM_LIMIT_CATEGORY_MODE_HAVE) { - uint32 curcount = GetItemCountWithLimitCategory(pProto->ItemLimitCategory, pItem); + uint32 curcount = GetItemCountWithLimitCategory(pProto->ItemLimitCategory, item); if (curcount + count > uint32(limitEntry->maxCount)) { if (no_space_count) *no_space_count = count + curcount - limitEntry->maxCount; + if (itemLimitedByLimitCategory) + *itemLimitedByLimitCategory = pProto->ItemId; return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED; } } @@ -1119,7 +1124,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& des if (pItem->IsBag() && pItem->IsNotEmptyBag()) return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS; - // Xinef: Removed next loot generated check + // swapping/merging with currently looted item if (pItem->GetGUID() == GetLootGUID()) { if (no_space_count) @@ -1538,79 +1543,102 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& des } ////////////////////////////////////////////////////////////////////////// -InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const +InventoryResult Player::CanStoreItems(Item** items, int count, uint32* itemLimitedByLimitCategory) const { - Item* pItem2; + Item* item2; - // fill space table - int inv_slot_items[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START]; - int inv_bags[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE]; - int inv_keys[KEYRING_SLOT_END - KEYRING_SLOT_START]; - int inv_tokens[CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START]; + // fill space tables, creating a mock-up of the player's inventory - memset(inv_slot_items, 0, sizeof(int) * (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START)); - memset(inv_bags, 0, sizeof(int) * (INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START) * MAX_BAG_SIZE); - memset(inv_keys, 0, sizeof(int) * (KEYRING_SLOT_END - KEYRING_SLOT_START)); - memset(inv_tokens, 0, sizeof(int) * (CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START)); + // counts + uint32 inventoryCounts[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START] = {}; + uint32 bagCounts[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE] = {}; + uint32 keyringCounts[KEYRING_SLOT_END - KEYRING_SLOT_START] = {}; + uint32 currencyCounts[CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START] = {}; + // Item pointers + Item* inventoryPointers[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START] = {}; + Item* bagPointers[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE] = {}; + Item* keyringPointers[KEYRING_SLOT_END - KEYRING_SLOT_START] = {}; + Item* currencyPointers[CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START] = {}; + + // filling inventory for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem2 && !pItem2->IsInTrade()) - inv_slot_items[i - INVENTORY_SLOT_ITEM_START] = pItem2->GetCount(); + // build items in stock backpack + item2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); + if (item2 && !item2->IsInTrade()) + { + inventoryCounts[i - INVENTORY_SLOT_ITEM_START] = item2->GetCount(); + inventoryPointers[i - INVENTORY_SLOT_ITEM_START] = item2; + } } for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem2 && !pItem2->IsInTrade()) - inv_keys[i - KEYRING_SLOT_START] = pItem2->GetCount(); + // build items in key ring 'bag' + item2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); + if (item2 && !item2->IsInTrade()) + { + keyringCounts[i - KEYRING_SLOT_START] = item2->GetCount(); + keyringPointers[i - KEYRING_SLOT_START] = item2; + } } for (uint8 i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; i++) { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem2 && !pItem2->IsInTrade()) - inv_tokens[i - CURRENCYTOKEN_SLOT_START] = pItem2->GetCount(); + // build items in currency 'bag' + item2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); + if (item2 && !item2->IsInTrade()) + { + currencyCounts[i - CURRENCYTOKEN_SLOT_START] = item2->GetCount(); + currencyPointers[i - CURRENCYTOKEN_SLOT_START] = item2; + } } for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) if (Bag* pBag = GetBagByPos(i)) for (uint32 j = 0; j < pBag->GetBagSize(); j++) { - pItem2 = GetItemByPos(i, j); - if (pItem2 && !pItem2->IsInTrade()) - inv_bags[i - INVENTORY_SLOT_BAG_START][j] = pItem2->GetCount(); + // build item counts in equippable bags + item2 = GetItemByPos(i, j); + if (item2 && !item2->IsInTrade()) + { + bagCounts[i - INVENTORY_SLOT_BAG_START][j] = item2->GetCount(); + bagPointers[i - INVENTORY_SLOT_BAG_START][j] = item2; + } } - // check free space for all items + // check free space for all items that we wish to add for (int k = 0; k < count; ++k) { - Item* pItem = pItems[k]; + // Incoming item + Item* item = items[k]; // no item - if (!pItem) + if (!item) continue; - LOG_DEBUG("entities.player.items", "STORAGE: CanStoreItems {}. item = {}, count = {}", k + 1, pItem->GetEntry(), pItem->GetCount()); - ItemTemplate const* pProto = pItem->GetTemplate(); + uint32 remaining_count = item->GetCount(); + + LOG_DEBUG("entities.player.items", "STORAGE: CanStoreItems {}. item = {}, count = {}", k + 1, item->GetEntry(), item->GetCount()); + ItemTemplate const* pProto = item->GetTemplate(); // strange item if (!pProto) return EQUIP_ERR_ITEM_NOT_FOUND; - // Xinef: Removed next loot generated check - if (pItem->GetGUID() == GetLootGUID()) + /// swapping/merging with currently looted item + if (item->GetGUID() == GetLootGUID()) return EQUIP_ERR_ALREADY_LOOTED; // item it 'bind' - if (pItem->IsBindedNotWith(this)) + if (item->IsBindedNotWith(this)) return EQUIP_ERR_DONT_OWN_THAT_ITEM; ItemTemplate const* pBagProto; // item is 'one item only' - InventoryResult res = CanTakeMoreSimilarItems(pItem); + InventoryResult res = CanTakeMoreSimilarItems(item, itemLimitedByLimitCategory); if (res != EQUIP_ERR_OK) return res; @@ -1621,40 +1649,58 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const for (uint8 t = KEYRING_SLOT_START; t < KEYRING_SLOT_END; ++t) { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t); - if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_keys[t - KEYRING_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize()) + item2 = keyringPointers[t - KEYRING_SLOT_START]; + if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && keyringCounts[t - KEYRING_SLOT_START] < pProto->GetMaxStackSize()) { - inv_keys[t - KEYRING_SLOT_START] += pItem->GetCount(); - b_found = true; - break; + keyringCounts[t - KEYRING_SLOT_START] += remaining_count; + remaining_count = keyringCounts[t - KEYRING_SLOT_START] < pProto->GetMaxStackSize() ? 0 : keyringCounts[t - KEYRING_SLOT_START] - pProto->GetMaxStackSize(); + + b_found = remaining_count == 0; + + // if no pieces of the stack remain, then stop checking keyring + if (b_found) + break; } } + if (b_found) continue; for (int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t) { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t); - if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_tokens[t - CURRENCYTOKEN_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize()) + item2 = currencyPointers[t - CURRENCYTOKEN_SLOT_START]; + if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && currencyCounts[t - CURRENCYTOKEN_SLOT_START] < pProto->GetMaxStackSize()) { - inv_tokens[t - CURRENCYTOKEN_SLOT_START] += pItem->GetCount(); - b_found = true; - break; + currencyCounts[t - CURRENCYTOKEN_SLOT_START] += remaining_count; + remaining_count = + currencyCounts[t - CURRENCYTOKEN_SLOT_START] < pProto->GetMaxStackSize() ? 0 : currencyCounts[t - CURRENCYTOKEN_SLOT_START] - pProto->GetMaxStackSize(); + + b_found = remaining_count == 0; + // if no pieces of the stack remain, then stop checking currency 'bag' + if (b_found) + break; } } + if (b_found) continue; for (int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; ++t) { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t); - if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_slot_items[t - INVENTORY_SLOT_ITEM_START] + pItem->GetCount() <= pProto->GetMaxStackSize()) + item2 = inventoryPointers[t - INVENTORY_SLOT_ITEM_START]; + if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inventoryCounts[t - INVENTORY_SLOT_ITEM_START] < pProto->GetMaxStackSize()) { - inv_slot_items[t - INVENTORY_SLOT_ITEM_START] += pItem->GetCount(); - b_found = true; - break; + inventoryCounts[t - INVENTORY_SLOT_ITEM_START] += remaining_count; + remaining_count = + inventoryCounts[t - INVENTORY_SLOT_ITEM_START] < pProto->GetMaxStackSize() ? 0 : inventoryCounts[t - INVENTORY_SLOT_ITEM_START] - pProto->GetMaxStackSize(); + + b_found = remaining_count == 0; + // if no pieces of the stack remain, then stop checking stock bag + if (b_found) + break; } } + if (b_found) continue; @@ -1662,21 +1708,29 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const { if (Bag* bag = GetBagByPos(t)) { - if (ItemCanGoIntoBag(pItem->GetTemplate(), bag->GetTemplate())) + if (!ItemCanGoIntoBag(item->GetTemplate(), bag->GetTemplate())) + continue; + + for (uint32 j = 0; j < bag->GetBagSize(); j++) { - for (uint32 j = 0; j < bag->GetBagSize(); j++) + item2 = bagPointers[t - INVENTORY_SLOT_BAG_START][j]; + if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && bagCounts[t - INVENTORY_SLOT_BAG_START][j] < pProto->GetMaxStackSize()) { - pItem2 = GetItemByPos(t, j); - if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_bags[t - INVENTORY_SLOT_BAG_START][j] + pItem->GetCount() <= pProto->GetMaxStackSize()) - { - inv_bags[t - INVENTORY_SLOT_BAG_START][j] += pItem->GetCount(); - b_found = true; + // add count to stack so that later items in the list do not double-book + bagCounts[t - INVENTORY_SLOT_BAG_START][j] += remaining_count; + remaining_count = + bagCounts[t - INVENTORY_SLOT_BAG_START][j] < pProto->GetMaxStackSize() ? 0 : bagCounts[t - INVENTORY_SLOT_BAG_START][j] - pProto->GetMaxStackSize(); + + b_found = remaining_count == 0; + + // if no pieces of the stack remain, then stop checking equippable bags + if (b_found) break; - } } } } } + if (b_found) continue; } @@ -1690,9 +1744,11 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const uint32 keyringSize = GetMaxKeyringSize(); for (uint32 t = KEYRING_SLOT_START; t < KEYRING_SLOT_START + keyringSize; ++t) { - if (inv_keys[t - KEYRING_SLOT_START] == 0) + if (keyringCounts[t - KEYRING_SLOT_START] == 0) { - inv_keys[t - KEYRING_SLOT_START] = 1; + keyringCounts[t - KEYRING_SLOT_START] = remaining_count; + keyringPointers[t - KEYRING_SLOT_START] = item; + b_found = true; break; } @@ -1706,9 +1762,11 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const { for (uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t) { - if (inv_tokens[t - CURRENCYTOKEN_SLOT_START] == 0) + if (currencyCounts[t - CURRENCYTOKEN_SLOT_START] == 0) { - inv_tokens[t - CURRENCYTOKEN_SLOT_START] = 1; + currencyCounts[t - CURRENCYTOKEN_SLOT_START] = remaining_count; + currencyPointers[t - CURRENCYTOKEN_SLOT_START] = item; + b_found = true; break; } @@ -1725,14 +1783,15 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const pBagProto = bag->GetTemplate(); // not plain container check - if (pBagProto && (pBagProto->Class != ITEM_CLASS_CONTAINER || pBagProto->SubClass != ITEM_SUBCLASS_CONTAINER) && - ItemCanGoIntoBag(pProto, pBagProto)) + if (pBagProto && (pBagProto->Class != ITEM_CLASS_CONTAINER || pBagProto->SubClass != ITEM_SUBCLASS_CONTAINER) && ItemCanGoIntoBag(pProto, pBagProto)) { for (uint32 j = 0; j < bag->GetBagSize(); j++) { - if (inv_bags[t - INVENTORY_SLOT_BAG_START][j] == 0) + if (bagCounts[t - INVENTORY_SLOT_BAG_START][j] == 0) { - inv_bags[t - INVENTORY_SLOT_BAG_START][j] = 1; + bagCounts[t - INVENTORY_SLOT_BAG_START][j] = remaining_count; + bagPointers[t - INVENTORY_SLOT_BAG_START][j] = item; + b_found = true; break; } @@ -1740,6 +1799,7 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const } } } + if (b_found) continue; } @@ -1748,18 +1808,21 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const bool b_found = false; for (int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; ++t) { - if (inv_slot_items[t - INVENTORY_SLOT_ITEM_START] == 0) + if (inventoryCounts[t - INVENTORY_SLOT_ITEM_START] == 0) { - inv_slot_items[t - INVENTORY_SLOT_ITEM_START] = 1; + inventoryCounts[t - INVENTORY_SLOT_ITEM_START] = remaining_count; + inventoryPointers[t - INVENTORY_SLOT_ITEM_START] = item; + b_found = true; break; } } + if (b_found) continue; // search free slot in bags - for (int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t) + for (uint8 t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t) { if (Bag* bag = GetBagByPos(t)) { @@ -1771,9 +1834,11 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const for (uint32 j = 0; j < bag->GetBagSize(); j++) { - if (inv_bags[t - INVENTORY_SLOT_BAG_START][j] == 0) + if (bagCounts[t - INVENTORY_SLOT_BAG_START][j] == 0) { - inv_bags[t - INVENTORY_SLOT_BAG_START][j] = 1; + bagCounts[t - INVENTORY_SLOT_BAG_START][j] = remaining_count; + bagPointers[t - INVENTORY_SLOT_BAG_START][j] = item; + b_found = true; break; } @@ -1781,9 +1846,9 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const } } - // no free slot found? + // if no free slot found for all pieces of the item, then return an error if (!b_found) - return EQUIP_ERR_INVENTORY_FULL; + return EQUIP_ERR_BAG_FULL; } return EQUIP_ERR_OK; diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index b0c7a8521..4b0bd93a4 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -1177,9 +1177,6 @@ bool Player::UpdatePosition(float x, float y, float z, float orientation, if (GetGroup()) SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POSITION); - if (GetTrader() && !IsWithinDistInMap(GetTrader(), INTERACTION_DISTANCE)) - GetSession()->SendCancelTrade(TRADE_STATUS_TRADE_CANCELED); - CheckAreaExploreAndOutdoor(); return true; diff --git a/src/server/game/Entities/Player/TradeData.cpp b/src/server/game/Entities/Player/TradeData.cpp index 7f0fca7f1..a8f1eedc0 100644 --- a/src/server/game/Entities/Player/TradeData.cpp +++ b/src/server/game/Entities/Player/TradeData.cpp @@ -20,12 +20,12 @@ TradeData* TradeData::GetTraderData() const { - return m_trader->GetTradeData(); + return _trader->GetTradeData(); } Item* TradeData::GetItem(TradeSlots slot) const { - return m_items[slot] ? m_player->GetItemByGuid(m_items[slot]) : nullptr; + return m_items[slot] ? _player->GetItemByGuid(m_items[slot]) : nullptr; } bool TradeData::HasItem(ObjectGuid itemGuid) const @@ -48,7 +48,7 @@ TradeSlots TradeData::GetTradeSlotForItem(ObjectGuid itemGuid) const Item* TradeData::GetSpellCastItem() const { - return m_spellCastItem ? m_player->GetItemByGuid(m_spellCastItem) : nullptr; + return m_spellCastItem ? _player->GetItemByGuid(m_spellCastItem) : nullptr; } void TradeData::SetItem(TradeSlots slot, Item* item) @@ -92,16 +92,19 @@ void TradeData::SetSpell(uint32 spell_id, Item* castItem /*= nullptr*/) void TradeData::SetMoney(uint32 money) { - if (m_money == money) + if (_money == money) return; - if (!m_player->HasEnoughMoney(money)) + if (!_player->HasEnoughMoney(money)) { - m_player->GetSession()->SendTradeStatus(TRADE_STATUS_BUSY); + TradeStatusInfo info; + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY; + _player->GetSession()->SendTradeStatus(info); return; } - m_money = money; + _money = money; SetAccepted(false); GetTraderData()->SetAccepted(false); @@ -112,20 +115,22 @@ void TradeData::SetMoney(uint32 money) void TradeData::Update(bool forTarget /*= true*/) { if (forTarget) - m_trader->GetSession()->SendUpdateTrade(true); // player state for trader + _trader->GetSession()->SendUpdateTrade(true); // player state for trader else - m_player->GetSession()->SendUpdateTrade(false); // player state for player + _player->GetSession()->SendUpdateTrade(false); // player state for player } -void TradeData::SetAccepted(bool state, bool crosssend /*= false*/) +void TradeData::SetAccepted(bool state, bool forTrader /*= false*/) { - m_accepted = state; + _accepted = state; if (!state) { - if (crosssend) - m_trader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + TradeStatusInfo info; + info.Status = TRADE_STATUS_BACK_TO_TRADE; + if (forTrader) + _trader->GetSession()->SendTradeStatus(info); else - m_player->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + _player->GetSession()->SendTradeStatus(info); } } diff --git a/src/server/game/Entities/Player/TradeData.h b/src/server/game/Entities/Player/TradeData.h index 5eb57e5fb..83e5c116d 100644 --- a/src/server/game/Entities/Player/TradeData.h +++ b/src/server/game/Entities/Player/TradeData.h @@ -36,9 +36,9 @@ class AC_GAME_API TradeData { public: // constructors TradeData(Player* player, Player* trader) : - m_player(player), m_trader(trader), m_accepted(false), m_acceptProccess(false), m_money(0), m_spell(0) { } + _player(player), _trader(trader), _accepted(false), m_acceptProccess(false), _money(0), m_spell(0) { } - [[nodiscard]] Player* GetTrader() const { return m_trader; } + [[nodiscard]] Player* GetTrader() const { return _trader; } [[nodiscard]] TradeData* GetTraderData() const; [[nodiscard]] Item* GetItem(TradeSlots slot) const; @@ -52,11 +52,11 @@ public: // constructors [[nodiscard]] Item* GetSpellCastItem() const; [[nodiscard]] bool HasSpellCastItem() const { return m_spellCastItem; } - [[nodiscard]] uint32 GetMoney() const { return m_money; } + [[nodiscard]] uint32 GetMoney() const { return _money; } void SetMoney(uint32 money); - [[nodiscard]] bool IsAccepted() const { return m_accepted; } - void SetAccepted(bool state, bool crosssend = false); + [[nodiscard]] bool IsAccepted() const { return _accepted; } + void SetAccepted(bool state, bool forTrader = false); [[nodiscard]] bool IsInAcceptProcess() const { return m_acceptProccess; } void SetInAcceptProcess(bool state) { m_acceptProccess = state; } @@ -65,13 +65,13 @@ private: // internal functions void Update(bool for_trader = true); private: // fields - Player* m_player; // Player who own of this TradeData - Player* m_trader; // Player who trade with m_player + Player* _player; // Player who own of this TradeData + Player* _trader; // Player who trade with m_player - bool m_accepted; // m_player press accept for trade list + bool _accepted; // m_player press accept for trade list bool m_acceptProccess; // one from player/trader press accept and this processed - uint32 m_money; // m_player place money to trade + uint32 _money; // m_player place money to trade uint32 m_spell; // m_player apply spell to non-traded slot item ObjectGuid m_spellCastItem; // applied spell casted by item use diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index 6bef09eb0..d87207a36 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -30,38 +30,29 @@ #include "WorldPacket.h" #include "WorldSession.h" -void WorldSession::SendTradeStatus(TradeStatus status) +void WorldSession::SendTradeStatus(TradeStatusInfo const& info) { - WorldPacket data; + WorldPacket data(SMSG_TRADE_STATUS, 13); + data << uint32(info.Status); - switch (status) + switch (info.Status) { case TRADE_STATUS_BEGIN_TRADE: - data.Initialize(SMSG_TRADE_STATUS, 4 + 8); - data << uint32(status); - data << uint64(0); + data << info.TraderGuid; // CGTradeInfo::m_tradingPlayer break; case TRADE_STATUS_OPEN_WINDOW: - data.Initialize(SMSG_TRADE_STATUS, 4 + 4); - data << uint32(status); - data << uint32(0); // added in 2.4.0 + data << uint32(0); // CGTradeInfo::m_tradeID break; case TRADE_STATUS_CLOSE_WINDOW: - data.Initialize(SMSG_TRADE_STATUS, 4 + 4 + 1 + 4); - data << uint32(status); - data << uint32(0); - data << uint8(0); - data << uint32(0); + data << uint32(info.Result); // InventoryResult + data << uint8(info.IsTargetResult); // bool isTargetError; used for: EQUIP_ERR_BAG_FULL, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_MISSING_REAGENT, EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED + data << uint32(info.ItemLimitedByLimitCategory);// when result 84 - Item Id that was limited by ItemLimitCategory.dbc break; - case TRADE_STATUS_ONLY_CONJURED: - case TRADE_STATUS_NOT_ELIGIBLE: - data.Initialize(SMSG_TRADE_STATUS, 4 + 1); - data << uint32(status); - data << uint8(0); + case TRADE_STATUS_WRONG_REALM: + case TRADE_STATUS_NOT_ON_TAPLIST: + data << uint8(info.Slot); // Trade slot; -1 here clears CGTradeInfo::m_tradeMoney break; default: - data.Initialize(SMSG_TRADE_STATUS, 4); - data << uint32(status); break; } @@ -84,7 +75,7 @@ void WorldSession::SendUpdateTrade(bool trader_data /*= true*/) WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 1 + 4 + 4 + 4 + 4 + 4 + 7 * (1 + 4 + 4 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 4 + 4)); data << uint8(trader_data); // 1 means traders data, 0 means own - data << uint32(0); // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?) + data << uint32(0); // CGTradeInfo::m_tradeID data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases data << uint32(view_trade->GetMoney()); // trader gold @@ -253,17 +244,27 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) if (!his_trade) return; - Item* myItems[TRADE_SLOT_TRADED_COUNT] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; - Item* hisItems[TRADE_SLOT_TRADED_COUNT] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; - bool myCanCompleteTrade = true, hisCanCompleteTrade = true; + Item* myItems[TRADE_SLOT_TRADED_COUNT] = { }; + Item* hisItems[TRADE_SLOT_TRADED_COUNT] = { }; // set before checks for propertly undo at problems (it already set in to client) my_trade->SetAccepted(true); + TradeStatusInfo info; + if (!_player->IsWithinDistInMap(trader, TRADE_DISTANCE, false)) + { + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); + my_trade->SetAccepted(false); + return; + } + // not accept case incorrect money amount if (!_player->HasEnoughMoney(my_trade->GetMoney())) { - ChatHandler(this).SendNotification(LANG_NOT_ENOUGH_GOLD); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY; + SendTradeStatus(info); my_trade->SetAccepted(false, true); return; } @@ -271,21 +272,27 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) // not accept case incorrect money amount if (!trader->HasEnoughMoney(his_trade->GetMoney())) { - ChatHandler(trader->GetSession()).SendNotification(LANG_NOT_ENOUGH_GOLD); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY; + trader->GetSession()->SendTradeStatus(info); his_trade->SetAccepted(false, true); return; } - if (_player->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - his_trade->GetMoney()) + if (_player->GetMoney() >= MAX_MONEY_AMOUNT - his_trade->GetMoney()) { - _player->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, nullptr, nullptr); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_TOO_MUCH_GOLD; + SendTradeStatus(info); my_trade->SetAccepted(false, true); return; } - if (trader->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - my_trade->GetMoney()) + if (trader->GetMoney() >= MAX_MONEY_AMOUNT - my_trade->GetMoney()) { - trader->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, nullptr, nullptr); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_TOO_MUCH_GOLD; + trader->GetSession()->SendTradeStatus(info); his_trade->SetAccepted(false, true); return; } @@ -297,14 +304,16 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) { if (!item->CanBeTraded(false, true)) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } if (item->IsBindedNotWith(trader)) { - SendTradeStatus(TRADE_STATUS_NOT_ELIGIBLE); - SendTradeStatus(TRADE_STATUS_CLOSE_WINDOW/*TRADE_STATUS_TRADE_CANCELED*/); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_CANNOT_TRADE_THAT; + SendTradeStatus(info); return; } } @@ -313,7 +322,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) { if (!item->CanBeTraded(false, true)) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } //if (item->IsBindedNotWith(_player)) // dont mark as invalid when his item isnt good (not exploitable because if item is invalid trade will fail anyway later on the same check) @@ -408,33 +418,39 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) } // inform partner client - trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); + info.Status = TRADE_STATUS_TRADE_ACCEPT; + trader->GetSession()->SendTradeStatus(info); // test if item will fit in each inventory - hisCanCompleteTrade = (trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK); - myCanCompleteTrade = (_player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK); + TradeStatusInfo myCanCompleteInfo, hisCanCompleteInfo; + hisCanCompleteInfo.Result = trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT, &hisCanCompleteInfo.ItemLimitedByLimitCategory); + myCanCompleteInfo.Result = _player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT, &myCanCompleteInfo.ItemLimitedByLimitCategory); clearAcceptTradeMode(myItems, hisItems); // in case of missing space report error - if (!myCanCompleteTrade) + if (myCanCompleteInfo.Result != EQUIP_ERR_OK) { clearAcceptTradeMode(my_trade, his_trade); - ChatHandler(this).SendNotification(LANG_NOT_FREE_TRADE_SLOTS); - ChatHandler(trader->GetSession()).SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); + myCanCompleteInfo.Status = TRADE_STATUS_CLOSE_WINDOW; + trader->GetSession()->SendTradeStatus(myCanCompleteInfo); + myCanCompleteInfo.IsTargetResult = true; + SendTradeStatus(myCanCompleteInfo); my_trade->SetAccepted(false); his_trade->SetAccepted(false); delete my_spell; delete his_spell; return; } - else if (!hisCanCompleteTrade) + else if (hisCanCompleteInfo.Result != EQUIP_ERR_OK) { clearAcceptTradeMode(my_trade, his_trade); - ChatHandler(this).SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); - ChatHandler(trader->GetSession()).SendNotification(LANG_NOT_FREE_TRADE_SLOTS); + hisCanCompleteInfo.Status = TRADE_STATUS_CLOSE_WINDOW; + SendTradeStatus(hisCanCompleteInfo); + hisCanCompleteInfo.IsTargetResult = true; + trader->GetSession()->SendTradeStatus(hisCanCompleteInfo); my_trade->SetAccepted(false); his_trade->SetAccepted(false); delete my_spell; @@ -460,6 +476,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) // execute trade: 2. store moveItems(myItems, hisItems); + // logging money if (my_trade->GetMoney() >= 10 * GOLD ) { CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"goods\", NOW(), {})", @@ -496,12 +513,14 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) trader->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); - trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); - SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); + info.Status = TRADE_STATUS_TRADE_COMPLETE; + trader->GetSession()->SendTradeStatus(info); + SendTradeStatus(info); } else { - trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); + info.Status = TRADE_STATUS_TRADE_ACCEPT; + trader->GetSession()->SendTradeStatus(info); } } @@ -516,12 +535,14 @@ void WorldSession::HandleUnacceptTradeOpcode(WorldPacket& /*recvPacket*/) void WorldSession::HandleBeginTradeOpcode(WorldPacket& /*recvPacket*/) { - TradeData* my_trade = _player->m_trade; + TradeData* my_trade = _player->GetTradeData(); if (!my_trade) return; - my_trade->GetTrader()->GetSession()->SendTradeStatus(TRADE_STATUS_OPEN_WINDOW); - SendTradeStatus(TRADE_STATUS_OPEN_WINDOW); + TradeStatusInfo info; + info.Status = TRADE_STATUS_OPEN_WINDOW; + my_trade->GetTrader()->GetSession()->SendTradeStatus(info); + SendTradeStatus(info); } void WorldSession::SendCancelTrade(TradeStatus status) @@ -529,7 +550,9 @@ void WorldSession::SendCancelTrade(TradeStatus status) if (PlayerRecentlyLoggedOut() || PlayerLogout()) return; - SendTradeStatus(status); + TradeStatusInfo info; + info.Status = status; + SendTradeStatus(info); } void WorldSession::HandleCancelTradeOpcode(WorldPacket& /*recvPacket*/) @@ -544,36 +567,43 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) ObjectGuid ID; recvPacket >> ID; - if (GetPlayer()->m_trade) + if (GetPlayer()->GetTradeData()) return; + TradeStatusInfo info; if (!GetPlayer()->IsAlive()) { - SendTradeStatus(TRADE_STATUS_YOU_DEAD); + info.Status = TRADE_STATUS_YOU_DEAD; + SendTradeStatus(info); return; } if (GetPlayer()->HasUnitState(UNIT_STATE_STUNNED)) { - SendTradeStatus(TRADE_STATUS_YOU_STUNNED); + info.Status = TRADE_STATUS_YOU_STUNNED; + SendTradeStatus(info); return; } if (isLogingOut()) { - SendTradeStatus(TRADE_STATUS_YOU_LOGOUT); + info.Status = TRADE_STATUS_YOU_LOGOUT; + SendTradeStatus(info); return; } if (GetPlayer()->IsInFlight()) { - SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); return; } if (GetPlayer()->GetLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)) { ChatHandler(this).SendNotification(LANG_TRADE_REQ, sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + SendTradeStatus(info); return; } @@ -584,55 +614,57 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) if (!pOther) { - SendTradeStatus(TRADE_STATUS_NO_TARGET); + info.Status = TRADE_STATUS_NO_TARGET; + SendTradeStatus(info); return; } if (pOther == GetPlayer() || pOther->m_trade) { - SendTradeStatus(TRADE_STATUS_BUSY); + info.Status = TRADE_STATUS_BUSY; + SendTradeStatus(info); return; } if (!pOther->IsAlive()) { - SendTradeStatus(TRADE_STATUS_TARGET_DEAD); + info.Status = TRADE_STATUS_TARGET_DEAD; + SendTradeStatus(info); return; } if (pOther->IsInFlight()) { - SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); return; } if (pOther->HasUnitState(UNIT_STATE_STUNNED)) { - SendTradeStatus(TRADE_STATUS_TARGET_STUNNED); + info.Status = TRADE_STATUS_TARGET_STUNNED; + SendTradeStatus(info); return; } if (pOther->GetSession()->isLogingOut()) { - SendTradeStatus(TRADE_STATUS_TARGET_LOGOUT); + info.Status = TRADE_STATUS_TARGET_LOGOUT; + SendTradeStatus(info); return; } if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) && pOther->GetTeamId() != _player->GetTeamId()) { - SendTradeStatus(TRADE_STATUS_WRONG_FACTION); + info.Status = TRADE_STATUS_WRONG_FACTION; + SendTradeStatus(info); return; } - if (!pOther->IsWithinDistInMap(_player, 10.0f, false)) + if (!pOther->IsWithinDistInMap(_player, TRADE_DISTANCE, false)) { - SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); - return; - } - - if (pOther->GetLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)) - { - ChatHandler(this).SendNotification(LANG_TRADE_OTHER_REQ, sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)); + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); return; } @@ -643,10 +675,13 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) _player->m_trade = new TradeData(_player, pOther); pOther->m_trade = new TradeData(pOther, _player); - WorldPacket data(SMSG_TRADE_STATUS, 12); - data << uint32(TRADE_STATUS_BEGIN_TRADE); - data << _player->GetGUID(); - pOther->SendDirectMessage(&data); + // WorldPacket data(SMSG_TRADE_STATUS, 12); + // data << uint32(TRADE_STATUS_BEGIN_TRADE); + // data << _player->GetGUID(); + // pOther->SendDirectMessage(&data); + info.Status = TRADE_STATUS_BEGIN_TRADE; + info.TraderGuid = _player->GetGUID(); + pOther->GetSession()->SendTradeStatus(info); } void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket) @@ -676,10 +711,12 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) if (!my_trade) return; + TradeStatusInfo info; // invalid slot number if (tradeSlot >= TRADE_SLOT_COUNT) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } @@ -687,7 +724,8 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) Item* item = _player->GetItemByPos(bag, slot); if (!item || (tradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded(false, true))) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } @@ -697,7 +735,8 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) if (my_trade->HasItem(iGUID)) { // cheating attempt - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } @@ -706,7 +745,16 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) { // Do not send TRADE_STATUS_TRADE_CANCELED because it will cause double display of "Transaction canceled" notification // On the trade initiator screen - SendTradeStatus(TRADE_STATUS_CLOSE_WINDOW); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + SendTradeStatus(info); + return; + } + + if (tradeSlot != TRADE_SLOT_NONTRADED && item->IsBindedNotWith(my_trade->GetTrader())) + { + info.Status = TRADE_STATUS_NOT_ON_TAPLIST; + info.Slot = tradeSlot; + SendTradeStatus(info); return; } diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 1ea355538..b00c1d6ec 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -57,6 +57,7 @@ struct AuctionEntry; struct DeclinedName; struct ItemTemplate; struct MovementInfo; +struct TradeStatusInfo; namespace lfg { @@ -510,7 +511,7 @@ public: void SendBattleGroundList(ObjectGuid guid, BattlegroundTypeId bgTypeId = BATTLEGROUND_RB); - void SendTradeStatus(TradeStatus status); + void SendTradeStatus(TradeStatusInfo const& info); void SendUpdateTrade(bool trader_data = true); void SendCancelTrade(TradeStatus status); diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index b5a979dea..d6b41138d 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -3812,7 +3812,7 @@ enum TradeStatus TRADE_STATUS_NO_TARGET = 6, TRADE_STATUS_BACK_TO_TRADE = 7, TRADE_STATUS_TRADE_COMPLETE = 8, - // 9? + TRADE_STATUS_TRADE_REJECTED = 9, TRADE_STATUS_TARGET_TO_FAR = 10, TRADE_STATUS_WRONG_FACTION = 11, TRADE_STATUS_CLOSE_WINDOW = 12, @@ -3825,8 +3825,8 @@ enum TradeStatus TRADE_STATUS_YOU_LOGOUT = 19, TRADE_STATUS_TARGET_LOGOUT = 20, TRADE_STATUS_TRIAL_ACCOUNT = 21, // Trial accounts can not perform that action - TRADE_STATUS_ONLY_CONJURED = 22, // You can only trade conjured items... (cross realm BG related). - TRADE_STATUS_NOT_ELIGIBLE = 23 // Related to trading soulbound loot items + TRADE_STATUS_WRONG_REALM = 22, // You can only trade conjured items... (cross realm BG related). + TRADE_STATUS_NOT_ON_TAPLIST = 23 // Related to trading soulbound loot items }; enum XPColorChar : uint8 From 208fd3e695d05a4093661307a573dab307657f52 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 14 Feb 2026 20:57:16 -0300 Subject: [PATCH 115/335] fix(Scripts/Naxxramas): fix Four Horsemen chest despawning (#24716) --- .../scripts/Northrend/Naxxramas/boss_four_horsemen.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp index ba777b91e..b9d4e81e2 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp @@ -256,11 +256,9 @@ public: BossAI::JustDied(killer); 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); + if (instance->IsBossDone(BOSS_HORSEMAN)) + if (GameObject* chest = me->GetMap()->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 From 14c3366d258d07bb5710d91784d577ccad4f8da7 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 14 Feb 2026 21:59:14 -0300 Subject: [PATCH 116/335] chore: Update build commands to indicate optional building Clarify that building is optional and requires explicit request. --- CLAUDE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 08a09ab39..bee9a607a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,6 +10,8 @@ AzerothCore is an open-source MMORPG server emulator for World of Warcraft patch ### Configure and build (out-of-source build required) +- Skip building unless explicitly requested. + ```bash # Create build directory and configure mkdir -p build && cd build From 088ffee46afbea1f36667717d459573765c84d1a Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Feb 2026 01:53:36 -0300 Subject: [PATCH 117/335] docs(Agents): Configure AI PR review to enforce CLAUDE.md and wiki standards (#24655) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/agents/README.md | 60 ++++++++++++++++++ .github/agents/pr-reviewer.md | 115 ++++++++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 .github/agents/README.md create mode 100644 .github/agents/pr-reviewer.md diff --git a/.github/agents/README.md b/.github/agents/README.md new file mode 100644 index 000000000..488bd1026 --- /dev/null +++ b/.github/agents/README.md @@ -0,0 +1,60 @@ +# GitHub Agents Configuration + +This directory contains configuration files for AI-powered code review and development agents used in the AzerothCore project. + +## Overview + +Agent configuration files provide context-specific instructions to AI tools (like GitHub Copilot, Claude, etc.) when they interact with this repository. These configurations ensure that automated reviews and code suggestions follow project-specific standards and best practices. + +## Available Agents + +### PR Reviewer (`pr-reviewer.md`) + +The PR Reviewer agent is configured to review pull requests with deep understanding of AzerothCore's: +- Architecture patterns (two-server model, scripting system, database structure) +- Code style requirements (indentation, line length, formatting) +- C++ coding conventions and naming standards +- SQL query formatting and database design standards +- Commit message conventions (Conventional Commits format) +- Testing and validation requirements +- Security and quality standards + +**Key Feature**: This agent always references `/CLAUDE.md`, the C++ Code Standards wiki, and the SQL Standards wiki before reviewing any PR. + +## How It Works + +When an AI tool reviews a PR in this repository: + +1. The tool reads the appropriate agent configuration from this directory +2. The agent configuration instructs it to read `/CLAUDE.md` for full project context +3. For C++ changes, the agent also references the [C++ Code Standards wiki](https://github.com/azerothcore/wiki/blob/master/docs/cpp-code-standards.md) +4. For SQL changes, the agent also references the [SQL Standards wiki](https://github.com/azerothcore/wiki/blob/master/docs/sql-standards.md) +5. The agent applies project-specific rules during review +6. Feedback is provided following the project's conventions and standards + +## For Contributors + +If you're using AI tools to assist with contributions: + +1. Familiarize yourself with `/CLAUDE.md` - it contains essential project knowledge +2. Review the [C++ Code Standards](https://github.com/azerothcore/wiki/blob/master/docs/cpp-code-standards.md) for C++ contributions +3. Review the [SQL Standards](https://github.com/azerothcore/wiki/blob/master/docs/sql-standards.md) for database contributions +4. The AI agents will help ensure your changes follow project standards +5. Agent feedback should be treated as helpful suggestions that align with maintainer expectations + +## For Maintainers + +To update agent configurations: + +1. Edit the relevant `.md` file in this directory +2. Ensure any changes align with documentation in `/CLAUDE.md` and the wiki standards +3. Test the updated configuration with a sample PR review +4. Commit changes following the project's commit message format + +## References + +- Project guidelines: `/CLAUDE.md` +- C++ standards: [C++ Code Standards](https://github.com/azerothcore/wiki/blob/master/docs/cpp-code-standards.md) +- SQL standards: [SQL Standards](https://github.com/azerothcore/wiki/blob/master/docs/sql-standards.md) +- PR template: `/pull_request_template.md` +- Contribution guide: `/.github/CONTRIBUTING.md` diff --git a/.github/agents/pr-reviewer.md b/.github/agents/pr-reviewer.md new file mode 100644 index 000000000..0c7ee6571 --- /dev/null +++ b/.github/agents/pr-reviewer.md @@ -0,0 +1,115 @@ +# PR Reviewer Agent + +You are an expert code reviewer for the AzerothCore project. When reviewing pull requests, you must follow the project-specific guidelines and architecture patterns defined in the repository. + +## Required Reading + +Before reviewing any PR, you MUST read and follow the instructions in: +- `/CLAUDE.md` - Contains comprehensive project architecture, coding standards, build instructions, and PR requirements +- [C++ Code Standards](https://github.com/azerothcore/wiki/blob/master/docs/cpp-code-standards.md) - Detailed C++ coding conventions and style guide +- [SQL Standards](https://github.com/azerothcore/wiki/blob/master/docs/sql-standards.md) - SQL query formatting and database standards + +## Key Review Focus Areas + +Based on CLAUDE.md, always verify: + +### 1. Commit Message Format +- Uses Conventional Commits: `Type(Scope/Subscope): Short description` +- Types: feat, fix, refactor, style, docs, test, chore +- Scopes: Core (C++ changes), DB (SQL changes) +- Max 50 characters for description +- Examples: `fix(Core/Spells): Fix damage calculation for Fireball`, `fix(DB/SAI): Missing spell to NPC Hogger` + +### 2. Code Style +- 4-space indentation for C++ (no tabs) +- 2-space indentation for JSON, YAML, shell scripts +- UTF-8 encoding, LF line endings +- Max 80 character line length +- No braces around single-line statements +- Format variables in output using {} placeholders instead of printf-style format specifiers like %u + +### 3. C++ Specific Standards +**From C++ Code Standards wiki - verify:** +- Indentation: 4 spaces, never tabs +- Comments: Above or beside code, avoid external hyperlinks +- No trailing whitespace or extra spaces within brackets +- Brackets: Single-line statements don't need braces; multi-line blocks on new line +- Use constants (enum/constexpr) instead of magic numbers +- Switch statements must have default case +- Prefer enum class over plain enum +- Standard prefixes: SPELL_, NPC_, ITEM_, GO_, QUEST_, SAY_, EMOTE_, MODEL_, EVENT_, DATA_, ACHIEV_ +- Naming conventions: + - Public/protected: `SomeGuid`, `ShadowBoltTimer` (UpperCamelCase) + - Private members: `_someGuid`, `_count` (underscore prefix, lowerCamelCase) + - Methods: `DoSomething(uint32 someNumber)` (UpperCamelCase, params lowerCamelCase) + - Always use 'f' suffix for float literals: `234.3456f` +- WorldObjects: `GameObject* go;`, `Creature* creature;` (never multiple pointer declarations) +- const placement: after type (`Player const* player`) +- static placement: before type (`static uint32 someVar`) +- All headers must have header guards + +### 4. SQL Specific Standards +**From SQL Standards wiki - verify:** +- Always use backticks around table and column names +- Single quotes for strings, no quotes for numeric values +- DELETE before INSERT (never use REPLACE) +- DELETE/UPDATE must include at least primary key in WHERE clause +- Prefer IN clause for multiple values: `WHERE entry IN (1, 2, 3)` +- Use variables for repeated entries: `SET @ENTRY := 7727;` +- Compact queries: bundle multiple rows in single INSERT +- For flags: use bitwise operations (`|` to add, `&~` to remove), never override +- Table naming: snake_case (`creature_loot_template`) +- Column naming: UpperCamelCase (`PositionX`, `DisplayID`) +- Acronyms in uppercase: `ItemGUID`, `DisplayID`, `RequiredNPCOrGOCount` +- No integer width specification: `INT` not `INT(11)` +- Never use MEDIUMINT (use INT instead for consistency) +- Float/Double: use CHECK constraints instead of UNSIGNED +- Charset: utf8mb4, Collation: utf8mb4_unicode_ci (utf8mb4_bin for names) +- Engine: InnoDB, Row Format: DEFAULT + +### 5. Architecture Compliance +- Changes to game logic should be in `src/server/game/` +- Scripts should follow the registration pattern (AddSC_*() functions) +- Spell scripts organized by class: `spell_dk.cpp`, `spell_mage.cpp`, etc. +- Database changes go in correct subdirectories: + - `data/sql/updates/pending_*/db_auth/` for auth database + - `data/sql/updates/pending_*/db_characters/` for characters database + - `data/sql/updates/pending_*/db_world/` for world database + +### 6. PR Requirements +- AI tool usage must be disclosed in PRs +- In-game testing expected and documented +- Changes to generic code require regression testing of related systems +- No breaking changes to existing functionality without strong justification + +### 7. Testing Requirements +- Unit tests should be updated when logic changes (Google Test framework) +- Build must succeed with `-Werror` (warnings treated as errors) +- Changes should compile on all platforms (Linux, Windows, macOS) + +### 8. Security & Quality +- No hardcoded credentials or sensitive data +- Proper error handling and bounds checking +- No memory leaks or buffer overflows +- SQL changes should be properly escaped/parameterized + +## Review Process + +1. Read CLAUDE.md to understand project context +2. Review C++ Code Standards wiki for C++ changes +3. Review SQL Standards wiki for database changes +4. Check commit message format +5. Verify code style compliance (general and language-specific) +6. Ensure architectural patterns are followed +7. Check for proper testing and documentation +8. Validate that generic changes don't introduce regressions +9. Confirm AI disclosure if applicable + +## Feedback Style + +- Be constructive and educational +- Reference specific sections of CLAUDE.md, C++ Code Standards, or SQL Standards when applicable +- Suggest specific fixes with code examples when possible +- Highlight both issues and good practices +- For C++ issues, cite specific rule from C++ Code Standards wiki +- For SQL issues, cite specific rule from SQL Standards wiki From bd0f5ee722e752239c9cfaa8324e1d69feb35881 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Sun, 15 Feb 2026 06:06:33 -0500 Subject: [PATCH 118/335] refactor(Core/Defines): Rename custom named creature family enum. (#24570) --- src/server/game/Globals/ObjectMgr.cpp | 4 ++-- src/server/shared/SharedDefines.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index d2e3c8ee5..725ea0ca3 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1145,8 +1145,8 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) const_cast(cInfo)->type = CREATURE_TYPE_HUMANOID; } - // must exist or used hidden but used in data horse case - if (cInfo->family && !sCreatureFamilyStore.LookupEntry(cInfo->family) && cInfo->family != CREATURE_FAMILY_HORSE_CUSTOM) + // Must exist in DBC or use hidden miscellaneous family + if (cInfo->family && !sCreatureFamilyStore.LookupEntry(cInfo->family) && cInfo->family != CREATURE_FAMILY_NOT_SPECIFIED) { LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid creature family ({}) in `family`.", cInfo->Entry, cInfo->family); const_cast(cInfo)->family = 0; diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index d6b41138d..7a07c16e6 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -2657,7 +2657,7 @@ enum CreatureFamily CREATURE_FAMILY_CARRION_BIRD = 7, CREATURE_FAMILY_CRAB = 8, CREATURE_FAMILY_GORILLA = 9, - CREATURE_FAMILY_HORSE_CUSTOM = 10, // not exist in DBC but used for horse like beasts in DB + CREATURE_FAMILY_NOT_SPECIFIED = 10, // Doesn't exist in DBC, but used by many creatures CREATURE_FAMILY_RAPTOR = 11, CREATURE_FAMILY_TALLSTRIDER = 12, CREATURE_FAMILY_FELHUNTER = 15, From e049122f5f8502f88eb5e72ba1f0f1d4d94ac121 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 15 Feb 2026 08:54:55 -0300 Subject: [PATCH 119/335] =?UTF-8?q?feat(Scripts/Commands):=20Add=20grid-ba?= =?UTF-8?q?sed=20search=20to=20npc=20near=20and=20gobject=E2=80=A6=20(#247?= =?UTF-8?q?18)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> --- src/server/scripts/Commands/cs_gobject.cpp | 40 ++++++++++++++++++++++ src/server/scripts/Commands/cs_npc.cpp | 40 ++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 46db7cf4c..c23832e99 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -15,17 +15,21 @@ * with this program. If not, see . */ +#include "CellImpl.h" #include "Chat.h" #include "CommandScript.h" #include "GameEventMgr.h" #include "GameObject.h" #include "GameTime.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" #include "Language.h" #include "MapMgr.h" #include "ObjectMgr.h" #include "Player.h" #include "PoolMgr.h" #include "Transport.h" +#include using namespace Acore::ChatCommands; @@ -497,6 +501,37 @@ public: Player* player = handler->GetSession()->GetPlayer(); + // Grid search - finds all game objects including temporary spawns + std::list gameobjects; + Acore::GameObjectInRangeCheck check(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), distance); + Acore::GameObjectListSearcher searcher(player, gameobjects, check); + Cell::VisitObjects(player, searcher, distance); + + std::unordered_set gridSpawnIds; + + for (GameObject* go : gameobjects) + { + GameObjectTemplate const* gameObjectInfo = sObjectMgr->GetGameObjectTemplate(go->GetEntry()); + if (!gameObjectInfo) + continue; + + handler->PSendSysMessage(LANG_GO_LIST_CHAT, go->GetSpawnId(), go->GetEntry(), + go->GetSpawnId(), gameObjectInfo->name, + go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), + go->GetMapId(), "", ""); + + if (go->GetSpawnId()) + gridSpawnIds.insert(go->GetSpawnId()); + ++count; + } + + if (count > 0 && distance <= SIZE_OF_GRIDS) + { + handler->PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE, distance, count); + return true; + } + + // Fallback to DB query WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_GAMEOBJECT_NEAREST); stmt->SetData(0, player->GetPositionX()); stmt->SetData(1, player->GetPositionY()); @@ -515,6 +550,11 @@ public: { Field* fields = result->Fetch(); ObjectGuid::LowType guid = fields[0].Get(); + + // Skip entries already emitted via grid search + if (gridSpawnIds.count(guid)) + continue; + uint32 entry = fields[1].Get(); float x = fields[2].Get(); float y = fields[3].Get(); diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index e933d4be1..99f3973d8 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -15,11 +15,14 @@ * with this program. If not, see . */ +#include "CellImpl.h" #include "Chat.h" #include "CommandScript.h" #include "CreatureAI.h" #include "CreatureGroups.h" #include "GameTime.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" #include "Language.h" #include "MapMgr.h" #include "ObjectMgr.h" @@ -29,6 +32,7 @@ #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand #include "Transport.h" #include +#include using namespace Acore::ChatCommands; @@ -728,6 +732,37 @@ public: Player* player = handler->GetSession()->GetPlayer(); + // Grid search - finds all creatures including temporary spawns + std::list creatures; + Acore::AllWorldObjectsInRange check(player, distance); + Acore::CreatureListSearcher searcher(player, creatures, check); + Cell::VisitObjects(player, searcher, distance); + + std::unordered_set gridSpawnIds; + + for (Creature* creature : creatures) + { + CreatureTemplate const* creatureTemplate = sObjectMgr->GetCreatureTemplate(creature->GetEntry()); + if (!creatureTemplate) + continue; + + handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, creature->GetSpawnId(), creature->GetEntry(), + creature->GetSpawnId(), creatureTemplate->Name, + creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), + creature->GetMapId(), "", ""); + + if (creature->GetSpawnId()) + gridSpawnIds.insert(creature->GetSpawnId()); + ++count; + } + + if (count > 0 && distance <= SIZE_OF_GRIDS) + { + handler->PSendSysMessage(LANG_COMMAND_NEAR_NPC_MESSAGE, distance, count); + return true; + } + + // Fallback to DB query WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_NEAREST); stmt->SetData(0, player->GetPositionX()); stmt->SetData(1, player->GetPositionY()); @@ -746,6 +781,11 @@ public: { Field* fields = result->Fetch(); ObjectGuid::LowType guid = fields[0].Get(); + + // Skip entries already emitted via grid search + if (gridSpawnIds.count(guid)) + continue; + uint32 entry = fields[1].Get(); //uint32 entry2 = fields[2].Get(); //uint32 entry3 = fields[3].Get(); From b348455d538115176363711ff6b9579f8d69ff69 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 15 Feb 2026 08:55:08 -0300 Subject: [PATCH 120/335] =?UTF-8?q?fix(Core/Cmake):=20Rename=20VER=5F*=20m?= =?UTF-8?q?acros=20to=20AC=5F*=20and=20centralize=20build=20dir=E2=80=A6?= =?UTF-8?q?=20(#24717)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Shauren --- modules/ModulesLoader.cpp.in.cmake | 2 +- src/cmake/compiler/clang/settings.cmake | 5 ---- src/cmake/compiler/gcc/settings.cmake | 5 ---- src/cmake/compiler/icc/settings.cmake | 5 ---- src/cmake/compiler/mingw/settings.cmake | 5 ---- src/cmake/compiler/msvc/settings.cmake | 13 --------- src/cmake/macros/ConfigureBaseTargets.cmake | 6 ++++ src/cmake/platform/unix/settings.cmake | 4 --- src/cmake/revision.h.in.cmake | 12 ++++---- src/common/GitRevision.cpp | 10 +++---- src/server/apps/authserver/authserver.rc | 29 +++++++++----------- src/server/apps/worldserver/worldserver.rc | 29 +++++++++----------- src/server/scripts/ScriptLoader.cpp.in.cmake | 2 +- 13 files changed, 45 insertions(+), 82 deletions(-) diff --git a/modules/ModulesLoader.cpp.in.cmake b/modules/ModulesLoader.cpp.in.cmake index 0df08a1cc..807fc840f 100644 --- a/modules/ModulesLoader.cpp.in.cmake +++ b/modules/ModulesLoader.cpp.in.cmake @@ -56,7 +56,7 @@ AC_MODULES_API void AddModulesScripts() /// Exposed in script modules to get the build directive of the module. AC_MODULES_API char const* GetModulesBuildDirective() { - return _BUILD_DIRECTIVE; + return AC_BUILD_TYPE; } #ifdef ACORE_IS_DYNAMIC_SCRIPTLOADER diff --git a/src/cmake/compiler/clang/settings.cmake b/src/cmake/compiler/clang/settings.cmake index 92b95cb47..32f9009a2 100644 --- a/src/cmake/compiler/clang/settings.cmake +++ b/src/cmake/compiler/clang/settings.cmake @@ -16,11 +16,6 @@ if ((USE_COREPCH OR USE_SCRIPTPCH) AND (CMAKE_C_COMPILER_LAUNCHER STREQUAL "ccac set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xclang -fno-pch-timestamp") endif() -# Set build-directive (used in core to tell which buildtype we used) -target_compile_definitions(acore-compile-option-interface - INTERFACE - -D_BUILD_DIRECTIVE="${CMAKE_BUILD_TYPE}") - set(CLANG_EXPECTED_VERSION 10.0.0) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS CLANG_EXPECTED_VERSION) diff --git a/src/cmake/compiler/gcc/settings.cmake b/src/cmake/compiler/gcc/settings.cmake index ce26ac135..2e69ac22a 100644 --- a/src/cmake/compiler/gcc/settings.cmake +++ b/src/cmake/compiler/gcc/settings.cmake @@ -10,11 +10,6 @@ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # -# Set build-directive (used in core to tell which buildtype we used) -target_compile_definitions(acore-compile-option-interface - INTERFACE - -D_BUILD_DIRECTIVE="${CMAKE_BUILD_TYPE}") - set(GCC_EXPECTED_VERSION 8.0.0) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS GCC_EXPECTED_VERSION) diff --git a/src/cmake/compiler/icc/settings.cmake b/src/cmake/compiler/icc/settings.cmake index 9e9e84b84..3d50f9d7c 100644 --- a/src/cmake/compiler/icc/settings.cmake +++ b/src/cmake/compiler/icc/settings.cmake @@ -10,11 +10,6 @@ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # -# Set build-directive (used in core to tell which buildtype we used) -target_compile_definitions(acore-compile-option-interface - INTERFACE - -D_BUILD_DIRECTIVE="${CMAKE_BUILD_TYPE}") - if(PLATFORM EQUAL 32) target_compile_options(acore-compile-option-interface INTERFACE diff --git a/src/cmake/compiler/mingw/settings.cmake b/src/cmake/compiler/mingw/settings.cmake index 1b5a0496a..39f3f3893 100644 --- a/src/cmake/compiler/mingw/settings.cmake +++ b/src/cmake/compiler/mingw/settings.cmake @@ -13,11 +13,6 @@ # set up output paths for executable binaries (.exe-files, and .dll-files on DLL-capable platforms) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -# Set build-directive (used in core to tell which buildtype we used) -target_compile_definitions(acore-compile-option-interface - INTERFACE - -D_BUILD_DIRECTIVE="${CMAKE_BUILD_TYPE}") - if(PLATFORM EQUAL 32) # Required on 32-bit systems to enable SSE2 (standard on x64) target_compile_options(acore-compile-option-interface diff --git a/src/cmake/compiler/msvc/settings.cmake b/src/cmake/compiler/msvc/settings.cmake index 8d859b828..4a95da0ca 100644 --- a/src/cmake/compiler/msvc/settings.cmake +++ b/src/cmake/compiler/msvc/settings.cmake @@ -59,19 +59,6 @@ else() message(STATUS "MSVC: Enabled SSE2 support") endif() -# Set build-directive (used in core to tell which buildtype we used) -# msbuild/devenv don't set CMAKE_MAKE_PROGRAM, you can choose build type from a dropdown after generating projects -if("${CMAKE_MAKE_PROGRAM}" MATCHES "MSBuild") - target_compile_definitions(acore-compile-option-interface - INTERFACE - -D_BUILD_DIRECTIVE="$(ConfigurationName)") -else() - # while all make-like generators do (nmake, ninja) - target_compile_definitions(acore-compile-option-interface - INTERFACE - -D_BUILD_DIRECTIVE="${CMAKE_BUILD_TYPE}") -endif() - # multithreaded compiling on VS target_compile_options(acore-compile-option-interface INTERFACE diff --git a/src/cmake/macros/ConfigureBaseTargets.cmake b/src/cmake/macros/ConfigureBaseTargets.cmake index 830a634ba..e3ff7e022 100644 --- a/src/cmake/macros/ConfigureBaseTargets.cmake +++ b/src/cmake/macros/ConfigureBaseTargets.cmake @@ -20,6 +20,12 @@ set(CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD 20) message(STATUS "Enabled С++20 standard") +# Set build-directive (used in core to tell which buildtype we used) +target_compile_definitions(acore-compile-option-interface + INTERFACE + AC_BUILD_TYPE="$" + AC_BUILD_HAS_DEBUG_INFO=$,$>) + # An interface library to make the warnings level available to other targets # This interface taget is set-up through the platform specific script add_library(acore-warning-interface INTERFACE) diff --git a/src/cmake/platform/unix/settings.cmake b/src/cmake/platform/unix/settings.cmake index 1096f533c..be964a665 100644 --- a/src/cmake/platform/unix/settings.cmake +++ b/src/cmake/platform/unix/settings.cmake @@ -51,8 +51,4 @@ elseif(CMAKE_C_COMPILER MATCHES "icc") include(${CMAKE_SOURCE_DIR}/src/cmake/compiler/icc/settings.cmake) elseif(CMAKE_C_COMPILER MATCHES "clang" OR CMAKE_C_COMPILER_ID MATCHES "Clang") include(${CMAKE_SOURCE_DIR}/src/cmake/compiler/clang/settings.cmake) -else() - target_compile_definitions(acore-compile-option-interface - INTERFACE - -D_BUILD_DIRECTIVE="${CMAKE_BUILD_TYPE}") endif() diff --git a/src/cmake/revision.h.in.cmake b/src/cmake/revision.h.in.cmake index de599c5a6..eb721bfb6 100644 --- a/src/cmake/revision.h.in.cmake +++ b/src/cmake/revision.h.in.cmake @@ -10,10 +10,10 @@ #define _SOURCE_DIRECTORY R"(@CMAKE_SOURCE_DIR@)" #define _BUILD_DIRECTORY R"(@BUILDDIR@)" #define _MYSQL_EXECUTABLE R"(@MYSQL_EXECUTABLE@)" - #define VER_COMPANYNAME_STR "AzerothCore" - #define VER_LEGALCOPYRIGHT_STR "(c)2016-@rev_year@ AzerothCore" - #define VER_FILEVERSION 0,0,0 - #define VER_FILEVERSION_STR "@rev_hash@ @rev_date@ (@rev_branch@ branch)" - #define VER_PRODUCTVERSION VER_FILEVERSION - #define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR + #define AC_COMPANYNAME_STR "AzerothCore" + #define AC_LEGALCOPYRIGHT_STR "(c)2016-@rev_year@ AzerothCore" + #define AC_FILEVERSION 0,0,0 + #define AC_FILEVERSION_STR "@rev_hash@ @rev_date@ (@rev_branch@ branch)" + #define AC_PRODUCTVERSION AC_FILEVERSION + #define AC_PRODUCTVERSION_STR AC_FILEVERSION_STR #endif // __REVISION_H__ diff --git a/src/common/GitRevision.cpp b/src/common/GitRevision.cpp index 7d2c4142c..76ea9f3b4 100644 --- a/src/common/GitRevision.cpp +++ b/src/common/GitRevision.cpp @@ -81,25 +81,25 @@ char const* GitRevision::GetMySQLExecutable() char const* GitRevision::GetFullVersion() { - return VER_COMPANYNAME_STR " rev. " VER_PRODUCTVERSION_STR " (" AZEROTH_PLATFORM_STR ", " _BUILD_DIRECTIVE ", " ACORE_LINKAGE_TYPE_STR ")"; // cppcheck-suppress unknownMacro + return AC_COMPANYNAME_STR " rev. " AC_PRODUCTVERSION_STR " (" AZEROTH_PLATFORM_STR ", " AC_BUILD_TYPE ", " ACORE_LINKAGE_TYPE_STR ")"; // cppcheck-suppress unknownMacro } char const* GitRevision::GetCompanyNameStr() { - return VER_COMPANYNAME_STR; + return AC_COMPANYNAME_STR; } char const* GitRevision::GetLegalCopyrightStr() { - return VER_LEGALCOPYRIGHT_STR; + return AC_LEGALCOPYRIGHT_STR; } char const* GitRevision::GetFileVersionStr() { - return VER_FILEVERSION_STR; + return AC_FILEVERSION_STR; } char const* GitRevision::GetProductVersionStr() { - return VER_PRODUCTVERSION_STR; + return AC_PRODUCTVERSION_STR; } diff --git a/src/server/apps/authserver/authserver.rc b/src/server/apps/authserver/authserver.rc index 3cf579e6c..f0c2e3f5e 100644 --- a/src/server/apps/authserver/authserver.rc +++ b/src/server/apps/authserver/authserver.rc @@ -51,21 +51,18 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT // Version // -VS_VERSION_INFO VERSIONINFO -FILEVERSION VER_FILEVERSION -PRODUCTVERSION VER_PRODUCTVERSION - -FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - -#ifndef _DEBUG - FILEFLAGS 0 +#if AC_BUILD_HAS_DEBUG_INFO == 1 +#define AC_DEBUG VS_FF_DEBUG #else - #define VER_PRERELEASE VS_FF_PRERELEASE - #define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD - #define VER_DEBUG 0 - FILEFLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG) +#define AC_DEBUG 0 #endif +VS_VERSION_INFO VERSIONINFO +FILEVERSION AC_FILEVERSION +PRODUCTVERSION AC_PRODUCTVERSION +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEFLAGS (VS_FF_PRERELEASE | AC_DEBUG) + FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_APP @@ -74,14 +71,14 @@ BEGIN BEGIN BLOCK "080004b0" BEGIN - VALUE "CompanyName", VER_COMPANYNAME_STR + VALUE "CompanyName", AC_COMPANYNAME_STR VALUE "FileDescription", "Authentication Server Daemon" - VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "FileVersion", AC_FILEVERSION_STR VALUE "InternalName", "authserver" - VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR + VALUE "LegalCopyright", AC_LEGALCOPYRIGHT_STR VALUE "OriginalFilename", "authserver.exe" VALUE "ProductName", "Authentication Server" - VALUE "ProductVersion", VER_PRODUCTVERSION_STR + VALUE "ProductVersion", AC_PRODUCTVERSION_STR END END diff --git a/src/server/apps/worldserver/worldserver.rc b/src/server/apps/worldserver/worldserver.rc index 6c8df0021..74b3c585d 100644 --- a/src/server/apps/worldserver/worldserver.rc +++ b/src/server/apps/worldserver/worldserver.rc @@ -51,21 +51,18 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT // Version // -VS_VERSION_INFO VERSIONINFO -FILEVERSION VER_FILEVERSION -PRODUCTVERSION VER_PRODUCTVERSION - -FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - -#ifndef _DEBUG - FILEFLAGS 0 +#if AC_BUILD_HAS_DEBUG_INFO == 1 +#define AC_DEBUG VS_FF_DEBUG #else - #define VER_PRERELEASE VS_FF_PRERELEASE - #define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD - #define VER_DEBUG 0 - FILEFLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG) +#define AC_DEBUG 0 #endif +VS_VERSION_INFO VERSIONINFO +FILEVERSION AC_FILEVERSION +PRODUCTVERSION AC_PRODUCTVERSION +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEFLAGS (VS_FF_PRERELEASE | AC_DEBUG) + FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_APP @@ -74,14 +71,14 @@ BEGIN BEGIN BLOCK "080004b0" BEGIN - VALUE "CompanyName", VER_COMPANYNAME_STR + VALUE "CompanyName", AC_COMPANYNAME_STR VALUE "FileDescription", "World Server Daemon" - VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "FileVersion", AC_FILEVERSION_STR VALUE "InternalName", "worldserver" - VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR + VALUE "LegalCopyright", AC_LEGALCOPYRIGHT_STR VALUE "OriginalFilename", "worldserver.exe" VALUE "ProductName", "World Server" - VALUE "ProductVersion", VER_PRODUCTVERSION_STR + VALUE "ProductVersion", AC_PRODUCTVERSION_STR END END diff --git a/src/server/scripts/ScriptLoader.cpp.in.cmake b/src/server/scripts/ScriptLoader.cpp.in.cmake index 1f6096ccb..8457cb2ec 100644 --- a/src/server/scripts/ScriptLoader.cpp.in.cmake +++ b/src/server/scripts/ScriptLoader.cpp.in.cmake @@ -58,7 +58,7 @@ AC_SCRIPT_API void AddScripts() /// Exposed in script modules to get the build directive of the module. AC_SCRIPT_API char const* GetBuildDirective() { - return _BUILD_DIRECTIVE; + return AC_BUILD_TYPE; } #ifdef ACORE_IS_DYNAMIC_SCRIPTLOADER From a05a43cee10ca02f09d0b7ba3d0ee9d0e56cb6bc Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 15 Feb 2026 08:57:57 -0300 Subject: [PATCH 121/335] refactor(Scripts/Ulduar): Update Ulduar to use boss states and other modernizations (#24714) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../rev_1771122450299085300.sql | 2 + .../Ulduar/boss_algalon_the_observer.cpp | 1493 ++++--- .../Ulduar/Ulduar/boss_assembly_of_iron.cpp | 1154 +++--- .../Northrend/Ulduar/Ulduar/boss_auriaya.cpp | 22 +- .../Ulduar/Ulduar/boss_flame_leviathan.cpp | 1664 ++++---- .../Northrend/Ulduar/Ulduar/boss_freya.cpp | 1675 ++++---- .../Ulduar/Ulduar/boss_general_vezax.cpp | 646 ++- .../Northrend/Ulduar/Ulduar/boss_hodir.cpp | 1710 ++++---- .../Northrend/Ulduar/Ulduar/boss_ignis.cpp | 556 ++- .../Northrend/Ulduar/Ulduar/boss_kologarn.cpp | 331 +- .../Northrend/Ulduar/Ulduar/boss_mimiron.cpp | 3630 ++++++++--------- .../Ulduar/Ulduar/boss_razorscale.cpp | 1407 +++---- .../Northrend/Ulduar/Ulduar/boss_thorim.cpp | 1417 +++---- .../Northrend/Ulduar/Ulduar/boss_xt002.cpp | 1184 +++--- .../Ulduar/Ulduar/boss_yoggsaron.cpp | 3306 +++++++-------- .../Ulduar/Ulduar/instance_ulduar.cpp | 881 ++-- .../Northrend/Ulduar/Ulduar/ulduar.cpp | 310 +- .../scripts/Northrend/Ulduar/Ulduar/ulduar.h | 102 +- 18 files changed, 9986 insertions(+), 11504 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771122450299085300.sql diff --git a/data/sql/updates/pending_db_world/rev_1771122450299085300.sql b/data/sql/updates/pending_db_world/rev_1771122450299085300.sql new file mode 100644 index 000000000..21b165a32 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771122450299085300.sql @@ -0,0 +1,2 @@ +-- Remove unused ScriptName from Pure Saronite Deposit +UPDATE `gameobject_template` SET `ScriptName` = '' WHERE `entry` = 195036; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 8a47bd335..d6833a913 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -260,847 +260,792 @@ private: Unit* _caster; }; -class boss_algalon_the_observer : public CreatureScript +struct boss_algalon_the_observer : public ScriptedAI { -public: - boss_algalon_the_observer() : CreatureScript("boss_algalon_the_observer") {} - - struct boss_algalon_the_observerAI : public ScriptedAI + boss_algalon_the_observer(Creature* creature) : ScriptedAI(creature), summons(me) { - boss_algalon_the_observerAI(Creature* creature) : ScriptedAI(creature), summons(me) - { - _fedOnTears = true; - _firstPull = true; - _fightWon = false; - m_pInstance = me->GetInstanceScript(); - } + _fedOnTears = true; + _firstPull = true; + _fightWon = false; + m_pInstance = me->GetInstanceScript(); + } - EventMap events; - SummonList summons; - InstanceScript* m_pInstance; + EventMap events; + SummonList summons; + InstanceScript* m_pInstance; - bool _firstPull; - bool _fightWon; - bool _phaseTwo; - bool _fedOnTears; - bool _heraldOfTheTitans; + bool _firstPull; + bool _fightWon; + bool _phaseTwo; + bool _fedOnTears; + bool _heraldOfTheTitans; - bool IsValidHeraldItem(ItemTemplate const* item) - { - if (!item) // should not happen, but checked in GetAverageItemLevel() - return true; - if (item->ItemLevel <= 226 || (item->ItemLevel <= 232 && ( - item->InventoryType == INVTYPE_SHIELD || - item->Class == ITEM_CLASS_WEAPON || - (item->Class == ITEM_CLASS_ARMOR && (item->InventoryType == INVTYPE_RELIC || item->InventoryType == INVTYPE_HOLDABLE)) - ))) - return true; - return false; - } + bool IsValidHeraldItem(ItemTemplate const* item) + { + if (!item) // should not happen, but checked in GetAverageItemLevel() + return true; + if (item->ItemLevel <= 226 || (item->ItemLevel <= 232 && ( + item->InventoryType == INVTYPE_SHIELD || + item->Class == ITEM_CLASS_WEAPON || + (item->Class == ITEM_CLASS_ARMOR && (item->InventoryType == INVTYPE_RELIC || item->InventoryType == INVTYPE_HOLDABLE)) + ))) + return true; + return false; + } - bool DoCheckHeraldOfTheTitans() - { - if (!_heraldOfTheTitans) - return true; + bool DoCheckHeraldOfTheTitans() + { + if (!_heraldOfTheTitans) + return true; - Map::PlayerList const& pl = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) - if (Player* plr = itr->GetSource()) - if (!plr->IsGameMaster() && plr->IsInCombat() /*performance*/) - { - for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i) // loop through equipped items - if (Item* item = plr->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (!IsValidHeraldItem(item->GetTemplate())) - { - _heraldOfTheTitans = false; - return true; - } - } - - return false; - } - - void AttackStart(Unit* who) override - { - if (_fightWon) - return; - ScriptedAI::AttackStart(who); - } - - uint32 GetData(uint32 param) const override - { - if (param == DATA_HAS_FED_ON_TEARS) - return _fedOnTears; - if (param == DATA_HERALD_OF_THE_TITANS) - return _heraldOfTheTitans; - return 0; - } - - void CallConstellations() - { - uint8 _count = 0; - for (SummonList::const_iterator i = summons.begin(); i != summons.end(); ) - { - Creature* summon = ObjectAccessor::GetCreature(*me, *i++); - if (summon && summon->GetEntry() == NPC_LIVING_CONSTELLATION && !summon->AI()->GetData(0)) + Map::PlayerList const& pl = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) + if (Player* plr = itr->GetSource()) + if (!plr->IsGameMaster() && plr->IsInCombat() /*performance*/) { - ++_count; - summon->AI()->DoAction(ACTION_ACTIVATE_STAR); - if (_count >= 3) - break; + for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i) // loop through equipped items + if (Item* item = plr->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + if (!IsValidHeraldItem(item->GetTemplate())) + { + _heraldOfTheTitans = false; + return true; + } } - } - } - void EnterEvadeMode(EvadeReason why) override + return false; + } + + void AttackStart(Unit* who) override + { + if (_fightWon) + return; + ScriptedAI::AttackStart(who); + } + + uint32 GetData(uint32 param) const override + { + if (param == DATA_HAS_FED_ON_TEARS) + return _fedOnTears; + if (param == DATA_HERALD_OF_THE_TITANS) + return _heraldOfTheTitans; + return 0; + } + + void CallConstellations() + { + uint8 _count = 0; + for (SummonList::const_iterator i = summons.begin(); i != summons.end(); ) { - if (_fightWon) - return; - - if (SelectTargetFromPlayerList(120.0f)) + Creature* summon = ObjectAccessor::GetCreature(*me, *i++); + if (summon && summon->GetEntry() == NPC_LIVING_CONSTELLATION && !summon->AI()->GetData(0)) { - me->SetInCombatWithZone(); - return; - } - else if (events.GetPhaseMask() & PHASE_NORMAL) - { - DoAction(ACTION_ASCEND); - return; - } - - if (m_pInstance) - m_pInstance->SetData(TYPE_ALGALON, FAIL); - - ScriptedAI::EnterEvadeMode(why); - } - - void Reset() override - { - if (_fightWon) - return; - - events.Reset(); - summons.DespawnAll(); - me->SetReactState(REACT_PASSIVE); - me->SetImmuneToPC(false); - me->SetSheath(SHEATH_STATE_UNARMED); - me->SetFaction(190); - me->CastSpell(me, SPELL_DUAL_WIELD, true); - - _phaseTwo = false; - _heraldOfTheTitans = true; - - if (m_pInstance->GetData(TYPE_ALGALON) == FAIL) - { - _firstPull = false; - } - - if (m_pInstance) - m_pInstance->SetData(TYPE_ALGALON, NOT_STARTED); - } - - void KilledUnit(Unit* victim) override - { - if (!victim->IsPlayer() || urand(0, 2)) - return; - - Talk(SAY_ALGALON_KILL); - } - - void DoAction(int32 action) override - { - switch (action) - { - case ACTION_START_INTRO: - { - me->SetImmuneToPC(true); - me->SetUnitFlag2(UNIT_FLAG2_DO_NOT_FADE_IN); - me->SetDisableGravity(true); - me->CastSpell(me, SPELL_ARRIVAL, true); - me->CastSpell(me, SPELL_RIDE_THE_LIGHTNING, true); - me->GetMotionMaster()->MovePoint(POINT_ALGALON_LAND, AlgalonLandPos); - me->SetHomePosition(AlgalonLandPos); - Movement::MoveSplineInit init(me); - init.MoveTo(AlgalonLandPos.GetPositionX(), AlgalonLandPos.GetPositionY(), AlgalonLandPos.GetPositionZ()); - init.SetOrientationFixed(true); - init.Launch(); - events.Reset(); - events.SetPhase(PHASE_ROLE_PLAY); - events.ScheduleEvent(EVENT_INTRO_1, 5s, 0, PHASE_ROLE_PLAY); - events.ScheduleEvent(EVENT_INTRO_2, 15s, 0, PHASE_ROLE_PLAY); - events.ScheduleEvent(EVENT_INTRO_3, 23s, 0, PHASE_ROLE_PLAY); - events.ScheduleEvent(EVENT_INTRO_FINISH, 36s, 0, PHASE_ROLE_PLAY); - break; - } - case ACTION_DESPAWN_ALGALON: - _fightWon = true; - events.Reset(); - summons.DespawnAll(); - events.SetPhase(PHASE_ROLE_PLAY); - events.ScheduleEvent(EVENT_DESPAWN_ALGALON_1, 5s); - events.ScheduleEvent(EVENT_DESPAWN_ALGALON_2, 17s); - events.ScheduleEvent(EVENT_DESPAWN_ALGALON_3, 26s); - if (me->IsInCombat()) - events.ScheduleEvent(EVENT_DESPAWN_ALGALON_4, 26s); - events.ScheduleEvent(EVENT_DESPAWN_ALGALON_5, 32s); - me->DespawnOrUnsummon(39s); - - me->SetReactState(REACT_PASSIVE); - me->AttackStop(); - me->SetFaction(FACTION_FRIENDLY); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->InterruptNonMeleeSpells(false); - if (m_pInstance) - m_pInstance->SetData(TYPE_ALGALON, NOT_STARTED); + ++_count; + summon->AI()->DoAction(ACTION_ACTIVATE_STAR); + if (_count >= 3) break; - case ACTION_INIT_ALGALON: - _firstPull = false; - _fedOnTears = false; - me->SetImmuneToPC(false); - break; - case ACTION_ASCEND: - summons.DespawnAll(); - events.SetPhase(PHASE_BIG_BANG); - events.ScheduleEvent(EVENT_ASCEND_TO_THE_HEAVENS, 1500ms); - break; - case ACTION_FEEDS_ON_TEARS_FAILED: - _fedOnTears = false; } } + } - void JustReachedHome() override + void EnterEvadeMode(EvadeReason why) override + { + if (_fightWon) + return; + + if (SelectTargetFromPlayerList(120.0f)) { - me->setActive(false); - } - - void JustEngagedWith(Unit*) override - { - if (_fightWon) - return; - - if (!m_pInstance) - { - EnterEvadeMode(EVADE_REASON_OTHER); - return; - } - - Milliseconds introDelay = 0ms; - me->setActive(true); me->SetInCombatWithZone(); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetImmuneToNPC(true); - events.Reset(); - events.SetPhase(PHASE_ROLE_PLAY); - - if (!_firstPull) - { - events.ScheduleEvent(EVENT_START_COMBAT, 0ms); - introDelay = 8s; - } - else - { - summons.DespawnEntry(NPC_AZEROTH); - _firstPull = false; - Talk(SAY_ALGALON_START_TIMER); - introDelay = 22s; - events.ScheduleEvent(EVENT_START_COMBAT, 14s); - m_pInstance->SetData(DATA_DESPAWN_ALGALON, 0); - } - - events.ScheduleEvent(EVENT_REMOVE_UNNATTACKABLE, introDelay - 500ms); - events.ScheduleEvent(EVENT_INTRO_TIMER_DONE, introDelay); - events.ScheduleEvent(EVENT_QUANTUM_STRIKE, 3500ms + introDelay); - events.ScheduleEvent(EVENT_PHASE_PUNCH, 15500ms + introDelay); - events.ScheduleEvent(EVENT_SUMMON_COLLAPSING_STAR, 16500ms + introDelay); - events.ScheduleEvent(EVENT_COSMIC_SMASH, 25s + introDelay); - events.ScheduleEvent(EVENT_ACTIVATE_LIVING_CONSTELLATION, 50500ms + introDelay); - events.ScheduleEvent(EVENT_BIG_BANG, 90s + introDelay); - events.ScheduleEvent(EVENT_ASCEND_TO_THE_HEAVENS, 360s + introDelay); - - events.ScheduleEvent(EVENT_CHECK_HERALD_ITEMS, 5s); - DoCheckHeraldOfTheTitans(); + return; + } + else if (events.GetPhaseMask() & PHASE_NORMAL) + { + DoAction(ACTION_ASCEND); + return; } - void MovementInform(uint32 movementType, uint32 pointId) override - { - if (movementType != POINT_MOTION_TYPE) - return; + if (m_pInstance) + m_pInstance->SetData(BOSS_ALGALON, FAIL); - if (pointId == POINT_ALGALON_LAND) - me->SetDisableGravity(false); - else if (pointId == POINT_ALGALON_OUTRO) - { - me->SetFacingTo(1.605703f); - events.ScheduleEvent(EVENT_OUTRO_3, 1200ms); - events.ScheduleEvent(EVENT_OUTRO_4, 2400ms); - events.ScheduleEvent(EVENT_OUTRO_5, 8500ms); - events.ScheduleEvent(EVENT_OUTRO_6, 15s + 500ms); - events.ScheduleEvent(EVENT_OUTRO_7, 55s + 500ms); - events.ScheduleEvent(EVENT_OUTRO_8, 73s + 500ms); - events.ScheduleEvent(EVENT_OUTRO_9, 85s + 500ms); - events.ScheduleEvent(EVENT_OUTRO_10, 101s + 500ms); - events.ScheduleEvent(EVENT_OUTRO_11, 117s + 500ms); - } + ScriptedAI::EnterEvadeMode(why); + } + + void Reset() override + { + if (_fightWon) + return; + + events.Reset(); + summons.DespawnAll(); + me->SetReactState(REACT_PASSIVE); + me->SetImmuneToPC(false); + me->SetSheath(SHEATH_STATE_UNARMED); + me->SetFaction(190); + me->CastSpell(me, SPELL_DUAL_WIELD, true); + + _phaseTwo = false; + _heraldOfTheTitans = true; + + if (m_pInstance->GetBossState(BOSS_ALGALON) == FAIL) + { + _firstPull = false; } - void JustSummoned(Creature* summon) override + if (m_pInstance) + m_pInstance->SetData(BOSS_ALGALON, NOT_STARTED); + } + + void KilledUnit(Unit* victim) override + { + if (!victim->IsPlayer() || urand(0, 2)) + return; + + Talk(SAY_ALGALON_KILL); + } + + void DoAction(int32 action) override + { + switch (action) { - summons.Summon(summon); - switch (summon->GetEntry()) - { - case NPC_AZEROTH: - me->CastSpell(summon, SPELL_REORIGINATION, true); + case ACTION_START_INTRO: + { + me->SetImmuneToPC(true); + me->SetUnitFlag2(UNIT_FLAG2_DO_NOT_FADE_IN); + me->SetDisableGravity(true); + me->CastSpell(me, SPELL_ARRIVAL, true); + me->CastSpell(me, SPELL_RIDE_THE_LIGHTNING, true); + me->GetMotionMaster()->MovePoint(POINT_ALGALON_LAND, AlgalonLandPos); + me->SetHomePosition(AlgalonLandPos); + Movement::MoveSplineInit init(me); + init.MoveTo(AlgalonLandPos.GetPositionX(), AlgalonLandPos.GetPositionY(), AlgalonLandPos.GetPositionZ()); + init.SetOrientationFixed(true); + init.Launch(); + events.Reset(); + events.SetPhase(PHASE_ROLE_PLAY); + events.ScheduleEvent(EVENT_INTRO_1, 5s, 0, PHASE_ROLE_PLAY); + events.ScheduleEvent(EVENT_INTRO_2, 15s, 0, PHASE_ROLE_PLAY); + events.ScheduleEvent(EVENT_INTRO_3, 23s, 0, PHASE_ROLE_PLAY); + events.ScheduleEvent(EVENT_INTRO_FINISH, 36s, 0, PHASE_ROLE_PLAY); break; - case NPC_BLACK_HOLE: - summon->CastSpell((Unit*)nullptr, SPELL_BLACK_HOLE_TRIGGER, true); - summon->CastSpell(summon, SPELL_CONSTELLATION_PHASE_TRIGGER, true); - summon->CastSpell((Unit*)nullptr, SPELL_BLACK_HOLE_EXPLOSION, false); - summon->CastSpell(summon, SPELL_SUMMON_VOID_ZONE_VISUAL, true); - break; - case NPC_ALGALON_VOID_ZONE_VISUAL_STALKER: - summon->CastSpell(summon, SPELL_VOID_ZONE_VISUAL, true); - break; - case NPC_ALGALON_STALKER_ASTEROID_TARGET_01: - summon->CastSpell(summon, SPELL_COSMIC_SMASH_VISUAL_STATE, true); - break; - case NPC_ALGALON_STALKER_ASTEROID_TARGET_02: - { - float x = summon->GetPositionX(); - float y = summon->GetPositionY(); - float z = summon->GetPositionZ() + 35.0f; - float o = summon->GetOrientation(); - - summon->GetMotionMaster()->Clear(); - summon->SetHomePosition(x, y, z, o); - summon->UpdatePosition(x, y, z, o, true); - summon->StopMovingOnCurrentPos(); - summon->m_Events.AddEventAtOffset(new CosmicSmashDamageEvent(summon), 4s); - break; - } - case NPC_UNLEASHED_DARK_MATTER: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true)) - if (summon->Attack(target, true)) - summon->GetMotionMaster()->MoveChase(target); - break; - } - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (_fightWon) - { - damage = 0; - return; - } - - if (!_phaseTwo && me->HealthBelowPctDamaged(20, damage)) - { - _phaseTwo = true; - Talk(SAY_ALGALON_PHASE_TWO); - summons.DespawnEntry(NPC_LIVING_CONSTELLATION); - summons.DespawnEntry(NPC_COLLAPSING_STAR); - summons.DespawnEntry(NPC_BLACK_HOLE); - summons.DespawnEntry(NPC_ALGALON_VOID_ZONE_VISUAL_STALKER); - events.CancelEvent(EVENT_SUMMON_COLLAPSING_STAR); - events.CancelEvent(EVENT_ACTIVATE_LIVING_CONSTELLATION); - - for (uint32 i = 0; i < COLLAPSING_STAR_COUNT; ++i) - me->SummonCreature(NPC_WORM_HOLE, CollapsingStarPos[i], TEMPSUMMON_MANUAL_DESPAWN); - } - else if (me->HealthBelowPctDamaged(2, damage) && !_fightWon) - { + } + case ACTION_DESPAWN_ALGALON: _fightWon = true; - damage = 0; + events.Reset(); + summons.DespawnAll(); + events.SetPhase(PHASE_ROLE_PLAY); + events.ScheduleEvent(EVENT_DESPAWN_ALGALON_1, 5s); + events.ScheduleEvent(EVENT_DESPAWN_ALGALON_2, 17s); + events.ScheduleEvent(EVENT_DESPAWN_ALGALON_3, 26s); + if (me->IsInCombat()) + events.ScheduleEvent(EVENT_DESPAWN_ALGALON_4, 26s); + events.ScheduleEvent(EVENT_DESPAWN_ALGALON_5, 32s); + me->DespawnOrUnsummon(39s); + me->SetReactState(REACT_PASSIVE); me->AttackStop(); me->SetFaction(FACTION_FRIENDLY); me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - events.Reset(); - summons.DespawnAll(); me->InterruptNonMeleeSpells(false); - events.SetPhase(PHASE_ROLE_PLAY); - events.ScheduleEvent(EVENT_OUTRO_START, 1500ms); - events.ScheduleEvent(EVENT_OUTRO_1, 7200ms); - events.ScheduleEvent(EVENT_OUTRO_2, 8700ms); - } + if (m_pInstance) + m_pInstance->SetData(BOSS_ALGALON, NOT_STARTED); + break; + case ACTION_INIT_ALGALON: + _firstPull = false; + _fedOnTears = false; + me->SetImmuneToPC(false); + break; + case ACTION_ASCEND: + summons.DespawnAll(); + events.SetPhase(PHASE_BIG_BANG); + events.ScheduleEvent(EVENT_ASCEND_TO_THE_HEAVENS, 1500ms); + break; + case ACTION_FEEDS_ON_TEARS_FAILED: + _fedOnTears = false; + } + } + + void JustReachedHome() override + { + me->setActive(false); + } + + void JustEngagedWith(Unit*) override + { + if (_fightWon) + return; + + if (!m_pInstance) + { + EnterEvadeMode(EVADE_REASON_OTHER); + return; } - bool IsInRoom() - { - if (me->GetExactDist2d(&me->GetHomePosition()) > 45.f || me->GetPositionZ() < 410.f) - { - DoAction(ACTION_ASCEND); - return false; - } + Milliseconds introDelay = 0ms; + me->setActive(true); + me->SetInCombatWithZone(); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetImmuneToNPC(true); + events.Reset(); + events.SetPhase(PHASE_ROLE_PLAY); - return true; + if (!_firstPull) + { + events.ScheduleEvent(EVENT_START_COMBAT, 0ms); + introDelay = 8s; + } + else + { + summons.DespawnEntry(NPC_AZEROTH); + _firstPull = false; + Talk(SAY_ALGALON_START_TIMER); + introDelay = 22s; + events.ScheduleEvent(EVENT_START_COMBAT, 14s); + m_pInstance->SetData(DATA_DESPAWN_ALGALON, 0); } - void UpdateAI(uint32 diff) override + events.ScheduleEvent(EVENT_REMOVE_UNNATTACKABLE, introDelay - 500ms); + events.ScheduleEvent(EVENT_INTRO_TIMER_DONE, introDelay); + events.ScheduleEvent(EVENT_QUANTUM_STRIKE, 3500ms + introDelay); + events.ScheduleEvent(EVENT_PHASE_PUNCH, 15500ms + introDelay); + events.ScheduleEvent(EVENT_SUMMON_COLLAPSING_STAR, 16500ms + introDelay); + events.ScheduleEvent(EVENT_COSMIC_SMASH, 25s + introDelay); + events.ScheduleEvent(EVENT_ACTIVATE_LIVING_CONSTELLATION, 50500ms + introDelay); + events.ScheduleEvent(EVENT_BIG_BANG, 90s + introDelay); + events.ScheduleEvent(EVENT_ASCEND_TO_THE_HEAVENS, 360s + introDelay); + + events.ScheduleEvent(EVENT_CHECK_HERALD_ITEMS, 5s); + DoCheckHeraldOfTheTitans(); + } + + void MovementInform(uint32 movementType, uint32 pointId) override + { + if (movementType != POINT_MOTION_TYPE) + return; + + if (pointId == POINT_ALGALON_LAND) + me->SetDisableGravity(false); + else if (pointId == POINT_ALGALON_OUTRO) { - if (!(events.GetPhaseMask() & PHASE_MASK_NO_UPDATE) && (!UpdateVictim() || !IsInRoom())) - return; + me->SetFacingTo(1.605703f); + events.ScheduleEvent(EVENT_OUTRO_3, 1200ms); + events.ScheduleEvent(EVENT_OUTRO_4, 2400ms); + events.ScheduleEvent(EVENT_OUTRO_5, 8500ms); + events.ScheduleEvent(EVENT_OUTRO_6, 15s + 500ms); + events.ScheduleEvent(EVENT_OUTRO_7, 55s + 500ms); + events.ScheduleEvent(EVENT_OUTRO_8, 73s + 500ms); + events.ScheduleEvent(EVENT_OUTRO_9, 85s + 500ms); + events.ScheduleEvent(EVENT_OUTRO_10, 101s + 500ms); + events.ScheduleEvent(EVENT_OUTRO_11, 117s + 500ms); + } + } - events.Update(diff); - if (!(events.GetPhaseMask() & PHASE_MASK_NO_CAST_CHECK) && me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_INTRO_1: - me->RemoveAurasDueToSpell(SPELL_RIDE_THE_LIGHTNING); - Talk(SAY_ALGALON_INTRO_1); - break; - case EVENT_INTRO_2: - me->CastSpell((Unit*)nullptr, SPELL_SUMMON_AZEROTH, true); - Talk(SAY_ALGALON_INTRO_2); - break; - case EVENT_INTRO_3: - Talk(SAY_ALGALON_INTRO_3); - break; - case EVENT_INTRO_FINISH: - events.Reset(); - me->SetImmuneToPC(false); - if (Creature* brann = ObjectAccessor::GetCreature(*me, m_pInstance->GetGuidData(NPC_BRANN_BRONZBEARD_ALG))) - brann->AI()->DoAction(ACTION_FINISH_INTRO); - break; - case EVENT_START_COMBAT: - m_pInstance->SetData(TYPE_ALGALON, IN_PROGRESS); - Talk(SAY_ALGALON_AGGRO); - break; - case EVENT_REMOVE_UNNATTACKABLE: - me->SetSheath(SHEATH_STATE_MELEE); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetImmuneToNPC(false); - break; - case EVENT_INTRO_TIMER_DONE: - events.SetPhase(PHASE_NORMAL); - me->CastSpell((Unit*)nullptr, SPELL_SUPERMASSIVE_FAIL, true); - // Hack: _IsValidTarget failed earlier due to flags, call AttackStart again - me->SetReactState(REACT_AGGRESSIVE); - me->SetFaction(FACTION_MONSTER); - if (Player* target = SelectTargetFromPlayerList(150.0f)) - AttackStart(target); - me->SetInCombatWithZone(); - - for (uint32 i = 0; i < LIVING_CONSTELLATION_COUNT; ++i) - me->SummonCreature(NPC_LIVING_CONSTELLATION, ConstellationPos[i], TEMPSUMMON_DEAD_DESPAWN); - break; - case EVENT_QUANTUM_STRIKE: - me->CastSpell(me->GetVictim(), SPELL_QUANTUM_STRIKE, false); - events.Repeat(3s, 4500ms); - break; - case EVENT_PHASE_PUNCH: - me->CastSpell(me->GetVictim(), SPELL_PHASE_PUNCH, false); - events.Repeat(15s + 500ms); - break; - case EVENT_SUMMON_COLLAPSING_STAR: - Talk(SAY_ALGALON_COLLAPSING_STAR); - Talk(EMOTE_ALGALON_COLLAPSING_STAR); - for (uint8 i = 0; i < COLLAPSING_STAR_COUNT; ++i) - me->SummonCreature(NPC_COLLAPSING_STAR, CollapsingStarPos[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); - events.Repeat(1min); - break; - case EVENT_COSMIC_SMASH: - Talk(EMOTE_ALGALON_COSMIC_SMASH); - me->CastCustomSpell(SPELL_COSMIC_SMASH, SPELLVALUE_MAX_TARGETS, RAID_MODE(1, 3), (Unit*)nullptr); - events.Repeat(25s + 500ms); - break; - case EVENT_ACTIVATE_LIVING_CONSTELLATION: - { - if (events.GetPhaseMask() & PHASE_MASK_NO_UPDATE) - { - events.Repeat(4s); - break; - } - CallConstellations(); - //me->CastSpell(me, SPELL_TRIGGER_3_ADDS, true); - events.Repeat(50s); - break; - } - case EVENT_BIG_BANG: - { - Talk(SAY_ALGALON_BIG_BANG); - Talk(EMOTE_ALGALON_BIG_BANG); - - EntryCheckPredicate pred(NPC_LIVING_CONSTELLATION); - summons.DoAction(ACTION_BIG_BANG, pred); - - me->CastSpell((Unit*)nullptr, SPELL_BIG_BANG, false); - events.Repeat(90s + 500ms); - break; - } - case EVENT_ASCEND_TO_THE_HEAVENS: - Talk(SAY_ALGALON_ASCEND); - me->CastSpell((Unit*)nullptr, SPELL_ASCEND_TO_THE_HEAVENS, false); - events.ScheduleEvent(EVENT_EVADE, 2500ms); - break; - case EVENT_EVADE: - events.Reset(); - ScriptedAI::EnterEvadeMode(); - return; - case EVENT_OUTRO_START: - if (m_pInstance) - { - m_pInstance->SetData(TYPE_ALGALON, DONE); - m_pInstance->SetData(DATA_ALGALON_DEFEATED, 1); - } - break; - case EVENT_OUTRO_1: - me->RemoveAllAuras(); - me->SetUnitFlag(UNIT_FLAG_RENAME); - break; - case EVENT_OUTRO_2: + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + switch (summon->GetEntry()) + { + case NPC_AZEROTH: + me->CastSpell(summon, SPELL_REORIGINATION, true); + break; + case NPC_BLACK_HOLE: + summon->CastSpell((Unit*)nullptr, SPELL_BLACK_HOLE_TRIGGER, true); + summon->CastSpell(summon, SPELL_CONSTELLATION_PHASE_TRIGGER, true); + summon->CastSpell((Unit*)nullptr, SPELL_BLACK_HOLE_EXPLOSION, false); + summon->CastSpell(summon, SPELL_SUMMON_VOID_ZONE_VISUAL, true); + break; + case NPC_ALGALON_VOID_ZONE_VISUAL_STALKER: + summon->CastSpell(summon, SPELL_VOID_ZONE_VISUAL, true); + break; + case NPC_ALGALON_STALKER_ASTEROID_TARGET_01: + summon->CastSpell(summon, SPELL_COSMIC_SMASH_VISUAL_STATE, true); + break; + case NPC_ALGALON_STALKER_ASTEROID_TARGET_02: { - Player* lootRecipent = me->GetLootRecipient(); - _EnterEvadeMode(); - // LootRecipent is cleared in _EnterEvadeMode, restore it - me->SetLootRecipient(lootRecipent); - me->GetMotionMaster()->MovePoint(POINT_ALGALON_OUTRO, AlgalonOutroPos); + float x = summon->GetPositionX(); + float y = summon->GetPositionY(); + float z = summon->GetPositionZ() + 35.0f; + float o = summon->GetOrientation(); + + summon->GetMotionMaster()->Clear(); + summon->SetHomePosition(x, y, z, o); + summon->UpdatePosition(x, y, z, o, true); + summon->StopMovingOnCurrentPos(); + summon->m_Events.AddEventAtOffset(new CosmicSmashDamageEvent(summon), 4s); break; } - case EVENT_OUTRO_3: - me->CastSpell((Unit*)nullptr, SPELL_KILL_CREDIT); - // Summon Chest - if (GameObject* go = me->SummonGameObject(RAID_MODE(GO_ALGALON_CHEST, GO_ALGALON_CHEST_HERO), 1632.1f, -306.561f, 417.321f, 4.69494f, 0, 0, 0, 1, 0)) - { - go->ReplaceAllGameObjectFlags((GameObjectFlags)0); - go->SetLootRecipient(me); - } - break; - case EVENT_OUTRO_4: - me->CastSpell((Unit*)nullptr, SPELL_SUPERMASSIVE_FAIL); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - break; - case EVENT_OUTRO_5: - if (Creature* brann = me->SummonCreature(NPC_BRANN_BRONZBEARD_ALG, BrannOutroPos[0], TEMPSUMMON_TIMED_DESPAWN, 131500)) - brann->AI()->DoAction(ACTION_OUTRO); - break; - case EVENT_OUTRO_6: - Talk(SAY_ALGALON_OUTRO_1); - me->SetStandState(UNIT_STAND_STATE_KNEEL); - break; - case EVENT_OUTRO_7: - Talk(SAY_ALGALON_OUTRO_2); - break; - case EVENT_OUTRO_8: - Talk(SAY_ALGALON_OUTRO_3); - break; - case EVENT_OUTRO_9: - Talk(SAY_ALGALON_OUTRO_4); - break; - case EVENT_OUTRO_10: - Talk(SAY_ALGALON_OUTRO_5); - break; - case EVENT_OUTRO_11: - me->SetStandState(UNIT_STAND_STATE_STAND); - me->CastSpell(me, SPELL_TELEPORT, false); - me->DespawnOrUnsummon(3s); - break; - case EVENT_DESPAWN_ALGALON_1: - Talk(SAY_ALGALON_DESPAWN_1); - break; - case EVENT_DESPAWN_ALGALON_2: - Talk(SAY_ALGALON_DESPAWN_2); - break; - case EVENT_DESPAWN_ALGALON_3: - Talk(SAY_ALGALON_DESPAWN_3); - break; - case EVENT_DESPAWN_ALGALON_4: - me->CastSpell((Unit*)nullptr, SPELL_ASCEND_TO_THE_HEAVENS, false); - break; - case EVENT_DESPAWN_ALGALON_5: - me->SetStandState(UNIT_STAND_STATE_STAND); - me->CastSpell(me, SPELL_TELEPORT, false); - me->DespawnOrUnsummon(3s); - break; - case EVENT_CHECK_HERALD_ITEMS: - if (!DoCheckHeraldOfTheTitans()) - events.Repeat(5s); - break; - } - - DoMeleeAttackIfReady(); + case NPC_UNLEASHED_DARK_MATTER: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true)) + if (summon->Attack(target, true)) + summon->GetMotionMaster()->MoveChase(target); + break; } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI(creature); } -}; -class npc_brann_bronzebeard_algalon : public CreatureScript -{ -public: - npc_brann_bronzebeard_algalon() : CreatureScript("npc_brann_bronzebeard_algalon") { } - - struct npc_brann_bronzebeard_algalonAI : public CreatureAI + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override { - npc_brann_bronzebeard_algalonAI(Creature* creature) : CreatureAI(creature) + if (_fightWon) { + damage = 0; + return; } - EventMap events; - uint32 _currentPoint; - - void DoAction(int32 action) override + if (!_phaseTwo && me->HealthBelowPctDamaged(20, damage)) { - switch (action) - { - case ACTION_START_INTRO: - me->SetWalk(false); - _currentPoint = 0; - events.Reset(); - events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 1ms); - break; - case ACTION_FINISH_INTRO: - Talk(SAY_BRANN_ALGALON_INTRO_2); - events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 1ms); - break; - case ACTION_OUTRO: - me->GetMotionMaster()->MovePoint(POINT_BRANN_OUTRO, BrannOutroPos[1]); - events.ScheduleEvent(EVENT_BRANN_OUTRO_1, 87s + 500ms); - events.ScheduleEvent(EVENT_BRANN_OUTRO_2, 116s + 500ms); - break; - } + _phaseTwo = true; + Talk(SAY_ALGALON_PHASE_TWO); + summons.DespawnEntry(NPC_LIVING_CONSTELLATION); + summons.DespawnEntry(NPC_COLLAPSING_STAR); + summons.DespawnEntry(NPC_BLACK_HOLE); + summons.DespawnEntry(NPC_ALGALON_VOID_ZONE_VISUAL_STALKER); + events.CancelEvent(EVENT_SUMMON_COLLAPSING_STAR); + events.CancelEvent(EVENT_ACTIVATE_LIVING_CONSTELLATION); + + for (uint32 i = 0; i < COLLAPSING_STAR_COUNT; ++i) + me->SummonCreature(NPC_WORM_HOLE, CollapsingStarPos[i], TEMPSUMMON_MANUAL_DESPAWN); } - - void MovementInform(uint32 movementType, uint32 pointId) override - { - if (movementType != POINT_MOTION_TYPE) - return; - - Milliseconds delay = 1ms; - _currentPoint = pointId + 1; - switch (pointId) - { - case 2: - delay = 8s; - me->SetWalk(true); - break; - case 6: - me->SetFacingTo(4.6156f); - me->SetWalk(false); - Talk(SAY_BRANN_ALGALON_INTRO_1); - events.ScheduleEvent(EVENT_SUMMON_ALGALON, 7500ms); - return; - case 10: - me->DespawnOrUnsummon(1ms); - return; - case POINT_BRANN_OUTRO: - case POINT_BRANN_OUTRO_END: - return; - } - - events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, delay); - } - - void UpdateAI(uint32 diff) override - { - UpdateVictim(); - events.Update(diff); - - switch (events.ExecuteEvent()) - { - case EVENT_BRANN_MOVE_INTRO: - if (_currentPoint < MAX_BRANN_WAYPOINTS_INTRO) - me->GetMotionMaster()->MovePoint(_currentPoint, BrannIntroWaypoint[_currentPoint]); - break; - case EVENT_SUMMON_ALGALON: - if (me->GetInstanceScript() && !me->GetInstanceScript()->GetGuidData(TYPE_ALGALON)) - if (Creature* algalon = me->GetMap()->SummonCreature(NPC_ALGALON, AlgalonSummonPos)) - algalon->AI()->DoAction(ACTION_START_INTRO); - break; - case EVENT_BRANN_OUTRO_1: - Talk(SAY_BRANN_ALGALON_OUTRO); - break; - case EVENT_BRANN_OUTRO_2: - me->GetMotionMaster()->MovePoint(POINT_BRANN_OUTRO_END, BrannOutroPos[2]); - break; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI(creature); - } -}; - -class npc_collapsing_star : public CreatureScript -{ -public: - npc_collapsing_star() : CreatureScript("npc_collapsing_star") { } - - struct npc_collapsing_starAI : public NullCreatureAI - { - npc_collapsing_starAI(Creature* creature) : NullCreatureAI(creature) - { - creature->GetMotionMaster()->MoveRandom(25.0f); - creature->CastSpell(creature, SPELL_COLLAPSE, true); - } - - void JustSummoned(Creature* summon) override - { - if (TempSummon* summ = me->ToTempSummon()) - if (Creature* algalon = ObjectAccessor::GetCreature(*me, summ->GetSummonerGUID())) - algalon->AI()->JustSummoned(summon); - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (damage >= me->GetHealth()) - { - me->CastSpell(me, SPELL_BLACK_HOLE_SPAWN_VISUAL, true); - me->CastSpell(me, SPELL_SUMMON_BLACK_HOLE, true); - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI(creature); - } -}; - -class npc_living_constellation : public CreatureScript -{ -public: - npc_living_constellation() : CreatureScript("npc_living_constellation") { } - - struct npc_living_constellationAI : public ScriptedAI - { - npc_living_constellationAI(Creature* creature) : ScriptedAI(creature) + else if (me->HealthBelowPctDamaged(2, damage) && !_fightWon) { + _fightWon = true; + damage = 0; me->SetReactState(REACT_PASSIVE); - } - - EventMap events; - bool _isActive; - - void Reset() override - { + me->AttackStop(); + me->SetFaction(FACTION_FRIENDLY); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); events.Reset(); - events.ScheduleEvent(EVENT_ARCANE_BARRAGE, 2500ms); - _isActive = false; + summons.DespawnAll(); + me->InterruptNonMeleeSpells(false); + events.SetPhase(PHASE_ROLE_PLAY); + events.ScheduleEvent(EVENT_OUTRO_START, 1500ms); + events.ScheduleEvent(EVENT_OUTRO_1, 7200ms); + events.ScheduleEvent(EVENT_OUTRO_2, 8700ms); } + } - uint32 GetData(uint32 /*param*/) const override - { - return _isActive; - } - - void DoAction(int32 action) override - { - switch (action) - { - case ACTION_ACTIVATE_STAR: - me->SetReactState(REACT_AGGRESSIVE); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetImmuneToAll(false); - _isActive = true; - - if (Player* target = SelectTargetFromPlayerList(250.0f)) - { - AttackStart(target); - me->AddThreat(target, 100.0f); - } - me->SetInCombatWithZone(); - break; - case ACTION_BIG_BANG: - events.SetPhase(PHASE_BIG_BANG); - events.DelayEvents(9500ms); - events.ScheduleEvent(EVENT_RESUME_UPDATING, 9500ms); - break; - } - } - - void SpellHit(Unit* caster, SpellInfo const* spell) override - { - if (spell->Id != SPELL_CONSTELLATION_PHASE_EFFECT || !caster->IsCreature()) - return; - - if (InstanceScript* instance = me->GetInstanceScript()) - instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_ID_SUPERMASSIVE_START); - - caster->CastSpell((Unit*)nullptr, SPELL_BLACK_HOLE_CREDIT, TRIGGERED_FULL_MASK); - caster->ToCreature()->DespawnOrUnsummon(1ms); - me->DespawnOrUnsummon(1ms); - if (Creature* voidZone = caster->FindNearestCreature(NPC_ALGALON_VOID_ZONE_VISUAL_STALKER, 10.0f)) - voidZone->DespawnOrUnsummon(1ms); - } - - void UpdateAI(uint32 diff) override - { - if (!(events.GetPhaseMask() & PHASE_MASK_NO_UPDATE) && !UpdateVictim()) - return; - - events.Update(diff); - switch (events.ExecuteEvent()) - { - case EVENT_ARCANE_BARRAGE: - me->CastCustomSpell(SPELL_ARCANE_BARRAGE, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, true); - events.Repeat(2500ms); - break; - case EVENT_RESUME_UPDATING: - events.SetPhase(0); - break; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override + bool IsInRoom() { - return GetUlduarAI(creature); + if (me->GetExactDist2d(&me->GetHomePosition()) > 45.f || me->GetPositionZ() < 410.f) + { + DoAction(ACTION_ASCEND); + return false; + } + + return true; + } + + void UpdateAI(uint32 diff) override + { + if (!(events.GetPhaseMask() & PHASE_MASK_NO_UPDATE) && (!UpdateVictim() || !IsInRoom())) + return; + + events.Update(diff); + if (!(events.GetPhaseMask() & PHASE_MASK_NO_CAST_CHECK) && me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_INTRO_1: + me->RemoveAurasDueToSpell(SPELL_RIDE_THE_LIGHTNING); + Talk(SAY_ALGALON_INTRO_1); + break; + case EVENT_INTRO_2: + me->CastSpell((Unit*)nullptr, SPELL_SUMMON_AZEROTH, true); + Talk(SAY_ALGALON_INTRO_2); + break; + case EVENT_INTRO_3: + Talk(SAY_ALGALON_INTRO_3); + break; + case EVENT_INTRO_FINISH: + events.Reset(); + me->SetImmuneToPC(false); + if (Creature* brann = m_pInstance->GetCreature(DATA_BRANN_BRONZEBEARD_ALG)) + brann->AI()->DoAction(ACTION_FINISH_INTRO); + break; + case EVENT_START_COMBAT: + m_pInstance->SetData(BOSS_ALGALON, IN_PROGRESS); + Talk(SAY_ALGALON_AGGRO); + break; + case EVENT_REMOVE_UNNATTACKABLE: + me->SetSheath(SHEATH_STATE_MELEE); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetImmuneToNPC(false); + break; + case EVENT_INTRO_TIMER_DONE: + events.SetPhase(PHASE_NORMAL); + me->CastSpell((Unit*)nullptr, SPELL_SUPERMASSIVE_FAIL, true); + // Hack: _IsValidTarget failed earlier due to flags, call AttackStart again + me->SetReactState(REACT_AGGRESSIVE); + me->SetFaction(FACTION_MONSTER); + if (Player* target = SelectTargetFromPlayerList(150.0f)) + AttackStart(target); + me->SetInCombatWithZone(); + + for (uint32 i = 0; i < LIVING_CONSTELLATION_COUNT; ++i) + me->SummonCreature(NPC_LIVING_CONSTELLATION, ConstellationPos[i], TEMPSUMMON_DEAD_DESPAWN); + break; + case EVENT_QUANTUM_STRIKE: + me->CastSpell(me->GetVictim(), SPELL_QUANTUM_STRIKE, false); + events.Repeat(3s, 4500ms); + break; + case EVENT_PHASE_PUNCH: + me->CastSpell(me->GetVictim(), SPELL_PHASE_PUNCH, false); + events.Repeat(15s + 500ms); + break; + case EVENT_SUMMON_COLLAPSING_STAR: + Talk(SAY_ALGALON_COLLAPSING_STAR); + Talk(EMOTE_ALGALON_COLLAPSING_STAR); + for (uint8 i = 0; i < COLLAPSING_STAR_COUNT; ++i) + me->SummonCreature(NPC_COLLAPSING_STAR, CollapsingStarPos[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); + events.Repeat(1min); + break; + case EVENT_COSMIC_SMASH: + Talk(EMOTE_ALGALON_COSMIC_SMASH); + me->CastCustomSpell(SPELL_COSMIC_SMASH, SPELLVALUE_MAX_TARGETS, RAID_MODE(1, 3), (Unit*)nullptr); + events.Repeat(25s + 500ms); + break; + case EVENT_ACTIVATE_LIVING_CONSTELLATION: + { + if (events.GetPhaseMask() & PHASE_MASK_NO_UPDATE) + { + events.Repeat(4s); + break; + } + CallConstellations(); + //me->CastSpell(me, SPELL_TRIGGER_3_ADDS, true); + events.Repeat(50s); + break; + } + case EVENT_BIG_BANG: + { + Talk(SAY_ALGALON_BIG_BANG); + Talk(EMOTE_ALGALON_BIG_BANG); + + EntryCheckPredicate pred(NPC_LIVING_CONSTELLATION); + summons.DoAction(ACTION_BIG_BANG, pred); + + me->CastSpell((Unit*)nullptr, SPELL_BIG_BANG, false); + events.Repeat(90s + 500ms); + break; + } + case EVENT_ASCEND_TO_THE_HEAVENS: + Talk(SAY_ALGALON_ASCEND); + me->CastSpell((Unit*)nullptr, SPELL_ASCEND_TO_THE_HEAVENS, false); + events.ScheduleEvent(EVENT_EVADE, 2500ms); + break; + case EVENT_EVADE: + events.Reset(); + ScriptedAI::EnterEvadeMode(); + return; + case EVENT_OUTRO_START: + if (m_pInstance) + { + m_pInstance->SetData(BOSS_ALGALON, DONE); + m_pInstance->SetData(DATA_ALGALON_DEFEATED, 1); + } + break; + case EVENT_OUTRO_1: + me->RemoveAllAuras(); + me->SetUnitFlag(UNIT_FLAG_RENAME); + break; + case EVENT_OUTRO_2: + { + Player* lootRecipent = me->GetLootRecipient(); + _EnterEvadeMode(); + // LootRecipent is cleared in _EnterEvadeMode, restore it + me->SetLootRecipient(lootRecipent); + me->GetMotionMaster()->MovePoint(POINT_ALGALON_OUTRO, AlgalonOutroPos); + break; + } + case EVENT_OUTRO_3: + me->CastSpell((Unit*)nullptr, SPELL_KILL_CREDIT); + // Summon Chest + if (GameObject* go = me->SummonGameObject(RAID_MODE(GO_ALGALON_CHEST, GO_ALGALON_CHEST_HERO), 1632.1f, -306.561f, 417.321f, 4.69494f, 0, 0, 0, 1, 0)) + { + go->ReplaceAllGameObjectFlags((GameObjectFlags)0); + go->SetLootRecipient(me); + } + break; + case EVENT_OUTRO_4: + me->CastSpell((Unit*)nullptr, SPELL_SUPERMASSIVE_FAIL); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + break; + case EVENT_OUTRO_5: + if (Creature* brann = me->SummonCreature(NPC_BRANN_BRONZBEARD_ALG, BrannOutroPos[0], TEMPSUMMON_TIMED_DESPAWN, 131500)) + brann->AI()->DoAction(ACTION_OUTRO); + break; + case EVENT_OUTRO_6: + Talk(SAY_ALGALON_OUTRO_1); + me->SetStandState(UNIT_STAND_STATE_KNEEL); + break; + case EVENT_OUTRO_7: + Talk(SAY_ALGALON_OUTRO_2); + break; + case EVENT_OUTRO_8: + Talk(SAY_ALGALON_OUTRO_3); + break; + case EVENT_OUTRO_9: + Talk(SAY_ALGALON_OUTRO_4); + break; + case EVENT_OUTRO_10: + Talk(SAY_ALGALON_OUTRO_5); + break; + case EVENT_OUTRO_11: + me->SetStandState(UNIT_STAND_STATE_STAND); + me->CastSpell(me, SPELL_TELEPORT, false); + me->DespawnOrUnsummon(3s); + break; + case EVENT_DESPAWN_ALGALON_1: + Talk(SAY_ALGALON_DESPAWN_1); + break; + case EVENT_DESPAWN_ALGALON_2: + Talk(SAY_ALGALON_DESPAWN_2); + break; + case EVENT_DESPAWN_ALGALON_3: + Talk(SAY_ALGALON_DESPAWN_3); + break; + case EVENT_DESPAWN_ALGALON_4: + me->CastSpell((Unit*)nullptr, SPELL_ASCEND_TO_THE_HEAVENS, false); + break; + case EVENT_DESPAWN_ALGALON_5: + me->SetStandState(UNIT_STAND_STATE_STAND); + me->CastSpell(me, SPELL_TELEPORT, false); + me->DespawnOrUnsummon(3s); + break; + case EVENT_CHECK_HERALD_ITEMS: + if (!DoCheckHeraldOfTheTitans()) + events.Repeat(5s); + break; + } + + DoMeleeAttackIfReady(); } }; -class npc_algalon_worm_hole : public CreatureScript +struct npc_brann_bronzebeard_algalon : public CreatureAI { -public: - npc_algalon_worm_hole() : CreatureScript("npc_algalon_worm_hole") { } - - struct npc_algalon_worm_holeAI : public NullCreatureAI + npc_brann_bronzebeard_algalon(Creature* creature) : CreatureAI(creature) { - npc_algalon_worm_holeAI(Creature* creature) : NullCreatureAI(creature) + } + + EventMap events; + uint32 _currentPoint; + + void DoAction(int32 action) override + { + switch (action) { - creature->CastSpell(creature, SPELL_WORM_HOLE_TRIGGER, true); - creature->CastSpell(creature, SPELL_SUMMON_VOID_ZONE_VISUAL, true); + case ACTION_START_INTRO: + me->SetWalk(false); + _currentPoint = 0; + events.Reset(); + events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 1ms); + break; + case ACTION_FINISH_INTRO: + Talk(SAY_BRANN_ALGALON_INTRO_2); + events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 1ms); + break; + case ACTION_OUTRO: + me->GetMotionMaster()->MovePoint(POINT_BRANN_OUTRO, BrannOutroPos[1]); + events.ScheduleEvent(EVENT_BRANN_OUTRO_1, 87s + 500ms); + events.ScheduleEvent(EVENT_BRANN_OUTRO_2, 116s + 500ms); + break; + } + } + + void MovementInform(uint32 movementType, uint32 pointId) override + { + if (movementType != POINT_MOTION_TYPE) + return; + + Milliseconds delay = 1ms; + _currentPoint = pointId + 1; + switch (pointId) + { + case 2: + delay = 8s; + me->SetWalk(true); + break; + case 6: + me->SetFacingTo(4.6156f); + me->SetWalk(false); + Talk(SAY_BRANN_ALGALON_INTRO_1); + events.ScheduleEvent(EVENT_SUMMON_ALGALON, 7500ms); + return; + case 10: + me->DespawnOrUnsummon(1ms); + return; + case POINT_BRANN_OUTRO: + case POINT_BRANN_OUTRO_END: + return; } - uint32 _summonTimer; + events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, delay); + } - void Reset() override + void UpdateAI(uint32 diff) override + { + UpdateVictim(); + events.Update(diff); + + switch (events.ExecuteEvent()) { - _summonTimer = urand(22000, 24000); + case EVENT_BRANN_MOVE_INTRO: + if (_currentPoint < MAX_BRANN_WAYPOINTS_INTRO) + me->GetMotionMaster()->MovePoint(_currentPoint, BrannIntroWaypoint[_currentPoint]); + break; + case EVENT_SUMMON_ALGALON: + if (me->GetInstanceScript() && !me->GetInstanceScript()->GetCreature(BOSS_ALGALON)) + if (Creature* algalon = me->GetMap()->SummonCreature(NPC_ALGALON, AlgalonSummonPos)) + algalon->AI()->DoAction(ACTION_START_INTRO); + break; + case EVENT_BRANN_OUTRO_1: + Talk(SAY_BRANN_ALGALON_OUTRO); + break; + case EVENT_BRANN_OUTRO_2: + me->GetMotionMaster()->MovePoint(POINT_BRANN_OUTRO_END, BrannOutroPos[2]); + break; } + } +}; - void JustSummoned(Creature* summon) override +struct npc_collapsing_star : public NullCreatureAI +{ + npc_collapsing_star(Creature* creature) : NullCreatureAI(creature) + { + creature->GetMotionMaster()->MoveRandom(25.0f); + creature->CastSpell(creature, SPELL_COLLAPSE, true); + } + + void JustSummoned(Creature* summon) override + { + if (TempSummon* summ = me->ToTempSummon()) + if (Creature* algalon = ObjectAccessor::GetCreature(*me, summ->GetSummonerGUID())) + algalon->AI()->JustSummoned(summon); + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (damage >= me->GetHealth()) { - if (TempSummon* summ = me->ToTempSummon()) - { - if (Creature* algalon = ObjectAccessor::GetCreature(*me, summ->GetSummonerGUID())) + me->CastSpell(me, SPELL_BLACK_HOLE_SPAWN_VISUAL, true); + me->CastSpell(me, SPELL_SUMMON_BLACK_HOLE, true); + } + } +}; + +struct npc_living_constellation : public ScriptedAI +{ + npc_living_constellation(Creature* creature) : ScriptedAI(creature) + { + me->SetReactState(REACT_PASSIVE); + } + + EventMap events; + bool _isActive; + + void Reset() override + { + events.Reset(); + events.ScheduleEvent(EVENT_ARCANE_BARRAGE, 2500ms); + _isActive = false; + } + + uint32 GetData(uint32 /*param*/) const override + { + return _isActive; + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_ACTIVATE_STAR: + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetImmuneToAll(false); + _isActive = true; + + if (Player* target = SelectTargetFromPlayerList(250.0f)) { - algalon->AI()->JustSummoned(summon); + AttackStart(target); + me->AddThreat(target, 100.0f); } - } + me->SetInCombatWithZone(); + break; + case ACTION_BIG_BANG: + events.SetPhase(PHASE_BIG_BANG); + events.DelayEvents(9500ms); + events.ScheduleEvent(EVENT_RESUME_UPDATING, 9500ms); + break; } + } - void UpdateAI(uint32 diff) override - { - _summonTimer += diff; - if (_summonTimer >= 30000) - { - me->CastSpell((Unit*)nullptr, SPELL_SUMMON_UNLEASHED_DARK_MATTER, true); - _summonTimer = 0; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override + void SpellHit(Unit* caster, SpellInfo const* spell) override { - return GetUlduarAI(creature); + if (spell->Id != SPELL_CONSTELLATION_PHASE_EFFECT || !caster->IsCreature()) + return; + + if (InstanceScript* instance = me->GetInstanceScript()) + instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_ID_SUPERMASSIVE_START); + + caster->CastSpell((Unit*)nullptr, SPELL_BLACK_HOLE_CREDIT, TRIGGERED_FULL_MASK); + caster->ToCreature()->DespawnOrUnsummon(1ms); + me->DespawnOrUnsummon(1ms); + if (Creature* voidZone = caster->FindNearestCreature(NPC_ALGALON_VOID_ZONE_VISUAL_STALKER, 10.0f)) + voidZone->DespawnOrUnsummon(1ms); + } + + void UpdateAI(uint32 diff) override + { + if (!(events.GetPhaseMask() & PHASE_MASK_NO_UPDATE) && !UpdateVictim()) + return; + + events.Update(diff); + switch (events.ExecuteEvent()) + { + case EVENT_ARCANE_BARRAGE: + me->CastCustomSpell(SPELL_ARCANE_BARRAGE, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, true); + events.Repeat(2500ms); + break; + case EVENT_RESUME_UPDATING: + events.SetPhase(0); + break; + } + } +}; + +struct npc_algalon_worm_hole : public NullCreatureAI +{ + npc_algalon_worm_hole(Creature* creature) : NullCreatureAI(creature) + { + creature->CastSpell(creature, SPELL_WORM_HOLE_TRIGGER, true); + creature->CastSpell(creature, SPELL_SUMMON_VOID_ZONE_VISUAL, true); + } + + uint32 _summonTimer; + + void Reset() override + { + _summonTimer = urand(22000, 24000); + } + + void JustSummoned(Creature* summon) override + { + if (TempSummon* summ = me->ToTempSummon()) + { + if (Creature* algalon = ObjectAccessor::GetCreature(*me, summ->GetSummonerGUID())) + { + algalon->AI()->JustSummoned(summon); + } + } + } + + void UpdateAI(uint32 diff) override + { + _summonTimer += diff; + if (_summonTimer >= 30000) + { + me->CastSpell((Unit*)nullptr, SPELL_SUMMON_UNLEASHED_DARK_MATTER, true); + _summonTimer = 0; + } } }; @@ -1153,10 +1098,10 @@ public: if (InstanceScript* instance = me->GetInstanceScript()) { instance->SetData(DATA_ALGALON_SUMMON_STATE, 1); - if (GameObject* sigil = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(GO_DOODAD_UL_SIGILDOOR_01))) + if (GameObject* sigil = instance->GetGameObject(DATA_SIGILDOOR_01)) sigil->SetGoState(GO_STATE_ACTIVE); - if (GameObject* sigil = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(GO_DOODAD_UL_SIGILDOOR_02))) + if (GameObject* sigil = instance->GetGameObject(DATA_SIGILDOOR_02)) sigil->SetGoState(GO_STATE_ACTIVE); if (Map* map = player->GetMap()) @@ -1394,11 +1339,11 @@ public: void AddSC_boss_algalon_the_observer() { // NPCs - new boss_algalon_the_observer(); - new npc_brann_bronzebeard_algalon(); - new npc_collapsing_star(); - new npc_living_constellation(); - new npc_algalon_worm_hole(); + RegisterUlduarCreatureAI(boss_algalon_the_observer); + RegisterUlduarCreatureAI(npc_brann_bronzebeard_algalon); + RegisterUlduarCreatureAI(npc_collapsing_star); + RegisterUlduarCreatureAI(npc_living_constellation); + RegisterUlduarCreatureAI(npc_algalon_worm_hole); // GOs new go_celestial_planetarium_access(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp index 8e423166a..fe3493e67 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp @@ -128,11 +128,7 @@ bool IsEncounterComplete(InstanceScript* pInstance, Creature* me) for (uint8 i = 0; i < 3; ++i) { - ObjectGuid guid = pInstance->GetGuidData(DATA_STEELBREAKER + i); - if (!guid) - return false; - - if (Creature* boss = (ObjectAccessor::GetCreature(*me, guid))) + if (Creature* boss = pInstance->GetCreature(DATA_STEELBREAKER + i)) { if (boss->IsAlive()) return false; @@ -151,201 +147,186 @@ void RespawnAssemblyOfIron(InstanceScript* pInstance, Creature* me) for (uint8 i = 0; i < 3; ++i) { - ObjectGuid guid = pInstance->GetGuidData(DATA_STEELBREAKER + i); - if (!guid) - return; - - if (Creature* boss = (ObjectAccessor::GetCreature((*me), guid))) + if (Creature* boss = pInstance->GetCreature(DATA_STEELBREAKER + i)) if (!boss->IsAlive()) boss->Respawn(); } return; } -void RestoreAssemblyHealth(ObjectGuid guid1, ObjectGuid guid2, Creature* me) +void RestoreAssemblyHealth(uint32 dataId1, uint32 dataId2, InstanceScript* pInstance) { - if (Creature* cr = ObjectAccessor::GetCreature(*me, guid1)) + if (Creature* cr = pInstance->GetCreature(dataId1)) if (cr->IsAlive()) cr->SetHealth(cr->GetMaxHealth()); - if (Creature* cr2 = ObjectAccessor::GetCreature(*me, guid2)) + if (Creature* cr2 = pInstance->GetCreature(dataId2)) if (cr2->IsAlive()) cr2->SetHealth(cr2->GetMaxHealth()); } -class boss_steelbreaker : public CreatureScript +struct boss_steelbreaker : public ScriptedAI { -public: - boss_steelbreaker() : CreatureScript("boss_steelbreaker") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_steelbreaker(Creature* c) : ScriptedAI(c) { - return GetUlduarAI(pCreature); + pInstance = c->GetInstanceScript(); } - struct boss_steelbreakerAI : public ScriptedAI + EventMap events; + InstanceScript* pInstance; + uint8 _phase; + + void Reset() override { - boss_steelbreakerAI(Creature* c) : ScriptedAI(c) + me->SetLootMode(0); + RespawnAssemblyOfIron(pInstance, me); + + _phase = 0; + events.Reset(); + if (pInstance) + pInstance->SetBossState(BOSS_ASSEMBLY, NOT_STARTED); + } + + void JustReachedHome() override + { + me->setActive(false); + me->RemoveAllAuras(); + } + + void JustEngagedWith(Unit* who) override + { + if (pInstance) + pInstance->SetBossState(BOSS_ASSEMBLY, IN_PROGRESS); + + me->setActive(true); + me->SetInCombatWithZone(); + me->CastSpell(me, SPELL_HIGH_VOLTAGE, true); + events.ScheduleEvent(EVENT_ENRAGE, 15min); + UpdatePhase(); + + if (!pInstance) + return; + + if (Creature* boss = pInstance->GetCreature(DATA_STEELBREAKER + urand(0, 2))) { - pInstance = c->GetInstanceScript(); + switch (boss->GetEntry()) + { + case NPC_STEELBREAKER: + boss->AI()->Talk(SAY_STEELBREAKER_AGGRO); + break; + case NPC_MOLGEIM: + boss->AI()->Talk(SAY_MOLGEIM_AGGRO); + break; + case NPC_BRUNDIR: + boss->AI()->Talk(SAY_BRUNDIR_AGGRO); + break; + } } - EventMap events; - InstanceScript* pInstance; - uint8 _phase; + for (uint8 i = 0; i < 3; ++i) + if (Creature* boss = pInstance->GetCreature(DATA_STEELBREAKER + i)) + if (!boss->IsInCombat()) + boss->AI()->AttackStart(who); + } - void Reset() override + void UpdatePhase() + { + if (_phase >= 3) + return; + + ++_phase; + + switch (_phase) { - me->SetLootMode(0); - RespawnAssemblyOfIron(pInstance, me); - - _phase = 0; - events.Reset(); - if (pInstance) - pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED); + case 1: + events.RescheduleEvent(EVENT_FUSION_PUNCH, 15s); + break; + case 2: + events.RescheduleEvent(EVENT_STATIC_DISRUPTION, 20s); + break; + case 3: + me->ResetLootMode(); + events.RescheduleEvent(EVENT_OVERWHELMING_POWER, 8s); + break; } + } - void JustReachedHome() override + void JustDied(Unit* /*Killer*/) override + { + if (!pInstance) + return; + + if (IsEncounterComplete(pInstance, me)) { - me->setActive(false); - me->RemoveAllAuras(); + pInstance->SetBossState(BOSS_ASSEMBLY, DONE); + me->CastSpell(me, 65195, true); // credit + Talk(SAY_STEELBREAKER_ENCOUNTER_DEFEATED); } - - void JustEngagedWith(Unit* who) override + else { - if (pInstance) - pInstance->SetData(TYPE_ASSEMBLY, IN_PROGRESS); + RestoreAssemblyHealth(DATA_BRUNDIR, DATA_MOLGEIM, pInstance); + me->CastSpell(me, SPELL_SUPERCHARGE, true); + Talk(SAY_STEELBREAKER_DEATH); + } + } - me->setActive(true); - me->SetInCombatWithZone(); - me->CastSpell(me, SPELL_HIGH_VOLTAGE, true); - events.ScheduleEvent(EVENT_ENRAGE, 15min); + void KilledUnit(Unit* who) override + { + if (!who->IsPlayer()) + return; + + if (_phase == 3) + me->CastSpell(me, SPELL_ELECTRICAL_CHARGE, true); + + Talk(SAY_STEELBREAKER_SLAY); + } + + void DoAction(int32 param) override + { + if (param == ACTION_ADD_CHARGE) + me->CastSpell(me, SPELL_ELECTRICAL_CHARGE, true); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_SUPERCHARGE) UpdatePhase(); + } - if (!pInstance) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + urand(0, 2)))) - { - switch (boss->GetEntry()) - { - case NPC_STEELBREAKER: - boss->AI()->Talk(SAY_STEELBREAKER_AGGRO); - break; - case NPC_MOLGEIM: - boss->AI()->Talk(SAY_MOLGEIM_AGGRO); - break; - case NPC_BRUNDIR: - boss->AI()->Talk(SAY_BRUNDIR_AGGRO); - break; - } - } + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - for (uint8 i = 0; i < 3; ++i) - if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + i))) - if (!boss->IsInCombat()) - boss->AI()->AttackStart(who); - } - - void UpdatePhase() + switch (events.ExecuteEvent()) { - if (_phase >= 3) - return; + case EVENT_FUSION_PUNCH: + me->CastSpell(me->GetVictim(), SPELL_FUSION_PUNCH, false); + events.Repeat(15s, 20s); + break; + case EVENT_STATIC_DISRUPTION: + if (Unit* pTarget = SelectTarget(SelectTargetMethod::MinDistance, 0, 0, true)) + me->CastSpell(pTarget, SPELL_STATIC_DISRUPTION, false); - ++_phase; - - switch (_phase) - { - case 1: - events.RescheduleEvent(EVENT_FUSION_PUNCH, 15s); - break; - case 2: - events.RescheduleEvent(EVENT_STATIC_DISRUPTION, 20s); - break; - case 3: - me->ResetLootMode(); - events.RescheduleEvent(EVENT_OVERWHELMING_POWER, 8s); - break; - } + events.Repeat(20s, 40s); + break; + case EVENT_OVERWHELMING_POWER: + Talk(SAY_STEELBREAKER_POWER); + me->CastSpell(me->GetVictim(), SPELL_OVERWHELMING_POWER, true); + events.Repeat(RAID_MODE(61s, 36s)); + break; + case EVENT_ENRAGE: + Talk(SAY_STEELBREAKER_BERSERK); + me->CastSpell(me, SPELL_BERSERK, true); + break; } - void JustDied(Unit* /*Killer*/) override - { - if (!pInstance) - return; - - if (IsEncounterComplete(pInstance, me)) - { - pInstance->SetData(TYPE_ASSEMBLY, DONE); - me->CastSpell(me, 65195, true); // credit - Talk(SAY_STEELBREAKER_ENCOUNTER_DEFEATED); - } - else - { - RestoreAssemblyHealth(pInstance->GetGuidData(DATA_BRUNDIR), pInstance->GetGuidData(DATA_MOLGEIM), me); - me->CastSpell(me, SPELL_SUPERCHARGE, true); - Talk(SAY_STEELBREAKER_DEATH); - } - } - - void KilledUnit(Unit* who) override - { - if (!who->IsPlayer()) - return; - - if (_phase == 3) - me->CastSpell(me, SPELL_ELECTRICAL_CHARGE, true); - - Talk(SAY_STEELBREAKER_SLAY); - } - - void DoAction(int32 param) override - { - if (param == ACTION_ADD_CHARGE) - me->CastSpell(me, SPELL_ELECTRICAL_CHARGE, true); - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_SUPERCHARGE) - UpdatePhase(); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_FUSION_PUNCH: - me->CastSpell(me->GetVictim(), SPELL_FUSION_PUNCH, false); - events.Repeat(15s, 20s); - break; - case EVENT_STATIC_DISRUPTION: - if (Unit* pTarget = SelectTarget(SelectTargetMethod::MinDistance, 0, 0, true)) - me->CastSpell(pTarget, SPELL_STATIC_DISRUPTION, false); - - events.Repeat(20s, 40s); - break; - case EVENT_OVERWHELMING_POWER: - Talk(SAY_STEELBREAKER_POWER); - me->CastSpell(me->GetVictim(), SPELL_OVERWHELMING_POWER, true); - events.Repeat(RAID_MODE(61s, 36s)); - break; - case EVENT_ENRAGE: - Talk(SAY_STEELBREAKER_BERSERK); - me->CastSpell(me, SPELL_BERSERK, true); - break; - } - - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; class CastRunesEvent : public BasicEvent @@ -364,464 +345,431 @@ private: Creature& _owner; }; -class boss_runemaster_molgeim : public CreatureScript +struct boss_runemaster_molgeim : public ScriptedAI { -public: - boss_runemaster_molgeim() : CreatureScript("boss_runemaster_molgeim") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_runemaster_molgeim(Creature* c) : ScriptedAI(c), summons(me) { - return GetUlduarAI(pCreature); + pInstance = c->GetInstanceScript(); } - struct boss_runemaster_molgeimAI : public ScriptedAI + InstanceScript* pInstance; + SummonList summons; + EventMap events; + uint8 _phase; + + void Reset() override { - boss_runemaster_molgeimAI(Creature* c) : ScriptedAI(c), summons(me) + me->SetLootMode(0); + RespawnAssemblyOfIron(pInstance, me); + + _phase = 0; + events.Reset(); + summons.DespawnAll(); + + if (pInstance) + pInstance->SetBossState(BOSS_ASSEMBLY, NOT_STARTED); + + me->m_Events.AddEventAtOffset(new CastRunesEvent(*me), 8s); + } + + void JustReachedHome() override + { + me->setActive(false); + me->RemoveAllAuras(); + } + + void JustEngagedWith(Unit* who) override + { + me->InterruptNonMeleeSpells(false); + me->setActive(true); + me->SetInCombatWithZone(); + events.ScheduleEvent(EVENT_ENRAGE, 15min); + UpdatePhase(); + + if (!pInstance) + return; + + for (uint8 i = 0; i < 3; ++i) + if (Creature* boss = pInstance->GetCreature(DATA_STEELBREAKER + i)) + if (!boss->IsInCombat()) + boss->AI()->AttackStart(who); + } + + void UpdatePhase() + { + if (_phase >= 3) + return; + + ++_phase; + + switch (_phase) { - pInstance = c->GetInstanceScript(); + case 1: + events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 20s); + events.RescheduleEvent(EVENT_RUNE_OF_POWER, 30s); + break; + case 2: + events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 35s); + break; + case 3: + me->ResetLootMode(); + events.RescheduleEvent(EVENT_RUNE_OF_SUMMONING, 20s, 30s); + break; } + } - InstanceScript* pInstance; - SummonList summons; - EventMap events; - uint8 _phase; + void JustDied(Unit* /*killer*/) override + { + if (!pInstance) + return; - void Reset() override + if (IsEncounterComplete(pInstance, me)) { - me->SetLootMode(0); - RespawnAssemblyOfIron(pInstance, me); - - _phase = 0; - events.Reset(); - summons.DespawnAll(); - - if (pInstance) - pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED); - - me->m_Events.AddEventAtOffset(new CastRunesEvent(*me), 8s); + pInstance->SetBossState(BOSS_ASSEMBLY, DONE); + me->CastSpell(me, 65195, true); // credit + Talk(SAY_MOLGEIM_ENCOUNTER_DEFEATED); } - - void JustReachedHome() override + else { - me->setActive(false); - me->RemoveAllAuras(); + RestoreAssemblyHealth(DATA_STEELBREAKER, DATA_BRUNDIR, pInstance); + me->CastSpell(me, SPELL_SUPERCHARGE, true); + Talk(SAY_MOLGEIM_DEATH); } + } - void JustEngagedWith(Unit* who) override - { - me->InterruptNonMeleeSpells(false); - me->setActive(true); - me->SetInCombatWithZone(); - events.ScheduleEvent(EVENT_ENRAGE, 15min); + void KilledUnit(Unit* who) override + { + if (!who->IsPlayer()) + return; + + Talk(SAY_MOLGEIM_SLAY); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_SUPERCHARGE) UpdatePhase(); - - if (!pInstance) - return; - - for (uint8 i = 0; i < 3; ++i) - if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + i))) - if (!boss->IsInCombat()) - boss->AI()->AttackStart(who); - } - - void UpdatePhase() - { - if (_phase >= 3) - return; - - ++_phase; - - switch (_phase) - { - case 1: - events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 20s); - events.RescheduleEvent(EVENT_RUNE_OF_POWER, 30s); - break; - case 2: - events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 35s); - break; - case 3: - me->ResetLootMode(); - events.RescheduleEvent(EVENT_RUNE_OF_SUMMONING, 20s, 30s); - break; - } - } - - void JustDied(Unit* /*killer*/) override - { - if (!pInstance) - return; - - if (IsEncounterComplete(pInstance, me)) - { - pInstance->SetData(TYPE_ASSEMBLY, DONE); - me->CastSpell(me, 65195, true); // credit - Talk(SAY_MOLGEIM_ENCOUNTER_DEFEATED); - } - else - { - RestoreAssemblyHealth(pInstance->GetGuidData(DATA_STEELBREAKER), pInstance->GetGuidData(DATA_BRUNDIR), me); - me->CastSpell(me, SPELL_SUPERCHARGE, true); - Talk(SAY_MOLGEIM_DEATH); - } - } - - void KilledUnit(Unit* who) override - { - if (!who->IsPlayer()) - return; - - Talk(SAY_MOLGEIM_SLAY); - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_SUPERCHARGE) - UpdatePhase(); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_RUNE_OF_POWER: - { - Unit* target = DoSelectLowestHpFriendly(60); - if (!target || !target->IsAlive()) - target = me; - - me->CastSpell(target, SPELL_RUNE_OF_POWER, true); - events.Repeat(1min); - break; - } - case EVENT_SHIELD_OF_RUNES: - me->CastSpell(me, SPELL_SHIELD_OF_RUNES, false); - events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27s, 34s); - break; - case EVENT_RUNE_OF_DEATH: - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - me->CastSpell(target, SPELL_RUNE_OF_DEATH, true); - - Talk(SAY_MOLGEIM_RUNE_DEATH); - events.Repeat(30s, 40s); - break; - case EVENT_RUNE_OF_SUMMONING: - Talk(SAY_MOLGEIM_SUMMON); - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - me->CastSpell(target, SPELL_RUNE_OF_SUMMONING); - events.Repeat(30s, 45s); - break; - case EVENT_ENRAGE: - me->CastSpell(me, SPELL_BERSERK, true); - Talk(SAY_MOLGEIM_BERSERK); - break; - } - - DoMeleeAttackIfReady(); - } - }; -}; - -class npc_assembly_lightning : public CreatureScript -{ -public: - npc_assembly_lightning() : CreatureScript("npc_assembly_lightning") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct npc_assembly_lightningAI : public ScriptedAI + void UpdateAI(uint32 diff) override { - npc_assembly_lightningAI(Creature* c) : ScriptedAI(c) + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - _boomed = false; - } - - void MoveInLineOfSight(Unit*) override {} - void AttackStart(Unit*) override {} - void UpdateAI(uint32) override {} - void EnterEvadeMode(EvadeReason /* why */) override {} - void OnCharmed(bool /*apply*/) override {} - - bool _boomed; - - void Reset() override - { - if (Player* target = SelectTargetFromPlayerList(150)) - me->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f); - else - me->DespawnOrUnsummon(1ms); - } - - void MovementInform(uint32 type, uint32 /*id*/) override - { - if (type == FOLLOW_MOTION_TYPE && !_boomed) - { - _boomed = true; - me->CastSpell(me, SPELL_LIGHTNING_BLAST, true); - me->DespawnOrUnsummon(1s); - } - } - }; -}; - -class boss_stormcaller_brundir : public CreatureScript -{ -public: - boss_stormcaller_brundir() : CreatureScript("boss_stormcaller_brundir") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_stormcaller_brundirAI : public ScriptedAI - { - boss_stormcaller_brundirAI(Creature* c) : ScriptedAI(c) - { - pInstance = c->GetInstanceScript(); - } - - EventMap events; - InstanceScript* pInstance; - uint32 _phase; - ObjectGuid _flyTargetGUID; - uint32 _channelTimer; - - bool _stunnedAchievement; - - void Reset() override - { - me->SetLootMode(0); - RespawnAssemblyOfIron(pInstance, me); - - _channelTimer = 0; - _phase = 0; - _flyTargetGUID.Clear(); - _stunnedAchievement = true; - - events.Reset(); - - me->SetDisableGravity(false); - me->SetRegeneratingHealth(true); - me->SetReactState(REACT_AGGRESSIVE); - if (pInstance) - pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED); - } - - void JustReachedHome() override - { - me->setActive(false); - me->RemoveAllAuras(); - } - - void JustEngagedWith(Unit* who) override - { - me->InterruptNonMeleeSpells(false); - me->setActive(true); - me->SetInCombatWithZone(); - events.ScheduleEvent(EVENT_ENRAGE, 15min); - UpdatePhase(); - - if (!pInstance) - return; - - for (uint8 i = 0; i < 3; ++i) - if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + i))) - if (!boss->IsInCombat()) - boss->AI()->AttackStart(who); - } - - void UpdatePhase() - { - if (_phase >= 3) - return; - - ++_phase; - - switch (_phase) - { - case 1: - events.RescheduleEvent(EVENT_CHAIN_LIGHTNING, 9s, 17s); - events.RescheduleEvent(EVENT_OVERLOAD, 25s, 40s); - break; - case 2: - events.RescheduleEvent(EVENT_LIGHTNING_WHIRL, 20s, 40s); - break; - case 3: - me->ResetLootMode(); - me->CastSpell(me, SPELL_STORMSHIELD, true); - events.RescheduleEvent(EVENT_LIGHTNING_TENDRILS, 15s, 16s); - break; - } - } - - void JustDied(Unit* /*Killer*/) override - { - if (!pInstance) - return; - me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), 427.5, me->GetOrientation()); - if (IsEncounterComplete(pInstance, me)) - { - pInstance->SetData(TYPE_ASSEMBLY, DONE); - me->CastSpell(me, 65195, true); // credit - Talk(SAY_BRUNDIR_ENCOUNTER_DEFEATED); - } - else - { - RestoreAssemblyHealth(pInstance->GetGuidData(DATA_STEELBREAKER), pInstance->GetGuidData(DATA_MOLGEIM), me); - me->CastSpell(me, SPELL_SUPERCHARGE, true); - Talk(SAY_BRUNDIR_DEATH); - } - } - - void KilledUnit(Unit* who) override - { - if (!who->IsPlayer() || urand(0, 2)) - return; - - Talk(SAY_BRUNDIR_SLAY); - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_SUPERCHARGE) - UpdatePhase(); - } - - void SpellHitTarget(Unit* /*target*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == sSpellMgr->GetSpellIdForDifficulty(SPELL_CHAIN_LIGHTNING, me) || spellInfo->Id == sSpellMgr->GetSpellIdForDifficulty(SPELL_LIGHTNING_WHIRL_TRIGG, me)) - _stunnedAchievement = false; - } - - uint32 GetData(uint32 param) const override - { - if (param == DATA_BRUNDIR) - return _stunnedAchievement; - - return 0; - } - - void MovementInform(uint32 type, uint32 point) override - { - if (type == POINT_MOTION_TYPE && point == POINT_CHANNEL_STEELBREAKER) - me->CastSpell(me, SPELL_LIGHTNING_CHANNEL_PRE, true); - } - - void UpdateAI(uint32 diff) override - { - if (!me->IsInCombat() && me->GetReactState() == REACT_AGGRESSIVE) - { - _channelTimer += diff; - if (_channelTimer >= 10000) + case EVENT_RUNE_OF_POWER: { - _channelTimer = 0; - float o = urand(0, 5) * M_PI / 3.0f; - me->InterruptNonMeleeSpells(false); - me->GetMotionMaster()->MovePoint(POINT_CHANNEL_STEELBREAKER, 1587.18f + 10.0f * cos(o), 121.02f + 10.0f * std::sin(o), 427.3f); + Unit* target = DoSelectLowestHpFriendly(60); + if (!target || !target->IsAlive()) + target = me; + + me->CastSpell(target, SPELL_RUNE_OF_POWER, true); + events.Repeat(1min); + break; } - } + case EVENT_SHIELD_OF_RUNES: + me->CastSpell(me, SPELL_SHIELD_OF_RUNES, false); + events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27s, 34s); + break; + case EVENT_RUNE_OF_DEATH: + if (Unit* target = SelectTarget(SelectTargetMethod::Random)) + me->CastSpell(target, SPELL_RUNE_OF_DEATH, true); - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_CHAIN_LIGHTNING: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false); - - events.Repeat(9s, 17s); - break; - case EVENT_OVERLOAD: - Talk(EMOTE_BRUNDIR_OVERLOAD); - me->CastSpell(me, SPELL_OVERLOAD, true); - events.RescheduleEvent(EVENT_OVERLOAD, 25s, 40s); - break; - case EVENT_LIGHTNING_WHIRL: - Talk(SAY_BRUNDIR_SPECIAL); - me->CastSpell(me, SPELL_LIGHTNING_WHIRL, true); - events.Repeat(10s, 25s); - break; - case EVENT_LIGHTNING_TENDRILS: - { - // Reschedule old - events.Repeat(35s); - events.DelayEvents(18s); - Talk(SAY_BRUNDIR_FLIGHT); - - Unit* oldVictim = me->GetVictim(); - _flyTargetGUID = oldVictim->GetGUID(); - me->SetRegeneratingHealth(false); - me->SetDisableGravity(true); - me->SetHover(true); - - me->CombatStop(); - me->StopMoving(); - me->SetReactState(REACT_PASSIVE); - me->SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty); - me->SetUnitFlag(UNIT_FLAG_STUNNED); - - me->CastSpell(me, SPELL_LIGHTNING_TENDRILS, true); - me->CastSpell(me, SPELL_LIGHTNING_TENDRILS_2, true); - events.ScheduleEvent(EVENT_LIGHTNING_LAND, 16s); - events.ScheduleEvent(EVENT_LIGHTNING_FLIGHT, 1s); - break; - } - case EVENT_LIGHTNING_LAND: - { - float speed = me->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()) / (1000.0f * 0.001f); - me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), FORCED_MOVEMENT_NONE, speed); - events.ScheduleEvent(EVENT_LAND_LAND, 1s); - break; - } - case EVENT_LAND_LAND: - me->SetCanFly(false); - me->SetHover(false); - me->SetReactState(REACT_AGGRESSIVE); - me->SetDisableGravity(false); - if (Unit* flyTarget = ObjectAccessor::GetUnit(*me, _flyTargetGUID)) - { - me->Attack(flyTarget, false); - } - - me->SetRegeneratingHealth(true); - _flyTargetGUID.Clear(); - me->RemoveAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_LIGHTNING_TENDRILS, me)); - me->RemoveAura(SPELL_LIGHTNING_TENDRILS_2); - DoResetThreatList(); - events.CancelEvent(EVENT_LIGHTNING_FLIGHT); - break; - case EVENT_ENRAGE: - Talk(SAY_BRUNDIR_BERSERK); - me->CastSpell(me, SPELL_BERSERK, true); - break; - case EVENT_LIGHTNING_FLIGHT: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true)) - { - me->GetMotionMaster()->MovePoint(0, *target); - } - events.ScheduleEvent(EVENT_LIGHTNING_FLIGHT, 6s); - break; - } - - DoMeleeAttackIfReady(); + Talk(SAY_MOLGEIM_RUNE_DEATH); + events.Repeat(30s, 40s); + break; + case EVENT_RUNE_OF_SUMMONING: + Talk(SAY_MOLGEIM_SUMMON); + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + me->CastSpell(target, SPELL_RUNE_OF_SUMMONING); + events.Repeat(30s, 45s); + break; + case EVENT_ENRAGE: + me->CastSpell(me, SPELL_BERSERK, true); + Talk(SAY_MOLGEIM_BERSERK); + break; } - }; + + DoMeleeAttackIfReady(); + } +}; + +struct npc_assembly_lightning : public ScriptedAI +{ + npc_assembly_lightning(Creature* c) : ScriptedAI(c) + { + _boomed = false; + } + + void MoveInLineOfSight(Unit*) override {} + void AttackStart(Unit*) override {} + void UpdateAI(uint32) override {} + void EnterEvadeMode(EvadeReason /* why */) override {} + void OnCharmed(bool /*apply*/) override {} + + bool _boomed; + + void Reset() override + { + if (Player* target = SelectTargetFromPlayerList(150)) + me->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f); + else + me->DespawnOrUnsummon(1ms); + } + + void MovementInform(uint32 type, uint32 /*id*/) override + { + if (type == FOLLOW_MOTION_TYPE && !_boomed) + { + _boomed = true; + me->CastSpell(me, SPELL_LIGHTNING_BLAST, true); + me->DespawnOrUnsummon(1s); + } + } +}; + +struct boss_stormcaller_brundir : public ScriptedAI +{ + boss_stormcaller_brundir(Creature* c) : ScriptedAI(c) + { + pInstance = c->GetInstanceScript(); + } + + EventMap events; + InstanceScript* pInstance; + uint32 _phase; + ObjectGuid _flyTargetGUID; + uint32 _channelTimer; + + bool _stunnedAchievement; + + void Reset() override + { + me->SetLootMode(0); + RespawnAssemblyOfIron(pInstance, me); + + _channelTimer = 0; + _phase = 0; + _flyTargetGUID.Clear(); + _stunnedAchievement = true; + + events.Reset(); + + me->SetDisableGravity(false); + me->SetRegeneratingHealth(true); + me->SetReactState(REACT_AGGRESSIVE); + if (pInstance) + pInstance->SetBossState(BOSS_ASSEMBLY, NOT_STARTED); + } + + void JustReachedHome() override + { + me->setActive(false); + me->RemoveAllAuras(); + } + + void JustEngagedWith(Unit* who) override + { + me->InterruptNonMeleeSpells(false); + me->setActive(true); + me->SetInCombatWithZone(); + events.ScheduleEvent(EVENT_ENRAGE, 15min); + UpdatePhase(); + + if (!pInstance) + return; + + for (uint8 i = 0; i < 3; ++i) + if (Creature* boss = pInstance->GetCreature(DATA_STEELBREAKER + i)) + if (!boss->IsInCombat()) + boss->AI()->AttackStart(who); + } + + void UpdatePhase() + { + if (_phase >= 3) + return; + + ++_phase; + + switch (_phase) + { + case 1: + events.RescheduleEvent(EVENT_CHAIN_LIGHTNING, 9s, 17s); + events.RescheduleEvent(EVENT_OVERLOAD, 25s, 40s); + break; + case 2: + events.RescheduleEvent(EVENT_LIGHTNING_WHIRL, 20s, 40s); + break; + case 3: + me->ResetLootMode(); + me->CastSpell(me, SPELL_STORMSHIELD, true); + events.RescheduleEvent(EVENT_LIGHTNING_TENDRILS, 15s, 16s); + break; + } + } + + void JustDied(Unit* /*Killer*/) override + { + if (!pInstance) + return; + me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), 427.5, me->GetOrientation()); + if (IsEncounterComplete(pInstance, me)) + { + pInstance->SetBossState(BOSS_ASSEMBLY, DONE); + me->CastSpell(me, 65195, true); // credit + Talk(SAY_BRUNDIR_ENCOUNTER_DEFEATED); + } + else + { + RestoreAssemblyHealth(DATA_STEELBREAKER, DATA_MOLGEIM, pInstance); + me->CastSpell(me, SPELL_SUPERCHARGE, true); + Talk(SAY_BRUNDIR_DEATH); + } + } + + void KilledUnit(Unit* who) override + { + if (!who->IsPlayer() || urand(0, 2)) + return; + + Talk(SAY_BRUNDIR_SLAY); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_SUPERCHARGE) + UpdatePhase(); + } + + void SpellHitTarget(Unit* /*target*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == sSpellMgr->GetSpellIdForDifficulty(SPELL_CHAIN_LIGHTNING, me) || spellInfo->Id == sSpellMgr->GetSpellIdForDifficulty(SPELL_LIGHTNING_WHIRL_TRIGG, me)) + _stunnedAchievement = false; + } + + uint32 GetData(uint32 param) const override + { + if (param == DATA_BRUNDIR) + return _stunnedAchievement; + + return 0; + } + + void MovementInform(uint32 type, uint32 point) override + { + if (type == POINT_MOTION_TYPE && point == POINT_CHANNEL_STEELBREAKER) + me->CastSpell(me, SPELL_LIGHTNING_CHANNEL_PRE, true); + } + + void UpdateAI(uint32 diff) override + { + if (!me->IsInCombat() && me->GetReactState() == REACT_AGGRESSIVE) + { + _channelTimer += diff; + if (_channelTimer >= 10000) + { + _channelTimer = 0; + float o = urand(0, 5) * M_PI / 3.0f; + me->InterruptNonMeleeSpells(false); + me->GetMotionMaster()->MovePoint(POINT_CHANNEL_STEELBREAKER, 1587.18f + 10.0f * cos(o), 121.02f + 10.0f * std::sin(o), 427.3f); + } + } + + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_CHAIN_LIGHTNING: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false); + + events.Repeat(9s, 17s); + break; + case EVENT_OVERLOAD: + Talk(EMOTE_BRUNDIR_OVERLOAD); + me->CastSpell(me, SPELL_OVERLOAD, true); + events.RescheduleEvent(EVENT_OVERLOAD, 25s, 40s); + break; + case EVENT_LIGHTNING_WHIRL: + Talk(SAY_BRUNDIR_SPECIAL); + me->CastSpell(me, SPELL_LIGHTNING_WHIRL, true); + events.Repeat(10s, 25s); + break; + case EVENT_LIGHTNING_TENDRILS: + { + // Reschedule old + events.Repeat(35s); + events.DelayEvents(18s); + Talk(SAY_BRUNDIR_FLIGHT); + + Unit* oldVictim = me->GetVictim(); + _flyTargetGUID = oldVictim->GetGUID(); + me->SetRegeneratingHealth(false); + me->SetDisableGravity(true); + me->SetHover(true); + + me->CombatStop(); + me->StopMoving(); + me->SetReactState(REACT_PASSIVE); + me->SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty); + me->SetUnitFlag(UNIT_FLAG_STUNNED); + + me->CastSpell(me, SPELL_LIGHTNING_TENDRILS, true); + me->CastSpell(me, SPELL_LIGHTNING_TENDRILS_2, true); + events.ScheduleEvent(EVENT_LIGHTNING_LAND, 16s); + events.ScheduleEvent(EVENT_LIGHTNING_FLIGHT, 1s); + break; + } + case EVENT_LIGHTNING_LAND: + { + float speed = me->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()) / (1000.0f * 0.001f); + me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), FORCED_MOVEMENT_NONE, speed); + events.ScheduleEvent(EVENT_LAND_LAND, 1s); + break; + } + case EVENT_LAND_LAND: + me->SetCanFly(false); + me->SetHover(false); + me->SetReactState(REACT_AGGRESSIVE); + me->SetDisableGravity(false); + if (Unit* flyTarget = ObjectAccessor::GetUnit(*me, _flyTargetGUID)) + { + me->Attack(flyTarget, false); + } + + me->SetRegeneratingHealth(true); + _flyTargetGUID.Clear(); + me->RemoveAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_LIGHTNING_TENDRILS, me)); + me->RemoveAura(SPELL_LIGHTNING_TENDRILS_2); + DoResetThreatList(); + events.CancelEvent(EVENT_LIGHTNING_FLIGHT); + break; + case EVENT_ENRAGE: + Talk(SAY_BRUNDIR_BERSERK); + me->CastSpell(me, SPELL_BERSERK, true); + break; + case EVENT_LIGHTNING_FLIGHT: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true)) + { + me->GetMotionMaster()->MovePoint(0, *target); + } + events.ScheduleEvent(EVENT_LIGHTNING_FLIGHT, 6s); + break; + } + + DoMeleeAttackIfReady(); + } }; class spell_shield_of_runes_aura : public AuraScript @@ -853,7 +801,7 @@ class spell_assembly_meltdown : public SpellScript void HandleInstaKill(SpellEffIndex /*effIndex*/) { if (InstanceScript* instance = GetCaster()->GetInstanceScript()) - if (Creature* Steelbreaker = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_STEELBREAKER))) + if (Creature* Steelbreaker = instance->GetCreature(DATA_STEELBREAKER)) Steelbreaker->AI()->DoAction(ACTION_ADD_CHARGE); } @@ -921,7 +869,7 @@ public: return false; if (InstanceScript* instance = target->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(DATA_BRUNDIR))) + if (Creature* cr = instance->GetCreature(DATA_BRUNDIR)) return cr->AI()->GetData(DATA_BRUNDIR); return false; @@ -930,10 +878,10 @@ public: void AddSC_boss_assembly_of_iron() { - new boss_steelbreaker(); - new boss_runemaster_molgeim(); - new boss_stormcaller_brundir(); - new npc_assembly_lightning(); + RegisterUlduarCreatureAI(boss_steelbreaker); + RegisterUlduarCreatureAI(boss_runemaster_molgeim); + RegisterUlduarCreatureAI(boss_stormcaller_brundir); + RegisterUlduarCreatureAI(npc_assembly_lightning); RegisterSpellScript(spell_shield_of_runes_aura); RegisterSpellScript(spell_assembly_meltdown); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp index b29cf2b26..015436c7a 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp @@ -97,7 +97,7 @@ enum Misc struct boss_auriaya : public BossAI { - boss_auriaya(Creature* creature) : BossAI(creature, TYPE_AURIAYA) { } + boss_auriaya(Creature* creature) : BossAI(creature, BOSS_AURIAYA) { } bool _feralDied{false}; bool _nineLives{false}; @@ -230,8 +230,8 @@ struct npc_auriaya_sanctum_sentry : public ScriptedAI void JustEngagedWith(Unit*) override { - if (me->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA))) + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* cr = instance->GetCreature(BOSS_AURIAYA)) cr->SetInCombatWithZone(); events.ScheduleEvent(EVENT_SAVAGE_POUNCE, 5s); @@ -241,7 +241,7 @@ struct npc_auriaya_sanctum_sentry : public ScriptedAI void Reset() override { events.Reset(); - me->CastSpell(me, SPELL_STRENGTH_OF_THE_PACK, true); + DoCastSelf(SPELL_STRENGTH_OF_THE_PACK, true); } void UpdateAI(uint32 diff) override @@ -303,8 +303,8 @@ struct npc_auriaya_feral_defender : public ScriptedAI void JustDied(Unit*) override { - if (me->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA))) + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* cr = instance->GetCreature(BOSS_AURIAYA)) cr->AI()->DoAction(_feralEssenceStack ? ACTION_FERAL_DEATH_WITH_STACK : ACTION_FERAL_DEATH); if (_feralEssenceStack) @@ -357,11 +357,11 @@ struct npc_auriaya_feral_defender : public ScriptedAI DoResetThreatList(); if (!UpdateVictim()) return; - me->CastSpell(me->GetVictim(), SPELL_FERAL_RUSH, true); + DoCastVictim(SPELL_FERAL_RUSH, true); events.Repeat(6s); break; case EVENT_FERAL_POUNCE: - me->CastSpell(me->GetVictim(), SPELL_FERAL_POUNCE, false); + DoCastVictim(SPELL_FERAL_POUNCE); events.Repeat(6s); break; } @@ -394,8 +394,8 @@ public: { if (target) if (InstanceScript* instance = target->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_AURIAYA))) - return cr->AI()->GetData(DATA_CRAZY_CAT); + if (Creature* auriaya = instance->GetCreature(BOSS_AURIAYA)) + return auriaya->AI()->GetData(DATA_CRAZY_CAT); return false; } @@ -410,7 +410,7 @@ public: { if (target) if (InstanceScript* instance = target->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_AURIAYA))) + if (Creature* cr = instance->GetCreature(BOSS_AURIAYA)) return cr->AI()->GetData(DATA_NINE_LIVES); return false; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index 6946daa78..61aaed9aa 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -193,319 +193,300 @@ enum Misc const Position homePos = {322.39f, -14.5f, 409.8f, 3.14f}; -class boss_flame_leviathan : public CreatureScript +struct boss_flame_leviathan : public BossAI { -public: - boss_flame_leviathan() : CreatureScript("boss_flame_leviathan") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_flame_leviathan(Creature* pCreature) : BossAI(pCreature, BOSS_LEVIATHAN), vehicle(me->GetVehicleKit()) { - return GetUlduarAI(pCreature); + assert(vehicle); } - struct boss_flame_leviathanAI : public ScriptedAI + Vehicle* vehicle; + + uint32 _startTimer; + uint32 _speakTimer; + uint8 _towersCount; + bool _shutdown; + uint32 _destroyedTurretCount; + + // Custom + void BindPlayers(); + void RadioSay(uint8 textid); + void ActivateTowers(); + void TurnGates(bool _start, bool _death); + void TurnHealStations(bool _apply); + void ScheduleEvents(); + void SummonTowerHelpers(uint8 towerId); + + // Original + void JustReachedHome() override { - boss_flame_leviathanAI(Creature* pCreature) : ScriptedAI(pCreature), vehicle(me->GetVehicleKit()), summons(me) + _JustReachedHome(); + // For achievement + instance->SetData(DATA_UNBROKEN_ACHIEVEMENT, 0); + me->setActive(false); + } + + void MoveInLineOfSight(Unit*) override {} + void JustSummoned(Creature* cr) override + { + if (cr->GetEntry() != NPC_FLAME_LEVIATHAN_TURRET && cr->GetEntry() != NPC_SEAT) + summons.Summon(cr); + } + + void SummonedCreatureDespawn(Creature* cr) override { summons.Despawn(cr); } + void SpellHit(Unit* caster, SpellInfo const* spellInfo) override; + void JustDied(Unit*) override; + void KilledUnit(Unit* who) override; + void SpellHitTarget(Unit* target, SpellInfo const* spell) override; + + void AttackStart(Unit* who) override + { + if (Unit* veh = who->GetVehicleBase()) + BossAI::AttackStart(veh); + else + BossAI::AttackStart(who); + } + + void JustEngagedWith(Unit*) override + { + ScheduleEvents(); + Talk(FLAME_LEVIATHAN_SAY_AGGRO); + + me->setActive(true); + me->SetHomePosition(homePos); + TurnHealStations(false); + ActivateTowers(); + instance->SetBossState(BOSS_LEVIATHAN, SPECIAL); + + BindPlayers(); + me->SetInCombatWithZone(); + + if (!_startTimer) { - m_pInstance = pCreature->GetInstanceScript(); - assert(vehicle); + TurnGates(true, false); } + } - InstanceScript* m_pInstance; - Vehicle* vehicle; - EventMap events; - SummonList summons; - - uint32 _startTimer; - uint32 _speakTimer; - uint8 _towersCount; - bool _shutdown; - uint32 _destroyedTurretCount; - - // Custom - void BindPlayers(); - void RadioSay(uint8 textid); - void ActivateTowers(); - void TurnGates(bool _start, bool _death); - void TurnHealStations(bool _apply); - void ScheduleEvents(); - void SummonTowerHelpers(uint8 towerId); - - // Original - void JustReachedHome() override + void InitializeAI() override + { + if (instance->GetBossState(BOSS_LEVIATHAN) == SPECIAL) { - // For achievement - if (m_pInstance) - m_pInstance->SetData(DATA_UNBROKEN_ACHIEVEMENT, 0); - me->setActive(false); - } - - void MoveInLineOfSight(Unit*) override {} - void JustSummoned(Creature* cr) override - { - if (cr->GetEntry() != NPC_FLAME_LEVIATHAN_TURRET && cr->GetEntry() != NPC_SEAT) - summons.Summon(cr); - } - - void SummonedCreatureDespawn(Creature* cr) override { summons.Despawn(cr); } - void SpellHit(Unit* caster, SpellInfo const* spellInfo) override; - void JustDied(Unit*) override; - void KilledUnit(Unit* who) override; - void SpellHitTarget(Unit* target, SpellInfo const* spell) override; - - void AttackStart(Unit* who) override - { - if (Unit* veh = who->GetVehicleBase()) - ScriptedAI::AttackStart(veh); - else - ScriptedAI::AttackStart(who); - } - - void JustEngagedWith(Unit*) override - { - ScheduleEvents(); - Talk(FLAME_LEVIATHAN_SAY_AGGRO); - - me->setActive(true); me->SetHomePosition(homePos); - TurnHealStations(false); - ActivateTowers(); - if (m_pInstance) - m_pInstance->SetData(TYPE_LEVIATHAN, SPECIAL); - - BindPlayers(); - me->SetInCombatWithZone(); - - if (!_startTimer) - { - TurnGates(true, false); - } + me->UpdatePosition(homePos); + me->StopMovingOnCurrentPos(); } - void InitializeAI() override - { - if (m_pInstance && m_pInstance->GetData(TYPE_LEVIATHAN) == SPECIAL) - { - me->SetHomePosition(homePos); - me->UpdatePosition(homePos); - me->StopMovingOnCurrentPos(); - } + BossAI::InitializeAI(); + } - ScriptedAI::InitializeAI(); + void Reset() override + { + // Special immunity case + me->CastSpell(me, SPELL_INVIS_AND_STEALTH_DETECT, true); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED, true); + + summons.DoAction(ACTION_DESPAWN_ADDS); + summons.DespawnAll(); + events.Reset(); + + _shutdown = false; + _startTimer = 1; + _speakTimer = 0; + _towersCount = 0; + _destroyedTurretCount = 0; + + if (instance->GetBossState(BOSS_LEVIATHAN) != SPECIAL) + { + instance->SetBossState(BOSS_LEVIATHAN, NOT_STARTED); + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + } + else + { + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + instance->SetData(DATA_VEHICLE_SPAWN, VEHICLE_POS_LEVIATHAN); + _startTimer = 0; } - void Reset() override + TurnGates(false, false); + TurnHealStations(true); + } + + uint32 GetData(uint32 param) const override + { + if (param == DATA_GET_TOWER_COUNT) + return _towersCount; + if (param == DATA_GET_SHUTDOWN) + return !_shutdown; + + return 0; + } + + void UpdateAI(uint32 diff) override + { + // THIS IS USED ONLY FOR FIRST ENGAGE! + if (_startTimer) { - // Special immunity case - me->CastSpell(me, SPELL_INVIS_AND_STEALTH_DETECT, true); - me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED, true); - - summons.DoAction(ACTION_DESPAWN_ADDS); - summons.DespawnAll(); - events.Reset(); - - _shutdown = false; - _startTimer = 1; - _speakTimer = 0; - _towersCount = 0; - _destroyedTurretCount = 0; - - if (m_pInstance) + _startTimer += diff; + if (_startTimer >= 4000) { - if (m_pInstance->GetData(TYPE_LEVIATHAN) != SPECIAL) - { - m_pInstance->SetData(TYPE_LEVIATHAN, NOT_STARTED); - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - } + // Colossus dead, players in range + if (me->FindNearestCreature(NPC_ULDUAR_COLOSSUS, 250.0f, true) || !SelectTargetFromPlayerList(250.0f)) + _startTimer = 1; else { - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - m_pInstance->SetData(DATA_VEHICLE_SPAWN, VEHICLE_POS_LEVIATHAN); _startTimer = 0; + _speakTimer = 1; } } - - TurnGates(false, false); - TurnHealStations(true); + return; } - uint32 GetData(uint32 param) const override + if (_speakTimer) { - if (param == DATA_GET_TOWER_COUNT) - return _towersCount; - if (param == DATA_GET_SHUTDOWN) - return !_shutdown; - - return 0; - } - - void UpdateAI(uint32 diff) override - { - // THIS IS USED ONLY FOR FIRST ENGAGE! - if (_startTimer) + _speakTimer += diff; + if (_speakTimer <= 10000) { - _startTimer += diff; - if (_startTimer >= 4000) - { - // Colossus dead, players in range - if (me->FindNearestCreature(NPC_ULDUAR_COLOSSUS, 250.0f, true) || !SelectTargetFromPlayerList(250.0f)) - _startTimer = 1; - else - { - _startTimer = 0; - _speakTimer = 1; - } - } - return; + _speakTimer = 10000; + RadioSay(BRANN_RADIO_SAY_FL_START_0); } - - if (_speakTimer) + else if (_speakTimer > 16000 && _speakTimer < 20000) { - _speakTimer += diff; - if (_speakTimer <= 10000) - { - _speakTimer = 10000; - RadioSay(BRANN_RADIO_SAY_FL_START_0); - } - else if (_speakTimer > 16000 && _speakTimer < 20000) - { - _speakTimer = 20000; - RadioSay(BRANN_RADIO_SAY_FL_START_1); - } - else if (_speakTimer > 24000 && _speakTimer < 40000) - { - _speakTimer = 40000; - RadioSay(BRANN_RADIO_SAY_FL_START_2); - } - else if (_speakTimer > 41000 && _speakTimer < 60000) - { - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - TurnGates(true, false); - me->GetMotionMaster()->MovePoint(0, homePos.GetPositionX(), homePos.GetPositionY(), homePos.GetPositionZ(), FORCED_MOVEMENT_NONE, 100.0f); - _speakTimer = 60000; - } - else if (_speakTimer > 63500) - { - me->SetInCombatWithZone(); - if (!me->GetVictim()) - { - me->CastSpell(me, SPELL_PURSUED, false); - events.RescheduleEvent(EVENT_PURSUE, 31s); - } - _speakTimer = 0; - } - return; + _speakTimer = 20000; + RadioSay(BRANN_RADIO_SAY_FL_START_1); } - - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) + else if (_speakTimer > 24000 && _speakTimer < 40000) { - case EVENT_POSITION_CHECK: - if (me->GetPositionX() > 450 || me->GetPositionX() < 120) - { - EnterEvadeMode(); - return; - } - events.Repeat(5s); - break; - case EVENT_PURSUE: - Talk(FLAME_LEVIATHAN_SAY_PURSUE); + _speakTimer = 40000; + RadioSay(BRANN_RADIO_SAY_FL_START_2); + } + else if (_speakTimer > 41000 && _speakTimer < 60000) + { + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + TurnGates(true, false); + me->GetMotionMaster()->MovePoint(0, homePos.GetPositionX(), homePos.GetPositionY(), homePos.GetPositionZ(), FORCED_MOVEMENT_NONE, 100.0f); + _speakTimer = 60000; + } + else if (_speakTimer > 63500) + { + me->SetInCombatWithZone(); + if (!me->GetVictim()) + { me->CastSpell(me, SPELL_PURSUED, false); events.RescheduleEvent(EVENT_PURSUE, 31s); - return; - case EVENT_SPEED: - me->CastSpell(me, SPELL_GATHERING_SPEED, false); - events.Repeat(15s); - return; - case EVENT_MISSILE: - me->CastSpell(me, SPELL_MISSILE_BARRAGE, true); - events.Repeat(4s); - return; - case EVENT_VENT: - me->CastSpell(me, SPELL_FLAME_VENTS, false); - events.Repeat(20s); - return; - case EVENT_SUMMON: - if (summons.size() < 20) - if (Creature* lift = DoSummonFlyer(NPC_MECHANOLIFT, me, 30.0f, 50.0f, 0)) - lift->GetMotionMaster()->MoveRandom(100); - - events.Repeat(4s); - return; - case EVENT_SOUND_BEGINNING: - if (_towersCount) - Talk(FLAME_LEVIATHAN_SAY_HARDMODE); - else - Talk(FLAME_LEVIATHAN_SAY_TOWER_NONE); - return; - case EVENT_REINSTALL: - for (uint8 i = RAID_MODE(0, 2); i < 4; ++i) - if (Unit* seat = vehicle->GetPassenger(i)) - if (seat->IsCreature()) - seat->ToCreature()->AI()->EnterEvadeMode(); - Talk(FLAME_LEVIATHAN_EMOTE_REACTIVATE); - return; - case EVENT_THORIMS_HAMMER: - SummonTowerHelpers(TOWER_OF_STORMS); - events.Repeat(1min, 2min); - Talk(FLAME_LEVIATHAN_EMOTE_STORM); - Talk(FLAME_LEVIATHAN_SAY_TOWER_STORM); - return; - case EVENT_FREYA: - SummonTowerHelpers(TOWER_OF_LIFE); - Talk(FLAME_LEVIATHAN_EMOTE_NATURE); - Talk(FLAME_LEVIATHAN_SAY_TOWER_NATURE); - return; - case EVENT_MIMIRONS_INFERNO: - SummonTowerHelpers(TOWER_OF_FLAMES); - Talk(FLAME_LEVIATHAN_EMOTE_FLAME); - Talk(FLAME_LEVIATHAN_SAY_TOWER_FLAME); - return; - case EVENT_HODIRS_FURY: - SummonTowerHelpers(TOWER_OF_FROST); - Talk(FLAME_LEVIATHAN_EMOTE_FROST); - Talk(FLAME_LEVIATHAN_SAY_TOWER_FROST); - return; - } - - if (me->isAttackReady() && !me->HasUnitState(UNIT_STATE_STUNNED)) - { - if (me->IsWithinCombatRange(me->GetVictim(), 15.0f)) - { - me->CastSpell(me->GetVictim(), SPELL_BATTERING_RAM, false); - me->resetAttackTimer(); } + _speakTimer = 0; } + return; } - void DoAction(int32 action) override + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - if (action == ACTION_DESTROYED_TURRET) - { - ++_destroyedTurretCount; - - if (_destroyedTurretCount == RAID_MODE(2, 4)) + case EVENT_POSITION_CHECK: + if (me->GetPositionX() > 450 || me->GetPositionX() < 120) { - _destroyedTurretCount = 0; - me->CastSpell(me, SPELL_SYSTEMS_SHUTDOWN, true); + EnterEvadeMode(); + return; } + events.Repeat(5s); + break; + case EVENT_PURSUE: + Talk(FLAME_LEVIATHAN_SAY_PURSUE); + me->CastSpell(me, SPELL_PURSUED, false); + events.RescheduleEvent(EVENT_PURSUE, 31s); + return; + case EVENT_SPEED: + me->CastSpell(me, SPELL_GATHERING_SPEED, false); + events.Repeat(15s); + return; + case EVENT_MISSILE: + me->CastSpell(me, SPELL_MISSILE_BARRAGE, true); + events.Repeat(4s); + return; + case EVENT_VENT: + me->CastSpell(me, SPELL_FLAME_VENTS, false); + events.Repeat(20s); + return; + case EVENT_SUMMON: + if (summons.size() < 20) + if (Creature* lift = DoSummonFlyer(NPC_MECHANOLIFT, me, 30.0f, 50.0f, 0)) + lift->GetMotionMaster()->MoveRandom(100); + + events.Repeat(4s); + return; + case EVENT_SOUND_BEGINNING: + if (_towersCount) + Talk(FLAME_LEVIATHAN_SAY_HARDMODE); + else + Talk(FLAME_LEVIATHAN_SAY_TOWER_NONE); + return; + case EVENT_REINSTALL: + for (uint8 i = RAID_MODE(0, 2); i < 4; ++i) + if (Unit* seat = vehicle->GetPassenger(i)) + if (seat->IsCreature()) + seat->ToCreature()->AI()->EnterEvadeMode(); + Talk(FLAME_LEVIATHAN_EMOTE_REACTIVATE); + return; + case EVENT_THORIMS_HAMMER: + SummonTowerHelpers(TOWER_OF_STORMS); + events.Repeat(1min, 2min); + Talk(FLAME_LEVIATHAN_EMOTE_STORM); + Talk(FLAME_LEVIATHAN_SAY_TOWER_STORM); + return; + case EVENT_FREYA: + SummonTowerHelpers(TOWER_OF_LIFE); + Talk(FLAME_LEVIATHAN_EMOTE_NATURE); + Talk(FLAME_LEVIATHAN_SAY_TOWER_NATURE); + return; + case EVENT_MIMIRONS_INFERNO: + SummonTowerHelpers(TOWER_OF_FLAMES); + Talk(FLAME_LEVIATHAN_EMOTE_FLAME); + Talk(FLAME_LEVIATHAN_SAY_TOWER_FLAME); + return; + case EVENT_HODIRS_FURY: + SummonTowerHelpers(TOWER_OF_FROST); + Talk(FLAME_LEVIATHAN_EMOTE_FROST); + Talk(FLAME_LEVIATHAN_SAY_TOWER_FROST); + return; + } + + if (me->isAttackReady() && !me->HasUnitState(UNIT_STATE_STUNNED)) + { + if (me->IsWithinCombatRange(me->GetVictim(), 15.0f)) + { + me->CastSpell(me->GetVictim(), SPELL_BATTERING_RAM, false); + me->resetAttackTimer(); } } - }; + } + + void DoAction(int32 action) override + { + if (action == ACTION_DESTROYED_TURRET) + { + ++_destroyedTurretCount; + + if (_destroyedTurretCount == RAID_MODE(2, 4)) + { + _destroyedTurretCount = 0; + me->CastSpell(me, SPELL_SYSTEMS_SHUTDOWN, true); + } + } + } }; -void boss_flame_leviathan::boss_flame_leviathanAI::BindPlayers() +void boss_flame_leviathan::BindPlayers() { me->GetMap()->ToInstanceMap()->PermBindAllPlayers(); } -void boss_flame_leviathan::boss_flame_leviathanAI::RadioSay(uint8 textid) +void boss_flame_leviathan::RadioSay(uint8 textid) { if (Creature* r = me->SummonCreature(NPC_BRANN_RADIO, me->GetPositionX() - 150, me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 5000)) { @@ -513,13 +494,13 @@ void boss_flame_leviathan::boss_flame_leviathanAI::RadioSay(uint8 textid) } } -void boss_flame_leviathan::boss_flame_leviathanAI::ActivateTowers() +void boss_flame_leviathan::ActivateTowers() { _towersCount = 0; me->ResetLootMode(); for (uint32 i = EVENT_TOWER_OF_LIFE_DESTROYED; i <= EVENT_TOWER_OF_FLAMES_DESTROYED; ++i) { - if (m_pInstance->GetData(i)) + if (instance->GetData(i)) { ++_towersCount; @@ -547,35 +528,35 @@ void boss_flame_leviathan::boss_flame_leviathanAI::ActivateTowers() } } -void boss_flame_leviathan::boss_flame_leviathanAI::TurnGates(bool _start, bool _death) +void boss_flame_leviathan::TurnGates(bool _start, bool _death) { - if (!m_pInstance) + if (!instance) return; if (_start) { // first one is ALWAYS turned on, unless leviathan is beaten GameObject* go = nullptr; - if ((go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(DATA_LIGHTNING_WALL2)))) + if ((go = instance->GetGameObject(DATA_LIGHTNING_WALL2))) go->SetGoState(GO_STATE_READY); - if (m_pInstance->GetData(TYPE_LEVIATHAN) == NOT_STARTED) - if ((go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(GO_LEVIATHAN_DOORS)))) + if (instance->GetBossState(BOSS_LEVIATHAN) == NOT_STARTED) + if ((go = instance->GetGameObject(DATA_LEVIATHAN_DOORS))) go->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); } else { GameObject* go = nullptr; if (_death) - if ((go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(DATA_LIGHTNING_WALL1)))) + if ((go = instance->GetGameObject(DATA_LIGHTNING_WALL1))) go->SetGoState(GO_STATE_ACTIVE); - if ((go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(DATA_LIGHTNING_WALL2)))) + if ((go = instance->GetGameObject(DATA_LIGHTNING_WALL2))) go->SetGoState(GO_STATE_ACTIVE); - if ((go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(GO_LEVIATHAN_DOORS)))) + if ((go = instance->GetGameObject(DATA_LEVIATHAN_DOORS))) { - if (m_pInstance->GetData(TYPE_LEVIATHAN) == SPECIAL || m_pInstance->GetData(TYPE_LEVIATHAN) == DONE) + if (instance->GetBossState(BOSS_LEVIATHAN) == SPECIAL || instance->GetBossState(BOSS_LEVIATHAN) == DONE) go->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); else go->SetGoState(GO_STATE_READY); @@ -583,29 +564,29 @@ void boss_flame_leviathan::boss_flame_leviathanAI::TurnGates(bool _start, bool _ } } -void boss_flame_leviathan::boss_flame_leviathanAI::TurnHealStations(bool _apply) +void boss_flame_leviathan::TurnHealStations(bool _apply) { - if (!m_pInstance) + if (!instance) return; GameObject* go = nullptr; if (_apply) { - if ((go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(DATA_REPAIR_STATION1)))) + if ((go = instance->GetGameObject(DATA_REPAIR_STATION1))) go->SetLootState(GO_READY); - if ((go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(DATA_REPAIR_STATION2)))) + if ((go = instance->GetGameObject(DATA_REPAIR_STATION2))) go->SetLootState(GO_READY); } else { - if ((go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(DATA_REPAIR_STATION1)))) + if ((go = instance->GetGameObject(DATA_REPAIR_STATION1))) go->SetLootState(GO_ACTIVATED); - if ((go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(DATA_REPAIR_STATION2)))) + if ((go = instance->GetGameObject(DATA_REPAIR_STATION2))) go->SetLootState(GO_ACTIVATED); } } -void boss_flame_leviathan::boss_flame_leviathanAI::ScheduleEvents() +void boss_flame_leviathan::ScheduleEvents() { events.RescheduleEvent(EVENT_MISSILE, 5s); events.RescheduleEvent(EVENT_VENT, 20s); @@ -617,7 +598,7 @@ void boss_flame_leviathan::boss_flame_leviathanAI::ScheduleEvents() events.RescheduleEvent(EVENT_PURSUE, 0ms); } -void boss_flame_leviathan::boss_flame_leviathanAI::SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) +void boss_flame_leviathan::SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) { if (spellInfo->Id == SPELL_SYSTEMS_SHUTDOWN) { @@ -634,17 +615,14 @@ void boss_flame_leviathan::boss_flame_leviathanAI::SpellHit(Unit* /*caster*/, S me->InterruptNonMeleeSpells(false); } -void boss_flame_leviathan::boss_flame_leviathanAI::JustDied(Unit*) +void boss_flame_leviathan::JustDied(Unit*) { // Despawn Lashers, do before summons clear summons.DoAction(ACTION_DESPAWN_ADDS); summons.DespawnAll(); - if (m_pInstance) - { - m_pInstance->SetData(TYPE_LEVIATHAN, DONE); - m_pInstance->SetData(DATA_VEHICLE_SPAWN, VEHICLE_POS_NONE); - } + instance->SetBossState(BOSS_LEVIATHAN, DONE); + instance->SetData(DATA_VEHICLE_SPAWN, VEHICLE_POS_NONE); Talk(FLAME_LEVIATHAN_SAY_DEATH); @@ -652,7 +630,7 @@ void boss_flame_leviathan::boss_flame_leviathanAI::JustDied(Unit*) BindPlayers(); } -void boss_flame_leviathan::boss_flame_leviathanAI::KilledUnit(Unit* who) +void boss_flame_leviathan::KilledUnit(Unit* who) { if (who == me->GetVictim()) events.RescheduleEvent(EVENT_PURSUE, 0ms); @@ -661,7 +639,7 @@ void boss_flame_leviathan::boss_flame_leviathanAI::KilledUnit(Unit* who) Talk(FLAME_LEVIATHAN_SAY_SLAY); } -void boss_flame_leviathan::boss_flame_leviathanAI::SummonTowerHelpers(uint8 towerId) +void boss_flame_leviathan::SummonTowerHelpers(uint8 towerId) { if (towerId == TOWER_OF_LIFE) { @@ -691,7 +669,7 @@ void boss_flame_leviathan::boss_flame_leviathanAI::SummonTowerHelpers(uint8 towe } } -void boss_flame_leviathan::boss_flame_leviathanAI::SpellHitTarget(Unit* target, SpellInfo const* spell) +void boss_flame_leviathan::SpellHitTarget(Unit* target, SpellInfo const* spell) { if (spell->Id != SPELL_PURSUED) return; @@ -706,729 +684,597 @@ void boss_flame_leviathan::boss_flame_leviathanAI::SpellHitTarget(Unit* target, } } -class boss_flame_leviathan_seat : public CreatureScript +struct boss_flame_leviathan_seat : public VehicleAI { -public: - boss_flame_leviathan_seat() : CreatureScript("boss_flame_leviathan_seat") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_flame_leviathan_seat(Creature* creature) : VehicleAI(creature), vehicle(creature->GetVehicleKit()) { - return GetUlduarAI(pCreature); + ASSERT(vehicle); + me->SetReactState(REACT_PASSIVE); } - struct boss_flame_leviathan_seatAI : public VehicleAI + Vehicle* vehicle; + uint32 _despawnTimer; + + void EnterEvadeMode(EvadeReason /*why*/) override { - boss_flame_leviathan_seatAI(Creature* creature) : VehicleAI(creature), vehicle(creature->GetVehicleKit()) - { - ASSERT(vehicle); - me->SetReactState(REACT_PASSIVE); - } - - Vehicle* vehicle; - uint32 _despawnTimer; - - void EnterEvadeMode(EvadeReason /*why*/) override - { - vehicle->InstallAllAccessories(false); - } - - void Reset() override - { - _despawnTimer = !me->GetMap()->Is25ManRaid(); - } - - void UpdateAI(uint32 diff) override - { - if (_despawnTimer) - { - _despawnTimer += diff; - if (_despawnTimer >= 2000) - { - _despawnTimer = 0; - if (Vehicle* veh = me->GetVehicle()) - if (veh->GetPassenger(0) == me || veh->GetPassenger(1) == me) - me->DespawnOrUnsummon(1ms); - } - } - - VehicleAI::UpdateAI(diff); - } - - void AttackStart(Unit*) override { } - - void PassengerBoarded(Unit* who, int8 seatId, bool apply) override - { - if (!who->IsPlayer() || !me->GetVehicle()) - return; - - who->ApplySpellImmune(63847, IMMUNITY_ID, 63847, apply); // SPELL_FLAME_VENTS_TRIGGER - who->ApplySpellImmune(SPELL_MISSILE_BARRAGE, IMMUNITY_ID, SPELL_MISSILE_BARRAGE, apply); - who->ApplySpellImmune(SPELL_BATTERING_RAM, IMMUNITY_ID, SPELL_BATTERING_RAM, apply); - - if (seatId == SEAT_PLAYER) - { - if (Unit* turret = me->GetVehicleKit()->GetPassenger(SEAT_TURRET)) - { - if (apply) - { - turret->ReplaceAllUnitFlags(UNIT_FLAG_NONE); - turret->GetAI()->AttackStart(who); - if (Creature* leviathan = me->GetVehicleCreatureBase()) - leviathan->AI()->Talk(FLAME_LEVIATHAN_SAY_PLAYER_RIDING); - } - else - { - turret->ReplaceAllUnitFlags(UNIT_FLAG_NOT_SELECTABLE); - turret->SetImmuneToAll(true); - if (turret->IsCreature()) - turret->ToCreature()->AI()->EnterEvadeMode(); - } - } - } - } - }; -}; - -class boss_flame_leviathan_defense_turret : public CreatureScript -{ -public: - boss_flame_leviathan_defense_turret() : CreatureScript("boss_flame_leviathan_defense_turret") { } - - struct boss_flame_leviathan_defense_turretAI : public TurretAI - { - boss_flame_leviathan_defense_turretAI(Creature* creature) : TurretAI(creature) - { - _setHealth = false; - _instance = creature->GetInstanceScript(); - } - - InstanceScript* _instance; - - bool _setHealth; - void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (!CanAIAttack(who)) - { - _setHealth = true; - damage = 0; - } - } - - void JustDied(Unit* killer) override - { - if (Player* player = killer->ToPlayer()) - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, me); - - if (Vehicle* vehicle = me->GetVehicle()) - if (Unit* device = vehicle->GetPassenger(SEAT_DEVICE)) - device->ReplaceAllUnitFlags(UNIT_FLAG_NONE); // unselectable - - if (Creature* leviathan = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(TYPE_LEVIATHAN))) - leviathan->AI()->DoAction(ACTION_DESTROYED_TURRET); - } - - bool CanAIAttack(Unit const* who) const override - { - if (!who || !who->IsPlayer() || !who->GetVehicle() || who->GetVehicleBase()->GetEntry() != NPC_SEAT) - return false; - return true; - } - - void UpdateAI(uint32 diff) override - { - if (_setHealth) - { - me->SetHealth(std::min(me->GetHealth() + 1, me->GetMaxHealth())); - _setHealth = false; - } - - TurretAI::UpdateAI(diff); - } - - void KilledUnit(Unit* who) override - { - if (Player* plr = who->ToPlayer()) // make sure that there's no death player on the seat. - if (plr->GetVehicle()) - plr->ExitVehicle(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI(creature); - } -}; - -class boss_flame_leviathan_overload_device : public CreatureScript -{ -public: - boss_flame_leviathan_overload_device() : CreatureScript("boss_flame_leviathan_overload_device") { } - - struct boss_flame_leviathan_overload_deviceAI : public NullCreatureAI - { - boss_flame_leviathan_overload_deviceAI(Creature* creature) : NullCreatureAI(creature) - { - } - - void OnSpellClick(Unit* /*clicker*/, bool& result) override - { - if (!result) - return; - - if (me->GetVehicle()) - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_SPELLCLICK); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - - if (Unit* player = me->GetVehicle()->GetPassenger(SEAT_PLAYER)) - { - me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true); - player->ExitVehicle(); - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI(creature); - } -}; - -class npc_freya_ward : public CreatureScript -{ -public: - npc_freya_ward() : CreatureScript("npc_freya_ward") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); + vehicle->InstallAllAccessories(false); } - struct npc_freya_wardAI : public NullCreatureAI + void Reset() override { - npc_freya_wardAI(Creature* c) : NullCreatureAI(c), summons(c) - { - } - - SummonList summons; - uint32 _castTimer; - bool _summoned; - - void Reset() override - { - _summoned = false; - _castTimer = 25000; - summons.DespawnAll(); - if (Creature* cr = me->FindNearestCreature(NPC_FREYA_WARD_TARGET, 60.0f, true)) - if (Aura* aur = cr->AddAura(SPELL_FREYA_DUMMY_GREEN, cr)) - { - aur->SetMaxDuration(-1); - aur->SetDuration(-1); - } - } - - void JustSummoned(Creature* cr) override - { - _summoned = true; - summons.Summon(cr); - } - - void SummonedCreatureDespawn(Creature* cr) override { summons.Despawn(cr); } - - void UpdateAI(uint32 diff) override - { - if (_summoned) - { - for (SummonList::const_iterator itr = summons.begin(); itr != summons.end();) - { - Creature* summon = ObjectAccessor::GetCreature(*me, *itr); - ++itr; - if (summon) - { - summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_MANUAL_DESPAWN); - if (Unit* target = summon->SelectNearestTarget(200.0f)) - summon->AI()->AttackStart(target); - } - } - _summoned = false; - } - - _castTimer += diff; - if (_castTimer >= 29 * IN_MILLISECONDS) - { - if (Creature* cr = me->FindNearestCreature(NPC_FREYA_WARD_TARGET, 60.0f, true)) - { - me->CastSpell(cr, SPELL_FREYA_WARD, false); - me->CastSpell(cr, 62947 /*SPELL_FREYA_WARD_SECOND_SUMMON*/, false); - } - - _castTimer = 0; - } - } - - void DoAction(int32 param) override - { - if (param == ACTION_DESPAWN_ADDS) - summons.DespawnAll(); - } - }; -}; - -class npc_hodirs_fury : public CreatureScript -{ -public: - npc_hodirs_fury() : CreatureScript("npc_hodirs_fury") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); + _despawnTimer = !me->GetMap()->Is25ManRaid(); } - struct npc_hodirs_furyAI : public NullCreatureAI + void UpdateAI(uint32 diff) override { - npc_hodirs_furyAI(Creature* c) : NullCreatureAI(c) + if (_despawnTimer) { - } - - uint32 _timeToHit; - uint32 _switchTargetTimer; - - void Reset() override - { - _timeToHit = 0; - _switchTargetTimer = 30000; - me->SetWalk(true); - - if (Aura* aur = me->AddAura(SPELL_FREYA_DUMMY_BLUE, me)) + _despawnTimer += diff; + if (_despawnTimer >= 2000) { - aur->SetMaxDuration(-1); - aur->SetDuration(-1); + _despawnTimer = 0; + if (Vehicle* veh = me->GetVehicle()) + if (veh->GetPassenger(0) == me || veh->GetPassenger(1) == me) + me->DespawnOrUnsummon(1ms); } } - void MovementInform(uint32 type, uint32 /*param*/) override - { - if (type == FOLLOW_MOTION_TYPE && !_timeToHit) - { - _timeToHit = 1; - _switchTargetTimer = 0; - me->SetControlled(true, UNIT_STATE_STUNNED); - } - } + VehicleAI::UpdateAI(diff); + } - void UpdateAI(uint32 diff) override + void AttackStart(Unit*) override { } + + void PassengerBoarded(Unit* who, int8 seatId, bool apply) override + { + if (!who->IsPlayer() || !me->GetVehicle()) + return; + + who->ApplySpellImmune(63847, IMMUNITY_ID, 63847, apply); // SPELL_FLAME_VENTS_TRIGGER + who->ApplySpellImmune(SPELL_MISSILE_BARRAGE, IMMUNITY_ID, SPELL_MISSILE_BARRAGE, apply); + who->ApplySpellImmune(SPELL_BATTERING_RAM, IMMUNITY_ID, SPELL_BATTERING_RAM, apply); + + if (seatId == SEAT_PLAYER) { - if (_timeToHit) + if (Unit* turret = me->GetVehicleKit()->GetPassenger(SEAT_TURRET)) { - _timeToHit += diff; - if (_timeToHit >= 5000) + if (apply) { - if (Creature* cr = me->SummonCreature(NPC_HODIRS_FURY, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 40, 0, TEMPSUMMON_TIMED_DESPAWN, 10000)) - cr->CastSpell(me, SPELL_HODIRS_FURY, true); - - _switchTargetTimer = 25000; // Switch target soon - _timeToHit = 0; - } - return; - } - - _switchTargetTimer += diff; - if (_switchTargetTimer >= 30000) - { - if (Unit* target = me->SelectNearbyTarget(nullptr, 200.0f)) - { - if (target->GetVehicleBase() && target->GetVehicleBase()->GetEntry() == NPC_SEAT) - { - _switchTargetTimer = 20000; - return; - } - me->SetControlled(false, UNIT_STATE_STUNNED); - me->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f); - _switchTargetTimer = 0; + turret->ReplaceAllUnitFlags(UNIT_FLAG_NONE); + turret->GetAI()->AttackStart(who); + if (Creature* leviathan = me->GetVehicleCreatureBase()) + leviathan->AI()->Talk(FLAME_LEVIATHAN_SAY_PLAYER_RIDING); } else - _switchTargetTimer = 25000; + { + turret->ReplaceAllUnitFlags(UNIT_FLAG_NOT_SELECTABLE); + turret->SetImmuneToAll(true); + if (turret->IsCreature()) + turret->ToCreature()->AI()->EnterEvadeMode(); + } } } - }; + } }; -class npc_mimirons_inferno : public CreatureScript +struct boss_flame_leviathan_defense_turret : public TurretAI { -public: - npc_mimirons_inferno() : CreatureScript("npc_mimirons_inferno") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_flame_leviathan_defense_turret(Creature* creature) : TurretAI(creature) { - return GetUlduarAI(creature); + _setHealth = false; + _instance = creature->GetInstanceScript(); } - struct npc_mimirons_infernoAI : public npc_escortAI + InstanceScript* _instance; + + bool _setHealth; + void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override { - npc_mimirons_infernoAI(Creature* creature) : npc_escortAI(creature), summons(me) + if (!CanAIAttack(who)) { - me->SetReactState(REACT_PASSIVE); + _setHealth = true; + damage = 0; + } + } + + void JustDied(Unit* killer) override + { + if (Player* player = killer->ToPlayer()) + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, me); + + if (Vehicle* vehicle = me->GetVehicle()) + if (Unit* device = vehicle->GetPassenger(SEAT_DEVICE)) + device->ReplaceAllUnitFlags(UNIT_FLAG_NONE); // unselectable + + if (Creature* leviathan = _instance->GetCreature(BOSS_LEVIATHAN)) + leviathan->AI()->DoAction(ACTION_DESTROYED_TURRET); + } + + bool CanAIAttack(Unit const* who) const override + { + if (!who || !who->IsPlayer() || !who->GetVehicle() || who->GetVehicleBase()->GetEntry() != NPC_SEAT) + return false; + return true; + } + + void UpdateAI(uint32 diff) override + { + if (_setHealth) + { + me->SetHealth(std::min(me->GetHealth() + 1, me->GetMaxHealth())); + _setHealth = false; } - SummonList summons; - uint32 _spellTimer; - uint32 _recastTimer; + TurretAI::UpdateAI(diff); + } - void AttackStart(Unit*) override { } - void MoveInLineOfSight(Unit*) override { } - void WaypointReached(uint32 /*waypointId*/) override { } + void KilledUnit(Unit* who) override + { + if (Player* plr = who->ToPlayer()) // make sure that there's no death player on the seat. + if (plr->GetVehicle()) + plr->ExitVehicle(); + } +}; - void DoAction(int32 param) override +struct boss_flame_leviathan_overload_device : public NullCreatureAI +{ + boss_flame_leviathan_overload_device(Creature* creature) : NullCreatureAI(creature) + { + } + + void OnSpellClick(Unit* /*clicker*/, bool& result) override + { + if (!result) + return; + + if (me->GetVehicle()) { - if (param == ACTION_DESPAWN_ADDS) - summons.DespawnAll(); + me->RemoveNpcFlag(UNIT_NPC_FLAG_SPELLCLICK); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + + if (Unit* player = me->GetVehicle()->GetPassenger(SEAT_PLAYER)) + { + me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true); + player->ExitVehicle(); + } } + } +}; - void Reset() override - { - summons.DespawnAll(); - _spellTimer = 0; - me->SetWalk(true); - Start(false, ObjectGuid::Empty, nullptr, false, true); - if (Aura* aur = me->AddAura(SPELL_FREYA_DUMMY_YELLOW, me)) +struct npc_freya_ward : public NullCreatureAI +{ + npc_freya_ward(Creature* c) : NullCreatureAI(c), summons(c) + { + } + + SummonList summons; + uint32 _castTimer; + bool _summoned; + + void Reset() override + { + _summoned = false; + _castTimer = 25000; + summons.DespawnAll(); + if (Creature* cr = me->FindNearestCreature(NPC_FREYA_WARD_TARGET, 60.0f, true)) + if (Aura* aur = cr->AddAura(SPELL_FREYA_DUMMY_GREEN, cr)) { aur->SetMaxDuration(-1); aur->SetDuration(-1); } - } - - void JustSummoned(Creature* cr) override { summons.Summon(cr); } - void SummonedCreatureDespawn(Creature* cr) override { summons.Despawn(cr); } - - void UpdateAI(uint32 diff) override - { - npc_escortAI::UpdateAI(diff); - - _spellTimer += diff; - if (_spellTimer >= 2000) - { - if (Creature* cr = me->SummonCreature(NPC_MIMIRONS_INFERNO, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 40.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 30000)) - cr->CastSpell(me, SPELL_MIMIRONS_INFERNO, true); - - _spellTimer = 0; - } - } - }; -}; - -class npc_thorims_hammer : public CreatureScript -{ -public: - npc_thorims_hammer() : CreatureScript("npc_thorims_hammer") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct npc_thorims_hammerAI : public NullCreatureAI + void JustSummoned(Creature* cr) override { - npc_thorims_hammerAI(Creature* c) : NullCreatureAI(c) - { - } + _summoned = true; + summons.Summon(cr); + } - uint32 _beamTimer; - uint32 _finishTime; - uint32 _removeTimer; + void SummonedCreatureDespawn(Creature* cr) override { summons.Despawn(cr); } - void Reset() override + void UpdateAI(uint32 diff) override + { + if (_summoned) { - _finishTime = 5000 + rand() % 15000; - _beamTimer = 1; - _removeTimer = 0; - me->CastSpell(me, SPELL_FREYA_DUMMY_BLUE, true); - } - - void UpdateAI(uint32 diff) override - { - if (_beamTimer) + for (SummonList::const_iterator itr = summons.begin(); itr != summons.end();) { - _beamTimer += diff; - if (_beamTimer >= _finishTime) + Creature* summon = ObjectAccessor::GetCreature(*me, *itr); + ++itr; + if (summon) { - if (Creature* cr = me->SummonCreature(NPC_THORIM_HAMMER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 40, 0, TEMPSUMMON_TIMED_DESPAWN, 5000)) - cr->CastSpell(me, SPELL_THORIMS_HAMMER, false); - - _beamTimer = 0; - _removeTimer = 1; - me->DespawnOrUnsummon(5s); + summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_MANUAL_DESPAWN); + if (Unit* target = summon->SelectNearestTarget(200.0f)) + summon->AI()->AttackStart(target); } } - if (_removeTimer) + _summoned = false; + } + + _castTimer += diff; + if (_castTimer >= 29 * IN_MILLISECONDS) + { + if (Creature* cr = me->FindNearestCreature(NPC_FREYA_WARD_TARGET, 60.0f, true)) { - _removeTimer += diff; - if (_removeTimer >= 3 * IN_MILLISECONDS) - { - _removeTimer = 0; - me->RemoveAura(SPELL_FREYA_DUMMY_BLUE); - } + me->CastSpell(cr, SPELL_FREYA_WARD, false); + me->CastSpell(cr, 62947 /*SPELL_FREYA_WARD_SECOND_SUMMON*/, false); } + + _castTimer = 0; } - }; -}; - -class npc_pool_of_tar : public CreatureScript -{ -public: - npc_pool_of_tar() : CreatureScript("npc_pool_of_tar") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct npc_pool_of_tarAI : public NullCreatureAI + void DoAction(int32 param) override { - npc_pool_of_tarAI(Creature* c) : NullCreatureAI(c) - { - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - damage = 0; - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->SchoolMask & SPELL_SCHOOL_MASK_FIRE && !me->HasAura(SPELL_BLAZE)) - me->CastSpell(me, SPELL_BLAZE, true); - } - }; + if (param == ACTION_DESPAWN_ADDS) + summons.DespawnAll(); + } }; -class npc_brann_radio : public CreatureScript +struct npc_hodirs_fury : public NullCreatureAI { -public: - npc_brann_radio() : CreatureScript("npc_brann_radio") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_hodirs_fury(Creature* c) : NullCreatureAI(c) { - return GetUlduarAI(pCreature); } - struct npc_brann_radioAI : public NullCreatureAI + uint32 _timeToHit; + uint32 _switchTargetTimer; + + void Reset() override { - npc_brann_radioAI(Creature* c) : NullCreatureAI(c) + _timeToHit = 0; + _switchTargetTimer = 30000; + me->SetWalk(true); + + if (Aura* aur = me->AddAura(SPELL_FREYA_DUMMY_BLUE, me)) { - _lock = (me->GetInstanceScript() && me->GetInstanceScript()->GetData(TYPE_LEVIATHAN) > NOT_STARTED); - _helpLock = _lock; + aur->SetMaxDuration(-1); + aur->SetDuration(-1); } + } - bool _lock; - bool _helpLock; - - void Reset() override + void MovementInform(uint32 type, uint32 /*param*/) override + { + if (type == FOLLOW_MOTION_TYPE && !_timeToHit) { - me->SetReactState(REACT_AGGRESSIVE); + _timeToHit = 1; + _switchTargetTimer = 0; + me->SetControlled(true, UNIT_STATE_STUNNED); } + } - void MoveInLineOfSight(Unit* who) override + void UpdateAI(uint32 diff) override + { + if (_timeToHit) { - if (!_lock) + _timeToHit += diff; + if (_timeToHit >= 5000) { - if (!who->IsPlayer() && !who->IsVehicle()) + if (Creature* cr = me->SummonCreature(NPC_HODIRS_FURY, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 40, 0, TEMPSUMMON_TIMED_DESPAWN, 10000)) + cr->CastSpell(me, SPELL_HODIRS_FURY, true); + + _switchTargetTimer = 25000; // Switch target soon + _timeToHit = 0; + } + return; + } + + _switchTargetTimer += diff; + if (_switchTargetTimer >= 30000) + { + if (Unit* target = me->SelectNearbyTarget(nullptr, 200.0f)) + { + if (target->GetVehicleBase() && target->GetVehicleBase()->GetEntry() == NPC_SEAT) + { + _switchTargetTimer = 20000; return; - - // MIMIRON - else if (me->GetDistance2d(-81.9207f, 111.432f) < 5.0f) - { - if (me->GetDistance2d(who) <= 60.0f && who->GetPositionZ() > 430.0f) - { - Talk(BRANN_RADIO_SAY_TOWER_MIMIRON); - _lock = true; - } - } - // FREYA - else if (me->GetDistance2d(-221.475f, -271.087f) < 5.0f) - { - if (me->GetDistance2d(who) <= 60.0f && who->GetPositionZ() < 380.0f) - { - Talk(BRANN_RADIO_SAY_TOWER_FREYA); - _lock = true; - } - } - // STATIONS - else if (me->GetDistance2d(73.8978f, -29.3306f) < 5.0f) - { - if (me->GetDistance2d(who) <= 40.0f) - { - Talk(BRANN_RADIO_SAY_STATIONS); - _lock = true; - } - } - // HODIR - else if (me->GetDistance2d(68.7679f, -325.026f) < 5.0f) - { - if (me->GetDistance2d(who) <= 40.0f) - { - Talk(BRANN_RADIO_SAY_TOWER_HODIR); - _lock = true; - } - } - // THORIM - else if (me->GetDistance2d(174.442f, 345.679f) < 5.0f) - { - if (me->GetDistance2d(who) <= 60.0f) - { - Talk(BRANN_RADIO_SAY_TOWER_THORIM); - _lock = true; - } - } - // COME A BIT CLOSER - else if (me->GetDistance2d(-508.898f, -32.9631f) < 5.0f) - { - if (who->GetPositionX() >= -480.0f) - { - Talk(BRANN_RADIO_SAY_GENERATORS); - _lock = true; - } } + me->SetControlled(false, UNIT_STATE_STUNNED); + me->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f); + _switchTargetTimer = 0; } + else + _switchTargetTimer = 25000; } - }; + } }; -class npc_storm_beacon_spawn : public CreatureScript +struct npc_mimirons_inferno : public npc_escortAI { -public: - npc_storm_beacon_spawn() : CreatureScript("npc_storm_beacon_spawn") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_mimirons_inferno(Creature* creature) : npc_escortAI(creature), summons(me) { - return GetUlduarAI(pCreature); + me->SetReactState(REACT_PASSIVE); } - struct npc_storm_beacon_spawnAI : public NullCreatureAI + SummonList summons; + uint32 _spellTimer; + uint32 _recastTimer; + + void AttackStart(Unit*) override { } + void MoveInLineOfSight(Unit*) override { } + void WaypointReached(uint32 /*waypointId*/) override { } + + void DoAction(int32 param) override { - npc_storm_beacon_spawnAI(Creature* c) : NullCreatureAI(c) + if (param == ACTION_DESPAWN_ADDS) + summons.DespawnAll(); + } + + void Reset() override + { + summons.DespawnAll(); + _spellTimer = 0; + me->SetWalk(true); + Start(false, ObjectGuid::Empty, nullptr, false, true); + if (Aura* aur = me->AddAura(SPELL_FREYA_DUMMY_YELLOW, me)) { - _amount = 0; - _checkTimer = 0; + aur->SetMaxDuration(-1); + aur->SetDuration(-1); } + } - uint8 _amount; - uint32 _checkTimer; + void JustSummoned(Creature* cr) override { summons.Summon(cr); } + void SummonedCreatureDespawn(Creature* cr) override { summons.Despawn(cr); } - void UpdateAI(uint32 diff) override + void UpdateAI(uint32 diff) override + { + npc_escortAI::UpdateAI(diff); + + _spellTimer += diff; + if (_spellTimer >= 2000) { - if (_amount < 40) + if (Creature* cr = me->SummonCreature(NPC_MIMIRONS_INFERNO, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 40.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 30000)) + cr->CastSpell(me, SPELL_MIMIRONS_INFERNO, true); + + _spellTimer = 0; + } + } +}; + +struct npc_thorims_hammer : public NullCreatureAI +{ + npc_thorims_hammer(Creature* c) : NullCreatureAI(c) + { + } + + uint32 _beamTimer; + uint32 _finishTime; + uint32 _removeTimer; + + void Reset() override + { + _finishTime = 5000 + rand() % 15000; + _beamTimer = 1; + _removeTimer = 0; + me->CastSpell(me, SPELL_FREYA_DUMMY_BLUE, true); + } + + void UpdateAI(uint32 diff) override + { + if (_beamTimer) + { + _beamTimer += diff; + if (_beamTimer >= _finishTime) { - _checkTimer += diff; - if (_checkTimer >= 4000) + if (Creature* cr = me->SummonCreature(NPC_THORIM_HAMMER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 40, 0, TEMPSUMMON_TIMED_DESPAWN, 5000)) + cr->CastSpell(me, SPELL_THORIMS_HAMMER, false); + + _beamTimer = 0; + _removeTimer = 1; + me->DespawnOrUnsummon(5s); + } + } + if (_removeTimer) + { + _removeTimer += diff; + if (_removeTimer >= 3 * IN_MILLISECONDS) + { + _removeTimer = 0; + me->RemoveAura(SPELL_FREYA_DUMMY_BLUE); + } + } + } +}; + +struct npc_pool_of_tar : public NullCreatureAI +{ + npc_pool_of_tar(Creature* c) : NullCreatureAI(c) + { + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + damage = 0; + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->SchoolMask & SPELL_SCHOOL_MASK_FIRE && !me->HasAura(SPELL_BLAZE)) + me->CastSpell(me, SPELL_BLAZE, true); + } +}; + +struct npc_brann_radio : public NullCreatureAI +{ + npc_brann_radio(Creature* c) : NullCreatureAI(c) + { + _lock = (me->GetInstanceScript() && me->GetInstanceScript()->GetBossState(BOSS_LEVIATHAN) > NOT_STARTED); + _helpLock = _lock; + } + + bool _lock; + bool _helpLock; + + void Reset() override + { + me->SetReactState(REACT_AGGRESSIVE); + } + + void MoveInLineOfSight(Unit* who) override + { + if (!_lock) + { + if (!who->IsPlayer() && !who->IsVehicle()) + return; + + // MIMIRON + else if (me->GetDistance2d(-81.9207f, 111.432f) < 5.0f) + { + if (me->GetDistance2d(who) <= 60.0f && who->GetPositionZ() > 430.0f) { - _checkTimer = 0; - if (Unit* target = me->SelectNearbyTarget(nullptr, 80.0f)) - { - ++_amount; - if (Creature* cr = me->SummonCreature(NPC_DEFENDER_GENERATED, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 4, me->GetOrientation(), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900000)) - cr->AI()->AttackStart(target); - } + Talk(BRANN_RADIO_SAY_TOWER_MIMIRON); + _lock = true; + } + } + // FREYA + else if (me->GetDistance2d(-221.475f, -271.087f) < 5.0f) + { + if (me->GetDistance2d(who) <= 60.0f && who->GetPositionZ() < 380.0f) + { + Talk(BRANN_RADIO_SAY_TOWER_FREYA); + _lock = true; + } + } + // STATIONS + else if (me->GetDistance2d(73.8978f, -29.3306f) < 5.0f) + { + if (me->GetDistance2d(who) <= 40.0f) + { + Talk(BRANN_RADIO_SAY_STATIONS); + _lock = true; + } + } + // HODIR + else if (me->GetDistance2d(68.7679f, -325.026f) < 5.0f) + { + if (me->GetDistance2d(who) <= 40.0f) + { + Talk(BRANN_RADIO_SAY_TOWER_HODIR); + _lock = true; + } + } + // THORIM + else if (me->GetDistance2d(174.442f, 345.679f) < 5.0f) + { + if (me->GetDistance2d(who) <= 60.0f) + { + Talk(BRANN_RADIO_SAY_TOWER_THORIM); + _lock = true; + } + } + // COME A BIT CLOSER + else if (me->GetDistance2d(-508.898f, -32.9631f) < 5.0f) + { + if (who->GetPositionX() >= -480.0f) + { + Talk(BRANN_RADIO_SAY_GENERATORS); + _lock = true; } } } - }; + } }; -class boss_flame_leviathan_safety_container : public CreatureScript +struct npc_storm_beacon_spawn : public NullCreatureAI { -public: - boss_flame_leviathan_safety_container() : CreatureScript("boss_flame_leviathan_safety_container") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_storm_beacon_spawn(Creature* c) : NullCreatureAI(c) { - return GetUlduarAI(pCreature); + _amount = 0; + _checkTimer = 0; } - struct boss_flame_leviathan_safety_containerAI : public NullCreatureAI + uint8 _amount; + uint32 _checkTimer; + + void UpdateAI(uint32 diff) override { - boss_flame_leviathan_safety_containerAI(Creature* c) : NullCreatureAI(c) + if (_amount < 40) { - _allowTimer = 0; - } - - uint32 _allowTimer; - - void MovementInform(uint32 /*type*/, uint32 id) override - { - if (id == me->GetEntry()) + _checkTimer += diff; + if (_checkTimer >= 4000) { - if (Creature* liquid = me->SummonCreature(NPC_LIQUID, *me)) + _checkTimer = 0; + if (Unit* target = me->SelectNearbyTarget(nullptr, 80.0f)) { - liquid->CastSpell(liquid, SPELL_LIQUID_PYRITE, true); - liquid->CastSpell(liquid, SPELL_DUST_CLOUD_IMPACT, true); + ++_amount; + if (Creature* cr = me->SummonCreature(NPC_DEFENDER_GENERATED, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 4, me->GetOrientation(), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900000)) + cr->AI()->AttackStart(target); } - - me->DespawnOrUnsummon(1ms); } } - - void UpdateAI(uint32 diff) override - { - _allowTimer += diff; - if (_allowTimer >= 5000 && !me->GetVehicle() && me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) - { - float x, y, z; - me->GetPosition(x, y, z); - z = me->GetMapHeight(x, y, z); - me->GetMotionMaster()->MovePoint(me->GetEntry(), x, y, z); - me->SetPosition(x, y, z, 0); - } - } - }; + } }; -class npc_mechanolift : public CreatureScript +struct boss_flame_leviathan_safety_container : public NullCreatureAI { -public: - npc_mechanolift() : CreatureScript("npc_mechanolift") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_flame_leviathan_safety_container(Creature* c) : NullCreatureAI(c) { - return GetUlduarAI(pCreature); + _allowTimer = 0; } - struct npc_mechanoliftAI : public NullCreatureAI + uint32 _allowTimer; + + void MovementInform(uint32 /*type*/, uint32 id) override { - npc_mechanoliftAI(Creature* c) : NullCreatureAI(c) + if (id == me->GetEntry()) { - me->SetSpeed(MOVE_RUN, rand_norm() + 0.5f); + if (Creature* liquid = me->SummonCreature(NPC_LIQUID, *me)) + { + liquid->CastSpell(liquid, SPELL_LIQUID_PYRITE, true); + liquid->CastSpell(liquid, SPELL_DUST_CLOUD_IMPACT, true); + } + + me->DespawnOrUnsummon(1ms); + } + } + + void UpdateAI(uint32 diff) override + { + _allowTimer += diff; + if (_allowTimer >= 5000 && !me->GetVehicle() && me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) + { + float x, y, z; + me->GetPosition(x, y, z); + z = me->GetMapHeight(x, y, z); + me->GetMotionMaster()->MovePoint(me->GetEntry(), x, y, z); + me->SetPosition(x, y, z, 0); + } + } +}; + +struct npc_mechanolift : public NullCreatureAI +{ + npc_mechanolift(Creature* c) : NullCreatureAI(c) + { + me->SetSpeed(MOVE_RUN, rand_norm() + 0.5f); + } + + int32 _startTimer; + uint32 _evadeTimer; + + void Reset() override + { + _startTimer = urand(1, 5000); + _evadeTimer = 0; + } + + void UpdateAI(uint32 diff) override + { + if (_startTimer) + { + _startTimer -= diff; + if (_startTimer <= 0) + { + me->GetMotionMaster()->MoveWaypoint(3000000 + urand(0, 11), true); + _startTimer = 0; + } } - int32 _startTimer; - uint32 _evadeTimer; - - void Reset() override + _evadeTimer += diff; + if (_evadeTimer >= 10000) { - _startTimer = urand(1, 5000); + _EnterEvadeMode(); _evadeTimer = 0; } - - void UpdateAI(uint32 diff) override - { - if (_startTimer) - { - _startTimer -= diff; - if (_startTimer <= 0) - { - me->GetMotionMaster()->MoveWaypoint(3000000 + urand(0, 11), true); - _startTimer = 0; - } - } - - _evadeTimer += diff; - if (_evadeTimer >= 10000) - { - _EnterEvadeMode(); - _evadeTimer = 0; - } - } - }; + } }; class go_ulduar_tower : public GameObjectScript @@ -2018,23 +1864,23 @@ public: void AddSC_boss_flame_leviathan() { - new boss_flame_leviathan(); - new boss_flame_leviathan_seat(); - new boss_flame_leviathan_defense_turret(); - new boss_flame_leviathan_overload_device(); - new npc_pool_of_tar(); + RegisterUlduarCreatureAI(boss_flame_leviathan); + RegisterUlduarCreatureAI(boss_flame_leviathan_seat); + RegisterUlduarCreatureAI(boss_flame_leviathan_defense_turret); + RegisterUlduarCreatureAI(boss_flame_leviathan_overload_device); + RegisterUlduarCreatureAI(npc_pool_of_tar); // Hard Mode - new npc_freya_ward(); - new npc_thorims_hammer(); - new npc_mimirons_inferno(); - new npc_hodirs_fury(); + RegisterUlduarCreatureAI(npc_freya_ward); + RegisterUlduarCreatureAI(npc_thorims_hammer); + RegisterUlduarCreatureAI(npc_mimirons_inferno); + RegisterUlduarCreatureAI(npc_hodirs_fury); // Helpers - new npc_brann_radio(); - new npc_storm_beacon_spawn(); - new boss_flame_leviathan_safety_container(); - new npc_mechanolift(); + RegisterUlduarCreatureAI(npc_brann_radio); + RegisterUlduarCreatureAI(npc_storm_beacon_spawn); + RegisterUlduarCreatureAI(boss_flame_leviathan_safety_container); + RegisterUlduarCreatureAI(npc_mechanolift); // GOs new go_ulduar_tower(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index 61841533b..cb3668d45 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -198,869 +198,763 @@ enum Misc CRITERIA_LUMBERJACKED = 21686, }; -class boss_freya : public CreatureScript +struct boss_freya : public BossAI { -public: - boss_freya() : CreatureScript("boss_freya") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_freya(Creature* pCreature) : BossAI(pCreature, BOSS_FREYA) { - return GetUlduarAI(pCreature); + if (!me->IsAlive()) + instance->SetBossState(BOSS_FREYA, DONE); } - struct boss_freyaAI : public ScriptedAI + uint8 _waveNumber; + uint8 _trioKilled; + uint8 _spawnedAmount; + uint8 _lumberjacked; + bool _respawningTrio; + bool _backToNature; + uint8 _deforestation; + + ObjectGuid _elderGUID[3]; + + void Reset() override { - boss_freyaAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me) + _Reset(); + + for (uint8 i = 0; i < 3; ++i) { - m_pInstance = pCreature->GetInstanceScript(); - if (!me->IsAlive()) - if (m_pInstance) - m_pInstance->SetData(TYPE_FREYA, DONE); + if (!_elderGUID[i]) + continue; + + if (Creature* elder = ObjectAccessor::GetCreature(*me, _elderGUID[i])) + elder->AI()->EnterEvadeMode(); + + _elderGUID[i].Clear(); } - InstanceScript* m_pInstance; - EventMap events; - SummonList summons; + _lumberjacked = 0; + _spawnedAmount = 0; + _trioKilled = 0; + _waveNumber = urand(1, 3); + _respawningTrio = false; + _backToNature = true; + _deforestation = 0; + } - uint8 _waveNumber; - uint8 _trioKilled; - uint8 _spawnedAmount; - uint8 _lumberjacked; - bool _respawningTrio; - bool _backToNature; - uint8 _deforestation; + void KilledUnit(Unit* victim) override + { + if (!victim->IsPlayer() || urand(0, 2)) + return; - ObjectGuid _elderGUID[3]; + Talk(SAY_SLAY); + } - void Reset() override + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (damage >= me->GetHealth()) { - if (m_pInstance && m_pInstance->GetData(TYPE_FREYA) != DONE) - m_pInstance->SetData(TYPE_FREYA, NOT_STARTED); + damage = 0; + if (instance->GetBossState(BOSS_FREYA) != DONE) + { + Talk(SAY_DEATH); - events.Reset(); - summons.DespawnAll(); + me->SetReactState(REACT_PASSIVE); + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetFaction(FACTION_FRIENDLY); + me->RemoveAllAuras(); + me->AttackStop(); + events.Reset(); + summons.DespawnAll(); + events.Reset(); + + uint8 _elderCount = 0; + for (uint8 i = 0; i < 3; ++i) + { + if (!_elderGUID[i]) + continue; + + if (Creature* e = ObjectAccessor::GetCreature(*me, _elderGUID[i])) + e->DespawnOrUnsummon(); + + ++_elderCount; + } + + uint32 chestId = RAID_MODE(GO_FREYA_CHEST, GO_FREYA_CHEST_HERO); + chestId -= 2 * _elderCount; // offset + + if (GameObject* go = me->SummonGameObject(chestId, 2345.61f, -71.20f, 425.104f, 3.0f, 0, 0, 0, 0, 0)) + { + go->ReplaceAllGameObjectFlags((GameObjectFlags)0); + go->SetLootRecipient(me->GetMap()); + } + + // Defeat credit + me->CastSpell(me, 65074, true); // credit + instance->SetBossState(BOSS_FREYA, DONE); + + scheduler.Schedule(14s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_TELEPORT); + }); + } + } + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_TELEPORT) + { + me->DespawnOrUnsummon(); + instance->SetData(EVENT_KEEPER_TELEPORTED, DONE); + } + } + + void JustSummoned(Creature* cr) override + { + if (cr->GetEntry() == NPC_FREYA_UNSTABLE_SUN_BEAM) + { + cr->CastSpell(cr, SPELL_UNSTABLE_SUN_VISUAL, true); + cr->CastSpell(cr, SPELL_UNSTABLE_SUN_FREYA_DAMAGE, true); + } + BossAI::JustSummoned(cr); + } + + void SpawnWave() + { + _waveNumber = _waveNumber == 1 ? 3 : _waveNumber - 1; + Talk(EMOTE_ALLIES_OF_NATURE); + + // Wave of three + if (_waveNumber == 1) + { + Talk(SAY_SUMMON_TRIO); + me->SummonCreature(NPC_ANCIENT_WATER_SPIRIT, me->GetPositionX() + urand(5, 15), me->GetPositionY() + urand(5, 15), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ())); + me->SummonCreature(NPC_STORM_LASHER, me->GetPositionX() + urand(5, 15), me->GetPositionY() + urand(5, 15), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ())); + me->SummonCreature(NPC_SNAPLASHER, me->GetPositionX() + urand(5, 15), me->GetPositionY() + urand(5, 15), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ())); + } + // Ancient Conservator + else if (_waveNumber == 2) + { + Talk(SAY_SUMMON_CONSERVATOR); + me->SummonCreature(NPC_ANCIENT_CONSERVATOR, me->GetPositionX() + urand(5, 15), me->GetPositionY() + urand(5, 15), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), 0, TEMPSUMMON_CORPSE_DESPAWN); + } + // Detonating Lashers + else if (_waveNumber == 3) + { + Talk(SAY_SUMMON_LASHERS); + for (uint8 i = 0; i < 10; ++i) + me->SummonCreature(NPC_DETONATING_LASHER, me->GetPositionX() + urand(5, 20), me->GetPositionY() + urand(5, 20), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), 0, TEMPSUMMON_CORPSE_DESPAWN); + } + } + + void DoAction(int32 param) override + { + if (param == ACTION_LUMBERJACKED) + { + ++_lumberjacked; + if (_lumberjacked == 1) + instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, CRITERIA_LUMBERJACKED); + else if (_lumberjacked == 3) + instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 65296 /*SPELL_LUMBERJACKED*/, 0, me); + return; + } + + if (param == ACTION_RESPAWN_TRIO) + { + if (!_respawningTrio) + { + _respawningTrio = true; + events.ScheduleEvent(EVENT_FREYA_RESPAWN_TRIO, 10s); + } + + ++_trioKilled; + return; + } + + // Deforestation Achievement Counter + if (param == ACTION_REMOVE_10_STACK) + { + ++_deforestation; + if (_deforestation >= 6) + instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_DEFORESTATION_CREDIT, 0, me); + // do not return + } + + if (Aura* aur = me->GetAura(SPELL_ATTUNED_TO_NATURE)) + { + // Back to Nature achievement + if (aur->GetStackAmount() - param < 25) + _backToNature = false; + + if (aur->GetStackAmount() > param) + aur->SetStackAmount(aur->GetStackAmount() - param); + else // Aura out of stack + { + events.ScheduleEvent(EVENT_FREYA_NATURE_BOMB, 5s); + events.SetPhase(EVENT_PHASE_FINAL); + aur->Remove(); + return; + } + } + } + + uint32 GetData(uint32 param) const override + { + if (param == DATA_GET_ELDER_COUNT) + { + uint8 _count = 0; for (uint8 i = 0; i < 3; ++i) - { - if (!_elderGUID[i]) - continue; + if (_elderGUID[i]) + ++_count; - if (Creature* elder = ObjectAccessor::GetCreature(*me, _elderGUID[i])) - elder->AI()->EnterEvadeMode(); + return _count; + } + if (param == DATA_BACK_TO_NATURE) + return _backToNature; - _elderGUID[i].Clear(); - } + return 0; + } - _lumberjacked = 0; - _spawnedAmount = 0; - _trioKilled = 0; - _waveNumber = urand(1, 3); - _respawningTrio = false; - _backToNature = true; - _deforestation = 0; + void JustReachedHome() override { _JustReachedHome(); me->setActive(false); } + + void JustEngagedWith(Unit*) override + { + me->setActive(true); + me->SetInCombatWithZone(); + me->CastSpell(me, SPELL_TOUCH_OF_EONAR, true); + if (Aura* aur = me->AddAura(SPELL_ATTUNED_TO_NATURE, me)) + aur->SetStackAmount(150); + + events.ScheduleEvent(EVENT_FREYA_ADDS_SPAM, 10s, 0, EVENT_PHASE_ADDS); + events.ScheduleEvent(EVENT_FREYA_LIFEBINDER, 30s); + events.ScheduleEvent(EVENT_FREYA_SUNBEAM, 17s); + events.ScheduleEvent(EVENT_FREYA_BERSERK, 10min); + events.SetPhase(EVENT_PHASE_ADDS); + + if (instance->GetBossState(BOSS_FREYA) != DONE) + instance->SetBossState(BOSS_FREYA, IN_PROGRESS); + + // HARD MODE CHECKS + Creature* elder = instance->GetCreature(DATA_ELDER_STONEBARK); + if (elder && elder->IsAlive()) + { + elder->CastSpell(elder, SPELL_DRAINED_OF_POWER, true); + elder->CastSpell(elder, SPELL_STONEBARK_ESSENCE, true); + elder->SetInCombatWithZone(); + + events.ScheduleEvent(EVENT_FREYA_GROUND_TREMOR, 35s); + _elderGUID[0] = elder->GetGUID(); } - void KilledUnit(Unit* victim) override + elder = instance->GetCreature(DATA_ELDER_IRONBRANCH); + if (elder && elder->IsAlive()) { - if (!victim->IsPlayer() || urand(0, 2)) - return; + elder->CastSpell(elder, SPELL_DRAINED_OF_POWER, true); + elder->CastSpell(elder, SPELL_IRONBRANCH_ESSENCE, true); + elder->SetInCombatWithZone(); - Talk(SAY_SLAY); + events.ScheduleEvent(EVENT_FREYA_IRON_ROOT, 20s); + _elderGUID[1] = elder->GetGUID(); } - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + elder = instance->GetCreature(DATA_ELDER_BRIGHTLEAF); + if (elder && elder->IsAlive()) { - if (damage >= me->GetHealth()) - { - damage = 0; - if (m_pInstance->GetData(TYPE_FREYA) != DONE) - { - Talk(SAY_DEATH); - - me->SetReactState(REACT_PASSIVE); - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetFaction(FACTION_FRIENDLY); - me->RemoveAllAuras(); - me->AttackStop(); - events.Reset(); - - summons.DespawnAll(); - events.Reset(); - - uint8 _elderCount = 0; - for (uint8 i = 0; i < 3; ++i) - { - if (!_elderGUID[i]) - continue; - - if (Creature* e = ObjectAccessor::GetCreature(*me, _elderGUID[i])) - e->DespawnOrUnsummon(); - - ++_elderCount; - } - - uint32 chestId = RAID_MODE(GO_FREYA_CHEST, GO_FREYA_CHEST_HERO); - chestId -= 2 * _elderCount; // offset - - if (GameObject* go = me->SummonGameObject(chestId, 2345.61f, -71.20f, 425.104f, 3.0f, 0, 0, 0, 0, 0)) - { - go->ReplaceAllGameObjectFlags((GameObjectFlags)0); - go->SetLootRecipient(me->GetMap()); - } - - // Defeat credit - if (m_pInstance) - { - me->CastSpell(me, 65074, true); // credit - m_pInstance->SetData(TYPE_FREYA, DONE); - } - - scheduler.Schedule(14s, [this](TaskContext /*context*/) - { - DoCastSelf(SPELL_TELEPORT); - }); - } - } - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_TELEPORT) - { - me->DespawnOrUnsummon(); - m_pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE); - } - } - - void JustSummoned(Creature* cr) override - { - if (cr->GetEntry() == NPC_FREYA_UNSTABLE_SUN_BEAM) - { - cr->CastSpell(cr, SPELL_UNSTABLE_SUN_VISUAL, true); - cr->CastSpell(cr, SPELL_UNSTABLE_SUN_FREYA_DAMAGE, true); - } - summons.Summon(cr); - } - - void SpawnWave() - { - _waveNumber = _waveNumber == 1 ? 3 : _waveNumber - 1; - Talk(EMOTE_ALLIES_OF_NATURE); - - // Wave of three - if (_waveNumber == 1) - { - Talk(SAY_SUMMON_TRIO); - me->SummonCreature(NPC_ANCIENT_WATER_SPIRIT, me->GetPositionX() + urand(5, 15), me->GetPositionY() + urand(5, 15), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ())); - me->SummonCreature(NPC_STORM_LASHER, me->GetPositionX() + urand(5, 15), me->GetPositionY() + urand(5, 15), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ())); - me->SummonCreature(NPC_SNAPLASHER, me->GetPositionX() + urand(5, 15), me->GetPositionY() + urand(5, 15), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ())); - } - // Ancient Conservator - else if (_waveNumber == 2) - { - Talk(SAY_SUMMON_CONSERVATOR); - me->SummonCreature(NPC_ANCIENT_CONSERVATOR, me->GetPositionX() + urand(5, 15), me->GetPositionY() + urand(5, 15), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), 0, TEMPSUMMON_CORPSE_DESPAWN); - } - // Detonating Lashers - else if (_waveNumber == 3) - { - Talk(SAY_SUMMON_LASHERS); - for (uint8 i = 0; i < 10; ++i) - me->SummonCreature(NPC_DETONATING_LASHER, me->GetPositionX() + urand(5, 20), me->GetPositionY() + urand(5, 20), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), 0, TEMPSUMMON_CORPSE_DESPAWN); - } - } - - void DoAction(int32 param) override - { - if (param == ACTION_LUMBERJACKED) - { - if (!m_pInstance) - return; - - ++_lumberjacked; - if (_lumberjacked == 1) - m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, CRITERIA_LUMBERJACKED); - else if (_lumberjacked == 3) - m_pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 65296 /*SPELL_LUMBERJACKED*/, 0, me); - return; - } - - if (param == ACTION_RESPAWN_TRIO) - { - if (!_respawningTrio) - { - _respawningTrio = true; - events.ScheduleEvent(EVENT_FREYA_RESPAWN_TRIO, 10s); - } - - ++_trioKilled; - return; - } - - // Deforestation Achievement Counter - if (param == ACTION_REMOVE_10_STACK) - { - ++_deforestation; - if (_deforestation >= 6 && m_pInstance) - m_pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_DEFORESTATION_CREDIT, 0, me); - // do not return - } - - if (Aura* aur = me->GetAura(SPELL_ATTUNED_TO_NATURE)) - { - // Back to Nature achievement - if (aur->GetStackAmount() - param < 25) - _backToNature = false; - - if (aur->GetStackAmount() > param) - aur->SetStackAmount(aur->GetStackAmount() - param); - else // Aura out of stack + elder->CastSpell(elder, SPELL_DRAINED_OF_POWER, true); + elder->CastSpell(elder, SPELL_BRIGHTLEAF_ESSENCE, true); + elder->SetInCombatWithZone(); + + events.ScheduleEvent(EVENT_FREYA_UNSTABLE_SUN_BEAM, 1min); + _elderGUID[2] = elder->GetGUID(); + } + + if (_elderGUID[0] || _elderGUID[1] || _elderGUID[2]) + { + Talk(SAY_AGGRO_WITH_ELDER); + } + else + { + Talk(SAY_AGGRO); + } + } + + void SpellHitTarget(Unit* target, SpellInfo const* spell) override + { + if (spell->Id == SPELL_NATURE_BOMB_FLIGHT) + me->SummonCreature(NPC_NATURE_BOMB, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); + } + + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_FREYA_ADDS_SPAM: + if (_spawnedAmount < 6) + SpawnWave(); + else if (me->GetAura(SPELL_ATTUNED_TO_NATURE)) { + me->RemoveAura(SPELL_ATTUNED_TO_NATURE); events.ScheduleEvent(EVENT_FREYA_NATURE_BOMB, 5s); events.SetPhase(EVENT_PHASE_FINAL); - aur->Remove(); return; } - } - } - - uint32 GetData(uint32 param) const override - { - if (param == DATA_GET_ELDER_COUNT) - { - uint8 _count = 0; - for (uint8 i = 0; i < 3; ++i) - if (_elderGUID[i]) - ++_count; - - return _count; - } - if (param == DATA_BACK_TO_NATURE) - return _backToNature; - - return 0; - } - - void JustReachedHome() override { me->setActive(false); } - - void JustEngagedWith(Unit*) override - { - me->setActive(true); - me->SetInCombatWithZone(); - me->CastSpell(me, SPELL_TOUCH_OF_EONAR, true); - if (Aura* aur = me->AddAura(SPELL_ATTUNED_TO_NATURE, me)) - aur->SetStackAmount(150); - - events.ScheduleEvent(EVENT_FREYA_ADDS_SPAM, 10s, 0, EVENT_PHASE_ADDS); - events.ScheduleEvent(EVENT_FREYA_LIFEBINDER, 30s); - events.ScheduleEvent(EVENT_FREYA_SUNBEAM, 17s); - events.ScheduleEvent(EVENT_FREYA_BERSERK, 10min); - events.SetPhase(EVENT_PHASE_ADDS); - - if (!m_pInstance) - return; - - if (m_pInstance->GetData(TYPE_FREYA) != DONE) - m_pInstance->SetData(TYPE_FREYA, IN_PROGRESS); - - // HARD MODE CHECKS - Creature* elder = ObjectAccessor::GetCreature(*me, m_pInstance->GetGuidData(NPC_ELDER_STONEBARK)); - if (elder && elder->IsAlive()) - { - elder->CastSpell(elder, SPELL_DRAINED_OF_POWER, true); - elder->CastSpell(elder, SPELL_STONEBARK_ESSENCE, true); - elder->SetInCombatWithZone(); - - events.ScheduleEvent(EVENT_FREYA_GROUND_TREMOR, 35s); - _elderGUID[0] = elder->GetGUID(); - } - - elder = ObjectAccessor::GetCreature(*me, m_pInstance->GetGuidData(NPC_ELDER_IRONBRANCH)); - if (elder && elder->IsAlive()) - { - elder->CastSpell(elder, SPELL_DRAINED_OF_POWER, true); - elder->CastSpell(elder, SPELL_IRONBRANCH_ESSENCE, true); - elder->SetInCombatWithZone(); - - events.ScheduleEvent(EVENT_FREYA_IRON_ROOT, 20s); - _elderGUID[1] = elder->GetGUID(); - } - - elder = ObjectAccessor::GetCreature(*me, m_pInstance->GetGuidData(NPC_ELDER_BRIGHTLEAF)); - if (elder && elder->IsAlive()) - { - elder->CastSpell(elder, SPELL_DRAINED_OF_POWER, true); - elder->CastSpell(elder, SPELL_BRIGHTLEAF_ESSENCE, true); - elder->SetInCombatWithZone(); - - events.ScheduleEvent(EVENT_FREYA_UNSTABLE_SUN_BEAM, 1min); - _elderGUID[2] = elder->GetGUID(); - } - - if (_elderGUID[0] || _elderGUID[1] || _elderGUID[2]) - { - Talk(SAY_AGGRO_WITH_ELDER); - } - else - { - Talk(SAY_AGGRO); - } - } - - void SpellHitTarget(Unit* target, SpellInfo const* spell) override - { - if (spell->Id == SPELL_NATURE_BOMB_FLIGHT) - me->SummonCreature(NPC_NATURE_BOMB, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); - } - - void UpdateAI(uint32 diff) override - { - scheduler.Update(diff); - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_FREYA_ADDS_SPAM: - if (_spawnedAmount < 6) - SpawnWave(); - else if (me->GetAura(SPELL_ATTUNED_TO_NATURE)) + _spawnedAmount++; + events.Repeat(1min); + break; + case EVENT_FREYA_LIFEBINDER: + { + Talk(EMOTE_LIFEBINDERS_GIFT); + events.Repeat(45s); + float x, y, z; + for (uint8 i = 0; i < 10; ++i) { - me->RemoveAura(SPELL_ATTUNED_TO_NATURE); - events.ScheduleEvent(EVENT_FREYA_NATURE_BOMB, 5s); - events.SetPhase(EVENT_PHASE_FINAL); - return; - } - _spawnedAmount++; - events.Repeat(1min); - break; - case EVENT_FREYA_LIFEBINDER: - { - Talk(EMOTE_LIFEBINDERS_GIFT); - events.Repeat(45s); - float x, y, z; - for (uint8 i = 0; i < 10; ++i) + x = me->GetPositionX() + urand(7, 25); + y = me->GetPositionY() + urand(7, 25); + z = me->GetMapHeight(x, y, me->GetPositionZ()); + if (me->IsWithinLOS(x, y, z)) { - x = me->GetPositionX() + urand(7, 25); - y = me->GetPositionY() + urand(7, 25); - z = me->GetMapHeight(x, y, me->GetPositionZ()); - if (me->IsWithinLOS(x, y, z)) - { - me->CastSpell(x, y, z, SPELL_SUMMON_LIFEBINDER, true); - return; - } + me->CastSpell(x, y, z, SPELL_SUMMON_LIFEBINDER, true); + return; } - - me->CastSpell(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), SPELL_SUMMON_LIFEBINDER, true); - break; } - case EVENT_FREYA_SUNBEAM: - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - me->CastSpell(target, SPELL_SUNBEAM, false); - events.Repeat(15s, 20s); - break; - case EVENT_FREYA_RESPAWN_TRIO: - _deforestation = 0; - _respawningTrio = false; - if (_trioKilled < 3) - summons.DoAction(ACTION_RESPAWN_TRIO); - _trioKilled = 0; + me->CastSpell(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), SPELL_SUMMON_LIFEBINDER, true); break; - case EVENT_FREYA_NATURE_BOMB: + } + case EVENT_FREYA_SUNBEAM: + if (Unit* target = SelectTarget(SelectTargetMethod::Random)) + me->CastSpell(target, SPELL_SUNBEAM, false); + events.Repeat(15s, 20s); + break; + case EVENT_FREYA_RESPAWN_TRIO: + _deforestation = 0; + _respawningTrio = false; + if (_trioKilled < 3) + summons.DoAction(ACTION_RESPAWN_TRIO); + + _trioKilled = 0; + break; + case EVENT_FREYA_NATURE_BOMB: + { + uint8 _minCount = me->GetMap()->Is25ManRaid() ? urand(7, 10) : urand(3, 4); + Map::PlayerList const& pList = me->GetMap()->GetPlayers(); + for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) { - uint8 _minCount = me->GetMap()->Is25ManRaid() ? urand(7, 10) : urand(3, 4); - Map::PlayerList const& pList = me->GetMap()->GetPlayers(); - for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) - { - if (me->GetDistance(itr->GetSource()) > 70 || !itr->GetSource()->IsAlive()) - continue; + if (me->GetDistance(itr->GetSource()) > 70 || !itr->GetSource()->IsAlive()) + continue; - me->CastSpell(itr->GetSource(), SPELL_NATURE_BOMB_FLIGHT, true); + me->CastSpell(itr->GetSource(), SPELL_NATURE_BOMB_FLIGHT, true); - if (!(--_minCount)) - break; - } - events.Repeat(18s); - break; + if (!(--_minCount)) + break; } - case EVENT_FREYA_BERSERK: - Talk(SAY_BERSERK); - me->CastSpell(me, SPELL_BERSERK, true); + events.Repeat(18s); break; - case EVENT_FREYA_GROUND_TREMOR: - Talk(EMOTE_GROUND_TREMOR); - me->CastSpell(me, SPELL_GROUND_TREMOR_FREYA, false); - events.Repeat(25s, 35s); - break; - case EVENT_FREYA_IRON_ROOT: - Talk(EMOTE_IRON_ROOTS); - me->CastCustomSpell(SPELL_IRON_ROOTS_FREYA, SPELLVALUE_MAX_TARGETS, 1, me, false); - events.Repeat(45s, 55s); - break; - case EVENT_FREYA_UNSTABLE_SUN_BEAM: + } + case EVENT_FREYA_BERSERK: + Talk(SAY_BERSERK); + me->CastSpell(me, SPELL_BERSERK, true); + break; + case EVENT_FREYA_GROUND_TREMOR: + Talk(EMOTE_GROUND_TREMOR); + me->CastSpell(me, SPELL_GROUND_TREMOR_FREYA, false); + events.Repeat(25s, 35s); + break; + case EVENT_FREYA_IRON_ROOT: + Talk(EMOTE_IRON_ROOTS); + me->CastCustomSpell(SPELL_IRON_ROOTS_FREYA, SPELLVALUE_MAX_TARGETS, 1, me, false); + events.Repeat(45s, 55s); + break; + case EVENT_FREYA_UNSTABLE_SUN_BEAM: + me->SummonCreature(NPC_FREYA_UNSTABLE_SUN_BEAM, me->GetPositionX() + urand(7, 25), me->GetPositionY() + urand(7, 25), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), 0, TEMPSUMMON_TIMED_DESPAWN, 10000); + if (Is25ManRaid()) + { me->SummonCreature(NPC_FREYA_UNSTABLE_SUN_BEAM, me->GetPositionX() + urand(7, 25), me->GetPositionY() + urand(7, 25), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), 0, TEMPSUMMON_TIMED_DESPAWN, 10000); - if (Is25ManRaid()) - { - me->SummonCreature(NPC_FREYA_UNSTABLE_SUN_BEAM, me->GetPositionX() + urand(7, 25), me->GetPositionY() + urand(7, 25), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), 0, TEMPSUMMON_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_FREYA_UNSTABLE_SUN_BEAM, me->GetPositionX() + urand(7, 25), me->GetPositionY() + urand(7, 25), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), 0, TEMPSUMMON_TIMED_DESPAWN, 10000); - } - events.Repeat(38s, 48s); - break; - } - - DoMeleeAttackIfReady(); + me->SummonCreature(NPC_FREYA_UNSTABLE_SUN_BEAM, me->GetPositionX() + urand(7, 25), me->GetPositionY() + urand(7, 25), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), 0, TEMPSUMMON_TIMED_DESPAWN, 10000); + } + events.Repeat(38s, 48s); + break; } - bool CheckEvadeIfOutOfCombatArea() const override - { - return me->GetPositionX() < 2135.0f; - } - }; -}; - -class boss_freya_elder_stonebark : public CreatureScript -{ -public: - boss_freya_elder_stonebark() : CreatureScript("boss_freya_elder_stonebark") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); + DoMeleeAttackIfReady(); } - struct boss_freya_elder_stonebarkAI : public ScriptedAI + bool CheckEvadeIfOutOfCombatArea() const override { - boss_freya_elder_stonebarkAI(Creature* pCreature) : ScriptedAI(pCreature) - { - } - - EventMap events; - uint8 _chargesCount; - - void Reset() override - { - events.Reset(); - _chargesCount = 0; - } - - void KilledUnit(Unit*) override - { - if (urand(0, 1)) - return; - - Talk(SAY_ELDER_SLAY); - } - - void JustDied(Unit* killer) override - { - if (killer && me->GetEntry() == killer->GetEntry()) - return; - Talk(SAY_ELDER_DEATH); - - // Lumberjacked - if (me->GetInstanceScript()) - if (Creature* freya = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_FREYA))) - freya->AI()->DoAction(ACTION_LUMBERJACKED); - } - - void JustEngagedWith(Unit*) override - { - events.ScheduleEvent(EVENT_STONEBARK_FISTS_OF_STONE, 40s); - events.ScheduleEvent(EVENT_STONEBARK_GROUND_TREMOR, 5s); - events.ScheduleEvent(EVENT_STONEBARK_PETRIFIED_BARK, 20s); - - if (!me->HasAura(SPELL_DRAINED_OF_POWER)) // Prevents speech if combat is initiated by hardmode activation - Talk(SAY_ELDER_AGGRO); - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType damageType, SpellSchoolMask damageSchoolMask) override - { - if ((damageType == DIRECT_DAMAGE || (damageType == SPELL_DIRECT_DAMAGE && damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL)) && _chargesCount) - { - --_chargesCount; - damage = 0; - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_STONEBARK_FISTS_OF_STONE: - me->CastSpell(me, SPELL_FISTS_OF_STONE, false); - events.Repeat(1min); - break; - case EVENT_STONEBARK_GROUND_TREMOR: - if (!me->HasAura(SPELL_FISTS_OF_STONE)) - me->CastSpell(me, SPELL_GROUND_TREMOR, false); - events.Repeat(20s); - break; - case EVENT_STONEBARK_PETRIFIED_BARK: - _chargesCount = RAID_MODE(60, 120); - me->CastSpell(me, SPELL_PETRIFIED_BARK, false); - events.Repeat(30s); - break; - } - - DoMeleeAttackIfReady(); - } - }; + return me->GetPositionX() < 2135.0f; + } }; -class boss_freya_elder_brightleaf : public CreatureScript +struct boss_freya_elder_stonebark : public ScriptedAI { -public: - boss_freya_elder_brightleaf() : CreatureScript("boss_freya_elder_brightleaf") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_freya_elder_stonebark(Creature* pCreature) : ScriptedAI(pCreature) { - return GetUlduarAI(pCreature); } - struct boss_freya_elder_brightleafAI : public ScriptedAI + EventMap events; + uint8 _chargesCount; + + void Reset() override { - boss_freya_elder_brightleafAI(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature) + events.Reset(); + _chargesCount = 0; + } + + void KilledUnit(Unit*) override + { + if (urand(0, 1)) + return; + + Talk(SAY_ELDER_SLAY); + } + + void JustDied(Unit* killer) override + { + if (killer && me->GetEntry() == killer->GetEntry()) + return; + Talk(SAY_ELDER_DEATH); + + // Lumberjacked + if (me->GetInstanceScript()) + if (Creature* freya = me->GetInstanceScript()->GetCreature(BOSS_FREYA)) + freya->AI()->DoAction(ACTION_LUMBERJACKED); + } + + void JustEngagedWith(Unit*) override + { + events.ScheduleEvent(EVENT_STONEBARK_FISTS_OF_STONE, 40s); + events.ScheduleEvent(EVENT_STONEBARK_GROUND_TREMOR, 5s); + events.ScheduleEvent(EVENT_STONEBARK_PETRIFIED_BARK, 20s); + + if (!me->HasAura(SPELL_DRAINED_OF_POWER)) // Prevents speech if combat is initiated by hardmode activation + Talk(SAY_ELDER_AGGRO); + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType damageType, SpellSchoolMask damageSchoolMask) override + { + if ((damageType == DIRECT_DAMAGE || (damageType == SPELL_DIRECT_DAMAGE && damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL)) && _chargesCount) { + --_chargesCount; + damage = 0; + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_STONEBARK_FISTS_OF_STONE: + me->CastSpell(me, SPELL_FISTS_OF_STONE, false); + events.Repeat(1min); + break; + case EVENT_STONEBARK_GROUND_TREMOR: + if (!me->HasAura(SPELL_FISTS_OF_STONE)) + me->CastSpell(me, SPELL_GROUND_TREMOR, false); + events.Repeat(20s); + break; + case EVENT_STONEBARK_PETRIFIED_BARK: + _chargesCount = RAID_MODE(60, 120); + me->CastSpell(me, SPELL_PETRIFIED_BARK, false); + events.Repeat(30s); + break; } - EventMap events; - SummonList summons; - - void Reset() override - { - events.Reset(); - summons.DespawnAll(); - } - - void KilledUnit(Unit*) override - { - if (urand(0, 1)) - return; - - Talk(SAY_ELDER_SLAY); - } - - void JustDied(Unit* killer) override - { - if (killer && me->GetEntry() == killer->GetEntry()) - return; - Talk(SAY_ELDER_DEATH); - - // Lumberjacked - if (me->GetInstanceScript()) - if (Creature* freya = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_FREYA))) - freya->AI()->DoAction(ACTION_LUMBERJACKED); - } - - void JustEngagedWith(Unit*) override - { - events.ScheduleEvent(EVENT_BRIGHTLEAF_FLUX, 10s); - events.ScheduleEvent(EVENT_BRIGHTLEAF_SOLAR_FLARE, 5s); - events.ScheduleEvent(EVENT_BRIGHTLEAF_UNSTABLE_SUN_BEAM, 8s); - - if (!me->HasAura(SPELL_DRAINED_OF_POWER)) // Prevents speech if combat is initiated by hardmode activation - Talk(SAY_ELDER_AGGRO); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_BRIGHTLEAF_FLUX: - if (Aura* aur = me->AddAura(SPELL_BRIGHTLEAF_FLUX, me)) - aur->SetStackAmount(urand(1, 10)); - events.Repeat(10s); - break; - case EVENT_BRIGHTLEAF_SOLAR_FLARE: - if (Aura* aur = me->GetAura(SPELL_BRIGHTLEAF_FLUX)) - { - me->CastCustomSpell(SPELL_SOLAR_FLARE, SPELLVALUE_MAX_TARGETS, aur->GetStackAmount(), me, false); - me->RemoveAura(aur); - } - events.Repeat(15s); - break; - case EVENT_BRIGHTLEAF_UNSTABLE_SUN_BEAM: - events.ScheduleEvent(EVENT_BRIGHTLEAF_DESPAWN_SUN_BEAM, 15s); - if (Creature* beam = me->SummonCreature(NPC_UNSTABLE_SUN_BRIGHTLEAF, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ())) - { - beam->CastSpell(beam, SPELL_UNSTABLE_SUN_BEAM_AURA, true); - beam->CastSpell(beam, SPELL_PHOTOSYNTHESIS, true); - summons.Summon(beam); - } - if (Creature* beam = me->SummonCreature(NPC_UNSTABLE_SUN_BRIGHTLEAF, me->GetPositionX() + 8, me->GetPositionY() + 8, me->GetPositionZ())) - { - beam->CastSpell(beam, SPELL_UNSTABLE_SUN_BEAM_AURA, true); - beam->CastSpell(beam, SPELL_PHOTOSYNTHESIS, true); - summons.Summon(beam); - } - events.Repeat(20s); - break; - case EVENT_BRIGHTLEAF_DESPAWN_SUN_BEAM: - for (SummonList::iterator i = summons.begin(); i != summons.end();) - { - Creature* summon = ObjectAccessor::GetCreature(*me, *i); - ++i; - if (summon) - summon->CastSpell(summon, SPELL_UNSTABLE_SUN_DAMAGE, false); - } - - summons.DespawnAll(); - break; - } - - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; -class boss_freya_elder_ironbranch : public CreatureScript +struct boss_freya_elder_brightleaf : public ScriptedAI { -public: - boss_freya_elder_ironbranch() : CreatureScript("boss_freya_elder_ironbranch") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_freya_elder_brightleaf(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature) { - return GetUlduarAI(pCreature); } - struct boss_freya_elder_ironbranchAI : public ScriptedAI + EventMap events; + SummonList summons; + + void Reset() override { - boss_freya_elder_ironbranchAI(Creature* pCreature) : ScriptedAI(pCreature) + events.Reset(); + summons.DespawnAll(); + } + + void KilledUnit(Unit*) override + { + if (urand(0, 1)) + return; + + Talk(SAY_ELDER_SLAY); + } + + void JustDied(Unit* killer) override + { + if (killer && me->GetEntry() == killer->GetEntry()) + return; + Talk(SAY_ELDER_DEATH); + + // Lumberjacked + if (me->GetInstanceScript()) + if (Creature* freya = me->GetInstanceScript()->GetCreature(BOSS_FREYA)) + freya->AI()->DoAction(ACTION_LUMBERJACKED); + } + + void JustEngagedWith(Unit*) override + { + events.ScheduleEvent(EVENT_BRIGHTLEAF_FLUX, 10s); + events.ScheduleEvent(EVENT_BRIGHTLEAF_SOLAR_FLARE, 5s); + events.ScheduleEvent(EVENT_BRIGHTLEAF_UNSTABLE_SUN_BEAM, 8s); + + if (!me->HasAura(SPELL_DRAINED_OF_POWER)) // Prevents speech if combat is initiated by hardmode activation + Talk(SAY_ELDER_AGGRO); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { + case EVENT_BRIGHTLEAF_FLUX: + if (Aura* aur = me->AddAura(SPELL_BRIGHTLEAF_FLUX, me)) + aur->SetStackAmount(urand(1, 10)); + events.Repeat(10s); + break; + case EVENT_BRIGHTLEAF_SOLAR_FLARE: + if (Aura* aur = me->GetAura(SPELL_BRIGHTLEAF_FLUX)) + { + me->CastCustomSpell(SPELL_SOLAR_FLARE, SPELLVALUE_MAX_TARGETS, aur->GetStackAmount(), me, false); + me->RemoveAura(aur); + } + events.Repeat(15s); + break; + case EVENT_BRIGHTLEAF_UNSTABLE_SUN_BEAM: + events.ScheduleEvent(EVENT_BRIGHTLEAF_DESPAWN_SUN_BEAM, 15s); + if (Creature* beam = me->SummonCreature(NPC_UNSTABLE_SUN_BRIGHTLEAF, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ())) + { + beam->CastSpell(beam, SPELL_UNSTABLE_SUN_BEAM_AURA, true); + beam->CastSpell(beam, SPELL_PHOTOSYNTHESIS, true); + summons.Summon(beam); + } + if (Creature* beam = me->SummonCreature(NPC_UNSTABLE_SUN_BRIGHTLEAF, me->GetPositionX() + 8, me->GetPositionY() + 8, me->GetPositionZ())) + { + beam->CastSpell(beam, SPELL_UNSTABLE_SUN_BEAM_AURA, true); + beam->CastSpell(beam, SPELL_PHOTOSYNTHESIS, true); + summons.Summon(beam); + } + events.Repeat(20s); + break; + case EVENT_BRIGHTLEAF_DESPAWN_SUN_BEAM: + for (SummonList::iterator i = summons.begin(); i != summons.end();) + { + Creature* summon = ObjectAccessor::GetCreature(*me, *i); + ++i; + if (summon) + summon->CastSpell(summon, SPELL_UNSTABLE_SUN_DAMAGE, false); + } + + summons.DespawnAll(); + break; } - EventMap events; - - void Reset() override - { - events.Reset(); - } - - void KilledUnit(Unit*) override - { - if (urand(0, 1)) - return; - - Talk(SAY_ELDER_SLAY); - } - - void JustDied(Unit* killer) override - { - if (killer && me->GetEntry() == killer->GetEntry()) - return; - Talk(SAY_ELDER_DEATH); - - // Lumberjacked - if (me->GetInstanceScript()) - if (Creature* freya = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_FREYA))) - freya->AI()->DoAction(ACTION_LUMBERJACKED); - } - - void JustEngagedWith(Unit*) override - { - events.ScheduleEvent(EVENT_IRONBRANCH_IMPALE, 10s); - events.ScheduleEvent(EVENT_IRONBRANCH_IRON_ROOT, 15s); - events.ScheduleEvent(EVENT_IRONBRANCH_THORN_SWARM, 3s); - - if (!me->HasAura(SPELL_DRAINED_OF_POWER)) // Prevents speech if combat is initiated by hardmode activation - Talk(SAY_ELDER_AGGRO); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_IRONBRANCH_IMPALE: - me->CastSpell(me->GetVictim(), SPELL_IMPALE, false); - events.Repeat(17s); - break; - case EVENT_IRONBRANCH_IRON_ROOT: - me->CastCustomSpell(SPELL_IRON_ROOTS, SPELLVALUE_MAX_TARGETS, 1, me, false); - events.Repeat(20s); - break; - case EVENT_IRONBRANCH_THORN_SWARM: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - me->CastSpell(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), SPELL_THORN_SWARM, false); - events.Repeat(14s); - break; - } - - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; -class boss_freya_iron_root : public CreatureScript +struct boss_freya_elder_ironbranch : public ScriptedAI { -public: - boss_freya_iron_root() : CreatureScript("boss_freya_iron_root") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_freya_elder_ironbranch(Creature* pCreature) : ScriptedAI(pCreature) { - return GetUlduarAI(pCreature); } - struct boss_freya_iron_rootAI : public NullCreatureAI + EventMap events; + + void Reset() override { - boss_freya_iron_rootAI(Creature* pCreature) : NullCreatureAI(pCreature) { } + events.Reset(); + } - void JustDied(Unit* /*killer*/) override + void KilledUnit(Unit*) override + { + if (urand(0, 1)) + return; + + Talk(SAY_ELDER_SLAY); + } + + void JustDied(Unit* killer) override + { + if (killer && me->GetEntry() == killer->GetEntry()) + return; + Talk(SAY_ELDER_DEATH); + + // Lumberjacked + if (me->GetInstanceScript()) + if (Creature* freya = me->GetInstanceScript()->GetCreature(BOSS_FREYA)) + freya->AI()->DoAction(ACTION_LUMBERJACKED); + } + + void JustEngagedWith(Unit*) override + { + events.ScheduleEvent(EVENT_IRONBRANCH_IMPALE, 10s); + events.ScheduleEvent(EVENT_IRONBRANCH_IRON_ROOT, 15s); + events.ScheduleEvent(EVENT_IRONBRANCH_THORN_SWARM, 3s); + + if (!me->HasAura(SPELL_DRAINED_OF_POWER)) // Prevents speech if combat is initiated by hardmode activation + Talk(SAY_ELDER_AGGRO); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - if (!me->IsSummon()) - return; - - if (Unit* target = ObjectAccessor::GetUnit(*me, me->ToTempSummon()->GetSummonerGUID())) - { - if (me->GetEntry() == NPC_IRON_ROOT_TRIGGER) // Iron Branch spell - target->RemoveAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_IRON_ROOTS_DAMAGE, me)); - else - target->RemoveAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_IRON_ROOTS_FREYA_DAMAGE, me)); - } + case EVENT_IRONBRANCH_IMPALE: + me->CastSpell(me->GetVictim(), SPELL_IMPALE, false); + events.Repeat(17s); + break; + case EVENT_IRONBRANCH_IRON_ROOT: + me->CastCustomSpell(SPELL_IRON_ROOTS, SPELLVALUE_MAX_TARGETS, 1, me, false); + events.Repeat(20s); + break; + case EVENT_IRONBRANCH_THORN_SWARM: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + me->CastSpell(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), SPELL_THORN_SWARM, false); + events.Repeat(14s); + break; } - }; + + DoMeleeAttackIfReady(); + } }; -class boss_freya_lifebinder : public CreatureScript +struct boss_freya_iron_root : public NullCreatureAI { -public: - boss_freya_lifebinder() : CreatureScript("boss_freya_lifebinder") { } + boss_freya_iron_root(Creature* pCreature) : NullCreatureAI(pCreature) { } - CreatureAI* GetAI(Creature* pCreature) const override + void JustDied(Unit* /*killer*/) override + { + if (!me->IsSummon()) + return; + + if (Unit* target = ObjectAccessor::GetUnit(*me, me->ToTempSummon()->GetSummonerGUID())) + { + if (me->GetEntry() == NPC_IRON_ROOT_TRIGGER) // Iron Branch spell + target->RemoveAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_IRON_ROOTS_DAMAGE, me)); + else + target->RemoveAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_IRON_ROOTS_FREYA_DAMAGE, me)); + } + } +}; + +struct boss_freya_lifebinder : public NullCreatureAI +{ + boss_freya_lifebinder(Creature* pCreature) : NullCreatureAI(pCreature) { - return GetUlduarAI(pCreature); } - struct boss_freya_lifebinderAI : public NullCreatureAI + uint32 _healTimer; + + void Reset() override { - boss_freya_lifebinderAI(Creature* pCreature) : NullCreatureAI(pCreature) - { - } + me->CastSpell(me, SPELL_LIFEBINDER_VISUAL, true); + me->CastSpell(me, SPELL_LIFEBINDER_PHERONOMES, true); + me->CastSpell(me, SPELL_AUTO_GROW, true); + _healTimer = 0; + } - uint32 _healTimer; - - void Reset() override + void UpdateAI(uint32 diff) override + { + _healTimer += diff; + if (_healTimer >= 12000) { - me->CastSpell(me, SPELL_LIFEBINDER_VISUAL, true); - me->CastSpell(me, SPELL_LIFEBINDER_PHERONOMES, true); - me->CastSpell(me, SPELL_AUTO_GROW, true); + me->RemoveAurasDueToSpell(SPELL_AUTO_GROW); + me->CastSpell(me, SPELL_LIFEBINDER_HEAL, true); + me->DespawnOrUnsummon(2s); _healTimer = 0; } - - void UpdateAI(uint32 diff) override - { - _healTimer += diff; - if (_healTimer >= 12000) - { - me->RemoveAurasDueToSpell(SPELL_AUTO_GROW); - me->CastSpell(me, SPELL_LIFEBINDER_HEAL, true); - me->DespawnOrUnsummon(2s); - _healTimer = 0; - } - } - }; + } }; -class boss_freya_healthy_spore : public CreatureScript +struct boss_freya_healthy_spore : public NullCreatureAI { -public: - boss_freya_healthy_spore() : CreatureScript("boss_freya_healthy_spore") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_freya_healthy_spore(Creature* pCreature) : NullCreatureAI(pCreature) { - return GetUlduarAI(pCreature); } - struct boss_freya_healthy_sporeAI : public NullCreatureAI + uint32 _despawnTimer; + + void Reset() override { - boss_freya_healthy_sporeAI(Creature* pCreature) : NullCreatureAI(pCreature) - { - } + me->CastSpell(me, SPELL_POTENT_PHEROMONES, true); + me->CastSpell(me, SPELL_HEALTHY_SPORE_VISUAL, true); + me->CastSpell(me, SPELL_AUTO_GROW, true); + _despawnTimer = 0; + } - uint32 _despawnTimer; - - void Reset() override + void UpdateAI(uint32 diff) override + { + _despawnTimer += diff; + if (_despawnTimer >= 22000) { - me->CastSpell(me, SPELL_POTENT_PHEROMONES, true); - me->CastSpell(me, SPELL_HEALTHY_SPORE_VISUAL, true); - me->CastSpell(me, SPELL_AUTO_GROW, true); + me->RemoveAurasDueToSpell(SPELL_AUTO_GROW); + me->DespawnOrUnsummon(2200ms); _despawnTimer = 0; } - - void UpdateAI(uint32 diff) override - { - _despawnTimer += diff; - if (_despawnTimer >= 22000) - { - me->RemoveAurasDueToSpell(SPELL_AUTO_GROW); - me->DespawnOrUnsummon(2200ms); - _despawnTimer = 0; - } - } - }; + } }; -class boss_freya_summons : public CreatureScript +struct boss_freya_summons : public ScriptedAI { -public: - boss_freya_summons() : CreatureScript("boss_freya_summons") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_freya_summons(Creature* pCreature) : ScriptedAI(pCreature) { - return GetUlduarAI(pCreature); + _isTrio = me->GetEntry() == NPC_ANCIENT_WATER_SPIRIT || me->GetEntry() == NPC_STORM_LASHER || me->GetEntry() == NPC_SNAPLASHER; + _hasDied = false; } - struct boss_freya_summonsAI : public ScriptedAI + EventMap events; + uint8 _stackCount; + bool _hasDied; + bool _isTrio; + + void Reset() override { - boss_freya_summonsAI(Creature* pCreature) : ScriptedAI(pCreature) - { - _freyaGUID = me->GetInstanceScript() ? me->GetInstanceScript()->GetGuidData(TYPE_FREYA) : ObjectGuid::Empty; - _isTrio = me->GetEntry() == NPC_ANCIENT_WATER_SPIRIT || me->GetEntry() == NPC_STORM_LASHER || me->GetEntry() == NPC_SNAPLASHER; - _hasDied = false; - } + _stackCount = 0; + events.Reset(); + if (Unit* target = SelectTargetFromPlayerList(70)) + AttackStart(target); + } - EventMap events; - ObjectGuid _freyaGUID; - uint8 _stackCount; - bool _hasDied; - bool _isTrio; - - void Reset() override + void JustDied(Unit* /*killer*/) override + { + if (InstanceScript* instance = me->GetInstanceScript()) { - _stackCount = 0; - events.Reset(); - if (Unit* target = SelectTargetFromPlayerList(70)) - AttackStart(target); - } - - void JustDied(Unit* /*killer*/) override - { - if (Creature* freya = ObjectAccessor::GetCreature(*me, _freyaGUID)) + if (Creature* freya = instance->GetCreature(BOSS_FREYA)) { if (!_hasDied) freya->AI()->DoAction(_stackCount); @@ -1071,153 +965,142 @@ public: _hasDied = true; } } - if (me->GetEntry() == NPC_DETONATING_LASHER) - me->CastSpell(me, SPELL_DETONATE, true); } - - void DoAction(int32 param) override - { - if (_isTrio && param == ACTION_RESPAWN_TRIO) - { - me->setDeathState(DeathState::JustRespawned); - Reset(); - } - } - - void JustEngagedWith(Unit*) override - { - if (me->GetEntry() == NPC_ANCIENT_CONSERVATOR) - { - me->CastSpell(me, SPELL_HEALTHY_SPORE_SUMMON, true); - events.ScheduleEvent(EVENT_ANCIENT_CONSERVATOR_GRIP, 6s); - events.ScheduleEvent(EVENT_ANCIENT_CONSERVATOR_NATURE_FURY, 14s); - _stackCount = ACTION_REMOVE_25_STACK; - } - else if (me->GetEntry() == NPC_ANCIENT_WATER_SPIRIT) - { - events.ScheduleEvent(EVENT_WATER_SPIRIT_CHARGE, 12s); - _stackCount = ACTION_REMOVE_10_STACK; - } - else if (me->GetEntry() == NPC_STORM_LASHER) - { - events.ScheduleEvent(EVENT_STORM_LASHER_LIGHTNING_LASH, 10s); - events.ScheduleEvent(EVENT_STORM_LASHER_STORMBOLT, 6s); - _stackCount = ACTION_REMOVE_10_STACK; - } - else if (me->GetEntry() == NPC_DETONATING_LASHER) - { - events.ScheduleEvent(EVENT_DETONATING_LASHER_FLAME_LASH, 10s); - _stackCount = ACTION_REMOVE_2_STACK; - } - else if (me->GetEntry() == NPC_SNAPLASHER) - { - me->CastSpell(me, SPELL_HARDENED_BARK, true); - _stackCount = ACTION_REMOVE_10_STACK; - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_ANCIENT_CONSERVATOR_NATURE_FURY: - me->CastSpell(me->GetVictim(), SPELL_NATURE_FURY, false); - events.Repeat(14s); - break; - case EVENT_ANCIENT_CONSERVATOR_GRIP: - me->CastSpell(me, SPELL_CONSERVATOR_GRIP, true); - break; - case EVENT_WATER_SPIRIT_CHARGE: - me->CastSpell(me, SPELL_TIDAL_WAVE_AURA, true); - me->CastSpell(me->GetVictim(), SPELL_TIDAL_WAVE, false); - events.Repeat(12s); - events.ScheduleEvent(EVENT_WATER_SPIRIT_DAMAGE, 3s); - break; - case EVENT_WATER_SPIRIT_DAMAGE: - me->CastSpell(me, SPELL_TIDAL_WAVE_DAMAGE, false); - break; - case EVENT_STORM_LASHER_LIGHTNING_LASH: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - me->CastSpell(target, SPELL_LIGHTNING_LASH, false); - events.Repeat(10s); - break; - case EVENT_STORM_LASHER_STORMBOLT: - me->CastSpell(me->GetVictim(), SPELL_STORMBOLT, false); - events.Repeat(6s); - break; - case EVENT_DETONATING_LASHER_FLAME_LASH: - me->CastSpell(me->GetVictim(), SPELL_FLAME_LASH, false); - DoResetThreatList(); - if (Unit* target = SelectTargetFromPlayerList(80)) - AttackStart(target); - else - me->DespawnOrUnsummon(1ms); - events.Repeat(10s); - break; - } - - DoMeleeAttackIfReady(); - } - }; -}; - -class boss_freya_nature_bomb : public CreatureScript -{ -public: - boss_freya_nature_bomb() : CreatureScript("boss_freya_nature_bomb") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); + if (me->GetEntry() == NPC_DETONATING_LASHER) + me->CastSpell(me, SPELL_DETONATE, true); } - struct boss_freya_nature_bombAI : public NullCreatureAI + void DoAction(int32 param) override { - boss_freya_nature_bombAI(Creature* pCreature) : NullCreatureAI(pCreature) + if (_isTrio && param == ACTION_RESPAWN_TRIO) { - _goGUID.Clear(); + me->setDeathState(DeathState::JustRespawned); + Reset(); + } + } + + void JustEngagedWith(Unit*) override + { + if (me->GetEntry() == NPC_ANCIENT_CONSERVATOR) + { + me->CastSpell(me, SPELL_HEALTHY_SPORE_SUMMON, true); + events.ScheduleEvent(EVENT_ANCIENT_CONSERVATOR_GRIP, 6s); + events.ScheduleEvent(EVENT_ANCIENT_CONSERVATOR_NATURE_FURY, 14s); + _stackCount = ACTION_REMOVE_25_STACK; + } + else if (me->GetEntry() == NPC_ANCIENT_WATER_SPIRIT) + { + events.ScheduleEvent(EVENT_WATER_SPIRIT_CHARGE, 12s); + _stackCount = ACTION_REMOVE_10_STACK; + } + else if (me->GetEntry() == NPC_STORM_LASHER) + { + events.ScheduleEvent(EVENT_STORM_LASHER_LIGHTNING_LASH, 10s); + events.ScheduleEvent(EVENT_STORM_LASHER_STORMBOLT, 6s); + _stackCount = ACTION_REMOVE_10_STACK; + } + else if (me->GetEntry() == NPC_DETONATING_LASHER) + { + events.ScheduleEvent(EVENT_DETONATING_LASHER_FLAME_LASH, 10s); + _stackCount = ACTION_REMOVE_2_STACK; + } + else if (me->GetEntry() == NPC_SNAPLASHER) + { + me->CastSpell(me, SPELL_HARDENED_BARK, true); + _stackCount = ACTION_REMOVE_10_STACK; + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_ANCIENT_CONSERVATOR_NATURE_FURY: + me->CastSpell(me->GetVictim(), SPELL_NATURE_FURY, false); + events.Repeat(14s); + break; + case EVENT_ANCIENT_CONSERVATOR_GRIP: + me->CastSpell(me, SPELL_CONSERVATOR_GRIP, true); + break; + case EVENT_WATER_SPIRIT_CHARGE: + me->CastSpell(me, SPELL_TIDAL_WAVE_AURA, true); + me->CastSpell(me->GetVictim(), SPELL_TIDAL_WAVE, false); + events.Repeat(12s); + events.ScheduleEvent(EVENT_WATER_SPIRIT_DAMAGE, 3s); + break; + case EVENT_WATER_SPIRIT_DAMAGE: + me->CastSpell(me, SPELL_TIDAL_WAVE_DAMAGE, false); + break; + case EVENT_STORM_LASHER_LIGHTNING_LASH: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + me->CastSpell(target, SPELL_LIGHTNING_LASH, false); + events.Repeat(10s); + break; + case EVENT_STORM_LASHER_STORMBOLT: + me->CastSpell(me->GetVictim(), SPELL_STORMBOLT, false); + events.Repeat(6s); + break; + case EVENT_DETONATING_LASHER_FLAME_LASH: + me->CastSpell(me->GetVictim(), SPELL_FLAME_LASH, false); + DoResetThreatList(); + if (Unit* target = SelectTargetFromPlayerList(80)) + AttackStart(target); + else + me->DespawnOrUnsummon(1ms); + events.Repeat(10s); + break; } - ObjectGuid _goGUID; - uint32 _explodeTimer; + DoMeleeAttackIfReady(); + } +}; - void Reset() override +struct boss_freya_nature_bomb : public NullCreatureAI +{ + boss_freya_nature_bomb(Creature* pCreature) : NullCreatureAI(pCreature) + { + _goGUID.Clear(); + } + + ObjectGuid _goGUID; + uint32 _explodeTimer; + + void Reset() override + { + me->SetObjectScale(0.5f); + me->CastSpell(me, SPELL_GREEN_BANISH_STATE, true); + + _explodeTimer = 0; + if (GameObject* go = me->SummonGameObject(194902 /*GO_NATURE_BOMB*/, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, 0, 0, 0, 0, 0)) + _goGUID = go->GetGUID(); + } + + uint32 Timer; + void UpdateAI(uint32 diff) override + { + _explodeTimer += diff; + if (_explodeTimer >= 11000) { - me->SetObjectScale(0.5f); - me->CastSpell(me, SPELL_GREEN_BANISH_STATE, true); - + me->CastSpell(me, SPELL_NATURE_BOMB_DAMAGE, false); + me->DespawnOrUnsummon(1s); _explodeTimer = 0; - if (GameObject* go = me->SummonGameObject(194902 /*GO_NATURE_BOMB*/, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, 0, 0, 0, 0, 0)) - _goGUID = go->GetGUID(); } - uint32 Timer; - void UpdateAI(uint32 diff) override + // Delay explosion a little, visual + if (_explodeTimer >= 5000 && _explodeTimer < 10000) { - _explodeTimer += diff; - if (_explodeTimer >= 11000) - { - me->CastSpell(me, SPELL_NATURE_BOMB_DAMAGE, false); - me->DespawnOrUnsummon(1s); - _explodeTimer = 0; - } - - // Delay explosion a little, visual - if (_explodeTimer >= 5000 && _explodeTimer < 10000) - { - _explodeTimer = 10000; - if (GameObject* go = me->GetMap()->GetGameObject(_goGUID)) - go->SetGoState(GO_STATE_ACTIVE); - } + _explodeTimer = 10000; + if (GameObject* go = me->GetMap()->GetGameObject(_goGUID)) + go->SetGoState(GO_STATE_ACTIVE); } - }; + } }; class achievement_freya_getting_back_to_nature : public AchievementCriteriaScript @@ -1253,15 +1136,15 @@ private: void AddSC_boss_freya() { - new boss_freya(); - new boss_freya_elder_stonebark(); - new boss_freya_elder_brightleaf(); - new boss_freya_elder_ironbranch(); - new boss_freya_iron_root(); - new boss_freya_lifebinder(); - new boss_freya_healthy_spore(); - new boss_freya_summons(); - new boss_freya_nature_bomb(); + RegisterUlduarCreatureAI(boss_freya); + RegisterUlduarCreatureAI(boss_freya_elder_stonebark); + RegisterUlduarCreatureAI(boss_freya_elder_brightleaf); + RegisterUlduarCreatureAI(boss_freya_elder_ironbranch); + RegisterUlduarCreatureAI(boss_freya_iron_root); + RegisterUlduarCreatureAI(boss_freya_lifebinder); + RegisterUlduarCreatureAI(boss_freya_healthy_spore); + RegisterUlduarCreatureAI(boss_freya_summons); + RegisterUlduarCreatureAI(boss_freya_nature_bomb); new achievement_freya_getting_back_to_nature(); new achievement_freya_knock_on_wood("achievement_freya_knock_on_wood", 1); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp index b71b583fe..1fed3825c 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp @@ -15,18 +15,14 @@ * with this program. If not, see . */ -#include "AccountMgr.h" #include "AchievementCriteriaScript.h" #include "AreaDefines.h" -#include "BanMgr.h" #include "CreatureScript.h" -#include "GameObjectScript.h" #include "PassiveAI.h" #include "Player.h" #include "ScriptedCreature.h" #include "SpellScript.h" #include "SpellScriptLoader.h" -#include "WorldSession.h" #include "ulduar.h" enum VezaxSpellData @@ -110,367 +106,307 @@ enum VaporsText SAY_EMOTE_VAPORS = 0, }; -class boss_vezax : public CreatureScript +struct boss_vezax : public BossAI { -public: - boss_vezax() : CreatureScript("boss_vezax") { } + boss_vezax(Creature* pCreature) : BossAI(pCreature, BOSS_VEZAX) { } - CreatureAI* GetAI(Creature* pCreature) const override + uint8 vaporsCount; + bool hardmodeAvailable; + bool berserk; + bool bAchievShadowdodger; + + void Reset() override { - return GetUlduarAI(pCreature); + _Reset(); + vaporsCount = 0; + hardmodeAvailable = true; + berserk = false; + bAchievShadowdodger = true; + me->SetLootMode(1); } - struct boss_vezaxAI : public ScriptedAI + void JustReachedHome() override { - boss_vezaxAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me) + _JustReachedHome(); + me->setActive(false); + } + + void JustEngagedWith(Unit* /*pWho*/) override + { + me->setActive(true); + _JustEngagedWith(); + + events.RescheduleEvent(EVENT_SPELL_VEZAX_SHADOW_CRASH, 13s); + events.RescheduleEvent(EVENT_SPELL_SEARING_FLAMES, 10s, 1); + events.RescheduleEvent(EVENT_SPELL_SURGE_OF_DARKNESS, 63s); + events.RescheduleEvent(EVENT_SPELL_MARK_OF_THE_FACELESS, 20s); + events.RescheduleEvent(EVENT_SPELL_SUMMON_SARONITE_VAPORS, 30s); + events.RescheduleEvent(EVENT_BERSERK, 10min); + + Talk(SAY_AGGRO); + + me->CastSpell(me, SPELL_AURA_OF_DESPAIR_1, true); + } + + void DoAction(int32 param) override + { + switch (param) { - pInstance = pCreature->GetInstanceScript(); + case 1: + hardmodeAvailable = false; + break; + case 2: + me->RemoveAura(SPELL_SARONITE_BARRIER); + me->SetLootMode(3); + break; } + } - EventMap events; - SummonList summons; - uint8 vaporsCount; - bool hardmodeAvailable; - bool berserk; - bool bAchievShadowdodger; - - InstanceScript* pInstance; - - void Reset() override + uint32 GetData(uint32 id) const override + { + switch (id) { - vaporsCount = 0; - hardmodeAvailable = true; - berserk = false; - bAchievShadowdodger = true; - events.Reset(); - summons.DespawnAll(); - me->SetLootMode(1); - - if (pInstance) - pInstance->SetData(TYPE_VEZAX, NOT_STARTED); + case 1: + return (me->GetLootMode() == 3 ? 1 : 0); + case 2: + return (bAchievShadowdodger ? 1 : 0); } + return 0; + } - void JustReachedHome() override + void SpellHitTarget(Unit* target, SpellInfo const* spell) override + { + if (target && spell && target->IsPlayer() && spell->Id == SPELL_VEZAX_SHADOW_CRASH_DMG) + bAchievShadowdodger = false; + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + if (!berserk && (me->GetPositionX() < 1720.0f || me->GetPositionX() > 1940.0f || me->GetPositionY() < 20.0f || me->GetPositionY() > 210.0f)) + events.RescheduleEvent(EVENT_BERSERK, 1ms); + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - me->setActive(false); - } - - void JustEngagedWith(Unit* /*pWho*/) override - { - me->setActive(true); - me->SetInCombatWithZone(); - - events.Reset(); - events.RescheduleEvent(EVENT_SPELL_VEZAX_SHADOW_CRASH, 13s); - events.RescheduleEvent(EVENT_SPELL_SEARING_FLAMES, 10s, 1); - events.RescheduleEvent(EVENT_SPELL_SURGE_OF_DARKNESS, 63s); - events.RescheduleEvent(EVENT_SPELL_MARK_OF_THE_FACELESS, 20s); - events.RescheduleEvent(EVENT_SPELL_SUMMON_SARONITE_VAPORS, 30s); - events.RescheduleEvent(EVENT_BERSERK, 10min); - - Talk(SAY_AGGRO); - - if (pInstance) - pInstance->SetData(TYPE_VEZAX, IN_PROGRESS); - - me->CastSpell(me, SPELL_AURA_OF_DESPAIR_1, true); - } - - void DoAction(int32 param) override - { - switch (param) - { - case 1: - hardmodeAvailable = false; - break; - case 2: - me->RemoveAura(SPELL_SARONITE_BARRIER); - me->SetLootMode(3); - break; - } - } - - uint32 GetData(uint32 id) const override - { - switch (id) - { - case 1: - return (me->GetLootMode() == 3 ? 1 : 0); - case 2: - return (bAchievShadowdodger ? 1 : 0); - } - return 0; - } - - void SpellHitTarget(Unit* target, SpellInfo const* spell) override - { - if (target && spell && target->IsPlayer() && spell->Id == SPELL_VEZAX_SHADOW_CRASH_DMG) - bAchievShadowdodger = false; - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (!berserk && (me->GetPositionX() < 1720.0f || me->GetPositionX() > 1940.0f || me->GetPositionY() < 20.0f || me->GetPositionY() > 210.0f)) - events.RescheduleEvent(EVENT_BERSERK, 1ms); - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_BERSERK: - berserk = true; - me->CastSpell(me, SPELL_VEZAX_BERSERK, true); - Talk(SAY_BERSERK); - break; - case EVENT_SPELL_VEZAX_SHADOW_CRASH: - { - events.Repeat(10s); - - std::vector players; - Map::PlayerList const& pl = me->GetMap()->GetPlayers(); - for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) - { - Player* temp = itr->GetSource(); - if (temp->IsAlive() && temp->GetDistance(me) > 15.0f ) - players.push_back(temp); - } - if (!players.empty()) - { - me->setAttackTimer(BASE_ATTACK, 2000); - Player* target = players.at(urand(0, players.size() - 1)); - me->SetGuidValue(UNIT_FIELD_TARGET, target->GetGUID()); - me->CastSpell(target, SPELL_VEZAX_SHADOW_CRASH, false); - events.ScheduleEvent(EVENT_RESTORE_TARGET, 750ms); - } - } - break; - case EVENT_RESTORE_TARGET: - if (me->GetVictim()) - me->SetGuidValue(UNIT_FIELD_TARGET, me->GetVictim()->GetGUID()); - break; - case EVENT_SPELL_SEARING_FLAMES: - if (!me->HasAura(SPELL_SARONITE_BARRIER)) - me->CastSpell(me->GetVictim(), SPELL_SEARING_FLAMES, false); - events.Repeat(me->GetMap()->Is25ManRaid() ? 8s : 15s); - break; - case EVENT_SPELL_SURGE_OF_DARKNESS: - Talk(SAY_SURGE_OF_DARKNESS); - Talk(SAY_EMOTE_SURGE_OF_DARKNESS); - me->CastSpell(me, SPELL_SURGE_OF_DARKNESS, false); - events.Repeat(63s); - events.DelayEvents(10s, 1); - break; - case EVENT_SPELL_MARK_OF_THE_FACELESS: - { - std::vector outside; - std::vector inside; - Map::PlayerList const& pl = me->GetMap()->GetPlayers(); - for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) - if (Player* tmp = itr->GetSource()) - if (tmp->IsAlive()) - { - if (tmp->GetDistance(me) > 15.0f ) - outside.push_back(tmp); - else - inside.push_back(tmp); - } - - Player* t = nullptr; - if (outside.size() >= uint8(me->GetMap()->Is25ManRaid() ? 9 : 4)) - t = outside.at(urand(0, outside.size() - 1)); - else if (!inside.empty()) - t = inside.at(urand(0, inside.size() - 1)); - - if (t) - me->CastSpell(t, SPELL_MARK_OF_THE_FACELESS_AURA, false); - - events.Repeat(40s); - } - break; - case EVENT_SPELL_SUMMON_SARONITE_VAPORS: - { - vaporsCount++; - me->CastSpell(me, SPELL_SUMMON_SARONITE_VAPORS, false); - - if (vaporsCount < 6 || !hardmodeAvailable) - events.Repeat(30s); - else - { - for (ObjectGuid const& guid : summons) - if (Creature* sv = ObjectAccessor::GetCreature(*me, guid)) - { - sv->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - sv->GetMotionMaster()->MoveIdle(); - sv->GetMotionMaster()->MoveCharge(1852.78f, 81.38f, 342.461f, 28.0f); - } - - events.DelayEvents(12s, 0); - events.DelayEvents(12s, 1); - events.ScheduleEvent(EVENT_SARONITE_VAPORS_SWIRL, 6s); - } - } - break; - case EVENT_SARONITE_VAPORS_SWIRL: - if (summons.size()) - { - Talk(SAY_EMOTE_ANIMUS); - if (Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin()))) - sv->CastSpell(sv, SPELL_SARONITE_ANIMUS_FORMATION_VISUAL, true); - - events.ScheduleEvent(EVENT_SPELL_SUMMON_SARONITE_ANIMUS, 2s); - break; - } - break; - case EVENT_SPELL_SUMMON_SARONITE_ANIMUS: - if (summons.size()) - { - Talk(SAY_HARDMODE); - Talk(SAY_EMOTE_BARRIER); - me->CastSpell(me, SPELL_SARONITE_BARRIER, true); - if (Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin()))) - sv->CastSpell(sv, SPELL_SUMMON_SARONITE_ANIMUS, true); - - events.ScheduleEvent(EVENT_DESPAWN_SARONITE_VAPORS, 2500ms); - break; - } - break; - case EVENT_DESPAWN_SARONITE_VAPORS: - summons.DespawnEntry(NPC_SARONITE_VAPORS); - break; - } - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) override - { - summons.DespawnAll(); - if (pInstance) - pInstance->SetData(TYPE_VEZAX, DONE); - - Talk(SAY_DEATH); - - if (GameObject* door = me->FindNearestGameObject(GO_VEZAX_DOOR, 500.0f)) - if (door->GetGoState() != GO_STATE_ACTIVE ) + case 0: + break; + case EVENT_BERSERK: + berserk = true; + me->CastSpell(me, SPELL_VEZAX_BERSERK, true); + Talk(SAY_BERSERK); + break; + case EVENT_SPELL_VEZAX_SHADOW_CRASH: { - door->SetLootState(GO_READY); - door->UseDoorOrButton(0, false); + events.Repeat(10s); + + std::vector players; + Map::PlayerList const& pl = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) + { + Player* temp = itr->GetSource(); + if (temp->IsAlive() && temp->GetDistance(me) > 15.0f) + players.push_back(temp); + } + if (!players.empty()) + { + me->setAttackTimer(BASE_ATTACK, 2000); + Player* target = players.at(urand(0, players.size() - 1)); + me->SetGuidValue(UNIT_FIELD_TARGET, target->GetGUID()); + me->CastSpell(target, SPELL_VEZAX_SHADOW_CRASH, false); + events.ScheduleEvent(EVENT_RESTORE_TARGET, 750ms); + } } + break; + case EVENT_RESTORE_TARGET: + if (me->GetVictim()) + me->SetGuidValue(UNIT_FIELD_TARGET, me->GetVictim()->GetGUID()); + break; + case EVENT_SPELL_SEARING_FLAMES: + if (!me->HasAura(SPELL_SARONITE_BARRIER)) + me->CastSpell(me->GetVictim(), SPELL_SEARING_FLAMES, false); + events.Repeat(me->GetMap()->Is25ManRaid() ? 8s : 15s); + break; + case EVENT_SPELL_SURGE_OF_DARKNESS: + Talk(SAY_SURGE_OF_DARKNESS); + Talk(SAY_EMOTE_SURGE_OF_DARKNESS); + me->CastSpell(me, SPELL_SURGE_OF_DARKNESS, false); + events.Repeat(63s); + events.DelayEvents(10s, 1); + break; + case EVENT_SPELL_MARK_OF_THE_FACELESS: + { + std::vector outside; + std::vector inside; + Map::PlayerList const& pl = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) + if (Player* tmp = itr->GetSource()) + if (tmp->IsAlive()) + { + if (tmp->GetDistance(me) > 15.0f) + outside.push_back(tmp); + else + inside.push_back(tmp); + } + + Player* t = nullptr; + if (outside.size() >= uint8(me->GetMap()->Is25ManRaid() ? 9 : 4)) + t = outside.at(urand(0, outside.size() - 1)); + else if (!inside.empty()) + t = inside.at(urand(0, inside.size() - 1)); + + if (t) + me->CastSpell(t, SPELL_MARK_OF_THE_FACELESS_AURA, false); + + events.Repeat(40s); + } + break; + case EVENT_SPELL_SUMMON_SARONITE_VAPORS: + { + vaporsCount++; + me->CastSpell(me, SPELL_SUMMON_SARONITE_VAPORS, false); + + if (vaporsCount < 6 || !hardmodeAvailable) + events.Repeat(30s); + else + { + for (ObjectGuid const& guid : summons) + if (Creature* sv = ObjectAccessor::GetCreature(*me, guid)) + { + sv->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + sv->GetMotionMaster()->MoveIdle(); + sv->GetMotionMaster()->MoveCharge(1852.78f, 81.38f, 342.461f, 28.0f); + } + + events.DelayEvents(12s, 0); + events.DelayEvents(12s, 1); + events.ScheduleEvent(EVENT_SARONITE_VAPORS_SWIRL, 6s); + } + } + break; + case EVENT_SARONITE_VAPORS_SWIRL: + if (summons.size()) + { + Talk(SAY_EMOTE_ANIMUS); + if (Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin()))) + sv->CastSpell(sv, SPELL_SARONITE_ANIMUS_FORMATION_VISUAL, true); + + events.ScheduleEvent(EVENT_SPELL_SUMMON_SARONITE_ANIMUS, 2s); + break; + } + break; + case EVENT_SPELL_SUMMON_SARONITE_ANIMUS: + if (summons.size()) + { + Talk(SAY_HARDMODE); + Talk(SAY_EMOTE_BARRIER); + me->CastSpell(me, SPELL_SARONITE_BARRIER, true); + if (Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin()))) + sv->CastSpell(sv, SPELL_SUMMON_SARONITE_ANIMUS, true); + + events.ScheduleEvent(EVENT_DESPAWN_SARONITE_VAPORS, 2500ms); + break; + } + break; + case EVENT_DESPAWN_SARONITE_VAPORS: + summons.DespawnEntry(NPC_SARONITE_VAPORS); + break; } - void KilledUnit(Unit* who) override - { - if (who->IsPlayer()) - Talk(SAY_SLAY); - } - - void MoveInLineOfSight(Unit* /*who*/) override {} - - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - } - - void SummonedCreatureDespawn(Creature* s) override - { - summons.Despawn(s); - } - }; -}; - -class npc_ulduar_saronite_vapors : public CreatureScript -{ -public: - npc_ulduar_saronite_vapors() : CreatureScript("npc_ulduar_saronite_vapors") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); + DoMeleeAttackIfReady(); } - struct npc_ulduar_saronite_vaporsAI : public NullCreatureAI + void JustDied(Unit* /*killer*/) override { - npc_ulduar_saronite_vaporsAI(Creature* pCreature) : NullCreatureAI(pCreature) - { - pInstance = pCreature->GetInstanceScript(); - me->GetMotionMaster()->MoveRandom(4.0f); - } + _JustDied(); + Talk(SAY_DEATH); - InstanceScript* pInstance; - - void JustDied(Unit* /*killer*/) override - { - me->CastSpell(me, SPELL_SARONITE_VAPORS_AURA, true); - - // killed saronite vapors, hard mode unavailable - if (pInstance) - if (Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX))) - vezax->AI()->DoAction(1); - } - - void IsSummonedBy(WorldObject* /*summoner*/) override - { - Talk(SAY_EMOTE_VAPORS); - } - }; -}; - -class npc_ulduar_saronite_animus : public CreatureScript -{ -public: - npc_ulduar_saronite_animus() : CreatureScript("npc_ulduar_saronite_animus") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct npc_ulduar_saronite_animusAI : public ScriptedAI - { - npc_ulduar_saronite_animusAI(Creature* pCreature) : ScriptedAI(pCreature) - { - pInstance = pCreature->GetInstanceScript(); - if (pInstance) - if (Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX))) - vezax->AI()->JustSummoned(me); - timer = 0; - me->SetInCombatWithZone(); - } - - InstanceScript* pInstance; - uint16 timer; - - void JustDied(Unit* /*killer*/) override - { - me->DespawnOrUnsummon(3s); - - if (pInstance) - if (Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX))) - vezax->AI()->DoAction(2); - } - - void UpdateAI(uint32 diff) override - { - UpdateVictim(); - - timer += diff; - if (timer >= 2000) + if (GameObject* door = me->FindNearestGameObject(GO_VEZAX_DOOR, 500.0f)) + if (door->GetGoState() != GO_STATE_ACTIVE) { - me->CastSpell(me, SPELL_PROFOUND_DARKNESS, true); - timer -= 2000; + door->SetLootState(GO_READY); + door->UseDoorOrButton(0, false); } + } - DoMeleeAttackIfReady(); + void KilledUnit(Unit* who) override + { + if (who->IsPlayer()) + Talk(SAY_SLAY); + } + + void MoveInLineOfSight(Unit* /*who*/) override {} +}; + +struct npc_ulduar_saronite_vapors : public NullCreatureAI +{ + npc_ulduar_saronite_vapors(Creature* pCreature) : NullCreatureAI(pCreature) + { + pInstance = pCreature->GetInstanceScript(); + me->GetMotionMaster()->MoveRandom(4.0f); + } + + InstanceScript* pInstance; + + void JustDied(Unit* /*killer*/) override + { + me->CastSpell(me, SPELL_SARONITE_VAPORS_AURA, true); + + // killed saronite vapors, hard mode unavailable + if (pInstance) + if (Creature* vezax = pInstance->GetCreature(BOSS_VEZAX)) + vezax->AI()->DoAction(1); + } + + void IsSummonedBy(WorldObject* /*summoner*/) override + { + Talk(SAY_EMOTE_VAPORS); + } +}; + +struct npc_ulduar_saronite_animus : public ScriptedAI +{ + npc_ulduar_saronite_animus(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = pCreature->GetInstanceScript(); + if (pInstance) + if (Creature* vezax = pInstance->GetCreature(BOSS_VEZAX)) + vezax->AI()->JustSummoned(me); + timer = 0; + me->SetInCombatWithZone(); + } + + InstanceScript* pInstance; + uint16 timer; + + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(3s); + + if (pInstance) + if (Creature* vezax = pInstance->GetCreature(BOSS_VEZAX)) + vezax->AI()->DoAction(2); + } + + void UpdateAI(uint32 diff) override + { + UpdateVictim(); + + timer += diff; + if (timer >= 2000) + { + me->CastSpell(me, SPELL_PROFOUND_DARKNESS, true); + timer -= 2000; } - }; + + DoMeleeAttackIfReady(); + } }; class spell_aura_of_despair_aura : public AuraScript @@ -630,34 +566,11 @@ public: } }; -class go_ulduar_pure_saronite_deposit : public GameObjectScript -{ -public: - go_ulduar_pure_saronite_deposit() : GameObjectScript("go_ulduar_pure_saronite_deposit") { } - - bool OnGossipHello(Player* plr, GameObject* go) override - { - if (plr->IsGameMaster()) - return false; - - if (InstanceScript* pInstance = go->GetInstanceScript()) - if (pInstance->GetData(TYPE_XT002) != DONE && pInstance->GetData(TYPE_MIMIRON) != DONE && pInstance->GetData(TYPE_THORIM) != DONE && pInstance->GetData(TYPE_FREYA) != DONE && pInstance->GetData(TYPE_HODIR) != DONE) - { - std::string accountName; - AccountMgr::GetName(plr->GetSession()->GetAccountId(), accountName); - sBan->BanAccount(accountName, "0s", "Tele hack", "Server"); - return true; - } - - return false; - } -}; - void AddSC_boss_vezax() { - new boss_vezax(); - new npc_ulduar_saronite_vapors(); - new npc_ulduar_saronite_animus(); + RegisterUlduarCreatureAI(boss_vezax); + RegisterUlduarCreatureAI(npc_ulduar_saronite_vapors); + RegisterUlduarCreatureAI(npc_ulduar_saronite_animus); RegisterSpellScript(spell_aura_of_despair_aura); RegisterSpellScript(spell_mark_of_the_faceless_periodic_aura); @@ -668,5 +581,4 @@ void AddSC_boss_vezax() new achievement_smell_saronite(); new achievement_shadowdodger(); - new go_ulduar_pure_saronite_deposit(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp index ae301a541..391a73146 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp @@ -197,987 +197,879 @@ HodirHelperData hhd[4][4] = } }; -class boss_hodir : public CreatureScript +struct boss_hodir : public BossAI { -public: - boss_hodir() : CreatureScript("boss_hodir") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_hodir(Creature* pCreature) : BossAI(pCreature, BOSS_HODIR) { - return GetUlduarAI(pCreature); + if (!me->IsAlive()) + instance->SetBossState(BOSS_HODIR, DONE); } - struct boss_hodirAI : public ScriptedAI + ObjectGuid Helpers[8]; + bool berserk{ false }; + bool bAchievCheese{ true }; + bool bAchievGettingCold{ true }; + bool bAchievCacheRare{ true }; + bool bAchievCoolestFriends{ true }; + uint16 addSpawnTimer{ 0 }; + + // Used to make Hodir disengage whenever he leaves his room + const Position ENTRANCE_DOOR{ 1999.160034f, -297.792999f, 431.960999f, 0 }; + const Position EXIT_DOOR{ 1999.709961f, -166.259003f, 432.822998f, 0 }; + + void Reset() override { - boss_hodirAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me) + _Reset(); + berserk = false; + bAchievCheese = true; + bAchievGettingCold = true; + bAchievCacheRare = true; + bAchievCoolestFriends = true; + me->SetSheath(SHEATH_STATE_MELEE); + + // Reset the spells cast after wipe + me->RemoveAllAuras(); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BITING_COLD_PLAYER_AURA); + + if (GameObject* go = me->FindNearestGameObject(GO_HODIR_FRONTDOOR, 900.0f)) { - pInstance = pCreature->GetInstanceScript(); - if (!me->IsAlive()) - if (pInstance) - pInstance->SetData(TYPE_HODIR, DONE); + go->SetGoState(GO_STATE_ACTIVE); } - InstanceScript* pInstance; - EventMap events; - SummonList summons; - ObjectGuid Helpers[8]; - bool berserk{ false }; - bool bAchievCheese{ true }; - bool bAchievGettingCold{ true }; - bool bAchievCacheRare{ true }; - bool bAchievCoolestFriends{ true }; - uint16 addSpawnTimer{ 0 }; + // Reset helpers + if (!summons.size()) + SpawnHelpers(); + } - // Used to make Hodir disengage whenever he leaves his room - const Position ENTRANCE_DOOR{ 1999.160034f, -297.792999f, 431.960999f, 0 }; - const Position EXIT_DOOR{ 1999.709961f, -166.259003f, 432.822998f, 0 }; + void JustEngagedWith(Unit* /*pWho*/) override + { + me->CastSpell(me, SPELL_BITING_COLD_BOSS_AURA, true); + SmallIcicles(true); + events.Reset(); + events.ScheduleEvent(EVENT_FLASH_FREEZE, 48s, 49s); + events.ScheduleEvent(EVENT_FREEZE, 17s, 20s); + events.ScheduleEvent(EVENT_BERSERK, 8min); + events.ScheduleEvent(EVENT_HARD_MODE_MISSED, 3min); + Talk(TEXT_AGGRO); - void Reset() override + if (instance->GetBossState(BOSS_HODIR) != DONE) { - events.Reset(); - summons.DespawnAll(); - berserk = false; - bAchievCheese = true; - bAchievGettingCold = true; - bAchievCacheRare = true; - bAchievCoolestFriends = true; - me->SetSheath(SHEATH_STATE_MELEE); - - // Reset the spells cast after wipe - me->RemoveAllAuras(); - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BITING_COLD_PLAYER_AURA); - - if (pInstance && pInstance->GetData(TYPE_HODIR) != DONE) - { - pInstance->SetData(TYPE_HODIR, NOT_STARTED); - } - - if (GameObject* go = me->FindNearestGameObject(GO_HODIR_FRONTDOOR, 900.0f)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - - // Reset helpers - if (!summons.size()) - SpawnHelpers(); + instance->SetBossState(BOSS_HODIR, IN_PROGRESS); } - void JustEngagedWith(Unit* /*pWho*/) override + if (GameObject* go = me->FindNearestGameObject(GO_HODIR_FRONTDOOR, 300.0f)) { - me->CastSpell(me, SPELL_BITING_COLD_BOSS_AURA, true); - SmallIcicles(true); - events.Reset(); - events.ScheduleEvent(EVENT_FLASH_FREEZE, 48s, 49s); - events.ScheduleEvent(EVENT_FREEZE, 17s, 20s); - events.ScheduleEvent(EVENT_BERSERK, 8min); - events.ScheduleEvent(EVENT_HARD_MODE_MISSED, 3min); - Talk(TEXT_AGGRO); - - if (pInstance && pInstance->GetData(TYPE_HODIR) != DONE) - { - pInstance->SetData(TYPE_HODIR, IN_PROGRESS); - } - - if (GameObject* go = me->FindNearestGameObject(GO_HODIR_FRONTDOOR, 300.0f)) - { - go->SetGoState(GO_STATE_READY); - } + go->SetGoState(GO_STATE_READY); } + } - void DoAction(int action) override + GameObject* GetHardmodeChest() + { + if (GameObject* go = instance->GetGameObject(DATA_HODIR_CHEST_HARD)) + return go; + return instance->GetGameObject(DATA_HODIR_CHEST_HARD_HERO); + } + + void DoAction(int action) override + { + if (action) { - if (action) + switch (action) { - switch (action) - { - case EVENT_FAIL_HM: - if (pInstance) - { - if (GameObject* go = pInstance->instance->GetGameObject(pInstance->GetGuidData(GO_HODIR_CHEST_HARD))) - { - go->SetGoState(GO_STATE_ACTIVE); - events.ScheduleEvent(EVENT_DESPAWN_CHEST, 3s); - } - } - break; - } - } - } - - void SmallIcicles(bool enable) - { - if (enable) - me->CastSpell(me, SPELL_ICICLE_BOSS_AURA, true); - else - me->RemoveAura(SPELL_ICICLE_BOSS_AURA); - } - - void SpellHitTarget(Unit* target, SpellInfo const* spell) override - { - switch (spell->Id) - { - case SPELL_ICICLE_TBBA: - me->CastSpell(target, SPELL_ICICLE_VISUAL_UNPACKED, true); - break; - case SPELL_FLASH_FREEZE_VISUAL: + case EVENT_FAIL_HM: + if (instance) { - std::list fires; - me->GetCreaturesWithEntryInRange(fires, 200.0f, NPC_TOASTY_FIRE); - for (std::list::iterator itr = fires.begin(); itr != fires.end(); ++itr) - (*itr)->AI()->DoAction(1); // remove it + if (GameObject* go = GetHardmodeChest()) + { + go->SetGoState(GO_STATE_ACTIVE); + events.ScheduleEvent(EVENT_DESPAWN_CHEST, 3s); + } } break; } } + } - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + void SmallIcicles(bool enable) + { + if (enable) + me->CastSpell(me, SPELL_ICICLE_BOSS_AURA, true); + else + me->RemoveAura(SPELL_ICICLE_BOSS_AURA); + } + + void SpellHitTarget(Unit* target, SpellInfo const* spell) override + { + switch (spell->Id) { - if (damage >= me->GetHealth() || me->GetHealth() < 150000) - { - damage = 0; - me->SetReactState(REACT_PASSIVE); - if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) + case SPELL_ICICLE_TBBA: + me->CastSpell(target, SPELL_ICICLE_VISUAL_UNPACKED, true); + break; + case SPELL_FLASH_FREEZE_VISUAL: { - if (pInstance) - { - pInstance->SetData(TYPE_HODIR, DONE); - me->CastSpell(me, 64899, true); // credit - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BITING_COLD_PLAYER_AURA); - } - - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetFaction(FACTION_FRIENDLY); - me->GetMotionMaster()->Clear(); - me->AttackStop(); - me->CombatStop(); - me->InterruptNonMeleeSpells(true); - me->RemoveAllAuras(); - - events.Reset(); - summons.DespawnAll(); - - if (GameObject* d = me->FindNearestGameObject(GO_HODIR_FROZEN_DOOR, 250.0f)) - { - if (d->GetGoState() != GO_STATE_ACTIVE ) - { - d->SetLootState(GO_READY); - d->UseDoorOrButton(0, false); - } - } - if (GameObject* d = me->FindNearestGameObject(GO_HODIR_DOOR, 250.0f)) - { - if (d->GetGoState() != GO_STATE_ACTIVE ) - { - d->SetLootState(GO_READY); - d->UseDoorOrButton(0, false); - } - } - - if (GameObject* go = me->FindNearestGameObject(GO_HODIR_FRONTDOOR, 300.0f)) - { - go->SetGoState(GO_STATE_ACTIVE); - } - - Talk(TEXT_DEATH); - scheduler.Schedule(14s, [this](TaskContext /*context*/) - { - DoCastSelf(SPELL_TELEPORT); - }); + std::list fires; + me->GetCreaturesWithEntryInRange(fires, 200.0f, NPC_TOASTY_FIRE); + for (std::list::iterator itr = fires.begin(); itr != fires.end(); ++itr) + (*itr)->AI()->DoAction(1); // remove it } + break; + } + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (damage >= me->GetHealth() || me->GetHealth() < 150000) + { + damage = 0; + me->SetReactState(REACT_PASSIVE); + if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) + { + if (instance) + { + instance->SetBossState(BOSS_HODIR, DONE); + me->CastSpell(me, 64899, true); // credit + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BITING_COLD_PLAYER_AURA); + } + + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetFaction(FACTION_FRIENDLY); + me->GetMotionMaster()->Clear(); + me->AttackStop(); + me->CombatStop(); + me->InterruptNonMeleeSpells(true); + me->RemoveAllAuras(); + + events.Reset(); + summons.DespawnAll(); + + if (GameObject* d = me->FindNearestGameObject(GO_HODIR_FROZEN_DOOR, 250.0f)) + { + if (d->GetGoState() != GO_STATE_ACTIVE ) + { + d->SetLootState(GO_READY); + d->UseDoorOrButton(0, false); + } + } + if (GameObject* d = me->FindNearestGameObject(GO_HODIR_DOOR, 250.0f)) + { + if (d->GetGoState() != GO_STATE_ACTIVE ) + { + d->SetLootState(GO_READY); + d->UseDoorOrButton(0, false); + } + } + + if (GameObject* go = me->FindNearestGameObject(GO_HODIR_FRONTDOOR, 300.0f)) + { + go->SetGoState(GO_STATE_ACTIVE); + } + + Talk(TEXT_DEATH); + scheduler.Schedule(14s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_TELEPORT); + }); } } + } - void UpdateAI(uint32 diff) override + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + if (me->GetPositionY() <= ENTRANCE_DOOR.GetPositionY() || me->GetPositionY() >= EXIT_DOOR.GetPositionY()) { - scheduler.Update(diff); - if (me->GetPositionY() <= ENTRANCE_DOOR.GetPositionY() || me->GetPositionY() >= EXIT_DOOR.GetPositionY()) - { - boss_hodirAI::EnterEvadeMode(); - return; - } + boss_hodir::EnterEvadeMode(); + return; + } - if (!UpdateVictim()) + if (!UpdateVictim()) + { + if (me->IsInCombat()) { - if (me->IsInCombat()) + Map::PlayerList const& pl = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) + itr->GetSource()->CastSpell(itr->GetSource(), SPELL_FLASH_FREEZE_INSTAKILL, true); + EnterEvadeMode(); + } + return; + } + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case 0: + break; + case EVENT_BERSERK: { + berserk = true; + me->CastSpell(me, SPELL_BERSERK, true); + Talk(TEXT_BERSERK); + } + break; + case EVENT_HARD_MODE_MISSED: + { + Talk(TEXT_HM_MISS); + bAchievCacheRare = false; + if (instance) + { + if (GameObject* go = GetHardmodeChest()) + me->CastSpell(go, SPELL_SHATTER_CHEST, false); + } + } + break; + case EVENT_DESPAWN_CHEST: + if (instance && instance->GetBossState(BOSS_HODIR) != DONE) + instance->SetData(TYPE_HODIR_HM_FAIL, 0); + break; + case EVENT_FLASH_FREEZE: + { + std::list targets; Map::PlayerList const& pl = me->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) - itr->GetSource()->CastSpell(itr->GetSource(), SPELL_FLASH_FREEZE_INSTAKILL, true); - EnterEvadeMode(); - } - return; - } + targets.push_back(itr->GetSource()); + targets.remove_if(Acore::ObjectTypeIdCheck(TYPEID_PLAYER, false)); + targets.remove_if(Acore::UnitAuraCheck(true, SPELL_FLASH_FREEZE_TRAPPED_PLAYER)); + Acore::Containers::RandomResize(targets, (RAID_MODE(2,3))); + for (std::list::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) + { + float prevZ = (*itr)->GetPositionZ(); + (*itr)->m_positionZ = 432.7f; + (*itr)->CastSpell((*itr), SPELL_ICICLE_VISUAL_PACKED, true); + (*itr)->m_positionZ = prevZ; + } - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_BERSERK: - { - berserk = true; - me->CastSpell(me, SPELL_BERSERK, true); - Talk(TEXT_BERSERK); - } - break; - case EVENT_HARD_MODE_MISSED: - { - Talk(TEXT_HM_MISS); - bAchievCacheRare = false; - if (pInstance) - { - if (GameObject* go = pInstance->instance->GetGameObject(pInstance->GetGuidData(GO_HODIR_CHEST_HARD))) - { - me->CastSpell(go, SPELL_SHATTER_CHEST, false); - } - } - } - break; - case EVENT_DESPAWN_CHEST: - if (pInstance && pInstance->GetData(TYPE_HODIR) != DONE) - pInstance->SetData(TYPE_HODIR_HM_FAIL, 0); - break; - case EVENT_FLASH_FREEZE: - { - std::list targets; - Map::PlayerList const& pl = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) - targets.push_back(itr->GetSource()); - targets.remove_if(Acore::ObjectTypeIdCheck(TYPEID_PLAYER, false)); - targets.remove_if(Acore::UnitAuraCheck(true, SPELL_FLASH_FREEZE_TRAPPED_PLAYER)); - Acore::Containers::RandomResize(targets, (RAID_MODE(2,3))); - for (std::list::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) - { - float prevZ = (*itr)->GetPositionZ(); - (*itr)->m_positionZ = 432.7f; - (*itr)->CastSpell((*itr), SPELL_ICICLE_VISUAL_PACKED, true); - (*itr)->m_positionZ = prevZ; - } - - me->CastSpell((Unit*)nullptr, SPELL_FLASH_FREEZE_CAST, false); - me->PlayDirectSound(SOUND_HODIR_FLASH_FREEZE, 0); - Talk(TEXT_FLASH_FREEZE); - Talk(TEXT_EMOTE_FREEZE); - SmallIcicles(false); - events.ScheduleEvent(EVENT_FLASH_FREEZE, 48s, 49s); - events.ScheduleEvent(EVENT_SMALL_ICICLES_ENABLE, Is25ManRaid() ? 12s : 24s); - events.ScheduleEvent(EVENT_FROZEN_BLOWS, 15s); - events.RescheduleEvent(EVENT_FREEZE, 17s, 20s); - } - break; - case EVENT_SMALL_ICICLES_ENABLE: - { - SmallIcicles(true); - } - break; - case EVENT_FROZEN_BLOWS: - { - Talk(TEXT_EMOTE_BLOW); - Talk(TEXT_STALACTITE); - me->CastSpell(me, SPELL_FROZEN_BLOWS, true); - } - break; - case EVENT_FREEZE: - if (Player* plr = SelectTargetFromPlayerList(50.0f, SPELL_FLASH_FREEZE_TRAPPED_PLAYER)) - { - me->CastSpell(plr, SPELL_FREEZE, false); - } - else if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) - { - me->CastSpell(target, SPELL_FREEZE, false); - } + me->CastSpell((Unit*)nullptr, SPELL_FLASH_FREEZE_CAST, false); + me->PlayDirectSound(SOUND_HODIR_FLASH_FREEZE, 0); + Talk(TEXT_FLASH_FREEZE); + Talk(TEXT_EMOTE_FREEZE); + SmallIcicles(false); + events.ScheduleEvent(EVENT_FLASH_FREEZE, 48s, 49s); + events.ScheduleEvent(EVENT_SMALL_ICICLES_ENABLE, Is25ManRaid() ? 12s : 24s); + events.ScheduleEvent(EVENT_FROZEN_BLOWS, 15s); events.RescheduleEvent(EVENT_FREEZE, 17s, 20s); - break; - } - - DoMeleeAttackIfReady(); - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_TELEPORT) - { - me->DespawnOrUnsummon(); - pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE); - } - } - - Creature* GetHelper(uint8 index) - { - return Helpers[index] ? ObjectAccessor::GetCreature(*me, Helpers[index]) : nullptr; - } - - void SpawnHelpers() - { - char faction = 'A'; - if (hhd[0][0].id) - { - Map::PlayerList const& cl = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = cl.begin(); itr != cl.end(); ++itr) - if (!itr->GetSource()->IsGameMaster()) - { - faction = (itr->GetSource()->GetTeamId() == TEAM_ALLIANCE ? 'A' : 'H'); - break; - } - } - - uint8 cnt = 0; - if (faction) - for( uint8 k = 0; k < 4; ++k ) + } + break; + case EVENT_SMALL_ICICLES_ENABLE: { - if ((faction == 'A' && ( k > 1 || (k == 1 && RAID_MODE(1, 0)))) || - (faction == 'H' && ( k < 2 || (k == 3 && RAID_MODE(1, 0))))) + SmallIcicles(true); + } + break; + case EVENT_FROZEN_BLOWS: + { + Talk(TEXT_EMOTE_BLOW); + Talk(TEXT_STALACTITE); + me->CastSpell(me, SPELL_FROZEN_BLOWS, true); + } + break; + case EVENT_FREEZE: + if (Player* plr = SelectTargetFromPlayerList(50.0f, SPELL_FLASH_FREEZE_TRAPPED_PLAYER)) + { + me->CastSpell(plr, SPELL_FREEZE, false); + } + else if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) + { + me->CastSpell(target, SPELL_FREEZE, false); + } + events.RescheduleEvent(EVENT_FREEZE, 17s, 20s); + break; + } + + DoMeleeAttackIfReady(); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_TELEPORT) + { + me->DespawnOrUnsummon(); + instance->SetData(EVENT_KEEPER_TELEPORTED, DONE); + } + } + + Creature* GetHelper(uint8 index) + { + return Helpers[index] ? ObjectAccessor::GetCreature(*me, Helpers[index]) : nullptr; + } + + void SpawnHelpers() + { + char faction = 'A'; + if (hhd[0][0].id) + { + Map::PlayerList const& cl = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = cl.begin(); itr != cl.end(); ++itr) + if (!itr->GetSource()->IsGameMaster()) + { + faction = (itr->GetSource()->GetTeamId() == TEAM_ALLIANCE ? 'A' : 'H'); + break; + } + } + + uint8 cnt = 0; + if (faction) + for( uint8 k = 0; k < 4; ++k ) + { + if ((faction == 'A' && ( k > 1 || (k == 1 && RAID_MODE(1, 0)))) || + (faction == 'H' && ( k < 2 || (k == 3 && RAID_MODE(1, 0))))) + continue; + + for( uint8 i = 0; i < 4; ++i ) + { + if (!hhd[k][i].id) continue; - for( uint8 i = 0; i < 4; ++i ) + if (Creature* h_p = me->SummonCreature(hhd[k][i].id, hhd[k][i].x, hhd[k][i].y, 432.69f, M_PI / 2)) { - if (!hhd[k][i].id) - continue; + h_p->SetFaction(1665); + if (cnt < 8) + Helpers[cnt++] = h_p->GetGUID(); - if (Creature* h_p = me->SummonCreature(hhd[k][i].id, hhd[k][i].x, hhd[k][i].y, 432.69f, M_PI / 2)) + if (Creature* c = h_p->SummonCreature(NPC_FLASH_FREEZE_NPC, h_p->GetPositionX(), h_p->GetPositionY(), h_p->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000)) { - h_p->SetFaction(1665); - if (cnt < 8) - Helpers[cnt++] = h_p->GetGUID(); - - if (Creature* c = h_p->SummonCreature(NPC_FLASH_FREEZE_NPC, h_p->GetPositionX(), h_p->GetPositionY(), h_p->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000)) - { - c->CastSpell(h_p, SPELL_FLASH_FREEZE_TRAPPED_NPC, true); - JustSummoned(c); - } + c->CastSpell(h_p, SPELL_FLASH_FREEZE_TRAPPED_NPC, true); + JustSummoned(c); } } } - } + } + } - void KilledUnit(Unit* who) override - { - if (who->IsPlayer()) - Talk(TEXT_SLAY); - } + void KilledUnit(Unit* who) override + { + if (who->IsPlayer()) + Talk(TEXT_SLAY); + } - void JustSummoned(Creature* s) override - { - summons.Summon(s); - } + bool CanAIAttack(Unit const* t) const override + { + if (t->IsPlayer()) + return !t->HasAura(SPELL_FLASH_FREEZE_TRAPPED_PLAYER); + else if (t->IsCreature()) + return !t->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC); - void SummonedCreatureDespawn(Creature* s) override - { - summons.Despawn(s); - } + return true; + } - bool CanAIAttack(Unit const* t) const override - { - if (t->IsPlayer()) - return !t->HasAura(SPELL_FLASH_FREEZE_TRAPPED_PLAYER); - else if (t->IsCreature()) - return !t->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC); - - return true; - } - - void SetData(uint32 id, uint32 value) override - { - if (value) - switch (id) - { - case 1: - bAchievCheese = false; - break; - case 2: - bAchievGettingCold = false; - break; - case 4: - bAchievCoolestFriends = false; - break; - } - } - - uint32 GetData(uint32 id) const override - { + void SetData(uint32 id, uint32 value) override + { + if (value) switch (id) { case 1: - return (bAchievCheese ? 1 : 0); + bAchievCheese = false; + break; case 2: - return (bAchievGettingCold ? 1 : 0); - case 3: - return (bAchievCacheRare ? 1 : 0); + bAchievGettingCold = false; + break; case 4: - return (bAchievCoolestFriends ? 1 : 0); + bAchievCoolestFriends = false; + break; } - return 0; - } - - void MoveInLineOfSight(Unit* /*who*/) override {} - }; -}; - -class npc_ulduar_icicle : public CreatureScript -{ -public: - npc_ulduar_icicle() : CreatureScript("npc_ulduar_icicle") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct npc_ulduar_icicleAI : public NullCreatureAI + uint32 GetData(uint32 id) const override { - npc_ulduar_icicleAI(Creature* pCreature) : NullCreatureAI(pCreature) + switch (id) { - timer1 = 2000; - timer2 = 5000; + case 1: + return (bAchievCheese ? 1 : 0); + case 2: + return (bAchievGettingCold ? 1 : 0); + case 3: + return (bAchievCacheRare ? 1 : 0); + case 4: + return (bAchievCoolestFriends ? 1 : 0); } - - uint16 timer1; - uint16 timer2; - - void UpdateAI(uint32 diff) override - { - if (timer1 <= diff) - { - me->CastSpell(me, (me->GetEntry() == 33169 ? SPELL_ICICLE_FALL_EFFECT_UNPACKED : SPELL_ICICLE_FALL_EFFECT_PACKED), true); - me->CastSpell(me, SPELL_ICICLE_VISUAL_FALLING, false); - timer1 = 60000; - } - else - timer1 -= diff; - - if (timer2 <= diff) - { - me->SetDisplayId(11686); - timer2 = 60000; - } - else - timer2 -= diff; - } - }; -}; - -class npc_ulduar_flash_freeze : public CreatureScript -{ -public: - npc_ulduar_flash_freeze() : CreatureScript("npc_ulduar_flash_freeze") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); + return 0; } - struct npc_ulduar_flash_freezeAI : public NullCreatureAI + void MoveInLineOfSight(Unit* /*who*/) override {} +}; + +struct npc_ulduar_icicle : public NullCreatureAI +{ + npc_ulduar_icicle(Creature* pCreature) : NullCreatureAI(pCreature) { - npc_ulduar_flash_freezeAI(Creature* pCreature) : NullCreatureAI(pCreature) + timer1 = 2000; + timer2 = 5000; + } + + uint16 timer1; + uint16 timer2; + + void UpdateAI(uint32 diff) override + { + if (timer1 <= diff) + { + me->CastSpell(me, (me->GetEntry() == 33169 ? SPELL_ICICLE_FALL_EFFECT_UNPACKED : SPELL_ICICLE_FALL_EFFECT_PACKED), true); + me->CastSpell(me, SPELL_ICICLE_VISUAL_FALLING, false); + timer1 = 60000; + } + else + timer1 -= diff; + + if (timer2 <= diff) + { + me->SetDisplayId(11686); + timer2 = 60000; + } + else + timer2 -= diff; + } +}; + +struct npc_ulduar_flash_freeze : public NullCreatureAI +{ + npc_ulduar_flash_freeze(Creature* pCreature) : NullCreatureAI(pCreature) + { + timer = 2500; + pInstance = me->GetInstanceScript(); + } + + InstanceScript* pInstance; + uint16 timer; + + void DamageTaken(Unit* doneBy, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override + { + if (pInstance && doneBy) + if (pInstance->GetBossState(BOSS_HODIR) == NOT_STARTED) + if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR)) + hodir->AI()->AttackStart(doneBy); + } + + void UpdateAI(uint32 diff) override + { + if (timer <= diff) { timer = 2500; - pInstance = me->GetInstanceScript(); - } - - InstanceScript* pInstance; - uint16 timer; - - void DamageTaken(Unit* doneBy, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override - { - if (pInstance && doneBy) - if (pInstance->GetData(TYPE_HODIR) == NOT_STARTED) - if (Creature* hodir = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_HODIR))) - hodir->AI()->AttackStart(doneBy); - } - - void UpdateAI(uint32 diff) override - { - if (timer <= diff) + if (me->IsSummon()) { - timer = 2500; - if (me->IsSummon()) + if (Unit* s = me->ToTempSummon()->GetSummonerUnit()) { - if (Unit* s = me->ToTempSummon()->GetSummonerUnit()) - { - if ((s->IsPlayer() && !s->HasAura(SPELL_FLASH_FREEZE_TRAPPED_PLAYER)) || (s->IsCreature() && !s->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC))) - me->DespawnOrUnsummon(2s); - else if (s->IsPlayer()) - if (InstanceScript* instanceScript = me->GetInstanceScript()) - if (instanceScript->GetData(TYPE_HODIR) == NOT_STARTED) - { - s->CastSpell(s, SPELL_FLASH_FREEZE_INSTAKILL, true); - me->DespawnOrUnsummon(2s); - } - } - else - { + if ((s->IsPlayer() && !s->HasAura(SPELL_FLASH_FREEZE_TRAPPED_PLAYER)) || (s->IsCreature() && !s->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC))) me->DespawnOrUnsummon(2s); - } - } - } - else - timer -= diff; - } - }; -}; - -class npc_ulduar_toasty_fire : public CreatureScript -{ -public: - npc_ulduar_toasty_fire() : CreatureScript("npc_ulduar_toasty_fire") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct npc_ulduar_toasty_fireAI : public NullCreatureAI - { - npc_ulduar_toasty_fireAI(Creature* pCreature) : NullCreatureAI(pCreature) - { - me->CastSpell(me, SPELL_MAGE_TOASTY_FIRE_AURA, true); - } - - void DoAction(int32 a) override - { - if (a == 1) - { - if (GameObject* fire = me->FindNearestGameObject(194300, 1.0f)) - { - fire->SetOwnerGUID(ObjectGuid::Empty); - fire->Delete(); - } - me->DespawnOrUnsummon(); // this will remove DynObjects - } - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - switch (spell->Id) - { - case SPELL_ICE_SHARDS_SMALL: - case SPELL_ICE_SHARDS_BIG: - DoAction(1); - break; - } - } - }; -}; - -class npc_ulduar_hodir_priest : public CreatureScript -{ -public: - npc_ulduar_hodir_priest() : CreatureScript("npc_ulduar_hodir_priest") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct npc_ulduar_hodir_priestAI : public ScriptedAI - { - npc_ulduar_hodir_priestAI(Creature* pCreature) : ScriptedAI(pCreature) - { - pInstance = me->GetInstanceScript(); - events.Reset(); - me->SetReactState(REACT_PASSIVE); - } - - EventMap events; - InstanceScript* pInstance; - - void AttackStart(Unit* who) override - { - AttackStartCaster(who, 17.0f); - } - - void ScheduleAbilities() - { - events.ScheduleEvent(EVENT_PRIEST_DISPELL_MAGIC, 7s); - events.ScheduleEvent(EVENT_PRIEST_GREAT_HEAL, 6s, 7s); - events.ScheduleEvent(EVENT_PRIEST_SMITE, 2100ms); - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - if (spell->Id == SPELL_FLASH_FREEZE_TRAPPED_NPC) - { - events.Reset(); - events.ScheduleEvent(EVENT_TRY_FREE_HELPER, 2s); - } - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_TRY_FREE_HELPER: - { - if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC)) - if (pInstance) - if (ObjectGuid g = pInstance->GetGuidData(TYPE_HODIR)) - if (Creature* hodir = ObjectAccessor::GetCreature(*me, g)) - { - AttackStart(hodir); - ScheduleAbilities(); - break; - } - events.Repeat(2s); - } - break; - case EVENT_PRIEST_DISPELL_MAGIC: - me->CastCustomSpell(SPELL_PRIEST_DISPELL_MAGIC, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false); - events.Repeat(7s); - break; - case EVENT_PRIEST_GREAT_HEAL: - me->CastSpell(me, SPELL_PRIEST_GREAT_HEAL, false); - events.Repeat(6s, 7s); - break; - case EVENT_PRIEST_SMITE: - if (Unit* victim = me->GetVictim()) - me->CastSpell(victim, SPELL_PRIEST_SMITE, false); - events.Repeat(2100ms); - break; - } - } - - void MoveInLineOfSight(Unit* /*who*/) override {} - - void EnterEvadeMode(EvadeReason /*why*/) override {} - bool CanAIAttack(Unit const* t) const override { return t->GetEntry() == NPC_HODIR; } - - void JustDied(Unit* /*killer*/) override - { - if (pInstance) - if (Creature* hodir = pInstance->instance->GetCreature(pInstance->GetGuidData(TYPE_HODIR))) - hodir->AI()->SetData(4, 1); - } - }; -}; - -class npc_ulduar_hodir_druid : public CreatureScript -{ -public: - npc_ulduar_hodir_druid() : CreatureScript("npc_ulduar_hodir_druid") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct npc_ulduar_hodir_druidAI : public ScriptedAI - { - npc_ulduar_hodir_druidAI(Creature* pCreature) : ScriptedAI(pCreature) - { - pInstance = me->GetInstanceScript(); - events.Reset(); - me->SetReactState(REACT_PASSIVE); - } - - EventMap events; - InstanceScript* pInstance; - - void AttackStart(Unit* who) override - { - AttackStartCaster(who, 22.0f); - } - - void ScheduleAbilities() - { - events.ScheduleEvent(EVENT_DRUID_WRATH, 1600ms); - events.ScheduleEvent(EVENT_DRUID_STARLIGHT, 10s); - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - if (spell->Id == SPELL_FLASH_FREEZE_TRAPPED_NPC) - { - events.Reset(); - events.ScheduleEvent(EVENT_TRY_FREE_HELPER, 2s); - } - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_TRY_FREE_HELPER: - { - if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC)) - if (pInstance) - if (ObjectGuid g = pInstance->GetGuidData(TYPE_HODIR)) - if (Creature* hodir = ObjectAccessor::GetCreature(*me, g)) - { - AttackStart(hodir); - ScheduleAbilities(); - break; - } - events.Repeat(2s); - } - break; - case EVENT_DRUID_WRATH: - if (Unit* victim = me->GetVictim()) - me->CastSpell(victim, SPELL_DRUID_WRATH, false); - events.Repeat(1600ms); - break; - case EVENT_DRUID_STARLIGHT: - if (me->GetPositionZ() < 433.0f) // ensure npc is on the ground - { - me->CastSpell(me, SPELL_DRUID_STARLIGHT_AREA_AURA, false); - events.Repeat(15s); - break; - } - events.Repeat(3s); - break; - } - } - - void MoveInLineOfSight(Unit* /*who*/) override {} - - void EnterEvadeMode(EvadeReason /*why*/) override {} - bool CanAIAttack(Unit const* t) const override { return t->GetEntry() == NPC_HODIR; } - - void JustDied(Unit* /*killer*/) override - { - if (pInstance) - if (Creature* hodir = pInstance->instance->GetCreature(pInstance->GetGuidData(TYPE_HODIR))) - hodir->AI()->SetData(4, 1); - } - }; -}; - -class npc_ulduar_hodir_shaman : public CreatureScript -{ -public: - npc_ulduar_hodir_shaman() : CreatureScript("npc_ulduar_hodir_shaman") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct npc_ulduar_hodir_shamanAI : public ScriptedAI - { - npc_ulduar_hodir_shamanAI(Creature* pCreature) : ScriptedAI(pCreature) - { - pInstance = me->GetInstanceScript(); - events.Reset(); - me->SetReactState(REACT_PASSIVE); - } - - EventMap events; - InstanceScript* pInstance; - - void AttackStart(Unit* who) override - { - AttackStartCaster(who, 25.0f); - } - - void ScheduleAbilities() - { - events.ScheduleEvent(EVENT_SHAMAN_LAVA_BURST, 2600ms); - events.ScheduleEvent(EVENT_SHAMAN_STORM_CLOUD, 10s); - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - if (spell->Id == SPELL_FLASH_FREEZE_TRAPPED_NPC) - { - events.Reset(); - events.ScheduleEvent(EVENT_TRY_FREE_HELPER, 2s); - } - } - - void SpellHitTarget(Unit* target, SpellInfo const* spell) override - { - uint32 spellid = sSpellMgr->GetSpellIdForDifficulty(SPELL_SHAMAN_STORM_CLOUD, me); - if (target && spell->Id == spellid) - if (Aura* a = target->GetAura(spellid, me->GetGUID())) - a->SetStackAmount(spell->StackAmount); - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_TRY_FREE_HELPER: - { - if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC)) - if (pInstance) - if (ObjectGuid g = pInstance->GetGuidData(TYPE_HODIR)) - if (Creature* hodir = ObjectAccessor::GetCreature(*me, g)) - { - AttackStart(hodir); - ScheduleAbilities(); - break; - } - events.Repeat(2s); - } - break; - case EVENT_SHAMAN_LAVA_BURST: - if (Unit* victim = me->GetVictim()) - me->CastSpell(victim, SPELL_SHAMAN_LAVA_BURST, false); - events.Repeat(2600ms); - break; - case EVENT_SHAMAN_STORM_CLOUD: - { - uint32 spellid = sSpellMgr->GetSpellIdForDifficulty(SPELL_SHAMAN_STORM_CLOUD, me); - if (Player* target = ScriptedAI::SelectTargetFromPlayerList(35.0f, spellid)) - me->CastSpell(target, spellid, false); - events.Repeat(30s); - break; - } - } - } - - void MoveInLineOfSight(Unit* /*who*/) override {} - - void EnterEvadeMode(EvadeReason /*why*/) override {} - bool CanAIAttack(Unit const* t) const override { return t->GetEntry() == NPC_HODIR; } - - void JustDied(Unit* /*killer*/) override - { - if (pInstance) - if (Creature* hodir = pInstance->instance->GetCreature(pInstance->GetGuidData(TYPE_HODIR))) - hodir->AI()->SetData(4, 1); - } - }; -}; - -class npc_ulduar_hodir_mage : public CreatureScript -{ -public: - npc_ulduar_hodir_mage() : CreatureScript("npc_ulduar_hodir_mage") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct npc_ulduar_hodir_mageAI : public ScriptedAI - { - npc_ulduar_hodir_mageAI(Creature* pCreature) : ScriptedAI(pCreature) - { - pInstance = me->GetInstanceScript(); - events.Reset(); - me->SetReactState(REACT_PASSIVE); - } - - EventMap events; - InstanceScript* pInstance; - - void AttackStart(Unit* who) override - { - AttackStartCaster(who, 30.0f); - } - - void ScheduleAbilities() - { - events.ScheduleEvent(EVENT_MAGE_FIREBALL, 3100ms); - events.ScheduleEvent(EVENT_MAGE_TOASTY_FIRE, 6s); - events.ScheduleEvent(EVENT_MAGE_MELT_ICE, 1s); - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - if (spell->Id == SPELL_FLASH_FREEZE_TRAPPED_NPC) - { - events.Reset(); - events.ScheduleEvent(EVENT_TRY_FREE_HELPER, 2s); - } - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_TRY_FREE_HELPER: - { - if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC)) - if (pInstance) - if (ObjectGuid g = pInstance->GetGuidData(TYPE_HODIR)) - if (Creature* hodir = ObjectAccessor::GetCreature(*me, g)) - { - AttackStart(hodir); - ScheduleAbilities(); - break; - } - events.Repeat(2s); - } - break; - case EVENT_MAGE_FIREBALL: - if (Unit* victim = me->GetVictim()) - me->CastSpell(victim, SPELL_MAGE_FIREBALL, false); - events.Repeat(3100ms); - break; - case EVENT_MAGE_TOASTY_FIRE: - me->CastSpell(me, SPELL_MAGE_CONJURE_TOASTY_FIRE, false); - events.Repeat(10s); - break; - case EVENT_MAGE_MELT_ICE: - { - std::list FB; - bool found = false; - me->GetCreaturesWithEntryInRange(FB, 150.0f, NPC_FLASH_FREEZE_NPC); - for( std::list::const_iterator itr = FB.begin(); itr != FB.end(); ++itr ) - if (!((*itr)->HasAura(SPELL_MAGE_MELT_ICE))) + else if (s->IsPlayer()) + if (InstanceScript* instanceScript = me->GetInstanceScript()) + if (instanceScript->GetBossState(BOSS_HODIR) == NOT_STARTED) { - me->CastSpell((*itr), SPELL_MAGE_MELT_ICE, false); - found = true; - break; + s->CastSpell(s, SPELL_FLASH_FREEZE_INSTAKILL, true); + me->DespawnOrUnsummon(2s); } + } + else + { + me->DespawnOrUnsummon(2s); + } + } + } + else + timer -= diff; + } +}; - if (found) +struct npc_ulduar_toasty_fire : public NullCreatureAI +{ + npc_ulduar_toasty_fire(Creature* pCreature) : NullCreatureAI(pCreature) + { + me->CastSpell(me, SPELL_MAGE_TOASTY_FIRE_AURA, true); + } + + void DoAction(int32 a) override + { + if (a == 1) + { + if (GameObject* fire = me->FindNearestGameObject(194300, 1.0f)) + { + fire->SetOwnerGUID(ObjectGuid::Empty); + fire->Delete(); + } + me->DespawnOrUnsummon(); // this will remove DynObjects + } + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + switch (spell->Id) + { + case SPELL_ICE_SHARDS_SMALL: + case SPELL_ICE_SHARDS_BIG: + DoAction(1); + break; + } + } +}; + +struct npc_ulduar_hodir_priest : public ScriptedAI +{ + npc_ulduar_hodir_priest(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = me->GetInstanceScript(); + events.Reset(); + me->SetReactState(REACT_PASSIVE); + } + + EventMap events; + InstanceScript* pInstance; + + void AttackStart(Unit* who) override + { + AttackStartCaster(who, 17.0f); + } + + void ScheduleAbilities() + { + events.ScheduleEvent(EVENT_PRIEST_DISPELL_MAGIC, 7s); + events.ScheduleEvent(EVENT_PRIEST_GREAT_HEAL, 6s, 7s); + events.ScheduleEvent(EVENT_PRIEST_SMITE, 2100ms); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_FLASH_FREEZE_TRAPPED_NPC) + { + events.Reset(); + events.ScheduleEvent(EVENT_TRY_FREE_HELPER, 2s); + } + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case 0: + break; + case EVENT_TRY_FREE_HELPER: + { + if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC)) + if (pInstance) + if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR)) + { + AttackStart(hodir); + ScheduleAbilities(); + break; + } + events.Repeat(2s); + } + break; + case EVENT_PRIEST_DISPELL_MAGIC: + me->CastCustomSpell(SPELL_PRIEST_DISPELL_MAGIC, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false); + events.Repeat(7s); + break; + case EVENT_PRIEST_GREAT_HEAL: + me->CastSpell(me, SPELL_PRIEST_GREAT_HEAL, false); + events.Repeat(6s, 7s); + break; + case EVENT_PRIEST_SMITE: + if (Unit* victim = me->GetVictim()) + me->CastSpell(victim, SPELL_PRIEST_SMITE, false); + events.Repeat(2100ms); + break; + } + } + + void MoveInLineOfSight(Unit* /*who*/) override {} + + void EnterEvadeMode(EvadeReason /*why*/) override {} + bool CanAIAttack(Unit const* t) const override { return t->GetEntry() == NPC_HODIR; } + + void JustDied(Unit* /*killer*/) override + { + if (pInstance) + if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR)) + hodir->AI()->SetData(4, 1); + } +}; + +struct npc_ulduar_hodir_druid : public ScriptedAI +{ + npc_ulduar_hodir_druid(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = me->GetInstanceScript(); + events.Reset(); + me->SetReactState(REACT_PASSIVE); + } + + EventMap events; + InstanceScript* pInstance; + + void AttackStart(Unit* who) override + { + AttackStartCaster(who, 22.0f); + } + + void ScheduleAbilities() + { + events.ScheduleEvent(EVENT_DRUID_WRATH, 1600ms); + events.ScheduleEvent(EVENT_DRUID_STARLIGHT, 10s); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_FLASH_FREEZE_TRAPPED_NPC) + { + events.Reset(); + events.ScheduleEvent(EVENT_TRY_FREE_HELPER, 2s); + } + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case 0: + break; + case EVENT_TRY_FREE_HELPER: + { + if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC)) + if (pInstance) + if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR)) + { + AttackStart(hodir); + ScheduleAbilities(); + break; + } + events.Repeat(2s); + } + break; + case EVENT_DRUID_WRATH: + if (Unit* victim = me->GetVictim()) + me->CastSpell(victim, SPELL_DRUID_WRATH, false); + events.Repeat(1600ms); + break; + case EVENT_DRUID_STARLIGHT: + if (me->GetPositionZ() < 433.0f) // ensure npc is on the ground + { + me->CastSpell(me, SPELL_DRUID_STARLIGHT_AREA_AURA, false); + events.Repeat(15s); + break; + } + events.Repeat(3s); + break; + } + } + + void MoveInLineOfSight(Unit* /*who*/) override {} + + void EnterEvadeMode(EvadeReason /*why*/) override {} + bool CanAIAttack(Unit const* t) const override { return t->GetEntry() == NPC_HODIR; } + + void JustDied(Unit* /*killer*/) override + { + if (pInstance) + if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR)) + hodir->AI()->SetData(4, 1); + } +}; + +struct npc_ulduar_hodir_shaman : public ScriptedAI +{ + npc_ulduar_hodir_shaman(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = me->GetInstanceScript(); + events.Reset(); + me->SetReactState(REACT_PASSIVE); + } + + EventMap events; + InstanceScript* pInstance; + + void AttackStart(Unit* who) override + { + AttackStartCaster(who, 25.0f); + } + + void ScheduleAbilities() + { + events.ScheduleEvent(EVENT_SHAMAN_LAVA_BURST, 2600ms); + events.ScheduleEvent(EVENT_SHAMAN_STORM_CLOUD, 10s); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_FLASH_FREEZE_TRAPPED_NPC) + { + events.Reset(); + events.ScheduleEvent(EVENT_TRY_FREE_HELPER, 2s); + } + } + + void SpellHitTarget(Unit* target, SpellInfo const* spell) override + { + uint32 spellid = sSpellMgr->GetSpellIdForDifficulty(SPELL_SHAMAN_STORM_CLOUD, me); + if (target && spell->Id == spellid) + if (Aura* a = target->GetAura(spellid, me->GetGUID())) + a->SetStackAmount(spell->StackAmount); + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case 0: + break; + case EVENT_TRY_FREE_HELPER: + { + if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC)) + if (pInstance) + if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR)) + { + AttackStart(hodir); + ScheduleAbilities(); + break; + } + events.Repeat(2s); + } + break; + case EVENT_SHAMAN_LAVA_BURST: + if (Unit* victim = me->GetVictim()) + me->CastSpell(victim, SPELL_SHAMAN_LAVA_BURST, false); + events.Repeat(2600ms); + break; + case EVENT_SHAMAN_STORM_CLOUD: + { + uint32 spellid = sSpellMgr->GetSpellIdForDifficulty(SPELL_SHAMAN_STORM_CLOUD, me); + if (Player* target = ScriptedAI::SelectTargetFromPlayerList(35.0f, spellid)) + me->CastSpell(target, spellid, false); + events.Repeat(30s); + break; + } + } + } + + void MoveInLineOfSight(Unit* /*who*/) override {} + + void EnterEvadeMode(EvadeReason /*why*/) override {} + bool CanAIAttack(Unit const* t) const override { return t->GetEntry() == NPC_HODIR; } + + void JustDied(Unit* /*killer*/) override + { + if (pInstance) + if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR)) + hodir->AI()->SetData(4, 1); + } +}; + +struct npc_ulduar_hodir_mage : public ScriptedAI +{ + npc_ulduar_hodir_mage(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = me->GetInstanceScript(); + events.Reset(); + me->SetReactState(REACT_PASSIVE); + } + + EventMap events; + InstanceScript* pInstance; + + void AttackStart(Unit* who) override + { + AttackStartCaster(who, 30.0f); + } + + void ScheduleAbilities() + { + events.ScheduleEvent(EVENT_MAGE_FIREBALL, 3100ms); + events.ScheduleEvent(EVENT_MAGE_TOASTY_FIRE, 6s); + events.ScheduleEvent(EVENT_MAGE_MELT_ICE, 1s); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_FLASH_FREEZE_TRAPPED_NPC) + { + events.Reset(); + events.ScheduleEvent(EVENT_TRY_FREE_HELPER, 2s); + } + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case 0: + break; + case EVENT_TRY_FREE_HELPER: + { + if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC)) + if (pInstance) + if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR)) + { + AttackStart(hodir); + ScheduleAbilities(); + break; + } + events.Repeat(2s); + } + break; + case EVENT_MAGE_FIREBALL: + if (Unit* victim = me->GetVictim()) + me->CastSpell(victim, SPELL_MAGE_FIREBALL, false); + events.Repeat(3100ms); + break; + case EVENT_MAGE_TOASTY_FIRE: + me->CastSpell(me, SPELL_MAGE_CONJURE_TOASTY_FIRE, false); + events.Repeat(10s); + break; + case EVENT_MAGE_MELT_ICE: + { + std::list FB; + bool found = false; + me->GetCreaturesWithEntryInRange(FB, 150.0f, NPC_FLASH_FREEZE_NPC); + for( std::list::const_iterator itr = FB.begin(); itr != FB.end(); ++itr ) + if (!((*itr)->HasAura(SPELL_MAGE_MELT_ICE))) { - events.DelayEvents(2s); - events.Repeat(2s); + me->CastSpell((*itr), SPELL_MAGE_MELT_ICE, false); + found = true; break; } - events.Repeat(5s); + + if (found) + { + events.DelayEvents(2s); + events.Repeat(2s); + break; } - break; - } + events.Repeat(5s); + } + break; } + } - void MoveInLineOfSight(Unit* /*who*/) override {} + void MoveInLineOfSight(Unit* /*who*/) override {} - void EnterEvadeMode(EvadeReason /*why*/) override {} - bool CanAIAttack(Unit const* t) const override { return t->GetEntry() == NPC_HODIR; } + void EnterEvadeMode(EvadeReason /*why*/) override {} + bool CanAIAttack(Unit const* t) const override { return t->GetEntry() == NPC_HODIR; } - void JustDied(Unit* /*killer*/) override - { - if (pInstance) - if (Creature* hodir = pInstance->instance->GetCreature(pInstance->GetGuidData(TYPE_HODIR))) - hodir->AI()->SetData(4, 1); - } - }; + void JustDied(Unit* /*killer*/) override + { + if (pInstance) + if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR)) + hodir->AI()->SetData(4, 1); + } }; class spell_hodir_shatter_chest : public SpellScript @@ -1271,7 +1163,7 @@ class spell_hodir_biting_cold_player_aura : public AuraScript { if (GetStackAmount() == 2) // increasing from 2 to 3 (not checking >= to improve performance) if (InstanceScript* pInstance = target->GetInstanceScript()) - if (Creature* hodir = pInstance->instance->GetCreature(pInstance->GetGuidData(TYPE_HODIR))) + if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR)) hodir->AI()->SetData(2, 1); ModStackAmount(1); _counter = 0; @@ -1544,15 +1436,15 @@ public: void AddSC_boss_hodir() { - new boss_hodir(); - new npc_ulduar_icicle(); - new npc_ulduar_flash_freeze(); - new npc_ulduar_toasty_fire(); + RegisterUlduarCreatureAI(boss_hodir); + RegisterUlduarCreatureAI(npc_ulduar_icicle); + RegisterUlduarCreatureAI(npc_ulduar_flash_freeze); + RegisterUlduarCreatureAI(npc_ulduar_toasty_fire); - new npc_ulduar_hodir_priest(); - new npc_ulduar_hodir_druid(); - new npc_ulduar_hodir_shaman(); - new npc_ulduar_hodir_mage(); + RegisterUlduarCreatureAI(npc_ulduar_hodir_priest); + RegisterUlduarCreatureAI(npc_ulduar_hodir_druid); + RegisterUlduarCreatureAI(npc_ulduar_hodir_shaman); + RegisterUlduarCreatureAI(npc_ulduar_hodir_mage); RegisterSpellScript(spell_hodir_shatter_chest); RegisterSpellScript(spell_hodir_biting_cold_main_aura); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp index 0b933628f..e0756cbd9 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp @@ -48,7 +48,6 @@ enum IgnisSpellData enum IgnisNPCs { - BOSS_IGNIS = 33118, NPC_IRON_CONSTRUCT = 33121, NPC_SCORCHED_GROUND = 33123, NPC_WATER_TRIGGER = 22515, @@ -78,155 +77,130 @@ enum eEvents EVENT_GRAB, }; -class npc_ulduar_iron_construct : public CreatureScript +struct npc_ulduar_iron_construct : public ScriptedAI { -public: - npc_ulduar_iron_construct() : CreatureScript("npc_ulduar_iron_construct") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_ulduar_iron_construct(Creature* pCreature) : ScriptedAI(pCreature) { - return GetUlduarAI(pCreature); + me->CastSpell(me, 38757, true); } - struct npc_ulduar_iron_constructAI : public ScriptedAI + uint16 timer; + + void Reset() override { - npc_ulduar_iron_constructAI(Creature* pCreature) : ScriptedAI(pCreature) - { - me->CastSpell(me, 38757, true); - } + timer = 1000; + me->SetReactState(REACT_PASSIVE); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + } - uint16 timer; + void JustReachedHome() override + { + me->CastSpell(me, 38757, true); + } - void Reset() override + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_ACTIVATE_CONSTRUCT) { - timer = 1000; - me->SetReactState(REACT_PASSIVE); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - } - - void JustReachedHome() override - { - me->CastSpell(me, 38757, true); - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - if (spell->Id == SPELL_ACTIVATE_CONSTRUCT) - { - me->RemoveAura(38757); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetReactState(REACT_AGGRESSIVE); - if (InstanceScript* instance = me->GetInstanceScript()) - if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS))) - { - ignis->CastSpell(ignis, SPELL_STRENGTH_OF_THE_CREATOR, true); - AttackStart(ignis->GetVictim()); - DoZoneInCombat(); - } - } - else if (spell->Id == SPELL_HEAT_BUFF) - { - if (Aura* heat = me->GetAura(SPELL_HEAT_BUFF)) + me->RemoveAura(38757); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* ignis = instance->GetCreature(BOSS_IGNIS)) { - if (heat->GetStackAmount() >= 10) + ignis->CastSpell(ignis, SPELL_STRENGTH_OF_THE_CREATOR, true); + AttackStart(ignis->GetVictim()); + DoZoneInCombat(); + } + } + else if (spell->Id == SPELL_HEAT_BUFF) + { + if (Aura* heat = me->GetAura(SPELL_HEAT_BUFF)) + { + if (heat->GetStackAmount() >= 10) + { + if (heat->GetStackAmount() > 10) { - if (heat->GetStackAmount() > 10) - { - heat->ModStackAmount(-1); - } - me->CastSpell(me, SPELL_MOLTEN, true); - me->GetThreatMgr().ResetAllThreat(); + heat->ModStackAmount(-1); } + me->CastSpell(me, SPELL_MOLTEN, true); + me->GetThreatMgr().ResetAllThreat(); } } } - - void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (damage >= RAID_MODE(3000U, 5000U) && me->GetAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_BRITTLE, me))) - { - me->CastSpell(me, SPELL_SHATTER, true); - Unit::Kill(attacker, me); - - if (InstanceScript* instance = me->GetInstanceScript()) - if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS))) - ignis->AI()->SetData(1337, 0); - } - } - - void JustDied(Unit* /*killer*/) override - { - if (InstanceScript* instance = me->GetInstanceScript()) - if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS))) - ignis->RemoveAuraFromStack(SPELL_STRENGTH_OF_THE_CREATOR); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (timer <= diff) - { - timer = 1000; - if (Aura* a = me->GetAura(SPELL_MOLTEN)) - if (me->FindNearestCreature(NPC_WATER_TRIGGER, 18.0f, true)) - { - me->RemoveAura(a); - me->CastSpell(me, SPELL_BRITTLE, true); - } - } - else - timer -= diff; - - DoMeleeAttackIfReady(); - } - - void MoveInLineOfSight(Unit* /*who*/) override {} - }; -}; - -class boss_ignis : public CreatureScript -{ -public: - boss_ignis() : CreatureScript("boss_ignis") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct boss_ignisAI : public ScriptedAI + void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask) override { - boss_ignisAI(Creature* pCreature) : ScriptedAI(pCreature) { } - - EventMap events; - uint8 counter; - bool bShattered; - uint32 lastShatterMSTime; - - void Reset() override + if (damage >= RAID_MODE(3000U, 5000U) && me->GetAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_BRITTLE, me))) { - events.Reset(); - me->SetControlled(false, UNIT_STATE_ROOT); - me->DisableRotate(false); - counter = 0; - bShattered = false; - lastShatterMSTime = 0; + me->CastSpell(me, SPELL_SHATTER, true); + Unit::Kill(attacker, me); - if (InstanceScript* m_pInstance = me->GetInstanceScript()) - { - m_pInstance->SetData(TYPE_IGNIS, NOT_STARTED); - m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT); - } + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* ignis = instance->GetCreature(BOSS_IGNIS)) + ignis->AI()->SetData(1337, 0); } + } - void JustEngagedWith(Unit* /*who*/) override + void JustDied(Unit* /*killer*/) override + { + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* ignis = instance->GetCreature(BOSS_IGNIS)) + ignis->RemoveAuraFromStack(SPELL_STRENGTH_OF_THE_CREATOR); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + if (timer <= diff) { - me->setActive(true); + timer = 1000; + if (Aura* a = me->GetAura(SPELL_MOLTEN)) + if (me->FindNearestCreature(NPC_WATER_TRIGGER, 18.0f, true)) + { + me->RemoveAura(a); + me->CastSpell(me, SPELL_BRITTLE, true); + } + } + else + timer -= diff; - std::list icl; - me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT); + DoMeleeAttackIfReady(); + } + + void MoveInLineOfSight(Unit* /*who*/) override {} +}; + +struct boss_ignis : public BossAI +{ + boss_ignis(Creature* pCreature) : BossAI(pCreature, BOSS_IGNIS) { } + + uint8 counter; + bool bShattered; + uint32 lastShatterMSTime; + + void Reset() override + { + _Reset(); + me->SetControlled(false, UNIT_STATE_ROOT); + me->DisableRotate(false); + counter = 0; + bShattered = false; + lastShatterMSTime = 0; + + if (instance) + instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT); + } + + void JustEngagedWith(Unit* /*who*/) override + { + me->setActive(true); + + std::list icl; + me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT); for( std::list::iterator itr = icl.begin(); itr != icl.end(); ++itr ) { if (!(*itr)->IsAlive()) @@ -240,185 +214,183 @@ public: (*itr)->CastSpell((*itr), 38757, true); } - bShattered = false; - lastShatterMSTime = 0; - events.Reset(); - events.ScheduleEvent(EVENT_ACTIVATE_CONSTRUCT, RAID_MODE(40s, 30s)); - events.ScheduleEvent(EVENT_SPELL_SCORCH, 10s); - events.ScheduleEvent(EVENT_SPELL_FLAME_JETS, 32s); - events.ScheduleEvent(EVENT_GRAB, 25s); + bShattered = false; + lastShatterMSTime = 0; + events.Reset(); + events.ScheduleEvent(EVENT_ACTIVATE_CONSTRUCT, RAID_MODE(40s, 30s)); + events.ScheduleEvent(EVENT_SPELL_SCORCH, 10s); + events.ScheduleEvent(EVENT_SPELL_FLAME_JETS, 32s); + events.ScheduleEvent(EVENT_GRAB, 25s); - Talk(SAY_AGGRO); - DoZoneInCombat(); + Talk(SAY_AGGRO); + DoZoneInCombat(); - if (InstanceScript* m_pInstance = me->GetInstanceScript()) - { - m_pInstance->SetData(TYPE_IGNIS, IN_PROGRESS); - m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT); - m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT); - } + if (instance) + { + instance->SetBossState(BOSS_IGNIS, IN_PROGRESS); + instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT); + instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT); + } + } + + void SetData(uint32 id, uint32 /*value*/) override + { + if (id == 1337) + { + if (lastShatterMSTime) + if (getMSTimeDiff(lastShatterMSTime, GameTime::GetGameTimeMS().count()) <= 5000) + bShattered = true; + + lastShatterMSTime = GameTime::GetGameTimeMS().count(); + } + } + + uint32 GetData(uint32 id) const override + { + if (id == 1337) + return (bShattered ? 1 : 0); + return 0; + } + + void JustReachedHome() override + { + _JustReachedHome(); + me->setActive(false); + } + + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer()) + Talk(SAY_SLAY); + } + + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); + _JustDied(); + + std::list icl; + me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT); + for (std::list::iterator itr = icl.begin(); itr != icl.end(); ++itr) + if ((*itr)->IsAlive() && (*itr)->IsInCombat()) + Unit::Kill(*itr, *itr); + } + + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + if (caster && spell->Id == SPELL_GRAB_CONTROL_2) + { + //caster->ClearUnitState(UNIT_STATE_ONVEHICLE); + me->CastSpell(caster, SPELL_SLAG_POT, true); + } + } + + void MoveInLineOfSight(Unit* /*who*/) override {} + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + if (me->GetPositionX() < 490.0f || me->GetPositionX() > 690.0f || me->GetPositionY() < 130.0f || me->GetPositionY() > 410.0f) + { + EnterEvadeMode(EVADE_REASON_OTHER); + return; } - void SetData(uint32 id, uint32 /*value*/) override + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - if (id == 1337) - { - if (lastShatterMSTime) - if (getMSTimeDiff(lastShatterMSTime, GameTime::GetGameTimeMS().count()) <= 5000) - bShattered = true; - - lastShatterMSTime = GameTime::GetGameTimeMS().count(); - } - } - - uint32 GetData(uint32 id) const override - { - if (id == 1337) - return (bShattered ? 1 : 0); - return 0; - } - - void JustReachedHome() override - { - me->setActive(false); - } - - void KilledUnit(Unit* victim) override - { - if (victim->IsPlayer()) - Talk(SAY_SLAY); - } - - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); - - if (me->GetInstanceScript()) - me->GetInstanceScript()->SetData(TYPE_IGNIS, DONE); - - std::list icl; - me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT); - for( std::list::iterator itr = icl.begin(); itr != icl.end(); ++itr ) - if ((*itr)->IsAlive() && (*itr)->IsInCombat()) - Unit::Kill(*itr, *itr); - } - - void SpellHit(Unit* caster, SpellInfo const* spell) override - { - if (caster && spell->Id == SPELL_GRAB_CONTROL_2) - { - //caster->ClearUnitState(UNIT_STATE_ONVEHICLE); - me->CastSpell(caster, SPELL_SLAG_POT, true); - } - } - - void MoveInLineOfSight(Unit* /*who*/) override {} - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (me->GetPositionX() < 490.0f || me->GetPositionX() > 690.0f || me->GetPositionY() < 130.0f || me->GetPositionY() > 410.0f ) - { - EnterEvadeMode(EVADE_REASON_OTHER); - return; - } - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: + case 0: + break; + case EVENT_ACTIVATE_CONSTRUCT: + Talk(SAY_SUMMON); + me->CastCustomSpell(SPELL_ACTIVATE_CONSTRUCT, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false); + if (++counter >= 20) + { + Talk(SAY_BERSERK); + me->CastSpell(me, SPELL_BERSERK, true); break; - case EVENT_ACTIVATE_CONSTRUCT: - Talk(SAY_SUMMON); - me->CastCustomSpell(SPELL_ACTIVATE_CONSTRUCT, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false); - if (++counter >= 20) + } + events.Repeat(RAID_MODE(40s, 30s)); + break; + case EVENT_SPELL_SCORCH: + Talk(SAY_SCORCH); + me->SetControlled(true, UNIT_STATE_ROOT); + me->DisableRotate(true); + me->SendMovementFlagUpdate(); + me->CastSpell(me->GetVictim(), SPELL_SCORCH, false); + events.Repeat(20s); + events.RescheduleEvent(EVENT_ENABLE_ROTATE, 3s); + break; + case EVENT_ENABLE_ROTATE: + me->SetControlled(false, UNIT_STATE_ROOT); + me->DisableRotate(false); + break; + case EVENT_SPELL_FLAME_JETS: + Talk(EMOTE_JETS); + me->CastSpell(me->GetVictim(), SPELL_FLAME_JETS, false); + events.Repeat(25s); + break; + case EVENT_GRAB: + { + std::list icl; + me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT); + + GuidVector playerGUIDs; + Map::PlayerList const& pl = me->GetMap()->GetPlayers(); + Player* temp = nullptr; + + for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) { - Talk(SAY_BERSERK); - me->CastSpell(me, SPELL_BERSERK, true); - break; - } - events.Repeat(RAID_MODE(40s, 30s)); - break; - case EVENT_SPELL_SCORCH: - Talk(SAY_SCORCH); - me->SetControlled(true, UNIT_STATE_ROOT); - me->DisableRotate(true); - me->SendMovementFlagUpdate(); - me->CastSpell(me->GetVictim(), SPELL_SCORCH, false); - events.Repeat(20s); - events.RescheduleEvent(EVENT_ENABLE_ROTATE, 3s); - break; - case EVENT_ENABLE_ROTATE: - me->SetControlled(false, UNIT_STATE_ROOT); - me->DisableRotate(false); - break; - case EVENT_SPELL_FLAME_JETS: - Talk(EMOTE_JETS); - me->CastSpell(me->GetVictim(), SPELL_FLAME_JETS, false); - events.Repeat(25s); - break; - case EVENT_GRAB: - { - std::list icl; - me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT); - - GuidVector playerGUIDs; - Map::PlayerList const& pl = me->GetMap()->GetPlayers(); - Player* temp = nullptr; - - for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) + temp = itr->GetSource(); + if (!temp->IsAlive() || temp->GetExactDist2d(me) > 90.0f) + continue; + if (me->GetVictim() && temp->GetGUID() == me->GetVictim()->GetGUID()) + continue; + bool found = false; + for (std::list::iterator iterator = icl.begin(); iterator != icl.end(); ++iterator) { - temp = itr->GetSource(); - if (!temp->IsAlive() || temp->GetExactDist2d(me) > 90.0f ) - continue; - if (me->GetVictim() && temp->GetGUID() == me->GetVictim()->GetGUID()) - continue; - bool found = false; - for (std::list::iterator iterator = icl.begin(); iterator != icl.end(); ++iterator) + if ((*iterator)->GetVictim() && (*iterator)->GetVictim()->GetGUID() == temp->GetGUID()) { - if ((*iterator)->GetVictim() && (*iterator)->GetVictim()->GetGUID() == temp->GetGUID()) - { - found = true; - break; - } - } - - if (!found) - playerGUIDs.push_back(temp->GetGUID()); - } - - if (!playerGUIDs.empty()) - { - int8 pos = urand(0, playerGUIDs.size() - 1); - if (Player* pTarget = ObjectAccessor::GetPlayer(*me, playerGUIDs.at(pos))) - { - Talk(SAY_SLAG_POT); - me->CastSpell(pTarget, SPELL_GRAB, false); + found = true; + break; } } - events.Repeat(24s); - events.DelayEvents(6s); + if (!found) + playerGUIDs.push_back(temp->GetGUID()); } - break; - } - DoMeleeAttackIfReady(); + if (!playerGUIDs.empty()) + { + int8 pos = urand(0, playerGUIDs.size() - 1); + if (Player* pTarget = ObjectAccessor::GetPlayer(*me, playerGUIDs.at(pos))) + { + Talk(SAY_SLAG_POT); + me->CastSpell(pTarget, SPELL_GRAB, false); + } + } + + events.Repeat(24s); + events.DelayEvents(6s); + } + break; } - void EnterEvadeMode(EvadeReason why) override - { - me->SetControlled(false, UNIT_STATE_ROOT); - me->DisableRotate(false); - ScriptedAI::EnterEvadeMode(why); - } - }; + DoMeleeAttackIfReady(); + } + + void EnterEvadeMode(EvadeReason why) override + { + me->SetControlled(false, UNIT_STATE_ROOT); + me->DisableRotate(false); + BossAI::EnterEvadeMode(why); + } }; class spell_ignis_scorch_aura : public AuraScript @@ -541,8 +513,8 @@ public: void AddSC_boss_ignis() { - new boss_ignis(); - new npc_ulduar_iron_construct(); + RegisterUlduarCreatureAI(boss_ignis); + RegisterUlduarCreatureAI(npc_ulduar_iron_construct); RegisterSpellScript(spell_ignis_scorch_aura); RegisterSpellScript(spell_ignis_grab_initial); RegisterSpellScript(spell_ignis_slag_pot_aura); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp index df8e2ea3e..99e5c4de9 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp @@ -117,34 +117,19 @@ enum Misc DATA_KOLOGARN_ARMS_ACHIEV = 57, }; -class boss_kologarn : public CreatureScript +struct boss_kologarn : public BossAI { -public: - boss_kologarn() : CreatureScript("boss_kologarn") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_kologarn(Creature* creature) : BossAI(creature, BOSS_KOLOGARN), vehicle(me->GetVehicleKit()), breathReady(false) { - return GetUlduarAI(pCreature); + assert(vehicle); + me->SetStandState(UNIT_STAND_STATE_SUBMERGED); } - struct boss_kologarnAI : public ScriptedAI - { - boss_kologarnAI(Creature* pCreature) : ScriptedAI(pCreature), vehicle(me->GetVehicleKit()), summons(me), breathReady(false) - { - m_pInstance = me->GetInstanceScript(); - assert(vehicle); - me->SetStandState(UNIT_STAND_STATE_SUBMERGED); - } + Vehicle* vehicle; + ObjectGuid _left, _right; - InstanceScript* m_pInstance; - - Vehicle* vehicle; - ObjectGuid _left, _right; - EventMap events; - SummonList summons; - - bool _looksAchievement, breathReady; - uint8 _rubbleAchievement; + bool _looksAchievement, breathReady; + uint8 _rubbleAchievement; void MoveInLineOfSight(Unit* who) override { @@ -158,13 +143,18 @@ public: } if (me->GetExactDist2d(who) < 30.0f) - ScriptedAI::MoveInLineOfSight(who); + BossAI::MoveInLineOfSight(who); } void EnterEvadeMode(EvadeReason why) override { - if (!_EnterEvadeMode(why)) + if (!CreatureAI::_EnterEvadeMode(why)) return; + if (instance && instance->GetBossState(BOSS_KOLOGARN) != DONE) + { + instance->SetBossState(BOSS_KOLOGARN, NOT_STARTED); + instance->SaveToDB(); + } Reset(); me->setActive(false); } @@ -214,15 +204,12 @@ public: me->SetDisableGravity(true); me->DisableRotate(true); - events.Reset(); - summons.DespawnAll(); + _Reset(); - if (m_pInstance) + if (instance) { - m_pInstance->SetData(TYPE_KOLOGARN, NOT_STARTED); - // Open the door inside Kologarn chamber - if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS))) + if (GameObject* door = instance->GetGameObject(DATA_KOLOGARN_DOORS)) door->SetGoState(GO_STATE_ACTIVE); } @@ -240,8 +227,8 @@ public: if (param == DATA_KOLOGARN_RUBBLE_ACHIEV) { // Means arm died - if (m_pInstance && (!_left || !_right)) - m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_DISARMED_CRITERIA); + if (instance && (!_left || !_right)) + instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_DISARMED_CRITERIA); ++_rubbleAchievement; } @@ -267,12 +254,12 @@ public: void JustSummoned(Creature* cr) override { if (cr->GetEntry() != NPC_LEFT_ARM && cr->GetEntry() != NPC_RIGHT_ARM) - summons.Summon(cr); + BossAI::JustSummoned(cr); } void SummonedCreatureDespawn(Creature* cr) override { - if (m_pInstance->GetData(TYPE_KOLOGARN) > NOT_STARTED) + if (instance->GetBossState(BOSS_KOLOGARN) > NOT_STARTED) return; if (cr->GetEntry() == NPC_LEFT_ARM) @@ -290,17 +277,15 @@ public: void JustDied(Unit*) override { - summons.DespawnAll(); + _JustDied(); me->StopMoving(); - if (m_pInstance) - m_pInstance->SetData(TYPE_KOLOGARN, DONE); Talk(SAY_DEATH); - if (m_pInstance) + if (instance) { // Open the door inside Kologarn chamber - if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS))) + if (GameObject* door = instance->GetGameObject(DATA_KOLOGARN_DOORS)) door->SetGoState(GO_STATE_ACTIVE); } @@ -333,7 +318,7 @@ public: void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) override { - if (!me->IsAlive() || m_pInstance->GetData(TYPE_KOLOGARN) != IN_PROGRESS) + if (!me->IsAlive() || instance->GetBossState(BOSS_KOLOGARN) != IN_PROGRESS) return; if (!apply) @@ -375,8 +360,8 @@ public: void JustEngagedWith(Unit* /*who*/) override { - if (m_pInstance) - m_pInstance->SetData(TYPE_KOLOGARN, IN_PROGRESS); + if (instance) + instance->SetBossState(BOSS_KOLOGARN, IN_PROGRESS); events.ScheduleEvent(EVENT_SMASH, 8s); events.ScheduleEvent(EVENT_SWEEP, 17s); @@ -389,9 +374,9 @@ public: me->setActive(true); // Close the door inside Kologarn chamber - if (m_pInstance) + if (instance) { - if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS))) + if (GameObject* door = instance->GetGameObject(DATA_KOLOGARN_DOORS)) { door->SetGoState(GO_STATE_READY); } @@ -491,173 +476,151 @@ public: me->resetAttackTimer(); } } - }; }; // also used for left arm, all functions except JustDied wont be used by left arm -class boss_kologarn_arms : public CreatureScript +struct boss_kologarn_arms : public ScriptedAI { -public: - boss_kologarn_arms() : CreatureScript("boss_kologarn_arms") { } + boss_kologarn_arms(Creature* c) : ScriptedAI(c) { } - CreatureAI* GetAI(Creature* pCreature) const override + int32 _damageDone; + bool _combatStarted; + + void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override {} + void MoveInLineOfSight(Unit*) override {} + void AttackStart(Unit*) override {} + void UpdateAI(uint32 /*diff*/) override {} + + void Reset() override { - return GetUlduarAI(pCreature); + _combatStarted = false; + _damageDone = 0; } - struct boss_kologarn_armsAI : public ScriptedAI + void PassengerBoarded(Unit* /*who*/, int8 /*seatId*/, bool apply) override { - boss_kologarn_armsAI(Creature* c) : ScriptedAI(c) { } - - int32 _damageDone; - bool _combatStarted; - - void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override {} - void MoveInLineOfSight(Unit*) override {} - void AttackStart(Unit*) override {} - void UpdateAI(uint32 /*diff*/) override {} - - void Reset() override - { - _combatStarted = false; + if (!apply) _damageDone = 0; + else + { + //who->ClearUnitState(UNIT_STATE_ONVEHICLE); + if (!_damageDone) + _damageDone = RAID_MODE(80000, 380000); + } + } + + void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (!_combatStarted) + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* cr = instance->GetCreature(BOSS_KOLOGARN)) + { + _combatStarted = true; + if (!cr->IsInCombat() && who) + cr->AI()->AttackStart(who); + } + + if (_damageDone > 0) + { + _damageDone -= damage; + if (_damageDone <= 0 || damage >= me->GetHealth()) + me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE); + } + } + + void JustDied(Unit*) override + { + float x, y, z; + // left arm + if (me->GetEntry() == NPC_LEFT_ARM ) + { + x = 1776.97f; + y = -44.8396f; + z = 448.888f; + } + else + { + x = 1777.82f; + y = -3.50803f; + z = 448.888f; } - void PassengerBoarded(Unit* /*who*/, int8 /*seatId*/, bool apply) override + if (Creature* cr = me->SummonTrigger(x, y, z, 0, 5000)) { - if (!apply) - _damageDone = 0; - else - { - //who->ClearUnitState(UNIT_STATE_ONVEHICLE); - if (!_damageDone) - _damageDone = RAID_MODE(80000, 380000); - } - } - - void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (!_combatStarted) - if (InstanceScript* instance = me->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_KOLOGARN))) - { - _combatStarted = true; - if (!cr->IsInCombat() && who) - cr->AI()->AttackStart(who); - } - - if (_damageDone > 0) - { - _damageDone -= damage; - if (_damageDone <= 0 || damage >= me->GetHealth()) - me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE); - } - } - - void JustDied(Unit*) override - { - float x, y, z; - // left arm - if (me->GetEntry() == NPC_LEFT_ARM ) - { - x = 1776.97f; - y = -44.8396f; - z = 448.888f; - } - else - { - x = 1777.82f; - y = -3.50803f; - z = 448.888f; - } - - if (Creature* cr = me->SummonTrigger(x, y, z, 0, 5000)) - { - cr->CastSpell(cr, SPELL_RUBBLE_FALL, true); - - if (me->GetInstanceScript()) - if (Creature* kologarn = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN))) - for (uint8 i = 0; i < 5; ++i) - if (Creature* cr2 = kologarn->SummonCreature(NPC_RUBBLE_SUMMON, cr->GetPositionX() + irand(-5, 5), cr->GetPositionY() + irand(-5, 5), cr->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000)) - { - cr2->SetInCombatWithZone(); - if (Unit* target = SelectTargetFromPlayerList(100)) - cr2->AI()->AttackStart(target); - } - } + cr->CastSpell(cr, SPELL_RUBBLE_FALL, true); if (me->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN))) - cr->AI()->DoAction(DATA_KOLOGARN_RUBBLE_ACHIEV); - - me->ExitVehicle(); + if (Creature* kologarn = me->GetInstanceScript()->GetCreature(BOSS_KOLOGARN)) + for (uint8 i = 0; i < 5; ++i) + if (Creature* cr2 = kologarn->SummonCreature(NPC_RUBBLE_SUMMON, cr->GetPositionX() + irand(-5, 5), cr->GetPositionY() + irand(-5, 5), cr->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000)) + { + cr2->SetInCombatWithZone(); + if (Unit* target = SelectTargetFromPlayerList(100)) + cr2->AI()->AttackStart(target); + } } - }; + + if (me->GetInstanceScript()) + if (Creature* cr = me->GetInstanceScript()->GetCreature(BOSS_KOLOGARN)) + cr->AI()->DoAction(DATA_KOLOGARN_RUBBLE_ACHIEV); + + me->ExitVehicle(); + } }; -class boss_kologarn_eyebeam : public CreatureScript +struct boss_kologarn_eyebeam : public ScriptedAI { -public: - boss_kologarn_eyebeam() : CreatureScript("boss_kologarn_eyebeam") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_kologarn_eyebeam(Creature* c) : ScriptedAI(c), _timer(1), _damaged(false) { - return GetUlduarAI(pCreature); + m_pInstance = (InstanceScript*)c->GetInstanceScript(); } - struct boss_kologarn_eyebeamAI : public ScriptedAI + + InstanceScript* m_pInstance; + uint32 _timer; + bool _damaged; + + void DamageDealt(Unit* /*victim*/, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override { - boss_kologarn_eyebeamAI(Creature* c) : ScriptedAI(c), _timer(1), _damaged(false) + if (damage > 0 && !_damaged && me->GetInstanceScript()) { - m_pInstance = (InstanceScript*)c->GetInstanceScript(); + _damaged = true; + if (Creature* cr = me->GetInstanceScript()->GetCreature(BOSS_KOLOGARN)) + cr->AI()->DoAction(DATA_KOLOGARN_LOOKS_ACHIEV); + } + } + + void IsSummonedBy(WorldObject* summoner) override + { + if (!summoner) + { + return; } - InstanceScript* m_pInstance; - uint32 _timer; - bool _damaged; - - void DamageDealt(Unit* /*victim*/, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override + // Should only work on playable characters + if (Player* player = summoner->ToPlayer()) { - if (damage > 0 && !_damaged && me->GetInstanceScript()) + me->Attack(player, false); + me->GetMotionMaster()->MoveChase(player); + + if (Creature* cr = m_pInstance->GetCreature(BOSS_KOLOGARN)) { - _damaged = true; - if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN))) - cr->AI()->DoAction(DATA_KOLOGARN_LOOKS_ACHIEV); + me->CastSpell(cr, me->GetEntry() == NPC_EYE_LEFT ? SPELL_FOCUSED_EYEBEAM_LEFT : SPELL_FOCUSED_EYEBEAM_RIGHT, true); } } + } - void IsSummonedBy(WorldObject* summoner) override + void UpdateAI(uint32 diff) override + { + if (_timer) { - if (!summoner) + _timer += diff; + if (_timer >= 2000) { - return; - } - - // Should only work on playable characters - if (Player* player = summoner->ToPlayer()) - { - me->Attack(player, false); - me->GetMotionMaster()->MoveChase(player); - - if (Creature* cr = ObjectAccessor::GetCreature(*me, m_pInstance->GetGuidData(TYPE_KOLOGARN))) - { - me->CastSpell(cr, me->GetEntry() == NPC_EYE_LEFT ? SPELL_FOCUSED_EYEBEAM_LEFT : SPELL_FOCUSED_EYEBEAM_RIGHT, true); - } + me->CastSpell(me, SPELL_FOCUSED_EYEBEAM, true); + _timer = 0; } } - - void UpdateAI(uint32 diff) override - { - if (_timer) - { - _timer += diff; - if (_timer >= 2000) - { - me->CastSpell(me, SPELL_FOCUSED_EYEBEAM, true); - _timer = 0; - } - } - } - }; + } }; class spell_kologarn_focused_eyebeam : public SpellScript @@ -867,7 +830,7 @@ public: { if (target) if (InstanceScript* instance = target->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN))) + if (Creature* cr = instance->GetCreature(BOSS_KOLOGARN)) return cr->AI()->GetData(DATA_KOLOGARN_LOOKS_ACHIEV); return false; @@ -883,7 +846,7 @@ public: { if (target) if (InstanceScript* instance = target->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN))) + if (Creature* cr = instance->GetCreature(BOSS_KOLOGARN)) return cr->AI()->GetData(DATA_KOLOGARN_RUBBLE_ACHIEV); return false; @@ -899,7 +862,7 @@ public: { if (target) if (InstanceScript* instance = target->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN))) + if (Creature* cr = instance->GetCreature(BOSS_KOLOGARN)) return cr->AI()->GetData(DATA_KOLOGARN_ARMS_ACHIEV); return false; @@ -909,9 +872,9 @@ public: void AddSC_boss_kologarn() { // Npcs - new boss_kologarn(); - new boss_kologarn_arms(); - new boss_kologarn_eyebeam(); + RegisterUlduarCreatureAI(boss_kologarn); + RegisterUlduarCreatureAI(boss_kologarn_arms); + RegisterUlduarCreatureAI(boss_kologarn_eyebeam); RegisterUlduarCreatureAI(boss_kologarn_pit_kill_bunny); // Spells diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index f09fc8252..e4c1367f9 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -250,1658 +250,1575 @@ enum Texts TALK_COMPUTER_ZERO = 12, }; -#define GetMimiron() ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_MIMIRON)) -#define GetLMK2() ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_MIMIRON_LEVIATHAN_MKII)) -#define GetVX001() ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_MIMIRON_VX001)) -#define GetACU() ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_MIMIRON_ACU)) +#define GetMimiron() instance->GetCreature(BOSS_MIMIRON) +#define GetLMK2() instance->GetCreature(DATA_MIMIRON_LEVIATHAN_MKII) +#define GetVX001() instance->GetCreature(DATA_MIMIRON_VX001) +#define GetACU() instance->GetCreature(DATA_MIMIRON_ACU) -class boss_mimiron : public CreatureScript +struct boss_mimiron : public BossAI { -public: - boss_mimiron() : CreatureScript("boss_mimiron") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_mimiron(Creature* pCreature) : BossAI(pCreature, BOSS_MIMIRON) { - return GetUlduarAI(pCreature); + if (!me->IsAlive()) + instance->SetBossState(BOSS_MIMIRON, DONE); + + bIsEvading = false; } - struct boss_mimironAI : public ScriptedAI + bool bIsEvading; + bool hardmode; + bool berserk; + bool bAchievProximityMine; + bool bAchievBombBot; + bool bAchievRocketStrike; + uint32 allowedFlameSpreadTime; + bool changeAllowedFlameSpreadTime; + uint8 minutesTalkNum; + uint32 outofCombatTimer; + + void Reset() override { - boss_mimironAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me) + hardmode = false; + berserk = false; + bAchievProximityMine = false; + bAchievBombBot = false; + bAchievRocketStrike = false; + allowedFlameSpreadTime = 0; + outofCombatTimer = 0; + changeAllowedFlameSpreadTime = false; + ResetGameObjects(); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + + if (!instance->IsBossDone(BOSS_MIMIRON)) + _Reset(); + } + + void AttackStart(Unit* who) override + { + if (who) + me->Attack(who, true); // skip following + } + + void JustReachedHome() override + { + _JustReachedHome(); + me->setActive(false); + } + + void JustEngagedWith(Unit* /*who*/) override + { + me->setActive(true); + DoZoneInCombat(); + me->RemoveAllAuras(); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + events.Reset(); + + if (Creature* c = GetLMK2()) { - pInstance = me->GetInstanceScript(); - if (!me->IsAlive()) - if (pInstance) - pInstance->SetData(TYPE_MIMIRON, DONE); - bIsEvading = false; - } - - InstanceScript* pInstance; - EventMap events; - SummonList summons; - bool bIsEvading; - bool hardmode; - bool berserk; - bool bAchievProximityMine; - bool bAchievBombBot; - bool bAchievRocketStrike; - uint32 allowedFlameSpreadTime; - bool changeAllowedFlameSpreadTime; - uint8 minutesTalkNum; - uint32 outofCombatTimer; - - void Reset() override - { - hardmode = false; - berserk = false; - bAchievProximityMine = false; - bAchievBombBot = false; - bAchievRocketStrike = false; - allowedFlameSpreadTime = 0; - outofCombatTimer = 0; - changeAllowedFlameSpreadTime = false; - ResetGameObjects(); - events.Reset(); - summons.DespawnAll(); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - - if (pInstance && pInstance->GetData(TYPE_MIMIRON) != DONE) - pInstance->SetData(TYPE_MIMIRON, NOT_STARTED); - } - - void AttackStart(Unit* who) override - { - if (who) - me->Attack(who, true); // skip following - } - - void JustReachedHome() override - { - me->setActive(false); - ScriptedAI::JustReachedHome(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - me->setActive(true); - DoZoneInCombat(); - me->RemoveAllAuras(); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - events.Reset(); - - if (Creature* c = GetLMK2()) - { - if (c->IsInEvadeMode()) - { - EnterEvadeMode(EVADE_REASON_OTHER); - return; - } - if (!c->IsAlive()) - c->Respawn(); - - me->EnterVehicle(c, 1); - } - else + if (c->IsInEvadeMode()) { EnterEvadeMode(EVADE_REASON_OTHER); return; } - CloseDoorAndButton(); + if (!c->IsAlive()) + c->Respawn(); - if (!hardmode) + me->EnterVehicle(c, 1); + } + else + { + EnterEvadeMode(EVADE_REASON_OTHER); + return; + } + CloseDoorAndButton(); + + if (!hardmode) + { + Talk(SAY_MKII_ACTIVATE); + events.ScheduleEvent(EVENT_SIT_LMK2, 6s); + events.ScheduleEvent(EVENT_BERSERK, 15min); + } + else + { + events.ScheduleEvent(EVENT_MIMIRON_SAY_HARDMODE, 7s); + events.ScheduleEvent(EVENT_BERSERK, Is25ManRaid() ? 10min : 8min); + + if (Creature* computer = me->SummonCreature(NPC_COMPUTER, 2746.7f, 2569.44f, 410.39f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000)) + computer->AI()->Talk(TALK_COMPUTER_INITIATED); + + events.ScheduleEvent(EVENT_COMPUTER_SAY_MINUTES, 3s); + minutesTalkNum = Is25ManRaid() ? TALK_COMPUTER_TEN : TALK_COMPUTER_EIGHT; + for (uint32 i = 0; i < uint32(TALK_COMPUTER_ZERO - minutesTalkNum - 1); ++i) + events.ScheduleEvent(EVENT_COMPUTER_SAY_MINUTES, Milliseconds((i + 1) * 60000)); + events.ScheduleEvent(EVENT_COMPUTER_SAY_MINUTES, Milliseconds((TALK_COMPUTER_ZERO - minutesTalkNum) * 60000)); + } + + // ensure LMK2 is at proper position + if (Creature* LMK2 = GetLMK2()) + { + LMK2->UpdatePosition(LMK2->GetHomePosition(), true); + LMK2->StopMovingOnCurrentPos(); + } + + if (!instance->IsBossDone(BOSS_MIMIRON)) + instance->SetBossState(BOSS_MIMIRON, IN_PROGRESS); + } + + void UpdateAI(uint32 diff) override + { + if (!me->IsInCombat()) + { + outofCombatTimer += diff; + if (outofCombatTimer >= 10000) { - Talk(SAY_MKII_ACTIVATE); - events.ScheduleEvent(EVENT_SIT_LMK2, 6s); - events.ScheduleEvent(EVENT_BERSERK, 15min); + outofCombatTimer = 0; + if (Creature* c = GetLMK2()) + me->CastSpell(c, RAND(SPELL_ENTER_VEHICLE_0, SPELL_ENTER_VEHICLE_1, SPELL_ENTER_VEHICLE_2, SPELL_ENTER_VEHICLE_4), true); } - else - { - events.ScheduleEvent(EVENT_MIMIRON_SAY_HARDMODE, 7s); - events.ScheduleEvent(EVENT_BERSERK, Is25ManRaid() ? 10min : 8min); + return; + } - events.ScheduleEvent(EVENT_COMPUTER_SAY_INITIATED, 0ms); - events.ScheduleEvent(EVENT_COMPUTER_SAY_MINUTES, 3s); - minutesTalkNum = Is25ManRaid() ? TALK_COMPUTER_TEN : TALK_COMPUTER_EIGHT; - for (uint32 i = 0; i < uint32(TALK_COMPUTER_ZERO - minutesTalkNum - 1); ++i) - events.ScheduleEvent(EVENT_COMPUTER_SAY_MINUTES, Milliseconds((i + 1) * 60000)); - events.ScheduleEvent(EVENT_COMPUTER_SAY_MINUTES, Milliseconds((TALK_COMPUTER_ZERO - minutesTalkNum) * 60000)); - } + Position p = me->GetHomePosition(); + if (me->GetExactDist(&p) > 80.0f || !SelectTargetFromPlayerList(150.0f)) + { + EnterEvadeMode(EVADE_REASON_OTHER); + return; + } - // ensure LMK2 is at proper position - if (pInstance) + events.Update(diff); + + switch (events.ExecuteEvent()) + { + case 0: + break; + case EVENT_COMPUTER_SAY_MINUTES: + if (Creature* computer = me->SummonCreature(NPC_COMPUTER, 2746.7f, 2569.44f, 410.39f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000)) + computer->AI()->Talk(minutesTalkNum++); + break; + case EVENT_MIMIRON_SAY_HARDMODE: + Talk(SAY_HARDMODE_ON); + events.ScheduleEvent(EVENT_SPAWN_FLAMES_INITIAL, 0ms); + events.ScheduleEvent(EVENT_SIT_LMK2, 4s); + break; + case EVENT_SPAWN_FLAMES_INITIAL: + { + if (changeAllowedFlameSpreadTime) + allowedFlameSpreadTime = GameTime::GetGameTime().count(); + + std::vector pg; + Map::PlayerList const& pl = me->GetMap()->GetPlayers(); + for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) + if (Player* plr = itr->GetSource()) + if (plr->IsAlive() && plr->GetExactDist2d(me) < 150.0f && !plr->IsGameMaster()) + pg.push_back(plr); + + for( uint8 i = 0; i < 3; ++i ) + if (!pg.empty()) + { + uint8 index = urand(0, pg.size() - 1); + Player* player = pg[index]; + float angle = rand_norm() * 2 * M_PI; + float z = 364.35f; + if (!player->IsWithinLOS(player->GetPositionX() + cos(angle) * 5.0f, player->GetPositionY() + std::sin(angle) * 5.0f, z)) + { + angle = player->GetAngle(2744.65f, 2569.46f); + } + me->CastSpell(player->GetPositionX() + cos(angle) * 5.0f, player->GetPositionY() + std::sin(angle) * 5.0f, z, SPELL_SUMMON_FLAMES_INITIAL, true); + pg.erase(pg.begin() + index); + } + + events.Repeat(30s); + } + break; + case EVENT_BERSERK: + berserk = true; + Talk(SAY_BERSERK); + if (hardmode) + me->SummonCreature(33576, 2744.78f, 2569.47f, 364.32f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 120000); + events.ScheduleEvent(EVENT_BERSERK_2, 0ms); + break; + case EVENT_BERSERK_2: + { + Creature* VX001 = nullptr; + Creature* LMK2 = nullptr; + Creature* ACU = nullptr; + if ((VX001 = GetVX001())) + VX001->CastSpell(VX001, SPELL_BERSERK, true); + if ((LMK2 = GetLMK2())) + LMK2->CastSpell(LMK2, SPELL_BERSERK, true); + if ((ACU = GetACU())) + ACU->CastSpell(ACU, SPELL_BERSERK, true); + events.Repeat(30s); + } + break; + case EVENT_SIT_LMK2: if (Creature* LMK2 = GetLMK2()) { - LMK2->UpdatePosition(LMK2->GetHomePosition(), true); - LMK2->StopMovingOnCurrentPos(); + me->EnterVehicle(LMK2, 6); + events.ScheduleEvent(EVENT_SIT_LMK2_INTERVAL, 2s); + break; } - - if (pInstance && pInstance->GetData(TYPE_MIMIRON) != DONE) - pInstance->SetData(TYPE_MIMIRON, IN_PROGRESS); - } - - void UpdateAI(uint32 diff) override - { - if (!me->IsInCombat()) - { - outofCombatTimer += diff; - if (outofCombatTimer >= 10000) - { - outofCombatTimer = 0; - if (Creature* c = GetLMK2()) - me->CastSpell(c, RAND(SPELL_ENTER_VEHICLE_0, SPELL_ENTER_VEHICLE_1, SPELL_ENTER_VEHICLE_2, SPELL_ENTER_VEHICLE_4), true); - } - return; - } - - Position p = me->GetHomePosition(); - if (me->GetExactDist(&p) > 80.0f || !SelectTargetFromPlayerList(150.0f)) - { EnterEvadeMode(EVADE_REASON_OTHER); - return; - } - - events.Update(diff); - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_COMPUTER_SAY_INITIATED: - if (Creature* computer = me->SummonCreature(NPC_COMPUTER, 2746.7f, 2569.44f, 410.39f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000)) - computer->AI()->Talk(TALK_COMPUTER_INITIATED); - break; - case EVENT_COMPUTER_SAY_MINUTES: - if (Creature* computer = me->SummonCreature(NPC_COMPUTER, 2746.7f, 2569.44f, 410.39f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000)) - computer->AI()->Talk(minutesTalkNum++); - break; - case EVENT_MIMIRON_SAY_HARDMODE: - Talk(SAY_HARDMODE_ON); - events.ScheduleEvent(EVENT_SPAWN_FLAMES_INITIAL, 0ms); - events.ScheduleEvent(EVENT_SIT_LMK2, 4s); - break; - case EVENT_SPAWN_FLAMES_INITIAL: - { - if (changeAllowedFlameSpreadTime) - allowedFlameSpreadTime = GameTime::GetGameTime().count(); - - std::vector pg; - Map::PlayerList const& pl = me->GetMap()->GetPlayers(); - for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) - if (Player* plr = itr->GetSource()) - if (plr->IsAlive() && plr->GetExactDist2d(me) < 150.0f && !plr->IsGameMaster()) - pg.push_back(plr); - - for( uint8 i = 0; i < 3; ++i ) - if (!pg.empty()) - { - uint8 index = urand(0, pg.size() - 1); - Player* player = pg[index]; - float angle = rand_norm() * 2 * M_PI; - float z = 364.35f; - if (!player->IsWithinLOS(player->GetPositionX() + cos(angle) * 5.0f, player->GetPositionY() + std::sin(angle) * 5.0f, z)) - { - angle = player->GetAngle(2744.65f, 2569.46f); - } - me->CastSpell(player->GetPositionX() + cos(angle) * 5.0f, player->GetPositionY() + std::sin(angle) * 5.0f, z, SPELL_SUMMON_FLAMES_INITIAL, true); - pg.erase(pg.begin() + index); - } - - events.Repeat(30s); - } - break; - case EVENT_BERSERK: - berserk = true; - Talk(SAY_BERSERK); + break; + case EVENT_SIT_LMK2_INTERVAL: + if (Creature* LMK2 = GetLMK2()) + { if (hardmode) - me->SummonCreature(33576, 2744.78f, 2569.47f, 364.32f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 120000); - events.ScheduleEvent(EVENT_BERSERK_2, 0ms); - break; - case EVENT_BERSERK_2: { - Creature* VX001 = nullptr; - Creature* LMK2 = nullptr; - Creature* ACU = nullptr; - if ((VX001 = GetVX001())) - VX001->CastSpell(VX001, SPELL_BERSERK, true); - if ((LMK2 = GetLMK2())) - LMK2->CastSpell(LMK2, SPELL_BERSERK, true); - if ((ACU = GetACU())) - ACU->CastSpell(ACU, SPELL_BERSERK, true); - events.Repeat(30s); + LMK2->CastSpell(LMK2, SPELL_EMERGENCY_MODE, true); + if (Vehicle* veh = LMK2->GetVehicleKit()) + if (Unit* cannon = veh->GetPassenger(3)) + cannon->CastSpell(cannon, SPELL_EMERGENCY_MODE, true); } + LMK2->AI()->SetData(1, 1); break; - case EVENT_SIT_LMK2: - if (Creature* LMK2 = GetLMK2()) - { - me->EnterVehicle(LMK2, 6); - events.ScheduleEvent(EVENT_SIT_LMK2_INTERVAL, 2s); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); + } + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_LMK2_RETREAT_INTERVAL: + if (Creature* LMK2 = GetLMK2()) + { + me->EnterVehicle(LMK2, 1); + Talk(SAY_MKII_DEATH); + LMK2->SetFacingTo(3.58f); + events.ScheduleEvent(EVENT_ELEVATOR_INTERVAL_0, 6s); break; - case EVENT_SIT_LMK2_INTERVAL: - if (Creature* LMK2 = GetLMK2()) - { - if (hardmode) - { - LMK2->CastSpell(LMK2, SPELL_EMERGENCY_MODE, true); - if (Vehicle* veh = LMK2->GetVehicleKit()) - if (Unit* cannon = veh->GetPassenger(3)) - cannon->CastSpell(cannon, SPELL_EMERGENCY_MODE, true); - } - LMK2->AI()->SetData(1, 1); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_LMK2_RETREAT_INTERVAL: - if (Creature* LMK2 = GetLMK2()) - { - me->EnterVehicle(LMK2, 1); - Talk(SAY_MKII_DEATH); - LMK2->SetFacingTo(3.58f); - events.ScheduleEvent(EVENT_ELEVATOR_INTERVAL_0, 6s); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_ELEVATOR_INTERVAL_0: + } + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_ELEVATOR_INTERVAL_0: + if (GameObject* elevator = me->FindNearestGameObject(GO_MIMIRON_ELEVATOR, 100.0f)) + { + elevator->SetLootState(GO_READY); + elevator->UseDoorOrButton(0, false); + elevator->EnableCollision(false); + } + events.ScheduleEvent(EVENT_ELEVATOR_INTERVAL_1, 6s); + break; + case EVENT_ELEVATOR_INTERVAL_1: + if (me->SummonCreature(NPC_VX001, 2744.65f, 2569.46f, 364.40f, 3.14f, TEMPSUMMON_MANUAL_DESPAWN)) + { if (GameObject* elevator = me->FindNearestGameObject(GO_MIMIRON_ELEVATOR, 100.0f)) { elevator->SetLootState(GO_READY); - elevator->UseDoorOrButton(0, false); + elevator->UseDoorOrButton(0, true); elevator->EnableCollision(false); } - events.ScheduleEvent(EVENT_ELEVATOR_INTERVAL_1, 6s); + events.ScheduleEvent(EVENT_ELEVATOR_INTERVAL_2, 18s); break; - case EVENT_ELEVATOR_INTERVAL_1: - if (me->SummonCreature(NPC_VX001, 2744.65f, 2569.46f, 364.40f, 3.14f, TEMPSUMMON_MANUAL_DESPAWN)) - { - if (GameObject* elevator = me->FindNearestGameObject(GO_MIMIRON_ELEVATOR, 100.0f)) - { - elevator->SetLootState(GO_READY); - elevator->UseDoorOrButton(0, true); - elevator->EnableCollision(false); - } - events.ScheduleEvent(EVENT_ELEVATOR_INTERVAL_2, 18s); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_ELEVATOR_INTERVAL_2: - if (Creature* VX001 = GetVX001()) - { - me->EnterVehicle(VX001, 0); - events.ScheduleEvent(EVENT_SITTING_ON_VX001, 4s); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_SITTING_ON_VX001: - Talk(SAY_VX001_ACTIVATE); - events.ScheduleEvent(EVENT_ENTER_VX001, 5s); - break; - case EVENT_ENTER_VX001: - if (Creature* VX001 = GetVX001()) - { - me->EnterVehicle(VX001, 1); - events.ScheduleEvent(EVENT_EMOTE_VX001, 2s); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_EMOTE_VX001: - if (Creature* VX001 = GetVX001()) - { - VX001->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); - events.ScheduleEvent(EVENT_VX001_START_FIGHT, 1750ms); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_VX001_START_FIGHT: - if (Creature* VX001 = GetVX001()) - { - if (hardmode) - VX001->CastSpell(VX001, SPELL_EMERGENCY_MODE, true); - VX001->AI()->SetData(1, 2); - me->SetInCombatWithZone(); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_VX001_EMOTESTATE_DEATH: - if (Creature* VX001 = GetVX001()) - { - VX001->HandleEmoteCommand(EMOTE_STATE_DROWNED); - VX001->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DROWNED); - events.ScheduleEvent(EVENT_GET_OUT_VX001, 2500ms); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_GET_OUT_VX001: - if (Creature* VX001 = GetVX001()) - if (Creature* ACU = me->SummonCreature(NPC_AERIAL_COMMAND_UNIT, 2743.91f, 2568.78f, 391.34f, M_PI, TEMPSUMMON_MANUAL_DESPAWN)) - { - me->EnterVehicle(VX001, 4); - float speed = ACU->GetDistance(2737.75f, 2574.22f, 381.34f) / 2.0f; - ACU->GetMotionMaster()->MovePoint(0, 2737.75f, 2574.22f, 381.34f, FORCED_MOVEMENT_NONE, speed); - ACU->SetPosition(2737.75f, 2574.22f, 381.34f, M_PI); - events.ScheduleEvent(EVENT_SAY_VX001_DEAD, 2s); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_SAY_VX001_DEAD: - changeAllowedFlameSpreadTime = true; - Talk(SAY_VX001_DEATH); - events.ScheduleEvent(EVENT_ENTER_ACU, 7s); - break; - case EVENT_ENTER_ACU: - if (Creature* ACU = GetACU()) - { - me->EnterVehicle(ACU, 0); - events.ScheduleEvent(EVENT_SAY_ACU_ACTIVATE, 6s); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_SAY_ACU_ACTIVATE: - Talk(SAY_AERIAL_ACTIVATE); - events.ScheduleEvent(EVENT_ACU_START_ATTACK, 4s); - break; - case EVENT_ACU_START_ATTACK: - if (Creature* ACU = GetACU()) - { - if (hardmode) - ACU->CastSpell(ACU, SPELL_EMERGENCY_MODE, true); - ACU->AI()->SetData(1, 3); - me->SetInCombatWithZone(); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_SAY_ACU_DEAD: - Talk(SAY_AERIAL_DEATH); - events.ScheduleEvent(EVENT_LEVIATHAN_COME_CLOSER, 5s); - break; - case EVENT_LEVIATHAN_COME_CLOSER: - if (Creature* LMK2 = GetLMK2()) - { - LMK2->GetMotionMaster()->MoveCharge(2755.77f, 2574.95f, 364.31f, 21.0f); - events.ScheduleEvent(EVENT_VX001_EMOTE_JUMP, 4s); - break; - } - EnterEvadeMode(EVADE_REASON_OTHER); - break; - case EVENT_VX001_EMOTE_JUMP: - { - Creature* LMK2 = GetLMK2(); - Creature* VX001 = GetVX001(); - if (!VX001 || !LMK2) - { - EnterEvadeMode(EVADE_REASON_OTHER); - return; - } - - VX001->SendMeleeAttackStop(); - VX001->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CUSTOM_SPELL_02); - VX001->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_02); - events.ScheduleEvent(EVENT_LEVIATHAN_RIDE_MIDDLE, 4800ms); - } - break; - case EVENT_LEVIATHAN_RIDE_MIDDLE: - { - Creature* VX001 = GetVX001(); - Creature* LMK2 = GetLMK2(); - if (!VX001 || !LMK2) - { - EnterEvadeMode(EVADE_REASON_OTHER); - return; - } - - LMK2->GetMotionMaster()->MoveCharge(2744.65f, 2569.46f, 364.31f, 21.0f); - VX001->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_CUSTOM_SPELL_01); - VX001->HandleEmoteCommand(EMOTE_STATE_CUSTOM_SPELL_01); - VX001->EnterVehicle(LMK2, 3); - events.ScheduleEvent(EVENT_JOIN_TOGETHER, 3s); - } - break; - case EVENT_JOIN_TOGETHER: - { - Creature* ACU = GetACU(); - Creature* VX001 = GetVX001(); - if (!VX001 || !ACU) - { - EnterEvadeMode(EVADE_REASON_OTHER); - return; - } - - ACU->SetDisableGravity(false); - ACU->EnterVehicle(VX001, 3); - me->EnterVehicle(VX001, 1); - Talk(SAY_V07TRON_ACTIVATE); - events.ScheduleEvent(EVENT_START_PHASE4, 10s); - } - break; - case EVENT_START_PHASE4: - { - Creature* VX001 = GetVX001(); - Creature* LMK2 = GetLMK2(); - Creature* ACU = GetACU(); - if (!VX001 || !LMK2 || !ACU) - { - EnterEvadeMode(EVADE_REASON_OTHER); - return; - } - - LMK2->AI()->SetData(1, 4); - VX001->AI()->SetData(1, 4); - ACU->AI()->SetData(1, 4); - LMK2->CastSpell(LMK2, SPELL_SELF_REPAIR, true); //LMK2->SetHealth( LMK2->GetMaxHealth()/2 ); - VX001->CastSpell(VX001, SPELL_SELF_REPAIR, true); //VX001->SetHealth( VX001->GetMaxHealth()/2 ); - ACU->CastSpell(ACU, SPELL_SELF_REPAIR, true); //ACU->SetHealth( ACU->GetMaxHealth()/2 ); - if (hardmode) - { - LMK2->CastSpell(LMK2, SPELL_EMERGENCY_MODE, true); - VX001->CastSpell(VX001, SPELL_EMERGENCY_MODE, true); - ACU->CastSpell(ACU, SPELL_EMERGENCY_MODE, true); - } - me->SetInCombatWithZone(); - } - break; - case EVENT_FINISH: - { - Creature* LMK2 = GetLMK2(); - Creature* VX001 = GetVX001(); - Creature* ACU = GetACU(); - - if (!VX001 || !LMK2 || !ACU) - return; - - LMK2->GetMotionMaster()->Clear(); - LMK2->StopMoving(); - LMK2->InterruptNonMeleeSpells(false); - LMK2->AttackStop(); - LMK2->AI()->SetData(1, 0); - LMK2->DespawnOrUnsummon(7s); - LMK2->SetReactState(REACT_PASSIVE); - VX001->InterruptNonMeleeSpells(false); - VX001->AttackStop(); - VX001->AI()->SetData(1, 0); - VX001->DespawnOrUnsummon(7s); - VX001->SetReactState(REACT_PASSIVE); - ACU->InterruptNonMeleeSpells(false); - ACU->AttackStop(); - ACU->AI()->SetData(1, 0); - ACU->DespawnOrUnsummon(7s); - ACU->SetReactState(REACT_PASSIVE); - - Position exitPos = me->GetPosition(); - me->_ExitVehicle(&exitPos); - me->AttackStop(); - me->GetMotionMaster()->Clear(); - summons.DoAction(1337); // despawn summons of summons - summons.DespawnEntry(NPC_FLAMES_INITIAL); - summons.DespawnEntry(33576); - - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - - float angle = VX001->GetOrientation(); - float v_x = me->GetPositionX() + cos(angle) * 10.0f; - float v_y = me->GetPositionY() + std::sin(angle) * 10.0f; - me->GetMotionMaster()->MoveJump(v_x, v_y, 364.32f, 7.0f, 7.0f); - - DoCastSelf(SPELL_SLEEP_VISUAL_1); - - if (pInstance) - for( uint16 i = 0; i < 3; ++i ) - if (ObjectGuid guid = pInstance->GetGuidData(DATA_GO_MIMIRON_DOOR_1 + i)) - if (GameObject* door = ObjectAccessor::GetGameObject(*me, guid)) - if (door->GetGoState() != GO_STATE_ACTIVE ) - { - door->SetLootState(GO_READY); - door->UseDoorOrButton(0, false); - } - - if (pInstance) - pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_LEVIATHAN_MKII, 1, me); - - if (hardmode) - if (Creature* computer = me->SummonCreature(NPC_COMPUTER, 2746.7f, 2569.44f, 410.39f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000)) - computer->AI()->Talk(TALK_COMPUTER_TERMINATED); - - events.Reset(); - events.ScheduleEvent(EVENT_STAND_UP_FRIENDLY, 6s); - } - break; - case EVENT_STAND_UP_FRIENDLY: - me->RemoveAurasDueToSpell(SPELL_SLEEP_VISUAL_1); - DoCastSelf(SPELL_SLEEP_VISUAL_2); - me->SetFaction(FACTION_FRIENDLY); - events.ScheduleEvent(EVENT_SAY_VOLTRON_DEAD, 4s); - break; - case EVENT_SAY_VOLTRON_DEAD: - Talk(SAY_V07TRON_DEATH); - me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); - if (pInstance) - pInstance->SetData(TYPE_MIMIRON, DONE); - // spawn chest - if (uint32 chestId = (hardmode ? RAID_MODE(GO_MIMIRON_CHEST_HARD, GO_MIMIRON_CHEST_HERO_HARD) : RAID_MODE(GO_MIMIRON_CHEST, GO_MIMIRON_CHEST_HERO))) - { - if (GameObject* go = me->SummonGameObject(chestId, 2744.65f, 2569.46f, 364.397f, 0, 0, 0, 0, 0, 0)) - { - go->ReplaceAllGameObjectFlags((GameObjectFlags)0); - go->SetLootRecipient(me->GetMap()); - } - } - events.ScheduleEvent(EVENT_DISAPPEAR, 9s); - break; - case EVENT_DISAPPEAR: - DoCastSelf(SPELL_TELEPORT); - summons.DespawnAll(); - break; - } - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_TELEPORT) - { - me->DespawnOrUnsummon(); - pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE); - } - } - - void MoveInLineOfSight(Unit* /*mover*/) override {} - - void EnterEvadeMode(EvadeReason why) override - { - if (bIsEvading) - return; - bIsEvading = true; - - if (Creature* c = GetLMK2()) - { - c->AI()->EnterEvadeMode(why); - } - if (Creature* c = GetVX001()) - { - c->AI()->EnterEvadeMode(why); - c->DespawnOrUnsummon(); - } - if (Creature* c = GetACU()) - { - c->AI()->EnterEvadeMode(why); - c->DespawnOrUnsummon(); - } - - summons.DoAction(1337); // despawn summons of summons - - me->RemoveAllAuras(); - me->ExitVehicle(); - ScriptedAI::EnterEvadeMode(why); - - bIsEvading = false; - } - - void JustSummoned(Creature* s) override - { - summons.Summon(s); - } - - void SummonedCreatureDespawn(Creature* s) override - { - summons.Despawn(s); - } - - void ResetGameObjects() - { - if (pInstance) - for( uint16 i = 0; i < 3; ++i ) - if (ObjectGuid guid = pInstance->GetGuidData(DATA_GO_MIMIRON_DOOR_1 + i)) - if (GameObject* door = ObjectAccessor::GetGameObject(*me, guid)) - if (door->GetGoState() != GO_STATE_ACTIVE ) - { - door->SetLootState(GO_READY); - door->UseDoorOrButton(0, false); - } - - if (GameObject* elevator = me->FindNearestGameObject(GO_MIMIRON_ELEVATOR, 200.0f)) - { - if (elevator->GetGoState() != GO_STATE_ACTIVE ) - { - elevator->SetLootState(GO_READY); - elevator->SetByteValue(GAMEOBJECT_BYTES_1, 0, GO_STATE_ACTIVE); } - elevator->EnableCollision(false); - } - - if (GameObject* button = me->FindNearestGameObject(GO_BUTTON, 200.0f)) - if (button->GetGoState() != GO_STATE_READY ) + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_ELEVATOR_INTERVAL_2: + if (Creature* VX001 = GetVX001()) { - button->SetLootState(GO_READY); - button->UseDoorOrButton(0, false); - button->RemoveGameObjectFlag(GO_FLAG_IN_USE); + me->EnterVehicle(VX001, 0); + events.ScheduleEvent(EVENT_SITTING_ON_VX001, 4s); + break; } + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_SITTING_ON_VX001: + Talk(SAY_VX001_ACTIVATE); + events.ScheduleEvent(EVENT_ENTER_VX001, 5s); + break; + case EVENT_ENTER_VX001: + if (Creature* VX001 = GetVX001()) + { + me->EnterVehicle(VX001, 1); + events.ScheduleEvent(EVENT_EMOTE_VX001, 2s); + break; + } + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_EMOTE_VX001: + if (Creature* VX001 = GetVX001()) + { + VX001->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); + events.ScheduleEvent(EVENT_VX001_START_FIGHT, 1750ms); + break; + } + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_VX001_START_FIGHT: + if (Creature* VX001 = GetVX001()) + { + if (hardmode) + VX001->CastSpell(VX001, SPELL_EMERGENCY_MODE, true); + VX001->AI()->SetData(1, 2); + me->SetInCombatWithZone(); + break; + } + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_VX001_EMOTESTATE_DEATH: + if (Creature* VX001 = GetVX001()) + { + VX001->HandleEmoteCommand(EMOTE_STATE_DROWNED); + VX001->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DROWNED); + events.ScheduleEvent(EVENT_GET_OUT_VX001, 2500ms); + break; + } + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_GET_OUT_VX001: + if (Creature* VX001 = GetVX001()) + if (Creature* ACU = me->SummonCreature(NPC_AERIAL_COMMAND_UNIT, 2743.91f, 2568.78f, 391.34f, M_PI, TEMPSUMMON_MANUAL_DESPAWN)) + { + me->EnterVehicle(VX001, 4); + float speed = ACU->GetDistance(2737.75f, 2574.22f, 381.34f) / 2.0f; + ACU->GetMotionMaster()->MovePoint(0, 2737.75f, 2574.22f, 381.34f, FORCED_MOVEMENT_NONE, speed); + ACU->SetPosition(2737.75f, 2574.22f, 381.34f, M_PI); + events.ScheduleEvent(EVENT_SAY_VX001_DEAD, 2s); + break; + } + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_SAY_VX001_DEAD: + changeAllowedFlameSpreadTime = true; + Talk(SAY_VX001_DEATH); + events.ScheduleEvent(EVENT_ENTER_ACU, 7s); + break; + case EVENT_ENTER_ACU: + if (Creature* ACU = GetACU()) + { + me->EnterVehicle(ACU, 0); + events.ScheduleEvent(EVENT_SAY_ACU_ACTIVATE, 6s); + break; + } + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_SAY_ACU_ACTIVATE: + Talk(SAY_AERIAL_ACTIVATE); + events.ScheduleEvent(EVENT_ACU_START_ATTACK, 4s); + break; + case EVENT_ACU_START_ATTACK: + if (Creature* ACU = GetACU()) + { + if (hardmode) + ACU->CastSpell(ACU, SPELL_EMERGENCY_MODE, true); + ACU->AI()->SetData(1, 3); + me->SetInCombatWithZone(); + break; + } + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_SAY_ACU_DEAD: + Talk(SAY_AERIAL_DEATH); + events.ScheduleEvent(EVENT_LEVIATHAN_COME_CLOSER, 5s); + break; + case EVENT_LEVIATHAN_COME_CLOSER: + if (Creature* LMK2 = GetLMK2()) + { + LMK2->GetMotionMaster()->MoveCharge(2755.77f, 2574.95f, 364.31f, 21.0f); + events.ScheduleEvent(EVENT_VX001_EMOTE_JUMP, 4s); + break; + } + EnterEvadeMode(EVADE_REASON_OTHER); + break; + case EVENT_VX001_EMOTE_JUMP: + { + Creature* LMK2 = GetLMK2(); + Creature* VX001 = GetVX001(); + if (!VX001 || !LMK2) + { + EnterEvadeMode(EVADE_REASON_OTHER); + return; + } + + VX001->SendMeleeAttackStop(); + VX001->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CUSTOM_SPELL_02); + VX001->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_02); + events.ScheduleEvent(EVENT_LEVIATHAN_RIDE_MIDDLE, 4800ms); + } + break; + case EVENT_LEVIATHAN_RIDE_MIDDLE: + { + Creature* VX001 = GetVX001(); + Creature* LMK2 = GetLMK2(); + if (!VX001 || !LMK2) + { + EnterEvadeMode(EVADE_REASON_OTHER); + return; + } + + LMK2->GetMotionMaster()->MoveCharge(2744.65f, 2569.46f, 364.31f, 21.0f); + VX001->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_CUSTOM_SPELL_01); + VX001->HandleEmoteCommand(EMOTE_STATE_CUSTOM_SPELL_01); + VX001->EnterVehicle(LMK2, 3); + events.ScheduleEvent(EVENT_JOIN_TOGETHER, 3s); + } + break; + case EVENT_JOIN_TOGETHER: + { + Creature* ACU = GetACU(); + Creature* VX001 = GetVX001(); + if (!VX001 || !ACU) + { + EnterEvadeMode(EVADE_REASON_OTHER); + return; + } + + ACU->SetDisableGravity(false); + ACU->EnterVehicle(VX001, 3); + me->EnterVehicle(VX001, 1); + Talk(SAY_V07TRON_ACTIVATE); + events.ScheduleEvent(EVENT_START_PHASE4, 10s); + } + break; + case EVENT_START_PHASE4: + { + Creature* VX001 = GetVX001(); + Creature* LMK2 = GetLMK2(); + Creature* ACU = GetACU(); + if (!VX001 || !LMK2 || !ACU) + { + EnterEvadeMode(EVADE_REASON_OTHER); + return; + } + + LMK2->AI()->SetData(1, 4); + VX001->AI()->SetData(1, 4); + ACU->AI()->SetData(1, 4); + LMK2->CastSpell(LMK2, SPELL_SELF_REPAIR, true); //LMK2->SetHealth( LMK2->GetMaxHealth()/2 ); + VX001->CastSpell(VX001, SPELL_SELF_REPAIR, true); //VX001->SetHealth( VX001->GetMaxHealth()/2 ); + ACU->CastSpell(ACU, SPELL_SELF_REPAIR, true); //ACU->SetHealth( ACU->GetMaxHealth()/2 ); + if (hardmode) + { + LMK2->CastSpell(LMK2, SPELL_EMERGENCY_MODE, true); + VX001->CastSpell(VX001, SPELL_EMERGENCY_MODE, true); + ACU->CastSpell(ACU, SPELL_EMERGENCY_MODE, true); + } + me->SetInCombatWithZone(); + } + break; + case EVENT_FINISH: + { + Creature* LMK2 = GetLMK2(); + Creature* VX001 = GetVX001(); + Creature* ACU = GetACU(); + + if (!VX001 || !LMK2 || !ACU) + return; + + LMK2->GetMotionMaster()->Clear(); + LMK2->StopMoving(); + LMK2->InterruptNonMeleeSpells(false); + LMK2->AttackStop(); + LMK2->AI()->SetData(1, 0); + LMK2->DespawnOrUnsummon(7s); + LMK2->SetReactState(REACT_PASSIVE); + VX001->InterruptNonMeleeSpells(false); + VX001->AttackStop(); + VX001->AI()->SetData(1, 0); + VX001->DespawnOrUnsummon(7s); + VX001->SetReactState(REACT_PASSIVE); + ACU->InterruptNonMeleeSpells(false); + ACU->AttackStop(); + ACU->AI()->SetData(1, 0); + ACU->DespawnOrUnsummon(7s); + ACU->SetReactState(REACT_PASSIVE); + + Position exitPos = me->GetPosition(); + me->_ExitVehicle(&exitPos); + me->AttackStop(); + me->GetMotionMaster()->Clear(); + summons.DoAction(1337); // despawn summons of summons + summons.DespawnEntry(NPC_FLAMES_INITIAL); + summons.DespawnEntry(33576); + + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + + float angle = VX001->GetOrientation(); + float v_x = me->GetPositionX() + cos(angle) * 10.0f; + float v_y = me->GetPositionY() + std::sin(angle) * 10.0f; + me->GetMotionMaster()->MoveJump(v_x, v_y, 364.32f, 7.0f, 7.0f); + + DoCastSelf(SPELL_SLEEP_VISUAL_1); + + if (instance) + for( uint16 i = 0; i < 3; ++i ) + if (GameObject* door = instance->GetGameObject(DATA_GO_MIMIRON_DOOR_1 + i)) + if (door->GetGoState() != GO_STATE_ACTIVE ) + { + door->SetLootState(GO_READY); + door->UseDoorOrButton(0, false); + } + + instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_LEVIATHAN_MKII, 1, me); + + if (hardmode) + if (Creature* computer = me->SummonCreature(NPC_COMPUTER, 2746.7f, 2569.44f, 410.39f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000)) + computer->AI()->Talk(TALK_COMPUTER_TERMINATED); + + events.Reset(); + events.ScheduleEvent(EVENT_STAND_UP_FRIENDLY, 6s); + } + break; + case EVENT_STAND_UP_FRIENDLY: + me->RemoveAurasDueToSpell(SPELL_SLEEP_VISUAL_1); + DoCastSelf(SPELL_SLEEP_VISUAL_2); + me->SetFaction(FACTION_FRIENDLY); + events.ScheduleEvent(EVENT_SAY_VOLTRON_DEAD, 4s); + break; + case EVENT_SAY_VOLTRON_DEAD: + Talk(SAY_V07TRON_DEATH); + me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); + instance->SetBossState(BOSS_MIMIRON, DONE); + // spawn chest + if (uint32 chestId = (hardmode ? RAID_MODE(GO_MIMIRON_CHEST_HARD, GO_MIMIRON_CHEST_HERO_HARD) : RAID_MODE(GO_MIMIRON_CHEST, GO_MIMIRON_CHEST_HERO))) + { + if (GameObject* go = me->SummonGameObject(chestId, 2744.65f, 2569.46f, 364.397f, 0, 0, 0, 0, 0, 0)) + { + go->ReplaceAllGameObjectFlags((GameObjectFlags)0); + go->SetLootRecipient(me->GetMap()); + } + } + events.ScheduleEvent(EVENT_DISAPPEAR, 9s); + break; + case EVENT_DISAPPEAR: + DoCastSelf(SPELL_TELEPORT); + summons.DespawnAll(); + break; + } + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_TELEPORT) + { + me->DespawnOrUnsummon(); + instance->SetData(EVENT_KEEPER_TELEPORTED, DONE); + } + } + + void MoveInLineOfSight(Unit* /*mover*/) override {} + + void EnterEvadeMode(EvadeReason why) override + { + if (bIsEvading) + return; + bIsEvading = true; + + if (Creature* c = GetLMK2()) + c->AI()->EnterEvadeMode(why); + if (Creature* c = GetVX001()) + { + c->AI()->EnterEvadeMode(why); + c->DespawnOrUnsummon(); + } + if (Creature* c = GetACU()) + { + c->AI()->EnterEvadeMode(why); + c->DespawnOrUnsummon(); } - void CloseDoorAndButton() - { - if (pInstance) - for( uint16 i = 0; i < 3; ++i ) - if (ObjectGuid guid = pInstance->GetGuidData(DATA_GO_MIMIRON_DOOR_1 + i)) - if (GameObject* door = ObjectAccessor::GetGameObject(*me, guid)) - if (door->GetGoState() != GO_STATE_READY ) - { - door->SetLootState(GO_READY); - door->UseDoorOrButton(0, false); - } + summons.DoAction(1337); // despawn summons of summons - if (GameObject* button = me->FindNearestGameObject(GO_BUTTON, 200.0f)) - if (button->GetGoState() != GO_STATE_ACTIVE ) - { - button->SetLootState(GO_READY); - button->UseDoorOrButton(0, false); - } - } + me->RemoveAllAuras(); + me->ExitVehicle(); + BossAI::EnterEvadeMode(why); - void SetData(uint32 /*id*/, uint32 value) override + bIsEvading = false; + } + + void ResetGameObjects() + { + for (uint16 i = 0; i < 3; ++i) + if (GameObject* door = instance->GetGameObject(DATA_GO_MIMIRON_DOOR_1 + i)) + if (door->GetGoState() != GO_STATE_ACTIVE) + { + door->SetLootState(GO_READY); + door->UseDoorOrButton(0, false); + } + + if (GameObject* elevator = me->FindNearestGameObject(GO_MIMIRON_ELEVATOR, 200.0f)) { - switch (value) // end of phase 1-3, 4-6 for voltron + if (elevator->GetGoState() != GO_STATE_ACTIVE ) { + elevator->SetLootState(GO_READY); + elevator->SetByteValue(GAMEOBJECT_BYTES_1, 0, GO_STATE_ACTIVE); + } + elevator->EnableCollision(false); + } + + if (GameObject* button = me->FindNearestGameObject(GO_BUTTON, 200.0f)) + if (button->GetGoState() != GO_STATE_READY ) + { + button->SetLootState(GO_READY); + button->UseDoorOrButton(0, false); + button->RemoveGameObjectFlag(GO_FLAG_IN_USE); + } + } + + void CloseDoorAndButton() + { + for (uint16 i = 0; i < 3; ++i) + if (GameObject* door = instance->GetGameObject(DATA_GO_MIMIRON_DOOR_1 + i)) + if (door->GetGoState() != GO_STATE_READY) + { + door->SetLootState(GO_READY); + door->UseDoorOrButton(0, false); + } + + if (GameObject* button = me->FindNearestGameObject(GO_BUTTON, 200.0f)) + if (button->GetGoState() != GO_STATE_ACTIVE) + { + button->SetLootState(GO_READY); + button->UseDoorOrButton(0, false); + } + } + + void SetData(uint32 /*id*/, uint32 value) override + { + switch (value) // end of phase 1-3, 4-6 for voltron + { + case 1: + events.ScheduleEvent(EVENT_LMK2_RETREAT_INTERVAL, 5s); + break; + case 2: + events.ScheduleEvent(EVENT_VX001_EMOTESTATE_DEATH, 2500ms); + break; + case 3: + events.ScheduleEvent(EVENT_SAY_ACU_DEAD, 5s); + break; + case 4: + case 5: + case 6: + { + Creature* LMK2 = GetLMK2(); + Creature* VX001 = GetVX001(); + Creature* ACU = GetACU(); + if (!LMK2 || !VX001 || !ACU) + { + EnterEvadeMode(EVADE_REASON_OTHER); + return; + } + + Spell* s1 = LMK2->GetCurrentSpell(CURRENT_GENERIC_SPELL); + Spell* s2 = VX001->GetCurrentSpell(CURRENT_GENERIC_SPELL); + Spell* s3 = ACU->GetCurrentSpell(CURRENT_GENERIC_SPELL); + if (s1 && s2 && s3 && s1->GetSpellInfo()->Id == SPELL_SELF_REPAIR && s2->GetSpellInfo()->Id == SPELL_SELF_REPAIR && s3->GetSpellInfo()->Id == SPELL_SELF_REPAIR) + events.ScheduleEvent(EVENT_FINISH, 0ms); + } + break; + case 7: + hardmode = true; + break; + case 11: + bAchievProximityMine = true; + break; + case 12: + bAchievBombBot = true; + break; + case 13: + bAchievRocketStrike = true; + break; + } + } + + uint32 GetData(uint32 id) const override + { + switch (id) + { + case 1: + return (hardmode ? 1 : 0); + case 2: + return (berserk ? 1 : 0); + case 10: + return allowedFlameSpreadTime; + case 11: + return (bAchievProximityMine ? 1 : 0); + case 12: + return (bAchievBombBot ? 1 : 0); + case 13: + return (bAchievRocketStrike ? 1 : 0); + } + return 0; + } +}; + +struct npc_ulduar_leviathan_mkii : public ScriptedAI +{ + npc_ulduar_leviathan_mkii(Creature* pCreature) : ScriptedAI(pCreature) + { + instance = me->GetInstanceScript(); + bIsEvading = false; + } + + InstanceScript* instance; + EventMap events; + bool bIsEvading; + uint8 Phase; + + void Reset() override + { + Phase = 0; + if (Unit* c = GetS3()) + c->ExitVehicle(); // this should never happen! + if (Creature* c = me->SummonCreature(NPC_LEVIATHAN_MKII_CANNON, *me, TEMPSUMMON_MANUAL_DESPAWN)) + c->EnterVehicle(me, 3); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_AGGRESSIVE); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + + events.Reset(); + } + + void SetData(uint32 id, uint32 value) override + { + if (id == 1) // setting phase to start fighting + { + switch (value) + { + case 0: + Phase = 0; + events.Reset(); + break; case 1: - events.ScheduleEvent(EVENT_LMK2_RETREAT_INTERVAL, 5s); - break; - case 2: - events.ScheduleEvent(EVENT_VX001_EMOTESTATE_DEATH, 2500ms); - break; - case 3: - events.ScheduleEvent(EVENT_SAY_ACU_DEAD, 5s); + Phase = 1; + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + if (Unit* target = SelectTargetFromPlayerList(75.0f)) + AttackStart(target); + DoZoneInCombat(); + events.Reset(); + events.ScheduleEvent(EVENT_SPELL_NAPALM_SHELL, 3s); + events.ScheduleEvent(EVENT_SPELL_PLASMA_BLAST, 10s); + events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, 20s); + events.ScheduleEvent(EVENT_PROXIMITY_MINES_1, 6s); + if (Creature* c = GetMimiron()) + if (c->AI()->GetData(1)) + events.ScheduleEvent(EVENT_FLAME_SUPPRESSION_50000, 60s); break; case 4: - case 5: - case 6: - { - Creature* LMK2 = GetLMK2(); - Creature* VX001 = GetVX001(); - Creature* ACU = GetACU(); - if (!LMK2 || !VX001 || !ACU) - { - EnterEvadeMode(EVADE_REASON_OTHER); - return; - } - - Spell* s1 = LMK2->GetCurrentSpell(CURRENT_GENERIC_SPELL); - Spell* s2 = VX001->GetCurrentSpell(CURRENT_GENERIC_SPELL); - Spell* s3 = ACU->GetCurrentSpell(CURRENT_GENERIC_SPELL); - if (s1 && s2 && s3 && s1->GetSpellInfo()->Id == SPELL_SELF_REPAIR && s2->GetSpellInfo()->Id == SPELL_SELF_REPAIR && s3->GetSpellInfo()->Id == SPELL_SELF_REPAIR) - events.ScheduleEvent(EVENT_FINISH, 0ms); - } - break; - case 7: - hardmode = true; - break; - case 11: - bAchievProximityMine = true; - break; - case 12: - bAchievBombBot = true; - break; - case 13: - bAchievRocketStrike = true; + me->SetReactState(REACT_AGGRESSIVE); + DoResetThreatList(); + Phase = 4; + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + if (Unit* target = SelectTargetFromPlayerList(75.0f)) + AttackStart(target); + DoZoneInCombat(); + events.Reset(); + events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, 20s); + events.ScheduleEvent(EVENT_PROXIMITY_MINES_1, 6s); break; } } - - uint32 GetData(uint32 id) const override - { - switch (id) - { - case 1: - return (hardmode ? 1 : 0); - case 2: - return (berserk ? 1 : 0); - case 10: - return allowedFlameSpreadTime; - case 11: - return (bAchievProximityMine ? 1 : 0); - case 12: - return (bAchievBombBot ? 1 : 0); - case 13: - return (bAchievRocketStrike ? 1 : 0); - } - return 0; - } - }; -}; - -class npc_ulduar_leviathan_mkii : public CreatureScript -{ -public: - npc_ulduar_leviathan_mkii() : CreatureScript("npc_ulduar_leviathan_mkii") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct npc_ulduar_leviathan_mkiiAI : public ScriptedAI + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override { - npc_ulduar_leviathan_mkiiAI(Creature* pCreature) : ScriptedAI(pCreature) + if (damage >= me->GetHealth() || me->GetHealth() < 15000) { - pInstance = me->GetInstanceScript(); - bIsEvading = false; - } - - InstanceScript* pInstance; - EventMap events; - bool bIsEvading; - uint8 Phase; - - void Reset() override - { - Phase = 0; - if (Unit* c = GetS3()) - c->ExitVehicle(); // this should never happen! - if (Creature* c = me->SummonCreature(NPC_LEVIATHAN_MKII_CANNON, *me, TEMPSUMMON_MANUAL_DESPAWN)) - c->EnterVehicle(me, 3); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_AGGRESSIVE); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - - events.Reset(); - } - - void SetData(uint32 id, uint32 value) override - { - if (id == 1) // setting phase to start fighting + damage = 0; + if (me->GetReactState() == REACT_PASSIVE) + return; + me->SetReactState(REACT_PASSIVE); + if (Phase == 1) { - switch (value) + if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) { - case 0: - Phase = 0; - events.Reset(); - break; - case 1: - Phase = 1; - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - if (Unit* target = SelectTargetFromPlayerList(75.0f)) - AttackStart(target); - DoZoneInCombat(); - events.Reset(); - events.ScheduleEvent(EVENT_SPELL_NAPALM_SHELL, 3s); - events.ScheduleEvent(EVENT_SPELL_PLASMA_BLAST, 10s); - events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, 20s); - events.ScheduleEvent(EVENT_PROXIMITY_MINES_1, 6s); - if (Creature* c = GetMimiron()) - if (c->AI()->GetData(1)) - events.ScheduleEvent(EVENT_FLAME_SUPPRESSION_50000, 60s); - break; - case 4: - me->SetReactState(REACT_AGGRESSIVE); - DoResetThreatList(); - Phase = 4; - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - if (Unit* target = SelectTargetFromPlayerList(75.0f)) - AttackStart(target); - DoZoneInCombat(); - events.Reset(); - events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, 20s); - events.ScheduleEvent(EVENT_PROXIMITY_MINES_1, 6s); - break; + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->GetMotionMaster()->Clear(); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + SetData(1, 0); + me->InterruptNonMeleeSpells(false); + me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); + if (Unit* cannon = GetS3()) + cannon->ExitVehicle(); + me->GetMotionMaster()->MoveCharge(2795.076f, 2598.616f, 364.32f, 21.0f); + if (Creature* c = GetMimiron()) + c->AI()->SetData(0, 1); + } + } + else if (Phase == 4) + { + if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) + { + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->InterruptNonMeleeSpells(false); + me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); + me->CastSpell(me, SPELL_SELF_REPAIR, false); + if (Creature* c = GetMimiron()) + { + if (c->AI()->GetData(1)) + me->CastSpell(me, SPELL_EMERGENCY_MODE, true); + if (c->AI()->GetData(2)) + me->CastSpell(me, SPELL_BERSERK, true); + c->AI()->SetData(0, 4); + } } } } + } - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (!me->HasUnitState(UNIT_STATE_CASTING)) + DoMeleeAttackIfReady(); + + Unit* cannon = GetS3(); + if (!cannon || cannon->HasUnitState(UNIT_STATE_CASTING) || me->HasUnitState(UNIT_STATE_CASTING) || me->HasSilenceAura()) + return; + + switch (events.ExecuteEvent()) { - if (damage >= me->GetHealth() || me->GetHealth() < 15000) + case 0: + break; + case EVENT_SPELL_NAPALM_SHELL: + { + Player* pTarget = nullptr; + std::vector pList; + Map::PlayerList const& pl = me->GetMap()->GetPlayers(); + for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) + if (Player* plr = itr->GetSource()) + if (plr->IsAlive() && plr->GetDistance2d(me) > 15.0f ) + pList.push_back(plr); + + if (!pList.empty()) + pTarget = pList[urand(0, pList.size() - 1)]; + else + pTarget = (Player*)SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true); + + if (pTarget) + cannon->CastSpell(pTarget, SPELL_NAPALM_SHELL, false); + + events.Repeat(14s); + } + break; + case EVENT_SPELL_PLASMA_BLAST: + if (Unit* victim = me->GetVictim()) + { + Talk(EMOTE_PLASMA_BLAST); + cannon->CastSpell(victim, SPELL_PLASMA_BLAST, false); + } + events.Repeat(22s); + break; + case EVENT_SPELL_SHOCK_BLAST: + me->CastSpell(me->GetVictim(), SPELL_SHOCK_BLAST, false); + events.Repeat(30s); + events.ScheduleEvent(EVENT_PROXIMITY_MINES_1, 8s); + break; + case EVENT_PROXIMITY_MINES_1: + for (uint8 i = 0; i < 10; ++i) + { + me->CastSpell(me, SPELL_SUMMON_PROXIMITY_MINE, true); + } + break; + case EVENT_FLAME_SUPPRESSION_50000: + me->CastSpell(me, SPELL_FLAME_SUPPRESSANT_50000yd, false); + break; + } + } + + void MoveInLineOfSight(Unit* /*mover*/) override {} + + void KilledUnit(Unit* who) override + { + if (who->IsPlayer()) + if (Creature* c = GetMimiron()) { - damage = 0; - if (me->GetReactState() == REACT_PASSIVE) - return; - me->SetReactState(REACT_PASSIVE); if (Phase == 1) { - if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) - { - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->GetMotionMaster()->Clear(); - me->AttackStop(); - me->SetReactState(REACT_PASSIVE); - SetData(1, 0); - me->InterruptNonMeleeSpells(false); - me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); - if (Unit* cannon = GetS3()) - cannon->ExitVehicle(); - me->GetMotionMaster()->MoveCharge(2795.076f, 2598.616f, 364.32f, 21.0f); - if (Creature* c = GetMimiron()) - c->AI()->SetData(0, 1); - } - } - else if (Phase == 4) - { - if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - { - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->InterruptNonMeleeSpells(false); - me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); - me->CastSpell(me, SPELL_SELF_REPAIR, false); - if (Creature* c = GetMimiron()) - { - if (c->AI()->GetData(1)) - me->CastSpell(me, SPELL_EMERGENCY_MODE, true); - if (c->AI()->GetData(2)) - me->CastSpell(me, SPELL_BERSERK, true); - c->AI()->SetData(0, 4); - } - } - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (!me->HasUnitState(UNIT_STATE_CASTING)) - DoMeleeAttackIfReady(); - - Unit* cannon = GetS3(); - if (!cannon || cannon->HasUnitState(UNIT_STATE_CASTING) || me->HasUnitState(UNIT_STATE_CASTING) || me->HasSilenceAura()) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_SPELL_NAPALM_SHELL: - { - Player* pTarget = nullptr; - std::vector pList; - Map::PlayerList const& pl = me->GetMap()->GetPlayers(); - for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) - if (Player* plr = itr->GetSource()) - if (plr->IsAlive() && plr->GetDistance2d(me) > 15.0f ) - pList.push_back(plr); - - if (!pList.empty()) - pTarget = pList[urand(0, pList.size() - 1)]; - else - pTarget = (Player*)SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true); - - if (pTarget) - cannon->CastSpell(pTarget, SPELL_NAPALM_SHELL, false); - - events.Repeat(14s); - } - break; - case EVENT_SPELL_PLASMA_BLAST: - if (Unit* victim = me->GetVictim()) - { - Talk(EMOTE_PLASMA_BLAST); - cannon->CastSpell(victim, SPELL_PLASMA_BLAST, false); - } - events.Repeat(22s); - break; - case EVENT_SPELL_SHOCK_BLAST: - me->CastSpell(me->GetVictim(), SPELL_SHOCK_BLAST, false); - events.Repeat(30s); - events.ScheduleEvent(EVENT_PROXIMITY_MINES_1, 8s); - break; - case EVENT_PROXIMITY_MINES_1: - for (uint8 i = 0; i < 10; ++i) - { - me->CastSpell(me, SPELL_SUMMON_PROXIMITY_MINE, true); - } - break; - case EVENT_FLAME_SUPPRESSION_50000: - me->CastSpell(me, SPELL_FLAME_SUPPRESSANT_50000yd, false); - break; - } - } - - void MoveInLineOfSight(Unit* /*mover*/) override {} - - void KilledUnit(Unit* who) override - { - if (who->IsPlayer()) - if (Creature* c = GetMimiron()) - { - if (Phase == 1) - { - c->AI()->Talk(SAY_MKII_SLAY); - } - else - { - c->AI()->Talk(SAY_V07TRON_SLAY); - } - } - } - - void EnterEvadeMode(EvadeReason why) override - { - if (bIsEvading) - return; - bIsEvading = true; - - me->RemoveAllAuras(); - me->ExitVehicle(); - ScriptedAI::EnterEvadeMode(); - - if (Creature* mimiron = GetMimiron()) - mimiron->AI()->EnterEvadeMode(why); - - bIsEvading = false; - } - - void PassengerBoarded(Unit* p, int8 /*seat*/, bool apply) override - { - if (p->GetEntry() == NPC_LEVIATHAN_MKII_CANNON && !apply) - { - Unit::Kill(p, p); - p->ToCreature()->DespawnOrUnsummon(6s); - } - } - - Unit* GetS3() - { - if (Vehicle* vk = me->GetVehicleKit()) - if (Unit* cannon = vk->GetPassenger(3)) - return cannon; - - return 0; - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - if (spell->Id == SPELL_SELF_REPAIR) - { - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_AGGRESSIVE); - } - } - }; -}; - -class npc_ulduar_vx001 : public CreatureScript -{ -public: - npc_ulduar_vx001() : CreatureScript("npc_ulduar_vx001") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct npc_ulduar_vx001AI : public ScriptedAI - { - npc_ulduar_vx001AI(Creature* pCreature) : ScriptedAI(pCreature) - { - pInstance = me->GetInstanceScript(); - bIsEvading = false; - } - - InstanceScript* pInstance; - EventMap events; - bool bIsEvading; - uint8 Phase; - bool fighting; - bool leftarm; - uint32 spinningUpOrientation; - uint16 spinningUpTimer; - - void Reset() override - { - Phase = 0; - fighting = false; - leftarm = false; - spinningUpTimer = 0; - me->SetRegeneratingHealth(false); - events.Reset(); - } - - void AttackStart(Unit* /*who*/) override {} - - void SetData(uint32 id, uint32 value) override - { - if (id == 1) // setting phase to start fighting - { - switch (value) - { - case 0: - Phase = 0; - fighting = false; - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - events.Reset(); - break; - case 2: - Phase = 2; - fighting = true; - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_SPELL_CAST_OMNI); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - events.Reset(); - events.ScheduleEvent(EVENT_SPELL_HEAT_WAVE, 10s); - events.ScheduleEvent(EVENT_SPELL_ROCKET_STRIKE, 16s); - events.ScheduleEvent(EVENT_SPELL_RAPID_BURST, 0ms); - events.ScheduleEvent(EVENT_SPELL_SPINNING_UP, 30s); - events.ScheduleEvent(EVENT_REINSTALL_ROCKETS, 3s); - if (Creature* c = GetMimiron()) - if (c->AI()->GetData(1)) - { - events.ScheduleEvent(EVENT_FLAME_SUPPRESSION_10, 7s); - events.ScheduleEvent(EVENT_FROST_BOMB, 1s); - } - break; - case 4: - Phase = 4; - fighting = true; - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - events.Reset(); - events.ScheduleEvent(EVENT_REINSTALL_ROCKETS, 3s); - events.ScheduleEvent(EVENT_SPELL_ROCKET_STRIKE, 16s); - events.ScheduleEvent(EVENT_HAND_PULSE, 1ms); - events.ScheduleEvent(EVENT_SPELL_SPINNING_UP, 30s); - if (Creature* c = GetMimiron()) - if (c->AI()->GetData(1)) - events.ScheduleEvent(EVENT_FROST_BOMB, 1s); - break; - } - } - } - - uint32 GetData(uint32 /*id*/) const override - { - return spinningUpOrientation; - } - - void DoAction(int32 action) override - { - if (action == 1337) - if (Vehicle* vk = me->GetVehicleKit()) - for (uint8 i = 0; i < 2; ++i) - if (Unit* r = vk->GetPassenger(5 + i)) - if (r->IsCreature()) - r->ToCreature()->DespawnOrUnsummon(1ms); - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (damage >= me->GetHealth() || me->GetHealth() < 15000) - { - damage = 0; - if (me->GetReactState() == REACT_PASSIVE) - return; - me->SetReactState(REACT_PASSIVE); - if (Phase == 2) - { - if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) - { - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - SetData(1, 0); - me->InterruptNonMeleeSpells(false); - me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); - me->SendMeleeAttackStop(); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CUSTOM_SPELL_06); - me->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_06); - if (Creature* c = GetMimiron()) - c->AI()->SetData(0, 2); - } - } - else if (Phase == 4) - { - if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - { - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->InterruptNonMeleeSpells(false); - me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); - me->CastSpell(me, SPELL_SELF_REPAIR, false); - if (Creature* c = GetMimiron()) - { - if (c->AI()->GetData(1)) - me->CastSpell(me, SPELL_EMERGENCY_MODE, true); - if (c->AI()->GetData(2)) - me->CastSpell(me, SPELL_BERSERK, true); - c->AI()->SetData(0, 5); - } - } - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!fighting) - return; - - events.Update(diff); - - if (spinningUpTimer) // executed about a second after starting casting to ensure players can see the correct direction - { - if (spinningUpTimer <= diff) - { - float angle = (spinningUpOrientation * 2 * M_PI) / 100.0f; - me->SetFacingTo(angle); - - spinningUpTimer = 0; + c->AI()->Talk(SAY_MKII_SLAY); } else - spinningUpTimer -= diff; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_SPELL_HEAT_WAVE: - me->CastSpell(me, SPELL_HEAT_WAVE, true); - events.Repeat(10s); - break; - case EVENT_SPELL_ROCKET_STRIKE: - if (Vehicle* vk = me->GetVehicleKit()) - { - for( int i = 0; i < (Phase / 2); ++i ) - { - uint8 index = (Phase == 2 ? rand() % 2 : i); - if (Unit* r = vk->GetPassenger(5 + index)) - if (Player* temp = SelectTargetFromPlayerList(100.0f)) - { - if (Creature* trigger = me->SummonCreature(NPC_ROCKET_STRIKE_N, temp->GetPositionX(), temp->GetPositionY(), temp->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 6000)) - trigger->CastSpell(trigger, SPELL_ROCKET_STRIKE_AURA, true); - Position exitPos = r->GetPosition(); - exitPos.m_positionX += cos(me->GetOrientation()) * 2.35f; - exitPos.m_positionY += std::sin(me->GetOrientation()) * 2.35f; - exitPos.m_positionZ += 2.0f * Phase; - r->_ExitVehicle(&exitPos); - me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE, r->GetGUID()); - if (r->IsCreature()) - r->ToCreature()->AI()->SetData(0, 0); - } - } - events.Repeat(20s); - events.ScheduleEvent(EVENT_REINSTALL_ROCKETS, 10s); - } - break; - case EVENT_REINSTALL_ROCKETS: - if (Vehicle* vk = me->GetVehicleKit()) - { - for (uint8 i = 5; i <= 6; ++i) - if (!vk->GetPassenger(i)) - if (TempSummon* accessory = me->SummonCreature(NPC_ROCKET_VISUAL, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 4.0f, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN)) - if (!me->HandleSpellClick(accessory, i)) - accessory->UnSummon(); - } - break; - case EVENT_SPELL_RAPID_BURST: - if (Player* p = SelectTargetFromPlayerList(80.0f)) - { - me->CastSpell(p, SPELL_RAPID_BURST, true); - me->SetFacingToObject(p); - } - events.Repeat(3200ms); - break; - case EVENT_HAND_PULSE: - if (Player* p = SelectTargetFromPlayerList(80.0f)) - { - me->SetFacingToObject(p); - if (Unit* vb = me->GetVehicleBase()) - { - vb->SendMeleeAttackStop(); - vb->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - - if (!leftarm) - { - vb->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_03); - me->CastSpell(p, SPELL_HAND_PULSE_R, false); - } - else - { - vb->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_04); - me->CastSpell(p, SPELL_HAND_PULSE_L, false); - } - } - - leftarm = !leftarm; - } - events.Repeat(1750ms); - break; - case EVENT_SPELL_SPINNING_UP: - events.Repeat(45s); - if (Player* p = SelectTargetFromPlayerList(80.0f)) - { - float angle = me->GetAngle(p); - - spinningUpOrientation = (uint32)((angle * 100.0f) / (2 * M_PI)); - spinningUpTimer = 1500; - me->SetFacingTo(angle); - me->CastSpell(p, SPELL_SPINNING_UP, true); - if (Unit* vehicle = me->GetVehicleBase()) - { - vehicle->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_CUSTOM_SPELL_01); - vehicle->HandleEmoteCommand(EMOTE_STATE_CUSTOM_SPELL_01); - } - events.RescheduleEvent((Phase == 2 ? EVENT_SPELL_RAPID_BURST : EVENT_HAND_PULSE), 14s + 500ms); - } - break; - case EVENT_FLAME_SUPPRESSION_10: - me->CastSpell(me, SPELL_FLAME_SUPPRESSANT_10yd, false); - events.Repeat(10s); - break; - case EVENT_FROST_BOMB: - me->CastCustomSpell(SPELL_VX001_FROST_BOMB, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false); - events.Repeat(45s); - break; - } - } - - void MoveInLineOfSight(Unit* /*mover*/) override {} - - void KilledUnit(Unit* who) override - { - if (who->IsPlayer()) - if (Creature* c = GetMimiron()) { - if (Phase == 2) - { - c->AI()->Talk(SAY_VX001_SLAY); - } - else - { - c->AI()->Talk(SAY_V07TRON_SLAY); - } + c->AI()->Talk(SAY_V07TRON_SLAY); } - } - - void EnterEvadeMode(EvadeReason why) override - { - if (bIsEvading) - return; - bIsEvading = true; - - me->RemoveAllAuras(); - me->ExitVehicle(); - _EnterEvadeMode(); - Reset(); - if (Creature* mimiron = GetMimiron()) - mimiron->AI()->EnterEvadeMode(why); - - bIsEvading = false; - } - - void PassengerBoarded(Unit* p, int8 /*seat*/, bool apply) override - { - if (p->GetEntry() == NPC_ROCKET_VISUAL && !apply) - p->ToCreature()->DespawnOrUnsummon(8s); - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - if (spell->Id == SPELL_SELF_REPAIR) - { - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_AGGRESSIVE); } - } - }; -}; - -class npc_ulduar_aerial_command_unit : public CreatureScript -{ -public: - npc_ulduar_aerial_command_unit() : CreatureScript("npc_ulduar_aerial_command_unit") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct npc_ulduar_aerial_command_unitAI : public ScriptedAI + void EnterEvadeMode(EvadeReason why) override { - npc_ulduar_aerial_command_unitAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me) + if (bIsEvading) + return; + bIsEvading = true; + + me->RemoveAllAuras(); + me->ExitVehicle(); + ScriptedAI::EnterEvadeMode(); + + if (Creature* mimiron = GetMimiron()) + mimiron->AI()->EnterEvadeMode(why); + + bIsEvading = false; + } + + void PassengerBoarded(Unit* p, int8 /*seat*/, bool apply) override + { + if (p->GetEntry() == NPC_LEVIATHAN_MKII_CANNON && !apply) { - pInstance = me->GetInstanceScript(); - bIsEvading = false; - immobilized = false; - me->SetDisableGravity(true); + Unit::Kill(p, p); + p->ToCreature()->DespawnOrUnsummon(6s); } + } - InstanceScript* pInstance; - EventMap events; - SummonList summons; - bool bIsEvading; - uint8 Phase; - bool immobilized; + Unit* GetS3() + { + if (Vehicle* vk = me->GetVehicleKit()) + if (Unit* cannon = vk->GetPassenger(3)) + return cannon; - void Reset() override + return 0; + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_SELF_REPAIR) { - Phase = 0; - events.Reset(); - summons.DespawnAll(); + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_AGGRESSIVE); } + } +}; - void AttackStart(Unit* who) override +struct npc_ulduar_vx001 : public ScriptedAI +{ + npc_ulduar_vx001(Creature* pCreature) : ScriptedAI(pCreature) + { + instance = me->GetInstanceScript(); + bIsEvading = false; + } + + InstanceScript* instance; + EventMap events; + bool bIsEvading; + uint8 Phase; + bool fighting; + bool leftarm; + uint32 spinningUpOrientation; + uint16 spinningUpTimer; + + void Reset() override + { + Phase = 0; + fighting = false; + leftarm = false; + spinningUpTimer = 0; + me->SetRegeneratingHealth(false); + events.Reset(); + } + + void AttackStart(Unit* /*who*/) override {} + + void SetData(uint32 id, uint32 value) override + { + if (id == 1) // setting phase to start fighting { - if (who) - me->Attack(who, true); // skip following - } - - void SetData(uint32 id, uint32 value) override - { - if (id == 1) // setting phase to start fighting - { - switch (value) - { - case 0: - Phase = 0; - events.Reset(); - immobilized = false; - break; - case 3: - Phase = 3; - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - if (Unit* target = SelectTargetFromPlayerList(75.0f)) - AttackStart(target); - DoZoneInCombat(); - events.Reset(); - events.ScheduleEvent(EVENT_SPELL_PLASMA_BALL, 0ms); - events.ScheduleEvent(EVENT_SUMMON_BOMB_BOT, 15s); - events.ScheduleEvent(EVENT_SUMMON_ASSAULT_BOT, 1s); - events.ScheduleEvent(EVENT_SUMMON_JUNK_BOT, 10s); - if (Creature* c = GetMimiron()) - if (c->AI()->GetData(1)) - events.ScheduleEvent(EVENT_SUMMON_EMERGENCY_FIRE_BOTS, 0ms); - break; - case 4: - me->SetReactState(REACT_AGGRESSIVE); - DoResetThreatList(); - Phase = 4; - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - if (Unit* target = SelectTargetFromPlayerList(75.0f)) - AttackStart(target); - DoZoneInCombat(); - events.Reset(); - events.ScheduleEvent(EVENT_SPELL_PLASMA_BALL, 0ms); - } - } - else if (id == 2 && !immobilized && Phase == 3) // magnetic core - { - immobilized = true; - events.ScheduleEvent(EVENT_MAGNETIC_CORE_PULL_DOWN, 2s); - } - } - - void DoAction(int32 param) override - { - if (param == 1337) - summons.DespawnAll(); - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (damage >= me->GetHealth() || me->GetHealth() < 15000) - { - damage = 0; - if (me->GetReactState() == REACT_PASSIVE) - return; - me->SetReactState(REACT_PASSIVE); - if (Phase == 3) - { - if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) - { - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->GetMotionMaster()->Clear(); - me->StopMoving(); - me->AttackStop(); - me->SetReactState(REACT_PASSIVE); - SetData(1, 0); - me->InterruptNonMeleeSpells(false); - me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); - - me->GetMotionMaster()->MovePoint(0, 2744.65f, 2569.46f, 381.34f); - - if (Creature* c = GetMimiron()) - c->AI()->SetData(0, 3); - } - } - else if (Phase == 4) - { - if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - { - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->InterruptNonMeleeSpells(false); - me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); - me->CastSpell(me, SPELL_SELF_REPAIR, false); - if (Creature* c = GetMimiron()) - { - if (c->AI()->GetData(1)) - me->CastSpell(me, SPELL_EMERGENCY_MODE, true); - if (c->AI()->GetData(2)) - me->CastSpell(me, SPELL_BERSERK, true); - c->AI()->SetData(0, 6); - } - } - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - // following :D - if (Phase == 3 && !immobilized) - if (Unit* victim = me->GetVictim()) - if (me->GetExactDist2d(victim) > 25.0f ) - { - float angle = victim->GetAngle(me->GetPositionX(), me->GetPositionY()); - me->SetOrientation( me->GetAngle(victim->GetPositionX(), victim->GetPositionY())); - float x = victim->GetPositionX() + 15.0f * cos(angle); - float y = victim->GetPositionY() + 15.0f * std::sin(angle); - - // check if there's magnetic core in line of movement - Creature* mc = nullptr; - std::list cl; - me->GetCreaturesWithEntryInRange(cl, me->GetExactDist2d(victim), NPC_MAGNETIC_CORE); - for( std::list::iterator itr = cl.begin(); itr != cl.end(); ++itr ) - { - if ((*itr)->IsInBetween(me, victim, 4.0f) && (*itr)->GetExactDist2d(victim) >= 10.0f) // don't come very close just because there's a magnetic core - { - x = (*itr)->GetPositionX(); - y = (*itr)->GetPositionY(); - mc = (*itr); - break; - } - } - - float speed = me->GetExactDist(x, y, 381.34f); - me->GetMotionMaster()->MovePoint(0, x, y, 381.34f, FORCED_MOVEMENT_NONE, speed); - if (mc) - { - mc->AI()->SetData(0, 0); - SetData(2, 1); - } - } - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) + switch (value) { case 0: + Phase = 0; + fighting = false; + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + events.Reset(); break; - case EVENT_SPELL_PLASMA_BALL: - if (!immobilized) - DoCastVictim(SPELL_PLASMA_BALL); - events.Repeat(3s); + case 2: + Phase = 2; + fighting = true; + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_SPELL_CAST_OMNI); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + events.Reset(); + events.ScheduleEvent(EVENT_SPELL_HEAT_WAVE, 10s); + events.ScheduleEvent(EVENT_SPELL_ROCKET_STRIKE, 16s); + events.ScheduleEvent(EVENT_SPELL_RAPID_BURST, 0ms); + events.ScheduleEvent(EVENT_SPELL_SPINNING_UP, 30s); + events.ScheduleEvent(EVENT_REINSTALL_ROCKETS, 3s); + if (Creature* c = GetMimiron()) + if (c->AI()->GetData(1)) + { + events.ScheduleEvent(EVENT_FLAME_SUPPRESSION_10, 7s); + events.ScheduleEvent(EVENT_FROST_BOMB, 1s); + } break; - case EVENT_SUMMON_BOMB_BOT: - if (!immobilized) - me->CastSpell(me, SPELL_SUMMON_BOMB_BOT, false); - events.Repeat(15s); + case 4: + Phase = 4; + fighting = true; + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + events.Reset(); + events.ScheduleEvent(EVENT_REINSTALL_ROCKETS, 3s); + events.ScheduleEvent(EVENT_SPELL_ROCKET_STRIKE, 16s); + events.ScheduleEvent(EVENT_HAND_PULSE, 1ms); + events.ScheduleEvent(EVENT_SPELL_SPINNING_UP, 30s); + if (Creature* c = GetMimiron()) + if (c->AI()->GetData(1)) + events.ScheduleEvent(EVENT_FROST_BOMB, 1s); break; - case EVENT_SUMMON_ASSAULT_BOT: - if (GameObject* pad = me->FindNearestGameObject(RAND(194742, 194746, 194745), 200.0f)) - if (Creature* trigger = me->SummonCreature(NPC_BOT_SUMMON_TRIGGER, *pad, TEMPSUMMON_TIMED_DESPAWN, 15000)) - trigger->AI()->DoAction(2); - events.Repeat(30s); - break; - case EVENT_SUMMON_JUNK_BOT: - if (GameObject* pad = me->FindNearestGameObject(RAND(194741, 194744, 194747), 200.0f)) - if (Creature* trigger = me->SummonCreature(NPC_BOT_SUMMON_TRIGGER, *pad, TEMPSUMMON_TIMED_DESPAWN, 15000)) - trigger->AI()->DoAction(1); - events.Repeat(10s); - break; - case EVENT_SUMMON_EMERGENCY_FIRE_BOTS: + } + } + } + + uint32 GetData(uint32 /*id*/) const override + { + return spinningUpOrientation; + } + + void DoAction(int32 action) override + { + if (action == 1337) + if (Vehicle* vk = me->GetVehicleKit()) + for (uint8 i = 0; i < 2; ++i) + if (Unit* r = vk->GetPassenger(5 + i)) + if (r->IsCreature()) + r->ToCreature()->DespawnOrUnsummon(1ms); + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (damage >= me->GetHealth() || me->GetHealth() < 15000) + { + damage = 0; + if (me->GetReactState() == REACT_PASSIVE) + return; + me->SetReactState(REACT_PASSIVE); + if (Phase == 2) + { + if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + SetData(1, 0); + me->InterruptNonMeleeSpells(false); + me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); + me->SendMeleeAttackStop(); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CUSTOM_SPELL_06); + me->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_06); + if (Creature* c = GetMimiron()) + c->AI()->SetData(0, 2); + } + } + else if (Phase == 4) + { + if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) + { + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->InterruptNonMeleeSpells(false); + me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); + me->CastSpell(me, SPELL_SELF_REPAIR, false); + if (Creature* c = GetMimiron()) { - uint32 ids[3] = {194740, 194743, 194748}; - for( uint8 i = 0; i < 3; ++i ) - if (GameObject* pad = me->FindNearestGameObject(ids[i], 200.0f)) - if (Creature* trigger = me->SummonCreature(NPC_BOT_SUMMON_TRIGGER, *pad, TEMPSUMMON_MANUAL_DESPAWN)) - trigger->AI()->DoAction(3); - events.Repeat(45s); + if (c->AI()->GetData(1)) + me->CastSpell(me, SPELL_EMERGENCY_MODE, true); + if (c->AI()->GetData(2)) + me->CastSpell(me, SPELL_BERSERK, true); + c->AI()->SetData(0, 5); } - break; - case EVENT_MAGNETIC_CORE_PULL_DOWN: - me->CastSpell(me, SPELL_MAGNETIC_CORE, true); - me->CastSpell(me, SPELL_SPINNING, true); - me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), 365.34f, FORCED_MOVEMENT_NONE, me->GetExactDist(me->GetPositionX(), me->GetPositionY(), 365.34f)); - events.ScheduleEvent(EVENT_MAGNETIC_CORE_FREE, 20s); - break; - case EVENT_MAGNETIC_CORE_FREE: - me->RemoveAura(SPELL_SPINNING); - me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), 381.34f, FORCED_MOVEMENT_NONE, me->GetDistance(me->GetPositionX(), me->GetPositionY(), 381.34f)); - events.ScheduleEvent(EVENT_MAGNETIC_CORE_REMOVE_IMMOBILIZE, 1s); - break; - case EVENT_MAGNETIC_CORE_REMOVE_IMMOBILIZE: + } + } + } + } + + void UpdateAI(uint32 diff) override + { + if (!fighting) + return; + + events.Update(diff); + + if (spinningUpTimer) // executed about a second after starting casting to ensure players can see the correct direction + { + if (spinningUpTimer <= diff) + { + float angle = (spinningUpOrientation * 2 * M_PI) / 100.0f; + me->SetFacingTo(angle); + + spinningUpTimer = 0; + } + else + spinningUpTimer -= diff; + } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case 0: + break; + case EVENT_SPELL_HEAT_WAVE: + me->CastSpell(me, SPELL_HEAT_WAVE, true); + events.Repeat(10s); + break; + case EVENT_SPELL_ROCKET_STRIKE: + if (Vehicle* vk = me->GetVehicleKit()) + { + for( int i = 0; i < (Phase / 2); ++i ) + { + uint8 index = (Phase == 2 ? rand() % 2 : i); + if (Unit* r = vk->GetPassenger(5 + index)) + if (Player* temp = SelectTargetFromPlayerList(100.0f)) + { + if (Creature* trigger = me->SummonCreature(NPC_ROCKET_STRIKE_N, temp->GetPositionX(), temp->GetPositionY(), temp->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 6000)) + trigger->CastSpell(trigger, SPELL_ROCKET_STRIKE_AURA, true); + Position exitPos = r->GetPosition(); + exitPos.m_positionX += cos(me->GetOrientation()) * 2.35f; + exitPos.m_positionY += std::sin(me->GetOrientation()) * 2.35f; + exitPos.m_positionZ += 2.0f * Phase; + r->_ExitVehicle(&exitPos); + me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE, r->GetGUID()); + if (r->IsCreature()) + r->ToCreature()->AI()->SetData(0, 0); + } + } + events.Repeat(20s); + events.ScheduleEvent(EVENT_REINSTALL_ROCKETS, 10s); + } + break; + case EVENT_REINSTALL_ROCKETS: + if (Vehicle* vk = me->GetVehicleKit()) + { + for (uint8 i = 5; i <= 6; ++i) + if (!vk->GetPassenger(i)) + if (TempSummon* accessory = me->SummonCreature(NPC_ROCKET_VISUAL, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 4.0f, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN)) + if (!me->HandleSpellClick(accessory, i)) + accessory->UnSummon(); + } + break; + case EVENT_SPELL_RAPID_BURST: + if (Player* p = SelectTargetFromPlayerList(80.0f)) + { + me->CastSpell(p, SPELL_RAPID_BURST, true); + me->SetFacingToObject(p); + } + events.Repeat(3200ms); + break; + case EVENT_HAND_PULSE: + if (Player* p = SelectTargetFromPlayerList(80.0f)) + { + me->SetFacingToObject(p); + if (Unit* vb = me->GetVehicleBase()) + { + vb->SendMeleeAttackStop(); + vb->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + + if (!leftarm) + { + vb->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_03); + me->CastSpell(p, SPELL_HAND_PULSE_R, false); + } + else + { + vb->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_04); + me->CastSpell(p, SPELL_HAND_PULSE_L, false); + } + } + + leftarm = !leftarm; + } + events.Repeat(1750ms); + break; + case EVENT_SPELL_SPINNING_UP: + events.Repeat(45s); + if (Player* p = SelectTargetFromPlayerList(80.0f)) + { + float angle = me->GetAngle(p); + + spinningUpOrientation = (uint32)((angle * 100.0f) / (2 * M_PI)); + spinningUpTimer = 1500; + me->SetFacingTo(angle); + me->CastSpell(p, SPELL_SPINNING_UP, true); + if (Unit* vehicle = me->GetVehicleBase()) + { + vehicle->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_CUSTOM_SPELL_01); + vehicle->HandleEmoteCommand(EMOTE_STATE_CUSTOM_SPELL_01); + } + events.RescheduleEvent((Phase == 2 ? EVENT_SPELL_RAPID_BURST : EVENT_HAND_PULSE), 14s + 500ms); + } + break; + case EVENT_FLAME_SUPPRESSION_10: + me->CastSpell(me, SPELL_FLAME_SUPPRESSANT_10yd, false); + events.Repeat(10s); + break; + case EVENT_FROST_BOMB: + me->CastCustomSpell(SPELL_VX001_FROST_BOMB, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false); + events.Repeat(45s); + break; + } + } + + void MoveInLineOfSight(Unit* /*mover*/) override {} + + void KilledUnit(Unit* who) override + { + if (who->IsPlayer()) + if (Creature* c = GetMimiron()) + { + if (Phase == 2) + { + c->AI()->Talk(SAY_VX001_SLAY); + } + else + { + c->AI()->Talk(SAY_V07TRON_SLAY); + } + } + } + + void EnterEvadeMode(EvadeReason why) override + { + if (bIsEvading) + return; + bIsEvading = true; + + me->RemoveAllAuras(); + me->ExitVehicle(); + _EnterEvadeMode(); + Reset(); + if (Creature* mimiron = GetMimiron()) + mimiron->AI()->EnterEvadeMode(why); + + bIsEvading = false; + } + + void PassengerBoarded(Unit* p, int8 /*seat*/, bool apply) override + { + if (p->GetEntry() == NPC_ROCKET_VISUAL && !apply) + p->ToCreature()->DespawnOrUnsummon(8s); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_SELF_REPAIR) + { + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_AGGRESSIVE); + } + } +}; + +struct npc_ulduar_aerial_command_unit : public ScriptedAI +{ + npc_ulduar_aerial_command_unit(Creature* pCreature) : ScriptedAI(pCreature), summons(me) + { + instance = me->GetInstanceScript(); + bIsEvading = false; + immobilized = false; + me->SetDisableGravity(true); + } + + InstanceScript* instance; + EventMap events; + SummonList summons; + bool bIsEvading; + uint8 Phase; + bool immobilized; + + void Reset() override + { + Phase = 0; + events.Reset(); + summons.DespawnAll(); + } + + void AttackStart(Unit* who) override + { + if (who) + me->Attack(who, true); // skip following + } + + void SetData(uint32 id, uint32 value) override + { + if (id == 1) // setting phase to start fighting + { + switch (value) + { + case 0: + Phase = 0; + events.Reset(); immobilized = false; break; + case 3: + Phase = 3; + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + if (Unit* target = SelectTargetFromPlayerList(75.0f)) + AttackStart(target); + DoZoneInCombat(); + events.Reset(); + events.ScheduleEvent(EVENT_SPELL_PLASMA_BALL, 0ms); + events.ScheduleEvent(EVENT_SUMMON_BOMB_BOT, 15s); + events.ScheduleEvent(EVENT_SUMMON_ASSAULT_BOT, 1s); + events.ScheduleEvent(EVENT_SUMMON_JUNK_BOT, 10s); + if (Creature* c = GetMimiron()) + if (c->AI()->GetData(1)) + events.ScheduleEvent(EVENT_SUMMON_EMERGENCY_FIRE_BOTS, 0ms); + break; + case 4: + me->SetReactState(REACT_AGGRESSIVE); + DoResetThreatList(); + Phase = 4; + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + if (Unit* target = SelectTargetFromPlayerList(75.0f)) + AttackStart(target); + DoZoneInCombat(); + events.Reset(); + events.ScheduleEvent(EVENT_SPELL_PLASMA_BALL, 0ms); } } - - void MoveInLineOfSight(Unit* /*mover*/) override {} - - void KilledUnit(Unit* who) override + else if (id == 2 && !immobilized && Phase == 3) // magnetic core { - if (who->IsPlayer()) - if (Creature* c = GetMimiron()) - { - if (Phase == 3) - { - c->AI()->Talk(SAY_AERIAL_SLAY); - } - else - { - c->AI()->Talk(SAY_V07TRON_SLAY); - } - } + immobilized = true; + events.ScheduleEvent(EVENT_MAGNETIC_CORE_PULL_DOWN, 2s); } - - void EnterEvadeMode(EvadeReason why) override - { - if (bIsEvading) - return; - bIsEvading = true; - - me->RemoveAllAuras(); - me->ExitVehicle(); - _EnterEvadeMode(); - Reset(); - if (Creature* mimiron = GetMimiron()) - mimiron->AI()->EnterEvadeMode(why); - - bIsEvading = false; - } - - void JustSummoned(Creature* s) override - { - summons.Summon(s); - if (s->GetEntry() == NPC_BOMB_BOT) - s->m_positionZ = 364.34f; - } - - void SummonedCreatureDespawn(Creature* s) override - { - summons.Despawn(s); - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override - { - if (spell->Id == SPELL_SELF_REPAIR) - { - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_AGGRESSIVE); - } - } - }; -}; - -class npc_ulduar_proximity_mine : public CreatureScript -{ -public: - npc_ulduar_proximity_mine() : CreatureScript("npc_ulduar_proximity_mine") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct npc_ulduar_proximity_mineAI : public ScriptedAI + void DoAction(int32 param) override { - npc_ulduar_proximity_mineAI(Creature* pCreature) : ScriptedAI(pCreature) + if (param == 1337) + summons.DespawnAll(); + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (damage >= me->GetHealth() || me->GetHealth() < 15000) + { + damage = 0; + if (me->GetReactState() == REACT_PASSIVE) + return; + me->SetReactState(REACT_PASSIVE); + if (Phase == 3) + { + if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->GetMotionMaster()->Clear(); + me->StopMoving(); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + SetData(1, 0); + me->InterruptNonMeleeSpells(false); + me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); + + me->GetMotionMaster()->MovePoint(0, 2744.65f, 2569.46f, 381.34f); + + if (Creature* c = GetMimiron()) + c->AI()->SetData(0, 3); + } + } + else if (Phase == 4) + { + if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) + { + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->InterruptNonMeleeSpells(false); + me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE); + me->CastSpell(me, SPELL_SELF_REPAIR, false); + if (Creature* c = GetMimiron()) + { + if (c->AI()->GetData(1)) + me->CastSpell(me, SPELL_EMERGENCY_MODE, true); + if (c->AI()->GetData(2)) + me->CastSpell(me, SPELL_BERSERK, true); + c->AI()->SetData(0, 6); + } + } + } + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + // following :D + if (Phase == 3 && !immobilized) + if (Unit* victim = me->GetVictim()) + if (me->GetExactDist2d(victim) > 25.0f ) + { + float angle = victim->GetAngle(me->GetPositionX(), me->GetPositionY()); + me->SetOrientation( me->GetAngle(victim->GetPositionX(), victim->GetPositionY())); + float x = victim->GetPositionX() + 15.0f * cos(angle); + float y = victim->GetPositionY() + 15.0f * std::sin(angle); + + // check if there's magnetic core in line of movement + Creature* mc = nullptr; + std::list cl; + me->GetCreaturesWithEntryInRange(cl, me->GetExactDist2d(victim), NPC_MAGNETIC_CORE); + for( std::list::iterator itr = cl.begin(); itr != cl.end(); ++itr ) + { + if ((*itr)->IsInBetween(me, victim, 4.0f) && (*itr)->GetExactDist2d(victim) >= 10.0f) // don't come very close just because there's a magnetic core + { + x = (*itr)->GetPositionX(); + y = (*itr)->GetPositionY(); + mc = (*itr); + break; + } + } + + float speed = me->GetExactDist(x, y, 381.34f); + me->GetMotionMaster()->MovePoint(0, x, y, 381.34f, FORCED_MOVEMENT_NONE, speed); + if (mc) + { + mc->AI()->SetData(0, 0); + SetData(2, 1); + } + } + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case 0: + break; + case EVENT_SPELL_PLASMA_BALL: + if (!immobilized) + DoCastVictim(SPELL_PLASMA_BALL); + events.Repeat(3s); + break; + case EVENT_SUMMON_BOMB_BOT: + if (!immobilized) + me->CastSpell(me, SPELL_SUMMON_BOMB_BOT, false); + events.Repeat(15s); + break; + case EVENT_SUMMON_ASSAULT_BOT: + if (GameObject* pad = me->FindNearestGameObject(RAND(194742, 194746, 194745), 200.0f)) + if (Creature* trigger = me->SummonCreature(NPC_BOT_SUMMON_TRIGGER, *pad, TEMPSUMMON_TIMED_DESPAWN, 15000)) + trigger->AI()->DoAction(2); + events.Repeat(30s); + break; + case EVENT_SUMMON_JUNK_BOT: + if (GameObject* pad = me->FindNearestGameObject(RAND(194741, 194744, 194747), 200.0f)) + if (Creature* trigger = me->SummonCreature(NPC_BOT_SUMMON_TRIGGER, *pad, TEMPSUMMON_TIMED_DESPAWN, 15000)) + trigger->AI()->DoAction(1); + events.Repeat(10s); + break; + case EVENT_SUMMON_EMERGENCY_FIRE_BOTS: + { + uint32 ids[3] = {194740, 194743, 194748}; + for( uint8 i = 0; i < 3; ++i ) + if (GameObject* pad = me->FindNearestGameObject(ids[i], 200.0f)) + if (Creature* trigger = me->SummonCreature(NPC_BOT_SUMMON_TRIGGER, *pad, TEMPSUMMON_MANUAL_DESPAWN)) + trigger->AI()->DoAction(3); + events.Repeat(45s); + } + break; + case EVENT_MAGNETIC_CORE_PULL_DOWN: + me->CastSpell(me, SPELL_MAGNETIC_CORE, true); + me->CastSpell(me, SPELL_SPINNING, true); + me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), 365.34f, FORCED_MOVEMENT_NONE, me->GetExactDist(me->GetPositionX(), me->GetPositionY(), 365.34f)); + events.ScheduleEvent(EVENT_MAGNETIC_CORE_FREE, 20s); + break; + case EVENT_MAGNETIC_CORE_FREE: + me->RemoveAura(SPELL_SPINNING); + me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), 381.34f, FORCED_MOVEMENT_NONE, me->GetDistance(me->GetPositionX(), me->GetPositionY(), 381.34f)); + events.ScheduleEvent(EVENT_MAGNETIC_CORE_REMOVE_IMMOBILIZE, 1s); + break; + case EVENT_MAGNETIC_CORE_REMOVE_IMMOBILIZE: + immobilized = false; + break; + } + } + + void MoveInLineOfSight(Unit* /*mover*/) override {} + + void KilledUnit(Unit* who) override + { + if (who->IsPlayer()) + if (Creature* c = GetMimiron()) + { + if (Phase == 3) + { + c->AI()->Talk(SAY_AERIAL_SLAY); + } + else + { + c->AI()->Talk(SAY_V07TRON_SLAY); + } + } + } + + void EnterEvadeMode(EvadeReason why) override + { + if (bIsEvading) + return; + bIsEvading = true; + + me->RemoveAllAuras(); + me->ExitVehicle(); + _EnterEvadeMode(); + Reset(); + if (Creature* mimiron = GetMimiron()) + mimiron->AI()->EnterEvadeMode(why); + + bIsEvading = false; + } + + void JustSummoned(Creature* s) override + { + summons.Summon(s); + if (s->GetEntry() == NPC_BOMB_BOT) + s->m_positionZ = 364.34f; + } + + void SummonedCreatureDespawn(Creature* s) override + { + summons.Despawn(s); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_SELF_REPAIR) + { + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_AGGRESSIVE); + } + } +}; + +struct npc_ulduar_proximity_mine : public ScriptedAI +{ + npc_ulduar_proximity_mine(Creature* pCreature) : ScriptedAI(pCreature) + { + exploded = false; + timer = 2500; + timer2 = 35000; + } + + bool exploded; + uint16 timer; + uint16 timer2; + + void AttackStart(Unit* /*who*/) override {} + void MoveInLineOfSight(Unit* /*who*/) override {} + bool CanAIAttack(Unit const* /*target*/) const override { return false; } + + // MoveInLineOfSight is checked every few yards, can't use it + void UpdateAI(uint32 diff) override + { + if (timer2 <= diff) { - exploded = false; - timer = 2500; timer2 = 35000; + if (!exploded) + { + exploded = true; + me->CastSpell(me, SPELL_MINE_EXPLOSION, false); + } } + else + timer2 -= diff; - bool exploded; - uint16 timer; - uint16 timer2; - - void AttackStart(Unit* /*who*/) override {} - void MoveInLineOfSight(Unit* /*who*/) override {} - bool CanAIAttack(Unit const* /*target*/) const override { return false; } - - // MoveInLineOfSight is checked every few yards, can't use it - void UpdateAI(uint32 diff) override + if (timer <= diff) { - if (timer2 <= diff) + timer = 500; + if (!exploded && SelectTargetFromPlayerList(1.9f)) { - timer2 = 35000; - if (!exploded) - { - exploded = true; - me->CastSpell(me, SPELL_MINE_EXPLOSION, false); - } + exploded = true; + me->CastSpell(me, SPELL_MINE_EXPLOSION, false); } - else - timer2 -= diff; - - if (timer <= diff) - { - timer = 500; - if (!exploded && SelectTargetFromPlayerList(1.9f)) - { - exploded = true; - me->CastSpell(me, SPELL_MINE_EXPLOSION, false); - } - } - else - timer -= diff; } - }; + else + timer -= diff; + } }; class spell_ulduar_mimiron_mine_explosion : public SpellScript @@ -1911,8 +1828,8 @@ class spell_ulduar_mimiron_mine_explosion : public SpellScript void HandleDamage(SpellEffIndex /*effIndex*/) { if (GetHitPlayer()) - if (InstanceScript* pInstance = GetCaster()->GetInstanceScript()) - if (Creature* mimi = pInstance->GetCreature(TYPE_MIMIRON)) + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (Creature* mimi = instance->GetCreature(BOSS_MIMIRON)) mimi->AI()->SetData(0, 11); } @@ -1922,163 +1839,130 @@ class spell_ulduar_mimiron_mine_explosion : public SpellScript } }; -class npc_ulduar_mimiron_rocket : public CreatureScript +struct npc_ulduar_mimiron_rocket : public NullCreatureAI { -public: - npc_ulduar_mimiron_rocket() : CreatureScript("npc_ulduar_mimiron_rocket") { } + npc_ulduar_mimiron_rocket(Creature* pCreature) : NullCreatureAI(pCreature) {} - CreatureAI* GetAI(Creature* pCreature) const override + void InitializeAI() override { - return GetUlduarAI(pCreature); + if (!me->isDead()) + Reset(); } - struct npc_ulduar_mimiron_rocketAI : public NullCreatureAI + void Reset() override { - npc_ulduar_mimiron_rocketAI(Creature* pCreature) : NullCreatureAI(pCreature) {} + me->SetCanFly(true); + me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING); + me->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD); + } - void InitializeAI() override - { - if (!me->isDead()) - Reset(); - } + void SetData(uint32 /*id*/, uint32 /*value*/) override + { + me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 100.0f, FORCED_MOVEMENT_NONE, 0.f, false, true); + } - void Reset() override + void UpdateAI(uint32 /*diff*/) override + { + if (!me->GetVehicle()) { - me->SetCanFly(true); - me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING); - me->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD); + me->SetSpeed(MOVE_RUN, me->GetSpeedRate(MOVE_RUN) + 0.4f, false); + me->SetSpeed(MOVE_FLIGHT, me->GetSpeedRate(MOVE_RUN), false); } - - void SetData(uint32 /*id*/, uint32 /*value*/) override - { - me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 100.0f, FORCED_MOVEMENT_NONE, 0.f, false, true); - } - - void UpdateAI(uint32 /*diff*/) override - { - if (!me->GetVehicle()) - { - me->SetSpeed(MOVE_RUN, me->GetSpeedRate(MOVE_RUN) + 0.4f, false); - me->SetSpeed(MOVE_FLIGHT, me->GetSpeedRate(MOVE_RUN), false); - } - } - }; + } }; -class npc_ulduar_magnetic_core : public CreatureScript +struct npc_ulduar_magnetic_core : public NullCreatureAI { -public: - npc_ulduar_magnetic_core() : CreatureScript("npc_ulduar_magnetic_core") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_ulduar_magnetic_core(Creature* pCreature) : NullCreatureAI(pCreature) { - return GetUlduarAI(pCreature); + instance = me->GetInstanceScript(); + if (Creature* c = GetACU()) + if (c->GetExactDist2d(me) <= 10.0f) + { + me->SendMonsterMove(c->GetPositionX(), c->GetPositionY(), 364.313f, 1); + me->UpdatePosition(c->GetPositionX(), c->GetPositionY(), 364.313f, me->GetOrientation(), true); + me->StopMovingOnCurrentPos(); + c->AI()->SetData(2, 1); + despawnTimer = 20000; + return; + } + despawnTimer = 60000; } - struct npc_ulduar_magnetic_coreAI : public NullCreatureAI + InstanceScript* instance; + uint16 despawnTimer; + + void SetData(uint32 /*id*/, uint32 /*value*/) override { - npc_ulduar_magnetic_coreAI(Creature* pCreature) : NullCreatureAI(pCreature) + despawnTimer = 20000; + } + + void UpdateAI(uint32 diff) override + { + if (despawnTimer <= diff) { - pInstance = me->GetInstanceScript(); - if (Creature* c = GetACU()) - if (c->GetExactDist2d(me) <= 10.0f) - { - me->SendMonsterMove(c->GetPositionX(), c->GetPositionY(), 364.313f, 1); - me->UpdatePosition(c->GetPositionX(), c->GetPositionY(), 364.313f, me->GetOrientation(), true); - me->StopMovingOnCurrentPos(); - c->AI()->SetData(2, 1); - despawnTimer = 20000; - return; - } despawnTimer = 60000; + me->DespawnOrUnsummon(1ms); } - - InstanceScript* pInstance; - uint16 despawnTimer; - - void SetData(uint32 /*id*/, uint32 /*value*/) override - { - despawnTimer = 20000; - } - - void UpdateAI(uint32 diff) override - { - if (despawnTimer <= diff) - { - despawnTimer = 60000; - me->DespawnOrUnsummon(1ms); - } - else - despawnTimer -= diff; - } - }; + else + despawnTimer -= diff; + } }; -class npc_ulduar_bot_summon_trigger : public CreatureScript +struct npc_ulduar_bot_summon_trigger : public NullCreatureAI { -public: - npc_ulduar_bot_summon_trigger() : CreatureScript("npc_ulduar_bot_summon_trigger") { } + npc_ulduar_bot_summon_trigger(Creature* pCreature) : NullCreatureAI(pCreature) { } - CreatureAI* GetAI(Creature* pCreature) const override + uint32 timer; + uint8 option; + + void Reset() override { - return GetUlduarAI(pCreature); + timer = 8000; + option = 0; } - struct npc_ulduar_bot_summon_triggerAI : public NullCreatureAI + void DoAction(int32 param) override { - npc_ulduar_bot_summon_triggerAI(Creature* pCreature) : NullCreatureAI(pCreature) { } - - uint32 timer; - uint8 option; - - void Reset() override + switch (param) { - timer = 8000; - option = 0; + case 1: + me->CastSpell(me, SPELL_BEAM_GREEN, true); + option = 1; + break; + case 2: + me->CastSpell(me, SPELL_BEAM_YELLOW, true); + option = 2; + break; + case 3: + me->CastSpell(me, SPELL_BEAM_BLUE, true); + option = 3; + break; } + } - void DoAction(int32 param) override + void UpdateAI(uint32 diff) override + { + if (timer <= diff) { - switch (param) - { - case 1: - me->CastSpell(me, SPELL_BEAM_GREEN, true); - option = 1; - break; - case 2: - me->CastSpell(me, SPELL_BEAM_YELLOW, true); - option = 2; - break; - case 3: - me->CastSpell(me, SPELL_BEAM_BLUE, true); - option = 3; - break; - } - } + uint32 option_npcid[3] = {NPC_JUNK_BOT, NPC_ASSAULT_BOT, NPC_EMERGENCY_FIRE_BOT}; + InstanceScript* instance = me->GetInstanceScript(); + if (Creature* ACU = GetACU()) // ACU summons for easy removing + if (Creature* bot = ACU->SummonCreature( option_npcid[option - 1], *me, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 25000)) + { + if (option < 3) + bot->SetInCombatWithZone(); + if (Creature* m = GetMimiron()) + if (m->AI()->GetData(1)) // hardmode + bot->CastSpell(bot, SPELL_EMERGENCY_MODE, true); + } - void UpdateAI(uint32 diff) override - { - if (timer <= diff) - { - uint32 option_npcid[3] = {NPC_JUNK_BOT, NPC_ASSAULT_BOT, NPC_EMERGENCY_FIRE_BOT}; - InstanceScript* pInstance = me->GetInstanceScript(); - if (Creature* ACU = GetACU()) // ACU summons for easy removing - if (Creature* bot = ACU->SummonCreature( option_npcid[option - 1], *me, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 25000)) - { - if (option < 3) - bot->SetInCombatWithZone(); - if (Creature* m = GetMimiron()) - if (m->AI()->GetData(1)) // hardmode - bot->CastSpell(bot, SPELL_EMERGENCY_MODE, true); - } - - me->DespawnOrUnsummon(500ms); - timer = 99999; - } - else - timer -= diff; + me->DespawnOrUnsummon(500ms); + timer = 99999; } - }; + else + timer -= diff; + } }; class spell_mimiron_rapid_burst_aura : public AuraScript @@ -2170,10 +2054,10 @@ public: if (InstanceScript* instance = go->GetInstanceScript()) { - if (instance->GetData(TYPE_MIMIRON) != NOT_STARTED) + if (instance->GetBossState(BOSS_MIMIRON) != NOT_STARTED) return false; - if (Creature* c = ObjectAccessor::GetCreature(*go, instance->GetGuidData(TYPE_MIMIRON))) + if (Creature* c = instance->GetCreature(BOSS_MIMIRON)) { c->AI()->SetData(0, 7); c->AI()->AttackStart(player); @@ -2184,254 +2068,208 @@ public: } }; -class npc_ulduar_flames_initial : public CreatureScript +struct npc_ulduar_flames_initial : public NullCreatureAI { -public: - npc_ulduar_flames_initial() : CreatureScript("npc_ulduar_flames_initial") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_ulduar_flames_initial(Creature* pCreature) : NullCreatureAI(pCreature) { - return GetUlduarAI(pCreature); + CreateTime = GameTime::GetGameTime().count(); + events.Reset(); + events.ScheduleEvent(EVENT_FLAMES_SPREAD, 5750ms); + if (Creature* flame = me->SummonCreature(NPC_FLAMES_SPREAD, me->GetPositionX(), me->GetPositionY(), 364.32f, 0.0f)) + { + FlameList.push_back(flame->GetGUID()); + flame->CastSpell(flame, SPELL_FLAMES_AURA, true); + } } - struct npc_ulduar_flames_initialAI : public NullCreatureAI + GuidList FlameList; + EventMap events; + uint32 CreateTime; + + void DoAction(int32 action) override { - npc_ulduar_flames_initialAI(Creature* pCreature) : NullCreatureAI(pCreature) - { - CreateTime = GameTime::GetGameTime().count(); - events.Reset(); - events.ScheduleEvent(EVENT_FLAMES_SPREAD, 5750ms); - if (Creature* flame = me->SummonCreature(NPC_FLAMES_SPREAD, me->GetPositionX(), me->GetPositionY(), 364.32f, 0.0f)) - { - FlameList.push_back(flame->GetGUID()); - flame->CastSpell(flame, SPELL_FLAMES_AURA, true); - } - } + if (action == 1337) + RemoveAll(); + } - GuidList FlameList; - EventMap events; - uint32 CreateTime; - - void DoAction(int32 action) override + void SpreadFlame(float x, float y) + { + if (Creature* flame = me->SummonCreature(NPC_FLAMES_SPREAD, x, y, 364.32f, 0.0f)) { - if (action == 1337) - RemoveAll(); - } - - void SpreadFlame(float x, float y) - { - if (Creature* flame = me->SummonCreature(NPC_FLAMES_SPREAD, x, y, 364.32f, 0.0f)) - { - FlameList.push_back(flame->GetGUID()); - if (Creature* c = me->FindNearestCreature(NPC_FLAMES_SPREAD, 10.0f)) - if (c->GetExactDist2d(flame->GetPositionX(), flame->GetPositionY()) <= 4.0f) - return; - flame->CastSpell(flame, SPELL_FLAMES_AURA, true); - } - } - - void RemoveFlame(ObjectGuid guid) - { - FlameList.remove(guid); - } - - void RemoveAll() - { - for (ObjectGuid const& guid : FlameList) - if (Creature* c = ObjectAccessor::GetCreature(*me, guid)) - c->DespawnOrUnsummon(); - FlameList.clear(); - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - if (InstanceScript* pInstance = me->GetInstanceScript()) - if (pInstance->GetData(TYPE_MIMIRON) != IN_PROGRESS) - { - RemoveAll(); + FlameList.push_back(flame->GetGUID()); + if (Creature* c = me->FindNearestCreature(NPC_FLAMES_SPREAD, 10.0f)) + if (c->GetExactDist2d(flame->GetPositionX(), flame->GetPositionY()) <= 4.0f) return; - } + flame->CastSpell(flame, SPELL_FLAMES_AURA, true); + } + } - events.Update(diff); + void RemoveFlame(ObjectGuid guid) + { + FlameList.remove(guid); + } - switch (events.ExecuteEvent()) + void RemoveAll() + { + for (ObjectGuid const& guid : FlameList) + if (Creature* c = ObjectAccessor::GetCreature(*me, guid)) + c->DespawnOrUnsummon(); + FlameList.clear(); + me->DespawnOrUnsummon(); + } + + void UpdateAI(uint32 diff) override + { + if (InstanceScript* instance = me->GetInstanceScript()) + if (instance->GetBossState(BOSS_MIMIRON) != IN_PROGRESS) { - case 0: - break; - case EVENT_FLAMES_SPREAD: - { - if (FlameList.empty()) - { - me->DespawnOrUnsummon(); - return; - } + RemoveAll(); + return; + } - if (InstanceScript* pInstance = me->GetInstanceScript()) - if (Creature* mimiron = GetMimiron()) - if (CreateTime < mimiron->AI()->GetData(10)) + events.Update(diff); + + switch (events.ExecuteEvent()) + { + case 0: + break; + case EVENT_FLAMES_SPREAD: + { + if (FlameList.empty()) + { + me->DespawnOrUnsummon(); + return; + } + + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* mimiron = GetMimiron()) + if (CreateTime < mimiron->AI()->GetData(10)) + break; + + Creature* last = ObjectAccessor::GetCreature(*me, FlameList.back()); + if (last) + { + float prevdist = 100.0f; + Player* target = nullptr; + + Map::PlayerList const& pl = me->GetMap()->GetPlayers(); + for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) + if (Player* plr = itr->GetSource()) + if (plr->IsAlive() && plr->GetExactDist2d(last) < prevdist && !plr->IsGameMaster()) { - break; + target = plr; + prevdist = plr->GetExactDist2d(last); } - Creature* last = ObjectAccessor::GetCreature(*me, FlameList.back()); - if (last) + if (target && prevdist >= 4.0f) // no need to spread when player is standing in fire, check distance { - float prevdist = 100.0f; - Player* target = nullptr; - - Map::PlayerList const& pl = me->GetMap()->GetPlayers(); - for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) - if (Player* plr = itr->GetSource()) - if (plr->IsAlive() && plr->GetExactDist2d(last) < prevdist && !plr->IsGameMaster()) - { - target = plr; - prevdist = plr->GetExactDist2d(last); - } - - if (target && prevdist >= 4.0f) // no need to spread when player is standing in fire, check distance - { - float angle = last->GetAngle(target->GetPositionX(), target->GetPositionY()) - M_PI / 8 + rand_norm() * 2 * M_PI / 8; - SpreadFlame(last->GetPositionX() + 7.0f * cos(angle), last->GetPositionY() + 7.0f * std::sin(angle)); - } + float angle = last->GetAngle(target->GetPositionX(), target->GetPositionY()) - M_PI / 8 + rand_norm() * 2 * M_PI / 8; + SpreadFlame(last->GetPositionX() + 7.0f * cos(angle), last->GetPositionY() + 7.0f * std::sin(angle)); } - - events.Repeat(5750ms); } - break; - } + + events.Repeat(5750ms); + } + break; } - }; + } }; -class npc_ulduar_flames_spread : public CreatureScript +struct npc_ulduar_flames_spread : public NullCreatureAI { -public: - npc_ulduar_flames_spread() : CreatureScript("npc_ulduar_flames_spread") { } + npc_ulduar_flames_spread(Creature* pCreature) : NullCreatureAI(pCreature) {} - CreatureAI* GetAI(Creature* pCreature) const override + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override { - return GetUlduarAI(pCreature); - } - - struct npc_ulduar_flames_spreadAI : public NullCreatureAI - { - npc_ulduar_flames_spreadAI(Creature* pCreature) : NullCreatureAI(pCreature) {} - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + switch (spell->Id) { - switch (spell->Id) - { - case SPELL_FROST_BOMB_EXPLOSION_10: - case SPELL_FROST_BOMB_EXPLOSION_25: - case SPELL_FLAME_SUPPRESSANT_10yd: - case SPELL_FLAME_SUPPRESSANT_50000yd: - case SPELL_WATER_SPRAY: - { - if (me->IsSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit()) - if (Creature* c = summoner->ToCreature()) - if (c->AI()) - CAST_AI(npc_ulduar_flames_initial::npc_ulduar_flames_initialAI, c->AI())->RemoveFlame(me->GetGUID()); + case SPELL_FROST_BOMB_EXPLOSION_10: + case SPELL_FROST_BOMB_EXPLOSION_25: + case SPELL_FLAME_SUPPRESSANT_10yd: + case SPELL_FLAME_SUPPRESSANT_50000yd: + case SPELL_WATER_SPRAY: + { + if (me->IsSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit()) + if (Creature* c = summoner->ToCreature()) + if (c->AI()) + CAST_AI(npc_ulduar_flames_initial, c->AI())->RemoveFlame(me->GetGUID()); - me->RemoveAllAuras(); - me->DespawnOrUnsummon(2500ms); - } - break; - case SPELL_VX001_FROST_BOMB: - me->CastSpell(me, SPELL_SUMMON_FROST_BOMB, true); - break; - } + me->RemoveAllAuras(); + me->DespawnOrUnsummon(2500ms); + } + break; + case SPELL_VX001_FROST_BOMB: + me->CastSpell(me, SPELL_SUMMON_FROST_BOMB, true); + break; } - }; + } }; -class npc_ulduar_emergency_fire_bot : public CreatureScript +struct npc_ulduar_emergency_fire_bot : public ScriptedAI { -public: - npc_ulduar_emergency_fire_bot() : CreatureScript("npc_ulduar_emergency_fire_bot") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_ulduar_emergency_fire_bot(Creature* pCreature) : ScriptedAI(pCreature) { - return GetUlduarAI(pCreature); + events.Reset(); + events.ScheduleEvent(EVENT_EMERGENCY_BOT_CHECK, 1s); } - struct npc_ulduar_emergency_fire_botAI : public ScriptedAI + EventMap events; + + void MoveInLineOfSight(Unit*) override {} + void AttackStart(Unit*) override {} + + void MovementInform(uint32 type, uint32 id) override { - npc_ulduar_emergency_fire_botAI(Creature* pCreature) : ScriptedAI(pCreature) + if (type == POINT_MOTION_TYPE && id == 1) + events.ScheduleEvent(EVENT_EMERGENCY_BOT_ATTACK, 0ms); + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + switch (events.ExecuteEvent()) { - events.Reset(); - events.ScheduleEvent(EVENT_EMERGENCY_BOT_CHECK, 1s); + case 0: + break; + case EVENT_EMERGENCY_BOT_CHECK: + events.Repeat(15s); + if (Creature* flame = me->FindNearestCreature(NPC_FLAMES_SPREAD, 150.0f, true)) + { + me->SetOrientation(me->GetAngle(flame->GetPositionX(), flame->GetPositionY())); + float dist = me->GetExactDist2d(flame); + if (dist <= 5.0f) + events.ScheduleEvent(EVENT_EMERGENCY_BOT_ATTACK, 0ms); + else + me->GetMotionMaster()->MovePoint(1, me->GetPositionX() + (dist - 5.0f)*cos(me->GetOrientation()), me->GetPositionY() + (dist - 5.0f)*sin(me->GetOrientation()), 364.32f); + } + break; + case EVENT_EMERGENCY_BOT_ATTACK: + me->CastSpell((Unit*)nullptr, SPELL_WATER_SPRAY, false); + events.RescheduleEvent(EVENT_EMERGENCY_BOT_CHECK, 5s); + break; } - - EventMap events; - - void MoveInLineOfSight(Unit*) override {} - void AttackStart(Unit*) override {} - - void MovementInform(uint32 type, uint32 id) override - { - if (type == POINT_MOTION_TYPE && id == 1) - events.ScheduleEvent(EVENT_EMERGENCY_BOT_ATTACK, 0ms); - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_EMERGENCY_BOT_CHECK: - events.Repeat(15s); - if (Creature* flame = me->FindNearestCreature(NPC_FLAMES_SPREAD, 150.0f, true)) - { - me->SetOrientation(me->GetAngle(flame->GetPositionX(), flame->GetPositionY())); - float dist = me->GetExactDist2d(flame); - if (dist <= 5.0f) - events.ScheduleEvent(EVENT_EMERGENCY_BOT_ATTACK, 0ms); - else - me->GetMotionMaster()->MovePoint(1, me->GetPositionX() + (dist - 5.0f)*cos(me->GetOrientation()), me->GetPositionY() + (dist - 5.0f)*sin(me->GetOrientation()), 364.32f); - } - break; - case EVENT_EMERGENCY_BOT_ATTACK: - me->CastSpell((Unit*)nullptr, SPELL_WATER_SPRAY, false); - events.RescheduleEvent(EVENT_EMERGENCY_BOT_CHECK, 5s); - break; - } - } - }; + } }; -class npc_ulduar_rocket_strike_trigger : public CreatureScript +struct npc_ulduar_rocket_strike_trigger : public NullCreatureAI { -public: - npc_ulduar_rocket_strike_trigger() : CreatureScript("npc_ulduar_rocket_strike_trigger") { } + npc_ulduar_rocket_strike_trigger(Creature* pCreature) : NullCreatureAI(pCreature) {} - CreatureAI* GetAI(Creature* pCreature) const override + void SpellHitTarget(Unit* target, SpellInfo const* spell) override { - return GetUlduarAI(pCreature); - } - - struct npc_ulduar_rocket_strike_triggerAI : public NullCreatureAI - { - npc_ulduar_rocket_strike_triggerAI(Creature* pCreature) : NullCreatureAI(pCreature) {} - - void SpellHitTarget(Unit* target, SpellInfo const* spell) override + if (!target || !spell) + return; + if (spell->Id == 63041) { - if (!target || !spell) - return; - if (spell->Id == 63041) - { - if (target->GetEntry() == NPC_ASSAULT_BOT) - me->CastSpell(me, 65040, true); // achievement Not-So-Friendly Fire - else if (target->IsPlayer()) - if (InstanceScript* pInstance = me->GetInstanceScript()) - if (Creature* c = GetMimiron()) - c->AI()->SetData(0, 13); - } + if (target->GetEntry() == NPC_ASSAULT_BOT) + me->CastSpell(me, 65040, true); // achievement Not-So-Friendly Fire + else if (target->IsPlayer()) + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* c = GetMimiron()) + c->AI()->SetData(0, 13); } - }; + } }; class achievement_mimiron_firefighter : public AchievementCriteriaScript @@ -2480,23 +2318,23 @@ public: void AddSC_boss_mimiron() { - new boss_mimiron(); - new npc_ulduar_leviathan_mkii(); - new npc_ulduar_vx001(); - new npc_ulduar_aerial_command_unit(); + RegisterUlduarCreatureAI(boss_mimiron); + RegisterUlduarCreatureAI(npc_ulduar_leviathan_mkii); + RegisterUlduarCreatureAI(npc_ulduar_vx001); + RegisterUlduarCreatureAI(npc_ulduar_aerial_command_unit); - new npc_ulduar_proximity_mine(); - new npc_ulduar_mimiron_rocket(); - new npc_ulduar_magnetic_core(); - new npc_ulduar_bot_summon_trigger(); + RegisterUlduarCreatureAI(npc_ulduar_proximity_mine); + RegisterUlduarCreatureAI(npc_ulduar_mimiron_rocket); + RegisterUlduarCreatureAI(npc_ulduar_magnetic_core); + RegisterUlduarCreatureAI(npc_ulduar_bot_summon_trigger); RegisterSpellScript(spell_mimiron_rapid_burst_aura); RegisterSpellScript(spell_mimiron_p3wx2_laser_barrage_aura); RegisterSpellScript(spell_ulduar_mimiron_mine_explosion); new go_ulduar_do_not_push_this_button(); - new npc_ulduar_flames_initial(); - new npc_ulduar_flames_spread(); - new npc_ulduar_emergency_fire_bot(); - new npc_ulduar_rocket_strike_trigger(); + RegisterUlduarCreatureAI(npc_ulduar_flames_initial); + RegisterUlduarCreatureAI(npc_ulduar_flames_spread); + RegisterUlduarCreatureAI(npc_ulduar_emergency_fire_bot); + RegisterUlduarCreatureAI(npc_ulduar_rocket_strike_trigger); new achievement_mimiron_firefighter(); new achievement_mimiron_set_up_us_the_bomb_11(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index 6a3682d78..2a2efb95c 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -135,480 +135,446 @@ enum Misc const Position CORDS_GROUND = {588.0f, -166.0f, 391.1f}; const Position CORDS_AIR = {588.0f, -178.0f, 490.0f}; -class boss_razorscale : public CreatureScript +struct boss_razorscale : public BossAI { -public: - boss_razorscale() : CreatureScript("boss_razorscale") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_razorscale(Creature* creature) : BossAI(creature, BOSS_RAZORSCALE) { - return GetUlduarAI(pCreature); + startPath = true; } - struct boss_razorscaleAI : public ScriptedAI + ObjectGuid ExpeditionEngineerGUIDs[3]; + ObjectGuid CommanderGUID; + float cords[4][2]; + bool bGroundPhase; + bool startPath; + uint8 flyTimes; + + void InitializeAI() override { - boss_razorscaleAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me) + me->SetDisableGravity(true); + me->setActive(true); + Reset(); + } + + void Reset() override + { + _Reset(); + + for (uint8 i = 0; i < 3; ++i) + ExpeditionEngineerGUIDs[i].Clear(); + + // Show gossip icon if previously hidden + if (Creature* commander = ObjectAccessor::GetCreature(*me, CommanderGUID)) + if (!commander->HasNpcFlag(UNIT_NPC_FLAG_GOSSIP)) + commander->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); + + CommanderGUID.Clear(); + bGroundPhase = false; + flyTimes = 0; + } + + void AttackStart(Unit* who) override + { + if (who && me->Attack(who, true) && bGroundPhase) + me->GetMotionMaster()->MoveChase(who); + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + events.ScheduleEvent(EVENT_COMMANDER_SAY_AGGRO, 5s); + events.ScheduleEvent(EVENT_EE_SAY_MOVE_OUT, 10s); + events.ScheduleEvent(EVENT_ENRAGE, 10min); + events.ScheduleEvent(EVENT_SPELL_FIREBALL, 6s); + events.ScheduleEvent(EVENT_SPELL_DEVOURING_FLAME, 13s); + events.ScheduleEvent(EVENT_SUMMON_MOLE_MACHINES, 11s); + + std::list eeList; + me->GetCreaturesWithEntryInRange(eeList, 300.0f, NPC_EXPEDITION_ENGINEER); + uint8 i = 0; + for( std::list::iterator itr = eeList.begin(); itr != eeList.end(); ++itr ) { - pInstance = me->GetInstanceScript(); - startPath = true; + if (i > 2) + break; + ExpeditionEngineerGUIDs[i] = (*itr)->GetGUID(); + if (!i) + (*itr)->AI()->Talk(SAY_EE_AGGRO); + ++i; } + if (Creature* c = me->FindNearestCreature(NPC_EXPEDITION_COMMANDER, 300.0f, true)) + CommanderGUID = c->GetGUID(); + } - InstanceScript* pInstance; - EventMap events; - SummonList summons; - ObjectGuid ExpeditionEngineerGUIDs[3]; - ObjectGuid CommanderGUID; - float cords[4][2]; - bool bGroundPhase; - bool startPath; - uint8 flyTimes; + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + if (!caster || !instance) + return; - void InitializeAI() override + switch (spell->Id) { - me->SetDisableGravity(true); - me->setActive(true); - Reset(); - } + case SPELL_LAUNCH_CHAIN: + { + uint32 spellId = SPELL_CHAIN_4; - void Reset() override - { - events.Reset(); - summons.DespawnAll(); - - for (uint8 i = 0; i < 3; ++i) - ExpeditionEngineerGUIDs[i].Clear(); - - // Show gossip icon if previously hidden - if (Creature* commander = ObjectAccessor::GetCreature(*me, CommanderGUID)) - if (!commander->HasNpcFlag(UNIT_NPC_FLAG_GOSSIP)) - commander->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); - - CommanderGUID.Clear(); - bGroundPhase = false; - flyTimes = 0; - - if (pInstance) - pInstance->SetData(TYPE_RAZORSCALE, NOT_STARTED); - } - - void AttackStart(Unit* who) override - { - if (who && me->Attack(who, true) && bGroundPhase) - me->GetMotionMaster()->MoveChase(who); - } - - void JustEngagedWith(Unit* /*who*/) override - { - me->SetInCombatWithZone(); - events.Reset(); - events.ScheduleEvent(EVENT_COMMANDER_SAY_AGGRO, 5s); - events.ScheduleEvent(EVENT_EE_SAY_MOVE_OUT, 10s); - events.ScheduleEvent(EVENT_ENRAGE, 10min); - events.ScheduleEvent(EVENT_SPELL_FIREBALL, 6s); - events.ScheduleEvent(EVENT_SPELL_DEVOURING_FLAME, 13s); - events.ScheduleEvent(EVENT_SUMMON_MOLE_MACHINES, 11s); - - std::list eeList; - me->GetCreaturesWithEntryInRange(eeList, 300.0f, NPC_EXPEDITION_ENGINEER); - uint8 i = 0; - for( std::list::iterator itr = eeList.begin(); itr != eeList.end(); ++itr ) - { - if (i > 2) - break; - ExpeditionEngineerGUIDs[i] = (*itr)->GetGUID(); - if (!i) - (*itr)->AI()->Talk(SAY_EE_AGGRO); - ++i; - } - if (Creature* c = me->FindNearestCreature(NPC_EXPEDITION_COMMANDER, 300.0f, true)) - CommanderGUID = c->GetGUID(); - - if (pInstance) - pInstance->SetData(TYPE_RAZORSCALE, IN_PROGRESS); - } - - void JustDied(Unit* /*Killer*/) override - { - summons.DespawnAll(); - - if (pInstance) - pInstance->SetData(TYPE_RAZORSCALE, DONE); - } - - void SpellHit(Unit* caster, SpellInfo const* spell) override - { - if (!caster || !pInstance) - return; - - switch (spell->Id) - { - case SPELL_LAUNCH_CHAIN: + if (caster->GetGUID() == instance->GetGuidData(DATA_HARPOON_FIRE_STATE_1)) { - uint32 spellId = SPELL_CHAIN_4; - - if (caster->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_1)) - { - spellId = SPELL_CHAIN_1; - } - else if (caster->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_2)) - { - spellId = SPELL_CHAIN_2; - } - else if (caster->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_3)) - { - spellId = SPELL_CHAIN_3; - } - - caster->CastSpell(me, spellId, true); + spellId = SPELL_CHAIN_1; } - break; - case SPELL_CHAIN_1: - case SPELL_CHAIN_2: - case SPELL_CHAIN_3: - case SPELL_CHAIN_4: + else if (caster->GetGUID() == instance->GetGuidData(DATA_HARPOON_FIRE_STATE_2)) { - uint8 count = 0; - if (me->HasAura(SPELL_CHAIN_1)) - count++; - if (me->HasAura(SPELL_CHAIN_3)) - count++; - if (RAID_MODE(0, 1)) - { - if (me->HasAura(SPELL_CHAIN_2)) - count++; - if (me->HasAura(SPELL_CHAIN_4)) - count++; - } - if (count >= REQ_CHAIN_COUNT) - { - if (Creature* commander = ObjectAccessor::GetCreature(*me, CommanderGUID)) - commander->AI()->Talk(SAY_COMMANDER_GROUND_PHASE); - - me->InterruptNonMeleeSpells(true); - events.CancelEvent(EVENT_SPELL_FIREBALL); - events.CancelEvent(EVENT_SPELL_DEVOURING_FLAME); - events.CancelEvent(EVENT_SUMMON_MOLE_MACHINES); - me->SetTarget(); - me->SendMeleeAttackStop(me->GetVictim()); - me->GetMotionMaster()->MoveLand(0, CORDS_GROUND, 25.0f); - } + spellId = SPELL_CHAIN_2; } - break; - } - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override - { - if (me->GetPositionZ() > 440.0f) // protection, razorscale is attackable (so harpoons can hit him, etc.), but should not receive dmg while in air - damage = 0; - else if (!bGroundPhase && ((me->GetHealth() * 100) / me->GetMaxHealth() < 50) && me->HasAura(62794)) // already below 50%, but still in chains and stunned - events.RescheduleEvent(EVENT_WARN_DEEP_BREATH, 0ms); - } - - void MovementInform(uint32 type, uint32 id) override - { - if (type == POINT_MOTION_TYPE && id == POINT_RAZORSCALE_INIT) - { - me->SetFacingTo(1.6f); - return; - } - else if (type == ESCORT_MOTION_TYPE && me->movespline->Finalized() && !me->IsInCombat()) - { - startPath = true; - return; - } - - if (type != EFFECT_MOTION_TYPE) - return; - if (id == 0) // landed - { - me->SetControlled(true, UNIT_STATE_ROOT); - me->DisableRotate(true); - me->SetOrientation((float)(M_PI + 0.01) / 2); - me->SetFacingTo(M_PI / 2); - me->SetDisableGravity(false); - me->CastSpell(me, 62794, true); - events.ScheduleEvent(EVENT_WARN_DEEP_BREATH, 30s); - } - else if (id == 1) // flied up - { - events.ScheduleEvent(EVENT_SPELL_FIREBALL, 2s); - events.ScheduleEvent(EVENT_SPELL_DEVOURING_FLAME, 4s); - events.ScheduleEvent(EVENT_SUMMON_MOLE_MACHINES, 5s); - } - } - - void UpdateAI(uint32 diff) override - { - if (startPath) - { - me->StopMoving(); - startPath = false; - me->GetMotionMaster()->MovePath(me->GetWaypointPath(), FORCED_MOVEMENT_NONE, PathSource::WAYPOINT_MGR); - } - - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_ENRAGE: - Talk(EMOTE_BERSERK); - me->CastSpell(me, SPELL_BERSERK, true); - break; - case EVENT_COMMANDER_SAY_AGGRO: - if (Creature* commander = ObjectAccessor::GetCreature(*me, CommanderGUID)) - commander->AI()->Talk(SAY_COMMANDER_AGGRO); - break; - case EVENT_EE_SAY_MOVE_OUT: - for (uint8 i = 0; i < 3; ++i) - if (Creature* c = ObjectAccessor::GetCreature(*me, ExpeditionEngineerGUIDs[i])) - { - if (!i) - c->AI()->Talk(SAY_EE_START_REPAIR); - c->AI()->SetData(1, 0); // start repairing - } - break; - case EVENT_SPELL_FIREBALL: - if (Unit* pTarget = SelectTarget(SelectTargetMethod::Random, 0, 200.0f, true)) - me->CastSpell(pTarget, SPELL_FIREBALL, false); - events.Repeat(4s); - break; - case EVENT_SPELL_DEVOURING_FLAME: - if (Unit* pTarget = SelectTarget(SelectTargetMethod::Random, 0, 200.0f, true)) - me->CastSpell(pTarget, SPELL_DEVOURINGFLAME, false); - events.Repeat(13s); - break; - case EVENT_SUMMON_MOLE_MACHINES: + else if (caster->GetGUID() == instance->GetGuidData(DATA_HARPOON_FIRE_STATE_3)) { - memset(cords, '\0', sizeof(cords)); - uint8 num = RAID_MODE( urand(2, 3), urand(2, 4)); - for( int i = 0; i < num; ++i ) - { - // X: (550, 625) Y: (-185, -230) - cords[i][0] = urand(550, 625); - cords[i][1] = -230 + rand() % 45; - if (GameObject* drill = me->SummonGameObject(GO_DRILL, cords[i][0], cords[i][1], 391.1f, M_PI / 4, 0.0f, 0.0f, 0.0f, 0.0f, 8)) - { - //drill->SetGoAnimProgress(0); - //drill->SetLootState(GO_READY); - //drill->UseDoorOrButton(8); - //drill->SetGoState(GO_STATE_READY); - drill->SetGoState(GO_STATE_ACTIVE); - drill->SetGoAnimProgress(0); - } - } - events.Repeat(45s); - events.RescheduleEvent(EVENT_SUMMON_ADDS, 4s); + spellId = SPELL_CHAIN_3; } - break; - case EVENT_SUMMON_ADDS: - for( int i = 0; i < 4; ++i ) - { - if (!cords[i][0]) - break; - uint8 opt; - uint8 r = urand(1, 100); - if (r <= 30) opt = 1; - else if (r <= 65) opt = 2; - else opt = 3; - - for( int j = 0; j < 4; ++j ) - { - float x = cords[i][0] + 4.0f * cos(j * M_PI / 2); - float y = cords[i][1] + 4.0f * std::sin(j * M_PI / 2); - - uint32 npc_entry = 0; - switch (opt) - { - case 1: - if (j == 1) npc_entry = NPC_DARK_RUNE_SENTINEL; - break; - case 2: - switch (j) - { - case 1: - npc_entry = NPC_DARK_RUNE_WATCHER; - break; - case 2: - npc_entry = NPC_DARK_RUNE_GUARDIAN; - break; - } - break; - default: // case 3: - switch (j) - { - case 1: - npc_entry = NPC_DARK_RUNE_WATCHER; - break; - case 2: - npc_entry = NPC_DARK_RUNE_GUARDIAN; - break; - case 3: - npc_entry = NPC_DARK_RUNE_GUARDIAN; - break; - } - break; - } - - if (npc_entry) - if (Creature* c = me->SummonCreature(npc_entry, x, y, 391.1f, j * M_PI / 2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000)) - DoZoneInCombat(c); - } - } - break; - case EVENT_WARN_DEEP_BREATH: - Talk(EMOTE_BREATH); - me->RemoveAura(62794); - events.ScheduleEvent(EVENT_PHASE2_FLAME_BREATH, 2500ms); - break; - case EVENT_PHASE2_FLAME_BREATH: - me->CastSpell(me, SPELL_FLAMEBREATH, true); - events.ScheduleEvent(EVENT_FLY_UP, 2s); - break; - case EVENT_FLY_UP: - me->SetInCombatWithZone(); // just in case - if (pInstance) - for( int i = 0; i < 4; ++i ) - if (ObjectGuid guid = pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_1 + i)) - if (Creature* hfs = ObjectAccessor::GetCreature(*me, guid)) - { - me->SummonCreature(34188, hfs->GetPositionX(), hfs->GetPositionY(), hfs->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 22000); - hfs->AI()->SetData(1, 0); - } - - me->RemoveAura(SPELL_LAUNCH_CHAIN); - me->RemoveAura(SPELL_CHAIN_1); - me->RemoveAura(SPELL_CHAIN_3); + caster->CastSpell(me, spellId, true); + } + break; + case SPELL_CHAIN_1: + case SPELL_CHAIN_2: + case SPELL_CHAIN_3: + case SPELL_CHAIN_4: + { + uint8 count = 0; + if (me->HasAura(SPELL_CHAIN_1)) + count++; + if (me->HasAura(SPELL_CHAIN_3)) + count++; if (RAID_MODE(0, 1)) { - me->RemoveAura(SPELL_CHAIN_2); - me->RemoveAura(SPELL_CHAIN_4); + if (me->HasAura(SPELL_CHAIN_2)) + count++; + if (me->HasAura(SPELL_CHAIN_4)) + count++; } - me->CastSpell(me, SPELL_WINGBUFFET, true); - - if ((me->GetHealth() * 100) / me->GetMaxHealth() < 50 ) // start phase 3 + if (count >= REQ_CHAIN_COUNT) { - Talk(EMOTE_PERMA_GROUND); - me->SetControlled(false, UNIT_STATE_ROOT); - me->DisableRotate(false); - DoResetThreatList(); - Unit* target = SelectTarget(SelectTargetMethod::MaxDistance, 0, 0.0, true); - if (!target) - target = me->SelectNearestPlayer(200.0f); - if (target) - { - AttackStart(target); - me->GetMotionMaster()->MoveChase(target); - } - bGroundPhase = true; + if (Creature* commander = ObjectAccessor::GetCreature(*me, CommanderGUID)) + commander->AI()->Talk(SAY_COMMANDER_GROUND_PHASE); + + me->InterruptNonMeleeSpells(true); events.CancelEvent(EVENT_SPELL_FIREBALL); events.CancelEvent(EVENT_SPELL_DEVOURING_FLAME); events.CancelEvent(EVENT_SUMMON_MOLE_MACHINES); - - events.ScheduleEvent(EVENT_SPELL_FLAME_BREATH, 20s); - events.ScheduleEvent(EVENT_SPELL_DEVOURING_FLAME_GROUND, 5s); - events.ScheduleEvent(EVENT_SPELL_FUSE_ARMOR, 10s); - events.ScheduleEvent(EVENT_SPELL_FLAME_BUFFET, 3s); - - break; - } - else - { - ++flyTimes; - me->SetControlled(false, UNIT_STATE_ROOT); - me->DisableRotate(false); + me->SetTarget(); me->SendMeleeAttackStop(me->GetVictim()); - me->GetMotionMaster()->MoveIdle(); - me->StopMoving(); - me->SetDisableGravity(true); - me->GetMotionMaster()->MoveTakeoff(1, CORDS_AIR, 25.0f); - events.ScheduleEvent(EVENT_RESUME_FIXING, 22s); + me->GetMotionMaster()->MoveLand(0, CORDS_GROUND, 25.0f); } - - break; - case EVENT_RESUME_FIXING: - for (uint8 i = 0; i < 3; ++i) - if (Creature* c = ObjectAccessor::GetCreature(*me, ExpeditionEngineerGUIDs[i])) - { - if (!i) - c->AI()->Talk(SAY_EE_REBUILD_TURRETS); - c->AI()->SetData(1, 0); // start repairing - } - break; - case EVENT_SPELL_FLAME_BREATH: - me->CastSpell(me->GetVictim(), SPELL_FLAMEBREATH, false); - events.Repeat(20s); - break; - case EVENT_SPELL_DEVOURING_FLAME_GROUND: - me->CastSpell(me->GetVictim(), SPELL_DEVOURINGFLAME, false); - events.Repeat(13s); - break; - case EVENT_SPELL_FUSE_ARMOR: - if (Unit* victim = me->GetVictim()) - if (me->IsWithinMeleeRange(victim)) - { - me->CastSpell(victim, SPELL_FUSEARMOR, false); - if (Aura* aur = victim->GetAura(SPELL_FUSEARMOR)) - if (aur->GetStackAmount() == 5) - victim->CastSpell(victim, SPELL_FUSED_ARMOR, true); - events.Repeat(10s); - break; - } - events.Repeat(2s); - break; - case EVENT_SPELL_FLAME_BUFFET: - me->CastSpell(me->GetVictim(), SPELL_FLAMEBUFFET, false); - events.Repeat(7s); - break; - } - - if (bGroundPhase) - DoMeleeAttackIfReady(); + } + break; } + } - void MoveInLineOfSight(Unit* /*who*/) override {} + void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override + { + if (me->GetPositionZ() > 440.0f) // protection, razorscale is attackable (so harpoons can hit him, etc.), but should not receive dmg while in air + damage = 0; + else if (!bGroundPhase && ((me->GetHealth() * 100) / me->GetMaxHealth() < 50) && me->HasAura(62794)) // already below 50%, but still in chains and stunned + events.RescheduleEvent(EVENT_WARN_DEEP_BREATH, 0ms); - void JustReachedHome() override + BossAI::DamageTaken(attacker, damage, damagetype, damageSchoolMask); + } + + void MovementInform(uint32 type, uint32 id) override + { + if (type == POINT_MOTION_TYPE && id == POINT_RAZORSCALE_INIT) + { + me->SetFacingTo(1.6f); + return; + } + else if (type == ESCORT_MOTION_TYPE && me->movespline->Finalized() && !me->IsInCombat()) { startPath = true; + return; } - void JustSummoned(Creature* s) override + if (type != EFFECT_MOTION_TYPE) + return; + if (id == 0) // landed { - summons.Summon(s); + me->SetControlled(true, UNIT_STATE_ROOT); + me->DisableRotate(true); + me->SetOrientation((float)(M_PI + 0.01) / 2); + me->SetFacingTo(M_PI / 2); + me->SetDisableGravity(false); + me->CastSpell(me, 62794, true); + events.ScheduleEvent(EVENT_WARN_DEEP_BREATH, 30s); + } + else if (id == 1) // flied up + { + events.ScheduleEvent(EVENT_SPELL_FIREBALL, 2s); + events.ScheduleEvent(EVENT_SPELL_DEVOURING_FLAME, 4s); + events.ScheduleEvent(EVENT_SUMMON_MOLE_MACHINES, 5s); + } + } + + void UpdateAI(uint32 diff) override + { + if (startPath) + { + me->StopMoving(); + startPath = false; + me->GetMotionMaster()->MovePath(me->GetWaypointPath(), FORCED_MOVEMENT_NONE, PathSource::WAYPOINT_MGR); } - uint32 GetData(uint32 id) const override + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - if (id == 1) - return (flyTimes <= 1 ? 1 : 0); - return 0; + case 0: + break; + case EVENT_ENRAGE: + Talk(EMOTE_BERSERK); + me->CastSpell(me, SPELL_BERSERK, true); + break; + case EVENT_COMMANDER_SAY_AGGRO: + if (Creature* commander = ObjectAccessor::GetCreature(*me, CommanderGUID)) + commander->AI()->Talk(SAY_COMMANDER_AGGRO); + break; + case EVENT_EE_SAY_MOVE_OUT: + for (uint8 i = 0; i < 3; ++i) + if (Creature* c = ObjectAccessor::GetCreature(*me, ExpeditionEngineerGUIDs[i])) + { + if (!i) + c->AI()->Talk(SAY_EE_START_REPAIR); + c->AI()->SetData(1, 0); // start repairing + } + break; + case EVENT_SPELL_FIREBALL: + if (Unit* pTarget = SelectTarget(SelectTargetMethod::Random, 0, 200.0f, true)) + me->CastSpell(pTarget, SPELL_FIREBALL, false); + events.Repeat(4s); + break; + case EVENT_SPELL_DEVOURING_FLAME: + if (Unit* pTarget = SelectTarget(SelectTargetMethod::Random, 0, 200.0f, true)) + me->CastSpell(pTarget, SPELL_DEVOURINGFLAME, false); + events.Repeat(13s); + break; + case EVENT_SUMMON_MOLE_MACHINES: + { + memset(cords, '\0', sizeof(cords)); + uint8 num = RAID_MODE( urand(2, 3), urand(2, 4)); + for( int i = 0; i < num; ++i ) + { + // X: (550, 625) Y: (-185, -230) + cords[i][0] = urand(550, 625); + cords[i][1] = -230 + rand() % 45; + if (GameObject* drill = me->SummonGameObject(GO_DRILL, cords[i][0], cords[i][1], 391.1f, M_PI / 4, 0.0f, 0.0f, 0.0f, 0.0f, 8)) + { + //drill->SetGoAnimProgress(0); + //drill->SetLootState(GO_READY); + //drill->UseDoorOrButton(8); + //drill->SetGoState(GO_STATE_READY); + drill->SetGoState(GO_STATE_ACTIVE); + drill->SetGoAnimProgress(0); + } + } + events.Repeat(45s); + events.RescheduleEvent(EVENT_SUMMON_ADDS, 4s); + } + break; + case EVENT_SUMMON_ADDS: + for( int i = 0; i < 4; ++i ) + { + if (!cords[i][0]) + break; + + uint8 opt; + uint8 r = urand(1, 100); + if (r <= 30) opt = 1; + else if (r <= 65) opt = 2; + else opt = 3; + + for( int j = 0; j < 4; ++j ) + { + float x = cords[i][0] + 4.0f * cos(j * M_PI / 2); + float y = cords[i][1] + 4.0f * std::sin(j * M_PI / 2); + + uint32 npc_entry = 0; + switch (opt) + { + case 1: + if (j == 1) npc_entry = NPC_DARK_RUNE_SENTINEL; + break; + case 2: + switch (j) + { + case 1: + npc_entry = NPC_DARK_RUNE_WATCHER; + break; + case 2: + npc_entry = NPC_DARK_RUNE_GUARDIAN; + break; + } + break; + default: // case 3: + switch (j) + { + case 1: + npc_entry = NPC_DARK_RUNE_WATCHER; + break; + case 2: + npc_entry = NPC_DARK_RUNE_GUARDIAN; + break; + case 3: + npc_entry = NPC_DARK_RUNE_GUARDIAN; + break; + } + break; + } + + if (npc_entry) + if (Creature* c = me->SummonCreature(npc_entry, x, y, 391.1f, j * M_PI / 2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000)) + DoZoneInCombat(c); + } + } + break; + case EVENT_WARN_DEEP_BREATH: + Talk(EMOTE_BREATH); + me->RemoveAura(62794); + events.ScheduleEvent(EVENT_PHASE2_FLAME_BREATH, 2500ms); + break; + case EVENT_PHASE2_FLAME_BREATH: + me->CastSpell(me, SPELL_FLAMEBREATH, true); + events.ScheduleEvent(EVENT_FLY_UP, 2s); + break; + case EVENT_FLY_UP: + me->SetInCombatWithZone(); // just in case + if (instance) + for( int i = 0; i < 4; ++i ) + if (Creature* hfs = instance->GetCreature(DATA_HARPOON_FIRE_STATE_1 + i)) + { + me->SummonCreature(34188, hfs->GetPositionX(), hfs->GetPositionY(), hfs->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 22000); + hfs->AI()->SetData(1, 0); + } + + me->RemoveAura(SPELL_LAUNCH_CHAIN); + me->RemoveAura(SPELL_CHAIN_1); + me->RemoveAura(SPELL_CHAIN_3); + if (RAID_MODE(0, 1)) + { + me->RemoveAura(SPELL_CHAIN_2); + me->RemoveAura(SPELL_CHAIN_4); + } + me->CastSpell(me, SPELL_WINGBUFFET, true); + + if ((me->GetHealth() * 100) / me->GetMaxHealth() < 50 ) // start phase 3 + { + Talk(EMOTE_PERMA_GROUND); + me->SetControlled(false, UNIT_STATE_ROOT); + me->DisableRotate(false); + DoResetThreatList(); + Unit* target = SelectTarget(SelectTargetMethod::MaxDistance, 0, 0.0, true); + if (!target) + target = me->SelectNearestPlayer(200.0f); + if (target) + { + AttackStart(target); + me->GetMotionMaster()->MoveChase(target); + } + bGroundPhase = true; + events.CancelEvent(EVENT_SPELL_FIREBALL); + events.CancelEvent(EVENT_SPELL_DEVOURING_FLAME); + events.CancelEvent(EVENT_SUMMON_MOLE_MACHINES); + + events.ScheduleEvent(EVENT_SPELL_FLAME_BREATH, 20s); + events.ScheduleEvent(EVENT_SPELL_DEVOURING_FLAME_GROUND, 5s); + events.ScheduleEvent(EVENT_SPELL_FUSE_ARMOR, 10s); + events.ScheduleEvent(EVENT_SPELL_FLAME_BUFFET, 3s); + + break; + } + else + { + ++flyTimes; + me->SetControlled(false, UNIT_STATE_ROOT); + me->DisableRotate(false); + me->SendMeleeAttackStop(me->GetVictim()); + me->GetMotionMaster()->MoveIdle(); + me->StopMoving(); + me->SetDisableGravity(true); + me->GetMotionMaster()->MoveTakeoff(1, CORDS_AIR, 25.0f); + events.ScheduleEvent(EVENT_RESUME_FIXING, 22s); + } + + break; + case EVENT_RESUME_FIXING: + for (uint8 i = 0; i < 3; ++i) + if (Creature* c = ObjectAccessor::GetCreature(*me, ExpeditionEngineerGUIDs[i])) + { + if (!i) + c->AI()->Talk(SAY_EE_REBUILD_TURRETS); + c->AI()->SetData(1, 0); // start repairing + } + break; + case EVENT_SPELL_FLAME_BREATH: + me->CastSpell(me->GetVictim(), SPELL_FLAMEBREATH, false); + events.Repeat(20s); + break; + case EVENT_SPELL_DEVOURING_FLAME_GROUND: + me->CastSpell(me->GetVictim(), SPELL_DEVOURINGFLAME, false); + events.Repeat(13s); + break; + case EVENT_SPELL_FUSE_ARMOR: + if (Unit* victim = me->GetVictim()) + if (me->IsWithinMeleeRange(victim)) + { + me->CastSpell(victim, SPELL_FUSEARMOR, false); + if (Aura* aur = victim->GetAura(SPELL_FUSEARMOR)) + if (aur->GetStackAmount() == 5) + victim->CastSpell(victim, SPELL_FUSED_ARMOR, true); + events.Repeat(10s); + break; + } + events.Repeat(2s); + break; + case EVENT_SPELL_FLAME_BUFFET: + me->CastSpell(me->GetVictim(), SPELL_FLAMEBUFFET, false); + events.Repeat(7s); + break; } - void KilledUnit(Unit* victim) override - { - if (victim && victim->GetEntry() == NPC_DARK_RUNE_GUARDIAN) - if (pInstance) - pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_DARK_RUNE_GUARDIAN, 1, me); - } + if (bGroundPhase) + DoMeleeAttackIfReady(); + } - void EnterEvadeMode(EvadeReason why) override - { - me->SetDisableGravity(true); - me->SetControlled(false, UNIT_STATE_ROOT); - me->DisableRotate(false); - ScriptedAI::EnterEvadeMode(why); - } - }; + void MoveInLineOfSight(Unit* /*who*/) override {} + + void JustReachedHome() override + { + _JustReachedHome(); + startPath = true; + } + + uint32 GetData(uint32 id) const override + { + if (id == 1) + return (flyTimes <= 1 ? 1 : 0); + return 0; + } + + void KilledUnit(Unit* victim) override + { + if (victim && victim->GetEntry() == NPC_DARK_RUNE_GUARDIAN) + if (instance) + instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_DARK_RUNE_GUARDIAN, 1, me); + } + + void EnterEvadeMode(EvadeReason why) override + { + me->SetDisableGravity(true); + me->SetControlled(false, UNIT_STATE_ROOT); + me->DisableRotate(false); + BossAI::EnterEvadeMode(why); + } }; class npc_ulduar_expedition_commander : public CreatureScript @@ -625,10 +591,10 @@ public: if (!instance) return true; - if (instance->GetData(TYPE_RAZORSCALE) == DONE) + if (instance->GetBossState(BOSS_RAZORSCALE) == DONE) return true; - Creature* razorscale = ObjectAccessor::GetCreature(*creature, instance->GetGuidData(TYPE_RAZORSCALE)); + Creature* razorscale = instance->GetCreature(BOSS_RAZORSCALE); if (!razorscale || razorscale->IsInCombat()) return true; @@ -645,10 +611,10 @@ public: if (uiAction == GOSSIP_ACTION_INFO_DEF + 1) { InstanceScript* instance = creature->GetInstanceScript(); - if (!instance || instance->GetData(TYPE_RAZORSCALE) == DONE) + if (!instance || instance->GetBossState(BOSS_RAZORSCALE) == DONE) return true; - Creature* razorscale = ObjectAccessor::GetCreature(*creature, instance->GetGuidData(TYPE_RAZORSCALE)); + Creature* razorscale = instance->GetCreature(BOSS_RAZORSCALE); if (razorscale && !razorscale->IsInCombat()) { // Do not show gossip icon if encounter is in progress @@ -656,7 +622,7 @@ public: // reset npcs NPC_HARPOON_FIRE_STATE for (uint8 i = 0; i < 4; ++i) - if (Creature* hfs = ObjectAccessor::GetCreature(*creature, instance->GetGuidData(DATA_HARPOON_FIRE_STATE_1 + i))) + if (Creature* hfs = instance->GetCreature(DATA_HARPOON_FIRE_STATE_1 + i)) hfs->AI()->SetData(1, 0); if (razorscale->AI()) @@ -682,7 +648,7 @@ public: npc_ulduar_expedition_commanderAI(Creature* creature) : NullCreatureAI(creature) { _instance = creature->GetInstanceScript(); - _introSpoken = _instance->GetData(TYPE_RAZORSCALE) == DONE; + _introSpoken = _instance->GetBossState(BOSS_RAZORSCALE) == DONE; me->SetReactState(REACT_AGGRESSIVE); } @@ -704,213 +670,188 @@ public: }; }; -class npc_ulduar_harpoonfirestate : public CreatureScript +struct npc_ulduar_harpoonfirestate : public NullCreatureAI { -public: - npc_ulduar_harpoonfirestate() : CreatureScript("npc_ulduar_harpoonfirestate") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_ulduar_harpoonfirestate(Creature* pCreature) : NullCreatureAI(pCreature) { - return GetUlduarAI(pCreature); + pInstance = me->GetInstanceScript(); } - struct npc_ulduar_harpoonfirestateAI : public NullCreatureAI + InstanceScript* pInstance; + uint8 repairPoints; + + void Reset() override { - npc_ulduar_harpoonfirestateAI(Creature* pCreature) : NullCreatureAI(pCreature) - { - pInstance = me->GetInstanceScript(); - } - - InstanceScript* pInstance; - uint8 repairPoints; - - void Reset() override - { - repairPoints = 0; - } - - uint32 GetHarpoonGunIdForThisHFS() - { - if (pInstance) - { - if (me->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_1)) - return GO_HARPOON_GUN_1; - else if (me->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_2)) - return GO_HARPOON_GUN_2; - else if (me->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_3)) - return GO_HARPOON_GUN_3; - else - return GO_HARPOON_GUN_4; - } - return 0; - } - - void SetData(uint32 id, uint32 value) override - { - switch (id) - { - case 1: // cleanup at the start of the fight - if (pInstance) - { - uint32 h_entry = GetHarpoonGunIdForThisHFS(); - if (GameObject* wh = me->FindNearestGameObject(h_entry, 5.0f)) - { - wh->SetRespawnTime(0); - wh->Delete(); - } - if (GameObject* bh = me->FindNearestGameObject(GO_BROKEN_HARPOON, 5.0f)) - if (bh->GetPhaseMask() != 1) - bh->SetPhaseMask(1, true); - } - Reset(); - break; - case 2: // repairing - if (repairPoints < REPAIR_POINTS) - { - if (++repairPoints >= REPAIR_POINTS) - { - if (GameObject* bh = me->FindNearestGameObject(GO_BROKEN_HARPOON, 4.0f)) - bh->SetPhaseMask(2, true); - if (GameObject* wh = me->SummonGameObject(GetHarpoonGunIdForThisHFS(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 3 * M_PI / 2, 0.0f, 0.0f, 0.0f, 0.0f, 0)) - { - me->RemoveGameObject(wh, false); - if (Creature* cr = me->SummonCreature(NPC_RAZORSCALE_CONTROLLER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 5000)) - cr->AI()->Talk(EMOTE_HARPOON); - } - } - } - break; - case 3: // shoot - if (pInstance) - { - Creature* razorscale = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_RAZORSCALE)); - if (!razorscale) - return; - if (!razorscale->HasAura(value)) - me->CastSpell(razorscale, SPELL_LAUNCH_CHAIN, true); - } - break; - } - } - - uint32 GetData(uint32 id) const override - { - switch (id) - { - case 2: - return (repairPoints >= REPAIR_POINTS ? 1 : 0); - } - return 0; - } - }; -}; - -class npc_ulduar_expedition_engineer : public CreatureScript -{ -public: - npc_ulduar_expedition_engineer() : CreatureScript("npc_ulduar_expedition_engineer") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); + repairPoints = 0; } - struct npc_ulduar_expedition_engineerAI : public NullCreatureAI + uint32 GetHarpoonGunIdForThisHFS() { - npc_ulduar_expedition_engineerAI(Creature* pCreature) : NullCreatureAI(pCreature) + if (pInstance) { - pInstance = me->GetInstanceScript(); + if (me->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_1)) + return GO_HARPOON_GUN_1; + else if (me->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_2)) + return GO_HARPOON_GUN_2; + else if (me->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_3)) + return GO_HARPOON_GUN_3; + else + return GO_HARPOON_GUN_4; } + return 0; + } - InstanceScript* pInstance; - bool working; - uint16 timer; - ObjectGuid fixingGUID; - - void Reset() override + void SetData(uint32 id, uint32 value) override + { + switch (id) { - working = false; - timer = 0; - fixingGUID.Clear(); - } - - void SetData(uint32 id, uint32 /*value*/) override - { - switch (id) - { - case 1: // start/resume repairing - working = true; - timer = 0; - fixingGUID.Clear(); - break; - case 2: // stop repairing - Reset(); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND); - me->GetMotionMaster()->MoveTargetedHome(); - break; - } - } - - void UpdateAI(uint32 diff) override - { - if (working) - { - if (timer <= diff) + case 1: // cleanup at the start of the fight + if (pInstance) { - timer = 3000; - - if (fixingGUID) + uint32 h_entry = GetHarpoonGunIdForThisHFS(); + if (GameObject* wh = me->FindNearestGameObject(h_entry, 5.0f)) { - if (Creature* c = ObjectAccessor::GetCreature(*me, fixingGUID)) - if (me->GetExactDist2dSq(c) <= 25.0f) - { - if (me->GetUInt32Value(UNIT_NPC_EMOTESTATE) != EMOTE_STATE_WORK ) - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_WORK); - - if (std::fabs(me->GetOrientation() - me->GetAngle(c)) > M_PI / 4) - me->SetFacingToObject(c); - - c->AI()->SetData(2, 0); - if (c->AI()->GetData(2)) - fixingGUID.Clear(); - } + wh->SetRespawnTime(0); + wh->Delete(); } - - if (!fixingGUID) + if (GameObject* bh = me->FindNearestGameObject(GO_BROKEN_HARPOON, 5.0f)) + if (bh->GetPhaseMask() != 1) + bh->SetPhaseMask(1, true); + } + Reset(); + break; + case 2: // repairing + if (repairPoints < REPAIR_POINTS) + { + if (++repairPoints >= REPAIR_POINTS) { - Creature* razorscale = nullptr; - if (ObjectGuid rsGUID = pInstance->GetGuidData(TYPE_RAZORSCALE)) - razorscale = ObjectAccessor::GetCreature(*me, rsGUID); - - if (!razorscale || !razorscale->IsInCombat()) + if (GameObject* bh = me->FindNearestGameObject(GO_BROKEN_HARPOON, 4.0f)) + bh->SetPhaseMask(2, true); + if (GameObject* wh = me->SummonGameObject(GetHarpoonGunIdForThisHFS(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 3 * M_PI / 2, 0.0f, 0.0f, 0.0f, 0.0f, 0)) { - Reset(); - me->GetMotionMaster()->MoveTargetedHome(); - return; + me->RemoveGameObject(wh, false); + if (Creature* cr = me->SummonCreature(NPC_RAZORSCALE_CONTROLLER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 5000)) + cr->AI()->Talk(EMOTE_HARPOON); } - - for( int i = 0; i < 4; ++i ) - if (ObjectGuid fs_GUID = pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_1 + i)) - if (Creature* fs = ObjectAccessor::GetCreature(*me, fs_GUID)) - if (!fs->AI()->GetData(2)) - { - float a = rand_norm() * M_PI; - me->GetMotionMaster()->MovePoint(0, fs->GetPositionX() + 3.0f * cos(a), fs->GetPositionY() + 3.0f * std::sin(a), fs->GetPositionZ()); - fixingGUID = fs->GetGUID(); - return; - } - - Reset(); // all harpoons repaired - me->GetMotionMaster()->MoveTargetedHome(); } } - else - timer -= diff; - } - else if (me->GetUInt32Value(UNIT_NPC_EMOTESTATE) == EMOTE_STATE_WORK) - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND); + break; + case 3: // shoot + if (pInstance) + { + Creature* razorscale = pInstance->GetCreature(BOSS_RAZORSCALE); + if (!razorscale) + return; + if (!razorscale->HasAura(value)) + me->CastSpell(razorscale, SPELL_LAUNCH_CHAIN, true); + } + break; } - }; + } + + uint32 GetData(uint32 id) const override + { + switch (id) + { + case 2: + return (repairPoints >= REPAIR_POINTS ? 1 : 0); + } + return 0; + } +}; + +struct npc_ulduar_expedition_engineer : public NullCreatureAI +{ + npc_ulduar_expedition_engineer(Creature* pCreature) : NullCreatureAI(pCreature) + { + pInstance = me->GetInstanceScript(); + } + + InstanceScript* pInstance; + bool working; + uint16 timer; + ObjectGuid fixingGUID; + + void Reset() override + { + working = false; + timer = 0; + fixingGUID.Clear(); + } + + void SetData(uint32 id, uint32 /*value*/) override + { + switch (id) + { + case 1: // start/resume repairing + working = true; + timer = 0; + fixingGUID.Clear(); + break; + case 2: // stop repairing + Reset(); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND); + me->GetMotionMaster()->MoveTargetedHome(); + break; + } + } + + void UpdateAI(uint32 diff) override + { + if (working) + { + if (timer <= diff) + { + timer = 3000; + + if (fixingGUID) + { + if (Creature* c = ObjectAccessor::GetCreature(*me, fixingGUID)) + if (me->GetExactDist2dSq(c) <= 25.0f) + { + if (me->GetUInt32Value(UNIT_NPC_EMOTESTATE) != EMOTE_STATE_WORK ) + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_WORK); + + if (std::fabs(me->GetOrientation() - me->GetAngle(c)) > M_PI / 4) + me->SetFacingToObject(c); + + c->AI()->SetData(2, 0); + if (c->AI()->GetData(2)) + fixingGUID.Clear(); + } + } + + if (!fixingGUID) + { + Creature* razorscale = pInstance->GetCreature(BOSS_RAZORSCALE); + + if (!razorscale || !razorscale->IsInCombat()) + { + Reset(); + me->GetMotionMaster()->MoveTargetedHome(); + return; + } + + for( int i = 0; i < 4; ++i ) + if (Creature* fs = pInstance->GetCreature(DATA_HARPOON_FIRE_STATE_1 + i)) + if (!fs->AI()->GetData(2)) + { + float a = rand_norm() * M_PI; + me->GetMotionMaster()->MovePoint(0, fs->GetPositionX() + 3.0f * cos(a), fs->GetPositionY() + 3.0f * std::sin(a), fs->GetPositionZ()); + fixingGUID = fs->GetGUID(); + return; + } + + Reset(); // all harpoons repaired + me->GetMotionMaster()->MoveTargetedHome(); + } + } + else + timer -= diff; + } + else if (me->GetUInt32Value(UNIT_NPC_EMOTESTATE) == EMOTE_STATE_WORK) + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND); + } }; class go_ulduar_working_harpoon : public GameObjectScript @@ -927,9 +868,7 @@ public: if (!pInstance) return true; - Creature* rs = nullptr; - if (ObjectGuid rsGUID = pInstance->GetGuidData(TYPE_RAZORSCALE)) - rs = ObjectAccessor::GetCreature(*go, rsGUID); + Creature* rs = pInstance->GetCreature(BOSS_RAZORSCALE); if (!rs || !rs->IsInCombat()) { @@ -960,8 +899,7 @@ public: break; } - if (ObjectGuid g = pInstance->GetGuidData(npc)) - if (Creature* hfs = ObjectAccessor::GetCreature(*go, g)) + if (Creature* hfs = pInstance->GetCreature(npc)) hfs->AI()->SetData(3, spell); go->SetLootState(GO_JUST_DEACTIVATED); @@ -969,161 +907,128 @@ public: } }; -class npc_ulduar_dark_rune_guardian : public CreatureScript +struct npc_ulduar_dark_rune_guardian : public ScriptedAI { -public: - npc_ulduar_dark_rune_guardian() : CreatureScript("npc_ulduar_dark_rune_guardian") { } + npc_ulduar_dark_rune_guardian(Creature* pCreature) : ScriptedAI(pCreature) { } - CreatureAI* GetAI(Creature* pCreature) const override + uint32 timer2; + + void Reset() override { - return GetUlduarAI(pCreature); + timer2 = 6000; } - struct npc_ulduar_dark_rune_guardianAI : public ScriptedAI + bool CanAIAttack(Unit const* target) const override { - npc_ulduar_dark_rune_guardianAI(Creature* pCreature) : ScriptedAI(pCreature) { } + return target && target->GetEntry() != NPC_RAZORSCALE; + } - uint32 timer2; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void Reset() override + if (timer2 <= diff) timer2 = 0; + else timer2 -= diff; + if (timer2 == 0 && me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim())) { - timer2 = 6000; + me->CastSpell(me->GetVictim(), SPELL_STORMSTRIKE_DMG, true); + me->CastSpell(me->GetVictim(), SPELL_STORMSTRIKE_DMG, true); // cast the same twice cus second one requires setting offhand damage + me->CastSpell(me->GetVictim(), SPELL_STORMSTRIKE_DEBUFF, true); + timer2 = urand(8000, 10000); + return; } - bool CanAIAttack(Unit const* target) const override - { - return target && target->GetEntry() != NPC_RAZORSCALE; - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (timer2 <= diff) timer2 = 0; - else timer2 -= diff; - if (timer2 == 0 && me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim())) - { - me->CastSpell(me->GetVictim(), SPELL_STORMSTRIKE_DMG, true); - me->CastSpell(me->GetVictim(), SPELL_STORMSTRIKE_DMG, true); // cast the same twice cus second one requires setting offhand damage - me->CastSpell(me->GetVictim(), SPELL_STORMSTRIKE_DEBUFF, true); - timer2 = urand(8000, 10000); - return; - } - - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; -class npc_ulduar_dark_rune_watcher : public CreatureScript +struct npc_ulduar_dark_rune_watcher : public ScriptedAI { -public: - npc_ulduar_dark_rune_watcher() : CreatureScript("npc_ulduar_dark_rune_watcher") { } + npc_ulduar_dark_rune_watcher(Creature* pCreature) : ScriptedAI(pCreature) { } - CreatureAI* GetAI(Creature* pCreature) const override + uint32 timer1; + uint32 timer2; + + void Reset() override { - return GetUlduarAI(pCreature); + timer1 = 6000; + timer2 = 2000; } - struct npc_ulduar_dark_rune_watcherAI : public ScriptedAI + bool CanAIAttack(Unit const* target) const override { - npc_ulduar_dark_rune_watcherAI(Creature* pCreature) : ScriptedAI(pCreature) { } + return target && target->GetEntry() != NPC_RAZORSCALE; + } - uint32 timer1; - uint32 timer2; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void Reset() override + if (timer1 <= diff) { - timer1 = 6000; - timer2 = 2000; + me->CastSpell(me->GetVictim(), SPELL_CHAINLIGHTNING, false); + timer1 = urand(10000, 12000); + return; } + else + timer1 -= diff; - bool CanAIAttack(Unit const* target) const override + if (timer2 <= diff) { - return target && target->GetEntry() != NPC_RAZORSCALE; + me->CastSpell(me->GetVictim(), SPELL_LIGHTINGBOLT, false); + timer2 = 4000; + return; } + else + timer2 -= diff; - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (timer1 <= diff) - { - me->CastSpell(me->GetVictim(), SPELL_CHAINLIGHTNING, false); - timer1 = urand(10000, 12000); - return; - } - else - timer1 -= diff; - - if (timer2 <= diff) - { - me->CastSpell(me->GetVictim(), SPELL_LIGHTINGBOLT, false); - timer2 = 4000; - return; - } - else - timer2 -= diff; - - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; -class npc_ulduar_dark_rune_sentinel : public CreatureScript +struct npc_ulduar_dark_rune_sentinel : public ScriptedAI { -public: - npc_ulduar_dark_rune_sentinel() : CreatureScript("npc_ulduar_dark_rune_sentinel") { } + npc_ulduar_dark_rune_sentinel(Creature* pCreature) : ScriptedAI(pCreature) { } - CreatureAI* GetAI(Creature* pCreature) const override + uint32 timer1; + uint32 timer2; + + void Reset() override { - return GetUlduarAI(pCreature); + timer1 = urand(1000, 2000); + timer2 = 6000; } - struct npc_ulduar_dark_rune_sentinelAI : public ScriptedAI + bool CanAIAttack(Unit const* target) const override { - npc_ulduar_dark_rune_sentinelAI(Creature* pCreature) : ScriptedAI(pCreature) { } + return target && target->GetEntry() != NPC_RAZORSCALE; + } - uint32 timer1; - uint32 timer2; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void Reset() override + if (timer1 <= diff) { - timer1 = urand(1000, 2000); - timer2 = 6000; + me->CastSpell(me, SPELL_BATTLE_SHOUT, false); + timer1 = urand(15000, 20000); + } + else + timer1 -= diff; + + if (timer2 <= diff) timer2 = 0; + else timer2 -= diff; + if (timer2 == 0 && me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim())) + { + me->CastSpell(me, SPELL_WHIRLWIND, false); + timer2 = urand(10000, 12000); } - bool CanAIAttack(Unit const* target) const override - { - return target && target->GetEntry() != NPC_RAZORSCALE; - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (timer1 <= diff) - { - me->CastSpell(me, SPELL_BATTLE_SHOUT, false); - timer1 = urand(15000, 20000); - } - else - timer1 -= diff; - - if (timer2 <= diff) timer2 = 0; - else timer2 -= diff; - if (timer2 == 0 && me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim())) - { - me->CastSpell(me, SPELL_WHIRLWIND, false); - timer2 = urand(10000, 12000); - } - - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; class achievement_quick_shave : public AchievementCriteriaScript @@ -1150,14 +1055,14 @@ public: void AddSC_boss_razorscale() { - new boss_razorscale(); + RegisterUlduarCreatureAI(boss_razorscale); new npc_ulduar_expedition_commander(); - new npc_ulduar_harpoonfirestate(); - new npc_ulduar_expedition_engineer(); + RegisterUlduarCreatureAI(npc_ulduar_harpoonfirestate); + RegisterUlduarCreatureAI(npc_ulduar_expedition_engineer); new go_ulduar_working_harpoon(); - new npc_ulduar_dark_rune_guardian(); - new npc_ulduar_dark_rune_watcher(); - new npc_ulduar_dark_rune_sentinel(); + RegisterUlduarCreatureAI(npc_ulduar_dark_rune_guardian); + RegisterUlduarCreatureAI(npc_ulduar_dark_rune_watcher); + RegisterUlduarCreatureAI(npc_ulduar_dark_rune_sentinel); new achievement_quick_shave(); new achievement_iron_dwarf_medium_rare(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp index b3e9a9633..6b94236bd 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp @@ -299,503 +299,468 @@ enum Misc const Position Middle = {2134.68f, -263.13f, 419.44f, M_PI * 1.5f}; -class boss_thorim : public CreatureScript +struct boss_thorim : public BossAI { -public: - boss_thorim() : CreatureScript("boss_thorim") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_thorim(Creature* creature) : BossAI(creature, BOSS_THORIM) { - return GetUlduarAI(pCreature); + _encounterFinished = !me->IsAlive(); + if (_encounterFinished) + instance->SetBossState(BOSS_THORIM, DONE); } - struct boss_thorimAI : public ScriptedAI + bool _isArenaEmpty; + bool _encounterFinished; + bool _spawnCommoners; + bool _hardMode; + bool _isHitAllowed; + bool _isAlly; + uint8 _trashCounter; + + bool _hitByLightning; + + void DisableThorim(bool apply) { - boss_thorimAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me) + if (apply) { - m_pInstance = pCreature->GetInstanceScript(); - if ((_encounterFinished = (!me->IsAlive()))) - if (m_pInstance) - m_pInstance->SetData(TYPE_THORIM, DONE); + me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_PACIFIED); + me->DisableRotate(true); + me->AddUnitState(UNIT_STATE_ROOT); } - - bool _isArenaEmpty; - bool _encounterFinished; - bool _spawnCommoners; - bool _hardMode; - bool _isHitAllowed; - bool _isAlly; - uint8 _trashCounter; - - InstanceScript* m_pInstance; - EventMap events; - SummonList summons; - - bool _hitByLightning; - - void DisableThorim(bool apply) + else { - if (apply) + me->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_PACIFIED); + me->DisableRotate(false); + me->ClearUnitState(UNIT_STATE_ROOT); + me->resetAttackTimer(BASE_ATTACK); + } + } + + GameObject* GetThorimObject(uint32 entry) + { + return instance->GetGameObject(entry); + } + + void SpawnAllNPCs() + { + // Jormungar Behemoth 32882 + me->SummonCreature(NPC_JORMUNGAR_BEHEMOT, 2149.68f, -263.477f, 419.679f, 3.12102f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + + // Captured Mercenary Soldier 32885 + me->SummonCreature(_isAlly ? NPC_CAPTURED_MERCENARY_SOLDIER_ALLY : NPC_CAPTURED_MERCENARY_SOLDIER_HORDE, 2127.24f, -251.309f, 419.793f, 5.89921f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + me->SummonCreature(_isAlly ? NPC_CAPTURED_MERCENARY_SOLDIER_ALLY : NPC_CAPTURED_MERCENARY_SOLDIER_HORDE, 2120.1f, -258.99f, 419.764f, 6.24828f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + me->SummonCreature(_isAlly ? NPC_CAPTURED_MERCENARY_SOLDIER_ALLY : NPC_CAPTURED_MERCENARY_SOLDIER_HORDE, 2123.32f, -254.771f, 419.789f, 6.17846f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + + // Captured Mercenary Captain 32908 + me->SummonCreature(_isAlly ? NPC_CAPTURED_MERCENARY_CAPTAIN_ALLY : NPC_CAPTURED_MERCENARY_CAPTAIN_HORDE, 2131.31f, -259.182f, 419.974f, 5.91667f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + + // Dark Rune Acolyte (arena) 32886 + me->SummonCreature(NPC_DARK_RUNE_ACOLYTE_I, 2129.09f, -277.142f, 419.756f, 1.22173f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + + // Iron Ring Guard 32874 + me->SummonCreature(NPC_IRON_RING_GUARD, 2217.69f, -337.394f, 412.177f, 1.23918f); + me->SummonCreature(NPC_IRON_RING_GUARD, 2218.38f, -297.505f, 412.176f, 1.02974f); + me->SummonCreature(NPC_IRON_RING_GUARD, 2235.26f, -338.345f, 412.134f, 1.58979f); + me->SummonCreature(NPC_IRON_RING_GUARD, 2235.07f, -297.985f, 412.134f, 1.61336f); + + // Dark Rune Acolyte (gauntlet) 33110 + me->SummonCreature(NPC_DARK_RUNE_ACOLYTE_G, 2198.29f, -436.92f, 419.985f, 0.261799f); + me->SummonCreature(NPC_DARK_RUNE_ACOLYTE_G, 2227.58f, -308.303f, 412.134f, 1.59372f); + me->SummonCreature(NPC_DARK_RUNE_ACOLYTE_G, 2227.47f, -345.375f, 412.134f, 1.56622f); + + // Iron Honor Guard 32875 + me->SummonCreature(NPC_IRON_HONOR_GUARD, 2198.05f, -428.769f, 419.985f, 6.05629f); + me->SummonCreature(NPC_IRON_HONOR_GUARD, 2220.31f, -436.22f, 412.26f, 1.06465f); + + // Runic Colossus 32872 + me->SummonCreature(NPC_RUNIC_COLOSSUS, 2227.5f, -396.179f, 412.176f, 1.79769f); + + // Ancient Rune Giant 32873 + me->SummonCreature(NPC_ANCIENT_RUNE_GIANT, 2134.57f, -440.318f, 438.331f, 0.226893f); + + // Sif 33196 + me->SummonCreature(NPC_SIF, 2147.86f, -301.2f, 438.246f, 2.488f); + } + + void CloseDoors() + { + GameObject* go; + if ((go = GetThorimObject(DATA_THORIM_LEVER))) + { + go->ReplaceAllGameObjectFlags((GameObjectFlags)48); + go->SetGoState(GO_STATE_READY); + } + if ((go = GetThorimObject(DATA_THORIM_FIRST_DOORS))) + go->SetGoState(GO_STATE_READY); + + if ((go = GetThorimObject(DATA_THORIM_SECOND_DOORS))) + go->SetGoState(GO_STATE_READY); + + if ((go = GetThorimObject(DATA_THORIM_FENCE))) + go->SetGoState(GO_STATE_ACTIVE); + } + + void EnterEvadeMode(EvadeReason why) override + { + DisableThorim(false); + BossAI::EnterEvadeMode(why); + } + + void Reset() override + { + if (!_encounterFinished) + _Reset(); + + _trashCounter = 0; + _isAlly = true; + _isHitAllowed = false; + _spawnCommoners = false; + _hardMode = false; + _isArenaEmpty = false; + _hitByLightning = false; + + if (Player* t = SelectTargetFromPlayerList(1000)) + if (t->GetTeamId() == TEAM_HORDE) + _isAlly = false; + + SpawnAllNPCs(); + + CloseDoors(); + DisableThorim(false); + } + + uint32 GetData(uint32 param) const override + { + if (param == DATA_HIT_BY_LIGHTNING) + return !_hitByLightning; + if (param == DATA_LOSE_YOUR_ILLUSION) + return _hardMode; + + return 0; + } + + void DoAction(int32 param) override + { + if (param == ACTION_START_TRASH_DIED) + { + _trashCounter++; + // activate levar + if (_trashCounter >= 6) { - me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_PACIFIED); - me->DisableRotate(true); - me->AddUnitState(UNIT_STATE_ROOT); - } - else - { - me->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_PACIFIED); - me->DisableRotate(false); - me->ClearUnitState(UNIT_STATE_ROOT); - me->resetAttackTimer(BASE_ATTACK); + if (GameObject* go = GetThorimObject(DATA_THORIM_LEVER)) + go->RemoveGameObjectFlag((GameObjectFlags)48); + + events.ScheduleEvent(EVENT_THORIM_AGGRO, 0ms); + events.SetPhase(EVENT_PHASE_START); + events.ScheduleEvent(EVENT_THORIM_START_PHASE1, 20s); + _trashCounter = 0; } } + else if (param == ACTION_ALLOW_HIT) + _isHitAllowed = true; + } - GameObject* GetThorimObject(uint32 entry) + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer()) + Talk(SAY_SLAY); + } + + void JustReachedHome() override + { + _JustReachedHome(); + me->setActive(false); + } + + void JustEngagedWith(Unit*) override + { + if (!_encounterFinished) + instance->SetBossState(BOSS_THORIM, IN_PROGRESS); + me->setActive(true); + DisableThorim(true); + me->CastSpell(me, SPELL_SHEATH_OF_LIGHTNING, true); + //me->CastSpell(me, SPELL_TOUCH_OF_DOMINION, true); + } + + void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (who && _isHitAllowed && who->GetPositionZ() > 430 && who->IsPlayer()) { - if (m_pInstance) - return ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(entry)); - return nullptr; - } - - void JustSummoned(Creature* cr) override { summons.Summon(cr); } - - void SpawnAllNPCs() - { - // Jormungar Behemoth 32882 - me->SummonCreature(NPC_JORMUNGAR_BEHEMOT, 2149.68f, -263.477f, 419.679f, 3.12102f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); - - // Captured Mercenary Soldier 32885 - me->SummonCreature(_isAlly ? NPC_CAPTURED_MERCENARY_SOLDIER_ALLY : NPC_CAPTURED_MERCENARY_SOLDIER_HORDE, 2127.24f, -251.309f, 419.793f, 5.89921f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); - me->SummonCreature(_isAlly ? NPC_CAPTURED_MERCENARY_SOLDIER_ALLY : NPC_CAPTURED_MERCENARY_SOLDIER_HORDE, 2120.1f, -258.99f, 419.764f, 6.24828f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); - me->SummonCreature(_isAlly ? NPC_CAPTURED_MERCENARY_SOLDIER_ALLY : NPC_CAPTURED_MERCENARY_SOLDIER_HORDE, 2123.32f, -254.771f, 419.789f, 6.17846f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); - - // Captured Mercenary Captain 32908 - me->SummonCreature(_isAlly ? NPC_CAPTURED_MERCENARY_CAPTAIN_ALLY : NPC_CAPTURED_MERCENARY_CAPTAIN_HORDE, 2131.31f, -259.182f, 419.974f, 5.91667f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); - - // Dark Rune Acolyte (arena) 32886 - me->SummonCreature(NPC_DARK_RUNE_ACOLYTE_I, 2129.09f, -277.142f, 419.756f, 1.22173f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); - - // Iron Ring Guard 32874 - me->SummonCreature(NPC_IRON_RING_GUARD, 2217.69f, -337.394f, 412.177f, 1.23918f); - me->SummonCreature(NPC_IRON_RING_GUARD, 2218.38f, -297.505f, 412.176f, 1.02974f); - me->SummonCreature(NPC_IRON_RING_GUARD, 2235.26f, -338.345f, 412.134f, 1.58979f); - me->SummonCreature(NPC_IRON_RING_GUARD, 2235.07f, -297.985f, 412.134f, 1.61336f); - - // Dark Rune Acolyte (gauntlet) 33110 - me->SummonCreature(NPC_DARK_RUNE_ACOLYTE_G, 2198.29f, -436.92f, 419.985f, 0.261799f); - me->SummonCreature(NPC_DARK_RUNE_ACOLYTE_G, 2227.58f, -308.303f, 412.134f, 1.59372f); - me->SummonCreature(NPC_DARK_RUNE_ACOLYTE_G, 2227.47f, -345.375f, 412.134f, 1.56622f); - - // Iron Honor Guard 32875 - me->SummonCreature(NPC_IRON_HONOR_GUARD, 2198.05f, -428.769f, 419.985f, 6.05629f); - me->SummonCreature(NPC_IRON_HONOR_GUARD, 2220.31f, -436.22f, 412.26f, 1.06465f); - - // Runic Colossus 32872 - me->SummonCreature(NPC_RUNIC_COLOSSUS, 2227.5f, -396.179f, 412.176f, 1.79769f); - - // Ancient Rune Giant 32873 - me->SummonCreature(NPC_ANCIENT_RUNE_GIANT, 2134.57f, -440.318f, 438.331f, 0.226893f); - - // Sif 33196 - me->SummonCreature(NPC_SIF, 2147.86f, -301.2f, 438.246f, 2.488f); - } - - void CloseDoors() - { - GameObject* go; - if ((go = GetThorimObject(DATA_THORIM_LEVER))) - { - go->ReplaceAllGameObjectFlags((GameObjectFlags)48); - go->SetGoState(GO_STATE_READY); - } - if ((go = GetThorimObject(DATA_THORIM_FIRST_DOORS))) - go->SetGoState(GO_STATE_READY); - - if ((go = GetThorimObject(DATA_THORIM_SECOND_DOORS))) - go->SetGoState(GO_STATE_READY); - - if ((go = GetThorimObject(DATA_THORIM_FENCE))) - go->SetGoState(GO_STATE_ACTIVE); - } - - void EnterEvadeMode(EvadeReason why) override - { - DisableThorim(false); - CreatureAI::EnterEvadeMode(why); - } - - void Reset() override - { - if (m_pInstance && !_encounterFinished) - m_pInstance->SetData(TYPE_THORIM, NOT_STARTED); - - events.Reset(); - events.SetPhase(0); - summons.DespawnAll(); - - _trashCounter = 0; - _isAlly = true; _isHitAllowed = false; - _spawnCommoners = false; - _hardMode = false; - _isArenaEmpty = false; - _hitByLightning = false; - - if (Player* t = SelectTargetFromPlayerList(1000)) - if (t->GetTeamId() == TEAM_HORDE) - _isAlly = false; - - SpawnAllNPCs(); - - CloseDoors(); DisableThorim(false); - } - uint32 GetData(uint32 param) const override - { - if (param == DATA_HIT_BY_LIGHTNING) - return !_hitByLightning; - if (param == DATA_LOSE_YOUR_ILLUSION) - return _hardMode; + events.SetPhase(EVENT_PHASE_RING); + events.ScheduleEvent(EVENT_THORIM_UNBALANCING_STRIKE, 8s, 0, EVENT_PHASE_RING); + events.ScheduleEvent(EVENT_THORIM_LIGHTNING_CHARGE, 12s + 500ms, 0, EVENT_PHASE_RING); + events.ScheduleEvent(EVENT_THORIM_CHAIN_LIGHTNING, 13s, 0, EVENT_PHASE_RING); + events.ScheduleEvent(EVENT_THORIM_BERSERK, 5min, 0, EVENT_PHASE_RING); - return 0; - } + me->GetMotionMaster()->MoveChase(me->GetVictim()); + me->GetMotionMaster()->MoveJump(Middle.GetPositionX(), Middle.GetPositionY(), Middle.GetPositionZ(), 20, 20); + me->RemoveAura(SPELL_SHEATH_OF_LIGHTNING); - void DoAction(int32 param) override - { - if (param == ACTION_START_TRASH_DIED) + Talk(SAY_JUMPDOWN); + + // Hard Mode + if (!me->HasAura(62565 /*TOUCH OF DOMINION TRIGGER*/)) { - _trashCounter++; - // activate levar - if (_trashCounter >= 6) - { - if (GameObject* go = GetThorimObject(DATA_THORIM_LEVER)) - go->RemoveGameObjectFlag((GameObjectFlags)48); + instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 64980 /*SIFFED ACHIEVEMENT*/); - events.ScheduleEvent(EVENT_THORIM_AGGRO, 0ms); - events.SetPhase(EVENT_PHASE_START); - events.ScheduleEvent(EVENT_THORIM_START_PHASE1, 20s); - _trashCounter = 0; - } - } - else if (param == ACTION_ALLOW_HIT) - _isHitAllowed = true; - } - - void KilledUnit(Unit* victim) override - { - if (victim->IsPlayer()) - Talk(SAY_SLAY); - } - - void JustReachedHome() override { me->setActive(false); } - - void JustEngagedWith(Unit*) override - { - if (m_pInstance && !_encounterFinished) - m_pInstance->SetData(TYPE_THORIM, IN_PROGRESS); - me->setActive(true); - DisableThorim(true); - me->CastSpell(me, SPELL_SHEATH_OF_LIGHTNING, true); - //me->CastSpell(me, SPELL_TOUCH_OF_DOMINION, true); - } - - void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (who && _isHitAllowed && who->GetPositionZ() > 430 && who->IsPlayer()) - { - _isHitAllowed = false; - DisableThorim(false); - - events.SetPhase(EVENT_PHASE_RING); - events.ScheduleEvent(EVENT_THORIM_UNBALANCING_STRIKE, 8s, 0, EVENT_PHASE_RING); - events.ScheduleEvent(EVENT_THORIM_LIGHTNING_CHARGE, 12s + 500ms, 0, EVENT_PHASE_RING); - events.ScheduleEvent(EVENT_THORIM_CHAIN_LIGHTNING, 13s, 0, EVENT_PHASE_RING); - events.ScheduleEvent(EVENT_THORIM_BERSERK, 5min, 0, EVENT_PHASE_RING); - - me->GetMotionMaster()->MoveChase(me->GetVictim()); - me->GetMotionMaster()->MoveJump(Middle.GetPositionX(), Middle.GetPositionY(), Middle.GetPositionZ(), 20, 20); - me->RemoveAura(SPELL_SHEATH_OF_LIGHTNING); - - Talk(SAY_JUMPDOWN); - - // Hard Mode - if (!me->HasAura(62565 /*TOUCH OF DOMINION TRIGGER*/)) - { - if (m_pInstance) - m_pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 64980 /*SIFFED ACHIEVEMENT*/); - - _hardMode = true; - EntryCheckPredicate pred(NPC_SIF); - summons.DoAction(ACTION_SIF_JOIN_FIGHT, pred); - } - - DoResetThreatList(); - if (Player* player = GetArenaPlayer()) - me->AddThreat(player, 1000.0f); + _hardMode = true; + EntryCheckPredicate pred(NPC_SIF); + summons.DoAction(ACTION_SIF_JOIN_FIGHT, pred); } - if (damage >= me->GetHealth()|| me->GetHealth()<2) - { - damage = 0; - if (!_encounterFinished) - { - _encounterFinished = true; - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetFaction(FACTION_FRIENDLY); - me->SetHealth(me->GetMaxHealth()); - me->CombatStop(); - me->RemoveAllAuras(); - events.Reset(); - DisableThorim(true); - - Talk(SAY_DEATH); - - events.SetPhase(EVENT_PHASE_OUTRO); - events.ScheduleEvent(EVENT_THORIM_OUTRO1, 2s, 0, EVENT_PHASE_OUTRO); - - GameObject* go = nullptr; - if ((go = GetThorimObject(DATA_THORIM_FENCE))) - go->SetGoState(GO_STATE_ACTIVE); - - uint32 chestId = me->GetMap()->Is25ManRaid() ? GO_THORIM_CHEST_HERO : GO_THORIM_CHEST; - if (_hardMode) - chestId += 1; // hard mode offset - - if ((go = me->SummonGameObject(chestId, 2134.73f, -286.32f, 419.51f, 4.65f, 0, 0, 0, 0, 0))) - { - go->ReplaceAllGameObjectFlags((GameObjectFlags)0); - go->SetLootRecipient(me->GetMap()); - } - - // Defeat credit - if (m_pInstance) - { - me->CastSpell(me, 64985, true); // credit - m_pInstance->SetData(TYPE_THORIM, DONE); - } - } - } + DoResetThreatList(); + if (Player* player = GetArenaPlayer()) + me->AddThreat(player, 1000.0f); } - void SpawnAnArenaNPC(uint32 arenaNpc) + if (damage >= me->GetHealth()|| me->GetHealth()<2) { - Creature* cr; - uint8 rnd = urand(0,13); - if ((cr = me->SummonCreature(arenaNpc, ArenaNPCs[rnd], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000))) - cr->GetMotionMaster()->MoveJump( - Middle.GetPositionX() + urand(19, 24) * cos(Middle.GetAngle(cr)), - Middle.GetPositionY() + urand(19, 24) * std::sin(Middle.GetAngle(cr)), - Middle.GetPositionZ(), 20, 20); - } - - void SpawnCommoners() - { - uint8 rnd = urand(6,7); - for (uint8 i = 0; i < rnd; ++i) - SpawnAnArenaNPC(NPC_DARK_RUNE_COMMONER); - } - - void SpellHit(Unit* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_LIGHTNING_ORB_CHARGER) - { - me->SetOrientation(me->GetAngle(caster)); - me->CastSpell(caster, SPELL_LIGHTNING_CHARGE_DAMAGE, true); - me->CastSpell(me, SPELL_LIGHTNING_CHARGE_BUFF, true); - events.RescheduleEvent(EVENT_THORIM_LIGHTNING_CHARGE, 10s, 0, EVENT_PHASE_RING); - } - else if (spellInfo->Id == SPELL_TELEPORT) - { - me->DespawnOrUnsummon(); - m_pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE); - } - } - - void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_LIGHTNING_CHARGE_DAMAGE && target->IsPlayer()) - _hitByLightning = true; - } - - Player* GetArenaPlayer() - { - Map::PlayerList const& pList = me->GetMap()->GetPlayers(); - for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) - if (Player* p = itr->GetSource()) - if (p->GetPositionX() > 2085 && p->GetPositionX() < 2185 && p->GetPositionY() < -214 && p->GetPositionY() > -305 && p->IsAlive() && p->GetPositionZ() < 425) - return p; - return nullptr; - } - - void UpdateAI(uint32 diff) override - { - if (!_encounterFinished && !UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_THORIM_AGGRO: - Talk(SAY_AGGRO_1); - events.ScheduleEvent(EVENT_THORIM_AGGRO2, 9s); - - if (GameObject* go = GetThorimObject(DATA_THORIM_FENCE)) - go->SetGoState(GO_STATE_READY); - - break; - case EVENT_THORIM_AGGRO2: - { - Talk(SAY_AGGRO_2); - - EntryCheckPredicate pred(NPC_SIF); - summons.DoAction(ACTION_SIF_START_TALK, pred); - break; - } - case EVENT_THORIM_START_PHASE1: - { - events.ScheduleEvent(EVENT_THORIM_STORMHAMMER, 8s, 0, EVENT_PHASE_START); - events.ScheduleEvent(EVENT_THORIM_CHARGE_ORB, 14s, 0, EVENT_PHASE_START); - events.ScheduleEvent(EVENT_THORIM_ARENA_SPAWN_WARBRINGER, 0ms, 0, EVENT_PHASE_START); - events.ScheduleEvent(EVENT_THORIM_ARENA_SPAWN_EVOKER, 5s, 0, EVENT_PHASE_START); - events.ScheduleEvent(EVENT_THORIM_ARENA_SPAWN_COMMONER, 7s, 0, EVENT_PHASE_START); - events.ScheduleEvent(EVENT_THORIM_ARENA_SPAWN_CHAMPION, 10s, 0, EVENT_PHASE_START); - events.ScheduleEvent(EVENT_THORIM_LIGHTNING_ORB, 5s, 0, EVENT_PHASE_START); // checked every 5 secs if there are players on arena - events.ScheduleEvent(EVENT_THORIM_NOT_REACH_IN_TIME, 5min, 0, EVENT_PHASE_START); - EntryCheckPredicate pred(NPC_SIF); - summons.DoAction(ACTION_SIF_START_DOMINION, pred); - break; - } - case EVENT_THORIM_STORMHAMMER: - me->CastCustomSpell(SPELL_STORMHAMMER, SPELLVALUE_MAX_TARGETS, 1, me->GetVictim(), false); - events.Repeat(16s); - break; - case EVENT_THORIM_CHARGE_ORB: - me->CastCustomSpell(SPELL_CHARGE_ORB, SPELLVALUE_MAX_TARGETS, 1, me, false); - events.Repeat(16s); - break; - case EVENT_THORIM_LIGHTNING_ORB: - { - if (GetArenaPlayer()) - { - // Player found, repeat and return - events.Repeat(5s); - return; - } - - // No players found - Talk(SAY_WIPE); - me->SummonCreature(NPC_LIGHTNING_ORB, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); - - _isArenaEmpty = true; - events.CancelEvent(EVENT_THORIM_NOT_REACH_IN_TIME); - break; - } - case EVENT_THORIM_NOT_REACH_IN_TIME: - _isArenaEmpty = true; - events.CancelEvent(EVENT_THORIM_LIGHTNING_ORB); - me->CastSpell(me, SPELL_BERSERK_FRIENDS, true); - me->SummonCreature(NPC_LIGHTNING_ORB, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); - break; - case EVENT_THORIM_ARENA_SPAWN_WARBRINGER: - SpawnAnArenaNPC(NPC_DARK_RUNE_WARBRINGER); - events.Repeat(15s); - break; - case EVENT_THORIM_ARENA_SPAWN_EVOKER: - SpawnAnArenaNPC(NPC_DARK_RUNE_EVOKER); - events.Repeat(20s); - break; - case EVENT_THORIM_ARENA_SPAWN_COMMONER: - SpawnCommoners(); - events.Repeat(21s); - break; - case EVENT_THORIM_ARENA_SPAWN_CHAMPION: - SpawnAnArenaNPC(NPC_DARK_RUNE_CHAMPION); - events.Repeat(25s); - break; - case EVENT_THORIM_UNBALANCING_STRIKE: - me->CastSpell(me->GetVictim(), SPELL_UNBALANCING_STRIKE, false); - events.Repeat(20s); - break; - case EVENT_THORIM_LIGHTNING_CHARGE: - me->CastSpell(me, SPELL_LIGHTNING_PILLAR_P2, true); - break; - case EVENT_THORIM_CHAIN_LIGHTNING: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false); - events.Repeat(15s); - break; - case EVENT_THORIM_BERSERK: - me->CastSpell(me, SPELL_BERSERK, true); - Talk(SAY_BERSERK); - break; - case EVENT_THORIM_OUTRO1: - if (_hardMode) - { - Talk(SAY_END_HARD_1); - events.ScheduleEvent(EVENT_THORIM_OUTRO2, 5s, 0, 3); - EntryCheckPredicate pred(NPC_SIF); - summons.DoAction(ACTION_SIF_TRANSFORM, pred); - } - else - { - Talk(SAY_END_NORMAL_1); - events.ScheduleEvent(EVENT_THORIM_OUTRO2, 9s, 0, 3); - } - break; - case EVENT_THORIM_OUTRO2: - if (_hardMode) - { - Talk(SAY_END_HARD_2); - events.ScheduleEvent(EVENT_THORIM_OUTRO3, 12s, 0, 3); - } - else - { - Talk(SAY_END_NORMAL_2); - events.ScheduleEvent(EVENT_THORIM_OUTRO3, 10s, 0, 3); - } - break; - case EVENT_THORIM_OUTRO3: - if (_hardMode) - { - Talk(SAY_END_HARD_3); - } - else - { - Talk(SAY_END_NORMAL_3); - } - // Defeat credit - if (m_pInstance) - m_pInstance->SetData(TYPE_THORIM, DONE); - events.ScheduleEvent(EVENT_THORIM_OUTRO4, 14s, 0, 3); - break; - case EVENT_THORIM_OUTRO4: - DoCastSelf(SPELL_TELEPORT); - break; - } - + damage = 0; if (!_encounterFinished) - DoMeleeAttackIfReady(); + { + _encounterFinished = true; + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetFaction(FACTION_FRIENDLY); + me->SetHealth(me->GetMaxHealth()); + me->CombatStop(); + me->RemoveAllAuras(); + events.Reset(); + DisableThorim(true); + + Talk(SAY_DEATH); + + events.SetPhase(EVENT_PHASE_OUTRO); + events.ScheduleEvent(EVENT_THORIM_OUTRO1, 2s, 0, EVENT_PHASE_OUTRO); + + GameObject* go = nullptr; + if ((go = GetThorimObject(DATA_THORIM_FENCE))) + go->SetGoState(GO_STATE_ACTIVE); + + uint32 chestId = me->GetMap()->Is25ManRaid() ? GO_THORIM_CHEST_HERO : GO_THORIM_CHEST; + if (_hardMode) + chestId += 1; // hard mode offset + + if ((go = me->SummonGameObject(chestId, 2134.73f, -286.32f, 419.51f, 4.65f, 0, 0, 0, 0, 0))) + { + go->ReplaceAllGameObjectFlags((GameObjectFlags)0); + go->SetLootRecipient(me->GetMap()); + } + + // Defeat credit + me->CastSpell(me, 64985, true); // credit + instance->SetBossState(BOSS_THORIM, DONE); + } } - }; + } + + void SpawnAnArenaNPC(uint32 arenaNpc) + { + Creature* cr; + uint8 rnd = urand(0,13); + if ((cr = me->SummonCreature(arenaNpc, ArenaNPCs[rnd], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000))) + cr->GetMotionMaster()->MoveJump( + Middle.GetPositionX() + urand(19, 24) * cos(Middle.GetAngle(cr)), + Middle.GetPositionY() + urand(19, 24) * std::sin(Middle.GetAngle(cr)), + Middle.GetPositionZ(), 20, 20); + } + + void SpawnCommoners() + { + uint8 rnd = urand(6,7); + for (uint8 i = 0; i < rnd; ++i) + SpawnAnArenaNPC(NPC_DARK_RUNE_COMMONER); + } + + void SpellHit(Unit* caster, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_LIGHTNING_ORB_CHARGER) + { + me->SetOrientation(me->GetAngle(caster)); + me->CastSpell(caster, SPELL_LIGHTNING_CHARGE_DAMAGE, true); + me->CastSpell(me, SPELL_LIGHTNING_CHARGE_BUFF, true); + events.RescheduleEvent(EVENT_THORIM_LIGHTNING_CHARGE, 10s, 0, EVENT_PHASE_RING); + } + else if (spellInfo->Id == SPELL_TELEPORT) + { + me->DespawnOrUnsummon(); + instance->SetData(EVENT_KEEPER_TELEPORTED, DONE); + } + } + + void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_LIGHTNING_CHARGE_DAMAGE && target->IsPlayer()) + _hitByLightning = true; + } + + Player* GetArenaPlayer() + { + Map::PlayerList const& pList = me->GetMap()->GetPlayers(); + for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) + if (Player* p = itr->GetSource()) + if (p->GetPositionX() > 2085 && p->GetPositionX() < 2185 && p->GetPositionY() < -214 && p->GetPositionY() > -305 && p->IsAlive() && p->GetPositionZ() < 425) + return p; + return nullptr; + } + + void UpdateAI(uint32 diff) override + { + if (!_encounterFinished && !UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_THORIM_AGGRO: + Talk(SAY_AGGRO_1); + events.ScheduleEvent(EVENT_THORIM_AGGRO2, 9s); + + if (GameObject* go = GetThorimObject(DATA_THORIM_FENCE)) + go->SetGoState(GO_STATE_READY); + + break; + case EVENT_THORIM_AGGRO2: + { + Talk(SAY_AGGRO_2); + + EntryCheckPredicate pred(NPC_SIF); + summons.DoAction(ACTION_SIF_START_TALK, pred); + break; + } + case EVENT_THORIM_START_PHASE1: + { + events.ScheduleEvent(EVENT_THORIM_STORMHAMMER, 8s, 0, EVENT_PHASE_START); + events.ScheduleEvent(EVENT_THORIM_CHARGE_ORB, 14s, 0, EVENT_PHASE_START); + events.ScheduleEvent(EVENT_THORIM_ARENA_SPAWN_WARBRINGER, 0ms, 0, EVENT_PHASE_START); + events.ScheduleEvent(EVENT_THORIM_ARENA_SPAWN_EVOKER, 5s, 0, EVENT_PHASE_START); + events.ScheduleEvent(EVENT_THORIM_ARENA_SPAWN_COMMONER, 7s, 0, EVENT_PHASE_START); + events.ScheduleEvent(EVENT_THORIM_ARENA_SPAWN_CHAMPION, 10s, 0, EVENT_PHASE_START); + events.ScheduleEvent(EVENT_THORIM_LIGHTNING_ORB, 5s, 0, EVENT_PHASE_START); // checked every 5 secs if there are players on arena + events.ScheduleEvent(EVENT_THORIM_NOT_REACH_IN_TIME, 5min, 0, EVENT_PHASE_START); + EntryCheckPredicate pred(NPC_SIF); + summons.DoAction(ACTION_SIF_START_DOMINION, pred); + break; + } + case EVENT_THORIM_STORMHAMMER: + me->CastCustomSpell(SPELL_STORMHAMMER, SPELLVALUE_MAX_TARGETS, 1, me->GetVictim(), false); + events.Repeat(16s); + break; + case EVENT_THORIM_CHARGE_ORB: + me->CastCustomSpell(SPELL_CHARGE_ORB, SPELLVALUE_MAX_TARGETS, 1, me, false); + events.Repeat(16s); + break; + case EVENT_THORIM_LIGHTNING_ORB: + { + if (GetArenaPlayer()) + { + // Player found, repeat and return + events.Repeat(5s); + return; + } + + // No players found + Talk(SAY_WIPE); + me->SummonCreature(NPC_LIGHTNING_ORB, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + + _isArenaEmpty = true; + events.CancelEvent(EVENT_THORIM_NOT_REACH_IN_TIME); + break; + } + case EVENT_THORIM_NOT_REACH_IN_TIME: + _isArenaEmpty = true; + events.CancelEvent(EVENT_THORIM_LIGHTNING_ORB); + me->CastSpell(me, SPELL_BERSERK_FRIENDS, true); + me->SummonCreature(NPC_LIGHTNING_ORB, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + break; + case EVENT_THORIM_ARENA_SPAWN_WARBRINGER: + SpawnAnArenaNPC(NPC_DARK_RUNE_WARBRINGER); + events.Repeat(15s); + break; + case EVENT_THORIM_ARENA_SPAWN_EVOKER: + SpawnAnArenaNPC(NPC_DARK_RUNE_EVOKER); + events.Repeat(20s); + break; + case EVENT_THORIM_ARENA_SPAWN_COMMONER: + SpawnCommoners(); + events.Repeat(21s); + break; + case EVENT_THORIM_ARENA_SPAWN_CHAMPION: + SpawnAnArenaNPC(NPC_DARK_RUNE_CHAMPION); + events.Repeat(25s); + break; + case EVENT_THORIM_UNBALANCING_STRIKE: + me->CastSpell(me->GetVictim(), SPELL_UNBALANCING_STRIKE, false); + events.Repeat(20s); + break; + case EVENT_THORIM_LIGHTNING_CHARGE: + me->CastSpell(me, SPELL_LIGHTNING_PILLAR_P2, true); + break; + case EVENT_THORIM_CHAIN_LIGHTNING: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false); + events.Repeat(15s); + break; + case EVENT_THORIM_BERSERK: + me->CastSpell(me, SPELL_BERSERK, true); + Talk(SAY_BERSERK); + break; + case EVENT_THORIM_OUTRO1: + if (_hardMode) + { + Talk(SAY_END_HARD_1); + events.ScheduleEvent(EVENT_THORIM_OUTRO2, 5s, 0, 3); + EntryCheckPredicate pred(NPC_SIF); + summons.DoAction(ACTION_SIF_TRANSFORM, pred); + } + else + { + Talk(SAY_END_NORMAL_1); + events.ScheduleEvent(EVENT_THORIM_OUTRO2, 9s, 0, 3); + } + break; + case EVENT_THORIM_OUTRO2: + if (_hardMode) + { + Talk(SAY_END_HARD_2); + events.ScheduleEvent(EVENT_THORIM_OUTRO3, 12s, 0, 3); + } + else + { + Talk(SAY_END_NORMAL_2); + events.ScheduleEvent(EVENT_THORIM_OUTRO3, 10s, 0, 3); + } + break; + case EVENT_THORIM_OUTRO3: + if (_hardMode) + { + Talk(SAY_END_HARD_3); + } + else + { + Talk(SAY_END_NORMAL_3); + } + // Defeat credit + instance->SetBossState(BOSS_THORIM, DONE); + events.ScheduleEvent(EVENT_THORIM_OUTRO4, 14s, 0, 3); + break; + case EVENT_THORIM_OUTRO4: + DoCastSelf(SPELL_TELEPORT); + break; + } + + if (!_encounterFinished) + DoMeleeAttackIfReady(); + } }; -class boss_thorim_sif : public CreatureScript +struct boss_thorim_sif : public ScriptedAI { -public: - boss_thorim_sif() : CreatureScript("boss_thorim_sif") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_thorim_sifAI : public ScriptedAI - { - boss_thorim_sifAI(Creature* pCreature) : ScriptedAI(pCreature) { } + boss_thorim_sif(Creature* creature) : ScriptedAI(creature) { } void MoveInLineOfSight(Unit*) override {} void AttackStart(Unit*) override {} @@ -817,7 +782,7 @@ public: else if (param == ACTION_SIF_START_DOMINION) { if (me->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_THORIM))) + if (Creature* cr = me->GetInstanceScript()->GetCreature(BOSS_THORIM)) me->CastSpell(cr, SPELL_TOUCH_OF_DOMINION, false); events.ScheduleEvent(EVENT_SIF_FINISH_DOMINION, 150s); @@ -888,22 +853,11 @@ public: me->StopMoving(); } } - }; }; -class boss_thorim_lightning_orb : public CreatureScript +struct boss_thorim_lightning_orb : public npc_escortAI { -public: - boss_thorim_lightning_orb() : CreatureScript("boss_thorim_lightning_orb") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_thorim_lightning_orbAI : public npc_escortAI - { - boss_thorim_lightning_orbAI(Creature* pCreature) : npc_escortAI(pCreature) + boss_thorim_lightning_orb(Creature* creature) : npc_escortAI(creature) { InitWaypoint(); Reset(); @@ -936,22 +890,11 @@ public: void WaypointReached(uint32 /*point*/) override { } - }; }; -class boss_thorim_trap : public CreatureScript +struct boss_thorim_trap : public NullCreatureAI { -public: - boss_thorim_trap() : CreatureScript("boss_thorim_trap") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_thorim_trapAI : public NullCreatureAI - { - boss_thorim_trapAI(Creature* pCreature) : NullCreatureAI(pCreature) { } + boss_thorim_trap(Creature* creature) : NullCreatureAI(creature) { } uint32 _checkTimer; @@ -974,22 +917,11 @@ public: } } } - }; }; -class boss_thorim_sif_blizzard : public CreatureScript +struct boss_thorim_sif_blizzard : public npc_escortAI { -public: - boss_thorim_sif_blizzard() : CreatureScript("boss_thorim_sif_blizzard") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_thorim_sif_blizzardAI : public npc_escortAI - { - boss_thorim_sif_blizzardAI(Creature* pCreature) : npc_escortAI(pCreature) + boss_thorim_sif_blizzard(Creature* creature) : npc_escortAI(creature) { InitWaypoint(); Reset(); @@ -1023,22 +955,11 @@ public: void WaypointReached(uint32 /*point*/) override { } - }; }; -class boss_thorim_pillar : public CreatureScript +struct boss_thorim_pillar : public NullCreatureAI { -public: - boss_thorim_pillar() : CreatureScript("boss_thorim_pillar") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_thorim_pillarAI : public NullCreatureAI - { - boss_thorim_pillarAI(Creature* pCreature) : NullCreatureAI(pCreature) { } + boss_thorim_pillar(Creature* pCreature) : NullCreatureAI(pCreature) { } uint32 _resetTimer; @@ -1066,22 +987,11 @@ public: if (_resetTimer >= 10000) Reset(); // _resetTimer set to 0 } - }; }; -class boss_thorim_start_npcs : public CreatureScript +struct boss_thorim_start_npcs : public ScriptedAI { -public: - boss_thorim_start_npcs() : CreatureScript("boss_thorim_start_npcs") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_thorim_start_npcsAI : public ScriptedAI - { - boss_thorim_start_npcsAI(Creature* pCreature) : ScriptedAI(pCreature) { } + boss_thorim_start_npcs(Creature* pCreature) : ScriptedAI(pCreature) { } EventMap events; bool _isCaster; @@ -1102,7 +1012,7 @@ public: if (!_playerAttack && who && (who->IsPlayer() || who->GetOwnerGUID().IsPlayer())) { if (me->GetInstanceScript()) - if (Creature* thorim = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_THORIM))) + if (Creature* thorim = me->GetInstanceScript()->GetCreature(BOSS_THORIM)) { if (!thorim->IsInCombat()) { @@ -1123,7 +1033,7 @@ public: void JustDied(Unit*) override { if (me->GetInstanceScript()) - if (Creature* thorim = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_THORIM))) + if (Creature* thorim = me->GetInstanceScript()->GetCreature(BOSS_THORIM)) thorim->AI()->DoAction(ACTION_START_TRASH_DIED); } @@ -1220,22 +1130,11 @@ public: if (!_isCaster || (me->GetPower(POWER_MANA) * 100 / me->GetMaxPower(POWER_MANA) < 10)) DoMeleeAttackIfReady(); } - }; }; -class boss_thorim_gauntlet_npcs : public CreatureScript +struct boss_thorim_gauntlet_npcs : public ScriptedAI { -public: - boss_thorim_gauntlet_npcs() : CreatureScript("boss_thorim_gauntlet_npcs") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_thorim_gauntlet_npcsAI : public ScriptedAI - { - boss_thorim_gauntlet_npcsAI(Creature* pCreature) : ScriptedAI(pCreature) { } + boss_thorim_gauntlet_npcs(Creature* pCreature) : ScriptedAI(pCreature) { } EventMap events; bool _isCaster; @@ -1327,22 +1226,11 @@ public: if (!_isCaster || (me->GetPower(POWER_MANA) * 100 / me->GetMaxPower(POWER_MANA) < 10)) DoMeleeAttackIfReady(); } - }; }; -class boss_thorim_runic_colossus : public CreatureScript +struct boss_thorim_runic_colossus : public ScriptedAI { -public: - boss_thorim_runic_colossus() : CreatureScript("boss_thorim_runic_colossus") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_thorim_runic_colossusAI : public ScriptedAI - { - boss_thorim_runic_colossusAI(Creature* pCreature) : ScriptedAI(pCreature) { } + boss_thorim_runic_colossus(Creature* pCreature) : ScriptedAI(pCreature) { } EventMap events; bool _leftHand; @@ -1374,10 +1262,10 @@ public: { if (me->GetInstanceScript()) { - if (GameObject* go = ObjectAccessor::GetGameObject(*me, me->GetInstanceScript()->GetGuidData(DATA_THORIM_FIRST_DOORS))) + if (GameObject* go = me->GetInstanceScript()->GetGameObject(DATA_THORIM_FIRST_DOORS)) go->SetGoState(GO_STATE_ACTIVE); - if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_THORIM))) + if (Creature* cr = me->GetInstanceScript()->GetCreature(BOSS_THORIM)) cr->AI()->Talk(SAY_SPECIAL_2); } } @@ -1468,238 +1356,215 @@ public: DoMeleeAttackIfReady(); } - }; }; -class boss_thorim_ancient_rune_giant : public CreatureScript +struct boss_thorim_ancient_rune_giant : public ScriptedAI { -public: - boss_thorim_ancient_rune_giant() : CreatureScript("boss_thorim_ancient_rune_giant") { } + boss_thorim_ancient_rune_giant(Creature* pCreature) : ScriptedAI(pCreature) { } - CreatureAI* GetAI(Creature* pCreature) const override + EventMap events; + bool _isInCombat; + + void Reset() override { - return GetUlduarAI(pCreature); + _isInCombat = false; + events.Reset(); } - struct boss_thorim_ancient_rune_giantAI : public ScriptedAI + void JustEngagedWith(Unit*) override { - boss_thorim_ancient_rune_giantAI(Creature* pCreature) : ScriptedAI(pCreature) { } + _isInCombat = true; + events.CancelEvent(EVENT_ARG_SPAWN); + events.ScheduleEvent(EVENT_ARG_RD, 12s); + events.ScheduleEvent(EVENT_ARG_STOMP, 8s); - EventMap events; - bool _isInCombat; + me->CastSpell(me, SPELL_RUNIC_FORTIFICATION, false); + Talk(SAY_GIANT_RUNIC_MIGHT); + } - void Reset() override + void JustDied(Unit*) override + { + if (InstanceScript* pInstance = me->GetInstanceScript()) { - _isInCombat = false; - events.Reset(); + if (GameObject* go = pInstance->GetGameObject(DATA_THORIM_SECOND_DOORS)) + go->SetGoState(GO_STATE_ACTIVE); + + if (Creature* thorim = pInstance->GetCreature(BOSS_THORIM)) + thorim->AI()->DoAction(ACTION_ALLOW_HIT); + } + } + + void DoAction(int32 param) override + { + if (param == ACTION_IRON_HONOR_DIED) + events.RescheduleEvent(EVENT_ARG_SPAWN, 20s); + } + + void UpdateAI(uint32 diff) override + { + if (_isInCombat && !UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_ARG_RD: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + me->CastSpell(target, SPELL_RUNE_DETONATION, false); + events.Repeat(12s); + break; + case EVENT_ARG_STOMP: + me->CastSpell(me->GetVictim(), SPELL_STOMP, false); + events.Repeat(8s); + break; + case EVENT_ARG_SPAWN: + if (Creature* cr = me->SummonCreature(NPC_IRON_HONOR_GUARD, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000)) + if (Unit* target = SelectTargetFromPlayerList(150.0f)) + cr->AI()->AttackStart(target); + events.Repeat(10s); + break; } - void JustEngagedWith(Unit*) override - { - _isInCombat = true; - events.CancelEvent(EVENT_ARG_SPAWN); - events.ScheduleEvent(EVENT_ARG_RD, 12s); - events.ScheduleEvent(EVENT_ARG_STOMP, 8s); - - me->CastSpell(me, SPELL_RUNIC_FORTIFICATION, false); - Talk(SAY_GIANT_RUNIC_MIGHT); - } - - void JustDied(Unit*) override - { - if (InstanceScript* pInstance = me->GetInstanceScript()) - { - if (GameObject* go = ObjectAccessor::GetGameObject(*me, pInstance->GetGuidData(DATA_THORIM_SECOND_DOORS))) - go->SetGoState(GO_STATE_ACTIVE); - - if (Creature* thorim = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_THORIM))) - thorim->AI()->DoAction(ACTION_ALLOW_HIT); - } - } - - void DoAction(int32 param) override - { - if (param == ACTION_IRON_HONOR_DIED) - events.RescheduleEvent(EVENT_ARG_SPAWN, 20s); - } - - void UpdateAI(uint32 diff) override - { - if (_isInCombat && !UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_ARG_RD: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - me->CastSpell(target, SPELL_RUNE_DETONATION, false); - events.Repeat(12s); - break; - case EVENT_ARG_STOMP: - me->CastSpell(me->GetVictim(), SPELL_STOMP, false); - events.Repeat(8s); - break; - case EVENT_ARG_SPAWN: - if (Creature* cr = me->SummonCreature(NPC_IRON_HONOR_GUARD, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000)) - if (Unit* target = SelectTargetFromPlayerList(150.0f)) - cr->AI()->AttackStart(target); - events.Repeat(10s); - break; - } - - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; -class boss_thorim_arena_npcs : public CreatureScript +struct boss_thorim_arena_npcs : public ScriptedAI { -public: - boss_thorim_arena_npcs() : CreatureScript("boss_thorim_arena_npcs") { } + boss_thorim_arena_npcs(Creature* pCreature) : ScriptedAI(pCreature) { } - CreatureAI* GetAI(Creature* pCreature) const override + EventMap events; + bool _isCaster; + + void Reset() override { - return GetUlduarAI(pCreature); + _isCaster = (me->GetEntry() == NPC_DARK_RUNE_EVOKER); + events.Reset(); + if (me->GetEntry() == NPC_DARK_RUNE_WARBRINGER) + me->CastSpell(me, SPELL_AURA_OF_CELERITY, true); } - struct boss_thorim_arena_npcsAI : public ScriptedAI + void JustEngagedWith(Unit*) override { - boss_thorim_arena_npcsAI(Creature* pCreature) : ScriptedAI(pCreature) { } - - EventMap events; - bool _isCaster; - - void Reset() override + if (me->GetEntry() == NPC_DARK_RUNE_WARBRINGER) { - _isCaster = (me->GetEntry() == NPC_DARK_RUNE_EVOKER); - events.Reset(); - if (me->GetEntry() == NPC_DARK_RUNE_WARBRINGER) - me->CastSpell(me, SPELL_AURA_OF_CELERITY, true); + events.ScheduleEvent(EVENT_DR_WARBRINGER_RS, 8s); + } + else if (me->GetEntry() == NPC_DARK_RUNE_EVOKER) + { + events.ScheduleEvent(EVENT_DR_EVOKER_RL, 2500ms); + events.ScheduleEvent(EVENT_DR_EVOKER_RM, 4s); + events.ScheduleEvent(EVENT_DR_EVOKER_RS, 10s); + } + else if (me->GetEntry() == NPC_DARK_RUNE_CHAMPION) + { + events.ScheduleEvent(EVENT_DR_CHAMPION_WH, 6s); + events.ScheduleEvent(EVENT_DR_CHAMPION_CH, 12s); + events.ScheduleEvent(EVENT_DR_CHAMPION_MS, 8s); + } + else if (me->GetEntry() == NPC_DARK_RUNE_COMMONER) + { + events.ScheduleEvent(EVENT_DR_COMMONER_LB, 5s); + events.ScheduleEvent(EVENT_DR_COMMONER_PM, 6s); + } + } + + bool CanAIAttack(Unit const* target) const override + { + return target->GetPositionX() < 2180 && target->GetPositionZ() < 425; + } + + bool SelectT() + { + Player* target = nullptr; + Map::PlayerList const& pList = me->GetMap()->GetPlayers(); + uint8 num = urand(0, pList.getSize() - 1); + uint8 count = 0; + for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr, ++count) + { + if (itr->GetSource()->GetPositionX() > 2180 || !itr->GetSource()->IsAlive() || itr->GetSource()->GetPositionZ() > 425) + continue; + + if (count <= num || !target) + target = itr->GetSource(); + else + break; } - void JustEngagedWith(Unit*) override + if (target) { - if (me->GetEntry() == NPC_DARK_RUNE_WARBRINGER) - { - events.ScheduleEvent(EVENT_DR_WARBRINGER_RS, 8s); - } - else if (me->GetEntry() == NPC_DARK_RUNE_EVOKER) - { - events.ScheduleEvent(EVENT_DR_EVOKER_RL, 2500ms); - events.ScheduleEvent(EVENT_DR_EVOKER_RM, 4s); - events.ScheduleEvent(EVENT_DR_EVOKER_RS, 10s); - } - else if (me->GetEntry() == NPC_DARK_RUNE_CHAMPION) - { - events.ScheduleEvent(EVENT_DR_CHAMPION_WH, 6s); - events.ScheduleEvent(EVENT_DR_CHAMPION_CH, 12s); - events.ScheduleEvent(EVENT_DR_CHAMPION_MS, 8s); - } - else if (me->GetEntry() == NPC_DARK_RUNE_COMMONER) - { - events.ScheduleEvent(EVENT_DR_COMMONER_LB, 5s); - events.ScheduleEvent(EVENT_DR_COMMONER_PM, 6s); - } + AttackStart(target); + me->AddThreat(target, 500.0f); + if (me->GetEntry() == NPC_DARK_RUNE_EVOKER && urand(0, 1)) + me->CastSpell(me, SPELL_RUNIC_SHIELD, false); + else if (me->GetEntry() == NPC_DARK_RUNE_CHAMPION && !urand(0, 2)) + me->CastSpell(target, SPELL_CHARGE, false); + return true; } + return false; + } - bool CanAIAttack(Unit const* target) const override + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !SelectT()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - return target->GetPositionX() < 2180 && target->GetPositionZ() < 425; - } - - bool SelectT() - { - Player* target = nullptr; - Map::PlayerList const& pList = me->GetMap()->GetPlayers(); - uint8 num = urand(0, pList.getSize() - 1); - uint8 count = 0; - for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr, ++count) - { - if (itr->GetSource()->GetPositionX() > 2180 || !itr->GetSource()->IsAlive() || itr->GetSource()->GetPositionZ() > 425) - continue; - - if (count <= num || !target) - target = itr->GetSource(); + case EVENT_DR_WARBRINGER_RS: + me->CastSpell(me->GetVictim(), SPELL_RUNIC_STRIKE, false); + events.Repeat(8s); + break; + case EVENT_DR_EVOKER_RL: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + me->CastSpell(target, SPELL_RUNIC_LIGHTNING, false); + events.Repeat(2500ms); + break; + case EVENT_DR_EVOKER_RM: + if (Unit* target = DoSelectLowestHpFriendly(40.0f, 15)) + me->CastSpell(target, SPELL_RUNIC_MENDING, false); else - break; - } - - if (target) - { - AttackStart(target); - me->AddThreat(target, 500.0f); - if (me->GetEntry() == NPC_DARK_RUNE_EVOKER && urand(0, 1)) - me->CastSpell(me, SPELL_RUNIC_SHIELD, false); - else if (me->GetEntry() == NPC_DARK_RUNE_CHAMPION && !urand(0, 2)) + me->CastSpell(me, SPELL_RUNIC_MENDING, false); + events.Repeat(4s); + break; + case EVENT_DR_EVOKER_RS: + me->CastSpell(me, SPELL_RUNIC_SHIELD, false); + events.Repeat(10s); + break; + case EVENT_DR_CHAMPION_CH: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) me->CastSpell(target, SPELL_CHARGE, false); - return true; - } - return false; + events.Repeat(12s); + break; + case EVENT_DR_CHAMPION_WH: + if (!me->HasUnitFlag(UNIT_FLAG_DISARMED)) + me->CastSpell(me, SPELL_WHIRLWIND, false); + events.Repeat(6s); + break; + case EVENT_DR_CHAMPION_MS: + me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false); + events.Repeat(8s); + break; + case EVENT_DR_COMMONER_LB: + me->CastSpell(me->GetVictim(), SPELL_LOW_BLOW, false); + events.Repeat(5s); + break; + case EVENT_DR_COMMONER_PM: + me->CastSpell(me->GetVictim(), SPELL_PUMMEL, false); + events.Repeat(6s); + break; } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() && !SelectT()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_DR_WARBRINGER_RS: - me->CastSpell(me->GetVictim(), SPELL_RUNIC_STRIKE, false); - events.Repeat(8s); - break; - case EVENT_DR_EVOKER_RL: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - me->CastSpell(target, SPELL_RUNIC_LIGHTNING, false); - events.Repeat(2500ms); - break; - case EVENT_DR_EVOKER_RM: - if (Unit* target = DoSelectLowestHpFriendly(40.0f, 15)) - me->CastSpell(target, SPELL_RUNIC_MENDING, false); - else - me->CastSpell(me, SPELL_RUNIC_MENDING, false); - events.Repeat(4s); - break; - case EVENT_DR_EVOKER_RS: - me->CastSpell(me, SPELL_RUNIC_SHIELD, false); - events.Repeat(10s); - break; - case EVENT_DR_CHAMPION_CH: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - me->CastSpell(target, SPELL_CHARGE, false); - events.Repeat(12s); - break; - case EVENT_DR_CHAMPION_WH: - if (!me->HasUnitFlag(UNIT_FLAG_DISARMED)) - me->CastSpell(me, SPELL_WHIRLWIND, false); - events.Repeat(6s); - break; - case EVENT_DR_CHAMPION_MS: - me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false); - events.Repeat(8s); - break; - case EVENT_DR_COMMONER_LB: - me->CastSpell(me->GetVictim(), SPELL_LOW_BLOW, false); - events.Repeat(5s); - break; - case EVENT_DR_COMMONER_PM: - me->CastSpell(me->GetVictim(), SPELL_PUMMEL, false); - events.Repeat(6s); - break; - } - - if (!_isCaster || (me->GetPower(POWER_MANA) * 100 / me->GetMaxPower(POWER_MANA) < 10)) - DoMeleeAttackIfReady(); - } - }; + if (!_isCaster || (me->GetPower(POWER_MANA) * 100 / me->GetMaxPower(POWER_MANA) < 10)) + DoMeleeAttackIfReady(); + } }; class go_thorim_lever : public GameObjectScript @@ -1759,7 +1624,7 @@ public: bool OnCheck(Player* player, Unit*, uint32 /*criteria_id*/) override { if (InstanceScript* instance = player->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*player, instance->GetGuidData(TYPE_THORIM))) + if (Creature* cr = instance->GetCreature(BOSS_THORIM)) return cr->AI()->GetData(DATA_HIT_BY_LIGHTNING); return false; @@ -1774,7 +1639,7 @@ public: bool OnCheck(Player* player, Unit*, uint32 /*criteria_id*/) override { if (InstanceScript* instance = player->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*player, instance->GetGuidData(TYPE_THORIM))) + if (Creature* cr = instance->GetCreature(BOSS_THORIM)) return cr->AI()->GetData(DATA_LOSE_YOUR_ILLUSION); return false; @@ -1784,21 +1649,21 @@ public: void AddSC_boss_thorim() { // Main encounter - new boss_thorim(); - new boss_thorim_sif(); - new boss_thorim_lightning_orb(); - new boss_thorim_trap(); - new boss_thorim_pillar(); - new boss_thorim_sif_blizzard(); + RegisterUlduarCreatureAI(boss_thorim); + RegisterUlduarCreatureAI(boss_thorim_sif); + RegisterUlduarCreatureAI(boss_thorim_lightning_orb); + RegisterUlduarCreatureAI(boss_thorim_trap); + RegisterUlduarCreatureAI(boss_thorim_pillar); + RegisterUlduarCreatureAI(boss_thorim_sif_blizzard); // Trash - new boss_thorim_start_npcs(); - new boss_thorim_gauntlet_npcs(); - new boss_thorim_arena_npcs(); + RegisterUlduarCreatureAI(boss_thorim_start_npcs); + RegisterUlduarCreatureAI(boss_thorim_gauntlet_npcs); + RegisterUlduarCreatureAI(boss_thorim_arena_npcs); // Mini bosses - new boss_thorim_runic_colossus(); - new boss_thorim_ancient_rune_giant(); + RegisterUlduarCreatureAI(boss_thorim_runic_colossus); + RegisterUlduarCreatureAI(boss_thorim_ancient_rune_giant); // GOs new go_thorim_lever(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp index c4ce68597..8bb4fded8 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp @@ -112,574 +112,520 @@ enum Misc DATA_XT002_GRAVITY_ACHIEV = 51, }; -class boss_xt002 : public CreatureScript +struct boss_xt002 : public BossAI { -public: - boss_xt002() : CreatureScript("boss_xt002") { } + boss_xt002(Creature* pCreature) : BossAI(pCreature, BOSS_XT002) { } - CreatureAI* GetAI(Creature* pCreature) const override + uint8 _healthCheck; + bool _hardMode; + bool _nerfAchievement; + bool _gravityAchievement; + + void RescheduleEvents() { - return GetUlduarAI(pCreature); + events.RescheduleEvent(EVENT_GRAVITY_BOMB, 1s, 1); + events.RescheduleEvent(EVENT_TYMPANIC_TANTARUM, 1min, 1); + if (!_hardMode) + events.RescheduleEvent(EVENT_HEALTH_CHECK, 2s, 1); } - struct boss_xt002AI : public ScriptedAI + void Reset() override { - boss_xt002AI(Creature* pCreature) : ScriptedAI(pCreature), summons(me) + _Reset(); + + me->ResetLootMode(); + me->RemoveAllAuras(); + + // first heart expose + _healthCheck = 75; + _hardMode = false; + _nerfAchievement = true; + _gravityAchievement = true; + + me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); // emerge + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetControlled(false, UNIT_STATE_STUNNED); + + if (instance) { - m_pInstance = pCreature->GetInstanceScript(); + instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_MUST_DECONSTRUCT_FASTER); + if (GameObject* pGo = instance->GetGameObject(DATA_XT002_DOORS)) + pGo->SetGoState(GO_STATE_ACTIVE); + } + } + + void AttachHeart() + { + if (Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : nullptr) + heart->SetHealth(heart->GetMaxHealth()); + else if (Creature* accessory = me->SummonCreature(NPC_XT002_HEART, *me, TEMPSUMMON_MANUAL_DESPAWN)) + { + accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY); + if (!me->HandleSpellClick(accessory, 0)) + accessory->DespawnOrUnsummon(); + } + } + + void JustReachedHome() override + { + _JustReachedHome(); + me->setActive(false); + } + + void JustEngagedWith(Unit*) override + { + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + events.ScheduleEvent(EVENT_ENRAGE, 10min, 0, 0); + events.ScheduleEvent(EVENT_CHECK_ROOM, 5s, 0, 0); + RescheduleEvents(); // Other events are scheduled here + + me->setActive(true); + Talk(SAY_AGGRO); + + if (instance) + { + instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_MUST_DECONSTRUCT_FASTER); + instance->SetBossState(BOSS_XT002, IN_PROGRESS); + if (GameObject* pGo = instance->GetGameObject(DATA_XT002_DOORS)) + pGo->SetGoState(GO_STATE_READY); } - InstanceScript* m_pInstance; - uint8 _healthCheck; - bool _hardMode; - bool _nerfAchievement; - bool _gravityAchievement; - EventMap events; - SummonList summons; + me->CallForHelp(175); + me->SetInCombatWithZone(); + AttachHeart(); + } - void RescheduleEvents() + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer() && !urand(0, 2)) { - events.RescheduleEvent(EVENT_GRAVITY_BOMB, 1s, 1); - events.RescheduleEvent(EVENT_TYMPANIC_TANTARUM, 1min, 1); - if (!_hardMode) - events.RescheduleEvent(EVENT_HEALTH_CHECK, 2s, 1); + Talk(SAY_SLAY); + } + } + + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); + _JustDied(); + + if (instance) + { + if (GameObject* pGo = instance->GetGameObject(DATA_XT002_DOORS)) + pGo->SetGoState(GO_STATE_ACTIVE); + } + } + + void DoAction(int32 param) override + { + if (param == DATA_XT002_NERF_ENGINEERING) + { + _nerfAchievement = false; + return; + } + if (param == DATA_XT002_GRAVITY_ACHIEV) + { + _gravityAchievement = false; + return; } - void Reset() override + if (!me->IsAlive() || _hardMode) + return; + + // heart destory + if (param == ACTION_HEART_BROKEN) { - summons.DespawnAll(); - events.Reset(); - - me->ResetLootMode(); - me->RemoveAllAuras(); - - // first heart expose - _healthCheck = 75; - _hardMode = false; - _nerfAchievement = true; - _gravityAchievement = true; - + _hardMode = true; + me->SetLootMode(3); // hard mode + normal loot + me->SetMaxHealth(me->GetMaxHealth()); + me->SetHealth(me->GetMaxHealth()); me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); // emerge - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - me->SetControlled(false, UNIT_STATE_STUNNED); - if (m_pInstance) - { - m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_MUST_DECONSTRUCT_FASTER); - m_pInstance->SetData(TYPE_XT002, NOT_STARTED); - if (GameObject* pGo = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(GO_XT002_DOORS))) - pGo->SetGoState(GO_STATE_ACTIVE); - } + me->CastSpell(me, SPELL_HEARTBREAK, true); + + Talk(EMOTE_HEART_CLOSED); + events.ScheduleEvent(EVENT_REMOVE_EMOTE, 4s); + return; } - void JustSummoned(Creature* cr) override { summons.Summon(cr); } - void SummonedCreatureDespawn(Creature* cr) override { summons.Despawn(cr); } - - void AttachHeart() + // damage from heart + if (param > 0) { - if (Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : nullptr) - heart->SetHealth(heart->GetMaxHealth()); - else if (Creature* accessory = me->SummonCreature(NPC_XT002_HEART, *me, TEMPSUMMON_MANUAL_DESPAWN)) - { - accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY); - if (!me->HandleSpellClick(accessory, 0)) - accessory->DespawnOrUnsummon(); - } + // avoid reducing health under 1 + int32 _final = std::min(param, int32(me->GetHealth() - 1)); + + me->ModifyHealth(-_final); + me->LowerPlayerDamageReq(_final); } + } - void JustReachedHome() override { me->setActive(false); } + uint32 GetData(uint32 param) const override + { + if (param == DATA_XT002_NERF_ENGINEERING) + return _nerfAchievement; + else if (param == DATA_XT002_GRAVITY_ACHIEV) + return _gravityAchievement; - void JustEngagedWith(Unit*) override + return 0; + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - events.ScheduleEvent(EVENT_ENRAGE, 10min, 0, 0); - events.ScheduleEvent(EVENT_CHECK_ROOM, 5s, 0, 0); - RescheduleEvents(); // Other events are scheduled here + // Control events + case EVENT_HEALTH_CHECK: + if (_hardMode) + { + return; + } - me->setActive(true); - Talk(SAY_AGGRO); + if (me->HealthBelowPct(_healthCheck)) + { + _healthCheck -= 25; + me->SetControlled(true, UNIT_STATE_STUNNED); + me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_SUBMERGED); // submerge with animation - if (m_pInstance) - { - m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_MUST_DECONSTRUCT_FASTER); - m_pInstance->SetData(TYPE_XT002, IN_PROGRESS); - if (GameObject* pGo = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(GO_XT002_DOORS))) - pGo->SetGoState(GO_STATE_READY); - } + Talk(SAY_HEART_OPENED); - me->CallForHelp(175); - me->SetInCombatWithZone(); - AttachHeart(); - } + events.CancelEventGroup(1); + events.ScheduleEvent(EVENT_START_SECOND_PHASE, 5s); + return; + } + events.Repeat(1s); + break; + case EVENT_CHECK_ROOM: + events.Repeat(5s); + if (me->GetPositionX() < 722 || me->GetPositionX() > 987 || me->GetPositionY() < -139 || me->GetPositionY() > 124) + EnterEvadeMode(); - void KilledUnit(Unit* victim) override - { - if (victim->IsPlayer() && !urand(0, 2)) - { - Talk(SAY_SLAY); - } - } - - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); - - if (m_pInstance) - { - m_pInstance->SetData(TYPE_XT002, DONE); - if (GameObject* pGo = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(GO_XT002_DOORS))) - pGo->SetGoState(GO_STATE_ACTIVE); - } - - // Despawn summons - summons.DespawnAll(); - } - - void DoAction(int32 param) override - { - if (param == DATA_XT002_NERF_ENGINEERING) - { - _nerfAchievement = false; - return; - } - if (param == DATA_XT002_GRAVITY_ACHIEV) - { - _gravityAchievement = false; - return; - } - - if (!me->IsAlive() || _hardMode) return; - // heart destory - if (param == ACTION_HEART_BROKEN) - { - _hardMode = true; - me->SetLootMode(3); // hard mode + normal loot - me->SetMaxHealth(me->GetMaxHealth()); - me->SetHealth(me->GetMaxHealth()); + // Abilities events + case EVENT_GRAVITY_BOMB: + me->CastCustomSpell(SPELL_GRAVITY_BOMB, SPELLVALUE_MAX_TARGETS, 1, me, true); + events.ScheduleEvent(EVENT_SEARING_LIGHT, 10s, 1); + break; + case EVENT_SEARING_LIGHT: + me->CastCustomSpell(SPELL_SEARING_LIGHT, SPELLVALUE_MAX_TARGETS, 1, me, true); + events.ScheduleEvent(EVENT_GRAVITY_BOMB, 10s, 1); + break; + case EVENT_TYMPANIC_TANTARUM: + Talk(EMOTE_TYMPANIC_TANTRUM); + Talk(SAY_TYMPANIC_TANTRUM); + me->CastSpell(me, SPELL_TYMPANIC_TANTARUM, true); + events.Repeat(1min); + return; + case EVENT_ENRAGE: + Talk(SAY_BERSERK); + me->CastSpell(me, SPELL_XT002_ENRAGE, true); + break; + + // Animation events + case EVENT_START_SECOND_PHASE: + Talk(EMOTE_HEART_OPENED); + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + if (Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : nullptr) + heart->GetAI()->DoAction(ACTION_AWAKEN_HEART); + + events.ScheduleEvent(EVENT_RESTORE, 30s); + return; + // Restore from heartbreak + case EVENT_RESTORE: + if (_hardMode) + { + return; + } + + Talk(SAY_HEART_CLOSED); + me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); // emerge + // Hide heart + if (Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : nullptr) + heart->GetAI()->DoAction(ACTION_HIDE_HEART); - me->CastSpell(me, SPELL_HEARTBREAK, true); - - Talk(EMOTE_HEART_CLOSED); events.ScheduleEvent(EVENT_REMOVE_EMOTE, 4s); return; - } + case EVENT_REMOVE_EMOTE: + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetControlled(false, UNIT_STATE_STUNNED); - // damage from heart - if (param > 0) - { - // avoid reducing health under 1 - int32 _final = std::min(param, int32(me->GetHealth() - 1)); - - me->ModifyHealth(-_final); - me->LowerPlayerDamageReq(_final); - } - } - - uint32 GetData(uint32 param) const override - { - if (param == DATA_XT002_NERF_ENGINEERING) - return _nerfAchievement; - else if (param == DATA_XT002_GRAVITY_ACHIEV) - return _gravityAchievement; - - return 0; - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) + RescheduleEvents(); return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - // Control events - case EVENT_HEALTH_CHECK: - if (_hardMode) - { - return; - } - - if (me->HealthBelowPct(_healthCheck)) - { - _healthCheck -= 25; - me->SetControlled(true, UNIT_STATE_STUNNED); - me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_SUBMERGED); // submerge with animation - - Talk(SAY_HEART_OPENED); - - events.CancelEventGroup(1); - events.ScheduleEvent(EVENT_START_SECOND_PHASE, 5s); - return; - } - events.Repeat(1s); - break; - case EVENT_CHECK_ROOM: - events.Repeat(5s); - if (me->GetPositionX() < 722 || me->GetPositionX() > 987 || me->GetPositionY() < -139 || me->GetPositionY() > 124) - EnterEvadeMode(); - - return; - - // Abilities events - case EVENT_GRAVITY_BOMB: - me->CastCustomSpell(SPELL_GRAVITY_BOMB, SPELLVALUE_MAX_TARGETS, 1, me, true); - events.ScheduleEvent(EVENT_SEARING_LIGHT, 10s, 1); - break; - case EVENT_SEARING_LIGHT: - me->CastCustomSpell(SPELL_SEARING_LIGHT, SPELLVALUE_MAX_TARGETS, 1, me, true); - events.ScheduleEvent(EVENT_GRAVITY_BOMB, 10s, 1); - break; - case EVENT_TYMPANIC_TANTARUM: - Talk(EMOTE_TYMPANIC_TANTRUM); - Talk(SAY_TYMPANIC_TANTRUM); - me->CastSpell(me, SPELL_TYMPANIC_TANTARUM, true); - events.Repeat(1min); - return; - case EVENT_ENRAGE: - Talk(SAY_BERSERK); - me->CastSpell(me, SPELL_XT002_ENRAGE, true); - break; - - // Animation events - case EVENT_START_SECOND_PHASE: - Talk(EMOTE_HEART_OPENED); - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - if (Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : nullptr) - heart->GetAI()->DoAction(ACTION_AWAKEN_HEART); - - events.ScheduleEvent(EVENT_RESTORE, 30s); - return; - // Restore from heartbreak - case EVENT_RESTORE: - if (_hardMode) - { - return; - } - - Talk(SAY_HEART_CLOSED); - - me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); // emerge - // Hide heart - if (Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : nullptr) - heart->GetAI()->DoAction(ACTION_HIDE_HEART); - - events.ScheduleEvent(EVENT_REMOVE_EMOTE, 4s); - return; - case EVENT_REMOVE_EMOTE: - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - me->SetControlled(false, UNIT_STATE_STUNNED); - - RescheduleEvents(); - return; - } - - // Disabled by stunned state - DoMeleeAttackIfReady(); } - }; + + // Disabled by stunned state + DoMeleeAttackIfReady(); + } }; -class npc_xt002_heart : public CreatureScript +struct npc_xt002_heart : public PassiveAI { -public: - npc_xt002_heart() : CreatureScript("npc_xt002_heart") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_xt002_heart(Creature* pCreature) : PassiveAI(pCreature), summons(me) { - return GetUlduarAI(pCreature); + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); } - struct npc_xt002_heartAI : public PassiveAI + SummonList summons; + uint32 _damageDone; + uint32 _timerSpawn; + + uint8 _spawnSelection; + uint8 _pummelerCount; + + void MoveInLineOfSight(Unit*) override { } + void AttackStart(Unit*) override { } + void JustSummoned(Creature* cr) override { - npc_xt002_heartAI(Creature* pCreature) : PassiveAI(pCreature), summons(me) + summons.Summon(cr); + if (Unit* owner = me->GetVehicleBase()) + if (owner->IsCreature()) + owner->ToCreature()->AI()->JustSummoned(cr); + } + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + _damageDone += damage; + } + + void SummonPiles() + { + me->SummonCreature(NPC_PILE_TRIGGER, 893.290f, 66.820f, 409.81f, 4.2f); + me->SummonCreature(NPC_PILE_TRIGGER, 898.099f, -88.9115f, 409.887f, 2.23402f); + me->SummonCreature(NPC_PILE_TRIGGER, 793.096f, -95.158f, 409.887f, 0.855211f); + me->SummonCreature(NPC_PILE_TRIGGER, 794.600f, 59.660f, 409.82f, 5.34f); + } + + void DoAction(int32 param) override + { + if (param == ACTION_AWAKEN_HEART) { + _pummelerCount = 0; + _spawnSelection = 0; + _damageDone = 0; + _timerSpawn = 0; + me->SetHealth(me->GetMaxHealth()); + me->CastSpell(me, SPELL_HEART_OVERLOAD, true); + me->CastSpell(me, SPELL_EXPOSED_HEART, false); // Channeled + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + + if (!summons.HasEntry(NPC_PILE_TRIGGER)) + SummonPiles(); + } + else if (param == ACTION_HIDE_HEART) + { + if (Creature* pXT002 = me->GetInstanceScript()->GetCreature(BOSS_XT002)) + if (pXT002->AI()) + { + pXT002->AI()->DoAction(_damageDone); + _damageDone = 0; + } me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); } - - SummonList summons; - uint32 _damageDone; - uint32 _timerSpawn; - - uint8 _spawnSelection; - uint8 _pummelerCount; - - void MoveInLineOfSight(Unit*) override { } - void AttackStart(Unit*) override { } - void JustSummoned(Creature* cr) override - { - summons.Summon(cr); - if (Unit* owner = me->GetVehicleBase()) - if (owner->IsCreature()) - owner->ToCreature()->AI()->JustSummoned(cr); - } - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - _damageDone += damage; - } - - void SummonPiles() - { - me->SummonCreature(NPC_PILE_TRIGGER, 893.290f, 66.820f, 409.81f, 4.2f); - me->SummonCreature(NPC_PILE_TRIGGER, 898.099f, -88.9115f, 409.887f, 2.23402f); - me->SummonCreature(NPC_PILE_TRIGGER, 793.096f, -95.158f, 409.887f, 0.855211f); - me->SummonCreature(NPC_PILE_TRIGGER, 794.600f, 59.660f, 409.82f, 5.34f); - } - - void DoAction(int32 param) override - { - if (param == ACTION_AWAKEN_HEART) - { - _pummelerCount = 0; - _spawnSelection = 0; - _damageDone = 0; - _timerSpawn = 0; - me->SetHealth(me->GetMaxHealth()); - me->CastSpell(me, SPELL_HEART_OVERLOAD, true); - me->CastSpell(me, SPELL_EXPOSED_HEART, false); // Channeled - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - - if (!summons.HasEntry(NPC_PILE_TRIGGER)) - SummonPiles(); - } - else if (param == ACTION_HIDE_HEART) - { - if (Creature* pXT002 = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_XT002))) - if (pXT002->AI()) - { - pXT002->AI()->DoAction(_damageDone); - _damageDone = 0; - } - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - } - } - - void SendEnergyToCorner() - { - Unit* pile = nullptr; - uint8 num = urand(1, 4); - for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) - if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr)) - if (summon->GetEntry() == NPC_PILE_TRIGGER) - { - pile = summon; - if ((--num) == 0) - break; - } - - if (pile) - me->CastSpell(pile, SPELL_ENERGY_ORB, true); - } - - void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override - { - // spawn not-so-random robots - if (spellInfo->Id == SPELL_ENERGY_ORB_TRIGGER && target->GetEntry() == NPC_PILE_TRIGGER) - switch (_spawnSelection) - { - case 0: - for (uint8 i = 0; i < 5; ++i) - me->SummonCreature(NPC_XS013_SCRAPBOT, target->GetPositionX() + irand(-3, 3), target->GetPositionY() + irand(-3, 3), target->GetPositionZ() + 2, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000); - _spawnSelection++; - break; - case 1: - me->SummonCreature(NPC_XE321_BOOMBOT, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 2, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); - _spawnSelection++; - break; - case 2: - for (uint8 i = 0; i < 5; ++i) - me->SummonCreature(NPC_XS013_SCRAPBOT, target->GetPositionX() + irand(-3, 3), target->GetPositionY() + irand(-3, 3), target->GetPositionZ() + 2, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000); - _spawnSelection++; - break; - case 3: - if (_pummelerCount < 2) - me->SummonCreature(NPC_XM024_PUMMELLER, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 2, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); - - _pummelerCount++; - _spawnSelection++; - break; - case 4: - for (uint8 i = 0; i < 5; ++i) - me->SummonCreature(NPC_XS013_SCRAPBOT, target->GetPositionX() + irand(-3, 3), target->GetPositionY() + irand(-3, 3), target->GetPositionZ() + 2, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000); - _spawnSelection = 0; - break; - } - } - - void JustDied(Unit* /*killer*/) override - { - me->SetVisible(false); - if (me->GetInstanceScript()) - if (Creature* XT002 = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_XT002))) - if (XT002->AI()) - XT002->AI()->DoAction(ACTION_HEART_BROKEN); - } - - void UpdateAI(uint32 diff) override - { - if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) - { - _timerSpawn += diff; - if (_timerSpawn >= 1900) - { - SendEnergyToCorner(); - _timerSpawn -= 1900; - } - } - } - }; -}; - -class npc_xt002_scrapbot : public CreatureScript -{ -public: - npc_xt002_scrapbot() : CreatureScript("npc_xt002_scrapbot") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct npc_xt002_scrapbotAI : public PassiveAI + void SendEnergyToCorner() { - npc_xt002_scrapbotAI(Creature* pCreature) : PassiveAI(pCreature) { } - - bool _locked; - void Reset() override - { - me->StopMoving(); - _locked = true; - me->SetWalk(true); - - if (me->GetInstanceScript()) - if (Creature* pXT002 = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_XT002))) + Unit* pile = nullptr; + uint8 num = urand(1, 4); + for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) + if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr)) + if (summon->GetEntry() == NPC_PILE_TRIGGER) { - if (pXT002->GetPositionZ() > 411.0f) // he is on stairs... idiot cryness protection - me->GetMotionMaster()->MovePoint(0, 884.028931f, -14.593809f, 409.786987f); - else - _locked = false; + pile = summon; + if ((--num) == 0) + break; } - } - void JustDied(Unit* killer) override - { - // Nerf Scrapbots achievement - if (killer && killer->GetEntry() == NPC_XE321_BOOMBOT) - if (me->GetInstanceScript()) - { - me->GetInstanceScript()->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, 65037); - me->GetInstanceScript()->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 65037); - } - } - - // tc use updateAI, while we have movementinform - void MovementInform(uint32 type, uint32 /*param*/) override - { - if (type == POINT_MOTION_TYPE) - { - _locked = false; - return; - } - - // we reached the target :) - if (type == FOLLOW_MOTION_TYPE && me->GetInstanceScript()) - if (Creature* pXT002 = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_XT002))) - { - if (pXT002->IsAlive()) - { - pXT002->AI()->DoAction(DATA_XT002_NERF_ENGINEERING); - pXT002->ModifyHealth(pXT002->GetMaxHealth() * 0.01f); - } - - if (!urand(0, 2)) - pXT002->AI()->Talk(EMOTE_SCRAPBOT); - - me->DespawnOrUnsummon(1ms); - } - } - - void UpdateAI(uint32 /*diff*/) override - { - if (!_locked) - { - if (me->GetInstanceScript()) - if (Creature* pXT002 = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_XT002))) - { - me->GetMotionMaster()->MoveFollow(pXT002, 0.0f, 0.0f); - _locked = true; - } - } - } - }; -}; - -class npc_xt002_pummeller : public CreatureScript -{ -public: - npc_xt002_pummeller() : CreatureScript("npc_xt002_pummeller") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); + if (pile) + me->CastSpell(pile, SPELL_ENERGY_ORB, true); } - struct npc_xt002_pummellerAI : public ScriptedAI + void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override { - npc_xt002_pummellerAI(Creature* pCreature) : ScriptedAI(pCreature) { } + // spawn not-so-random robots + if (spellInfo->Id == SPELL_ENERGY_ORB_TRIGGER && target->GetEntry() == NPC_PILE_TRIGGER) + switch (_spawnSelection) + { + case 0: + for (uint8 i = 0; i < 5; ++i) + me->SummonCreature(NPC_XS013_SCRAPBOT, target->GetPositionX() + irand(-3, 3), target->GetPositionY() + irand(-3, 3), target->GetPositionZ() + 2, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000); + _spawnSelection++; + break; + case 1: + me->SummonCreature(NPC_XE321_BOOMBOT, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 2, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + _spawnSelection++; + break; + case 2: + for (uint8 i = 0; i < 5; ++i) + me->SummonCreature(NPC_XS013_SCRAPBOT, target->GetPositionX() + irand(-3, 3), target->GetPositionY() + irand(-3, 3), target->GetPositionZ() + 2, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000); + _spawnSelection++; + break; + case 3: + if (_pummelerCount < 2) + me->SummonCreature(NPC_XM024_PUMMELLER, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 2, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); - int32 _arcingSmashTimer; - int32 _trampleTimer; - int32 _uppercutTimer; + _pummelerCount++; + _spawnSelection++; + break; + case 4: + for (uint8 i = 0; i < 5; ++i) + me->SummonCreature(NPC_XS013_SCRAPBOT, target->GetPositionX() + irand(-3, 3), target->GetPositionY() + irand(-3, 3), target->GetPositionZ() + 2, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000); + _spawnSelection = 0; + break; + } + } - void Reset() override + void JustDied(Unit* /*killer*/) override + { + me->SetVisible(false); + if (me->GetInstanceScript()) + if (Creature* XT002 = me->GetInstanceScript()->GetCreature(BOSS_XT002)) + if (XT002->AI()) + XT002->AI()->DoAction(ACTION_HEART_BROKEN); + } + + void UpdateAI(uint32 diff) override + { + if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) { + _timerSpawn += diff; + if (_timerSpawn >= 1900) + { + SendEnergyToCorner(); + _timerSpawn -= 1900; + } + } + } +}; + +struct npc_xt002_scrapbot : public PassiveAI +{ + npc_xt002_scrapbot(Creature* pCreature) : PassiveAI(pCreature) { } + + bool _locked; + void Reset() override + { + me->StopMoving(); + _locked = true; + me->SetWalk(true); + + if (me->GetInstanceScript()) + if (Creature* pXT002 = me->GetInstanceScript()->GetCreature(BOSS_XT002)) + { + if (pXT002->GetPositionZ() > 411.0f) // he is on stairs... idiot cryness protection + me->GetMotionMaster()->MovePoint(0, 884.028931f, -14.593809f, 409.786987f); + else + _locked = false; + } + } + + void JustDied(Unit* killer) override + { + // Nerf Scrapbots achievement + if (killer && killer->GetEntry() == NPC_XE321_BOOMBOT) + if (me->GetInstanceScript()) + { + me->GetInstanceScript()->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, 65037); + me->GetInstanceScript()->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 65037); + } + } + + // tc use updateAI, while we have movementinform + void MovementInform(uint32 type, uint32 /*param*/) override + { + if (type == POINT_MOTION_TYPE) + { + _locked = false; + return; + } + + // we reached the target :) + if (type == FOLLOW_MOTION_TYPE && me->GetInstanceScript()) + if (Creature* pXT002 = me->GetInstanceScript()->GetCreature(BOSS_XT002)) + { + if (pXT002->IsAlive()) + { + pXT002->AI()->DoAction(DATA_XT002_NERF_ENGINEERING); + pXT002->ModifyHealth(pXT002->GetMaxHealth() * 0.01f); + } + + if (!urand(0, 2)) + pXT002->AI()->Talk(EMOTE_SCRAPBOT); + + me->DespawnOrUnsummon(1ms); + } + } + + void UpdateAI(uint32 /*diff*/) override + { + if (!_locked) + { + if (me->GetInstanceScript()) + if (Creature* pXT002 = me->GetInstanceScript()->GetCreature(BOSS_XT002)) + { + me->GetMotionMaster()->MoveFollow(pXT002, 0.0f, 0.0f); + _locked = true; + } + } + } +}; + +struct npc_xt002_pummeller : public ScriptedAI +{ + npc_xt002_pummeller(Creature* pCreature) : ScriptedAI(pCreature) { } + + int32 _arcingSmashTimer; + int32 _trampleTimer; + int32 _uppercutTimer; + + void Reset() override + { + _arcingSmashTimer = 0; + _trampleTimer = 0; + _uppercutTimer = 0; + + if (Unit* target = SelectTargetFromPlayerList(200)) + AttackStart(target); + else + me->DespawnOrUnsummon(500ms); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _arcingSmashTimer += diff; + _trampleTimer += diff; + _uppercutTimer += diff; + + if (_arcingSmashTimer >= 8000) + { + me->CastSpell(me->GetVictim(), SPELL_ARCING_SMASH, false); _arcingSmashTimer = 0; - _trampleTimer = 0; - _uppercutTimer = 0; - - if (Unit* target = SelectTargetFromPlayerList(200)) - AttackStart(target); - else - me->DespawnOrUnsummon(500ms); + return; } - - void UpdateAI(uint32 diff) override + if (_trampleTimer >= 11000) { - if (!UpdateVictim()) - return; - - _arcingSmashTimer += diff; - _trampleTimer += diff; - _uppercutTimer += diff; - - if (_arcingSmashTimer >= 8000) - { - me->CastSpell(me->GetVictim(), SPELL_ARCING_SMASH, false); - _arcingSmashTimer = 0; - return; - } - if (_trampleTimer >= 11000) - { - me->CastSpell(me->GetVictim(), SPELL_TRAMPLE, false); - _trampleTimer = 0; - return; - } - if (_uppercutTimer >= 14000) - { - me->CastSpell(me->GetVictim(), SPELL_UPPERCUT, false); - _uppercutTimer = 0; - return; - } - - DoMeleeAttackIfReady(); + me->CastSpell(me->GetVictim(), SPELL_TRAMPLE, false); + _trampleTimer = 0; + return; } - }; + if (_uppercutTimer >= 14000) + { + me->CastSpell(me->GetVictim(), SPELL_UPPERCUT, false); + _uppercutTimer = 0; + return; + } + + DoMeleeAttackIfReady(); + } }; class BoomEvent : public BasicEvent @@ -705,144 +651,122 @@ private: Creature* _me; }; -class npc_xt002_boombot : public CreatureScript +struct npc_xt002_boombot : public PassiveAI { -public: - npc_xt002_boombot() : CreatureScript("npc_xt002_boombot") { } + npc_xt002_boombot(Creature* pCreature) : PassiveAI(pCreature) { } - CreatureAI* GetAI(Creature* pCreature) const override + bool _locked; + bool _boomed; + void Reset() override { - return GetUlduarAI(pCreature); + me->StopMoving(); + _locked = true; + _boomed = false; + me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING); + + if (me->GetInstanceScript()) + if (Creature* pXT002 = me->GetInstanceScript()->GetCreature(BOSS_XT002)) + { + if (pXT002->GetPositionZ() > 411.0f) // he is on stairs... idiot cryness protection + me->GetMotionMaster()->MovePoint(0, 884.028931f, -14.593809f, 409.786987f); + else + _locked = false; + } } - struct npc_xt002_boombotAI : public PassiveAI + void Explode() { - npc_xt002_boombotAI(Creature* pCreature) : PassiveAI(pCreature) { } + if (_boomed) + return; - bool _locked; - bool _boomed; - void Reset() override + _boomed = true; // Prevent recursive calls + + WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4); + data << me->GetGUID(); + data << me->GetGUID(); + data << uint32(SPELL_BOOM); + me->SendMessageToSet(&data, false); + + me->KillSelf(); + + // Visual only seems to work if the instant kill event is delayed or the spell itself is delayed + // Casting done from player and caster source has the same targetinfo flags, + // so that can't be the issue + // See BoomEvent class + // Schedule 1s delayed + me->m_Events.AddEventAtOffset(new BoomEvent(me), 1s); + } + + void JustDied(Unit* /*killer*/) override + { + me->m_Events.AddEventAtOffset(new BoomEvent(me), 1s); + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (_boomed) + damage = 0; + + if (me->HealthBelowPctDamaged(50, damage) && !_boomed) { - me->StopMoving(); - _locked = true; - _boomed = false; - me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING); + damage = 0; + Explode(); + } + } + // tc they use updateAI, while we have movementinform + void MovementInform(uint32 type, uint32 /*param*/) override + { + if (type == POINT_MOTION_TYPE) + { + _locked = false; + return; + } + // we reached the target :) + //if (type == FOLLOW_MOTION_TYPE) + // _kill = true; + } + + void UpdateAI(uint32 /*diff*/) override + { + if (!_locked) + { if (me->GetInstanceScript()) - if (Creature* pXT002 = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_XT002))) + if (Creature* pXT002 = me->GetInstanceScript()->GetCreature(BOSS_XT002)) { - if (pXT002->GetPositionZ() > 411.0f) // he is on stairs... idiot cryness protection - me->GetMotionMaster()->MovePoint(0, 884.028931f, -14.593809f, 409.786987f); - else - _locked = false; + me->GetMotionMaster()->MoveFollow(pXT002, 0.0f, 0.0f); + _locked = true; } } - - void Explode() - { - if (_boomed) - return; - - _boomed = true; // Prevent recursive calls - - WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4); - data << me->GetGUID(); - data << me->GetGUID(); - data << uint32(SPELL_BOOM); - me->SendMessageToSet(&data, false); - - me->KillSelf(); - - // Visual only seems to work if the instant kill event is delayed or the spell itself is delayed - // Casting done from player and caster source has the same targetinfo flags, - // so that can't be the issue - // See BoomEvent class - // Schedule 1s delayed - me->m_Events.AddEventAtOffset(new BoomEvent(me), 1s); - } - - void JustDied(Unit* /*killer*/) override - { - me->m_Events.AddEventAtOffset(new BoomEvent(me), 1s); - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (_boomed) - damage = 0; - - if (me->HealthBelowPctDamaged(50, damage) && !_boomed) - { - damage = 0; - Explode(); - } - } - - // tc they use updateAI, while we have movementinform - void MovementInform(uint32 type, uint32 /*param*/) override - { - if (type == POINT_MOTION_TYPE) - { - _locked = false; - return; - } - // we reached the target :) - //if (type == FOLLOW_MOTION_TYPE) - // _kill = true; - } - - void UpdateAI(uint32 /*diff*/) override - { - if (!_locked) - { - if (me->GetInstanceScript()) - if (Creature* pXT002 = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_XT002))) - { - me->GetMotionMaster()->MoveFollow(pXT002, 0.0f, 0.0f); - _locked = true; - } - } - } - }; + } }; -class npc_xt002_life_spark : public CreatureScript +struct npc_xt002_life_spark : public ScriptedAI { -public: - npc_xt002_life_spark() : CreatureScript("npc_xt002_life_spark") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_xt002_life_spark(Creature* pCreature) : ScriptedAI(pCreature) { - return GetUlduarAI(pCreature); + me->SetMaxHealth(RAID_MODE(54000, 172000)); + me->SetHealth(me->GetMaxHealth()); + me->CastSpell(me, SPELL_SPARK_DAMAGE, true); } - struct npc_xt002_life_sparkAI : public ScriptedAI + uint32 _attackTimer; + void Reset() override { - npc_xt002_life_sparkAI(Creature* pCreature) : ScriptedAI(pCreature) - { - me->SetMaxHealth(RAID_MODE(54000, 172000)); - me->SetHealth(me->GetMaxHealth()); - me->CastSpell(me, SPELL_SPARK_DAMAGE, true); - } + if (Unit* target = SelectTargetFromPlayerList(200)) + AttackStart(target); + else + me->DespawnOrUnsummon(); + } - uint32 _attackTimer; - void Reset() override - { - if (Unit* target = SelectTargetFromPlayerList(200)) - AttackStart(target); - else - me->DespawnOrUnsummon(); - } + void UpdateAI(uint32 /*diff*/) override + { + if (!UpdateVictim()) + return; - void UpdateAI(uint32 /*diff*/) override - { - if (!UpdateVictim()) - return; - - me->CastSpell(me->GetVictim(), SPELL_SPARK_MELEE, false); - DoMeleeAttackIfReady(); - } - }; + me->CastSpell(me->GetVictim(), SPELL_SPARK_MELEE, false); + DoMeleeAttackIfReady(); + } }; // 62775 - Tympanic Tantrum @@ -999,7 +923,7 @@ public: { if (target) if (InstanceScript* instance = target->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_XT002))) + if (Creature* cr = instance->GetCreature(BOSS_XT002)) return cr->AI()->GetData(DATA_XT002_NERF_ENGINEERING); return false; @@ -1015,7 +939,7 @@ public: { if (target) if (InstanceScript* instance = target->GetInstanceScript()) - if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_XT002))) + if (Creature* cr = instance->GetCreature(BOSS_XT002)) return cr->AI()->GetData(DATA_XT002_GRAVITY_ACHIEV); return false; @@ -1025,12 +949,12 @@ public: void AddSC_boss_xt002() { // Npcs - new boss_xt002(); - new npc_xt002_heart(); - new npc_xt002_scrapbot(); - new npc_xt002_pummeller(); - new npc_xt002_boombot(); - new npc_xt002_life_spark(); + RegisterUlduarCreatureAI(boss_xt002); + RegisterUlduarCreatureAI(npc_xt002_heart); + RegisterUlduarCreatureAI(npc_xt002_scrapbot); + RegisterUlduarCreatureAI(npc_xt002_pummeller); + RegisterUlduarCreatureAI(npc_xt002_boombot); + RegisterUlduarCreatureAI(npc_xt002_life_spark); // Spells RegisterSpellScript(spell_xt002_tympanic_tantrum); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp index 1b4ce7bf5..3e458823e 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp @@ -285,7 +285,7 @@ const Position KeepersPos[4] = const uint32 TABLE_KEEPER_ENTRY[4] = {NPC_FREYA_KEEPER, NPC_HODIR_KEEPER, NPC_MIMIRON_KEEPER, NPC_THORIM_KEEPER}; const uint32 TABLE_GOSSIP_ENTRY[4] = {NPC_FREYA_GOSSIP, NPC_HODIR_GOSSIP, NPC_MIMIRON_GOSSIP, NPC_THORIM_GOSSIP}; -const uint32 TABLE_KEEPER_TYPE[4] = {TYPE_FREYA, TYPE_HODIR, TYPE_MIMIRON, TYPE_THORIM}; +const uint32 TABLE_KEEPER_TYPE[4] = {BOSS_FREYA, BOSS_HODIR, BOSS_MIMIRON, BOSS_THORIM}; static LocationsXY yoggPortalLoc[] = { @@ -364,1361 +364,1262 @@ enum Texts const Position Middle = {1980.28f, -25.5868f, 329.397f, M_PI * 1.5f}; -class boss_yoggsaron_sara : public CreatureScript +struct boss_yoggsaron_sara : public ScriptedAI { -public: - boss_yoggsaron_sara() : CreatureScript("boss_yoggsaron_sara") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_yoggsaron_sara(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature) { - return GetUlduarAI(pCreature); + m_pInstance = pCreature->GetInstanceScript(); } - struct boss_yoggsaron_saraAI : public ScriptedAI + InstanceScript* m_pInstance; + EventMap events; + SummonList summons; + + uint32 _initFight; + uint8 _summonedGuardiansCount; + uint32 _p2TalkTimer; + bool _secondPhase; + float _summonSpeed; + uint8 _currentIllusion; + bool _isIllusionReversed; + + void AttackStart(Unit*) override { } + void MoveInLineOfSight(Unit*) override { } + + void JustSummoned(Creature* summon) override { - boss_yoggsaron_saraAI(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature) + summons.Summon(summon); + } + + void SpawnClouds() + { + for (uint8 i = 0; i < 6; ++i) { - m_pInstance = pCreature->GetInstanceScript(); - } - - InstanceScript* m_pInstance; - EventMap events; - SummonList summons; - - uint32 _initFight; - uint8 _summonedGuardiansCount; - uint32 _p2TalkTimer; - bool _secondPhase; - float _summonSpeed; - uint8 _currentIllusion; - bool _isIllusionReversed; - - void AttackStart(Unit*) override { } - void MoveInLineOfSight(Unit*) override { } - - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - } - - void SpawnClouds() - { - for (uint8 i = 0; i < 6; ++i) - { - float Zplus = i > 2 ? (i - 2) * 1.6f : 0; - if (i % 2) - me->SummonCreature(NPC_OMINOUS_CLOUD, me->GetPositionX() + 8 + i * 7, me->GetPositionY() + 8 + i * 7, 326 + Zplus, 0); - else - me->SummonCreature(NPC_OMINOUS_CLOUD, me->GetPositionX() - 8 - i * 7, me->GetPositionY() - 8 - i * 7, 326 + Zplus, 0); - } - } - - void EnterEvadeMode(EvadeReason why) override - { - if (!_EnterEvadeMode(why)) - return; - - Position pos; - pos = me->GetHomePosition(); - me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); - Reset(); - me->setActive(false); - } - - void EnableSara(bool apply) - { - if (apply) - { - me->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE); - me->DisableRotate(false); - me->ClearUnitState(UNIT_STATE_ROOT); - } + float Zplus = i > 2 ? (i - 2) * 1.6f : 0; + if (i % 2) + me->SummonCreature(NPC_OMINOUS_CLOUD, me->GetPositionX() + 8 + i * 7, me->GetPositionY() + 8 + i * 7, 326 + Zplus, 0); else - { - me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE); - me->DisableRotate(true); - me->AddUnitState(UNIT_STATE_ROOT); - } + me->SummonCreature(NPC_OMINOUS_CLOUD, me->GetPositionX() - 8 - i * 7, me->GetPositionY() - 8 - i * 7, 326 + Zplus, 0); } - - void Reset() override - { - if (!_secondPhase) // Phase 1 wipe - { - me->GetMap()->DoForAllPlayers([&](Player* player) - { - if (Creature* voice = me->FindNearestCreature(NPC_VOICE_OF_YOGG_SARON, 10.0f)) - { - voice->AI()->Talk(WHISPER_VOICE_PHASE_1_WIPE, player); - } - }); - } - - summons.DoAction(ACTION_DESPAWN_ADDS); - events.Reset(); - summons.DespawnAll(); - - me->SetVisible(true); - me->SetDisplayId(me->GetNativeDisplayId()); - me->SetDisableGravity(true); - EnableSara(false); - SpawnClouds(); - - _initFight = 1; - - UpdateKeeperSpawns(); - _summonedGuardiansCount = 0; - _p2TalkTimer = 0; - _secondPhase = false; - _summonSpeed = 1.0f; - _currentIllusion = urand(1, 3); - _isIllusionReversed = urand(0, 1); - - if (m_pInstance) - { - m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, CRITERIA_NOT_GETTING_OLDER); - m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SANITY); - m_pInstance->SetData(TYPE_YOGGSARON, NOT_STARTED); - if (GameObject* go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(GO_YOGG_SARON_DOORS))) - go->SetGoState(GO_STATE_ACTIVE); - } - } - - void InitFight(Unit* target) - { - if (!m_pInstance) - return; - - // some simple hack checks - if (m_pInstance->GetData(TYPE_VEZAX) != DONE || m_pInstance->GetData(TYPE_XT002) != DONE) - return; - - m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, CRITERIA_NOT_GETTING_OLDER); - m_pInstance->SetData(TYPE_YOGGSARON, IN_PROGRESS); - me->SetInCombatWithZone(); - AttackStart(target); - - DespawnGossipKeepers(); - // Engage Keepers - summons.DoZoneInCombat(); - - me->CastSpell(me, SPELL_SANITY_BASE, true); - - events.ScheduleEvent(EVENT_SARA_P1_DOORS_CLOSE, 15s, 0, EVENT_PHASE_ONE); - events.ScheduleEvent(EVENT_SARA_P1_BERSERK, 15min, 0, 0); - events.ScheduleEvent(EVENT_SARA_P1_SUMMON, 0ms, 0, EVENT_PHASE_ONE); - events.SetPhase(EVENT_PHASE_ONE); - - Talk(SAY_SARA_AGGRO); - me->setActive(true); - } - - void DespawnGossipKeepers() - { - for (uint8 i = KEEPER_FREYA; i <= KEEPER_THORIM; i++) - summons.DespawnEntry(TABLE_GOSSIP_ENTRY[i]); - } - - void UpdateKeeperSpawns() - { - for (uint8 i = KEEPER_FREYA; i <= KEEPER_THORIM; i++) - { - if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i)) - { - if (!summons.HasEntry(TABLE_KEEPER_ENTRY[i])) - me->SummonCreature(TABLE_KEEPER_ENTRY[i], KeepersPos[i]); - } - else if (m_pInstance->GetData(TABLE_KEEPER_TYPE[i]) == DONE) - { - if (!summons.HasEntry(TABLE_GOSSIP_ENTRY[i])) - me->SummonCreature(TABLE_GOSSIP_ENTRY[i], GossipKeepersPos[i]); - } - } - } - - void InformCloud() - { - Creature* cloud = nullptr; - for (SummonList::const_iterator itr = summons.begin(); itr != summons.end();) - { - Creature* summon = ObjectAccessor::GetCreature(*me, *itr); - ++itr; - if (!summon || summon->GetEntry() != NPC_OMINOUS_CLOUD || me->GetDistance(summon) < 20) - continue; - - if ((!cloud || (urand(0, 1) && !summon->HasAura(SPELL_SUMMON_GUARDIAN_OF_YS)))) - cloud = summon; - } - - if (cloud) - cloud->AI()->DoAction(ACTION_START_SUMMONING); - } - - void SpawnTentacle(uint32 entry) - { - uint32 dist = urand(38, 48); - float o = rand_norm() * M_PI * 2; - float spawnX = me->GetPositionX() + dist * cos(o); - float spawnY = me->GetPositionY() + dist * std::sin(o); - float spawnZ = me->GetMap()->GetHeight(me->GetPhaseMask(), spawnX, spawnY, 330.0f); - if (Creature* cr = me->SummonCreature(entry, spawnX, spawnY, spawnZ, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000)) - { - cr->CastSpell(cr, SPELL_TENTACLE_ERUPT, true); - cr->CastSpell(cr, SPELL_VOID_ZONE_SMALL, true); - cr->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); - } - } - - void SummonDeathOrbs() - { - for (uint8 i = 0; i < 4; ++i) - { - uint32 dist = urand(38, 48); - float o = rand_norm() * M_PI * 2; - float Zplus = (dist - 38) / 6.5f; - me->SummonCreature(NPC_DEATH_ORB, me->GetPositionX() + dist * cos(o), me->GetPositionY() + dist * std::sin(o), 327.2 + Zplus, 0, TEMPSUMMON_TIMED_DESPAWN, 20000); - } - } - - void AddPortals() - { - _summonSpeed -= 0.1f; - Creature* cr = nullptr; - - // Spawn Portals - for (uint8 i = 0; i < RAID_MODE(4, 10); ++i) - { - if ((cr = me->SummonCreature(NPC_DESCEND_INTO_MADNESS, yoggPortalLoc[i].x, yoggPortalLoc[i].y, yoggPortalLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 25000))) - { - cr->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NON_ATTACKABLE); - cr->SetArmor(_currentIllusion); - } - } - - EntryCheckPredicate pred(NPC_BRAIN_OF_YOGG_SARON); - summons.DoAction(_currentIllusion, pred); - - if (_isIllusionReversed) - _currentIllusion = _currentIllusion == 3 ? 1 : (_currentIllusion + 1); - else - _currentIllusion = _currentIllusion == 1 ? 3 : (_currentIllusion - 1); - } - - void KilledUnit(Unit* who) override - { - if (who->IsPlayer()) - { - Talk(SAY_SARA_KILL); - } - } - - void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_SANITY) - if (Aura* aur = target->GetAura(SPELL_SANITY)) - aur->SetStackAmount(100); - } - - uint32 GetData(uint32 param) const override - { - if (param == DATA_GET_KEEPERS_COUNT) - { - uint8 _count = 0; - for (uint8 i = 0; i < 4; ++i) - if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i)) - ++_count; - return _count; - } - else if (param == DATA_GET_SARA_PHASE) - return _secondPhase; - - return 4; // just to be sure, return max numer of keepers - } - - void DoAction(int32 param) override - { - if (param == ACTION_SARA_UPDATE_SUMMON_KEEPERS) - { - UpdateKeeperSpawns(); - } - else if (param == ACTION_BRAIN_DAMAGED) - { - summons.DoAction(ACTION_REMOVE_STUN); - - EntryCheckPredicate pred2(NPC_YOGG_SARON); - summons.DoAction(ACTION_YOGG_SARON_START_P3, pred2); - - EntryCheckPredicate pred3(NPC_THORIM_KEEPER); - summons.DoAction(ACTION_THORIM_START_STORM, pred3); - - if (me->GetMap()->Is25ManRaid() && (GetData(DATA_GET_KEEPERS_COUNT) > 0)) - summons.DoAction(ACTION_YOGG_SARON_HARD_MODE, pred2); - - summons.DespawnEntry(NPC_DEATH_ORB); - events.SetPhase(EVENT_PHASE_THREE); - - me->RemoveAllAuras(); - me->SetVisible(false); - return; - } - else if (param == ACTION_YOGG_SARON_DEATH) - { - // Despawn everything but Yogg-Saron's corpse - summons.DoAction(ACTION_DESPAWN_ADDS); - summons.DespawnEntry(NPC_CRUSHER_TENTACLE); - summons.DespawnEntry(NPC_CONSTRICTOR_TENTACLE); - summons.DespawnEntry(NPC_CORRUPTOR_TENTACLE); - summons.DespawnEntry(NPC_VOICE_OF_YOGG_SARON); - summons.DespawnEntry(NPC_BRAIN_OF_YOGG_SARON); - summons.DespawnEntry(NPC_MIMIRON_GOSSIP); - summons.DespawnEntry(NPC_HODIR_GOSSIP); - summons.DespawnEntry(NPC_FREYA_GOSSIP); - summons.DespawnEntry(NPC_THORIM_GOSSIP); - summons.DespawnEntry(NPC_MIMIRON_KEEPER); - summons.DespawnEntry(NPC_HODIR_KEEPER); - summons.DespawnEntry(NPC_FREYA_KEEPER); - summons.DespawnEntry(NPC_THORIM_KEEPER); - summons.DespawnEntry(NPC_SANITY_WELL); - me->KillSelf(); - return; - } - - // Determine shatter duration - if (param <= 0) - return; - - // Illusion shatters (param - stun time) - if (Creature* yoggb = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(NPC_BRAIN_OF_YOGG_SARON))) - { - yoggb->AI()->Talk(EMOTE_YOGG_SARON_BRAIN_SHATTERED); - } - - Milliseconds timer = events.GetTimeUntilEvent(EVENT_SARA_P2_OPEN_PORTALS); - Milliseconds portalTime = (timer > 0ms ? timer : 0ms); - events.DelayEvents(Milliseconds(param + 100)); - events.RescheduleEvent(EVENT_SARA_P2_OPEN_PORTALS, portalTime, 0, EVENT_PHASE_TWO); - events.ScheduleEvent(EVENT_SARA_P2_REMOVE_STUN, Milliseconds(param), 0, EVENT_PHASE_TWO); - me->CastSpell(me, SPELL_SHATTERED_ILLUSION, true); - } - - void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (who && who->GetEntry() == NPC_GUARDIAN_OF_YS && !_secondPhase) - { - damage = 25000; - - // START PHASE 2 - if (me->GetHealth() <= damage) - { - _secondPhase = true; - damage = 0; - - events.SetPhase(EVENT_PHASE_TWO); - me->SetHealth(me->GetMaxHealth()); - - if (Creature* cr = me->SummonCreature(NPC_YOGG_SARON, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), M_PI)) - cr->SetVisible(false); - - _p2TalkTimer++; - Talk(SAY_SARA_TRANSFORM_1); - } - return; - } - - damage = 0; - } - - void UpdateAI(uint32 diff) override - { - if (_initFight) - { - _initFight += diff; - if (_initFight > 5000) - { - if (Unit* target = SelectTargetFromPlayerList(90)) - { - _initFight = 0; - InitFight(target); - } - else - _initFight = 1; - } - return; - } - - if (!SelectTargetFromPlayerList(90, SPELL_INSANE1)) - { - m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_INSANE1); - EnterEvadeMode(EVADE_REASON_OTHER); - return; - } - - if (_p2TalkTimer) - { - _p2TalkTimer += diff; - if (_p2TalkTimer >= 4000 && _p2TalkTimer < 20000) - { - EntryCheckPredicate pred(NPC_OMINOUS_CLOUD); - summons.DoAction(ACTION_UNSUMMON_CLOUDS, pred); - Talk(SAY_SARA_TRANSFORM_2); - _p2TalkTimer = 20000; - } - else if (_p2TalkTimer >= 25000 && _p2TalkTimer < 40000) - { - summons.DespawnEntry(NPC_OMINOUS_CLOUD); - Talk(SAY_SARA_TRANSFORM_3); - _p2TalkTimer = 40000; - } - else if (_p2TalkTimer >= 44500 && _p2TalkTimer < 60000) - { - Talk(SAY_SARA_TRANSFORM_4); - _p2TalkTimer = 60000; - } - else if (_p2TalkTimer >= 64000) - { - EntryCheckPredicate pred(NPC_YOGG_SARON); - summons.DoAction(ACTION_YOGG_SARON_START_YELL, pred); - _p2TalkTimer = 0; - events.ScheduleEvent(EVENT_SARA_P2_START, 500ms, 0, EVENT_PHASE_TWO); - } - return; - } - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SARA_P1_DOORS_CLOSE: - // Whispers of YS - me->SummonCreature(NPC_VOICE_OF_YOGG_SARON, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); - - if (m_pInstance) - if (GameObject* go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(GO_YOGG_SARON_DOORS))) - go->SetGoState(GO_STATE_READY); - - events.ScheduleEvent(EVENT_SARA_P1_SPELLS, 0ms, 1, EVENT_PHASE_ONE); - break; - case EVENT_SARA_P1_SUMMON: - events.Repeat(Milliseconds(20000 - (std::min(_summonedGuardiansCount, (uint8)5) * 2000))); - ++_summonedGuardiansCount; - InformCloud(); - break; - case EVENT_SARA_P1_SPELLS: - { - uint32 spell = RAND(SPELL_SARAS_ANGER_TARGET_SELECTOR, SPELL_SARAS_BLESSING_TARGET_SELECTOR, SPELL_SARAS_FAVOR_TARGET_SELECTOR); - if (urand(0, 2)) - { - if (spell == SPELL_SARAS_ANGER_TARGET_SELECTOR) - { - Talk(SAY_SARA_ANGER); - } - else if (spell == SPELL_SARAS_FAVOR_TARGET_SELECTOR) - { - Talk(SAY_SARA_FERVOR_HIT); - } - } - - me->CastCustomSpell(spell, SPELLVALUE_MAX_TARGETS, 1, nullptr, false); - events.Repeat(me->GetMap()->Is25ManRaid() ? randtime(0ms, 3s) : randtime(4s, 6s)); - break; - } - case EVENT_SARA_P2_START: - { - EntryCheckPredicate pred(NPC_YOGG_SARON); - summons.DoAction(ACTION_YOGG_SARON_APPEAR, pred); - events.RescheduleEvent(EVENT_SARA_P2_SPAWN_START_TENTACLES, 500ms, 0, EVENT_PHASE_TWO); - - // Spawn Brain! - me->SummonCreature(NPC_BRAIN_OF_YOGG_SARON, 1981.3f, -25.43f, 265); - break; - } - case EVENT_SARA_P2_MALADY: - me->CastCustomSpell(SPELL_MALADY_OF_THE_MIND, SPELLVALUE_MAX_TARGETS, 1, me, false); - events.Repeat(20s); - break; - case EVENT_SARA_P2_PSYCHOSIS: - if ((urand(0, 9)) == 0) // Rarely said (as it's casted every 3.5s) - { - Talk(SAY_SARA_PSYCHOSIS_HIT); - } - me->CastCustomSpell(SPELL_SARA_PSYCHOSIS_10, SPELLVALUE_MAX_TARGETS, 1, me, false); - events.Repeat(3500ms); - break; - case EVENT_SARA_P2_DEATH_RAY: - Talk(SAY_SARA_DEATH_RAY); - SummonDeathOrbs(); - events.Repeat(20s); - break; - case EVENT_SARA_P2_SUMMON_T1: // CRUSHER - SpawnTentacle(NPC_CRUSHER_TENTACLE); - events.Repeat(Milliseconds(uint32((50000 + urand(0, 10000)) * _summonSpeed))); - break; - case EVENT_SARA_P2_SUMMON_T2: // CONSTRICTOR - SpawnTentacle(NPC_CONSTRICTOR_TENTACLE); - events.Repeat(Milliseconds(uint32((15000 + urand(0, 5000))* _summonSpeed))); - break; - case EVENT_SARA_P2_SUMMON_T3: // CORRUPTOR - SpawnTentacle(NPC_CORRUPTOR_TENTACLE); - events.Repeat(Milliseconds(uint32((30000 + urand(0, 10000))* _summonSpeed))); - break; - case EVENT_SARA_P2_BRAIN_LINK: - me->CastCustomSpell(SPELL_BRAIN_LINK, SPELLVALUE_MAX_TARGETS, 1, me, false); - events.Repeat(30s); - break; - case EVENT_SARA_P2_OPEN_PORTALS: - { - AddPortals(); - EntryCheckPredicate pred(NPC_YOGG_SARON); - summons.DoAction(ACTION_YOGG_SARON_OPEN_PORTAL_YELL, pred); - events.Repeat(80s); - break; - } - case EVENT_SARA_P2_REMOVE_STUN: - { - me->RemoveAura(SPELL_SHATTERED_ILLUSION); - summons.DoAction(ACTION_REMOVE_STUN); - break; - } - case EVENT_SARA_P2_SPAWN_START_TENTACLES: - me->SetOrientation(M_PI); - me->SetDisplayId(SARA_TRANSFORM_MODEL); - - me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), 355, me->GetOrientation()); - me->SetPosition(me->GetPositionX(), me->GetPositionY(), 355, me->GetOrientation()); - - SpawnTentacle(NPC_CRUSHER_TENTACLE); - SpawnTentacle(NPC_CONSTRICTOR_TENTACLE); - SpawnTentacle(NPC_CORRUPTOR_TENTACLE); - SpawnTentacle(NPC_CORRUPTOR_TENTACLE); - - events.ScheduleEvent(EVENT_SARA_P2_MALADY, 7s, 0, EVENT_PHASE_TWO); - events.ScheduleEvent(EVENT_SARA_P2_PSYCHOSIS, 3s, 0, EVENT_PHASE_TWO); - events.ScheduleEvent(EVENT_SARA_P2_DEATH_RAY, 15s, 0, EVENT_PHASE_TWO); - events.ScheduleEvent(EVENT_SARA_P2_SUMMON_T1, 50s, 60s, 0, EVENT_PHASE_TWO); - events.ScheduleEvent(EVENT_SARA_P2_SUMMON_T2, 15s, 20s, 0, EVENT_PHASE_TWO); - events.ScheduleEvent(EVENT_SARA_P2_SUMMON_T3, 30s + randtime(0ms, 10s), 0, EVENT_PHASE_TWO); - events.ScheduleEvent(EVENT_SARA_P2_BRAIN_LINK, 0ms, 0, EVENT_PHASE_TWO); - events.ScheduleEvent(EVENT_SARA_P2_OPEN_PORTALS, 60s, 0, EVENT_PHASE_TWO); - break; - case EVENT_SARA_P1_BERSERK: - if (me->GetInstanceScript()) - { - if (Creature* yogg = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_YOGGSARON))) - { - yogg->AI()->Talk(EMOTE_YOGG_SARON_BERSERK); - } - } - me->CastSpell(me, SPELL_EXTINGUISH_ALL_LIFE, true); - events.Repeat(5s); - break; - } - } - }; -}; - -class boss_yoggsaron_cloud : public CreatureScript -{ -public: - boss_yoggsaron_cloud() : CreatureScript("boss_yoggsaron_cloud") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct boss_yoggsaron_cloudAI : public npc_escortAI + void EnterEvadeMode(EvadeReason why) override { - boss_yoggsaron_cloudAI(Creature* pCreature) : npc_escortAI(pCreature) - { - InitWaypoint(); - Reset(); - Start(false, ObjectGuid::Empty, nullptr, false, true); - } + if (!_EnterEvadeMode(why)) + return; - uint32 _checkTimer; - bool _isSummoning; - - void JustSummoned(Creature* cr) override - { - cr->ToTempSummon()->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN); - - _isSummoning = false; - if (me->GetInstanceScript()) - if (Creature* sara = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(NPC_SARA))) - sara->AI()->JustSummoned(cr); - } - - void MoveInLineOfSight(Unit* /*who*/) override {} - void AttackStart(Unit* /*who*/) override {} - void WaypointReached(uint32 /*point*/) override {} - - void Reset() override - { - me->CastSpell(me, SPELL_CLOUD_VISUAL, true); - _checkTimer = 0; - _isSummoning = false; - } - - void DoAction(int32 param) override - { - if (param == ACTION_UNSUMMON_CLOUDS) - { - me->RemoveAllAuras(); - } - else if (param == ACTION_START_SUMMONING) - { - _isSummoning = true; - me->CastSpell(me, SPELL_SUMMON_GUARDIAN_OF_YS, true); - } - } - - void InitWaypoint() - { - float dist = Middle.GetExactDist(me); - if (me->GetPositionX() > Middle.GetPositionX()) - { - for (uint8 i = 0; i <= dist; ++i) - { - float angle = M_PI * 2 / dist * i; - AddWaypoint(i, Middle.GetPositionX() + dist * cos(angle), Middle.GetPositionY() + dist * std::sin(angle), me->GetPositionZ(), 0); - } - } - else - { - for (uint8 i = 0; i <= dist; ++i) - { - float angle = M_PI * 2 - (M_PI * 2 / dist * i); - AddWaypoint(i, Middle.GetPositionX() + dist * cos(angle), Middle.GetPositionY() + dist * std::sin(angle), me->GetPositionZ(), 0); - } - } - } - - void UpdateEscortAI(uint32 diff) override - { - _checkTimer += diff; - if (_checkTimer >= 500 && !_isSummoning) - { - Unit* who = me->SelectNearbyTarget(nullptr, 6.0f); - if (who && who->IsPlayer() && !me->HasAura(SPELL_SUMMON_GUARDIAN_OF_YS) && !who->HasAura(SPELL_HODIR_FLASH_FREEZE)) - { - _isSummoning = true; - Talk(0, who); - me->CastSpell(me, SPELL_SUMMON_GUARDIAN_OF_YS, true); - } - - _checkTimer = 0; - } - } - }; -}; - -class boss_yoggsaron_guardian_of_ys : public CreatureScript -{ -public: - boss_yoggsaron_guardian_of_ys() : CreatureScript("boss_yoggsaron_guardian_of_ys") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); + Position pos; + pos = me->GetHomePosition(); + me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); + Reset(); + me->setActive(false); } - struct boss_yoggsaron_guardian_of_ysAI : public ScriptedAI + void EnableSara(bool apply) { - boss_yoggsaron_guardian_of_ysAI(Creature* pCreature) : ScriptedAI(pCreature) { } - - uint32 _spellTimer; - - void Reset() override + if (apply) { - _spellTimer = 0; - me->SetInCombatWithZone(); + me->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE); + me->DisableRotate(false); + me->ClearUnitState(UNIT_STATE_ROOT); } - - void JustDied(Unit*) override + else { - me->CastSpell((Unit*)nullptr, SPELL_SHADOW_NOVA, true); + me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE); + me->DisableRotate(true); + me->AddUnitState(UNIT_STATE_ROOT); } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _spellTimer += diff; - if (_spellTimer > 8000) - { - me->CastSpell(me, SPELL_DARK_VOLLEY, false); - _spellTimer = 0; - } - - DoMeleeAttackIfReady(); - } - }; -}; - -class boss_yoggsaron : public CreatureScript -{ -public: - boss_yoggsaron() : CreatureScript("boss_yoggsaron") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct boss_yoggsaronAI : public ScriptedAI + void Reset() override { - boss_yoggsaronAI(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature) + if (!_secondPhase) // Phase 1 wipe { - m_pInstance = me->GetInstanceScript(); - _thirdPhase = false; - _usedInsane = false; - summons.DespawnAll(); - events.Reset(); - - uint8 _count = 4; - me->SetLootMode(31); // 1 + 2 + 4 + 8 + 16, remove with watchers addition - if (m_pInstance) + me->GetMap()->DoForAllPlayers([&](Player* player) { - for (uint8 i = 0; i < 4; ++i) - if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i)) - { - me->RemoveLootMode(1 << _count); - --_count; - } - } + if (Creature* voice = me->FindNearestCreature(NPC_VOICE_OF_YOGG_SARON, 10.0f)) + { + voice->AI()->Talk(WHISPER_VOICE_PHASE_1_WIPE, player); + } + }); } - InstanceScript* m_pInstance; - EventMap events; - SummonList summons; - bool _thirdPhase; - bool _usedInsane; + summons.DoAction(ACTION_DESPAWN_ADDS); + events.Reset(); + summons.DespawnAll(); - void AttackStart(Unit*) override { } + me->SetVisible(true); + me->SetDisplayId(me->GetNativeDisplayId()); + me->SetDisableGravity(true); + EnableSara(false); + SpawnClouds(); - void JustSummoned(Creature* cr) override { summons.Summon(cr); } + _initFight = 1; - void SummonImmortalGuardian() + UpdateKeeperSpawns(); + _summonedGuardiansCount = 0; + _p2TalkTimer = 0; + _secondPhase = false; + _summonSpeed = 1.0f; + _currentIllusion = urand(1, 3); + _isIllusionReversed = urand(0, 1); + + if (m_pInstance) + { + m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, CRITERIA_NOT_GETTING_OLDER); + m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SANITY); + m_pInstance->SetData(BOSS_YOGGSARON, NOT_STARTED); + if (GameObject* go = m_pInstance->GetGameObject(DATA_YOGG_SARON_DOORS)) + go->SetGoState(GO_STATE_ACTIVE); + } + } + + void InitFight(Unit* target) + { + if (!m_pInstance) + return; + + // some simple hack checks + if (m_pInstance->GetBossState(BOSS_VEZAX) != DONE || m_pInstance->GetBossState(BOSS_XT002) != DONE) + return; + + m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, CRITERIA_NOT_GETTING_OLDER); + m_pInstance->SetData(BOSS_YOGGSARON, IN_PROGRESS); + me->SetInCombatWithZone(); + AttackStart(target); + + DespawnGossipKeepers(); + // Engage Keepers + summons.DoZoneInCombat(); + + me->CastSpell(me, SPELL_SANITY_BASE, true); + + events.ScheduleEvent(EVENT_SARA_P1_DOORS_CLOSE, 15s, 0, EVENT_PHASE_ONE); + events.ScheduleEvent(EVENT_SARA_P1_BERSERK, 15min, 0, 0); + events.ScheduleEvent(EVENT_SARA_P1_SUMMON, 0ms, 0, EVENT_PHASE_ONE); + events.SetPhase(EVENT_PHASE_ONE); + + Talk(SAY_SARA_AGGRO); + me->setActive(true); + } + + void DespawnGossipKeepers() + { + for (uint8 i = KEEPER_FREYA; i <= KEEPER_THORIM; i++) + summons.DespawnEntry(TABLE_GOSSIP_ENTRY[i]); + } + + void UpdateKeeperSpawns() + { + for (uint8 i = KEEPER_FREYA; i <= KEEPER_THORIM; i++) + { + if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i)) + { + if (!summons.HasEntry(TABLE_KEEPER_ENTRY[i])) + me->SummonCreature(TABLE_KEEPER_ENTRY[i], KeepersPos[i]); + } + else if (m_pInstance->GetData(TABLE_KEEPER_TYPE[i]) == DONE) + { + if (!summons.HasEntry(TABLE_GOSSIP_ENTRY[i])) + me->SummonCreature(TABLE_GOSSIP_ENTRY[i], GossipKeepersPos[i]); + } + } + } + + void InformCloud() + { + Creature* cloud = nullptr; + for (SummonList::const_iterator itr = summons.begin(); itr != summons.end();) + { + Creature* summon = ObjectAccessor::GetCreature(*me, *itr); + ++itr; + if (!summon || summon->GetEntry() != NPC_OMINOUS_CLOUD || me->GetDistance(summon) < 20) + continue; + + if ((!cloud || (urand(0, 1) && !summon->HasAura(SPELL_SUMMON_GUARDIAN_OF_YS)))) + cloud = summon; + } + + if (cloud) + cloud->AI()->DoAction(ACTION_START_SUMMONING); + } + + void SpawnTentacle(uint32 entry) + { + uint32 dist = urand(38, 48); + float o = rand_norm() * M_PI * 2; + float spawnX = me->GetPositionX() + dist * cos(o); + float spawnY = me->GetPositionY() + dist * std::sin(o); + float spawnZ = me->GetMap()->GetHeight(me->GetPhaseMask(), spawnX, spawnY, 330.0f); + if (Creature* cr = me->SummonCreature(entry, spawnX, spawnY, spawnZ, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000)) + { + cr->CastSpell(cr, SPELL_TENTACLE_ERUPT, true); + cr->CastSpell(cr, SPELL_VOID_ZONE_SMALL, true); + cr->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); + } + } + + void SummonDeathOrbs() + { + for (uint8 i = 0; i < 4; ++i) { uint32 dist = urand(38, 48); float o = rand_norm() * M_PI * 2; float Zplus = (dist - 38) / 6.5f; - me->SummonCreature(NPC_IMMORTAL_GUARDIAN, me->GetPositionX() + dist * cos(o), me->GetPositionY() + dist * std::sin(o), 327.2 + Zplus, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + me->SummonCreature(NPC_DEATH_ORB, me->GetPositionX() + dist * cos(o), me->GetPositionY() + dist * std::sin(o), 327.2 + Zplus, 0, TEMPSUMMON_TIMED_DESPAWN, 20000); } - - void JustDied(Unit* /*who*/) override - { - summons.DespawnAll(); - events.Reset(); - - Talk(SAY_YOGG_SARON_DEATH); - - if (m_pInstance) - { - m_pInstance->SetData(TYPE_YOGGSARON, DONE); - if (Creature* sara = ObjectAccessor::GetCreature(*me, m_pInstance->GetGuidData(NPC_SARA))) - sara->AI()->DoAction(ACTION_YOGG_SARON_DEATH); - if (GameObject* go = ObjectAccessor::GetGameObject(*me, m_pInstance->GetGuidData(GO_YOGG_SARON_DOORS))) - go->SetGoState(GO_STATE_ACTIVE); - } - - Map::PlayerList const& pList = me->GetMap()->GetPlayers(); - for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) - { - itr->GetSource()->RemoveAura(SPELL_SANITY); - itr->GetSource()->RemoveAura(SPELL_INSANE1); - itr->GetSource()->RemoveAura(SPELL_INSANE2); - } - } - - void DoAction(int32 param) override - { - if (param == ACTION_DESPAWN_ADDS) - summons.DespawnAll(); - else if (param == ACTION_YOGG_SARON_APPEAR) - { - me->SetVisible(true); - me->CastSpell(me, SPELL_SHADOW_BARRIER, true); - me->CastSpell(me, SPELL_KNOCK_AWAY, true); - me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); - me->SetInCombatWithZone(); - - me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_PACIFIED); - } - else if (param == ACTION_YOGG_SARON_START_YELL) - { - Talk(SAY_YOGG_SARON_SPAWN); - } - else if (param == ACTION_YOGG_SARON_OPEN_PORTAL_YELL) - { - Talk(SAY_YOGG_SARON_MADNESS); - Talk(EMOTE_YOGG_SARON_MADNESS); - } - else if (param == ACTION_YOGG_SARON_START_P3) - { - me->SetHealth(me->GetMaxHealth() * 0.3f); - me->LowerPlayerDamageReq(me->GetMaxHealth() * 0.7f); - - me->RemoveAura(SPELL_SHADOW_BARRIER); - - events.ScheduleEvent(EVENT_YS_LUNATIC_GAZE, 7s); - events.ScheduleEvent(EVENT_YS_SHADOW_BEACON, 20s); - events.ScheduleEvent(EVENT_YS_SUMMON_GUARDIAN, 0ms); - _thirdPhase = true; - - Talk(SAY_YOGG_SARON_PHASE_3); - } - else if (param == ACTION_YOGG_SARON_HARD_MODE) - { - events.ScheduleEvent(EVENT_YS_DEAFENING_ROAR, 50s); - } - else if (param == ACTION_YOGG_SARON_SHADOW_BEACON) - { - events.RescheduleEvent(EVENT_YS_SHADOW_BEACON, 40s); - } - else if (param == ACTION_REMOVE_STUN) - { - me->RemoveAura(SPELL_SHATTERED_ILLUSION); - me->SetControlled(true, UNIT_STATE_ROOT); - } - else if (param == ACTION_FAILED_DRIVE_ME_CRAZY) - _usedInsane = true; - } - - uint32 GetData(uint32 param) const override - { - if (param == DATA_GET_DRIVE_ME_CRAZY) - return !_usedInsane; - - return 0; - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_IN_THE_MAWS_OF_THE_OLD_GOD) - me->AddLootMode(32); - } - - void UpdateAI(uint32 diff) override - { - if (!_thirdPhase) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_YS_LUNATIC_GAZE: - me->PlayDirectSound(YS_P3_LUNATIC_GAZE); - me->CastSpell(me, SPELL_LUNATIC_GAZE_YS, true); - events.Repeat(12s); - break; - case EVENT_YS_DEAFENING_ROAR: - Talk(SAY_YOGG_SARON_DEAFENING_ROAR); - Talk(EMOTE_YOGG_SARON_DEAFENING_ROAR); - me->CastSpell(me, SPELL_DEAFENING_ROAR, false); - events.Repeat(50s); - break; - case EVENT_YS_SHADOW_BEACON: - events.Repeat(5s); - Talk(EMOTE_YOGG_SARON_EMPOWERING_SHADOWS); - me->CastCustomSpell(SPELL_SHADOW_BEACON, SPELLVALUE_MAX_TARGETS, RAID_MODE(1, 3), me, false); - break; - case EVENT_YS_SUMMON_GUARDIAN: - SummonImmortalGuardian(); - events.Repeat(10s); - break; - } - } - }; -}; - -class boss_yoggsaron_brain : public CreatureScript -{ -public: - boss_yoggsaron_brain() : CreatureScript("boss_yoggsaron_brain") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - struct boss_yoggsaron_brainAI : public NullCreatureAI + void AddPortals() { - boss_yoggsaron_brainAI(Creature* pCreature) : NullCreatureAI(pCreature), summons(pCreature) - { - me->SetDisableGravity(true); - _tentacleCount = 0; - _activeIllusion = 0; - _induceTimer = 0; - _brainDamaged = false; - me->SetRegeneratingHealth(false); - } + _summonSpeed -= 0.1f; + Creature* cr = nullptr; - bool _brainDamaged; - uint8 _tentacleCount; - uint8 _activeIllusion; - uint32 _induceTimer; - SummonList summons; - - void Reset() override { } - void JustSummoned(Creature* cr) override + // Spawn Portals + for (uint8 i = 0; i < RAID_MODE(4, 10); ++i) { - if (cr->GetEntry() == NPC_INFLUENCE_TENTACLE) + if ((cr = me->SummonCreature(NPC_DESCEND_INTO_MADNESS, yoggPortalLoc[i].x, yoggPortalLoc[i].y, yoggPortalLoc[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 25000))) { - // Dragons Illusion - if (cr->GetPositionX() > 2000.0f && cr->GetPositionX() < 2150.0f) - cr->UpdateEntry(urand(NPC_CONSORT_FIRST, NPC_CONSORT_LAST)); - // Icecrown Illusion - else if (cr->GetPositionY() > -150.0f && cr->GetPositionY() < -90.0f) - { - cr->SetStandState(UNIT_STAND_STATE_KNEEL); - cr->UpdateEntry(NPC_DEATHSWORN_ZEALOT); - } - // Stormwind Illusion - else - cr->UpdateEntry(NPC_SUIT_OF_ARMOR); + cr->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NON_ATTACKABLE); + cr->SetArmor(_currentIllusion); } - else if (cr->GetEntry() == NPC_LICH_KING) - cr->CastSpell(cr, SPELL_DEATHGRASP, false); - - summons.Summon(cr); } - void PrepareChamberIllusion() + EntryCheckPredicate pred(NPC_BRAIN_OF_YOGG_SARON); + summons.DoAction(_currentIllusion, pred); + + if (_isIllusionReversed) + _currentIllusion = _currentIllusion == 3 ? 1 : (_currentIllusion + 1); + else + _currentIllusion = _currentIllusion == 1 ? 3 : (_currentIllusion - 1); + } + + void KilledUnit(Unit* who) override + { + if (who->IsPlayer()) { - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2126.13f, -65.488f, 239.721f, 1.99171f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2141.05f, -50.5146f, 239.751f, 2.72998f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2148.83f, -23.9568f, 239.721f, 3.04807f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2064.39f, -42.0691f, 239.719f, 0.0949586f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2064.29f, -7.13128f, 239.756f, 5.96974f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2117.31f, 14.897f, 239.731f, 4.32041f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2136.7f, 2.43262f, 239.72f, 3.90023f); + Talk(SAY_SARA_KILL); + } + } - // Laughing Skulls - if (urand(0, 1)) - me->SummonCreature(NPC_LAUGHING_SKULL, 2139.13f, -59.0848f, 239.728f, 2.2974f); - else - me->SummonCreature(NPC_LAUGHING_SKULL, 2083, -25.66f, 244, 0); - if (urand(0, 1)) - me->SummonCreature(NPC_LAUGHING_SKULL, 2066.67f, -59.8984f, 239.72f, 0.718747f); - else - me->SummonCreature(NPC_LAUGHING_SKULL, 2126.22f, -25.86f, 244, 0); + void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_SANITY) + if (Aura* aur = target->GetAura(SPELL_SANITY)) + aur->SetStackAmount(100); + } - me->SummonCreature(NPC_LAUGHING_SKULL, 2133.09f, 15.341f, 239.72f, 4.0724f); - me->SummonCreature(NPC_LAUGHING_SKULL, 2065.83f, 12.3772f, 239.792f, 5.49789f); + uint32 GetData(uint32 param) const override + { + if (param == DATA_GET_KEEPERS_COUNT) + { + uint8 _count = 0; + for (uint8 i = 0; i < 4; ++i) + if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i)) + ++_count; + return _count; + } + else if (param == DATA_GET_SARA_PHASE) + return _secondPhase; - // Aspects - me->SummonCreature(NPC_ALEXTRASZA, 2091.92f, -25.8f, 242.647f, 0); - me->SummonCreature(NPC_YSERA, 2116, -25.8f, 242.647f, 3.14f); - me->SummonCreature(NPC_NELTHARION, 2103.6f, -35.8f, 242.64f, 1.5f); - me->SummonCreature(NPC_MALYGOS, 2103.6f, -15.8f, 242.64f, 4.7f); + return 4; // just to be sure, return max numer of keepers + } - // Yogg Vision - me->SummonCreature(NPC_YOGG_SARON_VISION, 2109.695f, -25.09549f, 222.3250f, 0); + void DoAction(int32 param) override + { + if (param == ACTION_SARA_UPDATE_SUMMON_KEEPERS) + { + UpdateKeeperSpawns(); + } + else if (param == ACTION_BRAIN_DAMAGED) + { + summons.DoAction(ACTION_REMOVE_STUN); + + EntryCheckPredicate pred2(NPC_YOGG_SARON); + summons.DoAction(ACTION_YOGG_SARON_START_P3, pred2); + + EntryCheckPredicate pred3(NPC_THORIM_KEEPER); + summons.DoAction(ACTION_THORIM_START_STORM, pred3); + + if (me->GetMap()->Is25ManRaid() && (GetData(DATA_GET_KEEPERS_COUNT) > 0)) + summons.DoAction(ACTION_YOGG_SARON_HARD_MODE, pred2); + + summons.DespawnEntry(NPC_DEATH_ORB); + events.SetPhase(EVENT_PHASE_THREE); + + me->RemoveAllAuras(); + me->SetVisible(false); + return; + } + else if (param == ACTION_YOGG_SARON_DEATH) + { + // Despawn everything but Yogg-Saron's corpse + summons.DoAction(ACTION_DESPAWN_ADDS); + summons.DespawnEntry(NPC_CRUSHER_TENTACLE); + summons.DespawnEntry(NPC_CONSTRICTOR_TENTACLE); + summons.DespawnEntry(NPC_CORRUPTOR_TENTACLE); + summons.DespawnEntry(NPC_VOICE_OF_YOGG_SARON); + summons.DespawnEntry(NPC_BRAIN_OF_YOGG_SARON); + summons.DespawnEntry(NPC_MIMIRON_GOSSIP); + summons.DespawnEntry(NPC_HODIR_GOSSIP); + summons.DespawnEntry(NPC_FREYA_GOSSIP); + summons.DespawnEntry(NPC_THORIM_GOSSIP); + summons.DespawnEntry(NPC_MIMIRON_KEEPER); + summons.DespawnEntry(NPC_HODIR_KEEPER); + summons.DespawnEntry(NPC_FREYA_KEEPER); + summons.DespawnEntry(NPC_THORIM_KEEPER); + summons.DespawnEntry(NPC_SANITY_WELL); + me->KillSelf(); + return; } - void PrepareIceCrownIllusion() + // Determine shatter duration + if (param <= 0) + return; + + // Illusion shatters (param - stun time) + if (Creature* yoggb = me->GetInstanceScript()->GetCreature(DATA_BRAIN_OF_YOGG_SARON)) { - // Laughing Skulls - me->SummonCreature(NPC_LAUGHING_SKULL, 1931.12f, -92.702f, 239.991f, 5.2819f); - if (urand(0, 1)) - me->SummonCreature(NPC_LAUGHING_SKULL, 1969.88f, -147.729f, 239.991f, 2.37593f); - else - me->SummonCreature(NPC_LAUGHING_SKULL, 1878, -93.3f, 240, 0); - if (urand(0, 1)) - me->SummonCreature(NPC_LAUGHING_SKULL, 1950.78f, -167.902f, 239.991f, 2.34844f); - else - me->SummonCreature(NPC_LAUGHING_SKULL, 1938.45f, -116.5f, 240, 0); - if (urand(0, 1)) - me->SummonCreature(NPC_LAUGHING_SKULL, 1896.45f, -141.469f, 239.991f, 6.12227f); - else - me->SummonCreature(NPC_LAUGHING_SKULL, 1921, -158, 240, 0); - - // Influence - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1958.29f, -128.65f, 239.99f, 3.61293f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1957.78f, -134.368f, 239.99f, 3.35375f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1953.04f, -137.843f, 239.99f, 3.55796f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1900.31f, -93.5241f, 239.99f, 4.50043f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1895.03f, -98.0773f, 239.99f, 4.88135f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1895.19f, -104.587f, 239.99f, 5.02271f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1923.31f, -125.98f, 240, 4.2f); - - // Others - me->SummonCreature(NPC_LICH_KING, 1906.98f, -153, 240, 4.2f); - me->SummonCreature(NPC_IMMOLATED_CHAMPION, 1902.03f, -161.7f, 240, 1.07f); - - // Yogg Vision - me->SummonCreature(NPC_YOGG_SARON_VISION, 1906.226f, -155.8941f, 223.4727, 0); + yoggb->AI()->Talk(EMOTE_YOGG_SARON_BRAIN_SHATTERED); } - void PrepareStormwindIllusion() + Milliseconds timer = events.GetTimeUntilEvent(EVENT_SARA_P2_OPEN_PORTALS); + Milliseconds portalTime = (timer > 0ms ? timer : 0ms); + events.DelayEvents(Milliseconds(param + 100)); + events.RescheduleEvent(EVENT_SARA_P2_OPEN_PORTALS, portalTime, 0, EVENT_PHASE_TWO); + events.ScheduleEvent(EVENT_SARA_P2_REMOVE_STUN, Milliseconds(param), 0, EVENT_PHASE_TWO); + me->CastSpell(me, SPELL_SHATTERED_ILLUSION, true); + } + + void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (who && who->GetEntry() == NPC_GUARDIAN_OF_YS && !_secondPhase) { - // Laughing Skulls - if (urand(0, 1)) - me->SummonCreature(NPC_LAUGHING_SKULL, 1916.36f, 28.05f, 239.666f, 1.30238f); - else - me->SummonCreature(NPC_LAUGHING_SKULL, 1966.7f, 57.8f, 239.66f, 0); - if (urand(0, 1)) - me->SummonCreature(NPC_LAUGHING_SKULL, 1902, 75.1362f, 239.666f, 6.06189f); - else - me->SummonCreature(NPC_LAUGHING_SKULL, 1933, 91, 240, 0); - me->SummonCreature(NPC_LAUGHING_SKULL, 1914.42f, 90.8465f, 239.666f, 5.25294f); - me->SummonCreature(NPC_LAUGHING_SKULL, 1963.68f, 89.7549f, 239.667f, 3.70571f); + damage = 25000; - // Influence - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1931.41f, 39.0711f, 239.66f, 1.82467f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1908.67f, 45.5867f, 239.666f, 0.72119f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1897.68f, 66.1274f, 239.666f, 6.27395f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1950.73f, 49.3446f, 239.666f, 2.63756f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1923.16f, 97.5586f, 239.666f, 4.74635f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1956.16f, 72.1403f, 239.666f, 3.19518f); - me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1944.81f, 92.3154f, 239.666f, 4.03556f); - - // Others - me->SummonCreature(NPC_GARONA, 1928.58f, 65.64f, 242.37f, 2.1f); - me->SummonCreature(NPC_KING_LLANE, 1925.14f, 71.74f, 242.37f, 5.17f); - - // Yogg Vision - me->SummonCreature(NPC_YOGG_SARON_VISION, 1929.160f, 67.75694f, 221.7322f, 0); - } - - void DoAction(int32 param) override - { - if (param == ACTION_DESPAWN_ADDS) - { - summons.DespawnAll(); - return; - } - else if (param == ACTION_INFLUENCE_TENTACLE_DIED) - { - _tentacleCount++; - if (_tentacleCount >= 7 /*TENTACLES COUNT*/) - { - // Stun - if (me->GetInstanceScript()) - if (Creature* sara = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(NPC_SARA))) - sara->AI()->DoAction(MINUTE * IN_MILLISECONDS - std::min((uint32)MINUTE * IN_MILLISECONDS, _induceTimer)); - - _induceTimer = 0; - summons.DespawnEntry(NPC_LAUGHING_SKULL); - if (GameObject* go = me->FindNearestGameObject(GO_CHAMBER_ILLUSION_DOORS + _activeIllusion, 150.0f)) - go->SetGoState(GO_STATE_ACTIVE); - } - return; - } - else if (param == ACTION_REMOVE_STUN) - return; - - summons.DespawnAll(); - switch (param) - { - case ACTION_ILLUSION_STORMWIND: - PrepareStormwindIllusion(); - break; - case ACTION_ILLUSION_DRAGONS: - PrepareChamberIllusion(); - break; - case ACTION_ILLUSION_ICECROWN: - PrepareIceCrownIllusion(); - break; - } - - for (uint32 i = GO_CHAMBER_ILLUSION_DOORS; i <= GO_STORMWIND_ILLUSION_DOORS; ++i) - if (GameObject* go = me->FindNearestGameObject(i, 150.0f)) - go->SetGoState(GO_STATE_READY); - - _activeIllusion = param - 1; - _tentacleCount = 0; - _induceTimer = 1; - - me->CastSpell(me, SPELL_INDUCE_MADNESS, false); - } - - uint32 GetData(uint32 param) const override - { - if (param == DATA_GET_CURRENT_ILLUSION) - return _activeIllusion + 1; - - return 0; - } - - void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (_tentacleCount < 7) // if all tentacles aren't killed + // START PHASE 2 + if (me->GetHealth() <= damage) { + _secondPhase = true; damage = 0; - if (who) - Unit::Kill(who, who); - return; + + events.SetPhase(EVENT_PHASE_TWO); + me->SetHealth(me->GetMaxHealth()); + + if (Creature* cr = me->SummonCreature(NPC_YOGG_SARON, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), M_PI)) + cr->SetVisible(false); + + _p2TalkTimer++; + Talk(SAY_SARA_TRANSFORM_1); } + return; + } - if (!_brainDamaged) + damage = 0; + } + + void UpdateAI(uint32 diff) override + { + if (_initFight) + { + _initFight += diff; + if (_initFight > 5000) { - // START PHASE 3 - if (me->HealthBelowPctDamaged(30, damage)) + if (Unit* target = SelectTargetFromPlayerList(90)) { - me->SetRegeneratingHealth(false); - _EnterEvadeMode(); - _brainDamaged = true; - - me->CastSpell(me, SPELL_BRAIN_HURT_VISUAL, true); - if (me->GetInstanceScript()) - if (Creature* sara = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(NPC_SARA))) - sara->AI()->DoAction(ACTION_BRAIN_DAMAGED); + _initFight = 0; + InitFight(target); } - } - } - - void UpdateAI(uint32 diff) override - { - if (_induceTimer) - _induceTimer += diff; - } - }; -}; - -class boss_yoggsaron_death_orb : public CreatureScript -{ -public: - boss_yoggsaron_death_orb() : CreatureScript("boss_yoggsaron_death_orb") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_yoggsaron_death_orbAI : public NullCreatureAI - { - boss_yoggsaron_death_orbAI(Creature* pCreature) : NullCreatureAI(pCreature) - { - me->CastSpell(me, SPELL_DEATH_RAY_WARNING, true); - _startTimer = 1; - } - - uint32 _startTimer; - - void UpdateAI(uint32 diff) override - { - if (_startTimer) - { - _startTimer += diff; - if (_startTimer > 4000) - { - me->CastSpell(me, SPELL_DEATH_RAY_DAMAGE_VISUAL, true); - me->CastSpell(me, SPELL_DEATH_RAY_DAMAGE, true); - - _startTimer = 0; - me->SetSpeed(MOVE_WALK, 2); - me->SetSpeed(MOVE_RUN, 2); - me->GetMotionMaster()->MoveRandom(20.0f); - } - } - } - }; -}; - -class boss_yoggsaron_crusher_tentacle : public CreatureScript -{ -public: - boss_yoggsaron_crusher_tentacle() : CreatureScript("boss_yoggsaron_crusher_tentacle") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_yoggsaron_crusher_tentacleAI : public ScriptedAI - { - boss_yoggsaron_crusher_tentacleAI(Creature* pCreature) : ScriptedAI(pCreature) - { - me->SetCombatMovement(false); - me->CastSpell(me, SPELL_CRUSH, true); - me->CastSpell(me, SPELL_FOCUSED_ANGER, true); - me->CastSpell(me, SPELL_DIMINISH_POWER, false); - } - - void Reset() override - { - me->SetInCombatWithZone(); - } - - void DamageTaken(Unit* who, uint32&, DamageEffectType damagetype, SpellSchoolMask) override - { - if (who && damagetype == DIRECT_DAMAGE) - { - DoResetThreatList(); - me->AddThreat(who, 100000); - AttackStart(who); - me->InterruptNonMeleeSpells(false); - } - } - - void DoAction(int32 param) override - { - if (param == ACTION_REMOVE_STUN) - me->RemoveAura(SPELL_SHATTERED_ILLUSION); - } - - void UpdateAI(uint32 /*diff*/) override - { - if (!UpdateVictim()) - return; - - if (me->IsWithinMeleeRange(me->GetVictim())) - { - DoMeleeAttackIfReady(); - return; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - me->CastSpell(me, SPELL_DIMINISH_POWER, false); - DoResetThreatList(); - } - }; -}; - -class boss_yoggsaron_corruptor_tentacle : public CreatureScript -{ -public: - boss_yoggsaron_corruptor_tentacle() : CreatureScript("boss_yoggsaron_corruptor_tentacle") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_yoggsaron_corruptor_tentacleAI : public ScriptedAI - { - boss_yoggsaron_corruptor_tentacleAI(Creature* pCreature) : ScriptedAI(pCreature) - { - me->SetCombatMovement(false); - } - - void DoAction(int32 param) override - { - if (param == ACTION_REMOVE_STUN) - me->RemoveAura(SPELL_SHATTERED_ILLUSION); - } - - Unit* SelectCorruptionTarget() - { - Player* target = nullptr; - Map::PlayerList const& pList = me->GetMap()->GetPlayers(); - uint8 num = urand(0, pList.getSize() - 1); - uint8 count = 0; - for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr, ++count) - { - if (me->GetDistance(itr->GetSource()) > 200 || itr->GetSource()->GetPositionZ() < 300 || !itr->GetSource()->IsAlive() || itr->GetSource()->IsGameMaster()) - continue; - - if (count <= num || !target) - target = itr->GetSource(); else - break; + _initFight = 1; } - - return target; + return; } - void UpdateAI(uint32 /*diff*/) override + if (!SelectTargetFromPlayerList(90, SPELL_INSANE1)) { - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_INSANE1); + EnterEvadeMode(EVADE_REASON_OTHER); + return; + } - if (Unit* target = SelectCorruptionTarget()) + if (_p2TalkTimer) + { + _p2TalkTimer += diff; + if (_p2TalkTimer >= 4000 && _p2TalkTimer < 20000) { - uint32 spellid = RAND(SPELL_APATHY, SPELL_BLACK_PLAGUE, SPELL_DRAINING_POISON, SPELL_CURSE_OF_DOOM); - me->CastSpell(target, spellid, false); + EntryCheckPredicate pred(NPC_OMINOUS_CLOUD); + summons.DoAction(ACTION_UNSUMMON_CLOUDS, pred); + Talk(SAY_SARA_TRANSFORM_2); + _p2TalkTimer = 20000; } - } - }; -}; - -class boss_yoggsaron_constrictor_tentacle : public CreatureScript -{ -public: - boss_yoggsaron_constrictor_tentacle() : CreatureScript("boss_yoggsaron_constrictor_tentacle") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_yoggsaron_constrictor_tentacleAI : public ScriptedAI - { - boss_yoggsaron_constrictor_tentacleAI(Creature* pCreature) : ScriptedAI(pCreature) - { - me->SetCombatMovement(false); - _checkTimer = 1; - _playerGUID.Clear(); - } - - uint32 _checkTimer; - ObjectGuid _playerGUID; - - Unit* SelectConstrictTarget() - { - Player* target = nullptr; - Map::PlayerList const& pList = me->GetMap()->GetPlayers(); - uint8 num = urand(0, pList.getSize() - 1); - uint8 count = 0; - for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr, ++count) + else if (_p2TalkTimer >= 25000 && _p2TalkTimer < 40000) { - if (me->GetDistance(itr->GetSource()) > 10 || !itr->GetSource()->IsAlive() || itr->GetSource()->IsGameMaster()) - continue; - if (itr->GetSource()->HasAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_SQUEEZE, me)) || itr->GetSource()->HasAura(SPELL_INSANE1)) - continue; - - if (count <= num || !target) - target = itr->GetSource(); - else - break; + summons.DespawnEntry(NPC_OMINOUS_CLOUD); + Talk(SAY_SARA_TRANSFORM_3); + _p2TalkTimer = 40000; } - - return target; + else if (_p2TalkTimer >= 44500 && _p2TalkTimer < 60000) + { + Talk(SAY_SARA_TRANSFORM_4); + _p2TalkTimer = 60000; + } + else if (_p2TalkTimer >= 64000) + { + EntryCheckPredicate pred(NPC_YOGG_SARON); + summons.DoAction(ACTION_YOGG_SARON_START_YELL, pred); + _p2TalkTimer = 0; + events.ScheduleEvent(EVENT_SARA_P2_START, 500ms, 0, EVENT_PHASE_TWO); + } + return; } - void UpdateAI(uint32 diff) override + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - if (_checkTimer) - { - _checkTimer += diff; - if (_checkTimer >= 1000 && !me->HasUnitState(UNIT_STATE_STUNNED)) + case EVENT_SARA_P1_DOORS_CLOSE: + // Whispers of YS + me->SummonCreature(NPC_VOICE_OF_YOGG_SARON, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + + if (m_pInstance) + if (GameObject* go = m_pInstance->GetGameObject(DATA_YOGG_SARON_DOORS)) + go->SetGoState(GO_STATE_READY); + + events.ScheduleEvent(EVENT_SARA_P1_SPELLS, 0ms, 1, EVENT_PHASE_ONE); + break; + case EVENT_SARA_P1_SUMMON: + events.Repeat(Milliseconds(20000 - (std::min(_summonedGuardiansCount, (uint8)5) * 2000))); + ++_summonedGuardiansCount; + InformCloud(); + break; + case EVENT_SARA_P1_SPELLS: { - if (Unit* target = SelectConstrictTarget()) + uint32 spell = RAND(SPELL_SARAS_ANGER_TARGET_SELECTOR, SPELL_SARAS_BLESSING_TARGET_SELECTOR, SPELL_SARAS_FAVOR_TARGET_SELECTOR); + if (urand(0, 2)) { - target->CastSpell(me, SPELL_LUNGE, true); - target->CastSpell(target, SPELL_SQUEEZE, true); - _playerGUID = target->GetGUID(); - _checkTimer = 0; - return; + if (spell == SPELL_SARAS_ANGER_TARGET_SELECTOR) + { + Talk(SAY_SARA_ANGER); + } + else if (spell == SPELL_SARAS_FAVOR_TARGET_SELECTOR) + { + Talk(SAY_SARA_FERVOR_HIT); + } } - _checkTimer = 1; + me->CastCustomSpell(spell, SPELLVALUE_MAX_TARGETS, 1, nullptr, false); + events.Repeat(me->GetMap()->Is25ManRaid() ? randtime(0ms, 3s) : randtime(4s, 6s)); + break; } + case EVENT_SARA_P2_START: + { + EntryCheckPredicate pred(NPC_YOGG_SARON); + summons.DoAction(ACTION_YOGG_SARON_APPEAR, pred); + events.RescheduleEvent(EVENT_SARA_P2_SPAWN_START_TENTACLES, 500ms, 0, EVENT_PHASE_TWO); + + // Spawn Brain! + me->SummonCreature(NPC_BRAIN_OF_YOGG_SARON, 1981.3f, -25.43f, 265); + break; + } + case EVENT_SARA_P2_MALADY: + me->CastCustomSpell(SPELL_MALADY_OF_THE_MIND, SPELLVALUE_MAX_TARGETS, 1, me, false); + events.Repeat(20s); + break; + case EVENT_SARA_P2_PSYCHOSIS: + if ((urand(0, 9)) == 0) // Rarely said (as it's casted every 3.5s) + { + Talk(SAY_SARA_PSYCHOSIS_HIT); + } + me->CastCustomSpell(SPELL_SARA_PSYCHOSIS_10, SPELLVALUE_MAX_TARGETS, 1, me, false); + events.Repeat(3500ms); + break; + case EVENT_SARA_P2_DEATH_RAY: + Talk(SAY_SARA_DEATH_RAY); + SummonDeathOrbs(); + events.Repeat(20s); + break; + case EVENT_SARA_P2_SUMMON_T1: // CRUSHER + SpawnTentacle(NPC_CRUSHER_TENTACLE); + events.Repeat(Milliseconds(uint32((50000 + urand(0, 10000)) * _summonSpeed))); + break; + case EVENT_SARA_P2_SUMMON_T2: // CONSTRICTOR + SpawnTentacle(NPC_CONSTRICTOR_TENTACLE); + events.Repeat(Milliseconds(uint32((15000 + urand(0, 5000))* _summonSpeed))); + break; + case EVENT_SARA_P2_SUMMON_T3: // CORRUPTOR + SpawnTentacle(NPC_CORRUPTOR_TENTACLE); + events.Repeat(Milliseconds(uint32((30000 + urand(0, 10000))* _summonSpeed))); + break; + case EVENT_SARA_P2_BRAIN_LINK: + me->CastCustomSpell(SPELL_BRAIN_LINK, SPELLVALUE_MAX_TARGETS, 1, me, false); + events.Repeat(30s); + break; + case EVENT_SARA_P2_OPEN_PORTALS: + { + AddPortals(); + EntryCheckPredicate pred(NPC_YOGG_SARON); + summons.DoAction(ACTION_YOGG_SARON_OPEN_PORTAL_YELL, pred); + events.Repeat(80s); + break; + } + case EVENT_SARA_P2_REMOVE_STUN: + { + me->RemoveAura(SPELL_SHATTERED_ILLUSION); + summons.DoAction(ACTION_REMOVE_STUN); + break; + } + case EVENT_SARA_P2_SPAWN_START_TENTACLES: + me->SetOrientation(M_PI); + me->SetDisplayId(SARA_TRANSFORM_MODEL); + + me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), 355, me->GetOrientation()); + me->SetPosition(me->GetPositionX(), me->GetPositionY(), 355, me->GetOrientation()); + + SpawnTentacle(NPC_CRUSHER_TENTACLE); + SpawnTentacle(NPC_CONSTRICTOR_TENTACLE); + SpawnTentacle(NPC_CORRUPTOR_TENTACLE); + SpawnTentacle(NPC_CORRUPTOR_TENTACLE); + + events.ScheduleEvent(EVENT_SARA_P2_MALADY, 7s, 0, EVENT_PHASE_TWO); + events.ScheduleEvent(EVENT_SARA_P2_PSYCHOSIS, 3s, 0, EVENT_PHASE_TWO); + events.ScheduleEvent(EVENT_SARA_P2_DEATH_RAY, 15s, 0, EVENT_PHASE_TWO); + events.ScheduleEvent(EVENT_SARA_P2_SUMMON_T1, 50s, 60s, 0, EVENT_PHASE_TWO); + events.ScheduleEvent(EVENT_SARA_P2_SUMMON_T2, 15s, 20s, 0, EVENT_PHASE_TWO); + events.ScheduleEvent(EVENT_SARA_P2_SUMMON_T3, 30s + randtime(0ms, 10s), 0, EVENT_PHASE_TWO); + events.ScheduleEvent(EVENT_SARA_P2_BRAIN_LINK, 0ms, 0, EVENT_PHASE_TWO); + events.ScheduleEvent(EVENT_SARA_P2_OPEN_PORTALS, 60s, 0, EVENT_PHASE_TWO); + break; + case EVENT_SARA_P1_BERSERK: + if (me->GetInstanceScript()) + { + if (Creature* yogg = me->GetInstanceScript()->GetCreature(BOSS_YOGGSARON)) + { + yogg->AI()->Talk(EMOTE_YOGG_SARON_BERSERK); + } + } + me->CastSpell(me, SPELL_EXTINGUISH_ALL_LIFE, true); + events.Repeat(5s); + break; + } + } +}; + +struct boss_yoggsaron_cloud : public npc_escortAI +{ + boss_yoggsaron_cloud(Creature* pCreature) : npc_escortAI(pCreature) + { + InitWaypoint(); + Reset(); + Start(false, ObjectGuid::Empty, nullptr, false, true); + } + + uint32 _checkTimer; + bool _isSummoning; + + void JustSummoned(Creature* cr) override + { + cr->ToTempSummon()->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN); + + _isSummoning = false; + if (me->GetInstanceScript()) + if (Creature* sara = me->GetInstanceScript()->GetCreature(DATA_SARA)) + sara->AI()->JustSummoned(cr); + } + + void MoveInLineOfSight(Unit* /*who*/) override {} + void AttackStart(Unit* /*who*/) override {} + void WaypointReached(uint32 /*point*/) override {} + + void Reset() override + { + me->CastSpell(me, SPELL_CLOUD_VISUAL, true); + _checkTimer = 0; + _isSummoning = false; + } + + void DoAction(int32 param) override + { + if (param == ACTION_UNSUMMON_CLOUDS) + { + me->RemoveAllAuras(); + } + else if (param == ACTION_START_SUMMONING) + { + _isSummoning = true; + me->CastSpell(me, SPELL_SUMMON_GUARDIAN_OF_YS, true); + } + } + + void InitWaypoint() + { + float dist = Middle.GetExactDist(me); + if (me->GetPositionX() > Middle.GetPositionX()) + { + for (uint8 i = 0; i <= dist; ++i) + { + float angle = M_PI * 2 / dist * i; + AddWaypoint(i, Middle.GetPositionX() + dist * cos(angle), Middle.GetPositionY() + dist * std::sin(angle), me->GetPositionZ(), 0); } } - - void DoAction(int32 param) override + else { - if (param == ACTION_REMOVE_STUN) - me->RemoveAura(SPELL_SHATTERED_ILLUSION); + for (uint8 i = 0; i <= dist; ++i) + { + float angle = M_PI * 2 - (M_PI * 2 / dist * i); + AddWaypoint(i, Middle.GetPositionX() + dist * cos(angle), Middle.GetPositionY() + dist * std::sin(angle), me->GetPositionZ(), 0); + } + } + } + + void UpdateEscortAI(uint32 diff) override + { + _checkTimer += diff; + if (_checkTimer >= 500 && !_isSummoning) + { + Unit* who = me->SelectNearbyTarget(nullptr, 6.0f); + if (who && who->IsPlayer() && !me->HasAura(SPELL_SUMMON_GUARDIAN_OF_YS) && !who->HasAura(SPELL_HODIR_FLASH_FREEZE)) + { + _isSummoning = true; + Talk(0, who); + me->CastSpell(me, SPELL_SUMMON_GUARDIAN_OF_YS, true); + } + + _checkTimer = 0; + } + } +}; + +struct boss_yoggsaron_guardian_of_ys : public ScriptedAI +{ + boss_yoggsaron_guardian_of_ys(Creature* pCreature) : ScriptedAI(pCreature) { } + + uint32 _spellTimer; + + void Reset() override + { + _spellTimer = 0; + me->SetInCombatWithZone(); + } + + void JustDied(Unit*) override + { + me->CastSpell((Unit*)nullptr, SPELL_SHADOW_NOVA, true); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _spellTimer += diff; + if (_spellTimer > 8000) + { + me->CastSpell(me, SPELL_DARK_VOLLEY, false); + _spellTimer = 0; } - void JustDied(Unit*) override + DoMeleeAttackIfReady(); + } +}; + +struct boss_yoggsaron : public ScriptedAI +{ + boss_yoggsaron(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature) + { + m_pInstance = me->GetInstanceScript(); + _thirdPhase = false; + _usedInsane = false; + summons.DespawnAll(); + events.Reset(); + + uint8 _count = 4; + me->SetLootMode(31); // 1 + 2 + 4 + 8 + 16, remove with watchers addition + if (m_pInstance) { - if (Unit* player = ObjectAccessor::GetUnit(*me, _playerGUID)) - player->RemoveAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_SQUEEZE, me)); + for (uint8 i = 0; i < 4; ++i) + if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i)) + { + me->RemoveLootMode(1 << _count); + --_count; + } } - }; + } + + InstanceScript* m_pInstance; + EventMap events; + SummonList summons; + bool _thirdPhase; + bool _usedInsane; + + void AttackStart(Unit*) override { } + + void JustSummoned(Creature* cr) override { summons.Summon(cr); } + + void SummonImmortalGuardian() + { + uint32 dist = urand(38, 48); + float o = rand_norm() * M_PI * 2; + float Zplus = (dist - 38) / 6.5f; + me->SummonCreature(NPC_IMMORTAL_GUARDIAN, me->GetPositionX() + dist * cos(o), me->GetPositionY() + dist * std::sin(o), 327.2 + Zplus, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + } + + void JustDied(Unit* /*who*/) override + { + summons.DespawnAll(); + events.Reset(); + + Talk(SAY_YOGG_SARON_DEATH); + + if (m_pInstance) + { + m_pInstance->SetData(BOSS_YOGGSARON, DONE); + if (Creature* sara = m_pInstance->GetCreature(DATA_SARA)) + sara->AI()->DoAction(ACTION_YOGG_SARON_DEATH); + if (GameObject* go = m_pInstance->GetGameObject(DATA_YOGG_SARON_DOORS)) + go->SetGoState(GO_STATE_ACTIVE); + } + + Map::PlayerList const& pList = me->GetMap()->GetPlayers(); + for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) + { + itr->GetSource()->RemoveAura(SPELL_SANITY); + itr->GetSource()->RemoveAura(SPELL_INSANE1); + itr->GetSource()->RemoveAura(SPELL_INSANE2); + } + } + + void DoAction(int32 param) override + { + if (param == ACTION_DESPAWN_ADDS) + summons.DespawnAll(); + else if (param == ACTION_YOGG_SARON_APPEAR) + { + me->SetVisible(true); + me->CastSpell(me, SPELL_SHADOW_BARRIER, true); + me->CastSpell(me, SPELL_KNOCK_AWAY, true); + me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); + me->SetInCombatWithZone(); + + me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_PACIFIED); + } + else if (param == ACTION_YOGG_SARON_START_YELL) + { + Talk(SAY_YOGG_SARON_SPAWN); + } + else if (param == ACTION_YOGG_SARON_OPEN_PORTAL_YELL) + { + Talk(SAY_YOGG_SARON_MADNESS); + Talk(EMOTE_YOGG_SARON_MADNESS); + } + else if (param == ACTION_YOGG_SARON_START_P3) + { + me->SetHealth(me->GetMaxHealth() * 0.3f); + me->LowerPlayerDamageReq(me->GetMaxHealth() * 0.7f); + + me->RemoveAura(SPELL_SHADOW_BARRIER); + + events.ScheduleEvent(EVENT_YS_LUNATIC_GAZE, 7s); + events.ScheduleEvent(EVENT_YS_SHADOW_BEACON, 20s); + events.ScheduleEvent(EVENT_YS_SUMMON_GUARDIAN, 0ms); + _thirdPhase = true; + + Talk(SAY_YOGG_SARON_PHASE_3); + } + else if (param == ACTION_YOGG_SARON_HARD_MODE) + { + events.ScheduleEvent(EVENT_YS_DEAFENING_ROAR, 50s); + } + else if (param == ACTION_YOGG_SARON_SHADOW_BEACON) + { + events.RescheduleEvent(EVENT_YS_SHADOW_BEACON, 40s); + } + else if (param == ACTION_REMOVE_STUN) + { + me->RemoveAura(SPELL_SHATTERED_ILLUSION); + me->SetControlled(true, UNIT_STATE_ROOT); + } + else if (param == ACTION_FAILED_DRIVE_ME_CRAZY) + _usedInsane = true; + } + + uint32 GetData(uint32 param) const override + { + if (param == DATA_GET_DRIVE_ME_CRAZY) + return !_usedInsane; + + return 0; + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_IN_THE_MAWS_OF_THE_OLD_GOD) + me->AddLootMode(32); + } + + void UpdateAI(uint32 diff) override + { + if (!_thirdPhase) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_YS_LUNATIC_GAZE: + me->PlayDirectSound(YS_P3_LUNATIC_GAZE); + me->CastSpell(me, SPELL_LUNATIC_GAZE_YS, true); + events.Repeat(12s); + break; + case EVENT_YS_DEAFENING_ROAR: + Talk(SAY_YOGG_SARON_DEAFENING_ROAR); + Talk(EMOTE_YOGG_SARON_DEAFENING_ROAR); + me->CastSpell(me, SPELL_DEAFENING_ROAR, false); + events.Repeat(50s); + break; + case EVENT_YS_SHADOW_BEACON: + events.Repeat(5s); + Talk(EMOTE_YOGG_SARON_EMPOWERING_SHADOWS); + me->CastCustomSpell(SPELL_SHADOW_BEACON, SPELLVALUE_MAX_TARGETS, RAID_MODE(1, 3), me, false); + break; + case EVENT_YS_SUMMON_GUARDIAN: + SummonImmortalGuardian(); + events.Repeat(10s); + break; + } + } +}; + +struct boss_yoggsaron_brain : public NullCreatureAI +{ + boss_yoggsaron_brain(Creature* pCreature) : NullCreatureAI(pCreature), summons(pCreature) + { + me->SetDisableGravity(true); + _tentacleCount = 0; + _activeIllusion = 0; + _induceTimer = 0; + _brainDamaged = false; + me->SetRegeneratingHealth(false); + } + + bool _brainDamaged; + uint8 _tentacleCount; + uint8 _activeIllusion; + uint32 _induceTimer; + SummonList summons; + + void Reset() override { } + void JustSummoned(Creature* cr) override + { + if (cr->GetEntry() == NPC_INFLUENCE_TENTACLE) + { + // Dragons Illusion + if (cr->GetPositionX() > 2000.0f && cr->GetPositionX() < 2150.0f) + cr->UpdateEntry(urand(NPC_CONSORT_FIRST, NPC_CONSORT_LAST)); + // Icecrown Illusion + else if (cr->GetPositionY() > -150.0f && cr->GetPositionY() < -90.0f) + { + cr->SetStandState(UNIT_STAND_STATE_KNEEL); + cr->UpdateEntry(NPC_DEATHSWORN_ZEALOT); + } + // Stormwind Illusion + else + cr->UpdateEntry(NPC_SUIT_OF_ARMOR); + } + else if (cr->GetEntry() == NPC_LICH_KING) + cr->CastSpell(cr, SPELL_DEATHGRASP, false); + + summons.Summon(cr); + } + + void PrepareChamberIllusion() + { + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2126.13f, -65.488f, 239.721f, 1.99171f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2141.05f, -50.5146f, 239.751f, 2.72998f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2148.83f, -23.9568f, 239.721f, 3.04807f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2064.39f, -42.0691f, 239.719f, 0.0949586f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2064.29f, -7.13128f, 239.756f, 5.96974f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2117.31f, 14.897f, 239.731f, 4.32041f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 2136.7f, 2.43262f, 239.72f, 3.90023f); + + // Laughing Skulls + if (urand(0, 1)) + me->SummonCreature(NPC_LAUGHING_SKULL, 2139.13f, -59.0848f, 239.728f, 2.2974f); + else + me->SummonCreature(NPC_LAUGHING_SKULL, 2083, -25.66f, 244, 0); + if (urand(0, 1)) + me->SummonCreature(NPC_LAUGHING_SKULL, 2066.67f, -59.8984f, 239.72f, 0.718747f); + else + me->SummonCreature(NPC_LAUGHING_SKULL, 2126.22f, -25.86f, 244, 0); + + me->SummonCreature(NPC_LAUGHING_SKULL, 2133.09f, 15.341f, 239.72f, 4.0724f); + me->SummonCreature(NPC_LAUGHING_SKULL, 2065.83f, 12.3772f, 239.792f, 5.49789f); + + // Aspects + me->SummonCreature(NPC_ALEXTRASZA, 2091.92f, -25.8f, 242.647f, 0); + me->SummonCreature(NPC_YSERA, 2116, -25.8f, 242.647f, 3.14f); + me->SummonCreature(NPC_NELTHARION, 2103.6f, -35.8f, 242.64f, 1.5f); + me->SummonCreature(NPC_MALYGOS, 2103.6f, -15.8f, 242.64f, 4.7f); + + // Yogg Vision + me->SummonCreature(NPC_YOGG_SARON_VISION, 2109.695f, -25.09549f, 222.3250f, 0); + } + + void PrepareIceCrownIllusion() + { + // Laughing Skulls + me->SummonCreature(NPC_LAUGHING_SKULL, 1931.12f, -92.702f, 239.991f, 5.2819f); + if (urand(0, 1)) + me->SummonCreature(NPC_LAUGHING_SKULL, 1969.88f, -147.729f, 239.991f, 2.37593f); + else + me->SummonCreature(NPC_LAUGHING_SKULL, 1878, -93.3f, 240, 0); + if (urand(0, 1)) + me->SummonCreature(NPC_LAUGHING_SKULL, 1950.78f, -167.902f, 239.991f, 2.34844f); + else + me->SummonCreature(NPC_LAUGHING_SKULL, 1938.45f, -116.5f, 240, 0); + if (urand(0, 1)) + me->SummonCreature(NPC_LAUGHING_SKULL, 1896.45f, -141.469f, 239.991f, 6.12227f); + else + me->SummonCreature(NPC_LAUGHING_SKULL, 1921, -158, 240, 0); + + // Influence + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1958.29f, -128.65f, 239.99f, 3.61293f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1957.78f, -134.368f, 239.99f, 3.35375f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1953.04f, -137.843f, 239.99f, 3.55796f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1900.31f, -93.5241f, 239.99f, 4.50043f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1895.03f, -98.0773f, 239.99f, 4.88135f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1895.19f, -104.587f, 239.99f, 5.02271f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1923.31f, -125.98f, 240, 4.2f); + + // Others + me->SummonCreature(NPC_LICH_KING, 1906.98f, -153, 240, 4.2f); + me->SummonCreature(NPC_IMMOLATED_CHAMPION, 1902.03f, -161.7f, 240, 1.07f); + + // Yogg Vision + me->SummonCreature(NPC_YOGG_SARON_VISION, 1906.226f, -155.8941f, 223.4727, 0); + } + + void PrepareStormwindIllusion() + { + // Laughing Skulls + if (urand(0, 1)) + me->SummonCreature(NPC_LAUGHING_SKULL, 1916.36f, 28.05f, 239.666f, 1.30238f); + else + me->SummonCreature(NPC_LAUGHING_SKULL, 1966.7f, 57.8f, 239.66f, 0); + if (urand(0, 1)) + me->SummonCreature(NPC_LAUGHING_SKULL, 1902, 75.1362f, 239.666f, 6.06189f); + else + me->SummonCreature(NPC_LAUGHING_SKULL, 1933, 91, 240, 0); + me->SummonCreature(NPC_LAUGHING_SKULL, 1914.42f, 90.8465f, 239.666f, 5.25294f); + me->SummonCreature(NPC_LAUGHING_SKULL, 1963.68f, 89.7549f, 239.667f, 3.70571f); + + // Influence + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1931.41f, 39.0711f, 239.66f, 1.82467f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1908.67f, 45.5867f, 239.666f, 0.72119f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1897.68f, 66.1274f, 239.666f, 6.27395f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1950.73f, 49.3446f, 239.666f, 2.63756f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1923.16f, 97.5586f, 239.666f, 4.74635f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1956.16f, 72.1403f, 239.666f, 3.19518f); + me->SummonCreature(NPC_INFLUENCE_TENTACLE, 1944.81f, 92.3154f, 239.666f, 4.03556f); + + // Others + me->SummonCreature(NPC_GARONA, 1928.58f, 65.64f, 242.37f, 2.1f); + me->SummonCreature(NPC_KING_LLANE, 1925.14f, 71.74f, 242.37f, 5.17f); + + // Yogg Vision + me->SummonCreature(NPC_YOGG_SARON_VISION, 1929.160f, 67.75694f, 221.7322f, 0); + } + + void DoAction(int32 param) override + { + if (param == ACTION_DESPAWN_ADDS) + { + summons.DespawnAll(); + return; + } + else if (param == ACTION_INFLUENCE_TENTACLE_DIED) + { + _tentacleCount++; + if (_tentacleCount >= 7 /*TENTACLES COUNT*/) + { + // Stun + if (me->GetInstanceScript()) + if (Creature* sara = me->GetInstanceScript()->GetCreature(DATA_SARA)) + sara->AI()->DoAction(MINUTE * IN_MILLISECONDS - std::min((uint32)MINUTE * IN_MILLISECONDS, _induceTimer)); + + _induceTimer = 0; + summons.DespawnEntry(NPC_LAUGHING_SKULL); + if (GameObject* go = me->FindNearestGameObject(GO_CHAMBER_ILLUSION_DOORS + _activeIllusion, 150.0f)) + go->SetGoState(GO_STATE_ACTIVE); + } + return; + } + else if (param == ACTION_REMOVE_STUN) + return; + + summons.DespawnAll(); + switch (param) + { + case ACTION_ILLUSION_STORMWIND: + PrepareStormwindIllusion(); + break; + case ACTION_ILLUSION_DRAGONS: + PrepareChamberIllusion(); + break; + case ACTION_ILLUSION_ICECROWN: + PrepareIceCrownIllusion(); + break; + } + + for (uint32 i = GO_CHAMBER_ILLUSION_DOORS; i <= GO_STORMWIND_ILLUSION_DOORS; ++i) + if (GameObject* go = me->FindNearestGameObject(i, 150.0f)) + go->SetGoState(GO_STATE_READY); + + _activeIllusion = param - 1; + _tentacleCount = 0; + _induceTimer = 1; + + me->CastSpell(me, SPELL_INDUCE_MADNESS, false); + } + + uint32 GetData(uint32 param) const override + { + if (param == DATA_GET_CURRENT_ILLUSION) + return _activeIllusion + 1; + + return 0; + } + + void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (_tentacleCount < 7) // if all tentacles aren't killed + { + damage = 0; + if (who) + Unit::Kill(who, who); + return; + } + + if (!_brainDamaged) + { + // START PHASE 3 + if (me->HealthBelowPctDamaged(30, damage)) + { + me->SetRegeneratingHealth(false); + _EnterEvadeMode(); + _brainDamaged = true; + + me->CastSpell(me, SPELL_BRAIN_HURT_VISUAL, true); + if (me->GetInstanceScript()) + if (Creature* sara = me->GetInstanceScript()->GetCreature(DATA_SARA)) + sara->AI()->DoAction(ACTION_BRAIN_DAMAGED); + } + } + } + + void UpdateAI(uint32 diff) override + { + if (_induceTimer) + _induceTimer += diff; + } +}; + +struct boss_yoggsaron_death_orb : public NullCreatureAI +{ + boss_yoggsaron_death_orb(Creature* pCreature) : NullCreatureAI(pCreature) + { + me->CastSpell(me, SPELL_DEATH_RAY_WARNING, true); + _startTimer = 1; + } + + uint32 _startTimer; + + void UpdateAI(uint32 diff) override + { + if (_startTimer) + { + _startTimer += diff; + if (_startTimer > 4000) + { + me->CastSpell(me, SPELL_DEATH_RAY_DAMAGE_VISUAL, true); + me->CastSpell(me, SPELL_DEATH_RAY_DAMAGE, true); + + _startTimer = 0; + me->SetSpeed(MOVE_WALK, 2); + me->SetSpeed(MOVE_RUN, 2); + me->GetMotionMaster()->MoveRandom(20.0f); + } + } + } +}; + +struct boss_yoggsaron_crusher_tentacle : public ScriptedAI +{ + boss_yoggsaron_crusher_tentacle(Creature* pCreature) : ScriptedAI(pCreature) + { + me->SetCombatMovement(false); + me->CastSpell(me, SPELL_CRUSH, true); + me->CastSpell(me, SPELL_FOCUSED_ANGER, true); + me->CastSpell(me, SPELL_DIMINISH_POWER, false); + } + + void Reset() override + { + me->SetInCombatWithZone(); + } + + void DamageTaken(Unit* who, uint32&, DamageEffectType damagetype, SpellSchoolMask) override + { + if (who && damagetype == DIRECT_DAMAGE) + { + DoResetThreatList(); + me->AddThreat(who, 100000); + AttackStart(who); + me->InterruptNonMeleeSpells(false); + } + } + + void DoAction(int32 param) override + { + if (param == ACTION_REMOVE_STUN) + me->RemoveAura(SPELL_SHATTERED_ILLUSION); + } + + void UpdateAI(uint32 /*diff*/) override + { + if (!UpdateVictim()) + return; + + if (me->IsWithinMeleeRange(me->GetVictim())) + { + DoMeleeAttackIfReady(); + return; + } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + me->CastSpell(me, SPELL_DIMINISH_POWER, false); + DoResetThreatList(); + } +}; + +struct boss_yoggsaron_corruptor_tentacle : public ScriptedAI +{ + boss_yoggsaron_corruptor_tentacle(Creature* pCreature) : ScriptedAI(pCreature) + { + me->SetCombatMovement(false); + } + + void DoAction(int32 param) override + { + if (param == ACTION_REMOVE_STUN) + me->RemoveAura(SPELL_SHATTERED_ILLUSION); + } + + Unit* SelectCorruptionTarget() + { + Player* target = nullptr; + Map::PlayerList const& pList = me->GetMap()->GetPlayers(); + uint8 num = urand(0, pList.getSize() - 1); + uint8 count = 0; + for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr, ++count) + { + if (me->GetDistance(itr->GetSource()) > 200 || itr->GetSource()->GetPositionZ() < 300 || !itr->GetSource()->IsAlive() || itr->GetSource()->IsGameMaster()) + continue; + + if (count <= num || !target) + target = itr->GetSource(); + else + break; + } + + return target; + } + + void UpdateAI(uint32 /*diff*/) override + { + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + if (Unit* target = SelectCorruptionTarget()) + { + uint32 spellid = RAND(SPELL_APATHY, SPELL_BLACK_PLAGUE, SPELL_DRAINING_POISON, SPELL_CURSE_OF_DOOM); + me->CastSpell(target, spellid, false); + } + } +}; + +struct boss_yoggsaron_constrictor_tentacle : public ScriptedAI +{ + boss_yoggsaron_constrictor_tentacle(Creature* pCreature) : ScriptedAI(pCreature) + { + me->SetCombatMovement(false); + _checkTimer = 1; + _playerGUID.Clear(); + } + + uint32 _checkTimer; + ObjectGuid _playerGUID; + + Unit* SelectConstrictTarget() + { + Player* target = nullptr; + Map::PlayerList const& pList = me->GetMap()->GetPlayers(); + uint8 num = urand(0, pList.getSize() - 1); + uint8 count = 0; + for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr, ++count) + { + if (me->GetDistance(itr->GetSource()) > 10 || !itr->GetSource()->IsAlive() || itr->GetSource()->IsGameMaster()) + continue; + if (itr->GetSource()->HasAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_SQUEEZE, me)) || itr->GetSource()->HasAura(SPELL_INSANE1)) + continue; + + if (count <= num || !target) + target = itr->GetSource(); + else + break; + } + + return target; + } + + void UpdateAI(uint32 diff) override + { + if (_checkTimer) + { + _checkTimer += diff; + if (_checkTimer >= 1000 && !me->HasUnitState(UNIT_STATE_STUNNED)) + { + if (Unit* target = SelectConstrictTarget()) + { + target->CastSpell(me, SPELL_LUNGE, true); + target->CastSpell(target, SPELL_SQUEEZE, true); + _playerGUID = target->GetGUID(); + _checkTimer = 0; + return; + } + + _checkTimer = 1; + } + } + } + + void DoAction(int32 param) override + { + if (param == ACTION_REMOVE_STUN) + me->RemoveAura(SPELL_SHATTERED_ILLUSION); + } + + void JustDied(Unit*) override + { + if (Unit* player = ObjectAccessor::GetUnit(*me, _playerGUID)) + player->RemoveAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_SQUEEZE, me)); + } }; struct boss_yoggsaron_keeper : public NullCreatureAI @@ -1773,495 +1674,418 @@ private: SummonList _summons; }; -class boss_yoggsaron_descend_portal : public CreatureScript +struct boss_yoggsaron_descend_portal : public PassiveAI { -public: - boss_yoggsaron_descend_portal() : CreatureScript("boss_yoggsaron_descend_portal") { } + boss_yoggsaron_descend_portal(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) {} - struct boss_yoggsaron_descend_portalAI : public PassiveAI + void OnSpellClick(Unit* clicker, bool& spellClickHandled) override { - boss_yoggsaron_descend_portalAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) {} + if (!spellClickHandled) + return; - void OnSpellClick(Unit* clicker, bool& spellClickHandled) override + if (!me->GetNpcFlags()) + return; + + switch (me->GetArmor()) { - if (!spellClickHandled) - return; - - if (!me->GetNpcFlags()) - return; - - switch (me->GetArmor()) - { - case ACTION_ILLUSION_DRAGONS: - clicker->CastSpell(clicker, SPELL_TELEPORT_TO_CHAMBER, true); - break; - case ACTION_ILLUSION_ICECROWN: - clicker->CastSpell(clicker, SPELL_TELEPORT_TO_ICECROWN, true); - break; - case ACTION_ILLUSION_STORMWIND: - clicker->CastSpell(clicker, SPELL_TELEPORT_TO_STORMWIND, true); - break; - } - - me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE); - me->DespawnOrUnsummon(1s); + case ACTION_ILLUSION_DRAGONS: + clicker->CastSpell(clicker, SPELL_TELEPORT_TO_CHAMBER, true); + break; + case ACTION_ILLUSION_ICECROWN: + clicker->CastSpell(clicker, SPELL_TELEPORT_TO_ICECROWN, true); + break; + case ACTION_ILLUSION_STORMWIND: + clicker->CastSpell(clicker, SPELL_TELEPORT_TO_STORMWIND, true); + break; } - private: - InstanceScript* _instance; - }; + me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE); + me->DespawnOrUnsummon(1s); + } - CreatureAI* GetAI(Creature* creature) const override +private: + InstanceScript* _instance; +}; + +struct boss_yoggsaron_influence_tentacle : public NullCreatureAI +{ + boss_yoggsaron_influence_tentacle(Creature* pCreature) : NullCreatureAI(pCreature) { - return GetUlduarAI(creature); + me->CastSpell(me, SPELL_GRIM_REPRISAL, true); + } + + void DamageTaken(Unit*, uint32&, DamageEffectType, SpellSchoolMask) override + { + if (me->GetEntry() != NPC_INFLUENCE_TENTACLE) + me->UpdateEntry(NPC_INFLUENCE_TENTACLE, 0, false); + } + + void JustDied(Unit*) override + { + if (me->IsSummon()) + if (Unit* sara = me->ToTempSummon()->GetSummonerUnit()) + sara->GetAI()->DoAction(ACTION_INFLUENCE_TENTACLE_DIED); } }; -class boss_yoggsaron_influence_tentacle : public CreatureScript +struct boss_yoggsaron_immortal_guardian : public ScriptedAI { -public: - boss_yoggsaron_influence_tentacle() : CreatureScript("boss_yoggsaron_influence_tentacle") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_yoggsaron_immortal_guardian(Creature* pCreature) : ScriptedAI(pCreature) { - return GetUlduarAI(pCreature); + Reset(); } - struct boss_yoggsaron_influence_tentacleAI : public NullCreatureAI + uint32 _visualTimer; + uint32 _spellTimer; + + void Reset() override { - boss_yoggsaron_influence_tentacleAI(Creature* pCreature) : NullCreatureAI(pCreature) - { - me->CastSpell(me, SPELL_GRIM_REPRISAL, true); - } + me->CastSpell(me, SPELL_RECENTLY_SPAWNED, true); + //me->CastSpell(me, SPELL_EMPOWERED_PASSIVE, true); + if (Aura* aur = me->AddAura(SPELL_EMPOWERED_PASSIVE, me)) + aur->SetStackAmount(9); - void DamageTaken(Unit*, uint32&, DamageEffectType, SpellSchoolMask) override - { - if (me->GetEntry() != NPC_INFLUENCE_TENTACLE) - me->UpdateEntry(NPC_INFLUENCE_TENTACLE, 0, false); - } - - void JustDied(Unit*) override - { - if (me->IsSummon()) - if (Unit* sara = me->ToTempSummon()->GetSummonerUnit()) - sara->GetAI()->DoAction(ACTION_INFLUENCE_TENTACLE_DIED); - } - }; -}; - -class boss_yoggsaron_immortal_guardian : public CreatureScript -{ -public: - boss_yoggsaron_immortal_guardian() : CreatureScript("boss_yoggsaron_immortal_guardian") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); + _spellTimer = 0; + _visualTimer = 1; + me->SetControlled(true, UNIT_STATE_ROOT); + me->SetInCombatWithZone(); } - struct boss_yoggsaron_immortal_guardianAI : public ScriptedAI + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override { - boss_yoggsaron_immortal_guardianAI(Creature* pCreature) : ScriptedAI(pCreature) + if (damage >= me->GetHealth()) + damage = me->GetHealth() - 1; + } + + void SpellHit(Unit* caster, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_SHADOW_BEACON) + caster->GetAI()->DoAction(ACTION_YOGG_SARON_SHADOW_BEACON); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + if (_visualTimer) { - Reset(); - } - - uint32 _visualTimer; - uint32 _spellTimer; - - void Reset() override - { - me->CastSpell(me, SPELL_RECENTLY_SPAWNED, true); - //me->CastSpell(me, SPELL_EMPOWERED_PASSIVE, true); - if (Aura* aur = me->AddAura(SPELL_EMPOWERED_PASSIVE, me)) - aur->SetStackAmount(9); - - _spellTimer = 0; - _visualTimer = 1; - me->SetControlled(true, UNIT_STATE_ROOT); - me->SetInCombatWithZone(); - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (damage >= me->GetHealth()) - damage = me->GetHealth() - 1; - } - - void SpellHit(Unit* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_SHADOW_BEACON) - caster->GetAI()->DoAction(ACTION_YOGG_SARON_SHADOW_BEACON); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (_visualTimer) + _visualTimer += diff; + if (_visualTimer >= 100 && _visualTimer < 10000) { - _visualTimer += diff; - if (_visualTimer >= 100 && _visualTimer < 10000) + me->CastSpell(me, SPELL_SIMPLE_TELEPORT, false); + _visualTimer = 10000; + } + else if (_visualTimer >= 11000) + { + me->SetControlled(false, UNIT_STATE_ROOT); + _visualTimer = 0; + } + } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + _spellTimer += diff; + if (_spellTimer >= 9500) + { + if (me->HealthBelowPct(85)) + { + if (Unit* target = SelectTargetFromPlayerList(40.0f)) { - me->CastSpell(me, SPELL_SIMPLE_TELEPORT, false); - _visualTimer = 10000; - } - else if (_visualTimer >= 11000) - { - me->SetControlled(false, UNIT_STATE_ROOT); - _visualTimer = 0; + me->CastSpell(target, SPELL_DRAIN_LIFE, false); + _spellTimer = 0; } } + else + _spellTimer = 7500; + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + DoMeleeAttackIfReady(); + } +}; - _spellTimer += diff; - if (_spellTimer >= 9500) +struct boss_yoggsaron_lich_king : public NullCreatureAI +{ + boss_yoggsaron_lich_king(Creature* c) : NullCreatureAI(c) { } + + bool _running; + int32 _checkTimer; + uint8 _step; + + void Reset() override + { + _running = true; + _checkTimer = 0; + _step = 0; + } + + void NextStep(const uint32 time) + { + _step++; + _checkTimer = time; + } + + void Say(uint8 text, uint32 id) + { + Creature* creature = me->FindNearestCreature(id, 50); + if (!creature) + return; + + creature->AI()->Talk(text); + return; + } + + void UpdateAI(uint32 diff) override + { + if (!_running) + return; + + if (_checkTimer != 0) + { + _checkTimer -= diff; + if (_checkTimer < 0) + _checkTimer = 0; + } + else + switch (_step) { - if (me->HealthBelowPct(85)) + case 0: + NextStep(5000); + break; + case 1: + Say(SAY_LK_1, NPC_LICH_KING); + NextStep(7000); + break; + case 2: + Say(SAY_IC_1, NPC_IMMOLATED_CHAMPION); + NextStep(6000); + break; + case 3: + Say(SAY_IC_2, NPC_IMMOLATED_CHAMPION); + NextStep(6500); + break; + case 4: + Say(SAY_LK_2, NPC_LICH_KING); + NextStep(7500); + break; + case 5: + Say(SAY_YOGG_5, NPC_YOGG_SARON_VISION); + NextStep(5000); + break; + case 6: + Say(SAY_YOGG_6, NPC_YOGG_SARON_VISION); + _running = false; + break; + } + } +}; + +struct boss_yoggsaron_llane : public NullCreatureAI +{ + boss_yoggsaron_llane(Creature* c) : NullCreatureAI(c) { } + + bool _running; + int32 _checkTimer; + uint8 _step; + + void Reset() override + { + _running = true; + _checkTimer = 0; + _step = 0; + } + + void NextStep(const uint32 time) + { + _step++; + _checkTimer = time; + } + + void Say(uint8 text, uint32 id) + { + Creature* creature = me->FindNearestCreature(id, 50); + if (!creature) + return; + + creature->AI()->Talk(text); + return; + } + + void UpdateAI(uint32 diff) override + { + if (!_running) + return; + + if (_checkTimer != 0) + { + _checkTimer -= diff; + if (_checkTimer < 0) + _checkTimer = 0; + } + else + switch (_step) + { + case 0: + NextStep(5000); + break; + case 1: + Say(SAY_GARONA_1, NPC_GARONA); + NextStep(2000); + break; + case 2: + Say(SAY_GARONA_2, NPC_GARONA); + NextStep(6500); + break; + case 3: + Say(SAY_GARONA_3, NPC_GARONA); + NextStep(11000); + break; + case 4: + Say(SAY_YOGG_1, NPC_YOGG_SARON_VISION); + NextStep(2500); + break; + case 5: + Say(SAY_YOGG_2, NPC_YOGG_SARON_VISION); + NextStep(2500); + break; + case 6: + Say(SAY_LLANE_1, NPC_KING_LLANE); + NextStep(10000); + break; + case 7: + Say(SAY_GARONA_4, NPC_GARONA); + NextStep(5000); + break; + case 8: + Say(SAY_YOGG_3, NPC_YOGG_SARON_VISION); + _running = false; + break; + } + } +}; + +struct boss_yoggsaron_neltharion : public ScriptedAI +{ + boss_yoggsaron_neltharion(Creature* c) : ScriptedAI(c) { } + + bool _running; + int32 _checkTimer; + uint8 _step; + + void Reset() override + { + _running = true; + _checkTimer = 0; + _step = 0; + } + + void NextStep(const uint32 time) + { + _step++; + _checkTimer = time; + } + + void Say(uint8 text, uint32 id) + { + Creature* creature = me->FindNearestCreature(id, 50); + if (!creature) + return; + + creature->AI()->Talk(text); + return; + } + + void UpdateAI(uint32 diff) override + { + if (!_running) + return; + + if (_checkTimer != 0) + { + _checkTimer -= diff; + if (_checkTimer < 0) + _checkTimer = 0; + } + else + switch (_step) + { + case 0: + NextStep(5000); + break; + case 1: + Say(SAY_NEL_1, NPC_NELTHARION); + NextStep(10000); + break; + case 2: + Say(SAY_YAS_1, NPC_YSERA); + NextStep(4000); + break; + case 3: + Say(SAY_NEL_2, NPC_NELTHARION); + NextStep(4000); + break; + case 4: + Say(SAY_MAL_1, NPC_MALYGOS); + NextStep(8000); + break; + case 5: + Say(SAY_YOGG_4, NPC_YOGG_SARON_VISION); + _running = false; + break; + } + } +}; + +struct boss_yoggsaron_voice : public NullCreatureAI +{ + boss_yoggsaron_voice(Creature* pCreature) : NullCreatureAI(pCreature) + { + _targets.clear(); + _current = 0; + } + + EventMap events; + GuidVector _targets; + uint32 _current; + + void Reset() override + { + me->CastSpell(me, SPELL_INSANE_PERIODIC, true); + } + + void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_INSANE1) + { + // Drive Me Crazy achievement failed + if (me->GetInstanceScript()) + if (Creature* yogg = me->GetInstanceScript()->GetCreature(BOSS_YOGGSARON)) + yogg->AI()->DoAction(ACTION_FAILED_DRIVE_ME_CRAZY); + + events.ScheduleEvent(40, 2s); + _targets.push_back(target->GetGUID()); + } + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + switch (events.ExecuteEvent()) + { + case 40: { - if (Unit* target = SelectTargetFromPlayerList(40.0f)) + ObjectGuid _guid = _targets.at(_current); + ++_current; + + if (Player* player = ObjectAccessor::GetPlayer(*me, _guid)) { - me->CastSpell(target, SPELL_DRAIN_LIFE, false); - _spellTimer = 0; + Talk(WHISPER_VOICE_INSANE, player); } - } - else - _spellTimer = 7500; - } - - DoMeleeAttackIfReady(); - } - }; -}; - -class boss_yoggsaron_lich_king : public CreatureScript -{ -public: - boss_yoggsaron_lich_king() : CreatureScript("boss_yoggsaron_lich_king") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_yoggsaron_lich_kingAI : public NullCreatureAI - { - boss_yoggsaron_lich_kingAI(Creature* c) : NullCreatureAI(c) { } - - bool _running; - int32 _checkTimer; - uint8 _step; - - void Reset() override - { - _running = true; - _checkTimer = 0; - _step = 0; - } - - void NextStep(const uint32 time) - { - _step++; - _checkTimer = time; - } - - void Say(uint8 text, uint32 id) - { - Creature* creature = me->FindNearestCreature(id, 50); - if (!creature) - return; - - creature->AI()->Talk(text); - return; - } - - void UpdateAI(uint32 diff) override - { - if (!_running) - return; - - if (_checkTimer != 0) - { - _checkTimer -= diff; - if (_checkTimer < 0) - _checkTimer = 0; - } - else - switch (_step) - { - case 0: - NextStep(5000); - break; - case 1: - Say(SAY_LK_1, NPC_LICH_KING); - NextStep(7000); - break; - case 2: - Say(SAY_IC_1, NPC_IMMOLATED_CHAMPION); - NextStep(6000); - break; - case 3: - Say(SAY_IC_2, NPC_IMMOLATED_CHAMPION); - NextStep(6500); - break; - case 4: - Say(SAY_LK_2, NPC_LICH_KING); - NextStep(7500); - break; - case 5: - Say(SAY_YOGG_5, NPC_YOGG_SARON_VISION); - NextStep(5000); - break; - case 6: - Say(SAY_YOGG_6, NPC_YOGG_SARON_VISION); - _running = false; - break; + break; } } - }; -}; - -class boss_yoggsaron_llane : public CreatureScript -{ -public: - boss_yoggsaron_llane() : CreatureScript("boss_yoggsaron_llane") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); } - - struct boss_yoggsaron_llaneAI : public NullCreatureAI - { - boss_yoggsaron_llaneAI(Creature* c) : NullCreatureAI(c) { } - - bool _running; - int32 _checkTimer; - uint8 _step; - - void Reset() override - { - _running = true; - _checkTimer = 0; - _step = 0; - } - - void NextStep(const uint32 time) - { - _step++; - _checkTimer = time; - } - - void Say(uint8 text, uint32 id) - { - Creature* creature = me->FindNearestCreature(id, 50); - if (!creature) - return; - - creature->AI()->Talk(text); - return; - } - - void UpdateAI(uint32 diff) override - { - if (!_running) - return; - - if (_checkTimer != 0) - { - _checkTimer -= diff; - if (_checkTimer < 0) - _checkTimer = 0; - } - else - switch (_step) - { - case 0: - NextStep(5000); - break; - case 1: - Say(SAY_GARONA_1, NPC_GARONA); - NextStep(2000); - break; - case 2: - Say(SAY_GARONA_2, NPC_GARONA); - NextStep(6500); - break; - case 3: - Say(SAY_GARONA_3, NPC_GARONA); - NextStep(11000); - break; - case 4: - Say(SAY_YOGG_1, NPC_YOGG_SARON_VISION); - NextStep(2500); - break; - case 5: - Say(SAY_YOGG_2, NPC_YOGG_SARON_VISION); - NextStep(2500); - break; - case 6: - Say(SAY_LLANE_1, NPC_KING_LLANE); - NextStep(10000); - break; - case 7: - Say(SAY_GARONA_4, NPC_GARONA); - NextStep(5000); - break; - case 8: - Say(SAY_YOGG_3, NPC_YOGG_SARON_VISION); - _running = false; - break; - } - } - }; -}; - -class boss_yoggsaron_neltharion : public CreatureScript -{ -public: - boss_yoggsaron_neltharion() : CreatureScript("boss_yoggsaron_neltharion") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_yoggsaron_neltharionAI : public ScriptedAI - { - boss_yoggsaron_neltharionAI(Creature* c) : ScriptedAI(c) { } - - bool _running; - int32 _checkTimer; - uint8 _step; - - void Reset() override - { - _running = true; - _checkTimer = 0; - _step = 0; - } - - void NextStep(const uint32 time) - { - _step++; - _checkTimer = time; - } - - void Say(uint8 text, uint32 id) - { - Creature* creature = me->FindNearestCreature(id, 50); - if (!creature) - return; - - creature->AI()->Talk(text); - return; - } - - void UpdateAI(uint32 diff) override - { - if (!_running) - return; - - if (_checkTimer != 0) - { - _checkTimer -= diff; - if (_checkTimer < 0) - _checkTimer = 0; - } - else - switch (_step) - { - case 0: - NextStep(5000); - break; - case 1: - Say(SAY_NEL_1, NPC_NELTHARION); - NextStep(10000); - break; - case 2: - Say(SAY_YAS_1, NPC_YSERA); - NextStep(4000); - break; - case 3: - Say(SAY_NEL_2, NPC_NELTHARION); - NextStep(4000); - break; - case 4: - Say(SAY_MAL_1, NPC_MALYGOS); - NextStep(8000); - break; - case 5: - Say(SAY_YOGG_4, NPC_YOGG_SARON_VISION); - _running = false; - break; - } - } - }; -}; - -class boss_yoggsaron_voice : public CreatureScript -{ -public: - boss_yoggsaron_voice() : CreatureScript("boss_yoggsaron_voice") { } - - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetUlduarAI(pCreature); - } - - struct boss_yoggsaron_voiceAI : public NullCreatureAI - { - boss_yoggsaron_voiceAI(Creature* pCreature) : NullCreatureAI(pCreature) - { - _targets.clear(); - _current = 0; - } - - EventMap events; - GuidVector _targets; - uint32 _current; - - void Reset() override - { - me->CastSpell(me, SPELL_INSANE_PERIODIC, true); - } - - void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_INSANE1) - { - // Drive Me Crazy achievement failed - if (me->GetInstanceScript()) - if (Creature* yogg = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_YOGGSARON))) - yogg->AI()->DoAction(ACTION_FAILED_DRIVE_ME_CRAZY); - - events.ScheduleEvent(40, 2s); - _targets.push_back(target->GetGUID()); - } - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - switch (events.ExecuteEvent()) - { - case 40: - { - ObjectGuid _guid = _targets.at(_current); - ++_current; - - if (Player* player = ObjectAccessor::GetPlayer(*me, _guid)) - { - Talk(WHISPER_VOICE_INSANE, player); - } - break; - } - } - } - }; }; // 63830, 63881 - Malady of the Mind @@ -2894,7 +2718,7 @@ public: bool OnCheck(Player* player, Unit* /*target*/ /*Yogg-Saron*/, uint32 /*criteria_id*/) override { if (player->GetInstanceScript()) - if (Creature* sara = ObjectAccessor::GetCreature(*player, player->GetInstanceScript()->GetGuidData(NPC_SARA))) + if (Creature* sara = player->GetInstanceScript()->GetCreature(DATA_SARA)) return sara->GetAI()->GetData(DATA_GET_KEEPERS_COUNT) <= _keepersCount; return false; @@ -2915,7 +2739,7 @@ public: bool OnCheck(Player* player, Unit* /*target*/ /*Yogg-Saron*/, uint32 /*criteria_id*/) override { if (player->GetInstanceScript()) - if (Creature* sara = ObjectAccessor::GetCreature(*player, player->GetInstanceScript()->GetGuidData(NPC_BRAIN_OF_YOGG_SARON))) + if (Creature* sara = player->GetInstanceScript()->GetCreature(DATA_BRAIN_OF_YOGG_SARON)) return sara->GetAI()->GetData(DATA_GET_CURRENT_ILLUSION) == _requiredIllusion; return false; @@ -2938,23 +2762,23 @@ public: void AddSC_boss_yoggsaron() { - new boss_yoggsaron(); - new boss_yoggsaron_sara(); - new boss_yoggsaron_cloud(); - new boss_yoggsaron_guardian_of_ys(); - new boss_yoggsaron_brain(); - new boss_yoggsaron_death_orb(); - new boss_yoggsaron_crusher_tentacle(); - new boss_yoggsaron_corruptor_tentacle(); - new boss_yoggsaron_constrictor_tentacle(); + RegisterUlduarCreatureAI(boss_yoggsaron); + RegisterUlduarCreatureAI(boss_yoggsaron_sara); + RegisterUlduarCreatureAI(boss_yoggsaron_cloud); + RegisterUlduarCreatureAI(boss_yoggsaron_guardian_of_ys); + RegisterUlduarCreatureAI(boss_yoggsaron_brain); + RegisterUlduarCreatureAI(boss_yoggsaron_death_orb); + RegisterUlduarCreatureAI(boss_yoggsaron_crusher_tentacle); + RegisterUlduarCreatureAI(boss_yoggsaron_corruptor_tentacle); + RegisterUlduarCreatureAI(boss_yoggsaron_constrictor_tentacle); RegisterUlduarCreatureAI(boss_yoggsaron_keeper); - new boss_yoggsaron_descend_portal(); - new boss_yoggsaron_influence_tentacle(); - new boss_yoggsaron_immortal_guardian(); - new boss_yoggsaron_lich_king(); - new boss_yoggsaron_llane(); - new boss_yoggsaron_neltharion(); - new boss_yoggsaron_voice(); + RegisterUlduarCreatureAI(boss_yoggsaron_descend_portal); + RegisterUlduarCreatureAI(boss_yoggsaron_influence_tentacle); + RegisterUlduarCreatureAI(boss_yoggsaron_immortal_guardian); + RegisterUlduarCreatureAI(boss_yoggsaron_lich_king); + RegisterUlduarCreatureAI(boss_yoggsaron_llane); + RegisterUlduarCreatureAI(boss_yoggsaron_neltharion); + RegisterUlduarCreatureAI(boss_yoggsaron_voice); // SPELLS RegisterSpellScript(spell_yogg_saron_malady_of_the_mind_aura); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index 0db04db30..3d179883c 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -19,6 +19,7 @@ #include "CreatureScript.h" #include "GameTime.h" #include "InstanceMapScript.h" +#include "InstanceScript.h" #include "Player.h" #include "ScriptedCreature.h" #include "Transport.h" @@ -27,6 +28,94 @@ #include "WorldStatePackets.h" #include "ulduar.h" +DoorData const doorData[] = +{ + { GO_LEVIATHAN_DOORS, BOSS_LEVIATHAN, DOOR_TYPE_ROOM }, + { GO_XT002_DOORS, BOSS_XT002, DOOR_TYPE_ROOM }, + { GO_KOLOGARN_DOORS, BOSS_KOLOGARN, DOOR_TYPE_ROOM }, + { GO_ASSEMBLY_DOORS, BOSS_ASSEMBLY, DOOR_TYPE_ROOM }, + { GO_ARCHIVUM_DOORS, BOSS_ASSEMBLY, DOOR_TYPE_PASSAGE }, + { GO_YOGG_SARON_DOORS, BOSS_YOGGSARON, DOOR_TYPE_ROOM }, + { 0, 0, DOOR_TYPE_ROOM } +}; + +ObjectData const creatureData[] = +{ + { NPC_LEVIATHAN, BOSS_LEVIATHAN }, + { NPC_IGNIS, BOSS_IGNIS }, + { NPC_RAZORSCALE, BOSS_RAZORSCALE }, + { NPC_XT002, BOSS_XT002 }, + { NPC_KOLOGARN, BOSS_KOLOGARN }, + { NPC_AURIAYA, BOSS_AURIAYA }, + { NPC_MIMIRON, BOSS_MIMIRON }, + { NPC_HODIR, BOSS_HODIR }, + { NPC_THORIM, BOSS_THORIM }, + { NPC_FREYA, BOSS_FREYA }, + { NPC_VEZAX, BOSS_VEZAX }, + { NPC_YOGGSARON, BOSS_YOGGSARON }, + { NPC_ALGALON, BOSS_ALGALON }, + // Assembly of Iron members + { NPC_STEELBREAKER, DATA_STEELBREAKER }, + { NPC_MOLGEIM, DATA_MOLGEIM }, + { NPC_BRUNDIR, DATA_BRUNDIR }, + // Mimiron vehicles + { NPC_MIMIRON_LEVIATHAN_MKII, DATA_MIMIRON_LEVIATHAN_MKII }, + { NPC_MIMIRON_VX001, DATA_MIMIRON_VX001 }, + { NPC_MIMIRON_ACU, DATA_MIMIRON_ACU }, + // Freya elders + { NPC_ELDER_IRONBRANCH, DATA_ELDER_IRONBRANCH }, + { NPC_ELDER_STONEBARK, DATA_ELDER_STONEBARK }, + { NPC_ELDER_BRIGHTLEAF, DATA_ELDER_BRIGHTLEAF }, + // Yogg-Saron helpers + { NPC_SARA, DATA_SARA }, + { NPC_BRAIN_OF_YOGG_SARON, DATA_BRAIN_OF_YOGG_SARON }, + // Algalon helpers + { NPC_BRANN_BRONZBEARD_ALG, DATA_BRANN_BRONZEBEARD_ALG }, + { NPC_BRANN_BASE_CAMP, DATA_BRANN_BASE_CAMP }, + { 0, 0 } +}; + +ObjectData const gameobjectData[] = +{ + { GO_LEVIATHAN_DOORS, DATA_LEVIATHAN_DOORS }, + { GO_LIGHTNING_WALL1, DATA_LIGHTNING_WALL1 }, + { GO_LIGHTNING_WALL2, DATA_LIGHTNING_WALL2 }, + { GO_XT002_DOORS, DATA_XT002_DOORS }, + { GO_KOLOGARN_DOORS, DATA_KOLOGARN_DOORS }, + { GO_ASSEMBLY_DOORS, DATA_ASSEMBLY_DOORS }, + { GO_ARCHIVUM_DOORS, DATA_ARCHIVUM_DOORS }, + { GO_MIMIRON_DOOR_1, DATA_GO_MIMIRON_DOOR_1 }, + { GO_MIMIRON_DOOR_2, DATA_GO_MIMIRON_DOOR_2 }, + { GO_MIMIRON_DOOR_3, DATA_GO_MIMIRON_DOOR_3 }, + { GO_ARENA_LEVER_GATE, DATA_THORIM_LEVER_GATE }, + { GO_ARENA_LEVER, DATA_THORIM_LEVER }, + { GO_ARENA_FENCE, DATA_THORIM_FENCE }, + { GO_FIRST_COLOSSUS_DOORS, DATA_THORIM_FIRST_DOORS }, + { GO_SECOND_COLOSSUS_DOORS, DATA_THORIM_SECOND_DOORS }, + { GO_YOGG_SARON_DOORS, DATA_YOGG_SARON_DOORS }, + { GO_KEEPERS_GATE, DATA_KEEPERS_GATE }, + { GO_DOODAD_UL_SIGILDOOR_01, DATA_SIGILDOOR_01 }, + { GO_DOODAD_UL_SIGILDOOR_02, DATA_SIGILDOOR_02 }, + { GO_DOODAD_UL_SIGILDOOR_03, DATA_SIGILDOOR_03 }, + { GO_DOODAD_UL_UNIVERSEFLOOR_01, DATA_UNIVERSE_FLOOR_01 }, + { GO_DOODAD_UL_UNIVERSEFLOOR_02, DATA_UNIVERSE_FLOOR_02 }, + { GO_DOODAD_UL_UNIVERSEGLOBE01, DATA_UNIVERSE_GLOBE }, + { GO_DOODAD_UL_ULDUAR_TRAPDOOR_03, DATA_ALGALON_TRAPDOOR }, + { GO_MIMIRON_TRAM, DATA_MIMIRON_TRAM }, + { GO_MIMIRON_ACTIVATE_TRAM, DATA_MIMIRON_ACTIVATE_TRAM }, + { GO_MIMIRON_TRAM_ROCKET_BOOSTER, DATA_MIMIRON_TRAM_ROCKET_BOOSTER}, + { GO_MIMIRON_CALL_TRAM_CENTER, DATA_MIMIRON_CALL_TRAM_CENTER }, + { GO_MIMIRON_CALL_TRAM_MIMIRON, DATA_MIMIRON_CALL_TRAM_MIMIRON }, + { GO_DOODAD_UL_TRAIN_TURNAROUND01, DATA_MIMIRON_TRAM_TURNAROUND_1 }, + { GO_DOODAD_UL_TRAIN_TURNAROUND02, DATA_MIMIRON_TRAM_TURNAROUND_2 }, + // Hodir chests (dynamically spawned, one per difficulty) + { GO_HODIR_CHEST_NORMAL, DATA_HODIR_CHEST_NORMAL }, + { GO_HODIR_CHEST_NORMAL_HERO, DATA_HODIR_CHEST_NORMAL_HERO }, + { GO_HODIR_CHEST_HARD, DATA_HODIR_CHEST_HARD }, + { GO_HODIR_CHEST_HARD_HERO, DATA_HODIR_CHEST_HARD_HERO }, + { 0, 0 } +}; + class instance_ulduar : public InstanceMapScript { public: @@ -41,39 +130,25 @@ public: { instance_ulduar_InstanceMapScript(Map* pMap) : InstanceScript(pMap) { - Initialize(); SetHeaders(DataHeader); + SetBossNumber(MAX_ENCOUNTER); + LoadDoorData(doorData); + LoadObjectData(creatureData, gameobjectData); + Initialize(); // 0: 10 man difficulty // 1: 25 man difficulty m_difficulty = (pMap->Is25ManRaid() ? 0 : 1); }; - uint32 m_auiEncounter[MAX_ENCOUNTER]; + // Only used for TYPE_WATCHERS bitmask + uint32 m_watchersMask; uint32 C_of_Ulduar_MASK; int m_difficulty; - // Bosses - ObjectGuid m_uiLeviathanGUID; - ObjectGuid m_uiIgnisGUID; - ObjectGuid m_uiRazorscaleGUID; - ObjectGuid m_uiXT002GUID; - ObjectGuid m_auiAssemblyGUIDs[3]; - ObjectGuid m_uiKologarnGUID; - ObjectGuid m_uiAuriayaGUID; - ObjectGuid m_uiMimironGUID; - ObjectGuid m_uiHodirGUID; - ObjectGuid m_uiThorimGUID; - ObjectGuid m_uiFreyaGUID; - ObjectGuid m_uiVezaxGUID; - ObjectGuid m_uiYoggSaronGUID; - ObjectGuid m_uiAlgalonGUID; - // Flame Leviathan - ObjectGuid m_leviathanDoorsGUID; ObjectGuid m_leviathanVisualTowers[4][2]; ObjectGuid m_RepairSGUID[2]; - ObjectGuid m_lightningWalls[2]; bool m_leviathanTowers[4]; GuidList _leviathanVehicles; uint32 m_unbrokenAchievement; @@ -82,57 +157,17 @@ public: // Razorscale ObjectGuid m_RazorscaleHarpoonFireStateGUID[4]; - // XT-002 - ObjectGuid m_xt002DoorsGUID; - - // Kologarn - ObjectGuid KologarnDoorGUID; - - // Assembly of Iron - ObjectGuid m_assemblyDoorsGUID; - ObjectGuid m_archivumDoorsGUID; - - // Thorim - ObjectGuid m_thorimGameobjectsGUID[5]; - - // Hodir's chests + // Hodir bool hmHodir; - ObjectGuid m_hodirNormalChest; - ObjectGuid m_hodirHardmodeChest; Position normalChestPosition = { 1967.152588f, -204.188461f, 432.686951f, 5.50957f }; Position hardChestPosition = { 2035.94600f, -202.084885f, 432.686859f, 3.164077f }; - // Mimiron Tram - ObjectGuid m_mimironTramGUID; - ObjectGuid m_mimironActivateTramGUID; - ObjectGuid m_mimironTramRocketBoosterGUID; - ObjectGuid m_mimironTramTurnaround1GUID; - ObjectGuid m_mimironTramTurnaround2GUID; - ObjectGuid m_mimironCallTramCenterGUID; - ObjectGuid m_mimironCallTramMimironGUID; - - // Mimiron - ObjectGuid m_MimironDoor[3]; - ObjectGuid m_MimironLeviathanMKIIguid; - ObjectGuid m_MimironVX001guid; - ObjectGuid m_MimironACUguid; - // Freya - ObjectGuid m_FreyaElder[3]; uint32 m_conspeedatoryAttempt; // Yogg-Saron - ObjectGuid m_saraGUID; - ObjectGuid m_yoggsaronBrainGUID; - ObjectGuid m_yoggsaronDoorsGUID; // Algalon - ObjectGuid m_algalonSigilDoorGUID[3]; - ObjectGuid m_algalonFloorGUID[2]; - ObjectGuid m_algalonUniverseGUID; - ObjectGuid m_algalonTrapdoorGUID; - ObjectGuid m_brannBronzebeardAlgGUID; - ObjectGuid m_brannBronzebeardBaseCamp; uint32 m_algalonTimer; // Ancient Gate @@ -141,13 +176,12 @@ public: // Shared EventMap _events; bool m_mimironTramUsed; - ObjectGuid m_keepersgateGUID; ObjectGuid m_keepersGossipGUID[4]; void Initialize() override { // Bosses - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + m_watchersMask = 0; C_of_Ulduar_MASK = 0; // Flame Leviathan @@ -182,21 +216,21 @@ public: void OnPlayerEnter(Player* player) override { // mimiron tram: - if (GameObject* MimironTram = instance->GetGameObject(m_mimironTramGUID)) + if (GameObject* MimironTram = GetGameObject(DATA_MIMIRON_TRAM)) { player->UpdateVisibilityOf(MimironTram); if (StaticTransport* t = MimironTram->ToStaticTransport()) { - if (GameObject* go = instance->GetGameObject(m_mimironTramRocketBoosterGUID)) + if (GameObject* go = GetGameObject(DATA_MIMIRON_TRAM_ROCKET_BOOSTER)) if (!go->GetTransport()) t->AddPassenger(go, true); - if (GameObject* go = instance->GetGameObject(m_mimironActivateTramGUID)) + if (GameObject* go = GetGameObject(DATA_MIMIRON_ACTIVATE_TRAM)) if (!go->GetTransport()) t->AddPassenger(go, true); } } - if (!m_uiAlgalonGUID && m_algalonTimer && (m_algalonTimer <= 60 || m_algalonTimer == TIMER_ALGALON_TO_SUMMON)) + if (!GetObjectGuid(BOSS_ALGALON) && m_algalonTimer && (m_algalonTimer <= 60 || m_algalonTimer == TIMER_ALGALON_TO_SUMMON)) { TempSummon* algalon = instance->SummonCreature(NPC_ALGALON, AlgalonLandPos); if (!algalon) @@ -217,15 +251,15 @@ public: bool IsEncounterInProgress() const override { - for (uint8 i = 0; i < (MAX_ENCOUNTER - 1); ++i) + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) { - if (m_auiEncounter[i] == IN_PROGRESS) + if (GetBossState(i) == IN_PROGRESS) return true; } // Leviathan does not use IN_PROGRESS type, instead SPECIAL is set and never reset, // Check if he is in combat. - if (Unit* l = instance->GetCreature(m_uiLeviathanGUID)) + if (Creature* l = instance->GetCreature(GetObjectGuid(BOSS_LEVIATHAN))) if (l->IsInCombat()) return true; @@ -239,13 +273,120 @@ public: SetData(eventId, 0); } + bool SetBossState(uint32 type, EncounterState state) override + { + if (!InstanceScript::SetBossState(type, state)) + return false; + + switch (type) + { + case BOSS_LEVIATHAN: + if (state == DONE) + { + instance->DoForAllPlayers([&](Player* player) + { + if (Creature* vehicleCreature = player->GetVehicleCreatureBase()) + vehicleCreature->DespawnOrUnsummon(); + }); + + if (GameObject* go = GetGameObject(DATA_LEVIATHAN_DOORS)) + go->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + } + break; + case BOSS_ASSEMBLY: + // Assembly doors handled by DoorData, archivum + // doors stay open only after DONE + if (GameObject* go = GetGameObject(DATA_ARCHIVUM_DOORS)) + go->SetGoState(state == DONE ? GO_STATE_ACTIVE : GO_STATE_READY); + break; + case BOSS_MIMIRON: + if (state == IN_PROGRESS) + m_mimironTramUsed = true; + [[fallthrough]]; + case BOSS_HODIR: + case BOSS_THORIM: + case BOSS_FREYA: + if (GetBossState(BOSS_MIMIRON) == DONE && GetBossState(BOSS_FREYA) == DONE && GetBossState(BOSS_HODIR) == DONE && GetBossState(BOSS_THORIM) == DONE) + { + scheduler.Schedule(45s, [this](TaskContext /*context*/) + { + if (GameObject* go = GetGameObject(DATA_KEEPERS_GATE)) + { + go->RemoveGameObjectFlag(GO_FLAG_LOCKED); + if (Creature* trigger = instance->SummonCreature(NPC_ANCIENT_GATE_WORLD_TRIGGER, triggerAncientGatePosition, nullptr, 10 * IN_MILLISECONDS)) + trigger->AI()->Talk(EMOTE_ANCIENT_GATE_UNLOCKED); + } + }); + } + if (type == BOSS_HODIR && state == DONE) + setChestsLootable(BOSS_HODIR); + break; + case BOSS_ALGALON: + if (GameObject* go = GetGameObject(DATA_SIGILDOOR_03)) + { + go->SetGoState(state != IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY); + go->EnableCollision(false); + } + if (GameObject* go = GetGameObject(DATA_UNIVERSE_FLOOR_01)) + { + go->SetGoState(state != IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY); + go->EnableCollision(false); + } + if (GameObject* go = GetGameObject(DATA_UNIVERSE_FLOOR_02)) + { + go->SetGoState(state == IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY); + go->EnableCollision(false); + } + if (GameObject* go = GetGameObject(DATA_UNIVERSE_GLOBE)) + { + go->SetGoState(state == IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY); + go->EnableCollision(false); + } + if (GameObject* go = GetGameObject(DATA_ALGALON_TRAPDOOR)) + { + go->SetGoState(state == IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY); + go->EnableCollision(false); + } + break; + default: + break; + } + + // take care of herbs + if (type == BOSS_FREYA && state == DONE) + { + std::list goList; + if (Creature* freya = GetCreature(BOSS_FREYA)) + { + freya->GetGameObjectListWithEntryInGrid(goList, { 191019, 190176, 190171, 190170, 189973 }, 333.0f); + + for (GameObject* herb : goList) + herb->SetRespawnTime(7 * DAY); + } + } + + if (state == DONE) + SaveToDB(); + + if (type > BOSS_LEVIATHAN && type < MAX_ENCOUNTER && state == IN_PROGRESS) + { + instance->DoForAllPlayers([&](Player* player) + { + if (Creature* vehicleCreature = player->GetVehicleCreatureBase()) + vehicleCreature->DespawnOrUnsummon(); + }); + } + + return true; + } + void SpawnHodirChests(Difficulty diff, Creature* hodir) { switch (diff) { case RAID_DIFFICULTY_10MAN_NORMAL: // 10 man chest { - if (!m_hodirNormalChest) + if (!GetObjectGuid(DATA_HODIR_CHEST_NORMAL)) { if (GameObject* go = hodir->SummonGameObject( GO_HODIR_CHEST_NORMAL, @@ -254,11 +395,10 @@ public: normalChestPosition.GetPositionZ(), normalChestPosition.GetOrientation(), 0, 0, 0, 0, 0)) { - m_hodirNormalChest = go->GetGUID(); go->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); } } - if (!m_hodirHardmodeChest) + if (!GetObjectGuid(DATA_HODIR_CHEST_HARD)) { if (GameObject* go = hodir->SummonGameObject( GO_HODIR_CHEST_HARD, @@ -267,7 +407,6 @@ public: hardChestPosition.GetPositionZ(), hardChestPosition.GetOrientation(), 0, 0, 0, 0, 0)) { - m_hodirHardmodeChest = go->GetGUID(); go->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); hmHodir = true; } @@ -276,7 +415,7 @@ public: } case RAID_DIFFICULTY_25MAN_NORMAL: // 25 man chest { - if (!m_hodirNormalChest) + if (!GetObjectGuid(DATA_HODIR_CHEST_NORMAL_HERO)) { if (GameObject* go = hodir->SummonGameObject( GO_HODIR_CHEST_NORMAL_HERO, @@ -285,11 +424,10 @@ public: normalChestPosition.GetPositionZ(), normalChestPosition.GetOrientation(), 0, 0, 0, 0, 0)) { - m_hodirNormalChest = go->GetGUID(); go->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); } } - if (!m_hodirHardmodeChest) + if (!GetObjectGuid(DATA_HODIR_CHEST_HARD_HERO)) { if (GameObject* go = hodir->SummonGameObject( GO_HODIR_CHEST_HARD_HERO, @@ -298,7 +436,6 @@ public: hardChestPosition.GetPositionZ(), hardChestPosition.GetOrientation(), 0, 0, 0, 0, 0)) { - m_hodirHardmodeChest = go->GetGUID(); go->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); hmHodir = true; } @@ -312,32 +449,12 @@ public: void OnCreatureCreate(Creature* creature) override { + InstanceScript::OnCreatureCreate(creature); + switch (creature->GetEntry()) { - case NPC_LEVIATHAN: - m_uiLeviathanGUID = creature->GetGUID(); - break; - case NPC_IGNIS: - m_uiIgnisGUID = creature->GetGUID(); - break; - case NPC_RAZORSCALE: - m_uiRazorscaleGUID = creature->GetGUID(); - break; - case NPC_XT002: - m_uiXT002GUID = creature->GetGUID(); - break; - case NPC_STEELBREAKER: - m_auiAssemblyGUIDs[0] = creature->GetGUID(); - break; - case NPC_MOLGEIM: - m_auiAssemblyGUIDs[1] = creature->GetGUID(); - break; - case NPC_BRUNDIR: - m_auiAssemblyGUIDs[2] = creature->GetGUID(); - break; case NPC_KOLOGARN: - m_uiKologarnGUID = creature->GetGUID(); - if (GetData(TYPE_KOLOGARN) == DONE) + if (GetBossState(BOSS_KOLOGARN) == DONE) { creature->SetDisableGravity(true); creature->SetPosition(creature->GetHomePosition()); @@ -345,34 +462,13 @@ public: creature->StopMovingOnCurrentPos(); } break; - case NPC_AURIAYA: - m_uiAuriayaGUID = creature->GetGUID(); - break; - case NPC_MIMIRON: - m_uiMimironGUID = creature->GetGUID(); - break; case NPC_HODIR: - m_uiHodirGUID = creature->GetGUID(); - if (m_auiEncounter[TYPE_HODIR] != DONE) + if (GetBossState(BOSS_HODIR) != DONE) { SpawnHodirChests(instance->GetDifficulty(), creature); } break; - case NPC_THORIM: - m_uiThorimGUID = creature->GetGUID(); - break; - case NPC_FREYA: - m_uiFreyaGUID = creature->GetGUID(); - break; - case NPC_VEZAX: - m_uiVezaxGUID = creature->GetGUID(); - break; - case NPC_YOGGSARON: - m_uiYoggSaronGUID = creature->GetGUID(); - break; case NPC_ALGALON: - m_uiAlgalonGUID = creature->GetGUID(); - if (!m_algalonTimer) creature->DespawnOrUnsummon(); break; @@ -388,32 +484,6 @@ public: m_RazorscaleHarpoonFireStateGUID[0] = creature->GetGUID(); } break; - case NPC_MIMIRON_LEVIATHAN_MKII: - m_MimironLeviathanMKIIguid = creature->GetGUID(); - break; - case NPC_MIMIRON_VX001: - m_MimironVX001guid = creature->GetGUID(); - break; - case NPC_MIMIRON_ACU: - m_MimironACUguid = creature->GetGUID(); - break; - case NPC_ELDER_IRONBRANCH: - case NPC_ELDER_STONEBARK: - case NPC_ELDER_BRIGHTLEAF: - m_FreyaElder[creature->GetEntry() - NPC_ELDER_IRONBRANCH] = creature->GetGUID(); - break; - case NPC_SARA: - m_saraGUID = creature->GetGUID(); - break; - case NPC_BRAIN_OF_YOGG_SARON: - m_yoggsaronBrainGUID = creature->GetGUID(); - break; - case NPC_BRANN_BRONZBEARD_ALG: - m_brannBronzebeardAlgGUID = creature->GetGUID(); - break; - case NPC_BRANN_BASE_CAMP: - m_brannBronzebeardBaseCamp = creature->GetGUID(); - break; //! These creatures are summoned by something else than Algalon //! but need to be controlled/despawned by him - so they need to be //! registered in his summon list @@ -421,31 +491,36 @@ public: case NPC_ALGALON_STALKER_ASTEROID_TARGET_01: case NPC_ALGALON_STALKER_ASTEROID_TARGET_02: case NPC_UNLEASHED_DARK_MATTER: - if (Creature* algalon = instance->GetCreature(m_uiAlgalonGUID)) + if (Creature* algalon = GetCreature(BOSS_ALGALON)) algalon->AI()->JustSummoned(creature); break; } } - void OnCreatureRemove(Creature* creature) override - { - switch (creature->GetEntry()) - { - case NPC_BRANN_BRONZBEARD_ALG: - if (m_brannBronzebeardAlgGUID == creature->GetGUID()) - m_brannBronzebeardAlgGUID.Clear(); - break; - } - } - void OpenIfDone(uint32 encounter, GameObject* go, GOState state) { - if (GetData(encounter) == DONE) + if (GetBossState(encounter) == DONE) go->SetGoState(state); } + GameObject* GetHodirChest(bool hardmode) + { + if (hardmode) + { + if (GameObject* go = GetGameObject(DATA_HODIR_CHEST_HARD)) + return go; + return GetGameObject(DATA_HODIR_CHEST_HARD_HERO); + } + + if (GameObject* go = GetGameObject(DATA_HODIR_CHEST_NORMAL)) + return go; + return GetGameObject(DATA_HODIR_CHEST_NORMAL_HERO); + } + void OnGameObjectCreate(GameObject* gameObject) override { + InstanceScript::OnGameObjectCreate(gameObject); + switch (gameObject->GetEntry()) { // Flame Leviathan @@ -458,108 +533,61 @@ public: break; } case GO_LIGHTNING_WALL1: - m_lightningWalls[0] = gameObject->GetGUID(); - OpenIfDone(TYPE_LEVIATHAN, gameObject, GO_STATE_ACTIVE); - break; - case GO_LIGHTNING_WALL2: - m_lightningWalls[1] = gameObject->GetGUID(); + OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE); break; case GO_MIMIRONS_TARGETTING_CRYSTAL: - OpenIfDone(TYPE_LEVIATHAN, gameObject, GO_STATE_ACTIVE); + OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE); m_leviathanVisualTowers[3][0] = gameObject->GetGUID(); break; case GO_FREYAS_TARGETTING_CRYSTAL: - OpenIfDone(TYPE_LEVIATHAN, gameObject, GO_STATE_ACTIVE); + OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE); m_leviathanVisualTowers[0][0] = gameObject->GetGUID(); break; case GO_HODIRS_TARGETTING_CRYSTAL: - OpenIfDone(TYPE_LEVIATHAN, gameObject, GO_STATE_ACTIVE); + OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE); m_leviathanVisualTowers[2][0] = gameObject->GetGUID(); break; case GO_THORIMS_TARGETTING_CRYSTAL: - OpenIfDone(TYPE_LEVIATHAN, gameObject, GO_STATE_ACTIVE); + OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE); m_leviathanVisualTowers[1][0] = gameObject->GetGUID(); break; case GO_MIMIRONS_GENERATOR: - OpenIfDone(TYPE_LEVIATHAN, gameObject, GO_STATE_ACTIVE); + OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE); m_leviathanVisualTowers[3][1] = gameObject->GetGUID(); break; case GO_FREYAS_GENERATOR: - OpenIfDone(TYPE_LEVIATHAN, gameObject, GO_STATE_ACTIVE); + OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE); m_leviathanVisualTowers[0][1] = gameObject->GetGUID(); break; case GO_HODIRS_GENERATOR: - OpenIfDone(TYPE_LEVIATHAN, gameObject, GO_STATE_ACTIVE); + OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE); m_leviathanVisualTowers[2][1] = gameObject->GetGUID(); break; case GO_THORIMS_GENERATOR: - OpenIfDone(TYPE_LEVIATHAN, gameObject, GO_STATE_ACTIVE); + OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE); m_leviathanVisualTowers[1][1] = gameObject->GetGUID(); break; case GO_LEVIATHAN_DOORS: - if (GetData(TYPE_LEVIATHAN) >= DONE) + if (GetBossState(BOSS_LEVIATHAN) >= DONE) gameObject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - m_leviathanDoorsGUID = gameObject->GetGUID(); - break; - // XT-002, Kologarn, Assembly of Iron - case GO_XT002_DOORS: - m_xt002DoorsGUID = gameObject->GetGUID(); - break; - case GO_KOLOGARN_DOORS: - KologarnDoorGUID = gameObject->GetGUID(); break; case GO_KOLOGARN_BRIDGE: - OpenIfDone(TYPE_KOLOGARN, gameObject, GO_STATE_READY); - break; - case GO_ASSEMBLY_DOORS: - m_assemblyDoorsGUID = gameObject->GetGUID(); + OpenIfDone(BOSS_KOLOGARN, gameObject, GO_STATE_READY); break; case GO_ARCHIVUM_DOORS: - m_archivumDoorsGUID = gameObject->GetGUID(); - OpenIfDone(TYPE_ASSEMBLY, gameObject, GO_STATE_ACTIVE); - break; - // Thorim - case GO_ARENA_LEVER_GATE: - m_thorimGameobjectsGUID[DATA_THORIM_LEVER_GATE - DATA_THORIM_LEVER_GATE] = gameObject->GetGUID(); - break; - case GO_ARENA_LEVER: - m_thorimGameobjectsGUID[DATA_THORIM_LEVER - DATA_THORIM_LEVER_GATE] = gameObject->GetGUID(); - break; - case GO_ARENA_FENCE: - m_thorimGameobjectsGUID[DATA_THORIM_FENCE - DATA_THORIM_LEVER_GATE] = gameObject->GetGUID(); - break; - case GO_FIRST_COLOSSUS_DOORS: - m_thorimGameobjectsGUID[DATA_THORIM_FIRST_DOORS - DATA_THORIM_LEVER_GATE] = gameObject->GetGUID(); - break; - case GO_SECOND_COLOSSUS_DOORS: - m_thorimGameobjectsGUID[DATA_THORIM_SECOND_DOORS - DATA_THORIM_LEVER_GATE] = gameObject->GetGUID(); - break; - // Yogg-Saron - case GO_YOGG_SARON_DOORS: - m_yoggsaronDoorsGUID = gameObject->GetGUID(); + OpenIfDone(BOSS_ASSEMBLY, gameObject, GO_STATE_ACTIVE); break; case GO_KEEPERS_GATE: - if (GetData(TYPE_MIMIRON) == DONE && GetData(TYPE_FREYA) == DONE && GetData(TYPE_HODIR) == DONE && GetData(TYPE_THORIM) == DONE) + if (GetBossState(BOSS_MIMIRON) == DONE && GetBossState(BOSS_FREYA) == DONE && GetBossState(BOSS_HODIR) == DONE && GetBossState(BOSS_THORIM) == DONE) gameObject->RemoveGameObjectFlag(GO_FLAG_LOCKED); - - m_keepersgateGUID = gameObject->GetGUID(); break; // Mimiron, Hodir, Vezax case GO_MIMIRON_ELEVATOR: gameObject->EnableCollision(false); break; - case GO_MIMIRON_DOOR_1: - m_MimironDoor[0] = gameObject->GetGUID(); - break; - case GO_MIMIRON_DOOR_2: - m_MimironDoor[1] = gameObject->GetGUID(); - break; - case GO_MIMIRON_DOOR_3: - m_MimironDoor[2] = gameObject->GetGUID(); - break; case GO_HODIR_FROZEN_DOOR: case GO_HODIR_DOOR: - if (GetData(TYPE_HODIR) == DONE) + if (GetBossState(BOSS_HODIR) == DONE) if (gameObject->GetGoState() != GO_STATE_ACTIVE ) { gameObject->SetLootState(GO_READY); @@ -567,7 +595,7 @@ public: } break; case GO_VEZAX_DOOR: - if (GetData(TYPE_VEZAX) == DONE ) + if (GetBossState(BOSS_VEZAX) == DONE ) if (gameObject->GetGoState() != GO_STATE_ACTIVE ) { gameObject->SetLootState(GO_READY); @@ -579,27 +607,8 @@ public: break; // Mimiron Tram case GO_MIMIRON_TRAM: - if (GetData(TYPE_MIMIRON) == DONE) + if (GetBossState(BOSS_MIMIRON) == DONE) m_mimironTramUsed = true; - m_mimironTramGUID = gameObject->GetGUID(); - break; - case GO_MIMIRON_TRAM_ROCKET_BOOSTER: - m_mimironTramRocketBoosterGUID = gameObject->GetGUID(); - break; - case GO_MIMIRON_ACTIVATE_TRAM: - m_mimironActivateTramGUID = gameObject->GetGUID(); - break; - case GO_MIMIRON_CALL_TRAM_CENTER: - m_mimironCallTramCenterGUID = gameObject->GetGUID(); - break; - case GO_MIMIRON_CALL_TRAM_MIMIRON: - m_mimironCallTramMimironGUID = gameObject->GetGUID(); - break; - case GO_DOODAD_UL_TRAIN_TURNAROUND01: - m_mimironTramTurnaround1GUID = gameObject->GetGUID(); - break; - case GO_DOODAD_UL_TRAIN_TURNAROUND02: - m_mimironTramTurnaround2GUID = gameObject->GetGUID(); break; // Algalon the Observer case GO_CELESTIAL_PLANETARIUM_ACCESS_10: @@ -608,37 +617,20 @@ public: gameObject->SetGameObjectFlag(GO_FLAG_IN_USE); break; case GO_DOODAD_UL_SIGILDOOR_01: - m_algalonSigilDoorGUID[0] = gameObject->GetGUID(); if (m_algalonTimer) gameObject->SetGoState(GO_STATE_ACTIVE); break; case GO_DOODAD_UL_SIGILDOOR_02: - m_algalonSigilDoorGUID[1] = gameObject->GetGUID(); if (m_algalonTimer) gameObject->SetGoState(GO_STATE_ACTIVE); break; - case GO_DOODAD_UL_SIGILDOOR_03: - m_algalonSigilDoorGUID[2] = gameObject->GetGUID(); - break; - case GO_DOODAD_UL_UNIVERSEFLOOR_01: - m_algalonFloorGUID[0] = gameObject->GetGUID(); - break; - case GO_DOODAD_UL_UNIVERSEFLOOR_02: - m_algalonFloorGUID[1] = gameObject->GetGUID(); - break; - case GO_DOODAD_UL_UNIVERSEGLOBE01: - m_algalonUniverseGUID = gameObject->GetGUID(); - break; - case GO_DOODAD_UL_ULDUAR_TRAPDOOR_03: - m_algalonTrapdoorGUID = gameObject->GetGUID(); - break; // Herbs case 191019: // Adder's Tongue case 190176: // Frost Lotus case 190171: // Lichbloom case 190170: // Talandra's Rose case 189973: // Goldclover - if (GetData(TYPE_FREYA) == DONE) + if (GetBossState(BOSS_FREYA) == DONE) gameObject->SetRespawnTime(7 * DAY); break; } @@ -650,16 +642,16 @@ public: { switch (boss) { - case TYPE_HODIR: + case BOSS_HODIR: if (hmHodir) { - if (GameObject* go = instance->GetGameObject(m_hodirHardmodeChest)) + if (GameObject* go = GetHodirChest(true)) { go->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); go->SetLootRecipient(instance); } } - if (GameObject* go = instance->GetGameObject(m_hodirNormalChest)) + if (GameObject* go = GetHodirChest(false)) { go->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); go->SetLootRecipient(instance); @@ -673,74 +665,18 @@ public: { switch (type) { - case TYPE_LEVIATHAN: - m_auiEncounter[type] = data; - if (data == DONE) - { - Map::PlayerList const& pList = instance->GetPlayers(); - for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) - { - if (Creature* vehicleCreature = itr->GetSource()->GetVehicleCreatureBase()) - { - vehicleCreature->DespawnOrUnsummon(); - } - } - } - break; - case TYPE_IGNIS: - case TYPE_RAZORSCALE: - case TYPE_XT002: - case TYPE_AURIAYA: - case TYPE_VEZAX: - case TYPE_YOGGSARON: - case TYPE_KOLOGARN: - m_auiEncounter[type] = data; - break; - case TYPE_ASSEMBLY: - if (GameObject* go = instance->GetGameObject(m_assemblyDoorsGUID)) - go->SetGoState(data == IN_PROGRESS ? GO_STATE_READY : GO_STATE_ACTIVE); - if (GameObject* go = instance->GetGameObject(m_archivumDoorsGUID)) - go->SetGoState(data == DONE ? GO_STATE_ACTIVE : GO_STATE_READY); - - m_auiEncounter[type] = data; - break; - case TYPE_MIMIRON: - case TYPE_HODIR: - case TYPE_THORIM: - case TYPE_FREYA: - m_auiEncounter[type] = data; - if (GetData(TYPE_MIMIRON) == DONE && GetData(TYPE_FREYA) == DONE && GetData(TYPE_HODIR) == DONE && GetData(TYPE_THORIM) == DONE) - { - scheduler.Schedule(45s, [this](TaskContext /*context*/) - { - if (GameObject* go = instance->GetGameObject(m_keepersgateGUID)) - { - go->RemoveGameObjectFlag(GO_FLAG_LOCKED); - if (Creature* trigger = instance->SummonCreature(NPC_ANCIENT_GATE_WORLD_TRIGGER, triggerAncientGatePosition, nullptr, 10*IN_MILLISECONDS)) - { - trigger->AI()->Talk(EMOTE_ANCIENT_GATE_UNLOCKED); - } - } - }); - } - if (type == TYPE_MIMIRON && data == IN_PROGRESS) // after reaching him without tram and starting the fight - m_mimironTramUsed = true; - if (GetData(TYPE_HODIR) == DONE) - setChestsLootable(TYPE_HODIR); - break; case TYPE_HODIR_HM_FAIL: - if (GameObject* go = instance->GetGameObject(m_hodirHardmodeChest)) + if (GameObject* go = GetHodirChest(true)) { hmHodir = false; go->Delete(); - m_hodirHardmodeChest.Clear(); } break; case TYPE_WATCHERS: - m_auiEncounter[type] |= 1 << data; + m_watchersMask |= 1 << data; [[fallthrough]]; case EVENT_KEEPER_TELEPORTED: - if (Creature* sara = instance->GetCreature(m_saraGUID)) + if (Creature* sara = GetCreature(DATA_SARA)) sara->AI()->DoAction(ACTION_SARA_UPDATE_SUMMON_KEEPERS); break; case DATA_MAGE_BARRIER: @@ -784,98 +720,66 @@ public: _events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER); SaveToDB(); return; - case TYPE_ALGALON: - m_auiEncounter[type] = data; - if (GameObject* go = instance->GetGameObject(GetGuidData(GO_DOODAD_UL_SIGILDOOR_03))) - { - go->SetGoState(data != IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY); - go->EnableCollision(false); - } - if (GameObject* go = instance->GetGameObject(GetGuidData(GO_DOODAD_UL_UNIVERSEFLOOR_01))) - { - go->SetGoState(data != IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY); - go->EnableCollision(false); - } - if (GameObject* go = instance->GetGameObject(GetGuidData(GO_DOODAD_UL_UNIVERSEFLOOR_02))) - { - go->SetGoState(data == IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY); - go->EnableCollision(false); - } - if (GameObject* go = instance->GetGameObject(GetGuidData(GO_DOODAD_UL_UNIVERSEGLOBE01))) - { - go->SetGoState(data == IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY); - go->EnableCollision(false); - } - if (GameObject* go = instance->GetGameObject(GetGuidData(GO_DOODAD_UL_ULDUAR_TRAPDOOR_03))) - { - go->SetGoState(data == IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY); - go->EnableCollision(false); - } - - break; - // Achievement case DATA_DWARFAGEDDON: DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, SPELL_DWARFAGEDDON); DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_DWARFAGEDDON); return; case DATA_CALL_TRAM: - if (GameObject* MimironTram = instance->GetGameObject(m_mimironTramGUID)) + if (GameObject* MimironTram = GetGameObject(DATA_MIMIRON_TRAM)) if (StaticTransport* t = MimironTram->ToStaticTransport()) { if (data == 0 && t->GetGoState() == GO_STATE_ACTIVE && t->GetPathProgress() == t->GetPauseTime()) { MimironTram->SetGoState(GO_STATE_READY); - if (GameObject* rocketBooster = instance->GetGameObject(m_mimironTramRocketBoosterGUID)) + if (GameObject* rocketBooster = GetGameObject(DATA_MIMIRON_TRAM_ROCKET_BOOSTER)) rocketBooster->SetGoState(GO_STATE_ACTIVE); - if (GameObject* activateTramButton = instance->GetGameObject(m_mimironActivateTramGUID)) + if (GameObject* activateTramButton = GetGameObject(DATA_MIMIRON_ACTIVATE_TRAM)) activateTramButton->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - if (GameObject* callTramCenterButton = instance->GetGameObject(m_mimironCallTramCenterGUID)) + if (GameObject* callTramCenterButton = GetGameObject(DATA_MIMIRON_CALL_TRAM_CENTER)) callTramCenterButton->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); scheduler.Schedule(30s, [this](TaskContext /*context*/) { - if (GameObject* turnaround1 = instance->GetGameObject(m_mimironTramTurnaround1GUID)) + if (GameObject* turnaround1 = GetGameObject(DATA_MIMIRON_TRAM_TURNAROUND_1)) turnaround1->UseDoorOrButton(); - if (GameObject* rocketBooster = instance->GetGameObject(m_mimironTramRocketBoosterGUID)) + if (GameObject* rocketBooster = GetGameObject(DATA_MIMIRON_TRAM_ROCKET_BOOSTER)) rocketBooster->SetGoState(GO_STATE_READY); }).Schedule(60s, [this](TaskContext /*context*/) { - if (GameObject* activateTramButton = instance->GetGameObject(m_mimironActivateTramGUID)) + if (GameObject* activateTramButton = GetGameObject(DATA_MIMIRON_ACTIVATE_TRAM)) activateTramButton->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - if (GameObject* callTramMimironButton = instance->GetGameObject(m_mimironCallTramMimironGUID)) + if (GameObject* callTramMimironButton = GetGameObject(DATA_MIMIRON_CALL_TRAM_MIMIRON)) callTramMimironButton->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); }); } if (data == 1 && t->GetGoState() == GO_STATE_READY && t->GetPathProgress() == 0) { MimironTram->SetGoState(GO_STATE_ACTIVE); - if (GameObject* rocketBooster = instance->GetGameObject(m_mimironTramRocketBoosterGUID)) + if (GameObject* rocketBooster = GetGameObject(DATA_MIMIRON_TRAM_ROCKET_BOOSTER)) rocketBooster->SetGoState(GO_STATE_ACTIVE); - if (GameObject* activateTramButton = instance->GetGameObject(m_mimironActivateTramGUID)) + if (GameObject* activateTramButton = GetGameObject(DATA_MIMIRON_ACTIVATE_TRAM)) activateTramButton->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - if (GameObject* callTramMimironButton = instance->GetGameObject(m_mimironCallTramMimironGUID)) + if (GameObject* callTramMimironButton = GetGameObject(DATA_MIMIRON_CALL_TRAM_MIMIRON)) callTramMimironButton->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); scheduler.Schedule(33s, [this](TaskContext /*context*/) { - if (GameObject* turnaround2 = instance->GetGameObject(m_mimironTramTurnaround2GUID)) + if (GameObject* turnaround2 = GetGameObject(DATA_MIMIRON_TRAM_TURNAROUND_2)) turnaround2->UseDoorOrButton(); - if (GameObject* rocketBooster = instance->GetGameObject(m_mimironTramRocketBoosterGUID)) + if (GameObject* rocketBooster = GetGameObject(DATA_MIMIRON_TRAM_ROCKET_BOOSTER)) rocketBooster->SetGoState(GO_STATE_READY); }).Schedule(63s, [this](TaskContext /*context*/) { - if (GameObject* activateTramButton = instance->GetGameObject(m_mimironActivateTramGUID)) + if (GameObject* activateTramButton = GetGameObject(DATA_MIMIRON_ACTIVATE_TRAM)) activateTramButton->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - if (GameObject* callTramCenterButton = instance->GetGameObject(m_mimironCallTramCenterGUID)) + if (GameObject* callTramCenterButton = GetGameObject(DATA_MIMIRON_CALL_TRAM_CENTER)) callTramCenterButton->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); }); } } break; case DATA_BRANN_MEMOTESAY: - if (Creature* cr = instance->GetCreature(m_brannBronzebeardBaseCamp)) - { + if (Creature* cr = GetCreature(DATA_BRANN_BASE_CAMP)) cr->TextEmote("Go to your vehicles!", nullptr, true); - } break; case DATA_BRANN_EASY_MODE: ProcessEvent(nullptr, EVENT_TOWER_OF_STORM_DESTROYED); @@ -885,88 +789,19 @@ public: break; } - // take care of herbs - if (type == TYPE_FREYA && data == DONE) - { - std::list goList; - if (Creature* freya = instance->GetCreature(GetGuidData(TYPE_FREYA))) - { - freya->GetGameObjectListWithEntryInGrid(goList, 191019 /*Adder's Tongue*/, 333.0f); - freya->GetGameObjectListWithEntryInGrid(goList, 190176 /*Frost Lotus*/, 333.0f); - freya->GetGameObjectListWithEntryInGrid(goList, 190171 /*Lichbloom*/, 333.0f); - freya->GetGameObjectListWithEntryInGrid(goList, 190170 /*Talandra's Rose*/, 333.0f); - freya->GetGameObjectListWithEntryInGrid(goList, 189973 /*Goldclover*/, 333.0f); - - for (std::list::const_iterator itr = goList.begin(); itr != goList.end(); ++itr) - (*itr)->SetRespawnTime(7 * DAY); - } - } - - if (data == DONE || type == TYPE_LEVIATHAN || type == TYPE_WATCHERS) + if (type == TYPE_WATCHERS) SaveToDB(); - - if (type > TYPE_LEVIATHAN && type < TYPE_WATCHERS && data == IN_PROGRESS) - { - Map::PlayerList const& pList = instance->GetPlayers(); - for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) - { - if (Creature* vehicleCreature = itr->GetSource()->GetVehicleCreatureBase()) - { - vehicleCreature->DespawnOrUnsummon(); - } - } - } } ObjectGuid GetGuidData(uint32 data) const override { switch (data) { - // Bosses - case TYPE_LEVIATHAN: - return m_uiLeviathanGUID; - case TYPE_IGNIS: - return m_uiIgnisGUID; - case TYPE_RAZORSCALE: - return m_uiRazorscaleGUID; - case TYPE_XT002: - return m_uiXT002GUID; - case TYPE_KOLOGARN: - return m_uiKologarnGUID; - case TYPE_AURIAYA: - return m_uiAuriayaGUID; - case TYPE_MIMIRON: - return m_uiMimironGUID; - case TYPE_HODIR: - return m_uiHodirGUID; - case TYPE_THORIM: - return m_uiThorimGUID; - case TYPE_FREYA: - return m_uiFreyaGUID; - case TYPE_VEZAX: - return m_uiVezaxGUID; - case TYPE_YOGGSARON: - return m_uiYoggSaronGUID; - case TYPE_ALGALON: - return m_uiAlgalonGUID; - case DATA_STEELBREAKER: - return m_auiAssemblyGUIDs[0]; - case DATA_MOLGEIM: - return m_auiAssemblyGUIDs[1]; - case DATA_BRUNDIR: - return m_auiAssemblyGUIDs[2]; - // Flame Leviathan case DATA_REPAIR_STATION1: return m_RepairSGUID[0]; case DATA_REPAIR_STATION2: return m_RepairSGUID[1]; - case DATA_LIGHTNING_WALL1: - return m_lightningWalls[0]; - case DATA_LIGHTNING_WALL2: - return m_lightningWalls[1]; - case GO_LEVIATHAN_DOORS: - return m_leviathanDoorsGUID; // Razorscales Harpoon Fire State GUIDs case DATA_HARPOON_FIRE_STATE_1: @@ -974,95 +809,17 @@ public: case DATA_HARPOON_FIRE_STATE_3: case DATA_HARPOON_FIRE_STATE_4: return m_RazorscaleHarpoonFireStateGUID[data - 200]; - - // XT-002 - case GO_XT002_DOORS: - return m_xt002DoorsGUID; - // XT-002 - case GO_KOLOGARN_DOORS: - return KologarnDoorGUID; - // Thorim - case DATA_THORIM_LEVER_GATE: - case DATA_THORIM_LEVER: - case DATA_THORIM_FENCE: - case DATA_THORIM_FIRST_DOORS: - case DATA_THORIM_SECOND_DOORS: - return m_thorimGameobjectsGUID[data - DATA_THORIM_LEVER_GATE]; - - // Hodir chests - case GO_HODIR_CHEST_HARD: - return m_hodirHardmodeChest; - case GO_HODIR_CHEST_NORMAL: - return m_hodirNormalChest; - - // Freya Elders - case NPC_ELDER_IRONBRANCH: - case NPC_ELDER_STONEBARK: - case NPC_ELDER_BRIGHTLEAF: - return m_FreyaElder[data - NPC_ELDER_IRONBRANCH]; - - // Mimiron's first vehicle (spawned by default) - case DATA_MIMIRON_LEVIATHAN_MKII: - return m_MimironLeviathanMKIIguid; - case DATA_MIMIRON_VX001: - return m_MimironVX001guid; - case DATA_MIMIRON_ACU: - return m_MimironACUguid; - case DATA_GO_MIMIRON_DOOR_1: - case DATA_GO_MIMIRON_DOOR_2: - case DATA_GO_MIMIRON_DOOR_3: - return m_MimironDoor[data - 311]; - - // Yogg-Saron - case GO_YOGG_SARON_DOORS: - return m_yoggsaronDoorsGUID; - case NPC_SARA: - return m_saraGUID; - case NPC_BRAIN_OF_YOGG_SARON: - return m_yoggsaronBrainGUID; - - // Algalon the Observer - case GO_DOODAD_UL_SIGILDOOR_01: - return m_algalonSigilDoorGUID[0]; - case GO_DOODAD_UL_SIGILDOOR_02: - return m_algalonSigilDoorGUID[1]; - case GO_DOODAD_UL_SIGILDOOR_03: - return m_algalonSigilDoorGUID[2]; - case GO_DOODAD_UL_UNIVERSEFLOOR_01: - return m_algalonFloorGUID[0]; - case GO_DOODAD_UL_UNIVERSEFLOOR_02: - return m_algalonFloorGUID[1]; - case GO_DOODAD_UL_UNIVERSEGLOBE01: - return m_algalonUniverseGUID; - case GO_DOODAD_UL_ULDUAR_TRAPDOOR_03: - return m_algalonTrapdoorGUID; - case NPC_BRANN_BRONZBEARD_ALG: - return m_brannBronzebeardAlgGUID; } - return ObjectGuid::Empty; + return GetObjectGuid(data); } uint32 GetData(uint32 type) const override { switch (type) { - case TYPE_LEVIATHAN: - case TYPE_IGNIS: - case TYPE_RAZORSCALE: - case TYPE_XT002: - case TYPE_ASSEMBLY: - case TYPE_KOLOGARN: - case TYPE_AURIAYA: - case TYPE_MIMIRON: - case TYPE_HODIR: - case TYPE_THORIM: - case TYPE_FREYA: - case TYPE_VEZAX: - case TYPE_YOGGSARON: - case TYPE_ALGALON: case TYPE_WATCHERS: - return m_auiEncounter[type]; + return m_watchersMask; case EVENT_TOWER_OF_LIFE_DESTROYED: case EVENT_TOWER_OF_STORM_DESTROYED: @@ -1088,8 +845,8 @@ public: // Feeds on Tears achievement if (unit->IsPlayer()) { - if (GetData(TYPE_ALGALON) == IN_PROGRESS) - if (Creature* algalon = instance->GetCreature(m_uiAlgalonGUID)) + if (GetBossState(BOSS_ALGALON) == IN_PROGRESS) + if (Creature* algalon = GetCreature(BOSS_ALGALON)) algalon->AI()->DoAction(ACTION_FEEDS_ON_TEARS_FAILED); } else if (unit->IsCreature() && unit->GetAreaId() == AREA_THE_CONSERVATORY_OF_LIFE) @@ -1107,14 +864,14 @@ public: for (uint8 i = 0; i <= 12; ++i) { bool go = false; - if (i == TYPE_LEVIATHAN) + if (i == BOSS_LEVIATHAN) { - if (Creature* c = instance->GetCreature(m_uiLeviathanGUID)) + if (Creature* c = GetCreature(BOSS_LEVIATHAN)) if (c->IsInCombat()) go = true; } else - go = (m_auiEncounter[i] == IN_PROGRESS); + go = (GetBossState(i) == IN_PROGRESS); if (go && (C_of_Ulduar_MASK & (1 << i)) == 0) { @@ -1126,21 +883,8 @@ public: void ReadSaveDataMore(std::istringstream& data) override { - data >> m_auiEncounter[0]; - data >> m_auiEncounter[1]; - data >> m_auiEncounter[2]; - data >> m_auiEncounter[3]; - data >> m_auiEncounter[4]; - data >> m_auiEncounter[5]; - data >> m_auiEncounter[6]; - data >> m_auiEncounter[7]; - data >> m_auiEncounter[8]; - data >> m_auiEncounter[9]; - data >> m_auiEncounter[10]; - data >> m_auiEncounter[11]; - data >> m_auiEncounter[12]; - data >> m_auiEncounter[13]; - data >> m_auiEncounter[14]; + // Boss states 0-13 are read by base InstanceScript. + data >> m_watchersMask; data >> m_conspeedatoryAttempt; data >> m_unbrokenAchievement; data >> m_algalonTimer; @@ -1148,7 +892,7 @@ public: if (m_algalonTimer == TIMER_ALGALON_SUMMONED) m_algalonTimer = TIMER_ALGALON_TO_SUMMON; - if (m_algalonTimer && m_algalonTimer <= 60 && GetData(TYPE_ALGALON) != DONE) + if (m_algalonTimer && m_algalonTimer <= 60 && GetBossState(BOSS_ALGALON) != DONE) { DoUpdateWorldState(WORLD_STATE_ULDUAR_ALGALON_TIMER_ENABLED, 1); DoUpdateWorldState(WORLD_STATE_ULDUAR_ALGALON_DESPAWN_TIMER, m_algalonTimer); @@ -1156,23 +900,18 @@ public: data >> C_of_Ulduar_MASK; data >> m_mageBarrier; - - for (uint8 i = 0; i < (MAX_ENCOUNTER - 1); ++i) - { - if (m_auiEncounter[i] == IN_PROGRESS) - { - m_auiEncounter[i] = NOT_STARTED; - } - } } void WriteSaveDataMore(std::ostringstream& data) override { - data << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' ' << m_auiEncounter[3] << ' ' - << m_auiEncounter[4] << ' ' << m_auiEncounter[5] << ' ' << m_auiEncounter[6] << ' ' << m_auiEncounter[7] << ' ' - << m_auiEncounter[8] << ' ' << m_auiEncounter[9] << ' ' << m_auiEncounter[10] << ' ' << m_auiEncounter[11] << ' ' - << m_auiEncounter[12] << ' ' << m_auiEncounter[13] << ' ' << m_auiEncounter[14] << ' ' << m_conspeedatoryAttempt << ' ' - << m_unbrokenAchievement << ' ' << m_algalonTimer << ' ' << C_of_Ulduar_MASK << ' ' << m_mageBarrier; + // Boss states 0-13 are written by base InstanceScript. + // Only write extra non-boss data here. + data << m_watchersMask << ' ' + << m_conspeedatoryAttempt << ' ' + << m_unbrokenAchievement << ' ' + << m_algalonTimer << ' ' + << C_of_Ulduar_MASK << ' ' + << m_mageBarrier; } void Update(uint32 diff) override @@ -1187,9 +926,7 @@ public: { case EVENT_UPDATE_ALGALON_TIMER: if (m_algalonTimer == TIMER_ALGALON_DEFEATED) - { return; - } SaveToDB(); DoUpdateWorldState(WORLD_STATE_ULDUAR_ALGALON_DESPAWN_TIMER, --m_algalonTimer); @@ -1200,7 +937,7 @@ public: } SetData(DATA_ALGALON_DEFEATED, 1); - if (Creature* algalon = instance->GetCreature(m_uiAlgalonGUID)) + if (Creature* algalon = GetCreature(BOSS_ALGALON)) algalon->AI()->DoAction(ACTION_DESPAWN_ALGALON); } } @@ -1213,43 +950,43 @@ public: { case 10042: case 10352: - return (C_of_Ulduar_MASK & (1 << TYPE_LEVIATHAN)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_LEVIATHAN)) == 0; case 10342: case 10355: - return (C_of_Ulduar_MASK & (1 << TYPE_IGNIS)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_IGNIS)) == 0; case 10340: case 10353: - return (C_of_Ulduar_MASK & (1 << TYPE_RAZORSCALE)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_RAZORSCALE)) == 0; case 10341: case 10354: - return (C_of_Ulduar_MASK & (1 << TYPE_XT002)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_XT002)) == 0; case 10598: case 10599: - return (C_of_Ulduar_MASK & (1 << TYPE_ASSEMBLY)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_ASSEMBLY)) == 0; case 10348: case 10357: - return (C_of_Ulduar_MASK & (1 << TYPE_KOLOGARN)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_KOLOGARN)) == 0; case 10351: case 10363: - return (C_of_Ulduar_MASK & (1 << TYPE_AURIAYA)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_AURIAYA)) == 0; case 10439: case 10719: - return (C_of_Ulduar_MASK & (1 << TYPE_HODIR)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_HODIR)) == 0; case 10403: case 10404: - return (C_of_Ulduar_MASK & (1 << TYPE_THORIM)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_THORIM)) == 0; case 10582: case 10583: - return (C_of_Ulduar_MASK & (1 << TYPE_FREYA)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_FREYA)) == 0; case 10347: case 10361: - return (C_of_Ulduar_MASK & (1 << TYPE_MIMIRON)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_MIMIRON)) == 0; case 10349: case 10362: - return (C_of_Ulduar_MASK & (1 << TYPE_VEZAX)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_VEZAX)) == 0; case 10350: case 10364: - return (C_of_Ulduar_MASK & (1 << TYPE_YOGGSARON)) == 0; + return (C_of_Ulduar_MASK & (1 << BOSS_YOGGSARON)) == 0; } return false; } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp index f38f49e2b..4a72bf5ab 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp @@ -300,56 +300,148 @@ private: uint8 _counter; }; -class npc_ulduar_storm_tempered_keeper : public CreatureScript +struct npc_ulduar_storm_tempered_keeper : public ScriptedAI { -public: - npc_ulduar_storm_tempered_keeper() : CreatureScript("npc_ulduar_storm_tempered_keeper") { } - - CreatureAI* GetAI(Creature* creature) const override + npc_ulduar_storm_tempered_keeper(Creature* creature) : ScriptedAI(creature) { - return GetUlduarAI(creature); + otherGUID.Clear(); } - struct npc_ulduar_storm_tempered_keeperAI : public ScriptedAI + EventMap events; + ObjectGuid otherGUID; + + void Reset() override { - npc_ulduar_storm_tempered_keeperAI(Creature* creature) : ScriptedAI(creature) + events.Reset(); + } + + void JustEngagedWith(Unit* /*who*/) override + { + events.Reset(); + events.ScheduleEvent(1, 2s); // checking Separation Anxiety, Charged Sphere + events.ScheduleEvent(2, 5s, 8s); // Forked Lightning + events.ScheduleEvent(3, (me->GetEntry() == 33722 ? 20s : 50s)); // Summon Charged Sphere + if (Creature* c = me->FindNearestCreature((me->GetEntry() == 33722 ? 33699 : 33722), 30.0f, true)) + otherGUID = c->GetGUID(); + else + me->CastSpell(me, 63630, true); // Vengeful Surge + } + + void JustDied(Unit* /*killer*/) override + { + if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID)) + c->CastSpell(c, 63630, true); // Vengeful Surge + } + + void JustSummoned(Creature* s) override + { + if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID)) + s->GetMotionMaster()->MoveFollow(c, 0.0f, 0.0f); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - otherGUID.Clear(); + case 0: + break; + case 1: + if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID)) + if (c->IsAlive() && me->GetExactDist2d(c) > 45.0f) + me->CastSpell(me, 63539, true); + if (Creature* c = me->FindNearestCreature(33715, 2.0f, true)) + if (c->IsSummon()) + if (c->ToTempSummon()->GetSummonerGUID() != me->GetGUID()) + me->CastSpell(me, 63528, true); + events.Repeat(2s); + break; + case 2: + me->CastSpell(me->GetVictim(), 63541, false); + events.Repeat(10s, 14s); + break; + case 3: + if (!me->HasAura(63630)) + me->CastSpell(me, 63527, false); + events.Repeat(1min); + break; } - EventMap events; - ObjectGuid otherGUID; + DoMeleeAttackIfReady(); + } +}; - void Reset() override +struct npc_ulduar_arachnopod_destroyer : public ScriptedAI +{ + npc_ulduar_arachnopod_destroyer(Creature* creature) : ScriptedAI(creature) + { + _spawnedMechanic = false; + me->ApplySpellImmune(0, IMMUNITY_ID, 64919, true); // Ice Nova from Ice Turret + } + + EventMap events; + bool _spawnedMechanic; + + void Reset() override + { + events.Reset(); + events.ScheduleEvent(1, 5s, 8s); // Flame Spray + events.ScheduleEvent(2, 3s, 6s); // Machine Gun + events.ScheduleEvent(3, 1s); // Charged Leap + } + + void PassengerBoarded(Unit* p, int8 /*seat*/, bool /*apply*/) override + { + me->SetFaction(p->GetFaction()); + me->SetReactState(REACT_PASSIVE); + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (!_spawnedMechanic && me->HealthBelowPctDamaged(20, damage)) { - events.Reset(); + _spawnedMechanic = true; + if (Creature* c = me->SummonCreature(34184, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN, 0)) + c->AI()->AttackStart(me->GetVictim()); + me->InterruptNonMeleeSpells(false); + me->CombatStop(true); + me->SetReactState(REACT_PASSIVE); + me->SetRegeneratingHealth(false); + me->SetFaction(FACTION_PREY); + me->SetNpcFlag(UNIT_NPC_FLAG_SPELLCLICK); + me->CastSpell(me, 64770, true); } + } - void JustEngagedWith(Unit* /*who*/) override + void AttackStart(Unit* who) override + { + if (me->GetFaction() == FACTION_MONSTER_2) + ScriptedAI::AttackStart(who); + } + + void EnterEvadeMode(EvadeReason why) override + { + if (me->GetFaction() == FACTION_MONSTER_2) + ScriptedAI::EnterEvadeMode(why); + } + + void OnCharmed(bool /*apply*/) override {} + + void UpdateAI(uint32 diff) override + { + if (me->GetFaction() != FACTION_MONSTER_2) { - events.Reset(); - events.ScheduleEvent(1, 2s); // checking Separation Anxiety, Charged Sphere - events.ScheduleEvent(2, 5s, 8s); // Forked Lightning - events.ScheduleEvent(3, (me->GetEntry() == 33722 ? 20s : 50s)); // Summon Charged Sphere - if (Creature* c = me->FindNearestCreature((me->GetEntry() == 33722 ? 33699 : 33722), 30.0f, true)) - otherGUID = c->GetGUID(); - else - me->CastSpell(me, 63630, true); // Vengeful Surge + if (me->IsAlive() && (me->GetExactDist2dSq(2058.0f, 42.0f) < 25.0f * 25.0f || me->GetExactDist2dSq(2203.0f, 292.0f) < 25.0f * 25.0f || me->GetExactDist2dSq(2125.0f, 170.0f) > 160.0f * 160.0f)) + Unit::Kill(me, me, false); } - - void JustDied(Unit* /*killer*/) override - { - if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID)) - c->CastSpell(c, 63630, true); // Vengeful Surge - } - - void JustSummoned(Creature* s) override - { - if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID)) - s->GetMotionMaster()->MoveFollow(c, 0.0f, 0.0f); - } - - void UpdateAI(uint32 diff) override + else { if (!UpdateVictim()) return; @@ -364,144 +456,30 @@ public: case 0: break; case 1: - if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID)) - if (c->IsAlive() && me->GetExactDist2d(c) > 45.0f) - me->CastSpell(me, 63539, true); - if (Creature* c = me->FindNearestCreature(33715, 2.0f, true)) - if (c->IsSummon()) - if (c->ToTempSummon()->GetSummonerGUID() != me->GetGUID()) - me->CastSpell(me, 63528, true); - events.Repeat(2s); + me->CastSpell(me->GetVictim(), SPELL_FLAME_SPRAY, false); + events.Repeat(15s, 25s); break; case 2: - me->CastSpell(me->GetVictim(), 63541, false); - events.Repeat(10s, 14s); + me->CastSpell(me->GetVictim(), SPELL_MACHINE_GUN, false); + events.Repeat(10s, 15s); break; case 3: - if (!me->HasAura(63630)) - me->CastSpell(me, 63527, false); - events.Repeat(1min); + { + float dist = me->GetDistance(me->GetVictim()); + if (dist > 10.0f && dist < 40.0f) + { + me->CastSpell(me->GetVictim(), 64779, false); + events.Repeat(25s); + } + else + events.Repeat(3s); + } break; } DoMeleeAttackIfReady(); } - }; -}; - -class npc_ulduar_arachnopod_destroyer : public CreatureScript -{ -public: - npc_ulduar_arachnopod_destroyer() : CreatureScript("npc_ulduar_arachnopod_destroyer") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI(creature); } - - struct npc_ulduar_arachnopod_destroyerAI : public ScriptedAI - { - npc_ulduar_arachnopod_destroyerAI(Creature* creature) : ScriptedAI(creature) - { - _spawnedMechanic = false; - me->ApplySpellImmune(0, IMMUNITY_ID, 64919, true); // Ice Nova from Ice Turret - } - - EventMap events; - bool _spawnedMechanic; - - void Reset() override - { - events.Reset(); - events.ScheduleEvent(1, 5s, 8s); // Flame Spray - events.ScheduleEvent(2, 3s, 6s); // Machine Gun - events.ScheduleEvent(3, 1s); // Charged Leap - } - - void PassengerBoarded(Unit* p, int8 /*seat*/, bool /*apply*/) override - { - me->SetFaction(p->GetFaction()); - me->SetReactState(REACT_PASSIVE); - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (!_spawnedMechanic && me->HealthBelowPctDamaged(20, damage)) - { - _spawnedMechanic = true; - if (Creature* c = me->SummonCreature(34184, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN, 0)) - c->AI()->AttackStart(me->GetVictim()); - me->InterruptNonMeleeSpells(false); - me->CombatStop(true); - me->SetReactState(REACT_PASSIVE); - me->SetRegeneratingHealth(false); - me->SetFaction(FACTION_PREY); - me->SetNpcFlag(UNIT_NPC_FLAG_SPELLCLICK); - me->CastSpell(me, 64770, true); - } - } - - void AttackStart(Unit* who) override - { - if (me->GetFaction() == FACTION_MONSTER_2) - ScriptedAI::AttackStart(who); - } - - void EnterEvadeMode(EvadeReason why) override - { - if (me->GetFaction() == FACTION_MONSTER_2) - ScriptedAI::EnterEvadeMode(why); - } - - void OnCharmed(bool /*apply*/) override {} - - void UpdateAI(uint32 diff) override - { - if (me->GetFaction() != FACTION_MONSTER_2) - { - if (me->IsAlive() && (me->GetExactDist2dSq(2058.0f, 42.0f) < 25.0f * 25.0f || me->GetExactDist2dSq(2203.0f, 292.0f) < 25.0f * 25.0f || me->GetExactDist2dSq(2125.0f, 170.0f) > 160.0f * 160.0f)) - Unit::Kill(me, me, false); - } - else - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case 1: - me->CastSpell(me->GetVictim(), SPELL_FLAME_SPRAY, false); - events.Repeat(15s, 25s); - break; - case 2: - me->CastSpell(me->GetVictim(), SPELL_MACHINE_GUN, false); - events.Repeat(10s, 15s); - break; - case 3: - { - float dist = me->GetDistance(me->GetVictim()); - if (dist > 10.0f && dist < 40.0f) - { - me->CastSpell(me->GetVictim(), 64779, false); - events.Repeat(25s); - } - else - events.Repeat(3s); - } - break; - } - - DoMeleeAttackIfReady(); - } - } - }; }; class spell_ulduar_arachnopod_damaged_aura : public AuraScript @@ -571,8 +549,8 @@ void AddSC_ulduar() new npc_ulduar_keeper(); RegisterSpellScript(spell_ulduar_energy_sap_aura); RegisterUlduarCreatureAI(npc_ulduar_snow_mound); - new npc_ulduar_storm_tempered_keeper(); - new npc_ulduar_arachnopod_destroyer(); + RegisterUlduarCreatureAI(npc_ulduar_storm_tempered_keeper); + RegisterUlduarCreatureAI(npc_ulduar_arachnopod_destroyer); RegisterSpellScript(spell_ulduar_arachnopod_damaged_aura); new AreaTrigger_at_celestial_planetarium_enterance(); RegisterCreatureAI(npc_salvaged_siege_engine); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index 797f6b61f..f443536ea 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -25,31 +25,38 @@ #define UlduarScriptName "instance_ulduar" -enum UlduarEncounters +enum UlduarBossIds { - MAX_ENCOUNTER = 15, - - TYPE_LEVIATHAN = 0, - TYPE_IGNIS = 1, - TYPE_RAZORSCALE = 2, - TYPE_XT002 = 3, - TYPE_ASSEMBLY = 4, - TYPE_KOLOGARN = 5, - TYPE_AURIAYA = 6, - TYPE_FREYA = 7, - TYPE_HODIR = 8, - TYPE_MIMIRON = 9, - TYPE_THORIM = 10, - TYPE_VEZAX = 11, - TYPE_YOGGSARON = 12, - TYPE_ALGALON = 13, - TYPE_WATCHERS = 14, - TYPE_HODIR_HM_FAIL = 15, - TYPE_WINTER_CACHE = 16 + // Boss IDs used by SetBossNumber/SetBossState (0-indexed) + BOSS_LEVIATHAN = 0, + BOSS_IGNIS = 1, + BOSS_RAZORSCALE = 2, + BOSS_XT002 = 3, + BOSS_ASSEMBLY = 4, + BOSS_KOLOGARN = 5, + BOSS_AURIAYA = 6, + BOSS_FREYA = 7, + BOSS_HODIR = 8, + BOSS_MIMIRON = 9, + BOSS_THORIM = 10, + BOSS_VEZAX = 11, + BOSS_YOGGSARON = 12, + BOSS_ALGALON = 13, + MAX_ENCOUNTER = 14 }; enum UlduarData { + // Non-boss encounter data + TYPE_WATCHERS = 14, + TYPE_HODIR_HM_FAIL = 15, + TYPE_WINTER_CACHE = 16, + + // Assembly of Iron + DATA_STEELBREAKER = 20, + DATA_MOLGEIM = 21, + DATA_BRUNDIR = 22, + // Flame Leviathan DATA_VEHICLE_SPAWN = 100, DATA_LIGHTNING_WALL1 = 101, @@ -57,6 +64,7 @@ enum UlduarData DATA_REPAIR_STATION1 = 103, DATA_REPAIR_STATION2 = 104, DATA_UNBROKEN_ACHIEVEMENT = 105, + DATA_LEVIATHAN_DOORS = 106, // Razorscales Harpoon Fire State GUIDs DATA_HARPOON_FIRE_STATE_1 = 200, @@ -64,16 +72,31 @@ enum UlduarData DATA_HARPOON_FIRE_STATE_3 = 202, DATA_HARPOON_FIRE_STATE_4 = 203, - // Mimiron's first vehicle (spawned by default) + // Mimiron creatures DATA_MIMIRON_LEVIATHAN_MKII = 301, DATA_MIMIRON_VX001 = 302, DATA_MIMIRON_ACU = 303, - // Mimiron's Doors + // Mimiron doors DATA_GO_MIMIRON_DOOR_1 = 311, DATA_GO_MIMIRON_DOOR_2 = 312, DATA_GO_MIMIRON_DOOR_3 = 313, + // Mimiron tram + DATA_MIMIRON_TRAM = 320, + DATA_MIMIRON_ACTIVATE_TRAM = 321, + DATA_MIMIRON_TRAM_ROCKET_BOOSTER = 322, + DATA_MIMIRON_CALL_TRAM_CENTER = 323, + DATA_MIMIRON_CALL_TRAM_MIMIRON = 324, + DATA_MIMIRON_TRAM_TURNAROUND_1 = 325, + DATA_MIMIRON_TRAM_TURNAROUND_2 = 326, + + // XT-002 + DATA_XT002_DOORS = 400, + + // Kologarn + DATA_KOLOGARN_DOORS = 410, + // Thorim DATA_THORIM_LEVER_GATE = 500, DATA_THORIM_LEVER = 501, @@ -81,15 +104,18 @@ enum UlduarData DATA_THORIM_FIRST_DOORS = 503, DATA_THORIM_SECOND_DOORS = 504, - // Assembly of Iron - DATA_STEELBREAKER = 20, - DATA_MOLGEIM = 21, - DATA_BRUNDIR = 22, - // Algalon the Observer DATA_ALGALON_SUMMON_STATE = 600, DATA_DESPAWN_ALGALON = 601, DATA_ALGALON_DEFEATED = 602, + DATA_SIGILDOOR_01 = 603, + DATA_SIGILDOOR_02 = 604, + DATA_SIGILDOOR_03 = 605, + DATA_UNIVERSE_FLOOR_01 = 606, + DATA_UNIVERSE_FLOOR_02 = 607, + DATA_UNIVERSE_GLOBE = 608, + DATA_ALGALON_TRAPDOOR = 609, + DATA_BRANN_BRONZEBEARD_ALG = 610, // Achievements DATA_DWARFAGEDDON = 700, @@ -97,10 +123,32 @@ enum UlduarData // Tram DATA_CALL_TRAM = 710, + // Freya elders + DATA_ELDER_IRONBRANCH = 750, + DATA_ELDER_STONEBARK = 751, + DATA_ELDER_BRIGHTLEAF = 752, + + // Yogg-Saron + DATA_SARA = 760, + DATA_BRAIN_OF_YOGG_SARON = 761, + DATA_YOGG_SARON_DOORS = 762, + + // Middle section + DATA_ASSEMBLY_DOORS = 770, + DATA_ARCHIVUM_DOORS = 771, + DATA_KEEPERS_GATE = 772, + + // Hodir chests (dynamically spawned) + DATA_HODIR_CHEST_NORMAL = 780, + DATA_HODIR_CHEST_HARD = 781, + DATA_HODIR_CHEST_NORMAL_HERO = 782, + DATA_HODIR_CHEST_HARD_HERO = 783, + // Mage Barrier DATA_MAGE_BARRIER = 800, DATA_BRANN_MEMOTESAY = 801, DATA_BRANN_EASY_MODE = 802, + DATA_BRANN_BASE_CAMP = 803, }; enum UlduarNPCs From 19f418f4893115fde76b3e4fbe1328ec6a80b6bd Mon Sep 17 00:00:00 2001 From: sogladev Date: Sun, 15 Feb 2026 13:00:27 +0100 Subject: [PATCH 122/335] fix(Scripts/ObsidianSanctum): enable Sartharion drakes patrols (#24702) Co-authored-by: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> --- .../rev_1770982083616316730.sql | 4 + .../ObsidianSanctum/boss_sartharion.cpp | 306 +++++++++++------- .../instance_obsidian_sanctum.cpp | 85 +++-- .../ObsidianSanctum/obsidian_sanctum.h | 3 + 4 files changed, 239 insertions(+), 159 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1770982083616316730.sql diff --git a/data/sql/updates/pending_db_world/rev_1770982083616316730.sql b/data/sql/updates/pending_db_world/rev_1770982083616316730.sql new file mode 100644 index 000000000..bec7b44a7 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770982083616316730.sql @@ -0,0 +1,4 @@ +DELETE FROM `waypoint_data` WHERE `id` IN (304490, 304520, 304510); + +-- CREATURE_FLAG_EXTRA_HARD_RESET +UPDATE `creature_template` SET `flags_extra` = `flags_extra` | 0x80000000 WHERE (`entry` = 28860); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp index adb3ccf57..8df23ba82 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp @@ -36,6 +36,8 @@ enum Says SAY_SARTHARION_SLAY = 8, SAY_SARTHARION_SPECIAL_4 = 10, // 9 is whisper + SAY_DRAKE_RESPOND = 4, + // TENEBRON SAY_TENEBRON_AGGRO = 0, SAY_TENEBRON_SLAY = 1, @@ -87,6 +89,7 @@ enum Spells SPELL_LAVA_STRIKE_SUMMON = 57572, SPELL_SARTHARION_PYROBUFFET = 56916, SPELL_SARTHARION_BERSERK = 61632, + SPELL_SARTHARION_ENRAGE = 56916, SPELL_SARTHARION_TWILIGHT_REVENGE = 60639, // Sartharion with drakes @@ -105,6 +108,7 @@ enum Spells SPELL_FLAME_TSUNAMI_DAMAGE_AURA = 57492, SPELL_FLAME_TSUNAMI_LEAP = 60241, SPELL_SARTHARION_PYROBUFFET_TRIGGER = 57557, + SPELL_FULL_HEAL = 43978, }; enum NPCs @@ -130,9 +134,7 @@ enum Misc ACTION_DRAKE_DIED = 3, // Movement points - POINT_FINAL_TENEBRON = 9, - POINT_FINAL_SHADRON = 5, - POINT_FINAL_VESPERON = 5, + POINT_LANDING = 1, // Lava directions. Its used to identify to which side lava was moving by last time LAVA_LEFT_SIDE = 0, @@ -156,6 +158,8 @@ enum Events EVENT_MINIBOSS_OPEN_PORTAL = 4, EVENT_MINIBOSS_SPAWN_HELPERS = 5, EVENT_MINIBOSS_RESPOND = 6, + EVENT_DRAGON_START_PATROL = 7, + EVENT_DRAGON_PATROL_WAYPOINT = 8, // Sartharion abilities EVENT_SARTHARION_CAST_CLEAVE = 10, @@ -222,6 +226,45 @@ const Position AreaTriggerSummonPos[MAX_AREA_TRIGGER_COUNT] = { 3242.84f, 553.979f, 58.8272f, 0.0f }, }; +// Patrol waypoints for Vesperon (circular patrol above Sartharion) +const Position VesperonPatrolPath[8] = +{ + { 3296.785f, 555.0555f, 87.29027f, 0.0f }, + { 3266.8242f, 575.95245f, 89.76242f, 0.0f }, + { 3227.2224f, 577.1228f, 89.87349f, 0.0f }, + { 3197.2644f, 553.5248f, 88.651405f, 0.0f }, + { 3195.9875f, 507.7954f, 87.45695f, 0.0f }, + { 3224.5435f, 481.11807f, 84.70684f, 0.0f }, + { 3265.2356f, 481.7216f, 83.595764f, 0.0f }, + { 3299.8765f, 506.4301f, 83.87355f, 0.0f }, +}; + +// Patrol waypoints for Tenebron (circular patrol above Sartharion) +const Position TenebronPatrolPath[8] = +{ + { 3232.0261f, 569.16376f, 97.53158f, 0.0f }, + { 3203.6875f, 548.84595f, 98.50729f, 0.0f }, + { 3206.0713f, 513.54425f, 99.3684f, 0.0f }, + { 3234.5671f, 489.96832f, 99.47933f, 0.0f }, + { 3265.446f, 490.026f, 98.423836f, 0.0f }, + { 3287.5674f, 503.39835f, 97.645226f, 0.0f }, + { 3288.8157f, 549.16187f, 96.70078f, 0.0f }, + { 3264.5164f, 568.97516f, 95.97868f, 0.0f }, +}; + +// Patrol waypoints for Shadron (circular patrol above Sartharion) +const Position ShadronPatrolPath[8] = +{ + { 3196.095f, 548.7049f, 115.83286f, 0.0f }, + { 3224.809f, 573.8922f, 116.08303f, 0.0f }, + { 3270.8267f, 572.1468f, 112.77744f, 0.0f }, + { 3295.5364f, 547.12506f, 109.66705f, 0.0f }, + { 3296.5833f, 503.22397f, 106.95133f, 0.0f }, + { 3254.0688f, 489.25906f, 108.92368f, 0.0f }, + { 3223.111f, 488.90338f, 110.53484f, 0.0f }, + { 3197.9263f, 511.4375f, 113.22937f, 0.0f }, +}; + float const FlameTsunamiLeftOffsets[MAX_LEFT_LAVA_TSUNAMIS] = { 476.0f, 484.0f, 492.0f, @@ -239,13 +282,30 @@ const Position bigIslandMiddlePos = { 3242.822754f, 477.279816f, 57.430473f }; const uint32 dragons[MAX_DRAGONS] = { DATA_TENEBRON, DATA_VESPERON, DATA_SHADRON }; +const Position dragonLandingPos[MAX_DRAGONS] ={ + {3249.75f, 566.95184f, 59.424007f, 0}, // Tenebron + {3230.4963f, 533.0001f, 59.5598f, 0}, // Shadron + {3269.7134f, 532.7908f, 59.51278f, 0} // Vesperon + }; + +static Position const& GetDragonLandingPos(uint32 entry) +{ + switch (entry) + { + case NPC_TENEBRON: return dragonLandingPos[0]; + case NPC_SHADRON: return dragonLandingPos[1]; + case NPC_VESPERON: return dragonLandingPos[2]; + default: return dragonLandingPos[0]; + } +} + ///////////////////////////// // SARTHARION ///////////////////////////// struct boss_sartharion : public BossAI { - boss_sartharion(Creature* creature) : BossAI(creature, DATA_SARTHARION), + explicit boss_sartharion(Creature* creature) : BossAI(creature, DATA_SARTHARION), dragonsCount(0), lastLavaSide(LAVA_RIGHT_SIDE), usedBerserk(false), @@ -257,7 +317,7 @@ struct boss_sartharion : public BossAI { _Reset(); extraEvents.Reset(); - RespawnDragons(false); + SummonStartingTriggers(); usedBerserk = false; below11PctReached = false; @@ -266,6 +326,21 @@ struct boss_sartharion : public BossAI instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_SHIFT); } + void EnterEvadeMode(EvadeReason why) override + { + BossAI::EnterEvadeMode(why); + + // Despawn drakes + for (uint32 i : dragons) + { + if (instance->GetBossState(i) == DONE) + continue; + + if (Creature* boss = instance->GetCreature(i) ) + boss->DespawnOnEvade(); + } + } + void DoAction(int32 param) override { if (param == ACTION_DRAKE_DIED) @@ -276,6 +351,7 @@ struct boss_sartharion : public BossAI { _JustEngagedWith(); DoCastSelf(SPELL_SARTHARION_PYROBUFFET, true); + ScheduleEnrageTimer(SPELL_SARTHARION_ENRAGE, 15min); Talk(SAY_SARTHARION_AGGRO); // Combat events @@ -296,7 +372,7 @@ struct boss_sartharion : public BossAI continue; dragon->SetImmuneToNPC(true); - dragon->SetFullHealth(); + dragon->CastSpell(dragon, SPELL_FULL_HEAL, true); ++dragonsCount; me->AddLootMode(1 << dragonsCount); @@ -306,33 +382,35 @@ struct boss_sartharion : public BossAI case DATA_TENEBRON: { dragon->CastSpell(dragon, SPELL_POWER_OF_TENEBRON, true); - extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_TENEBRON, 10s); + extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_TENEBRON, 20s); break; } case DATA_SHADRON: { dragon->CastSpell(dragon, SPELL_POWER_OF_SHADRON, true); - extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_SHADRON, 65s); + extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_SHADRON, 60s); break; } case DATA_VESPERON: { dragon->CastSpell(dragon, SPELL_POWER_OF_VESPERON, true); - extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_VESPERON, 115s); + extraEvents.ScheduleEvent(EVENT_SARTHARION_CALL_VESPERON, 120s); break; } } } if (dragonsCount) + { DoCastSelf(SPELL_WILL_OF_SARTHARION, true); + instance->DoAction(ACTION_START_PATROL); + } me->CallForHelp(500.0f); } void JustDied(Unit* /*killer*/) override { - RespawnDragons(true); _JustDied(); Talk(SAY_SARTHARION_DEATH); } @@ -475,6 +553,8 @@ struct boss_sartharion : public BossAI break; } + default: + break; } } @@ -535,6 +615,8 @@ struct boss_sartharion : public BossAI summons.DespawnEntry(NPC_SAFE_AREA_TRIGGER); break; } + default: + break; } if (me->HasUnitState(UNIT_STATE_CASTING)) @@ -547,15 +629,11 @@ struct boss_sartharion : public BossAI private: void SummonStartingTriggers() { - for (uint8 i = 0; i < MAX_CYCLONE_COUNT; ++i) - { - me->SummonCreature(NPC_FIRE_CYCLONE, CycloneSummonPos[i]); - } + for (auto const& CycloneSummonPo : CycloneSummonPos) + me->SummonCreature(NPC_FIRE_CYCLONE, CycloneSummonPo); - for (uint8 i = 0; i < MAX_AREA_TRIGGER_COUNT; ++i) - { - me->SummonCreature(NPC_SAFE_AREA_TRIGGER, AreaTriggerSummonPos[i]); - } + for (auto const& AreaTriggerSummonPo : AreaTriggerSummonPos) + me->SummonCreature(NPC_SAFE_AREA_TRIGGER, AreaTriggerSummonPo); } void SummonLavaWaves() @@ -617,26 +695,6 @@ private: } } - void RespawnDragons(bool checkCombat) - { - for (uint8 i = 0; i < MAX_DRAGONS; ++i) - { - if (instance->GetBossState(dragons[i]) == DONE) - continue; - - if (Creature* dragon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(dragons[i]))) - { - if (checkCombat && dragon->IsInCombat()) - continue; - - dragon->DespawnOrUnsummon(); - dragon->SetRespawnTime(5); - } - } - - dragonsCount = 0; - } - EventMap extraEvents; std::list volcanoBlows; uint8 dragonsCount; @@ -647,20 +705,21 @@ private: struct boss_sartharion_dragonAI : public BossAI { - boss_sartharion_dragonAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId), isCalledBySartharion(false) - { - } + boss_sartharion_dragonAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId), isCalledBySartharion(false), currentPatrolPoint(0) { } void Reset() override { _Reset(); events.Reset(); + extraEvents.Reset(); ClearInstance(); me->SetImmuneToNPC(false); me->SetSpeed(MOVE_FLIGHT, 1.0f); - me->SetCanFly(false); + me->SetDisableGravity(false); + me->SetHover(true); me->ResetLootMode(); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); portalGUID.Clear(); isCalledBySartharion = false; instance->DoAction(ACTION_CLEAR_PORTAL); @@ -673,11 +732,14 @@ struct boss_sartharion_dragonAI : public BossAI isCalledBySartharion = true; extraEvents.RescheduleEvent(EVENT_MINIDRAKE_SPEECH, 4s); } + else if (param == ACTION_START_PATROL) + extraEvents.ScheduleEvent(EVENT_DRAGON_START_PATROL, 500ms); } void MoveInLineOfSight(Unit* who) final { - if (isCalledBySartharion) + // Prevent aggro during patrol (NOT_SELECTABLE set) and while flying to landing position + if (isCalledBySartharion || me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) return; ScriptedAI::MoveInLineOfSight(who); @@ -685,33 +747,21 @@ struct boss_sartharion_dragonAI : public BossAI void MovementInform(uint32 type, uint32 pointId) final { - if (type != WAYPOINT_MOTION_TYPE) - return; - - switch (me->GetEntry()) + if (type == POINT_MOTION_TYPE && pointId == POINT_LANDING) { - case NPC_TENEBRON: - { - if (pointId != POINT_FINAL_TENEBRON) - return; - break; - } - case NPC_SHADRON: - { - if (pointId != POINT_FINAL_SHADRON) - return; - break; - } - case NPC_VESPERON: - { - if (pointId != POINT_FINAL_VESPERON) - return; - break; - } + // Dragon has landed - set ground flags + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetDisableGravity(false); + me->SetHover(false); + me->SetAnimTier(AnimTier::Ground); + me->SetImmuneToNPC(false); + me->SetInCombatWithZone(); + } + else if (type == POINT_MOTION_TYPE && pointId >= 100 && pointId < 200) + { + // Patrol waypoint reached - schedule next waypoint + extraEvents.ScheduleEvent(EVENT_DRAGON_PATROL_WAYPOINT, 100ms); } - - me->SetImmuneToNPC(false); - me->SetInCombatWithZone(); } void JustSummoned(Creature* summon) override @@ -735,7 +785,6 @@ struct boss_sartharion_dragonAI : public BossAI if (me->IsFlying()) { me->SetSpeed(MOVE_FLIGHT, 1.0f); - me->SetCanFly(false); } if (!isCalledBySartharion || instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) @@ -881,7 +930,66 @@ struct boss_sartharion_dragonAI : public BossAI RemoveTwilightPortal(); } - virtual void HandleExtraEvent(uint32 const /*eventId*/) { } + void HandleExtraEvent(uint32 const eventId) + { + if (eventId == EVENT_MINIDRAKE_SPEECH) + { + // Dragon speaks and starts flying to landing position + Talk(SAY_DRAKE_RESPOND); + me->GetMotionMaster()->Clear(); + me->SetDisableGravity(true); + me->SetHover(true); + me->SetAnimTier(AnimTier::Fly); + me->SetSpeed(MOVE_FLIGHT, 3.0f); + me->GetMotionMaster()->MovePoint(POINT_LANDING, GetDragonLandingPos(me->GetEntry())); + } + else if (eventId == EVENT_DRAGON_START_PATROL) + { + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetDisableGravity(true); + me->SetHover(true); + me->SetAnimTier(AnimTier::Fly); + currentPatrolPoint = 0; + + // Start patrol using custom waypoint system + extraEvents.ScheduleEvent(EVENT_DRAGON_PATROL_WAYPOINT, 100ms); + } + else if (eventId == EVENT_DRAGON_PATROL_WAYPOINT) + { + // Only continue patrol if not in combat and still selectable flag is set + if (!me->IsInCombat() && me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + // Ensure flying flags are maintained + me->SetDisableGravity(true); + me->SetHover(true); + me->SetAnimTier(AnimTier::Fly); + + // Get the appropriate patrol path based on creature entry + Position const* patrolPath = nullptr; + switch (me->GetEntry()) + { + case NPC_VESPERON: + patrolPath = VesperonPatrolPath; + break; + case NPC_TENEBRON: + patrolPath = TenebronPatrolPath; + break; + case NPC_SHADRON: + patrolPath = ShadronPatrolPath; + break; + default: + return; + } + + // Move to next patrol point (use pointId 100+ to identify patrol points) + me->GetMotionMaster()->MovePoint(100 + currentPatrolPoint, patrolPath[currentPatrolPoint]); + + // Cycle to next waypoint + currentPatrolPoint = (currentPatrolPoint + 1) % 8; + } + } + } + protected: void RemoveTwilightPortal() { @@ -897,6 +1005,7 @@ protected: EventMap extraEvents; ObjectGuid portalGUID; bool isCalledBySartharion; + uint8 currentPatrolPoint; }; ///////////////////////////// @@ -905,9 +1014,7 @@ protected: struct boss_sartharion_tenebron : public boss_sartharion_dragonAI { - boss_sartharion_tenebron(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_TENEBRON), summons2(creature) - { - } + explicit boss_sartharion_tenebron(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_TENEBRON), summons2(creature) { } void Reset() override { @@ -935,17 +1042,6 @@ struct boss_sartharion_tenebron : public boss_sartharion_dragonAI boss_sartharion_dragonAI::JustDied(killer); } - void HandleExtraEvent(uint32 const eventId) override - { - if (eventId == EVENT_MINIDRAKE_SPEECH) - { - Talk(SAY_TENEBRON_RESPOND); - me->SetCanFly(true); - me->SetSpeed(MOVE_FLIGHT, 3.0f); - me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false); - } - } - void ExecuteEvent(uint32 eventId) override { switch (eventId) @@ -1036,6 +1132,8 @@ struct boss_sartharion_tenebron : public boss_sartharion_dragonAI summons.DoAction(ACTION_SWITCH_PHASE, pred); break; } + default: + break; } } @@ -1055,9 +1153,7 @@ private: struct boss_sartharion_shadron : public boss_sartharion_dragonAI { - boss_sartharion_shadron(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_SHADRON) - { - } + explicit boss_sartharion_shadron(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_SHADRON) { } void Reset() override { @@ -1087,17 +1183,6 @@ struct boss_sartharion_shadron : public boss_sartharion_dragonAI events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s); } - void HandleExtraEvent(uint32 const eventId) override - { - if (eventId == EVENT_MINIDRAKE_SPEECH) - { - Talk(SAY_SHADRON_RESPOND); - me->SetCanFly(true); - me->SetSpeed(MOVE_FLIGHT, 3.0f); - me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false); - } - } - void ExecuteEvent(uint32 eventId) override { switch (eventId) @@ -1147,6 +1232,8 @@ struct boss_sartharion_shadron : public boss_sartharion_dragonAI break; } + default: + break; } } }; @@ -1157,9 +1244,7 @@ struct boss_sartharion_shadron : public boss_sartharion_dragonAI struct boss_sartharion_vesperon : public boss_sartharion_dragonAI { - boss_sartharion_vesperon(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_VESPERON) - { - } + explicit boss_sartharion_vesperon(Creature* creature) : boss_sartharion_dragonAI(creature, DATA_VESPERON) { } void Reset() override { @@ -1182,17 +1267,6 @@ struct boss_sartharion_vesperon : public boss_sartharion_dragonAI events.ScheduleEvent(EVENT_MINIBOSS_OPEN_PORTAL, 30s); } - void HandleExtraEvent(uint32 const eventId) override - { - if (eventId == EVENT_MINIDRAKE_SPEECH) - { - Talk(SAY_SHADRON_RESPOND); - me->SetCanFly(true); - me->SetSpeed(MOVE_FLIGHT, 3.0f); - me->GetMotionMaster()->MoveWaypoint(me->GetEntry() * 10, false); - } - } - void ExecuteEvent(uint32 eventId) override { switch (eventId) @@ -1241,6 +1315,8 @@ struct boss_sartharion_vesperon : public boss_sartharion_dragonAI break; } + default: + break; } } @@ -1258,9 +1334,7 @@ private: // other struct npc_twilight_summon : public ScriptedAI { - npc_twilight_summon(Creature* creature) : ScriptedAI(creature), - fadeArmorTimer(urand(0, 15000)) - { + explicit npc_twilight_summon(Creature* creature) : ScriptedAI(creature), fadeArmorTimer(urand(0, 15000)) { } void Reset() override @@ -1349,7 +1423,7 @@ class spell_sartharion_lava_strike : public SpellScript } private: - bool _spawned; + bool _spawned{false}; }; // 57491 - Flame Tsunami diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp index 982a49c5d..e43aa563e 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp @@ -21,6 +21,15 @@ #include "ScriptedCreature.h" #include "obsidian_sanctum.h" +ObjectData const creatureData[] = +{ + { NPC_SARTHARION, DATA_SARTHARION }, + { NPC_TENEBRON, DATA_TENEBRON }, + { NPC_SHADRON, DATA_SHADRON }, + { NPC_VESPERON, DATA_VESPERON }, + { 0, 0 } +}; + class instance_obsidian_sanctum : public InstanceMapScript { public: @@ -33,46 +42,16 @@ public: struct instance_obsidian_sanctum_InstanceMapScript : public InstanceScript { - instance_obsidian_sanctum_InstanceMapScript(Map* pMap) : InstanceScript(pMap), portalCount(0) + explicit instance_obsidian_sanctum_InstanceMapScript(Map* pMap) : InstanceScript(pMap), portalCount(0) { SetHeaders(DataHeader); SetBossNumber(MAX_ENCOUNTERS); - } - - void OnCreatureCreate(Creature* pCreature) override - { - switch (pCreature->GetEntry()) - { - case NPC_SARTHARION: - m_uiSartharionGUID = pCreature->GetGUID(); - break; - case NPC_TENEBRON: - m_uiTenebronGUID = pCreature->GetGUID(); - break; - case NPC_SHADRON: - m_uiShadronGUID = pCreature->GetGUID(); - break; - case NPC_VESPERON: - m_uiVesperonGUID = pCreature->GetGUID(); - break; - } + LoadObjectData(creatureData, nullptr); } ObjectGuid GetGuidData(uint32 uiData) const override { - switch (uiData) - { - case DATA_SARTHARION: - return m_uiSartharionGUID; - case DATA_TENEBRON: - return m_uiTenebronGUID; - case DATA_SHADRON: - return m_uiShadronGUID; - case DATA_VESPERON: - return m_uiVesperonGUID; - } - - return ObjectGuid::Empty; + return GetObjectGuid(uiData); } bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* /*target*/, uint32 /*miscvalue1*/) override @@ -84,7 +63,7 @@ public: // Gonna Go When the Volcano Blows (25 player) (2048) case 7327: { - Creature const* sartharion = instance->GetCreature(m_uiSartharionGUID); + Creature const* sartharion = GetCreature(DATA_SARTHARION); return sartharion && !sartharion->AI()->GetData(source->GetGUID().GetCounter()); } // Less Is More (10 player) (624) @@ -108,7 +87,7 @@ public: // Twilight Assist (25 player) (2052) case 7331: { - Creature const* sartharion = instance->GetCreature(m_uiSartharionGUID); + Creature const* sartharion = GetCreature(DATA_SARTHARION); return sartharion && sartharion->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 1; } // Twilight Duo (10 player) (2050) @@ -116,7 +95,7 @@ public: // Twilight Duo (25 player) (2053) case 7332: { - Creature const* sartharion = instance->GetCreature(m_uiSartharionGUID); + Creature const* sartharion = GetCreature(DATA_SARTHARION); return sartharion && sartharion->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 2; } // Twilight Zone (10 player) (2051) @@ -124,12 +103,13 @@ public: // Twilight Zone (25 player) (2054) case 7333: { - Creature const* sartharion = instance->GetCreature(m_uiSartharionGUID); + Creature const* sartharion = GetCreature(DATA_SARTHARION); return sartharion && sartharion->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 3; } + default: + return false; } - return false; } void DoAction(int32 action) override @@ -140,7 +120,7 @@ public: { if (!m_uiPortalGUID) { - if (Creature* sartharion = instance->GetCreature(m_uiSartharionGUID)) + if (Creature* sartharion = GetCreature(DATA_SARTHARION)) { if (GameObject* portal = sartharion->SummonGameObject(GO_TWILIGHT_PORTAL, 3247.29f, 529.804f, 58.9595f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) { @@ -170,14 +150,33 @@ public: } break; } + case ACTION_START_PATROL: + { + if (Creature* tenebron = GetCreature(DATA_TENEBRON)) + { + if (tenebron->IsAlive() && GetBossState(DATA_TENEBRON) != DONE) + tenebron->AI()->DoAction(ACTION_START_PATROL); + } + + if (Creature* shadron = GetCreature(DATA_SHADRON)) + { + if (shadron->IsAlive() && GetBossState(DATA_SHADRON) != DONE) + shadron->AI()->DoAction(ACTION_START_PATROL); + } + + if (Creature* vesperon = GetCreature(DATA_VESPERON)) + { + if (vesperon->IsAlive() && GetBossState(DATA_VESPERON) != DONE) + vesperon->AI()->DoAction(ACTION_START_PATROL); + } + break; + } + default: + break; } } private: - ObjectGuid m_uiSartharionGUID; - ObjectGuid m_uiTenebronGUID; - ObjectGuid m_uiShadronGUID; - ObjectGuid m_uiVesperonGUID; ObjectGuid m_uiPortalGUID; uint8 portalCount; }; diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h index 02c6b3983..fdd004dea 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h @@ -58,6 +58,9 @@ enum OSActions // Portal ACTION_CLEAR_PORTAL = -1, ACTION_ADD_PORTAL = -2, + + // Dragon patrol + ACTION_START_PATROL = -3, }; template From ce3ebadbecbec453d2c934d76c2a88b869aa0479 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Feb 2026 12:01:35 +0000 Subject: [PATCH 123/335] chore(DB): import pending files Referenced commit(s): b348455d538115176363711ff6b9579f8d69ff69 --- .../rev_1770982083616316730.sql => db_world/2026_02_15_00.sql} | 1 + .../rev_1771122450299085300.sql => db_world/2026_02_15_01.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1770982083616316730.sql => db_world/2026_02_15_00.sql} (82%) rename data/sql/updates/{pending_db_world/rev_1771122450299085300.sql => db_world/2026_02_15_01.sql} (74%) diff --git a/data/sql/updates/pending_db_world/rev_1770982083616316730.sql b/data/sql/updates/db_world/2026_02_15_00.sql similarity index 82% rename from data/sql/updates/pending_db_world/rev_1770982083616316730.sql rename to data/sql/updates/db_world/2026_02_15_00.sql index bec7b44a7..52998bb13 100644 --- a/data/sql/updates/pending_db_world/rev_1770982083616316730.sql +++ b/data/sql/updates/db_world/2026_02_15_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_13_03 -> 2026_02_15_00 DELETE FROM `waypoint_data` WHERE `id` IN (304490, 304520, 304510); -- CREATURE_FLAG_EXTRA_HARD_RESET diff --git a/data/sql/updates/pending_db_world/rev_1771122450299085300.sql b/data/sql/updates/db_world/2026_02_15_01.sql similarity index 74% rename from data/sql/updates/pending_db_world/rev_1771122450299085300.sql rename to data/sql/updates/db_world/2026_02_15_01.sql index 21b165a32..22838c08b 100644 --- a/data/sql/updates/pending_db_world/rev_1771122450299085300.sql +++ b/data/sql/updates/db_world/2026_02_15_01.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_15_00 -> 2026_02_15_01 -- Remove unused ScriptName from Pure Saronite Deposit UPDATE `gameobject_template` SET `ScriptName` = '' WHERE `entry` = 195036; From f8cfcf9c55cdacc09fa73ef1169f93286595c8ef Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 15 Feb 2026 11:35:02 -0300 Subject: [PATCH 124/335] fix(Core/Commands): Add detailed quest availability info to .quest info (#24721) Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> --- .../rev_1771157757057970557.sql | 25 ++++++ src/server/game/Miscellaneous/Language.h | 23 ++++- src/server/scripts/Commands/cs_quest.cpp | 83 ++++++++++++++++++- 3 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771157757057970557.sql diff --git a/data/sql/updates/pending_db_world/rev_1771157757057970557.sql b/data/sql/updates/pending_db_world/rev_1771157757057970557.sql new file mode 100644 index 000000000..b3f9d02aa --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771157757057970557.sql @@ -0,0 +1,25 @@ +-- +DELETE FROM `acore_string` WHERE `entry` IN (5089, 5090, 5091, 5092, 5093, 5094, 5095, 5096, 5097, 5098, 5099, 5100, 5101, 5102, 5103, 5104, 5105, 5106, 5107, 5108, 5109, 5110); +INSERT INTO `acore_string` (`entry`, `content_default`) VALUES +(5089, 'Quest {} cannot be taken. Reasons:'), +(5090, ' - Quest is disabled.'), +(5091, ' - Quest has already been taken or completed.'), +(5092, ' - Class requirement not met.'), +(5093, ' - Race requirement not met.'), +(5094, ' - Player level too low (required: {}).'), +(5095, ' - Player level too high (max: {}).'), +(5096, ' - Skill requirement not met.'), +(5097, ' - Reputation requirement not met.'), +(5098, ' - Previous quest in chain not completed.'), +(5099, ' - Already on a timed quest.'), +(5100, ' - Exclusive group quest conflict.'), +(5101, ' - Next quest in chain already started.'), +(5102, ' - Previous chain quest still active.'), +(5103, ' - Breadcrumb quest conflict.'), +(5104, ' - Daily quest not available today.'), +(5105, ' - Weekly quest already completed this week.'), +(5106, ' - Monthly quest already completed this month.'), +(5107, ' - Seasonal quest already completed this season.'), +(5108, ' - Condition requirements not met:'), +(5109, ' - Quest log is full.'), +(5110, ' - Condition not met: type {} value1: {} value2: {} value3: {}'); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 7f972a0a9..31ae7965a 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1161,8 +1161,29 @@ enum AcoreStrings LANG_CMD_QUEST_STATUS = 5088, LANG_CMD_QUEST_UNAVAILABLE = 5089, + LANG_CMD_QUEST_STATUS_DISABLED = 5090, + LANG_CMD_QUEST_STATUS_ALREADY_DONE = 5091, + LANG_CMD_QUEST_STATUS_CLASS = 5092, + LANG_CMD_QUEST_STATUS_RACE = 5093, + LANG_CMD_QUEST_STATUS_LOW_LEVEL = 5094, + LANG_CMD_QUEST_STATUS_HIGH_LEVEL = 5095, + LANG_CMD_QUEST_STATUS_SKILL = 5096, + LANG_CMD_QUEST_STATUS_REPUTATION = 5097, + LANG_CMD_QUEST_STATUS_PREV_QUEST = 5098, + LANG_CMD_QUEST_STATUS_TIMED = 5099, + LANG_CMD_QUEST_STATUS_EXCLUSIVE = 5100, + LANG_CMD_QUEST_STATUS_NEXT_CHAIN = 5101, + LANG_CMD_QUEST_STATUS_PREV_CHAIN = 5102, + LANG_CMD_QUEST_STATUS_BREADCRUMB = 5103, + LANG_CMD_QUEST_STATUS_DAY = 5104, + LANG_CMD_QUEST_STATUS_WEEK = 5105, + LANG_CMD_QUEST_STATUS_MONTH = 5106, + LANG_CMD_QUEST_STATUS_SEASONAL = 5107, + LANG_CMD_QUEST_STATUS_CONDITION = 5108, + LANG_CMD_QUEST_STATUS_LOG_FULL = 5109, + LANG_CMD_QUEST_STATUS_COND_DETAIL = 5110, - // Room for more strings 5090-9999 + // Room for more strings 5111-9999 // Level requirement notifications LANG_SAY_REQ = 6604, diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index 9730b3221..daee0c91c 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -17,6 +17,8 @@ #include "Chat.h" #include "CommandScript.h" +#include "ConditionMgr.h" +#include "DisableMgr.h" #include "GameTime.h" #include "ObjectMgr.h" #include "Player.h" @@ -766,8 +768,85 @@ public: handler->PSendSysMessage(LANG_CMD_QUEST_STATUS, quest->GetTitle(), entry, status); - if (!player->CanTakeQuest(quest, true)) - handler->PSendSysMessage(LANG_CMD_QUEST_UNAVAILABLE, entry, status); + if (!player->CanTakeQuest(quest, false)) + { + handler->PSendSysMessage(LANG_CMD_QUEST_UNAVAILABLE, entry); + + if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_QUEST, entry, player)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_DISABLED); + + if (!player->SatisfyQuestStatus(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_ALREADY_DONE); + + if (!player->SatisfyQuestClass(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_CLASS); + + if (!player->SatisfyQuestRace(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_RACE); + + if (player->GetLevel() < quest->GetMinLevel()) + handler->PSendSysMessage(LANG_CMD_QUEST_STATUS_LOW_LEVEL, quest->GetMinLevel()); + + if (quest->GetMaxLevel() > 0 && player->GetLevel() > quest->GetMaxLevel()) + handler->PSendSysMessage(LANG_CMD_QUEST_STATUS_HIGH_LEVEL, quest->GetMaxLevel()); + + if (!player->SatisfyQuestSkill(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_SKILL); + + if (!player->SatisfyQuestReputation(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_REPUTATION); + + if (!player->SatisfyQuestPreviousQuest(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_PREV_QUEST); + + if (!player->SatisfyQuestTimed(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_TIMED); + + if (!player->SatisfyQuestExclusiveGroup(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_EXCLUSIVE); + + if (!player->SatisfyQuestNextChain(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_NEXT_CHAIN); + + if (!player->SatisfyQuestPrevChain(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_PREV_CHAIN); + + if (!player->SatisfyQuestBreadcrumb(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_BREADCRUMB); + + if (!player->SatisfyQuestDay(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_DAY); + + if (!player->SatisfyQuestWeek(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_WEEK); + + if (!player->SatisfyQuestMonth(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_MONTH); + + if (!player->SatisfyQuestSeasonal(quest, false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_SEASONAL); + + if (!player->SatisfyQuestConditions(quest, false)) + { + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_CONDITION); + + ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_AVAILABLE, entry); + ConditionSourceInfo srcInfo = ConditionSourceInfo(player); + for (Condition* cond : conditions) + { + if (!cond->Meets(srcInfo)) + handler->PSendSysMessage(LANG_CMD_QUEST_STATUS_COND_DETAIL, uint32(cond->ConditionType), cond->ConditionValue1, cond->ConditionValue2, cond->ConditionValue3); + } + } + + if (!player->SatisfyQuestLog(false)) + handler->SendSysMessage(LANG_CMD_QUEST_STATUS_LOG_FULL); + } + } + else + { + handler->SendErrorMessage(LANG_PLAYER_NOT_FOUND); + return false; } return true; From 4289b2641f436cedb428e8fc5e0d8dd6ff53e481 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Feb 2026 14:36:12 +0000 Subject: [PATCH 125/335] chore(DB): import pending files Referenced commit(s): f8cfcf9c55cdacc09fa73ef1169f93286595c8ef --- .../rev_1771157757057970557.sql => db_world/2026_02_15_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771157757057970557.sql => db_world/2026_02_15_02.sql} (96%) diff --git a/data/sql/updates/pending_db_world/rev_1771157757057970557.sql b/data/sql/updates/db_world/2026_02_15_02.sql similarity index 96% rename from data/sql/updates/pending_db_world/rev_1771157757057970557.sql rename to data/sql/updates/db_world/2026_02_15_02.sql index b3f9d02aa..ca041d49a 100644 --- a/data/sql/updates/pending_db_world/rev_1771157757057970557.sql +++ b/data/sql/updates/db_world/2026_02_15_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_15_01 -> 2026_02_15_02 -- DELETE FROM `acore_string` WHERE `entry` IN (5089, 5090, 5091, 5092, 5093, 5094, 5095, 5096, 5097, 5098, 5099, 5100, 5101, 5102, 5103, 5104, 5105, 5106, 5107, 5108, 5109, 5110); INSERT INTO `acore_string` (`entry`, `content_default`) VALUES From d9807742e57771095f6460e34240418f81e0e16d Mon Sep 17 00:00:00 2001 From: Tereneckla Date: Sun, 15 Feb 2026 16:32:41 +0000 Subject: [PATCH 126/335] refactor(Core/Unit): use spell_group functions for a few more cases (#24019) --- src/server/game/Entities/Unit/Unit.cpp | 63 ++++++++++++-------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 018cbd47d..5352f8b40 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -2226,15 +2226,19 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) { if (attacker) { - AuraEffectList const& ResIgnoreAurasAb = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST); - for (AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin(); j != ResIgnoreAurasAb.end(); ++j) - if (((*j)->GetMiscValue() & schoolMask) && (*j)->IsAffectedOnSpell(spellInfo)) - AddPct(damageResisted, -(*j)->GetAmount()); + float mult = attacker->GetTotalAuraMultiplier(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST, [schoolMask, spellInfo](AuraEffect const* aurEff) + { + if (!(aurEff->GetMiscValue() & schoolMask)) + return false; - AuraEffectList const& ResIgnoreAuras = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); - for (AuraEffectList::const_iterator j = ResIgnoreAuras.begin(); j != ResIgnoreAuras.end(); ++j) - if ((*j)->GetMiscValue() & schoolMask) - AddPct(damageResisted, -(*j)->GetAmount()); + if (!aurEff->IsAffectedOnSpell(spellInfo)) + return false; + + return true; + }); + damageResisted -= damageResisted * (mult - 1.0f); + mult = attacker->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_IGNORE_TARGET_RESIST, schoolMask); + damageResisted -= damageResisted * (mult - 1.0f); } // pussywizard: @@ -2254,25 +2258,17 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) float auraAbsorbMod = 0; if (attacker) { - AuraEffectList const& AbsIgnoreAurasA = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL); - for (AuraEffectList::const_iterator itr = AbsIgnoreAurasA.begin(); itr != AbsIgnoreAurasA.end(); ++itr) + auraAbsorbMod = attacker->GetMaxPositiveAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL, schoolMask); + auraAbsorbMod = std::max(auraAbsorbMod, float(attacker->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL, [spellInfo, schoolMask](AuraEffect const* aurEff) { - if (!((*itr)->GetMiscValue() & schoolMask)) - continue; + if (!(aurEff->GetMiscValue() & schoolMask)) + return false; - if ((*itr)->GetAmount() > auraAbsorbMod) - auraAbsorbMod = float((*itr)->GetAmount()); - } + if (!aurEff->IsAffectedOnSpell(spellInfo)) + return false; - AuraEffectList const& AbsIgnoreAurasB = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL); - for (AuraEffectList::const_iterator itr = AbsIgnoreAurasB.begin(); itr != AbsIgnoreAurasB.end(); ++itr) - { - if (!((*itr)->GetMiscValue() & schoolMask)) - continue; - - if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectedOnSpell(spellInfo)) - auraAbsorbMod = float((*itr)->GetAmount()); - } + return true; + }))); RoundToInterval(auraAbsorbMod, 0.0f, 100.0f); } @@ -11871,13 +11867,12 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin // done scripted mod (take it from owner) Unit* owner = GetOwner() ? GetOwner() : this; int32 DoneAdvertisedBenefit = 0; - AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) + DoneAdvertisedBenefit += owner->GetTotalAuraModifier(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS, [spellProto](AuraEffect const* aurEff) { - if (!(*i)->IsAffectedOnSpell(spellProto)) - continue; + if (!aurEff->IsAffectedOnSpell(spellProto)) + return false; - switch ((*i)->GetMiscValue()) + switch (aurEff->GetMiscValue()) { case 4418: // Increased Shock Damage case 4554: // Increased Lightning Damage @@ -11887,12 +11882,14 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin case 5148: // Idol of the Shooting Star case 6008: // Increased Lightning Damage case 8627: // Totem of Hex - { - DoneAdvertisedBenefit += (*i)->GetAmount(); + return true; + break; + default: break; - } } - } + + return false; + }); // Custom scripted damage switch (spellProto->SpellFamilyName) From 404a568bef8bba6f29762249449ae52b49478cc6 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Sun, 15 Feb 2026 17:42:54 +0100 Subject: [PATCH 127/335] fix(Script/ObsidianSanctum): Lava Strike event now starts correctly. (#24723) --- .../updates/pending_db_world/lava_strike.sql | 3 ++ .../ObsidianSanctum/boss_sartharion.cpp | 47 +++++++------------ 2 files changed, 19 insertions(+), 31 deletions(-) create mode 100644 data/sql/updates/pending_db_world/lava_strike.sql diff --git a/data/sql/updates/pending_db_world/lava_strike.sql b/data/sql/updates/pending_db_world/lava_strike.sql new file mode 100644 index 000000000..327c2b7c4 --- /dev/null +++ b/data/sql/updates/pending_db_world/lava_strike.sql @@ -0,0 +1,3 @@ + +-- Move the text in its own group. +UPDATE `creature_text` SET `GroupID` = 10, `ID` = 0 WHERE (`CreatureID` = 28860) AND (`GroupID` = 7) AND (`ID` = 3); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp index 8df23ba82..962007d02 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp @@ -32,9 +32,9 @@ enum Says SAY_SARTHARION_CALL_TENEBRON = 4, SAY_SARTHARION_CALL_VESPERON = 5, SAY_SARTHARION_DEATH = 6, - SAY_SARTHARION_SPECIAL = 7, + SAY_SARTHARION_CYCLONE = 7, SAY_SARTHARION_SLAY = 8, - SAY_SARTHARION_SPECIAL_4 = 10, // 9 is whisper + SAY_SARTHARION_LAVA = 10, SAY_DRAKE_RESPOND = 4, @@ -356,12 +356,12 @@ struct boss_sartharion : public BossAI // Combat events events.ScheduleEvent(EVENT_SARTHARION_CAST_CLEAVE, 7s); - events.ScheduleEvent(EVENT_SARTHARION_CAST_FLAME_BREATH, 15s); + events.ScheduleEvent(EVENT_SARTHARION_CAST_FLAME_BREATH, 6s); events.ScheduleEvent(EVENT_SARTHARION_CAST_TAIL_LASH, 11s); // Extra events extraEvents.ScheduleEvent(EVENT_SARTHARION_SUMMON_LAVA, 20s); - extraEvents.ScheduleEvent(EVENT_SARTHARION_LAVA_STRIKE, 5s); + extraEvents.ScheduleEvent(EVENT_SARTHARION_LAVA_STRIKE, 15s); extraEvents.ScheduleEvent(EVENT_SARTHARION_BERSERK, 15min); // Store dragons @@ -512,8 +512,7 @@ struct boss_sartharion : public BossAI { case EVENT_SARTHARION_SUMMON_LAVA: { - if (!urand(0, 3)) - Talk(SAY_SARTHARION_SPECIAL); + Talk(SAY_SARTHARION_LAVA); SummonLavaWaves(); extraEvents.Repeat(25s); @@ -553,6 +552,16 @@ struct boss_sartharion : public BossAI break; } + case EVENT_SARTHARION_LAVA_STRIKE: + { + Talk(SAY_SARTHARION_CYCLONE); + summons.RemoveNotExisting(); + if (auto summon = summons.GetRandomCreatureWithEntry(NPC_FIRE_CYCLONE)) + summon->CastSpell(summon, SPELL_CYCLONE_AURA_PERIODIC, true); + + extraEvents.Repeat((below11PctReached ? randtime(1400ms, 2s) : 25s)); + break; + } default: break; } @@ -577,7 +586,7 @@ struct boss_sartharion : public BossAI case EVENT_SARTHARION_CAST_FLAME_BREATH: { DoCastVictim(SPELL_SARTHARION_FLAME_BREATH, false); - events.Repeat(20s); + events.Repeat(10s); break; } case EVENT_SARTHARION_CAST_TAIL_LASH: @@ -586,30 +595,6 @@ struct boss_sartharion : public BossAI events.Repeat(18s); break; } - case EVENT_SARTHARION_LAVA_STRIKE: - { - if (!urand(0, 2)) - Talk(SAY_SARTHARION_SPECIAL_4); - - summons.RemoveNotExisting(); - uint8 rand = urand(0, MAX_CYCLONE_COUNT - 1); // 5 - number of cyclones - uint8 iter = 0; - if (!summons.empty()) - { - for (ObjectGuid const& summonGuid : summons) - { - Creature* summon = ObjectAccessor::GetCreature(*me, summonGuid); - if (summon && summon->GetEntry() == NPC_FIRE_CYCLONE && iter == rand) - { - summon->CastSpell(summon, SPELL_CYCLONE_AURA_PERIODIC, true); - ++iter; - } - } - } - - events.Repeat((below11PctReached ? randtime(1400ms, 2s) : randtime(5s, 20s))); - break; - } case EVENT_SARTHARION_BERSERK: { summons.DespawnEntry(NPC_SAFE_AREA_TRIGGER); From 7a7f455ca2fbe9c2f554e59d587f9caa872bc733 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Feb 2026 17:13:04 +0000 Subject: [PATCH 128/335] chore(DB): import pending files Referenced commit(s): 404a568bef8bba6f29762249449ae52b49478cc6 --- .../lava_strike.sql => db_world/2026_02_15_03.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/lava_strike.sql => db_world/2026_02_15_03.sql} (77%) diff --git a/data/sql/updates/pending_db_world/lava_strike.sql b/data/sql/updates/db_world/2026_02_15_03.sql similarity index 77% rename from data/sql/updates/pending_db_world/lava_strike.sql rename to data/sql/updates/db_world/2026_02_15_03.sql index 327c2b7c4..3b7ca78e5 100644 --- a/data/sql/updates/pending_db_world/lava_strike.sql +++ b/data/sql/updates/db_world/2026_02_15_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_15_02 -> 2026_02_15_03 -- Move the text in its own group. UPDATE `creature_text` SET `GroupID` = 10, `ID` = 0 WHERE (`CreatureID` = 28860) AND (`GroupID` = 7) AND (`ID` = 3); From c7a8c9ae9a444b62223280e90de6d40957e62d12 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 15 Feb 2026 15:14:42 -0300 Subject: [PATCH 129/335] fix(Core/Player): Fix skill rewarded spell learning to properly handle skill-rewarded spells with out-of-order IDs (#24581) Co-authored-by: Claude Haiku 4.5 Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/server/game/Entities/Player/Player.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 1414098af..d100bbc8b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -11993,7 +11993,17 @@ void Player::learnSkillRewardedSpells(uint32 skill_id, uint32 skill_value) { uint32 raceMask = getRaceMask(); uint32 classMask = getClassMask(); - for (SkillLineAbilityEntry const* pAbility : GetSkillLineAbilitiesBySkillLine(skill_id)) + + // Get all abilities for this skill and sort by MinSkillLineRank (lowest to highest) + auto abilities = GetSkillLineAbilitiesBySkillLine(skill_id); + std::vector sortedAbilities(abilities.begin(), abilities.end()); + std::sort(sortedAbilities.begin(), sortedAbilities.end(), + [](SkillLineAbilityEntry const* a, SkillLineAbilityEntry const* b) + { + return a->MinSkillLineRank < b->MinSkillLineRank; + }); + + for (SkillLineAbilityEntry const* pAbility : sortedAbilities) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(pAbility->Spell); if (!spellInfo) From dcafad1a41b9f7befc7b73a39cb0caf3d382b41c Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sun, 15 Feb 2026 16:51:23 -0300 Subject: [PATCH 130/335] fix(Scripts/StormPeaks): Time-Lost & Vyragosa rescheduling and invisible combat (#24691) --- src/server/scripts/Northrend/zone_storm_peaks.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index 3317d63ca..4b4b17728 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -221,15 +221,22 @@ public: { npc_time_lost_proto_drakeAI(Creature* creature) : ScriptedAI(creature) {} + void Reset() override + { + scheduler.CancelAll(); + } + void InitializeAI() override { ScriptedAI::InitializeAI(); me->SetAnimTier(AnimTier::Fly); me->setActive(true); me->SetVisible(false); + me->SetImmuneToAll(true); me->m_Events.AddEventAtOffset([&] { me->SetVisible(true); + me->SetImmuneToAll(false); }, Hours(urand(6, 22))); } From ce74c0b19cb80eddbc7c70ad6697d5849f7fa04a Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 15 Feb 2026 15:05:00 -0600 Subject: [PATCH 131/335] feat(Core/Scripts): Add gameobject_summon_groups with quaternion rotation support (#24708) Co-authored-by: blinkysc --- .../rev_1771030836870880917.sql | 49 ++++++ .../game/AI/SmartScripts/SmartScript.cpp | 8 + .../game/AI/SmartScripts/SmartScriptMgr.cpp | 2 + .../game/AI/SmartScripts/SmartScriptMgr.h | 8 +- .../game/Entities/Creature/TemporarySummon.h | 10 ++ src/server/game/Entities/Object/Object.cpp | 26 ++++ src/server/game/Entities/Object/Object.h | 1 + src/server/game/Globals/ObjectMgr.cpp | 81 ++++++++++ src/server/game/Globals/ObjectMgr.h | 13 ++ src/server/game/Maps/Map.h | 1 + src/server/game/World/World.cpp | 3 + .../Globals/GameObjectSummonGroupTest.cpp | 141 ++++++++++++++++++ 12 files changed, 342 insertions(+), 1 deletion(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771030836870880917.sql create mode 100644 src/test/server/game/Globals/GameObjectSummonGroupTest.cpp diff --git a/data/sql/updates/pending_db_world/rev_1771030836870880917.sql b/data/sql/updates/pending_db_world/rev_1771030836870880917.sql new file mode 100644 index 000000000..f8ffe265e --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771030836870880917.sql @@ -0,0 +1,49 @@ +-- DB update 2026_02_13_00 >> 2026_02_13_01 +-- Add gameobject_summon_groups table +DROP TABLE IF EXISTS `gameobject_summon_groups`; +CREATE TABLE IF NOT EXISTS `gameobject_summon_groups` ( + `summonerId` int unsigned NOT NULL DEFAULT '0', + `summonerType` tinyint unsigned NOT NULL DEFAULT '0', + `groupId` tinyint unsigned NOT NULL DEFAULT '0', + `entry` int unsigned NOT NULL DEFAULT '0', + `position_x` float NOT NULL DEFAULT '0', + `position_y` float NOT NULL DEFAULT '0', + `position_z` float NOT NULL DEFAULT '0', + `orientation` float NOT NULL DEFAULT '0', + `rotation0` float NOT NULL DEFAULT '0', + `rotation1` float NOT NULL DEFAULT '0', + `rotation2` float NOT NULL DEFAULT '0', + `rotation3` float NOT NULL DEFAULT '0', + `respawnTime` int unsigned NOT NULL DEFAULT '120', + `Comment` varchar(255) CHARACTER SET `utf8mb4` COLLATE `utf8mb4_unicode_ci` NOT NULL DEFAULT '' +) ENGINE=InnoDB DEFAULT CHARSET=`utf8mb4` COLLATE=`utf8mb4_unicode_ci`; + +-- Quest 619 "Enticing Negolash" - Gameobject spawns on quest turn-in at Ruined Lifeboat (GO 2289) +-- Sniff data: Barbequed Buzzard Wings (2332), Stranglevine Wine (2333), Baked Bread (2562) +DELETE FROM `gameobject_summon_groups` WHERE `summonerId` = 2289 AND `summonerType` = 1; +INSERT INTO `gameobject_summon_groups` (`summonerId`, `summonerType`, `groupId`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `respawnTime`, `Comment`) VALUES +(2289, 1, 0, 2332, -14652.3798828125, 146.5117950439453125, 3.501179933547973632, 0.349065244197845458, 0, 0, 0.173647880554199218, 0.984807789325714111, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2332, -14652.9423828125, 146.867401123046875, 2.506906986236572265, 2.949595451354980468, 0, 0, 0.995395660400390625, 0.095851235091686248, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2332, -14653.017578125, 146.524169921875, 2.355585098266601562, 6.003933906555175781, 0, 0, -0.13917255401611328, 0.990268170833587646, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2332, -14653.044921875, 145.137908935546875, 2.653269052505493164, 5.84685373306274414, 0, 0, -0.21643924713134765, 0.976296067237854003, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2332, -14654.0361328125, 147.3063201904296875, 2.467313051223754882, 0.942476630210876464, 0, 0, 0.453989982604980468, 0.891006767749786376, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2332, -14654.45703125, 147.324005126953125, 2.456363916397094726, 1.815141916275024414, 0, 0, 0.788010597229003906, 0.615661680698394775, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2332, -14654.703125, 146.1419219970703125, 2.089060068130493164, 2.373644113540649414, 0, 0, 0.927183151245117187, 0.37460830807685852, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2332, -14654.87890625, 147.2779693603515625, 2.425240993499755859, 5.881760597229003906, 0, 0, -0.19936752319335937, 0.979924798011779785, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2332, -14655.1357421875, 146.6710968017578125, 2.230948925018310546, 2.652894020080566406, 0, 0, 0.970294952392578125, 0.241925001144409179, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2332, -14655.2763671875, 147.80206298828125, 2.639719009399414062, 6.161012649536132812, 0, 0, -0.06104850769042968, 0.998134791851043701, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2332, -14656.1884765625, 147.0958404541015625, 2.387770891189575195, 0.174532130360603332, 0, 0, 0.087155342102050781, 0.996194720268249511, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2332, -14656.8330078125, 148.8932647705078125, 3.288661956787109375, 5.096362113952636718, 0, 0, -0.55919265747070312, 0.829037725925445556, 120, 'Enticing Negolash - Barbequed Buzzard Wings'), +(2289, 1, 0, 2333, -14653.044921875, 145.3892364501953125, 2.85199904441833496, 4.852017402648925781, 0, 0, -0.65605831146240234, 0.754710197448730468, 120, 'Enticing Negolash - Stranglevine Wine'), +(2289, 1, 0, 2333, -14655.728515625, 148.9776458740234375, 4.056398868560791015, 3.473210096359252929, 0, 0, -0.98628520965576171, 0.165049895644187927, 120, 'Enticing Negolash - Stranglevine Wine'), +(2289, 1, 0, 2333, -14656.4482421875, 147.5946807861328125, 3.129076004028320312, 1.588248729705810546, 0, 0, 0.713250160217285156, 0.700909554958343505, 120, 'Enticing Negolash - Stranglevine Wine'), +(2289, 1, 0, 2333, -14656.8408203125, 147.4337310791015625, 3.102070093154907226, 3.019413232803344726, 0, 0, 0.998134613037109375, 0.061051756143569946, 120, 'Enticing Negolash - Stranglevine Wine'), +(2289, 1, 0, 2333, -14657.1513671875, 148.227569580078125, 2.886320114135742187, 1.535889506340026855, 0, 0, 0.694658279418945312, 0.719339847564697265, 120, 'Enticing Negolash - Stranglevine Wine'), +(2289, 1, 0, 2562, -14652.4326171875, 145.7533721923828125, 3.254641056060791015, 2.932138919830322265, 0, 0, 0.994521141052246093, 0.104535527527332305, 120, 'Enticing Negolash - Baked Bread'), +(2289, 1, 0, 2562, -14653.8486328125, 146.2042694091796875, 2.14631199836730957, 4.886923789978027343, 0, 0, -0.64278697967529296, 0.766044974327087402, 120, 'Enticing Negolash - Baked Bread'), +(2289, 1, 0, 2562, -14656.138671875, 148.3673248291015625, 3.515635967254638671, 5.637413978576660156, 0, 0, -0.31730461120605468, 0.948323667049407958, 120, 'Enticing Negolash - Baked Bread'); + +-- SmartAI: Ruined Lifeboat (GO 2289) - On Quest 619 Reward - Summon Gameobject Group 0 +DELETE FROM `smart_scripts` WHERE `entryorguid` = 2289 AND `source_type` = 1 AND `id` = 1; +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 +(2289, 1, 1, 0, 20, 0, 100, 0, 619, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ruined Lifeboat - On Quest ''Enticing Negolash'' Rewarded - Summon Gameobject Group 0'); diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index ff41ef0ed..f80a36d7a 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3332,6 +3332,14 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } break; } + case SMART_ACTION_SUMMON_GAMEOBJECT_GROUP: + { + if (!GetBaseObject()) + break; + + GetBaseObject()->SummonGameObjectGroup(e.action.gameobjectGroup.group); + break; + } default: LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry {} SourceType {}, Event {}, Unhandled Action type {}", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); break; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 834c1bc79..52faaef4b 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -886,6 +886,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e) case SMART_ACTION_DISABLE_REWARD: return sizeof(SmartAction::reward); case SMART_ACTION_SET_ANIM_TIER: return sizeof(SmartAction::animTier); case SMART_ACTION_SET_GOSSIP_MENU: return sizeof(SmartAction::setGossipMenu); + case SMART_ACTION_SUMMON_GAMEOBJECT_GROUP: return sizeof(SmartAction::gameobjectGroup); case SMART_ACTION_DISMOUNT: return NO_PARAMS; default: LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using an action with no unused params specified in SmartAIMgr::CheckUnusedActionParams(), please report this.", @@ -2042,6 +2043,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_MOVEMENT_RESUME: case SMART_ACTION_WORLD_SCRIPT: case SMART_ACTION_SET_GOSSIP_MENU: + case SMART_ACTION_SUMMON_GAMEOBJECT_GROUP: break; default: LOG_ERROR("sql.sql", "SmartAIMgr: Not handled action_type({}), event_type({}), Entry {} SourceType {} Event {}, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 8296d38d3..2601f5bd1 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -725,8 +725,9 @@ enum SMART_ACTION SMART_ACTION_DISABLE_REWARD = 238, // reputation 0/1, loot 0/1 SMART_ACTION_SET_ANIM_TIER = 239, // animtier SMART_ACTION_SET_GOSSIP_MENU = 240, // gossipMenuId + SMART_ACTION_SUMMON_GAMEOBJECT_GROUP = 241, // group - SMART_ACTION_AC_END = 241, // placeholder + SMART_ACTION_AC_END = 242, // placeholder }; enum class SmartActionSummonCreatureFlags @@ -1517,6 +1518,11 @@ struct SmartAction { uint32 gossipMenuId; } setGossipMenu; + + struct + { + uint32 group; + } gameobjectGroup; }; }; diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index 4140d37c7..740779162 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -19,6 +19,7 @@ #define AZEROTHCORE_TEMPSUMMON_H #include "Creature.h" +#include "G3D/Quat.h" enum SummonerType { @@ -36,6 +37,15 @@ struct TempSummonData uint32 time; ///< Despawn time, usable only with certain temp summon types }; +/// Stores data for temp gameobject summons +struct GameObjectSummonData +{ + uint32 entry; + Position pos; + G3D::Quat rot; + uint32 respawnTime; ///< Duration in seconds; passed to SummonGameObject's respawnTime parameter +}; + class TempSummon : public Creature { public: diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 8df600651..921eb4ff3 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2284,6 +2284,18 @@ void Map::SummonCreatureGroup(uint8 group, std::list* list /*= null list->push_back(summon); } +void Map::SummonGameObjectGroup(uint8 group, std::list* list /*= nullptr*/) +{ + std::vector const* data = sObjectMgr->GetGameObjectSummonGroup(GetId(), SUMMONER_TYPE_MAP, group); + if (!data) + return; + + for (std::vector::const_iterator itr = data->begin(); itr != data->end(); ++itr) + if (GameObject* go = SummonGameObject(itr->entry, itr->pos.GetPositionX(), itr->pos.GetPositionY(), itr->pos.GetPositionZ(), itr->pos.GetOrientation(), itr->rot.x, itr->rot.y, itr->rot.z, itr->rot.w, itr->respawnTime)) + if (list) + list->push_back(go); +} + TempSummon* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float ang, TempSummonType spwtype, uint32 despwtime, SummonPropertiesEntry const* properties, bool visibleBySummonerOnly) { if (!x && !y && !z) @@ -2440,6 +2452,20 @@ void WorldObject::SummonCreatureGroup(uint8 group, std::list* list list->push_back(summon); } +void WorldObject::SummonGameObjectGroup(uint8 group, std::list* list /*= nullptr*/) +{ + ASSERT((IsGameObject() || IsCreature()) && "Only GOs and creatures can summon gameobject groups!"); + + std::vector const* data = sObjectMgr->GetGameObjectSummonGroup(GetEntry(), IsGameObject() ? SUMMONER_TYPE_GAMEOBJECT : SUMMONER_TYPE_CREATURE, group); + if (!data) + return; + + for (std::vector::const_iterator itr = data->begin(); itr != data->end(); ++itr) + if (GameObject* go = SummonGameObject(itr->entry, itr->pos.GetPositionX(), itr->pos.GetPositionY(), itr->pos.GetPositionZ(), itr->pos.GetOrientation(), itr->rot.x, itr->rot.y, itr->rot.z, itr->rot.w, itr->respawnTime)) + if (list) + list->push_back(go); +} + Creature* WorldObject::FindNearestCreature(uint32 entry, float range, bool alive) const { Creature* creature = nullptr; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 02d38a2f5..b6bea411f 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -630,6 +630,7 @@ public: GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime, bool checkTransport = true, GOSummonType summonType = GO_SUMMON_TIMED_OR_CORPSE_DESPAWN); Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, bool setLevel = false, CreatureAI * (*GetAI)(Creature*) = nullptr); void SummonCreatureGroup(uint8 group, std::list* list = nullptr); + void SummonGameObjectGroup(uint8 group, std::list* list = nullptr); [[nodiscard]] Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const; [[nodiscard]] GameObject* FindNearestGameObject(uint32 entry, float range, bool onlySpawned = false) const; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 725ea0ca3..41fbafc9e 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2224,6 +2224,87 @@ void ObjectMgr::LoadTempSummons() LOG_INFO("server.loading", " "); } +void ObjectMgr::LoadGameObjectSummons() +{ + uint32 oldMSTime = getMSTime(); + + _goSummonDataStore.clear(); + + // 0 1 2 3 4 5 6 7 8 9 10 11 12 + QueryResult result = WorldDatabase.Query("SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, respawnTime FROM gameobject_summon_groups"); + + if (!result) + { + LOG_WARN("server.loading", ">> Loaded 0 gameobject summons. DB table `gameobject_summon_groups` is empty."); + return; + } + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + + uint32 summonerId = fields[0].Get(); + SummonerType summonerType = SummonerType(fields[1].Get()); + uint8 group = fields[2].Get(); + + switch (summonerType) + { + case SUMMONER_TYPE_CREATURE: + if (!GetCreatureTemplate(summonerId)) + { + LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has summoner with non existing entry {} for creature summoner type, skipped.", summonerId); + continue; + } + break; + case SUMMONER_TYPE_GAMEOBJECT: + if (!GetGameObjectTemplate(summonerId)) + { + LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has summoner with non existing entry {} for gameobject summoner type, skipped.", summonerId); + continue; + } + break; + case SUMMONER_TYPE_MAP: + if (!sMapStore.LookupEntry(summonerId)) + { + LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has summoner with non existing entry {} for map summoner type, skipped.", summonerId); + continue; + } + break; + default: + LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has unhandled summoner type {} for summoner {}, skipped.", summonerType, summonerId); + continue; + } + + GameObjectSummonData data; + data.entry = fields[3].Get(); + + if (!GetGameObjectTemplate(data.entry)) + { + LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has gameobject in group [Summoner ID: {}, Summoner Type: {}, Group ID: {}] with non existing gameobject entry {}, skipped.", summonerId, summonerType, group, data.entry); + continue; + } + + float posX = fields[4].Get(); + float posY = fields[5].Get(); + float posZ = fields[6].Get(); + float orientation = fields[7].Get(); + + data.pos.Relocate(posX, posY, posZ, orientation); + + data.rot = G3D::Quat(fields[8].Get(), fields[9].Get(), fields[10].Get(), fields[11].Get()); + data.respawnTime = fields[12].Get(); + + TempSummonGroupKey key(summonerId, summonerType, group); + _goSummonDataStore[key].push_back(data); + + ++count; + } while (result->NextRow()); + + LOG_INFO("server.loading", ">> Loaded {} Gameobject Summons in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", " "); +} + void ObjectMgr::LoadCreatures() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 0afcfdc5b..294f90959 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -507,6 +507,7 @@ typedef std::map LinkedRespawnContainer; typedef std::unordered_map CreatureDataContainer; typedef std::unordered_map GameObjectDataContainer; typedef std::map > TempSummonDataContainer; +typedef std::map > GameObjectSummonDataContainer; typedef std::unordered_map CreatureLocaleContainer; typedef std::unordered_map GameObjectLocaleContainer; typedef std::unordered_map ItemLocaleContainer; @@ -1036,6 +1037,7 @@ public: void LoadGameObjectQuestItems(); void LoadCreatureQuestItems(); void LoadTempSummons(); + void LoadGameObjectSummons(); void LoadCreatures(); void LoadCreatureSparring(); void LoadLinkedRespawn(); @@ -1208,6 +1210,15 @@ public: return nullptr; } + [[nodiscard]] std::vector const* GetGameObjectSummonGroup(uint32 summonerId, SummonerType summonerType, uint8 group) const + { + GameObjectSummonDataContainer::const_iterator itr = _goSummonDataStore.find(TempSummonGroupKey(summonerId, summonerType, group)); + if (itr != _goSummonDataStore.end()) + return &itr->second; + + return nullptr; + } + [[nodiscard]] BroadcastText const* GetBroadcastText(uint32 id) const { BroadcastTextContainer::const_iterator itr = _broadcastTextStore.find(id); @@ -1635,6 +1646,8 @@ private: GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore; /// Stores temp summon data grouped by summoner's entry, summoner's type and group id TempSummonDataContainer _tempSummonDataStore; + /// Stores gameobject summon data grouped by summoner's entry, summoner's type and group id + GameObjectSummonDataContainer _goSummonDataStore; BroadcastTextContainer _broadcastTextStore; ItemTemplateContainer _itemTemplateStore; diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 21226c54a..29857eadf 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -337,6 +337,7 @@ public: GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime, bool checkTransport = true); GameObject* SummonGameObject(uint32 entry, Position const& pos, float rotation0 = 0.0f, float rotation1 = 0.0f, float rotation2 = 0.0f, float rotation3 = 0.0f, uint32 respawnTime = 100, bool checkTransport = true); void SummonCreatureGroup(uint8 group, std::list* list = nullptr); + void SummonGameObjectGroup(uint8 group, std::list* list = nullptr); Corpse* GetCorpse(ObjectGuid const& guid); Creature* GetCreature(ObjectGuid const& guid); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index e1de134a2..035dfcb13 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -570,6 +570,9 @@ void World::SetInitialWorldSettings() LOG_INFO("server.loading", "Loading Temporary Summon Data..."); sObjectMgr->LoadTempSummons(); // must be after LoadCreatureTemplates() and LoadGameObjectTemplates() + LOG_INFO("server.loading", "Loading Gameobject Summon Data..."); + sObjectMgr->LoadGameObjectSummons(); // must be after LoadCreatureTemplates() and LoadGameObjectTemplates() + LOG_INFO("server.loading", "Loading Pet Levelup Spells..."); sSpellMgr->LoadPetLevelupSpellMap(); diff --git a/src/test/server/game/Globals/GameObjectSummonGroupTest.cpp b/src/test/server/game/Globals/GameObjectSummonGroupTest.cpp new file mode 100644 index 000000000..97664bc89 --- /dev/null +++ b/src/test/server/game/Globals/GameObjectSummonGroupTest.cpp @@ -0,0 +1,141 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ObjectMgr.h" +#include "SmartScriptMgr.h" +#include "TemporarySummon.h" +#include "WorldMock.h" +#include "gtest/gtest.h" + +class GameObjectSummonGroupTest : public ::testing::Test +{ +protected: + void SetUp() override + { + _previousWorld = std::move(sWorld); + auto* worldMock = + new ::testing::NiceMock(); + ON_CALL(*worldMock, getIntConfig(::testing::_)) + .WillByDefault(::testing::Return(0)); + sWorld.reset(worldMock); + } + + void TearDown() override + { + sWorld = std::move(_previousWorld); + } + + std::unique_ptr _previousWorld; +}; + +TEST_F(GameObjectSummonGroupTest, DataStructStoresFields) +{ + GameObjectSummonData data; + data.entry = 2332; + data.pos.Relocate(-14652.38f, 146.51f, 3.50f, 0.35f); + data.rot = G3D::Quat(0.0f, 0.0f, 0.17f, 0.98f); + data.respawnTime = 120; + + EXPECT_EQ(data.entry, 2332u); + EXPECT_FLOAT_EQ(data.pos.GetPositionX(), -14652.38f); + EXPECT_FLOAT_EQ(data.pos.GetPositionY(), 146.51f); + EXPECT_FLOAT_EQ(data.pos.GetPositionZ(), 3.50f); + EXPECT_FLOAT_EQ(data.pos.GetOrientation(), 0.35f); + EXPECT_FLOAT_EQ(data.rot.x, 0.0f); + EXPECT_FLOAT_EQ(data.rot.y, 0.0f); + EXPECT_FLOAT_EQ(data.rot.z, 0.17f); + EXPECT_FLOAT_EQ(data.rot.w, 0.98f); + EXPECT_EQ(data.respawnTime, 120u); +} + +TEST_F(GameObjectSummonGroupTest, QuaternionIdentity) +{ + GameObjectSummonData data; + data.rot = G3D::Quat(0.0f, 0.0f, 0.0f, 1.0f); + + EXPECT_FLOAT_EQ(data.rot.x, 0.0f); + EXPECT_FLOAT_EQ(data.rot.y, 0.0f); + EXPECT_FLOAT_EQ(data.rot.z, 0.0f); + EXPECT_FLOAT_EQ(data.rot.w, 1.0f); +} + +TEST_F(GameObjectSummonGroupTest, AccessorReturnsNullForMissing) +{ + auto const* result = sObjectMgr->GetGameObjectSummonGroup( + 99999, SUMMONER_TYPE_CREATURE, 0); + EXPECT_EQ(result, nullptr); +} + +TEST_F(GameObjectSummonGroupTest, AccessorReturnsNullForAllTypes) +{ + auto const* r1 = sObjectMgr->GetGameObjectSummonGroup( + 99999, SUMMONER_TYPE_CREATURE, 0); + auto const* r2 = sObjectMgr->GetGameObjectSummonGroup( + 99999, SUMMONER_TYPE_GAMEOBJECT, 0); + auto const* r3 = sObjectMgr->GetGameObjectSummonGroup( + 99999, SUMMONER_TYPE_MAP, 0); + + EXPECT_EQ(r1, nullptr); + EXPECT_EQ(r2, nullptr); + EXPECT_EQ(r3, nullptr); +} + +TEST_F(GameObjectSummonGroupTest, DifferentGroupsAreIndependent) +{ + auto const* g0 = sObjectMgr->GetGameObjectSummonGroup( + 2289, SUMMONER_TYPE_GAMEOBJECT, 0); + auto const* g1 = sObjectMgr->GetGameObjectSummonGroup( + 2289, SUMMONER_TYPE_GAMEOBJECT, 1); + + // Both should be null since DB isn't loaded in tests, + // but they should be independent lookups + EXPECT_EQ(g0, nullptr); + EXPECT_EQ(g1, nullptr); +} + +TEST_F(GameObjectSummonGroupTest, SmartActionEnumValue) +{ + EXPECT_EQ(SMART_ACTION_SUMMON_GAMEOBJECT_GROUP, 241); + EXPECT_EQ(SMART_ACTION_AC_END, 242); +} + +TEST_F(GameObjectSummonGroupTest, SmartActionUnionSize) +{ + SmartAction action{}; + action.gameobjectGroup.group = 5; + EXPECT_EQ(action.gameobjectGroup.group, 5u); +} + +TEST_F(GameObjectSummonGroupTest, TempSummonGroupKeyOrdering) +{ + TempSummonGroupKey k1(100, SUMMONER_TYPE_CREATURE, 0); + TempSummonGroupKey k2(100, SUMMONER_TYPE_GAMEOBJECT, 0); + TempSummonGroupKey k3(100, SUMMONER_TYPE_CREATURE, 1); + TempSummonGroupKey k4(200, SUMMONER_TYPE_CREATURE, 0); + + // std::tuple ordering: summoner ID first, then type, then group + EXPECT_LT(k1, k2); // same id, creature < gameobject + EXPECT_LT(k1, k3); // same id+type, group 0 < 1 + EXPECT_LT(k1, k4); // id 100 < 200 +} + +TEST_F(GameObjectSummonGroupTest, SummonerTypeValues) +{ + EXPECT_EQ(SUMMONER_TYPE_CREATURE, 0); + EXPECT_EQ(SUMMONER_TYPE_GAMEOBJECT, 1); + EXPECT_EQ(SUMMONER_TYPE_MAP, 2); +} From dea82df9a9b20e2ec0bcfaab215223a4a3c441bc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Feb 2026 21:06:07 +0000 Subject: [PATCH 132/335] chore(DB): import pending files Referenced commit(s): ce74c0b19cb80eddbc7c70ad6697d5849f7fa04a --- .../rev_1771030836870880917.sql => db_world/2026_02_15_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771030836870880917.sql => db_world/2026_02_15_04.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771030836870880917.sql b/data/sql/updates/db_world/2026_02_15_04.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771030836870880917.sql rename to data/sql/updates/db_world/2026_02_15_04.sql index f8ffe265e..8eca269c7 100644 --- a/data/sql/updates/pending_db_world/rev_1771030836870880917.sql +++ b/data/sql/updates/db_world/2026_02_15_04.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_15_03 -> 2026_02_15_04 -- DB update 2026_02_13_00 >> 2026_02_13_01 -- Add gameobject_summon_groups table DROP TABLE IF EXISTS `gameobject_summon_groups`; From 35126423ac184ded18cec26f5fef752d24a9e303 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 15 Feb 2026 18:39:21 -0300 Subject: [PATCH 133/335] refactor(Scripts/EoE): Make use of creature/GO storages (#24724) --- .../Nexus/EyeOfEternity/boss_malygos.cpp | 286 +++++++++--------- .../Nexus/EyeOfEternity/eye_of_eternity.h | 4 +- .../instance_eye_of_eternity.cpp | 197 ++++++------ 3 files changed, 234 insertions(+), 253 deletions(-) diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 1ed35c6e6..67c9af88e 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -235,8 +235,8 @@ struct boss_malygos : public BossAI { float angle = me->GetOrientation(); float dist = 75.0f; - if (Creature* c = me->SummonCreature(NPC_PORTAL, me->GetPositionX() + cos(angle) * dist, me->GetPositionY() + std::sin(angle) * dist, me->GetPositionZ(), FourSidesPos[id].GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 13000)) - me->CastSpell(c, SPELL_PORTAL_BEAM, false); + if (Creature* portal = me->SummonCreature(NPC_PORTAL, me->GetPositionX() + cos(angle) * dist, me->GetPositionY() + std::sin(angle) * dist, me->GetPositionZ(), FourSidesPos[id].GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 13000)) + me->CastSpell(portal, SPELL_PORTAL_BEAM, false); timer2 = INTRO_MOVEMENT_INTERVAL - 10000; } break; @@ -245,8 +245,8 @@ struct boss_malygos : public BossAI events.RescheduleEvent(EVENT_INTRO_LAND, 0ms, 1); break; case MI_POINT_VORTEX_CENTER: - if (Creature* c = me->SummonCreature(NPC_WORLD_TRIGGER_LAOI, CenterPos, TEMPSUMMON_TIMED_DESPAWN, 15000)) - c->CastSpell(c, SPELL_VORTEX_VISUAL, true); + if (Creature* trigger = me->SummonCreature(NPC_WORLD_TRIGGER_LAOI, CenterPos, TEMPSUMMON_TIMED_DESPAWN, 15000)) + trigger->CastSpell(trigger, SPELL_VORTEX_VISUAL, true); events.RescheduleEvent(EVENT_START_VORTEX_REAL, 1s, 1); break; case MI_POINT_CENTER_GROUND_PH_2: @@ -394,12 +394,12 @@ struct boss_malygos : public BossAI case EVENT_SUMMON_POWER_SPARK: { uint8 random = urand(0, 3); - if (Creature* c = me->SummonCreature(NPC_PORTAL, FourSidesPos[random], TEMPSUMMON_TIMED_DESPAWN, 6000)) - c->CastSpell(c, SPELL_PORTAL_BEAM, false); - if (Creature* c = me->SummonCreature(NPC_POWER_SPARK, FourSidesPos[random], TEMPSUMMON_MANUAL_DESPAWN, 0)) + if (Creature* portal = me->SummonCreature(NPC_PORTAL, FourSidesPos[random], TEMPSUMMON_TIMED_DESPAWN, 6000)) + portal->CastSpell(portal, SPELL_PORTAL_BEAM, false); + if (Creature* spark = me->SummonCreature(NPC_POWER_SPARK, FourSidesPos[random], TEMPSUMMON_MANUAL_DESPAWN, 0)) { - c->AI()->DoAction(ACTION_POWER_SPARK_FOLLOW); - c->AI()->Talk(EMOTE_POWER_SPARK); + spark->AI()->DoAction(ACTION_POWER_SPARK_FOLLOW); + spark->AI()->Talk(EMOTE_POWER_SPARK); } events.Repeat(20s, 30s); @@ -444,47 +444,47 @@ struct boss_malygos : public BossAI { vp->SetDisableGravity(true); - me->GetMap()->DoForAllPlayers([&](Player* pPlayer) + me->GetMap()->DoForAllPlayers([&](Player* player) { - if (!pPlayer->IsAlive() || pPlayer->IsGameMaster()) + if (!player->IsAlive() || player->IsGameMaster()) return; Position plrpos; - float playerAngle = CenterPos.GetAngle(pPlayer); + float playerAngle = CenterPos.GetAngle(player); plrpos.m_positionX = CenterPos.GetPositionX() + cos(playerAngle) * 5.0f; plrpos.m_positionY = CenterPos.GetPositionY() + std::sin(playerAngle) * 5.0f; plrpos.m_positionZ = CenterPos.GetPositionZ() + 18.0f; plrpos.SetOrientation(plrpos.GetAngle(&CenterPos)); - if (Creature* c = me->SummonCreature(NPC_VORTEX, plrpos, TEMPSUMMON_TIMED_DESPAWN, 15000)) + if (Creature* vortex = me->SummonCreature(NPC_VORTEX, plrpos, TEMPSUMMON_TIMED_DESPAWN, 15000)) { - pPlayer->CastSpell(pPlayer, SPELL_FREEZE_ANIM, true); - pPlayer->CastSpell(c, SPELL_VORTEX_CONTROL_VEHICLE, true); - if (!pPlayer->GetVehicle()) // didn't work somehow, try again with a different way, if fails - break + player->CastSpell(player, SPELL_FREEZE_ANIM, true); + player->CastSpell(vortex, SPELL_VORTEX_CONTROL_VEHICLE, true); + if (!player->GetVehicle()) // didn't work somehow, try again with a different way, if fails - break { - pPlayer->EnterVehicle(c, 0); - if (!pPlayer->GetVehicle()) + player->EnterVehicle(vortex, 0); + if (!player->GetVehicle()) return; } - //pPlayer->ClearUnitState(UNIT_STATE_ONVEHICLE); + //player->ClearUnitState(UNIT_STATE_ONVEHICLE); - Movement::MoveSplineInit init(pPlayer); // TODO: has to be removed and handled with vehicle exit and vehicle enter code + Movement::MoveSplineInit init(player); // TODO: has to be removed and handled with vehicle exit and vehicle enter code init.MoveTo(CenterPos.GetPositionX(), CenterPos.GetPositionY(), CenterPos.GetPositionZ()); - init.SetFacing(pPlayer->GetOrientation()); + init.SetFacing(player->GetOrientation()); init.SetTransportExit(); init.Launch(); - pPlayer->SetUnitMovementFlags(MOVEMENTFLAG_NONE); - pPlayer->SetDisableGravity(true); + player->SetUnitMovementFlags(MOVEMENTFLAG_NONE); + player->SetDisableGravity(true); WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); - data << pPlayer->GetPackGUID(); - pPlayer->SendMessageToSet(&data, true); + data << player->GetPackGUID(); + player->SendMessageToSet(&data, true); - sScriptMgr->AnticheatSetUnderACKmount(pPlayer); + sScriptMgr->AnticheatSetUnderACKmount(player); - pPlayer->SetGuidValue(PLAYER_FARSIGHT, vp->GetGUID()); - c->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + player->SetGuidValue(PLAYER_FARSIGHT, vp->GetGUID()); + vortex->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); } }); } @@ -538,9 +538,9 @@ struct boss_malygos : public BossAI float dist = 22.0f; float angle = M_PI / 2 + ((float)i / MAX_NEXUS_LORDS) * 2 * M_PI; if (Creature* disk = me->SummonCreature(NPC_HOVER_DISK, CenterPos.GetPositionX() + cos(angle) * dist, CenterPos.GetPositionY() + std::sin(angle) * dist, CenterPos.GetPositionZ() + 30.0f, 0.0f, TEMPSUMMON_MANUAL_DESPAWN, 0)) - if (Creature* c = me->SummonCreature(NPC_NEXUS_LORD, *disk, TEMPSUMMON_MANUAL_DESPAWN, 0)) + if (Creature* lord = me->SummonCreature(NPC_NEXUS_LORD, *disk, TEMPSUMMON_MANUAL_DESPAWN, 0)) { - c->EnterVehicle(disk, 0); + lord->EnterVehicle(disk, 0); disk->AI()->DoAction(ACTION_DISK_START_MOVING); } } @@ -549,9 +549,9 @@ struct boss_malygos : public BossAI float dist = 30.0f; float angle = 0.0f + ((float)i / MAX_SCIONS_OF_ETERNITY) * 2 * M_PI; if (Creature* disk = me->SummonCreature(NPC_HOVER_DISK, CenterPos.GetPositionX() + cos(angle) * dist, CenterPos.GetPositionY() + std::sin(angle) * dist, CenterPos.GetPositionZ() + 30.0f, 0.0f, TEMPSUMMON_MANUAL_DESPAWN, 0)) - if (Creature* c = me->SummonCreature(NPC_SCION_OF_ETERNITY, *disk, TEMPSUMMON_MANUAL_DESPAWN, 0)) + if (Creature* scion = me->SummonCreature(NPC_SCION_OF_ETERNITY, *disk, TEMPSUMMON_MANUAL_DESPAWN, 0)) { - c->EnterVehicle(disk, 0); + scion->EnterVehicle(disk, 0); disk->AI()->DoAction(ACTION_DISK_START_MOVING); } } @@ -595,8 +595,8 @@ struct boss_malygos : public BossAI events.RescheduleEvent(EVENT_SPELL_SURGE_OF_POWER, 1500ms, 1); break; case EVENT_SPELL_SURGE_OF_POWER: - if (Creature* c = me->SummonCreature(NPC_SURGE_OF_POWER, CenterPos, TEMPSUMMON_TIMED_DESPAWN, 10000)) - me->CastSpell(c, SPELL_SURGE_OF_POWER, false); + if (Creature* surge = me->SummonCreature(NPC_SURGE_OF_POWER, CenterPos, TEMPSUMMON_TIMED_DESPAWN, 10000)) + me->CastSpell(surge, SPELL_SURGE_OF_POWER, false); Talk(SAY_SURGE_OF_POWER); events.RescheduleEvent(EVENT_CLEAR_TARGET, 10s, 1); events.RescheduleEvent(EVENT_RESUME_FLYING_CIRCLES_PH_2, 10s, 1); @@ -632,11 +632,11 @@ struct boss_malygos : public BossAI me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_CHANGE_DIMENSIONS, 2s); break; case EVENT_DESTROY_PLATFORM_0: - if (Creature* c = me->SummonCreature(NPC_WORLD_TRIGGER_LAOI, CenterPos, TEMPSUMMON_TIMED_DESPAWN, 3000)) + if (Creature* trigger = me->SummonCreature(NPC_WORLD_TRIGGER_LAOI, CenterPos, TEMPSUMMON_TIMED_DESPAWN, 3000)) { - c->SetFaction(me->GetFaction()); - c->CastSpell(c, SPELL_DESTROY_PLATFORM_VISUAL, true); - c->CastSpell(c, SPELL_DESTROY_PLATFORM_EFFECT, false); + trigger->SetFaction(me->GetFaction()); + trigger->CastSpell(trigger, SPELL_DESTROY_PLATFORM_VISUAL, true); + trigger->CastSpell(trigger, SPELL_DESTROY_PLATFORM_EFFECT, false); } me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_OBSCURE_SPACE, 1s); events.RescheduleEvent(EVENT_MOVE_TO_PHASE_3_POSITION, 2s, 1); @@ -784,7 +784,7 @@ struct boss_malygos : public BossAI struct npc_vortex_ride : public VehicleAI { - npc_vortex_ride(Creature* pCreature) : VehicleAI(pCreature) + npc_vortex_ride(Creature* creature) : VehicleAI(creature) { vortexRadius = urand(22, 28); float h = urand(15, 30); @@ -810,15 +810,15 @@ struct npc_vortex_ride : public VehicleAI if (!pass || apply || !pass->IsPlayer()) return; - Player* plr = pass->ToPlayer(); - float speed = plr->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()) / (1.0f * 0.001f); - plr->SetDisableGravity(false); // packet only would lead to issues elsewhere - plr->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), speed); - plr->RemoveAura(SPELL_FREEZE_ANIM); - plr->SetGuidValue(PLAYER_FARSIGHT, ObjectGuid::Empty); + Player* player = pass->ToPlayer(); + float speed = player->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()) / (1.0f * 0.001f); + player->SetDisableGravity(false); // packet only would lead to issues elsewhere + player->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), speed); + player->RemoveAura(SPELL_FREEZE_ANIM); + player->SetGuidValue(PLAYER_FARSIGHT, ObjectGuid::Empty); - sScriptMgr->AnticheatSetCanFlybyServer(plr, false); - sScriptMgr->AnticheatSetUnderACKmount(plr); + sScriptMgr->AnticheatSetCanFlybyServer(player, false); + sScriptMgr->AnticheatSetUnderACKmount(player); } void UpdateAI(uint32 diff) override @@ -848,15 +848,15 @@ struct npc_vortex_ride : public VehicleAI float dist = 2 * me->GetDistance2d(newx, newy); if (me->GetVehicleKit()) if (Unit* pass = me->GetVehicleKit()->GetPassenger(0)) - if (Player* plr = pass->ToPlayer()) + if (Player* player = pass->ToPlayer()) { if (!bUpdatedFlying && timer) { bUpdatedFlying = true; - plr->SetDisableGravity(true); + player->SetDisableGravity(true); } - plr->SendMonsterMove(me->GetPositionX() + dist * cos(arcangle), me->GetPositionY() + dist * std::sin(arcangle), me->GetPositionZ(), VORTEX_DEFAULT_DIFF * 2, SPLINEFLAG_FLYING); + player->SendMonsterMove(me->GetPositionX() + dist * cos(arcangle), me->GetPositionY() + dist * std::sin(arcangle), me->GetPositionZ(), VORTEX_DEFAULT_DIFF * 2, SPLINEFLAG_FLYING); me->Relocate(newx, newy); } @@ -873,27 +873,27 @@ struct npc_vortex_ride : public VehicleAI struct npc_power_spark : public NullCreatureAI { - npc_power_spark(Creature* pCreature) : NullCreatureAI(pCreature) + npc_power_spark(Creature* creature) : NullCreatureAI(creature) { - pInstance = me->GetInstanceScript(); + _instance = me->GetInstanceScript(); me->CastSpell(me, SPELL_POWER_SPARK_VISUAL, false); - CheckTimer = 1000; - MoveTimer = 0; + _checkTimer = 1000; + _moveTimer = 0; } - InstanceScript* pInstance; - uint16 CheckTimer; - uint16 MoveTimer; + InstanceScript* _instance; + uint16 _checkTimer; + uint16 _moveTimer; void DoAction(int32 param) override { switch (param) { case ACTION_POWER_SPARK_FOLLOW: - MoveTimer = 1; + _moveTimer = 1; break; case ACTION_POWER_SPARK_STOP: - MoveTimer = 0; + _moveTimer = 0; me->GetMotionMaster()->MoveIdle(); me->DisableSpline(); me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 0.05f, FORCED_MOVEMENT_NONE, 7.0f); @@ -910,7 +910,7 @@ struct npc_power_spark : public NullCreatureAI if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) return; - MoveTimer = 0; + _moveTimer = 0; me->GetMotionMaster()->MoveIdle(); me->DisableSpline(); me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), CenterPos.GetPositionZ(), FORCED_MOVEMENT_NONE, 100.0f); @@ -925,39 +925,40 @@ struct npc_power_spark : public NullCreatureAI if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) return; - if (CheckTimer <= diff) + if (_checkTimer <= diff) { - if (pInstance) - if (Creature* c = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_MALYGOS_GUID))) - if (me->IsWithinDist3d(c, 12.0f)) + if (_instance) + { + if (Creature* malygos = _instance->GetCreature(DATA_MALYGOS)) + { + if (me->IsWithinDist3d(malygos, 12.0f)) { - me->CastSpell(c, SPELL_POWER_SPARK_MALYGOS_BUFF, true); + me->CastSpell(malygos, SPELL_POWER_SPARK_MALYGOS_BUFF, true); me->DespawnOrUnsummon(); return; } - CheckTimer = 1000; + } + } + _checkTimer = 1000; } else - CheckTimer -= diff; + _checkTimer -= diff; - if (MoveTimer) + if (_moveTimer <= diff) { - if (MoveTimer <= diff) - { - if (pInstance) - if (Creature* c = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_MALYGOS_GUID))) - me->GetMotionMaster()->MovePoint(0, *c); - MoveTimer = 2000; - } - else - MoveTimer -= diff; + if (_instance) + if (Creature* malygos = _instance->GetCreature(DATA_MALYGOS)) + me->GetMotionMaster()->MovePoint(0, *malygos); + _moveTimer = 2000; } + else + _moveTimer -= diff; } }; struct npc_nexus_lord : public ScriptedAI { - npc_nexus_lord(Creature* pCreature) : ScriptedAI(pCreature) + npc_nexus_lord(Creature* creature) : ScriptedAI(creature) { me->SetReactState(REACT_PASSIVE); timer = 0; @@ -1016,28 +1017,28 @@ struct npc_nexus_lord : public ScriptedAI void JustDied(Unit* /*killer*/) override { - if (Vehicle* v = me->GetVehicle()) - v->RemoveAllPassengers(); + if (Vehicle* vehicle = me->GetVehicle()) + vehicle->RemoveAllPassengers(); } }; struct npc_scion_of_eternity : public ScriptedAI { - npc_scion_of_eternity(Creature* pCreature) : ScriptedAI(pCreature) + npc_scion_of_eternity(Creature* creature) : ScriptedAI(creature) { me->SetReactState(REACT_PASSIVE); me->CastSpell(me, SPELL_TELEPORT_VISUAL, true); ScheduleTimedEvent(20s, 25s, [&] { GuidVector guids; - me->GetMap()->DoForAllPlayers([&](Player* pPlayer) + me->GetMap()->DoForAllPlayers([&](Player* player) { - if (pPlayer->IsAlive() && !pPlayer->GetVehicle()) - guids.push_back(pPlayer->GetGUID()); + if (player->IsAlive() && !player->GetVehicle()) + guids.push_back(player->GetGUID()); }); if (!guids.empty()) - if (Player* plr = ObjectAccessor::GetPlayer(*me, guids.at(urand(0, guids.size() - 1)))) - me->CastSpell(plr, SPELL_SCION_ARCANE_BARRAGE); + if (Player* player = ObjectAccessor::GetPlayer(*me, guids.at(urand(0, guids.size() - 1)))) + me->CastSpell(player, SPELL_SCION_ARCANE_BARRAGE); }, 5s, 8s); } @@ -1051,8 +1052,8 @@ struct npc_scion_of_eternity : public ScriptedAI void JustDied(Unit* killer) override { - if (Vehicle* v = me->GetVehicle()) - v->RemoveAllPassengers(); + if (Vehicle* vehicle = me->GetVehicle()) + vehicle->RemoveAllPassengers(); if (killer) if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself()) @@ -1065,7 +1066,7 @@ struct npc_scion_of_eternity : public ScriptedAI struct npc_hover_disk : public VehicleAI { - npc_hover_disk(Creature* pCreature) : VehicleAI(pCreature) + npc_hover_disk(Creature* creature) : VehicleAI(creature) { events.Reset(); } @@ -1120,72 +1121,61 @@ struct npc_hover_disk : public VehicleAI if (type != POINT_MOTION_TYPE) return; - switch (id) + if (id == MI_POINT_NEXUS_LORD) { - case MI_POINT_SCION: - events.RescheduleEvent(EVENT_DISK_MOVE_NEXT_POINT, 0ms); - break; - case MI_POINT_NEXUS_LORD: if (me->GetPositionZ() > CenterPos.GetPositionZ() + 2.0f) events.RescheduleEvent(EVENT_DISK_MOVE_NEXT_POINT, 0ms); - else if (Vehicle* v = me->GetVehicleKit()) - if (Unit* pass = v->GetPassenger(0)) - if (Creature* c = pass->ToCreature()) + else if (Vehicle* vehicle = me->GetVehicleKit()) + if (Unit* passenger = vehicle->GetPassenger(0)) + if (Creature* creature = passenger->ToCreature()) { - c->SetReactState(REACT_AGGRESSIVE); - if (Player* plr = c->SelectNearestPlayer(100.0f)) - c->AI()->AttackStart(plr); + creature->SetReactState(REACT_AGGRESSIVE); + if (Player* player = creature->SelectNearestPlayer(100.0f)) + creature->AI()->AttackStart(player); } - break; - } + } else if (id == MI_POINT_SCION) + events.RescheduleEvent(EVENT_DISK_MOVE_NEXT_POINT, 0ms); } void DoAction(int32 param) override { - switch (param) - { - case ACTION_DISK_START_MOVING: - if (Vehicle* v = me->GetVehicleKit()) - if (Unit* pass = v->GetPassenger(0)) - switch (pass->GetEntry()) - { - case NPC_NEXUS_LORD: - { - float angle = CenterPos.GetAngle(me); - float newangle = angle - 0.5f; - if (newangle < 0.0f) newangle += 2 * M_PI; - float newz = me->GetPositionZ() - 4.0f; - if (newz < CenterPos.GetPositionZ()) newz = CenterPos.GetPositionZ(); - me->GetMotionMaster()->MovePoint(MI_POINT_NEXUS_LORD, CenterPos.GetPositionX() + cos(newangle) * 22.0f, CenterPos.GetPositionY() + std::sin(newangle) * 22.0f, newz); - } - break; - case NPC_SCION_OF_ETERNITY: - { - float angle = CenterPos.GetAngle(me); - float newangle = angle - 0.3f; - if (newangle < 0.0f) newangle += 2 * M_PI; - float newz = me->GetPositionZ() - 2.0f; - if (newz < CenterPos.GetPositionZ() + 20.0f) newz = CenterPos.GetPositionZ() + 20.0f; - me->GetMotionMaster()->MovePoint(MI_POINT_SCION, CenterPos.GetPositionX() + cos(newangle) * 30.0f, CenterPos.GetPositionY() + std::sin(newangle) * 30.0f, newz); - } - break; - } - break; - } + if (param != ACTION_DISK_START_MOVING) + return; + + if (Vehicle* vehicle = me->GetVehicleKit()) + if (Unit* pass = vehicle->GetPassenger(0)) + { + if (pass->GetEntry() == NPC_NEXUS_LORD) + { + float angle = CenterPos.GetAngle(me); + float newangle = angle - 0.5f; + if (newangle < 0.0f) + newangle += 2 * M_PI; + float newz = me->GetPositionZ() - 4.0f; + if (newz < CenterPos.GetPositionZ()) + newz = CenterPos.GetPositionZ(); + me->GetMotionMaster()->MovePoint(MI_POINT_NEXUS_LORD, CenterPos.GetPositionX() + cos(newangle) * 22.0f, CenterPos.GetPositionY() + std::sin(newangle) * 22.0f, newz); + } + else if (pass->GetEntry() == NPC_SCION_OF_ETERNITY) + { + float angle = CenterPos.GetAngle(me); + float newangle = angle - 0.3f; + if (newangle < 0.0f) + newangle += 2 * M_PI; + float newz = me->GetPositionZ() - 2.0f; + if (newz < CenterPos.GetPositionZ() + 20.0f) + newz = CenterPos.GetPositionZ() + 20.0f; + me->GetMotionMaster()->MovePoint(MI_POINT_SCION, CenterPos.GetPositionX() + cos(newangle) * 30.0f, CenterPos.GetPositionY() + std::sin(newangle) * 30.0f, newz); + } + } } void UpdateAI(uint32 diff) override { events.Update(diff); - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_DISK_MOVE_NEXT_POINT: + if (events.ExecuteEvent() == EVENT_DISK_MOVE_NEXT_POINT) DoAction(ACTION_DISK_START_MOVING); - break; - } } void MoveInLineOfSight(Unit* /*who*/) override {} @@ -1194,7 +1184,7 @@ struct npc_hover_disk : public VehicleAI struct npc_alexstrasza : public ScriptedAI { - npc_alexstrasza(Creature* pCreature) : ScriptedAI(pCreature) + npc_alexstrasza(Creature* creature) : ScriptedAI(creature) { me->SetCanFly(true); me->SetDisableGravity(true); @@ -1276,8 +1266,8 @@ struct go_the_focusing_iris : public GameObjectAI bool GossipHello(Player* /*user*/, bool /*reportUse*/) override { - if (InstanceScript* pInstance = me->GetInstanceScript()) - pInstance->SetData(DATA_IRIS_ACTIVATED, 0); + if (InstanceScript* instance = me->GetInstanceScript()) + instance->SetData(DATA_IRIS_ACTIVATED, 0); return true; } @@ -1292,18 +1282,18 @@ class spell_eoe_ph3_surge_of_power : public SpellScript bool Load() override { if (Unit* caster = GetCaster()) - if (Creature* c = caster->ToCreature()) + if (Creature* creature = caster->ToCreature()) { uint8 i = 0; std::list drakes; - c->AI()->SelectTargetList(drakes, (c->GetMap()->GetSpawnMode() == 0 ? 1 : 3), SelectTargetMethod::Random, 0, 0.0f, false, true, 57403 /*only drakes have this aura*/); + creature->AI()->SelectTargetList(drakes, (creature->GetMap()->GetSpawnMode() == 0 ? 1 : 3), SelectTargetMethod::Random, 0, 0.0f, false, true, 57403 /*only drakes have this aura*/); for (std::list::iterator itr = drakes.begin(); itr != drakes.end() && i < 3; ++itr) { DrakeGUID[i++] = (*itr)->GetGUID(); - if (Vehicle* v = (*itr)->GetVehicleKit()) - if (Unit* p = v->GetPassenger(0)) - if (Player* plr = p->ToPlayer()) - c->AI()->Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, plr); + if (Vehicle* vehicle = (*itr)->GetVehicleKit()) + if (Unit* passenger = vehicle->GetPassenger(0)) + if (Player* player = passenger->ToPlayer()) + creature->AI()->Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, player); } } diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h index bbbdc5779..c77eb635c 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h @@ -54,10 +54,12 @@ enum NPCs enum Data { DATA_MALYGOS = 0, + DATA_IRIS, + DATA_EXIT_PORTAL, + DATA_NEXUS_PLATFORM, DATA_IRIS_ACTIVATED, DATA_SET_IRIS_INACTIVE, DATA_HIDE_IRIS_AND_PORTAL, - DATA_MALYGOS_GUID, }; enum eSpells diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index 590836726..0b4e5060f 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -21,68 +21,60 @@ #include "Vehicle.h" #include "eye_of_eternity.h" +ObjectData const creatureData[] = +{ + { NPC_MALYGOS, DATA_MALYGOS }, + { 0, 0 } +}; + +ObjectData const gameobjectData[] = +{ + { GO_IRIS_N, DATA_IRIS }, + { GO_IRIS_H, DATA_IRIS }, + { GO_EXIT_PORTAL, DATA_EXIT_PORTAL }, + { GO_NEXUS_PLATFORM, DATA_NEXUS_PLATFORM }, + { 0, 0 } +}; + struct instance_eye_of_eternity : public InstanceScript { - instance_eye_of_eternity(Map* pMap) : InstanceScript(pMap) { Initialize(); } - - ObjectGuid NPC_MalygosGUID; - ObjectGuid GO_IrisGUID; - ObjectGuid GO_ExitPortalGUID; - ObjectGuid GO_PlatformGUID; - bool bPokeAchiev; - - void Initialize() override + instance_eye_of_eternity(Map* pMap) : InstanceScript(pMap) { SetHeaders(DataHeader); SetBossNumber(EncounterCount); - bPokeAchiev = false; + LoadObjectData(creatureData, gameobjectData); + Initialize(); + _pokeAchievementValid = false; } + bool _pokeAchievementValid = false; + void OnPlayerEnter(Player* player) override { if (GetBossState(DATA_MALYGOS) != DONE) return; ProcessEvent(nullptr, EVENT_IRIS_ACTIVATED); - if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) - if (go->GetPhaseMask() != 2) - go->SetPhaseMask(2, true); + if (GameObject* iris = GetGameObject(DATA_IRIS)) + if (iris->GetPhaseMask() != 2) + iris->SetPhaseMask(2, true); if (player && player->IsAlive()) player->CastSpell(player, SPELL_SUMMON_RED_DRAGON_BUDDY, true); } - void OnCreatureCreate(Creature* creature) override + void OnGameObjectCreate(GameObject* gameobject) override { - switch (creature->GetEntry()) - { - case NPC_MALYGOS: - NPC_MalygosGUID = creature->GetGUID(); - break; - } - } + InstanceScript::OnGameObjectCreate(gameobject); - void OnGameObjectCreate(GameObject* go) override - { - switch (go->GetEntry()) + uint32 entry = gameobject->GetEntry(); + if ((entry == GO_IRIS_N || entry == GO_IRIS_H) && GetBossState(DATA_MALYGOS) == DONE) + gameobject->SetPhaseMask(2, true); + + if (entry == GO_NEXUS_PLATFORM && GetBossState(DATA_MALYGOS) == DONE) { - case GO_IRIS_N: - case GO_IRIS_H: - GO_IrisGUID = go->GetGUID(); - if (GetBossState(DATA_MALYGOS) == DONE) - go->SetPhaseMask(2, true); - break; - case GO_EXIT_PORTAL: - GO_ExitPortalGUID = go->GetGUID(); - break; - case GO_NEXUS_PLATFORM: - GO_PlatformGUID = go->GetGUID(); - if (GetBossState(DATA_MALYGOS) == DONE) - { - go->ModifyHealth(-int32(PLATFORM_DESTROY_DAMAGE)); - go->EnableCollision(false); - } - break; + gameobject->ModifyHealth(-int32(PLATFORM_DESTROY_DAMAGE)); + gameobject->EnableCollision(false); } } @@ -92,23 +84,29 @@ struct instance_eye_of_eternity : public InstanceScript { case DATA_IRIS_ACTIVATED: if (GetBossState(DATA_MALYGOS) == NOT_STARTED) - if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) - if (Player* plr = c->SelectNearestPlayer(250.0f)) - c->AI()->AttackStart(plr); - break; - case DATA_SET_IRIS_INACTIVE: - if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) { - HandleGameObject(GO_IrisGUID, true, go); - if (Creature* c = go->SummonCreature(NPC_WORLD_TRIGGER_LAOI, *go, TEMPSUMMON_TIMED_DESPAWN, 10000)) - c->CastSpell(c, SPELL_IRIS_ACTIVATED, true); + if (Creature* malygos = GetCreature(DATA_MALYGOS)) + { + if (Player* player = malygos->SelectNearestPlayer(250.0f)) + malygos->AI()->AttackStart(player); + } } break; + case DATA_SET_IRIS_INACTIVE: + { + if (GameObject* iris = GetGameObject(DATA_IRIS)) + { + HandleGameObject(ObjectGuid::Empty, true, iris); + if (Creature* trigger = iris->SummonCreature(NPC_WORLD_TRIGGER_LAOI, *iris, TEMPSUMMON_TIMED_DESPAWN, 10000)) + trigger->CastSpell(trigger, SPELL_IRIS_ACTIVATED, true); + } + break; + } case DATA_HIDE_IRIS_AND_PORTAL: - if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) - go->SetPhaseMask(2, true); - if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) - go->SetPhaseMask(2, true); + if (GameObject* iris = GetGameObject(DATA_IRIS)) + iris->SetPhaseMask(2, true); + if (GameObject* portal = GetGameObject(DATA_EXIT_PORTAL)) + portal->SetPhaseMask(2, true); break; } } @@ -118,63 +116,54 @@ struct instance_eye_of_eternity : public InstanceScript if (!InstanceScript::SetBossState(type, state)) return false; - if (type == DATA_MALYGOS) + if (type != DATA_MALYGOS) + return true; + + switch (state) { - switch (state) - { - case NOT_STARTED: - bPokeAchiev = false; - if (GameObject* go = instance->GetGameObject(GO_IrisGUID)) - { - go->SetPhaseMask(1, true); - HandleGameObject(GO_IrisGUID, false, go); - } - if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) - go->SetPhaseMask(1, true); - if (GameObject* go = instance->GetGameObject(GO_PlatformGUID)) - { - go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, nullptr, true); - go->EnableCollision(true); - } - break; - case IN_PROGRESS: - bPokeAchiev = (instance->GetPlayersCountExceptGMs() < (instance->GetSpawnMode() == 0 ? (uint32)9 : (uint32)21)); - break; - case DONE: - bPokeAchiev = false; - if (GameObject* go = instance->GetGameObject(GO_ExitPortalGUID)) - go->SetPhaseMask(1, true); - if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) - c->SummonCreature(NPC_ALEXSTRASZA, 798.0f, 1268.0f, 299.0f, 2.45f, TEMPSUMMON_MANUAL_DESPAWN); - break; - default: - break; - } + case NOT_STARTED: + _pokeAchievementValid = false; + if (GameObject* iris = GetGameObject(DATA_IRIS)) + { + iris->SetPhaseMask(1, true); + HandleGameObject(iris->GetGUID(), false, iris); + } + if (GameObject* portal = GetGameObject(DATA_EXIT_PORTAL)) + portal->SetPhaseMask(1, true); + if (GameObject* platform = GetGameObject(DATA_NEXUS_PLATFORM)) + { + platform->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, nullptr, true); + platform->EnableCollision(true); + } + break; + case IN_PROGRESS: + _pokeAchievementValid = (instance->GetPlayersCountExceptGMs() < (instance->GetSpawnMode() == 0 ? (uint32)9 : (uint32)21)); + break; + case DONE: + _pokeAchievementValid = false; + if (GameObject* portal = GetGameObject(DATA_EXIT_PORTAL)) + portal->SetPhaseMask(1, true); + if (Creature* malygos = GetCreature(DATA_MALYGOS)) + malygos->SummonCreature(NPC_ALEXSTRASZA, 798.0f, 1268.0f, 299.0f, 2.45f, TEMPSUMMON_MANUAL_DESPAWN); + break; + default: + break; } return true; } - ObjectGuid GetGuidData(uint32 type) const override - { - switch (type) - { - case DATA_MALYGOS_GUID: - return NPC_MalygosGUID; - } - - return ObjectGuid::Empty; - } - void ProcessEvent(WorldObject* /*unit*/, uint32 eventId) override { - if (eventId == EVENT_IRIS_ACTIVATED) - if (GameObject* go = instance->GetGameObject(GO_PlatformGUID)) - if (Creature* c = instance->GetCreature(NPC_MalygosGUID)) - { - go->ModifyHealth(-int32(PLATFORM_DESTROY_DAMAGE), c); - go->EnableCollision(false); - } + if (eventId != EVENT_IRIS_ACTIVATED) + return; + + if (GameObject* platform = GetGameObject(DATA_NEXUS_PLATFORM)) + if (Creature* malygos = GetCreature(DATA_MALYGOS)) + { + platform->ModifyHealth(-int32(PLATFORM_DESTROY_DAMAGE), malygos); + platform->EnableCollision(false); + } } bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* /*target*/, uint32 /*miscvalue1*/) override @@ -183,7 +172,7 @@ struct instance_eye_of_eternity : public InstanceScript { case ACHIEV_CRITERIA_A_POKE_IN_THE_EYE_10: case ACHIEV_CRITERIA_A_POKE_IN_THE_EYE_25: - return bPokeAchiev; + return _pokeAchievementValid; case ACHIEV_CRITERIA_DENYIN_THE_SCION_10: case ACHIEV_CRITERIA_DENYIN_THE_SCION_25: return source && source->GetVehicle() && source->GetVehicle()->GetVehicleInfo()->m_ID == 224; From 1c3c53609807cc72fe10fef3604dafc2eeda3d5f Mon Sep 17 00:00:00 2001 From: sogladev Date: Sun, 15 Feb 2026 23:37:43 +0100 Subject: [PATCH 134/335] fix(DB/Gossip): Enable BoxCoded for Zas'Tysh and Tharl Stonebleeder (#24673) --- data/sql/updates/pending_db_world/rev_1770693909847997293.sql | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1770693909847997293.sql diff --git a/data/sql/updates/pending_db_world/rev_1770693909847997293.sql b/data/sql/updates/pending_db_world/rev_1770693909847997293.sql new file mode 100644 index 000000000..5988281c7 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1770693909847997293.sql @@ -0,0 +1,3 @@ +-- +UPDATE `gossip_menu_option` SET `BoxCoded` = 1 WHERE `MenuID` = 6565 AND `OptionID` IN (0, 1, 2); +UPDATE `gossip_menu_option` SET `BoxCoded` = 1 WHERE `MenuID` = 7034 AND `OptionID` = 0; From b17ccafe765833330eedbaf334c9a5e52e8af635 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Feb 2026 22:38:51 +0000 Subject: [PATCH 135/335] chore(DB): import pending files Referenced commit(s): 1c3c53609807cc72fe10fef3604dafc2eeda3d5f --- .../rev_1770693909847997293.sql => db_world/2026_02_15_05.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1770693909847997293.sql => db_world/2026_02_15_05.sql} (81%) diff --git a/data/sql/updates/pending_db_world/rev_1770693909847997293.sql b/data/sql/updates/db_world/2026_02_15_05.sql similarity index 81% rename from data/sql/updates/pending_db_world/rev_1770693909847997293.sql rename to data/sql/updates/db_world/2026_02_15_05.sql index 5988281c7..e60b831d9 100644 --- a/data/sql/updates/pending_db_world/rev_1770693909847997293.sql +++ b/data/sql/updates/db_world/2026_02_15_05.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_15_04 -> 2026_02_15_05 -- UPDATE `gossip_menu_option` SET `BoxCoded` = 1 WHERE `MenuID` = 6565 AND `OptionID` IN (0, 1, 2); UPDATE `gossip_menu_option` SET `BoxCoded` = 1 WHERE `MenuID` = 7034 AND `OptionID` = 0; From 24f84ee8497dfd6cc383e230a12c5282dd4a7e9e Mon Sep 17 00:00:00 2001 From: sogladev Date: Sun, 15 Feb 2026 23:43:46 +0100 Subject: [PATCH 136/335] fix(Core/Spell): further limit exploit prevention standup to non-triggered spells (#24688) --- src/server/game/Spells/Spell.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 608b9614b..377b15ef2 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3587,10 +3587,9 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const LOG_DEBUG("spells.aura", "Spell::prepare: spell id {} source {} caster {} customCastFlags {} mask {}", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask()); - if (!(m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !(m_spellInfo->Attributes & SPELL_ATTR0_ALLOW_WHILE_SITTING) && !m_triggeredByAuraSpell && m_caster->IsSitState()) - { + // prevent exploit that allows to cast spell while sitting + if (!IsTriggered() && !(m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !(m_spellInfo->Attributes & SPELL_ATTR0_ALLOW_WHILE_SITTING) && !m_triggeredByAuraSpell && m_caster->IsSitState()) m_caster->SetStandState(UNIT_STAND_STATE_STAND); - } //Containers for channeled spells have to be set //TODO:Apply this to all casted spells if needed From 1e47f701accc4ed62b8aa9cc0167ec1dc82b68bb Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Sun, 15 Feb 2026 17:44:44 -0500 Subject: [PATCH 137/335] feat(Core/Player): Add hooks for reputation price discount calculation. (#24666) --- src/server/game/Entities/Player/Player.cpp | 18 +++++++++++++---- .../Scripting/ScriptDefines/PlayerScript.cpp | 10 ++++++++++ .../Scripting/ScriptDefines/PlayerScript.h | 20 +++++++++++++++++++ src/server/game/Scripting/ScriptMgr.h | 2 ++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d100bbc8b..47d15362a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -12333,23 +12333,33 @@ bool Player::GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const float Player::GetReputationPriceDiscount(Creature const* creature) const { - return GetReputationPriceDiscount(creature->GetFactionTemplateEntry()); + float discount = GetReputationPriceDiscount(creature->GetFactionTemplateEntry()); + sScriptMgr->OnPlayerGetReputationPriceDiscount(this, creature, discount); + return discount; } float Player::GetReputationPriceDiscount(FactionTemplateEntry const* factionTemplate) const { + float discount = 1.0f; + if (!factionTemplate || !factionTemplate->faction) { - return 1.0f; + sScriptMgr->OnPlayerGetReputationPriceDiscount(this, factionTemplate, discount); + return discount; } ReputationRank rank = GetReputationRank(factionTemplate->faction); + if (rank <= REP_NEUTRAL) { - return 1.0f; + sScriptMgr->OnPlayerGetReputationPriceDiscount(this, factionTemplate, discount); + return discount; } - return 1.0f - 0.05f * (rank - REP_NEUTRAL); + discount = discount - 0.05f * (rank - REP_NEUTRAL); + + sScriptMgr->OnPlayerGetReputationPriceDiscount(this, factionTemplate, discount); + return discount; } bool Player::IsSpellFitByClassAndRace(uint32 spell_id) const diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp index 62439d284..d52bb272f 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp @@ -910,6 +910,16 @@ void ScriptMgr::OnPlayerSendListInventory(Player* player, ObjectGuid vendorGuid, CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_SEND_LIST_INVENTORY, script->OnPlayerSendListInventory(player, vendorGuid, vendorEntry)); } +void ScriptMgr::OnPlayerGetReputationPriceDiscount(Player const* player, Creature const* creature, float& discount) +{ + CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_GET_REPUTATION_PRICE_DISCOUNT, script->OnPlayerGetReputationPriceDiscount(player, creature, discount)); +} + +void ScriptMgr::OnPlayerGetReputationPriceDiscount(Player const* player, FactionTemplateEntry const* factionTemplate, float& discount) +{ + CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_GET_REPUTATION_PRICE_DISCOUNT, script->OnPlayerGetReputationPriceDiscount(player, factionTemplate, discount)); +} + PlayerScript::PlayerScript(const char* name, std::vector enabledHooks) : ScriptObject(name, PLAYERHOOK_END) { diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.h b/src/server/game/Scripting/ScriptDefines/PlayerScript.h index 5ee56e7ac..c90c77410 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.h +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.h @@ -20,6 +20,7 @@ #include "ScriptObject.h" #include "SharedDefines.h" +#include "DBCStructure.h" #include // TODO to remove @@ -207,6 +208,7 @@ enum PlayerHook PLAYERHOOK_ON_CAN_GIVE_LEVEL, PLAYERHOOK_ON_SEND_LIST_INVENTORY, PLAYERHOOK_ON_GIVE_REPUTATION, + PLAYERHOOK_ON_GET_REPUTATION_PRICE_DISCOUNT, PLAYERHOOK_END }; @@ -796,6 +798,24 @@ public: * @param vendorEntry Entry of the vendor player is interacting with */ virtual void OnPlayerSendListInventory(Player* /*player*/, ObjectGuid /*vendorGuid*/, uint32& /*vendorEntry*/) {} + + /** + * @brief This hook is called whenever a player attempts to buy items, repair, take taxis, or learn spells. This then uses this information to call OnPlayerGetReputationPriceDiscoun(Player, FactionTemplateEntry, float) + * + * @param player Contains information about the Player + * @param creature Contains information about the creature involved in the transaction + * @param discount Float value of the discount, as a multiplier of the base price + */ + virtual void OnPlayerGetReputationPriceDiscount(Player const* /*player*/, Creature const* /*creature*/, float& /*discount*/) {} + + /** + * @brief This hook is called whenever a player attempts to buy items, repair, take taxis, or learn spells. It is also called when continuing along taxis + * + * @param player Contains information about the Player + * @param factionTemplate Contains information about the faction template involved in the transaction. Can be null! + * @param discount Float value of the discount, as a multiplier of the base price + */ + virtual void OnPlayerGetReputationPriceDiscount(Player const* /*player*/, FactionTemplateEntry const* /*factionTemplate*/, float& /*discount*/) {} }; #endif diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 056a44a57..222dac69e 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -462,6 +462,8 @@ public: /* PlayerScript */ bool OnPlayerCanResurrect(Player* player); bool OnPlayerCanGiveLevel(Player* player, uint8 newLevel); void OnPlayerSendListInventory(Player* player, ObjectGuid vendorGuid, uint32& vendorEntry); + void OnPlayerGetReputationPriceDiscount(Player const* player, Creature const* creature, float& discount); + void OnPlayerGetReputationPriceDiscount(Player const* player, FactionTemplateEntry const* factionTemplate, float& discount); // Anti cheat void AnticheatSetCanFlybyServer(Player* player, bool apply); From 2ab0af1a7fb666e61c1dfd75035e4a60e58e584d Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sun, 15 Feb 2026 19:50:46 -0300 Subject: [PATCH 138/335] fix(DB/Loot): Abandoned Adventurer's Satchel (#24509) Co-authored-by: Ryan Turner <16946913+TheSCREWEDSoftware@users.noreply.github.com> --- .../pending_db_world/rev_1769269959538797000.sql | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1769269959538797000.sql diff --git a/data/sql/updates/pending_db_world/rev_1769269959538797000.sql b/data/sql/updates/pending_db_world/rev_1769269959538797000.sql new file mode 100644 index 000000000..1ab2852ff --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769269959538797000.sql @@ -0,0 +1,15 @@ +-- +DELETE FROM `item_loot_template` WHERE (`Entry` = 44663); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(44663, 33470, 0, 100, 0, 1, 0, 20, 20, 'Abandoned Adventurer\'s Satchel - Frostweave Cloth'), +(44663, 1, 44663, 37.5, 0, 1, 1, 1, 1, 'Abandoned Adventurer\'s Satchel - One Crystallized Element'), +(44663, 2, 44663, 12.5, 0, 1, 1, 2, 2, 'Abandoned Adventurer\'s Satchel - Two Crystallized Elements'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 44663); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(44663, 37700, 0, 0, 0, 1, 1, 3, 5, 'Abandoned Adventurer\'s Satchel - Crystallized Air'), +(44663, 37701, 0, 0, 0, 1, 1, 3, 5, 'Abandoned Adventurer\'s Satchel - Crystallized Earth'), +(44663, 37702, 0, 0, 0, 1, 1, 3, 5, 'Abandoned Adventurer\'s Satchel - Crystallized Fire'), +(44663, 37703, 0, 0, 0, 1, 1, 3, 5, 'Abandoned Adventurer\'s Satchel - Crystallized Shadow'), +(44663, 37704, 0, 0, 0, 1, 1, 3, 5, 'Abandoned Adventurer\'s Satchel - Crystallized Life'), +(44663, 37705, 0, 0, 0, 1, 1, 3, 5, 'Abandoned Adventurer\'s Satchel - Crystallized Water'); From 848adf73ed43a563099d6e5313c4572c1000228b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Feb 2026 22:52:09 +0000 Subject: [PATCH 139/335] chore(DB): import pending files Referenced commit(s): 2ab0af1a7fb666e61c1dfd75035e4a60e58e584d --- .../rev_1769269959538797000.sql => db_world/2026_02_15_06.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1769269959538797000.sql => db_world/2026_02_15_06.sql} (96%) diff --git a/data/sql/updates/pending_db_world/rev_1769269959538797000.sql b/data/sql/updates/db_world/2026_02_15_06.sql similarity index 96% rename from data/sql/updates/pending_db_world/rev_1769269959538797000.sql rename to data/sql/updates/db_world/2026_02_15_06.sql index 1ab2852ff..f945226d4 100644 --- a/data/sql/updates/pending_db_world/rev_1769269959538797000.sql +++ b/data/sql/updates/db_world/2026_02_15_06.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_15_05 -> 2026_02_15_06 -- DELETE FROM `item_loot_template` WHERE (`Entry` = 44663); INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES From 01f8f9147548928a803aeb41d13e1bd4499a9163 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sun, 15 Feb 2026 20:13:29 -0300 Subject: [PATCH 140/335] fix(Core/Loot): Allow References to be grouped like Items (#24275) --- .../rev_1767140544966521500.sql | 933 ++++++++++++++++++ src/server/game/Loot/LootMgr.cpp | 48 +- src/server/game/Loot/LootMgr.h | 4 +- 3 files changed, 947 insertions(+), 38 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1767140544966521500.sql diff --git a/data/sql/updates/pending_db_world/rev_1767140544966521500.sql b/data/sql/updates/pending_db_world/rev_1767140544966521500.sql new file mode 100644 index 000000000..9db201cab --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1767140544966521500.sql @@ -0,0 +1,933 @@ +-- +DELETE FROM `creature_loot_template` WHERE (`Entry` = 20169) AND (`Item` IN (12018, 43002)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(20169, 12018, 12018, 100, 0, 1, 0, 1, 1, 'Hungarfen (1) - (ReferenceTable)'), +(20169, 43002, 43002, 25, 0, 1, 0, 1, 1, 'Hungarfen (1) - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 17808) AND (`Item` IN (34063, 34065)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(17808, 34063, 34063, 2, 0, 1, 0, 1, 1, 'Anetheron - (ReferenceTable)'), +(17808, 34065, 34065, 100, 0, 1, 0, 2, 2, 'Anetheron - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 1911) AND (`Item` IN (2, 4303)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1911, 2, 1011212, 10, 0, 1, 0, 1, 1, 'World Drop - White World Drop - NPC Levels: 12-12'), +(1911, 4303, 0, 50, 0, 1, 1, 1, 1, 'Deeb - Cranial Thumper'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14517) AND (`Item` IN (34086)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14517, 34086, 34086, 100, 0, 1, 0, 1, 1, 'High Priestess Jeklik - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 18831) AND (`Item` IN (34050)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(18831, 34050, 34050, 100, 0, 1, 0, 3, 3, 'High King Maulgar - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 2749) AND (`Item` IN (24037, 24039, 24041, 24047, 24056)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(2749, 24037, 24037, 1, 0, 1, 0, 1, 1, 'Siege Golem - (ReferenceTable)'), +(2749, 24039, 24039, 1, 0, 1, 0, 1, 1, 'Siege Golem - (ReferenceTable)'), +(2749, 24041, 24041, 50, 0, 1, 1, 1, 1, 'Siege Golem - (ReferenceTable)'), +(2749, 24047, 24047, 50, 0, 1, 1, 1, 1, 'Siege Golem - (ReferenceTable)'), +(2749, 24056, 24056, 1, 0, 1, 0, 1, 1, 'Siege Golem - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14507) AND (`Item` IN (34086)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14507, 34086, 34086, 100, 0, 1, 0, 1, 1, 'High Priest Venoxis - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 10503) AND (`Item` IN (24016)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(10503, 24016, 24016, 100, 0, 1, 0, 1, 1, 'Jandice Barov - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 11486) AND (`Item` IN (35021)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(11486, 35021, 35021, 100, 0, 1, 0, 2, 2, 'Prince Tortheldrin - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 25165) AND (`Item` IN (34081, 34085)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(25165, 34081, 34081, 100, 0, 1, 0, 1, 1, 'Lady Sacrolash - (ReferenceTable 2)'), +(25165, 34085, 34085, 100, 0, 1, 0, 4, 4, 'Lady Sacrolash - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 16968) AND (`Item` IN (1)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(16968, 1, 6000, 80, 0, 1, 0, 1, 1, 'Tunneler - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 10439) AND (`Item` IN (24016)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(10439, 24016, 24016, 100, 0, 1, 0, 1, 1, 'Ramstein the Gorger - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 24892) AND (`Item` IN (34082)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(24892, 34082, 34082, 100, 0, 1, 0, 3, 3, 'Sathrovarr the Corruptor - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 25840) AND (`Item` IN (34095)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(25840, 34095, 34095, 100, 0, 1, 0, 3, 3, 'Entropius - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 10363) AND (`Item` IN (35025)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(10363, 35025, 35025, 100, 0, 1, 0, 2, 2, 'General Drakkisath - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 11382) AND (`Item` IN (34088)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(11382, 34088, 34088, 100, 0, 1, 2, 2, 2, 'Bloodlord Mandokir - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 11380) AND (`Item` IN (34087, 34089)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(11380, 34087, 34087, 100, 0, 1, 0, 1, 1, 'Jin\'do the Hexxer - (ReferenceTable)'), +(11380, 34089, 34089, 100, 0, 1, 0, 2, 2, 'Jin\'do the Hexxer - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 17842) AND (`Item` IN (34063, 34067)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(17842, 34063, 34063, 2, 0, 1, 0, 1, 1, 'Azgalor - (ReferenceTable)'), +(17842, 34067, 34067, 100, 0, 1, 0, 3, 3, 'Azgalor - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 24018) AND (`Item` IN (44003, 44004)); +-- Redundant Loot +-- INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +-- (24018, 44003, 44003, 100, 0, 1, 0, 1, 1, 'Necro Overlord Mezhen - (ReferenceTable)'), +-- (24018, 44004, 44004, 100, 0, 1, 0, 1, 1, 'Necro Overlord Mezhen - (ReferenceTable)'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` IN (44003, 44004)); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 4830) AND (`Item` IN (24070)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4830, 24070, 24070, 5, 0, 1, 0, 1, 1, 'Old Serra\'kis - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 5837) AND (`Item` IN (2)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(5837, 2, 1011515, 10, 0, 1, 0, 1, 1, 'World Drop - White World Drop - NPC Levels: 15-15'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14509) AND (`Item` IN (34086)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14509, 34086, 34086, 100, 0, 1, 0, 1, 1, 'High Priest Thekal - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 10440) AND (`Item` IN (35028)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(10440, 35028, 35028, 100, 0, 1, 0, 2, 2, 'Baron Rivendare - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14326) AND (`Item` IN (35018)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14326, 35018, 35018, 100, 0, 1, 0, 1, 1, 'Guard Mol\'dar - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14510) AND (`Item` IN (34086)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14510, 34086, 34086, 100, 0, 1, 0, 1, 1, 'High Priestess Mar\'li - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14515) AND (`Item` IN (34086)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14515, 34086, 34086, 100, 0, 1, 0, 1, 1, 'High Priestess Arlokk - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 15114) AND (`Item` IN (34003)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(15114, 34003, 34003, 100, 0, 1, 0, 1, 1, 'Gahz\'ranka - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 25166) AND (`Item` IN (34081, 34085)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(25166, 34081, 34081, 100, 0, 1, 0, 1, 1, 'Grand Warlock Alythess - (ReferenceTable 2)'), +(25166, 34085, 34085, 100, 0, 1, 0, 4, 4, 'Grand Warlock Alythess - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 17767) AND (`Item` IN (34063, 34064)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(17767, 34063, 34063, 2, 0, 1, 0, 1, 1, 'Rage Winterchill - (ReferenceTable)'), +(17767, 34064, 34064, 100, 0, 1, 0, 2, 2, 'Rage Winterchill - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 17888) AND (`Item` IN (34063, 34066)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(17888, 34063, 34063, 2, 0, 1, 0, 1, 1, 'Kaz\'rogal - (ReferenceTable)'), +(17888, 34066, 34066, 100, 0, 1, 0, 2, 2, 'Kaz\'rogal - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 24882) AND (`Item` IN (34083)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(24882, 34083, 34083, 100, 0, 1, 0, 3, 3, 'Brutallus - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 25038) AND (`Item` IN (34084)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(25038, 34084, 34084, 100, 0, 1, 0, 3, 3, 'Felmyst - (ReferenceTable)'); + +DELETE FROM `fishing_loot_template` WHERE (`Entry` = 1) AND (`Item` IN (11000, 11799)); +INSERT INTO `fishing_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1, 11000, 11000, 100, 0, 1, 0, 1, 1, '(ReferenceTable)'), +(1, 11799, 11799, 100, 0, 32768, 0, 1, 1, '(ReferenceTable)'); + +DELETE FROM `fishing_loot_template` WHERE (`Entry` = 33); +INSERT INTO `fishing_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(33, 11006, 11006, 100, 0, 1, 0, 1, 1, '(ReferenceTable)'), +(33, 11150, 11150, 33, 0, 1, 0, 1, 1, '(ReferenceTable)'); + +DELETE FROM `gameobject_loot_template` WHERE `Entry` = 16591; +INSERT INTO `gameobject_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(16591, 12006, 12006, 100, 0, 1, 0, 2, 2, 'Knot Thimblejack\'s Cache - (ReferenceTable)'), +(16591, 18240, 0, 35, 0, 1, 0, 1, 2, 'Knot Thimblejack\'s Cache - Ogre Tannin'), +(16591, 18414, 0, 2, 0, 1, 1, 1, 1, 'Knot Thimblejack\'s Cache - Pattern: Belt of the Archmage'), +(16591, 18415, 0, 2, 0, 1, 1, 1, 1, 'Knot Thimblejack\'s Cache - Pattern: Felcloth Gloves'), +(16591, 18416, 0, 2, 0, 1, 1, 1, 1, 'Knot Thimblejack\'s Cache - Pattern: Inferno Gloves'), +(16591, 18417, 0, 2, 0, 1, 1, 1, 1, 'Knot Thimblejack\'s Cache - Pattern: Mooncloth Gloves'), +(16591, 18418, 0, 2, 0, 1, 1, 1, 1, 'Knot Thimblejack\'s Cache - Pattern: Cloak of Warding'), +(16591, 18514, 0, 2, 0, 1, 1, 1, 1, 'Knot Thimblejack\'s Cache - Pattern: Girdle of Insight'), +(16591, 18515, 0, 2, 0, 1, 1, 1, 1, 'Knot Thimblejack\'s Cache - Pattern: Mongoose Boots'), +(16591, 18516, 0, 2, 0, 1, 1, 1, 1, 'Knot Thimblejack\'s Cache - Pattern: Swift Flight Bracers'), +(16591, 18517, 0, 2, 0, 1, 1, 1, 1, 'Knot Thimblejack\'s Cache - Pattern: Chromatic Cloak'), +(16591, 18518, 0, 2, 0, 1, 1, 1, 1, 'Knot Thimblejack\'s Cache - Pattern: Hide of the Wild'), +(16591, 18519, 0, 2, 0, 1, 1, 1, 1, 'Knot Thimblejack\'s Cache - Pattern: Shifting Cloak'); + +UPDATE `gameobject_loot_template` SET `GroupId` = 0 WHERE `Entry` = 13960 AND `Item` = 1; +UPDATE `gameobject_loot_template` SET `GroupId` = 0 WHERE `Entry`=26862; + +DELETE FROM `item_loot_template` WHERE (`Entry` = 33844) AND (`Item` IN (10003)); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(33844, 10003, 10003, 100, 0, 1, 0, 2, 2, 'Barrel of Fish - (ReferenceTable)'); + +DELETE FROM `item_loot_template` WHERE (`Entry` = 33857) AND (`Item` IN (10004)); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(33857, 10004, 10004, 100, 0, 1, 0, 2, 2, 'Crate of Meat - (ReferenceTable)'); + +DELETE FROM `prospecting_loot_template` WHERE (`Entry` = 23425) AND (`Item` IN (1, 2, 3)); +INSERT INTO `prospecting_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(23425, 1, 13001, 100, 0, 1, 0, 1, 1, '(ReferenceTable)'), +(23425, 2, 13002, 24, 0, 1, 0, 1, 1, '(ReferenceTable)'), +(23425, 3, 13001, 15, 0, 1, 0, 1, 1, '(ReferenceTable)'); + +DELETE FROM `prospecting_loot_template` WHERE (`Entry` = 36910) AND (`Item` IN (2, 3)); +INSERT INTO `prospecting_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(36910, 2, 1002, 100, 0, 1, 0, 1, 1, '(ReferenceTable)'), +(36910, 3, 1003, 75, 0, 1, 0, 1, 1, '(ReferenceTable)'); + +-- AQ20 Enchanting Formulas +DELETE FROM `reference_loot_template` WHERE `Entry` = 34024 AND `Item` IN (20727,20728,20729,20730,20731,20734,20736); +DELETE FROM `reference_loot_template` WHERE `Entry` = 34026; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34026, 20727, 0, 0, 0, 1, 1, 1, 1, 'Formula: Enchant Gloves - Shadow Power'), +(34026, 20728, 0, 0, 0, 1, 1, 1, 1, 'Formula: Enchant Gloves - Frost Power'), +(34026, 20729, 0, 0, 0, 1, 1, 1, 1, 'Formula: Enchant Gloves - Fire Power'), +(34026, 20730, 0, 0, 0, 1, 1, 1, 1, 'Formula: Enchant Gloves - Healing Power'), +(34026, 20731, 0, 0, 0, 1, 1, 1, 1, 'Formula: Enchant Gloves - Superior Agility'), +(34026, 20734, 0, 0, 0, 1, 1, 1, 1, 'Formula: Enchant Cloak - Stealth'), +(34026, 20736, 0, 0, 0, 1, 1, 1, 1, 'Formula: Enchant Cloak - Dodge'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 15339) AND (`Item` IN (34024, 34025, 190024, 34026)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(15339, 34024, 34024, 100, 0, 1, 0, 2, 2, 'Ossirian the Unscarred - (ReferenceTable)'), +(15339, 34025, 34025, 1.5, 0, 1, 0, 2, 2, 'Ossirian the Unscarred - (ReferenceTable)'), +(15339, 34026, 34026, 1, 0, 1, 0, 1, 1, 'Enchanting Formulas'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 15348) AND (`Item` IN (34024, 190024, 34026)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(15348, 34024, 34024, 100, 0, 1, 0, 2, 2, 'Kurinnaxx - (ReferenceTable)'), +(15348, 34026, 34026, 1, 0, 1, 0, 1, 1, 'Enchanting Formulas'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 15341) AND (`Item` IN (34024, 190024, 34026)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(15341, 34024, 34024, 100, 0, 1, 0, 2, 2, 'General Rajaxx - (ReferenceTable)'), +(15341, 34026, 34026, 1, 0, 1, 0, 1, 1, 'Enchanting Formulas'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 15369) AND (`Item` IN (34024, 190024, 34026)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(15369, 34024, 34024, 100, 0, 1, 0, 2, 2, 'Ayamiss the Hunter - (ReferenceTable)'), +(15369, 34026, 34026, 1, 0, 1, 0, 1, 1, 'Enchanting Formulas'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 15370) AND (`Item` IN (34024, 190024, 34026)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(15370, 34024, 34024, 100, 0, 1, 0, 2, 2, 'Buru the Gorger - (ReferenceTable)'), +(15370, 34026, 34026, 1, 0, 1, 0, 1, 1, 'Enchanting Formulas'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 15340) AND (`Item` IN (34024, 34026, 190024)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(15340, 34024, 34024, 100, 0, 1, 0, 2, 2, 'Moam - (ReferenceTable)'), +(15340, 34026, 34026, 1, 0, 1, 0, 1, 1, 'Enchanting Formulas'); + +-- Sacks of Gems (World Bosses) +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34003) AND (`Item` IN (17962, 17963, 17964, 17965, 17969)); +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34010); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34010, 17962, 0, 0, 0, 1, 2, 1, 1, 'Blue Sack of Gems'), +(34010, 17963, 0, 0, 0, 1, 2, 1, 1, 'Green Sack of Gems'), +(34010, 17964, 0, 0, 0, 1, 2, 1, 1, 'Gray Sack of Gems'), +(34010, 17965, 0, 0, 0, 1, 2, 1, 1, 'Yellow Sack of Gems'), +(34010, 17969, 0, 0, 0, 1, 2, 1, 1, 'Red Sack of Gems'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 6109) AND (`Item` IN (34002, 34004, 190003, 34010)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(6109, 34002, 34002, 100, 0, 1, 0, 3, 3, 'Azuregos - (ReferenceTable)'), +(6109, 34004, 34004, 100, 0, 1, 0, 2, 2, 'Azuregos - (ReferenceTable)'), +(6109, 34010, 34010, 100, 0, 1, 0, 2, 2, 'Sack of Gems'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14887) AND (`Item` IN (34002, 34008, 190003, 34010)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14887, 34002, 34002, 100, 0, 1, 0, 2, 2, 'Ysondre - (ReferenceTable)'), +(14887, 34008, 34008, 100, 0, 1, 0, 2, 2, 'Ysondre - (ReferenceTable)'), +(14887, 34010, 34010, 100, 0, 1, 1, 1, 1, 'Sack of Gems'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14888) AND (`Item` IN (34002, 34005, 190003, 34010)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14888, 34002, 34002, 100, 0, 1, 0, 2, 2, 'Lethon - (ReferenceTable)'), +(14888, 34005, 34005, 100, 0, 1, 0, 2, 2, 'Lethon - (ReferenceTable)'), +(14888, 34010, 34010, 100, 0, 1, 1, 1, 1, 'Sack of Gems'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14889) AND (`Item` IN (34002, 34006, 190003, 34010)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14889, 34002, 34002, 100, 0, 1, 0, 2, 2, 'Emeriss - (ReferenceTable)'), +(14889, 34006, 34006, 100, 0, 1, 0, 2, 2, 'Emeriss - (ReferenceTable)'), +(14889, 34010, 34010, 100, 0, 1, 0, 1, 1, 'Sack of Gems'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14890) AND (`Item` IN (34002, 34007, 190003, 34010)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14890, 34002, 34002, 100, 0, 1, 0, 2, 2, 'Taerar - (ReferenceTable)'), +(14890, 34007, 34007, 100, 0, 1, 0, 2, 2, 'Taerar - (ReferenceTable)'), +(14890, 34010, 34010, 100, 0, 1, 0, 1, 1, 'Sack of Gems'); + +-- Librams +DELETE FROM `reference_loot_template` WHERE (`Entry` = 35016) AND (`Item` IN (18332, 18333)); +DELETE FROM `reference_loot_template` WHERE (`Entry` = 35029) AND (`Item` IN (18332, 18333)); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(35029, 18332, 0, 100, 0, 1, 0, 1, 1, 'Libram of Rapidity'), +(35029, 18333, 0, 100, 0, 1, 0, 1, 1, 'Libram of Focus'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 11490) AND (`Item` IN (35016, 91016, 35029)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(11490, 35016, 35016, 2, 0, 1, 0, 1, 1, 'Zevrim Thornhoof - (ReferenceTable)'), +(11490, 35029, 35029, 2, 0, 1, 0, 1, 1, 'Zevrim Thornhoof - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 11492) AND (`Item` IN (35016, 35017, 91016, 35029)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(11492, 35017, 35017, 100, 0, 1, 0, 2, 2, 'Alzzin the Wildshaper - (ReferenceTable)'), +(11492, 91016, 35016, 2, 0, 1, 0, 1, 1, 'Alzzin the Wildshaper - (ReferenceTable)'), +(11492, 35029, 35029, 2, 0, 1, 0, 1, 1, 'Alzzin the Wildshaper - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 11501) AND (`Item` IN (35019)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(11501, 35019, 35019, 100, 0, 1, 0, 2, 2, 'King Gordok - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 13280) AND (`Item` IN (91016, 35029)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(13280, 35029, 35029, 2, 0, 1, 2, 1, 1, 'Hydrospawn - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14323) AND (`Item` IN (35016, 35018)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14323, 35016, 35016, 100, 0, 1, 0, 1, 1, 'Guard Slip\'kik - (ReferenceTable)'), +(14323, 35018, 35018, 100, 0, 1, 0, 1, 1, 'Guard Slip\'kik - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14327) AND (`Item` IN (35016, 35029)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14327, 35029, 35029, 2, 0, 1, 0, 1, 1, 'Lethtendris - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14349) AND (`Item` IN (35016, 35029)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14349, 35029, 35029, 2, 0, 1, 2, 1, 1, 'Pimgib - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 14354) AND (`Item` IN (191016, 35029)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(14354, 35029, 35029, 2, 0, 1, 2, 1, 1, 'Pusillin - (ReferenceTable)'); + +-- Now Useless GroupIds +UPDATE `creature_loot_template` SET `GroupId` = 0 WHERE `Item` = 35016 AND `Reference` = 35016 AND `Entry` IN ( +11487, -- Magister Kalendris +11488, -- Illyanna Ravenoak +11489, -- Tendris Warpwood +14321, -- Guard Fengus +14324, -- Cho'Rush the Observer +14325 -- Captain Kromcrush +); + +-- Magtheridon (3 Tokens, 2 Drops) +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34039) AND (`Item` IN (29753, 29754, 29755)); +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34047) AND (`Item` IN (29753, 29754, 29755)); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34047, 29753, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of the Fallen Defender'), +(34047, 29754, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of the Fallen Champion'), +(34047, 29755, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of the Fallen Hero'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 17257) AND (`Item` IN (34039, 90039, 34047)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(17257, 34039, 34039, 100, 0, 1, 0, 2, 2, 'Magtheridon - (ReferenceTable)'), +(17257, 34047, 34047, 100, 0, 1, 0, 3, 3, 'Magtheridon - Tokens'); + +-- Kalithresh: Doubled Loot. One Reference handles 2 drops +DELETE FROM `creature_loot_template` WHERE (`Entry` = 17798) AND (`Item` IN (35001, 43000)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(17798, 35001, 35001, 100, 0, 1, 0, 1, 1, 'Warlord Kalithresh Table - (ReferenceTable)'), +(17798, 43000, 43000, 2, 0, 1, 0, 1, 1, 'Warlord Kalithresh - (ReferenceTable)'); + +-- Ditto +DELETE FROM `creature_loot_template` WHERE (`Entry` = 17881) AND (`Item` IN (35004, 43000)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(17881, 35004, 35004, 100, 0, 1, 0, 1, 1, 'Aeonus - (ReferenceTable)'), +(17881, 43000, 43000, 2, 0, 1, 0, 1, 1, 'Aeonus - (ReferenceTable)'); + +-- Ditto +DELETE FROM `creature_loot_template` WHERE (`Entry` = 17977) AND (`Item` IN (35006)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(17977, 35006, 35006, 100, 0, 1, 0, 1, 1, 'Warp Splinter High Value Table - (ReferenceTable)'); + +-- Solarian +DELETE FROM `reference_loot_template` WHERE (`Entry` IN (34052, 34092)); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34052, 30280, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Belt of Blasting'), +(34052, 30281, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Belt of the Long Road'), +(34052, 30301, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Belt of Natural Power'), +(34052, 30302, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Belt of Deep Shadow'), +(34052, 30303, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Belt of the Black Eagle'), +(34052, 30304, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Monsoon Belt'), +(34052, 30321, 0, 0, 0, 1, 1, 1, 1, 'Plans: Belt of the Guardian'), +(34052, 30322, 0, 0, 0, 1, 1, 1, 1, 'Plans: Red Belt of Battle'), +(34092, 30305, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Boots of Natural Grace'), +(34092, 30306, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Boots of Utter Darkness'), +(34092, 30307, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Boots of the Crimson Hawk'), +(34092, 30308, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Hurricane Boots'), +(34092, 30282, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Boots of Blasting'), +(34092, 30283, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Boots of the Long Road'), +(34092, 30323, 0, 0, 0, 1, 2, 1, 1, 'Plans: Boots of the Protector'), +(34092, 30324, 0, 0, 0, 1, 2, 1, 1, 'Plans: Red Havoc Boots'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 18805) AND (`Item` IN (34052, 90052, 34092)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(18805, 34052, 34052, 10, 0, 1, 0, 1, 1, 'High Astromancer Solarian - (ReferenceTable)'), +(18805, 34092, 34092, 10, 0, 1, 0, 1, 1, 'High Astromancer Solarian - (ReferenceTable)'); + +-- Gruul +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34051) AND (`Item` IN (29765, 29766, 29767)); +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34097); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34097, 29765, 0, 100, 0, 1, 0, 1, 1, 'Leggings of the Fallen Hero'), +(34097, 29766, 0, 100, 0, 1, 0, 1, 1, 'Leggings of the Fallen Champion'), +(34097, 29767, 0, 100, 0, 1, 0, 1, 1, 'Leggings of the Fallen Defender'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 19044) AND (`Item` IN (190039, 34097)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(19044, 34097, 34097, 100, 0, 1, 0, 3, 3, 'Gruul the Dragonkiller - Tokens'); + +-- Pathaleon (2 Gear Drops) +DELETE FROM `creature_loot_template` WHERE (`Entry` = 19220) AND (`Item` IN (21907, 23572, 35005, 43000)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(19220, 21907, 0, 10, 0, 1, 0, 1, 1, 'Pathaleon the Calculator - Pattern: Arcanoweave Robe'), +(19220, 23572, 0, 5, 0, 1, 0, 1, 1, 'Pathaleon the Calculator - Primal Nether'), +(19220, 35005, 35005, 100, 0, 1, 0, 1, 1, 'Pathaleon the Calculator - (ReferenceTable)'), +(19220, 43000, 43000, 2, 0, 1, 0, 1, 1, 'Pathaleon the Calculator - (ReferenceTable)'); + +-- Al'ar +DELETE FROM `creature_loot_template` WHERE (`Entry` = 19514) AND (`Item` IN (1, 2, 3, 34053, 34052, 34092)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(19514, 34053, 34053, 100, 0, 1, 0, 3, 3, 'Al\'ar - (ReferenceTable)'), +(19514, 34052, 34052, 10, 0, 1, 0, 1, 1, 'Al\'ar - (ReferenceTable)'), +(19514, 34092, 34092, 10, 0, 1, 0, 1, 1, 'Al\'ar - (ReferenceTable)'); + +-- Void Reaver +DELETE FROM `creature_loot_template` WHERE (`Entry` = 19516) AND (`Item` IN (34052, 90052, 34092)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(19516, 34052, 34052, 10, 0, 1, 0, 1, 1, 'Void Reaver - (ReferenceTable)'), +(19516, 34092, 34092, 10, 0, 1, 0, 1, 1, 'Void Reaver - (ReferenceTable)'); + +-- Kael'thas +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34056) AND (`Item` IN (30236, 30237, 30238)); +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34104); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34104, 30236, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of the Vanquished Champion'), +(34104, 30237, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of the Vanquished Defender'), +(34104, 30238, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of the Vanquished Hero'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 19622) AND (`Item` IN (34052, 34056, 90052, 90056, 34092, 34104)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(19622, 34052, 34052, 10, 0, 1, 0, 1, 1, 'Kael\'thas Sunstrider - (ReferenceTable)'), +(19622, 34056, 34056, 100, 0, 1, 0, 2, 2, 'Kael\'thas Sunstrider - (ReferenceTable)'), +(19622, 34092, 34092, 10, 0, 1, 0, 1, 1, 'Kael\'thas Sunstrider - (ReferenceTable)'), +(19622, 34104, 34104, 100, 0, 1, 0, 3, 3, 'Kael\'thas Sunstrider - (ReferenceTable)'); + +-- Skyriss +DELETE FROM `creature_loot_template` WHERE (`Entry` = 20912) AND (`Item` IN (25004, 43000)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(20912, 25004, 25004, 100, 0, 1, 0, 1, 1, 'Harbinger Skyriss - (ReferenceTable)'), +(20912, 43000, 43000, 10, 0, 1, 0, 1, 1, 'Harbinger Skyriss - (ReferenceTable)'); + +-- Vash'j +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34062) AND (`Item` IN (30242, 30243, 30244)); +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34105); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34105, 30242, 0, 0, 0, 1, 1, 1, 1, 'Helm of the Vanquished Champion'), +(34105, 30243, 0, 0, 0, 1, 1, 1, 1, 'Helm of the Vanquished Defender'), +(34105, 30244, 0, 0, 0, 1, 1, 1, 1, 'Helm of the Vanquished Hero'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 21212) AND (`Item` IN (34052, 34062, 90062, 190052, 34105, 34092)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(21212, 34052, 34052, 10, 0, 1, 0, 1, 1, 'Lady Vashj - (ReferenceTable)'), +(21212, 34062, 34062, 100, 0, 1, 0, 2, 2, 'Lady Vashj - (ReferenceTable)'), +(21212, 34105, 34105, 100, 0, 1, 0, 3, 3, 'Lady Vashj - Tokens'), +(21212, 34092, 34092, 10, 0, 1, 0, 1, 1, 'Lady Vashj - (ReferenceTable)'); + +-- SSC Patterns +DELETE FROM `creature_loot_template` WHERE (`Entry` = 21213) AND (`Item` IN (34052, 90052, 34092)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(21213, 34052, 34052, 10, 0, 1, 0, 1, 1, 'Morogrim Tidewalker - (ReferenceTable)'), +(21213, 34092, 34092, 10, 0, 1, 0, 1, 1, 'Morogrim Tidewalker - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 21214) AND (`Item` IN (34052, 90052, 34092)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(21214, 34052, 34052, 10, 0, 1, 0, 1, 1, 'Fathom-Lord Karathress - (ReferenceTable)'), +(21214, 34092, 34092, 10, 0, 1, 0, 1, 1, 'Fathom-Lord Karathress - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 21215) AND (`Item` IN (34052, 190052, 34092)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(21215, 34052, 34052, 10, 0, 1, 0, 1, 1, 'Leotheras the Blind - (ReferenceTable)'), +(21215, 34092, 34092, 10, 0, 1, 0, 1, 1, 'Leotheras the Blind - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 21216) AND (`Item` IN (34052, 90052, 34092)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(21216, 34052, 34052, 10, 0, 1, 0, 1, 1, 'Hydross the Unstable - (ReferenceTable)'), +(21216, 34092, 34092, 10, 0, 1, 0, 1, 1, 'Hydross the Unstable - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 21217) AND (`Item` IN (34052, 90052, 34092)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(21217, 34052, 34052, 10, 0, 1, 0, 1, 1, 'The Lurker Below - (ReferenceTable)'), +(21217, 34092, 34092, 10, 0, 1, 0, 1, 1, 'The Lurker Below - (ReferenceTable)'); + +-- Black Temple +DELETE FROM `reference_loot_template` WHERE (`Entry` IN (34069, 34116)); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34069, 32736, 0, 0, 0, 1, 1, 1, 1, 'Plans: Swiftsteel Bracers'), +(34069, 32738, 0, 0, 0, 1, 1, 1, 1, 'Plans: Dawnsteel Bracers'), +(34069, 32744, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Bracers of Renewed Life'), +(34069, 32746, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Swiftstrike Bracers'), +(34069, 32748, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Bindings of Lightning Reflexes'), +(34069, 32750, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Living Earth Bindings'), +(34069, 32752, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Swiftheal Wraps'), +(34069, 32754, 0, 0, 0, 1, 1, 1, 1, 'Pattern: Bracers of Nimble Thought'), +(34116, 32739, 0, 0, 0, 1, 2, 1, 1, 'Plans: Dawnsteel Shoulders'), +(34116, 32745, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Shoulderpads of Renewed Life'), +(34116, 32747, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Swiftstrike Shoulders'), +(34116, 32749, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Shoulders of Lightning Reflexes'), +(34116, 32751, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Living Earth Shoulders'), +(34116, 32753, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Swiftheal Mantle'), +(34116, 32737, 0, 0, 0, 1, 2, 1, 1, 'Plans: Swiftsteel Shoulders'), +(34116, 32755, 0, 0, 0, 1, 2, 1, 1, 'Pattern: Mantle of Nimble Thought'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 22841) AND (`Item` IN (34069, 34072, 190069, 34116)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(22841, 34069, 34069, 10, 0, 1, 0, 1, 1, 'Shade of Akama - (ReferenceTable)'), +(22841, 34072, 34072, 100, 0, 1, 0, 2, 2, 'Shade of Akama - (ReferenceTable)'), +(22841, 34116, 34116, 2, 0, 1, 0, 1, 1, 'Shade of Akama - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 22871) AND (`Item` IN (34069, 34073, 190069, 34116)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(22871, 34069, 34069, 10, 0, 1, 0, 1, 1, 'Teron Gorefiend - (ReferenceTable)'), +(22871, 34073, 34073, 100, 0, 1, 0, 2, 2, 'Teron Gorefiend - (ReferenceTable)'), +(22871, 34116, 34116, 2, 0, 1, 0, 1, 1, 'Teron Gorefiend - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 22887) AND (`Item` IN (34069, 34070, 90069, 34116)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(22887, 34069, 34069, 2, 0, 1, 0, 1, 1, 'High Warlord Naj\'entus - (ReferenceTable)'), +(22887, 34070, 34070, 100, 0, 1, 0, 2, 2, 'High Warlord Naj\'entus - (ReferenceTable)'), +(22887, 34116, 34116, 10, 0, 1, 0, 1, 1, 'High Warlord Naj\'entus - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 22898) AND (`Item` IN (34069, 34071, 190069, 34116)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(22898, 34069, 34069, 10, 0, 1, 0, 1, 1, 'Supremus - (ReferenceTable)'), +(22898, 34071, 34071, 100, 0, 1, 0, 2, 2, 'Supremus - (ReferenceTable)'), +(22898, 34116, 34116, 2, 0, 1, 0, 1, 1, 'Supremus - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 22947) AND (`Item` IN (34069, 34076, 90069, 34116)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(22947, 34069, 34069, 2, 0, 1, 0, 1, 1, 'Mother Shahraz - (ReferenceTable)'), +(22947, 34076, 34076, 100, 0, 1, 0, 3, 3, 'Mother Shahraz - (ReferenceTable)'), +(22947, 34116, 34116, 10, 0, 1, 0, 1, 1, 'Mother Shahraz - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 22948) AND (`Item` IN (34069, 90069, 34116)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(22948, 34069, 34069, 2, 0, 1, 0, 1, 1, 'Gurtogg Bloodboil - (ReferenceTable)'), +(22948, 34116, 34116, 10, 0, 1, 0, 1, 1, 'Gurtogg Bloodboil - (ReferenceTable)'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 23420) AND (`Item` IN (34069, 34075, 90069, 34116)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(23420, 34069, 34069, 2, 0, 1, 0, 1, 1, 'Essence of Anger - (ReferenceTable)'), +(23420, 34075, 34075, 100, 0, 1, 0, 2, 2, 'Essence of Anger - (ReferenceTable)'), +(23420, 34116, 34116, 10, 0, 1, 0, 1, 1, 'Essence of Anger - (ReferenceTable)'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34077); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34077, 32235, 0, 0, 0, 1, 1, 1, 1, 'Cursed Vision of Sargeras'), +(34077, 32336, 0, 0, 0, 1, 1, 1, 1, 'Black Bow of the Betrayer'), +(34077, 32374, 0, 0, 0, 1, 1, 1, 1, 'Zhar\'doom, Greatstaff of the Devourer'), +(34077, 32375, 0, 0, 0, 1, 1, 1, 1, 'Bulwark of Azzinoth'), +(34077, 32471, 0, 0, 0, 1, 1, 1, 1, 'Shard of Azzinoth'), +(34077, 32483, 0, 0, 0, 1, 1, 1, 1, 'The Skull of Gul\'dan'), +(34077, 32496, 0, 0, 0, 1, 1, 1, 1, 'Memento of Tyrande'), +(34077, 32497, 0, 0, 0, 1, 1, 1, 1, 'Stormrage Signet Ring'), +(34077, 32500, 0, 0, 0, 1, 1, 1, 1, 'Crystal Spire of Karabor'), +(34077, 32521, 0, 0, 0, 1, 1, 1, 1, 'Faceplate of the Impenetrable'), +(34077, 32524, 0, 0, 0, 1, 1, 1, 1, 'Shroud of the Highborne'), +(34077, 32525, 0, 0, 0, 1, 1, 1, 1, 'Cowl of the Illidari High Lord'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34117); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34117, 31089, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of the Forgotten Conqueror'), +(34117, 31090, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of the Forgotten Vanquisher'), +(34117, 31091, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of the Forgotten Protector'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 22917); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(22917, 29434, 0, 100, 0, 1, 0, 2, 2, 'Illidan Stormrage - Badge of Justice'), +(22917, 32837, 0, 5, 0, 1, 0, 1, 1, 'Illidan Stormrage - Warglaive of Azzinoth'), +(22917, 32838, 0, 5, 0, 1, 0, 1, 1, 'Illidan Stormrage - Warglaive of Azzinoth'), +(22917, 34069, 34069, 10, 0, 1, 0, 1, 1, 'Illidan Stormrage - (Patterns)'), +(22917, 34077, 34077, 100, 0, 1, 0, 2, 2, 'Illidan Stormrage - (Items)'), +(22917, 34116, 34116, 10, 0, 1, 0, 1, 1, 'Illidan Stormrage - (Patterns)'), +(22917, 34117, 34117, 100, 0, 1, 0, 3, 3, 'Illidan Stormrage - (Tokens)'); + +-- Koralon +DELETE FROM `reference_loot_template` WHERE `Entry` IN (34204, 34210, 34211); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34204, 40807, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Plate Gauntlets'), +(34204, 40808, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Scaled Gauntlets'), +(34204, 40809, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Dreadplate Gauntlets'), +(34204, 40847, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Plate Legguards'), +(34204, 40849, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Scaled Legguards'), +(34204, 40881, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Girdle of Triumph'), +(34204, 40882, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Greaves of Triumph'), +(34204, 40889, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Bracers of Triumph'), +(34204, 40927, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Ornamented Gloves'), +(34204, 40939, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Ornamented Legplates'), +(34204, 40976, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Girdle of Salvation'), +(34204, 40977, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Greaves of Salvation'), +(34204, 40983, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Bracers of Salvation'), +(34204, 41001, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Ringmail Gauntlets'), +(34204, 41007, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Mail Gauntlets'), +(34204, 41027, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Ringmail Leggings'), +(34204, 41033, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Mail Leggings'), +(34204, 41051, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Waistguard of Salvation'), +(34204, 41055, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Sabatons of Salvation'), +(34204, 41060, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Wristguards of Salvation'), +(34204, 41065, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Wristguards of Dominance'), +(34204, 41070, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Waistguard of Dominance'), +(34204, 41075, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Sabatons of Dominance'), +(34204, 41137, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Linked Gauntlets'), +(34204, 41143, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Chain Gauntlets'), +(34204, 41199, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Linked Leggings'), +(34204, 41205, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Chain Leggings'), +(34204, 41225, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Wristguards of Triumph'), +(34204, 41230, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Sabatons of Triumph'), +(34204, 41235, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Waistguard of Triumph'), +(34204, 41287, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Kodohide Gloves'), +(34204, 41293, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Wyrmhide Gloves'), +(34204, 41298, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Kodohide Legguards'), +(34204, 41304, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Wyrmhide Legguards'), +(34204, 41617, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Belt of Salvation'), +(34204, 41621, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Boots of Salvation'), +(34204, 41625, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Armwraps of Salvation'), +(34204, 41630, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Belt of Dominance'), +(34204, 41635, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Boots of Dominance'), +(34204, 41640, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Armwraps of Dominance'), +(34204, 41655, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Leather Legguards'), +(34204, 41667, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Dragonhide Legguards'), +(34204, 41767, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Leather Gloves'), +(34204, 41773, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Dragonhide Gloves'), +(34204, 41832, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Belt of Triumph'), +(34204, 41836, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Boots of Triumph'), +(34204, 41840, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Armwraps of Triumph'), +(34204, 41848, 0, 0, 0, 1, 1, 1, 1, 'Savage Gladiator\'s Mooncloth Hood'), +(34204, 41864, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Mooncloth Leggings'), +(34204, 41874, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Mooncloth Gloves'), +(34204, 41881, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Cord of Salvation'), +(34204, 41885, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Slippers of Salvation'), +(34204, 41893, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Cuffs of Salvation'), +(34204, 41898, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Cord of Dominance'), +(34204, 41903, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Slippers of Dominance'), +(34204, 41909, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Cuffs of Dominance'), +(34204, 41927, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Satin Leggings'), +(34204, 41940, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Satin Gloves'), +(34204, 41959, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Silk Trousers'), +(34204, 41971, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Silk Handguards'), +(34204, 42005, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Felweave Trousers'), +(34204, 42017, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Felweave Handguards'), +(34204, 42034, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Pendant of Triumph'), +(34204, 42035, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Pendant of Victory'), +(34204, 42036, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Pendant of Dominance'), +(34204, 42037, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Pendant of Ascendancy'), +(34204, 42038, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Pendant of Subjugation'), +(34204, 42039, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Pendant of Deliverance'), +(34204, 42040, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Pendant of Salvation'), +(34204, 42069, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Cloak of Dominance'), +(34204, 42070, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Cloak of Subjugation'), +(34204, 42071, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Cloak of Ascendancy'), +(34204, 42072, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Cloak of Salvation'), +(34204, 42073, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Cloak of Deliverance'), +(34204, 42074, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Cloak of Triumph'), +(34204, 42075, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Cloak of Victory'), +(34204, 42116, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Band of Dominance'), +(34204, 42117, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Band of Triumph'), +(34204, 46373, 0, 0, 0, 1, 1, 1, 1, 'Furious Gladiator\'s Pendant of Sundering'), +(34210, 47750, 0, 0, 0, 1, 1, 1, 1, 'Khadgar\'s Leggings of Conquest'), +(34210, 47752, 0, 0, 0, 1, 1, 1, 1, 'Khadgar\'s Gauntlets of Conquest'), +(34210, 47783, 0, 0, 0, 1, 1, 1, 1, 'Kel\'Thuzad\'s Gloves of Conquest'), +(34210, 47785, 0, 0, 0, 1, 1, 1, 1, 'Kel\'Thuzad\'s Leggings of Conquest'), +(34210, 47980, 0, 0, 0, 1, 1, 1, 1, 'Velen\'s Leggings of Conquest'), +(34210, 47982, 0, 0, 0, 1, 1, 1, 1, 'Velen\'s Gloves of Conquest'), +(34210, 48072, 0, 0, 0, 1, 1, 1, 1, 'Velen\'s Handwraps of Conquest'), +(34210, 48074, 0, 0, 0, 1, 1, 1, 1, 'Velen\'s Pants of Conquest'), +(34210, 48130, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Leggings of Conquest'), +(34210, 48132, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Handguards of Conquest'), +(34210, 48160, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Trousers of Conquest'), +(34210, 48162, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Gloves of Conquest'), +(34210, 48213, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Handgrips of Conquest'), +(34210, 48215, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Legguards of Conquest'), +(34210, 48220, 0, 0, 0, 1, 1, 1, 1, 'VanCleef\'s Legplates of Conquest'), +(34210, 48222, 0, 0, 0, 1, 1, 1, 1, 'VanCleef\'s Gauntlets of Conquest'), +(34210, 48252, 0, 0, 0, 1, 1, 1, 1, 'Windrunner\'s Legguards of Conquest'), +(34210, 48254, 0, 0, 0, 1, 1, 1, 1, 'Windrunner\'s Handguards of Conquest'), +(34210, 48282, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s Legguards of Conquest'), +(34210, 48284, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s Handguards of Conquest'), +(34210, 48312, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s Gloves of Conquest'), +(34210, 48314, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s Kilt of Conquest'), +(34210, 48342, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s Grips of Conquest'), +(34210, 48344, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s War-Kilt of Conquest'), +(34210, 48373, 0, 0, 0, 1, 1, 1, 1, 'Wrynn\'s Legplates of Conquest'), +(34210, 48375, 0, 0, 0, 1, 1, 1, 1, 'Wrynn\'s Gauntlets of Conquest'), +(34210, 48445, 0, 0, 0, 1, 1, 1, 1, 'Wrynn\'s Legguards of Conquest'), +(34210, 48449, 0, 0, 0, 1, 1, 1, 1, 'Wrynn\'s Handguards of Conquest'), +(34210, 48476, 0, 0, 0, 1, 1, 1, 1, 'Thassarian\'s Legplates of Conquest'), +(34210, 48480, 0, 0, 0, 1, 1, 1, 1, 'Thassarian\'s Gauntlets of Conquest'), +(34210, 48533, 0, 0, 0, 1, 1, 1, 1, 'Thassarian\'s Legguards of Conquest'), +(34210, 48537, 0, 0, 0, 1, 1, 1, 1, 'Thassarian\'s Handguards of Conquest'), +(34210, 48568, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Greaves of Conquest'), +(34210, 48574, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Gloves of Conquest'), +(34210, 48603, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Gauntlets of Conquest'), +(34210, 48605, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Legplates of Conquest'), +(34210, 48633, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Handguards of Conquest'), +(34210, 48635, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Legguards of Conquest'), +(34211, 47773, 0, 0, 0, 1, 1, 1, 1, 'Sunstrider\'s Gauntlets of Conquest'), +(34211, 47775, 0, 0, 0, 1, 1, 1, 1, 'Sunstrider\'s Leggings of Conquest'), +(34211, 47800, 0, 0, 0, 1, 1, 1, 1, 'Gul\'dan\'s Leggings of Conquest'), +(34211, 47802, 0, 0, 0, 1, 1, 1, 1, 'Gul\'dan\'s Gloves of Conquest'), +(34211, 48067, 0, 0, 0, 1, 1, 1, 1, 'Zabra\'s Gloves of Conquest'), +(34211, 48069, 0, 0, 0, 1, 1, 1, 1, 'Zabra\'s Leggings of Conquest'), +(34211, 48097, 0, 0, 0, 1, 1, 1, 1, 'Zabra\'s Handwraps of Conquest'), +(34211, 48099, 0, 0, 0, 1, 1, 1, 1, 'Zabra\'s Pants of Conquest'), +(34211, 48153, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Handguards of Conquest'), +(34211, 48155, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Leggings of Conquest'), +(34211, 48183, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Gloves of Conquest'), +(34211, 48185, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Trousers of Conquest'), +(34211, 48190, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Legguards of Conquest'), +(34211, 48192, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Handgrips of Conquest'), +(34211, 48244, 0, 0, 0, 1, 1, 1, 1, 'Garona\'s Gauntlets of Conquest'), +(34211, 48246, 0, 0, 0, 1, 1, 1, 1, 'Garona\'s Legplates of Conquest'), +(34211, 48276, 0, 0, 0, 1, 1, 1, 1, 'Windrunner\'s Handguards of Conquest'), +(34211, 48278, 0, 0, 0, 1, 1, 1, 1, 'Windrunner\'s Legguards of Conquest'), +(34211, 48296, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s Handguards of Conquest'), +(34211, 48298, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s Legguards of Conquest'), +(34211, 48337, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s Gloves of Conquest'), +(34211, 48339, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s Kilt of Conquest'), +(34211, 48367, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s Grips of Conquest'), +(34211, 48369, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s War-Kilt of Conquest'), +(34211, 48387, 0, 0, 0, 1, 1, 1, 1, 'Hellscream\'s Gauntlets of Conquest'), +(34211, 48389, 0, 0, 0, 1, 1, 1, 1, 'Hellscream\'s Legplates of Conquest'), +(34211, 48457, 0, 0, 0, 1, 1, 1, 1, 'Hellscream\'s Handguards of Conquest'), +(34211, 48459, 0, 0, 0, 1, 1, 1, 1, 'Hellscream\'s Legguards of Conquest'), +(34211, 48502, 0, 0, 0, 1, 1, 1, 1, 'Koltira\'s Gauntlets of Conquest'), +(34211, 48504, 0, 0, 0, 1, 1, 1, 1, 'Koltira\'s Legplates of Conquest'), +(34211, 48559, 0, 0, 0, 1, 1, 1, 1, 'Koltira\'s Handguards of Conquest'), +(34211, 48561, 0, 0, 0, 1, 1, 1, 1, 'Koltira\'s Legguards of Conquest'), +(34211, 48596, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Greaves of Conquest'), +(34211, 48598, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Gloves of Conquest'), +(34211, 48628, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Legplates of Conquest'), +(34211, 48630, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Gauntlets of Conquest'), +(34211, 48653, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Handguards of Conquest'), +(34211, 48655, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Legguards of Conquest'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 35013); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(35013, 34204, 34204, 100, 0, 1, 0, 1, 1, 'Koralon the Flame Watcher - (ReferenceTable)'), +(35013, 34210, 34210, 100, 0, 1, 0, 1, 1, 'Koralon the Flame Watcher - (ReferenceTable)'), +(35013, 34211, 34211, 100, 0, 1, 0, 1, 1, 'Koralon the Flame Watcher - (ReferenceTable)'), +(35013, 47241, 0, 100, 0, 1, 0, 2, 2, 'Koralon the Flame Watcher - Emblem of Triumph'); + +DELETE FROM `reference_loot_template` WHERE `Entry` IN (34205, 34212, 34213); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34205, 40810, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Plate Gauntlets'), +(34205, 40812, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Scaled Gauntlets'), +(34205, 40850, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Plate Legguards'), +(34205, 40851, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Dreadplate Legguards'), +(34205, 40852, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Scaled Legguards'), +(34205, 40883, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Girdle of Triumph'), +(34205, 40884, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Greaves of Triumph'), +(34205, 40890, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Bracers of Triumph'), +(34205, 40928, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Ornamented Gloves'), +(34205, 40940, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Ornamented Legplates'), +(34205, 40978, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Girdle of Salvation'), +(34205, 40979, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Greaves of Salvation'), +(34205, 40984, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Bracers of Salvation'), +(34205, 41002, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Ringmail Gauntlets'), +(34205, 41008, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Mail Gauntlets'), +(34205, 41028, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Ringmail Leggings'), +(34205, 41034, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Mail Leggings'), +(34205, 41052, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Waistguard of Salvation'), +(34205, 41056, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Sabatons of Salvation'), +(34205, 41061, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Wristguards of Salvation'), +(34205, 41066, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Wristguards of Dominance'), +(34205, 41071, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Waistguard of Dominance'), +(34205, 41076, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Sabatons of Dominance'), +(34205, 41138, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Linked Gauntlets'), +(34205, 41144, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Chain Gauntlets'), +(34205, 41200, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Linked Leggings'), +(34205, 41206, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Chain Leggings'), +(34205, 41226, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Wristguards of Triumph'), +(34205, 41231, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Sabatons of Triumph'), +(34205, 41236, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Waistguard of Triumph'), +(34205, 41288, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Kodohide Gloves'), +(34205, 41294, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Wyrmhide Gloves'), +(34205, 41299, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Kodohide Legguards'), +(34205, 41305, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Wyrmhide Legguards'), +(34205, 41618, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Belt of Salvation'), +(34205, 41622, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Boots of Salvation'), +(34205, 41626, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Armwraps of Salvation'), +(34205, 41631, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Belt of Dominance'), +(34205, 41636, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Boots of Dominance'), +(34205, 41641, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Armwraps of Dominance'), +(34205, 41656, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Leather Legguards'), +(34205, 41668, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Dragonhide Legguards'), +(34205, 41768, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Leather Gloves'), +(34205, 41774, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Dragonhide Gloves'), +(34205, 41833, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Belt of Triumph'), +(34205, 41837, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Boots of Triumph'), +(34205, 41841, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Armwraps of Triumph'), +(34205, 41865, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Mooncloth Leggings'), +(34205, 41875, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Mooncloth Gloves'), +(34205, 41882, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Cord of Salvation'), +(34205, 41886, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Treads of Salvation'), +(34205, 41894, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Cuffs of Salvation'), +(34205, 41899, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Cord of Dominance'), +(34205, 41904, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Treads of Dominance'), +(34205, 41910, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Cuffs of Dominance'), +(34205, 41928, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Satin Leggings'), +(34205, 41941, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Satin Gloves'), +(34205, 41960, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Silk Trousers'), +(34205, 41972, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Silk Handguards'), +(34205, 42006, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Felweave Trousers'), +(34205, 42018, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Felweave Handguards'), +(34205, 42041, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Pendant of Triumph'), +(34205, 42042, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Pendant of Victory'), +(34205, 42043, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Pendant of Dominance'), +(34205, 42044, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Pendant of Ascendancy'), +(34205, 42045, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Pendant of Subjugation'), +(34205, 42046, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Pendant of Deliverance'), +(34205, 42047, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Pendant of Salvation'), +(34205, 42076, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Cloak of Dominance'), +(34205, 42077, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Cloak of Subjugation'), +(34205, 42078, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Cloak of Ascendancy'), +(34205, 42079, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Cloak of Salvation'), +(34205, 42080, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Cloak of Deliverance'), +(34205, 42081, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Cloak of Triumph'), +(34205, 42082, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Cloak of Victory'), +(34205, 42118, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Band of Ascendancy'), +(34205, 42119, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Band of Victory'), +(34205, 46374, 0, 0, 0, 1, 1, 1, 1, 'Relentless Gladiator\'s Pendant of Sundering'), +(34212, 47753, 0, 0, 0, 1, 1, 1, 1, 'Khadgar\'s Gauntlets of Triumph'), +(34212, 47755, 0, 0, 0, 1, 1, 1, 1, 'Khadgar\'s Leggings of Triumph'), +(34212, 47780, 0, 0, 0, 1, 1, 1, 1, 'Kel\'Thuzad\'s Leggings of Triumph'), +(34212, 47782, 0, 0, 0, 1, 1, 1, 1, 'Kel\'Thuzad\'s Gloves of Triumph'), +(34212, 47983, 0, 0, 0, 1, 1, 1, 1, 'Velen\'s Gloves of Triumph'), +(34212, 47985, 0, 0, 0, 1, 1, 1, 1, 'Velen\'s Leggings of Triumph'), +(34212, 48077, 0, 0, 0, 1, 1, 1, 1, 'Velen\'s Handwraps of Triumph'), +(34212, 48079, 0, 0, 0, 1, 1, 1, 1, 'Velen\'s Pants of Triumph'), +(34212, 48133, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Handguards of Triumph'), +(34212, 48135, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Leggings of Triumph'), +(34212, 48163, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Gloves of Triumph'), +(34212, 48165, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Trousers of Triumph'), +(34212, 48210, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Legguards of Triumph'), +(34212, 48212, 0, 0, 0, 1, 1, 1, 1, 'Malfurion\'s Handgrips of Triumph'), +(34212, 48224, 0, 0, 0, 1, 1, 1, 1, 'VanCleef\'s Gauntlets of Triumph'), +(34212, 48226, 0, 0, 0, 1, 1, 1, 1, 'VanCleef\'s Legplates of Triumph'), +(34212, 48256, 0, 0, 0, 1, 1, 1, 1, 'Windrunner\'s Handguards of Triumph'), +(34212, 48258, 0, 0, 0, 1, 1, 1, 1, 'Windrunner\'s Legguards of Triumph'), +(34212, 48286, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s Handguards of Triumph'), +(34212, 48288, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s Legguards of Triumph'), +(34212, 48317, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s Gloves of Triumph'), +(34212, 48319, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s Kilt of Triumph'), +(34212, 48347, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s Grips of Triumph'), +(34212, 48349, 0, 0, 0, 1, 1, 1, 1, 'Nobundo\'s War-Kilt of Triumph'), +(34212, 48377, 0, 0, 0, 1, 1, 1, 1, 'Wrynn\'s Gauntlets of Triumph'), +(34212, 48379, 0, 0, 0, 1, 1, 1, 1, 'Wrynn\'s Legplates of Triumph'), +(34212, 48446, 0, 0, 0, 1, 1, 1, 1, 'Wrynn\'s Legguards of Triumph'), +(34212, 48452, 0, 0, 0, 1, 1, 1, 1, 'Wrynn\'s Handguards of Triumph'), +(34212, 48482, 0, 0, 0, 1, 1, 1, 1, 'Thassarian\'s Gauntlets of Triumph'), +(34212, 48484, 0, 0, 0, 1, 1, 1, 1, 'Thassarian\'s Legplates of Triumph'), +(34212, 48539, 0, 0, 0, 1, 1, 1, 1, 'Thassarian\'s Handguards of Triumph'), +(34212, 48541, 0, 0, 0, 1, 1, 1, 1, 'Thassarian\'s Legguards of Triumph'), +(34212, 48576, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Gloves of Triumph'), +(34212, 48578, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Greaves of Triumph'), +(34212, 48608, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Gauntlets of Triumph'), +(34212, 48610, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Legplates of Triumph'), +(34212, 48638, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Legguards of Triumph'), +(34212, 48640, 0, 0, 0, 1, 1, 1, 1, 'Turalyon\'s Handguards of Triumph'), +(34213, 47770, 0, 0, 0, 1, 1, 1, 1, 'Sunstrider\'s Leggings of Triumph'), +(34213, 47772, 0, 0, 0, 1, 1, 1, 1, 'Sunstrider\'s Gauntlets of Triumph'), +(34213, 47803, 0, 0, 0, 1, 1, 1, 1, 'Gul\'dan\'s Gloves of Triumph'), +(34213, 47805, 0, 0, 0, 1, 1, 1, 1, 'Gul\'dan\'s Leggings of Triumph'), +(34213, 48064, 0, 0, 0, 1, 1, 1, 1, 'Zabra\'s Leggings of Triumph'), +(34213, 48066, 0, 0, 0, 1, 1, 1, 1, 'Zabra\'s Gloves of Triumph'), +(34213, 48094, 0, 0, 0, 1, 1, 1, 1, 'Zabra\'s Pants of Triumph'), +(34213, 48096, 0, 0, 0, 1, 1, 1, 1, 'Zabra\'s Handwraps of Triumph'), +(34213, 48150, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Leggings of Triumph'), +(34213, 48152, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Handguards of Triumph'), +(34213, 48180, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Trousers of Triumph'), +(34213, 48182, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Gloves of Triumph'), +(34213, 48193, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Handgrips of Triumph'), +(34213, 48195, 0, 0, 0, 1, 1, 1, 1, 'Runetotem\'s Legguards of Triumph'), +(34213, 48239, 0, 0, 0, 1, 1, 1, 1, 'Garona\'s Legplates of Triumph'), +(34213, 48241, 0, 0, 0, 1, 1, 1, 1, 'Garona\'s Gauntlets of Triumph'), +(34213, 48271, 0, 0, 0, 1, 1, 1, 1, 'Windrunner\'s Legguards of Triumph'), +(34213, 48273, 0, 0, 0, 1, 1, 1, 1, 'Windrunner\'s Handguards of Triumph'), +(34213, 48301, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s Handguards of Triumph'), +(34213, 48303, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s Legguards of Triumph'), +(34213, 48332, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s Kilt of Triumph'), +(34213, 48334, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s Gloves of Triumph'), +(34213, 48362, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s War-Kilt of Triumph'), +(34213, 48364, 0, 0, 0, 1, 1, 1, 1, 'Thrall\'s Grips of Triumph'), +(34213, 48392, 0, 0, 0, 1, 1, 1, 1, 'Hellscream\'s Gauntlets of Triumph'), +(34213, 48394, 0, 0, 0, 1, 1, 1, 1, 'Hellscream\'s Legplates of Triumph'), +(34213, 48462, 0, 0, 0, 1, 1, 1, 1, 'Hellscream\'s Handguards of Triumph'), +(34213, 48464, 0, 0, 0, 1, 1, 1, 1, 'Hellscream\'s Legguards of Triumph'), +(34213, 48497, 0, 0, 0, 1, 1, 1, 1, 'Koltira\'s Legplates of Triumph'), +(34213, 48499, 0, 0, 0, 1, 1, 1, 1, 'Koltira\'s Gauntlets of Triumph'), +(34213, 48554, 0, 0, 0, 1, 1, 1, 1, 'Koltira\'s Legguards of Triumph'), +(34213, 48556, 0, 0, 0, 1, 1, 1, 1, 'Koltira\'s Handguards of Triumph'), +(34213, 48591, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Greaves of Triumph'), +(34213, 48593, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Gloves of Triumph'), +(34213, 48623, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Legplates of Triumph'), +(34213, 48625, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Gauntlets of Triumph'), +(34213, 48658, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Handguards of Triumph'), +(34213, 48660, 0, 0, 0, 1, 1, 1, 1, 'Liadrin\'s Legguards of Triumph'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 35360); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(35360, 34205, 34205, 100, 0, 1, 0, 2, 2, 'Koralon the Flame Watcher (1) - (ReferenceTable)'), +(35360, 2, 34203, 1, 0, 1, 0, 1, 1, 'Koralon the Flame Watcher (1) - (ReferenceTable)'), +(35360, 34212, 34212, 100, 0, 1, 0, 2, 2, 'Koralon the Flame Watcher (1) - (ReferenceTable)'), +(35360, 34213, 34213, 100, 0, 1, 0, 2, 2, 'Koralon the Flame Watcher (1) - (ReferenceTable)'), +(35360, 47241, 0, 100, 0, 1, 0, 2, 2, 'Koralon the Flame Watcher (1) - Emblem of Triumph'); + +UPDATE `conditions` SET `SourceGroup` = 34212 WHERE `SourceTypeOrReferenceId` = 10 AND `SourceGroup` = 34205 AND `SourceEntry` IN (47753,47755,47780,47782,47983,47985,48077,48079,48133,48135,48163,48165,48210,48212,48224,48226,48256,48258,48286,48288,48317,48319,48347,48349,48377,48379,48446,48452,48482,48484,48539,48541,48576,48578,48608,48610,48638,48640); + +UPDATE `conditions` SET `SourceGroup` = 34213 WHERE `SourceTypeOrReferenceId` = 10 AND `SourceGroup` = 34205 AND `SourceEntry` IN (47770,47772,47803,47805,48064,48066,48094,48096,48150,48152,48180,48182,48193,48195,48239,48241,48271,48273,48301,48303,48332,48334,48362,48364,48392,48394,48462,48464,48497,48499,48554,48556,48591,48593,48623,48625,48658,48660); + +UPDATE `conditions` SET `SourceGroup` = 34210 WHERE `SourceTypeOrReferenceId` = 10 AND `SourceGroup` = 34204 AND `SourceEntry` IN (47750,47752,47783,47785,47980,47982,48072,48074,48130,48132,48160,48162,48213,48215,48220,48222,48252,48254,48282,48284,48312,48314,48342,48344,48373,48375,48445,48449,48476,48480,48533,48537,48568,48574,48603,48605,48633,48635); + +UPDATE `conditions` SET `SourceGroup` = 34211 WHERE `SourceTypeOrReferenceId` = 10 AND `SourceGroup` = 34204 AND `SourceEntry` IN (47773,47775,47800,47802,48067,48069,48097,48099,48153,48155,48183,48185,48190,48192,48244,48246,48276,48278,48296,48298,48337,48339,48367,48369,48387,48389,48457,48459,48502,48504,48559,48561,48596,48598,48628,48630,48653,48655); + +-- Worldserver fixes +DELETE FROM `creature_loot_template` WHERE (`Entry` = 29380) AND (`Item` IN (26001, 26002, 26012, 26013, 26014, 26015, 26028)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(29380, 26001, 26001, 3, 0, 1, 0, 1, 1, 'Stormforged War Golem - (ReferenceTable)'), +(29380, 26002, 26002, 3, 0, 1, 0, 1, 1, 'Stormforged War Golem - (ReferenceTable)'), +(29380, 26012, 26012, 1, 0, 1, 0, 1, 1, 'Stormforged War Golem - (ReferenceTable)'), +(29380, 26013, 26013, 1, 0, 1, 0, 1, 1, 'Stormforged War Golem - (ReferenceTable)'), +(29380, 26014, 26014, 1, 0, 1, 0, 1, 1, 'Stormforged War Golem - (ReferenceTable)'), +(29380, 26015, 26015, 1, 0, 1, 0, 1, 1, 'Stormforged War Golem - (ReferenceTable)'), +(29380, 26028, 26028, 0.5, 0, 1, 0, 1, 1, 'Stormforged War Golem - (ReferenceTable)'); + +-- Now useless +DELETE FROM `reference_loot_template` WHERE `Entry` = 1276883; +-- Rename to not mess up things in the future soont(tm) +UPDATE `reference_loot_template` SET `Entry` = 34214 WHERE `Entry` = 1276884; +UPDATE `creature_loot_template` SET `Reference` = 34214 WHERE `Entry` = 17968 AND `Item` = 34069 AND `Reference` = 1276884 AND `GroupId`=3; +-- Hacked Quest Item? +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 10) AND (`SourceGroup` = 44003) AND (`SourceEntry` = 34090) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 9) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 11236) AND (`ConditionValue2` = 0) AND (`ConditionValue3` = 0); +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 10) AND (`SourceGroup` = 44004) AND (`SourceEntry` = 34091) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 9) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 11264) AND (`ConditionValue2` = 0) AND (`ConditionValue3` = 0); + +-- Thorium Prospecting was the only ever entry with negative References +UPDATE `prospecting_loot_template` SET `Reference` = 13001 WHERE `Entry` = 10620 AND `Item` = 1 AND `Reference` = -13001; diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 59a6c9d20..74e8b7575 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -376,9 +376,9 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const { if (needs_quest) LOG_ERROR("sql.sql", "Table '{}' Entry {} Item {}: quest required will be ignored", store.GetName(), entry, itemid); - else if (chance == 0) // no chance for the reference + else if (chance == 0 && groupid == 0) { - LOG_ERROR("sql.sql", "Table '{}' Entry {} Item {}: zero chance is specified for a reference, skipped", store.GetName(), entry, itemid); + LOG_ERROR("sql.sql", "Table '{}' Entry {} Item {}: zero chance is specified for an ungrouped reference, skipped", store.GetName(), entry, itemid); return false; } } @@ -1340,7 +1340,7 @@ bool LootTemplate::LootGroup::HasQuestDrop(LootTemplateMap const& store) const continue; // Error message [should be] already printed at loading stage } - if (Referenced->second->HasQuestDrop(store, item->groupid)) + if (Referenced->second->HasQuestDrop(store)) { return true; } @@ -1362,7 +1362,7 @@ bool LootTemplate::LootGroup::HasQuestDrop(LootTemplateMap const& store) const continue; // Error message [should be] already printed at loading stage } - if (Referenced->second->HasQuestDrop(store, item->groupid)) + if (Referenced->second->HasQuestDrop(store)) { return true; } @@ -1390,7 +1390,7 @@ bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const* player, LootTe continue; // Error message already printed at loading stage } - if (Referenced->second->HasQuestDropForPlayer(store, player, item->groupid)) + if (Referenced->second->HasQuestDropForPlayer(store, player)) { return true; } @@ -1412,7 +1412,7 @@ bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const* player, LootTe continue; // Error message already printed at loading stage } - if (Referenced->second->HasQuestDropForPlayer(store, player, item->groupid)) + if (Referenced->second->HasQuestDropForPlayer(store, player)) { return true; } @@ -1451,7 +1451,7 @@ void LootTemplate::LootGroup::Process(Loot& loot, Player const* player, LootStor for (uint32 loop = 0; loop < maxcount; ++loop) // Ref multiplicator // This reference needs to be processed further, but it is marked isTopLevel=false so that any groups inside // the reference are not multiplied by Rate.Drop.Item.GroupAmount - Referenced->Process(loot, store, lootMode, player, item->groupid, false); + Referenced->Process(loot, store, lootMode, player, 0, false); } } else @@ -1561,9 +1561,7 @@ LootTemplate::~LootTemplate() // Adds an entry to the group (at loading stage) void LootTemplate::AddEntry(LootStoreItem* item) { - // `item->reference` > 0 --> Reference is counted as a normal and non grouped entry - // `item->reference` < 0 --> Reference is counted as grouped entry within shared groupid - if (item->groupid > 0 && item->reference <= 0) // Group and grouped reference + if (item->groupid > 0) // Group and grouped reference { if (item->groupid >= Groups.size()) { @@ -1768,19 +1766,8 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint16 lootMode, } // True if template includes at least 1 quest drop entry -bool LootTemplate::HasQuestDrop(LootTemplateMap const& store, uint8 groupId) const +bool LootTemplate::HasQuestDrop(LootTemplateMap const& store) const { - if (groupId) // Group reference - { - if (groupId > Groups.size()) - return false; // Error message [should be] already printed at loading stage - - if (!Groups[groupId - 1]) - return false; - - return Groups[groupId - 1]->HasQuestDrop(store); - } - for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i) { LootStoreItem* item = *i; @@ -1790,7 +1777,7 @@ bool LootTemplate::HasQuestDrop(LootTemplateMap const& store, uint8 groupId) con if (Referenced == store.end()) continue; // Error message [should be] already printed at loading stage - if (Referenced->second->HasQuestDrop(store, item->groupid)) + if (Referenced->second->HasQuestDrop(store)) return true; } else if (item->needs_quest) @@ -1813,19 +1800,8 @@ bool LootTemplate::HasQuestDrop(LootTemplateMap const& store, uint8 groupId) con } // True if template includes at least 1 quest drop for an active quest of the player -bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player const* player, uint8 groupId) const +bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player const* player) const { - if (groupId) // Group reference - { - if (groupId > Groups.size()) - return false; // Error message already printed at loading stage - - if (!Groups[groupId - 1]) - return false; - - return Groups[groupId - 1]->HasQuestDropForPlayer(player, store); - } - // Checking non-grouped entries for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i) { @@ -1835,7 +1811,7 @@ bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player co LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference)); if (Referenced == store.end()) continue; // Error message already printed at loading stage - if (Referenced->second->HasQuestDropForPlayer(store, player, item->groupid)) + if (Referenced->second->HasQuestDropForPlayer(store, player)) return true; } else if (player->HasQuestForItem(item->itemid)) diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index d906a56a0..fd2b0e8b5 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -258,9 +258,9 @@ public: bool CopyConditions(LootItem* li, uint32 conditionLootId = 0) const; // True if template includes at least 1 quest drop entry - [[nodiscard]] bool HasQuestDrop(LootTemplateMap const& store, uint8 groupId = 0) const; + [[nodiscard]] bool HasQuestDrop(LootTemplateMap const& store) const; // True if template includes at least 1 quest drop for an active quest of the player - bool HasQuestDropForPlayer(LootTemplateMap const& store, Player const* player, uint8 groupId = 0) const; + bool HasQuestDropForPlayer(LootTemplateMap const& store, Player const* player) const; // Checks integrity of the template void Verify(LootStore const& store, uint32 Id) const; From ff079ae0ccdc40e5121e2a099c1a70a3721cebf9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Feb 2026 23:14:49 +0000 Subject: [PATCH 141/335] chore(DB): import pending files Referenced commit(s): 01f8f9147548928a803aeb41d13e1bd4499a9163 --- .../rev_1767140544966521500.sql => db_world/2026_02_15_07.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1767140544966521500.sql => db_world/2026_02_15_07.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1767140544966521500.sql b/data/sql/updates/db_world/2026_02_15_07.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1767140544966521500.sql rename to data/sql/updates/db_world/2026_02_15_07.sql index 9db201cab..fe88bcf95 100644 --- a/data/sql/updates/pending_db_world/rev_1767140544966521500.sql +++ b/data/sql/updates/db_world/2026_02_15_07.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_15_06 -> 2026_02_15_07 -- DELETE FROM `creature_loot_template` WHERE (`Entry` = 20169) AND (`Item` IN (12018, 43002)); INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES From 27a39dda665d5721c7ac5cca946805c9226bb564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ga=C5=82ecki?= Date: Mon, 16 Feb 2026 00:35:25 +0100 Subject: [PATCH 142/335] fix(Core/Battlegrounds): Fix Siege Engine being destroyed after spawn, fix demolishers not being destroyed after flag contest (#24461) --- .../Battlegrounds/Zones/BattlegroundIC.cpp | 95 +++++++++++++------ 1 file changed, 64 insertions(+), 31 deletions(-) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index 50721aa03..d4924f7f2 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -179,7 +179,7 @@ void BattlegroundIC::PostUpdateImpl(uint32 diff) if (siegeEngineWorkshopTimer <= diff) { uint8 siegeType = (nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_A : BG_IC_NPC_SIEGE_ENGINE_H); - if (Creature* siege = GetBGCreature(siegeType)) // this always should be true + if (Creature* siege = GetBgMap()->GetCreature(BgCreatures[siegeType])) if (!siege->IsAlive()) { // Check if creature respawn time is properly saved @@ -749,6 +749,37 @@ void BattlegroundIC::HandleContestedNodes(ICNodePoint* nodePoint) { DelObject(BG_IC_GO_SEAFORIUM_BOMBS_1); DelObject(BG_IC_GO_SEAFORIUM_BOMBS_2); + + for (uint8 i = 0; i < MAX_DEMOLISHERS_SPAWNS_PER_FACTION; ++i) + { + uint8 type = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_1_H : BG_IC_NPC_DEMOLISHER_1_A) + i; + if (BgCreatures[type] && GetBgMap()->GetCreature(BgCreatures[type])) + { + if (Creature* demolisher = GetBgMap()->GetCreature(BgCreatures[type])) + { + if (Vehicle* veh = demolisher->GetVehicleKit()) + if (!veh->IsVehicleInUse()) + { + respawnMap.erase(demolisher->GetGUID()); + DelCreature(type); + } + } + } + } + + uint8 siegeType = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_H : BG_IC_NPC_SIEGE_ENGINE_A); + if (BgCreatures[siegeType] && GetBgMap()->GetCreature(BgCreatures[siegeType])) + { + if (Creature* siege = GetBgMap()->GetCreature(BgCreatures[siegeType])) + { + if (Vehicle* veh = siege->GetVehicleKit()) + if (!veh->IsVehicleInUse()) + { + respawnMap.erase(siege->GetGUID()); + DelCreature(siegeType); + } + } + } } } @@ -865,43 +896,45 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) if (siegeEngineWorkshopTimer < WORKSHOP_UPDATE_TIME) siegeEngineWorkshopTimer = WORKSHOP_UPDATE_TIME; - if (!recapture) + for (uint8 i = 0; i < MAX_DEMOLISHERS_SPAWNS_PER_FACTION; ++i) { - for (uint8 i = 0; i < MAX_DEMOLISHERS_SPAWNS_PER_FACTION; ++i) - { - uint8 type = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_1_A : BG_IC_NPC_DEMOLISHER_1_H) + i; + uint8 type = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_1_A : BG_IC_NPC_DEMOLISHER_1_H) + i; - if (GetBgMap()->GetCreature(BgCreatures[type])) - continue; + if (GetBgMap()->GetCreature(BgCreatures[type])) + continue; - if (AddCreature(NPC_DEMOLISHER, type, - BG_IC_WorkshopVehicles[i].GetPositionX(), BG_IC_WorkshopVehicles[i].GetPositionY(), - BG_IC_WorkshopVehicles[i].GetPositionZ(), BG_IC_WorkshopVehicles[i].GetOrientation(), - RESPAWN_ONE_DAY)) - GetBGCreature(type)->SetFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE)]); - } + if (AddCreature(NPC_DEMOLISHER, type, + BG_IC_WorkshopVehicles[i].GetPositionX(), BG_IC_WorkshopVehicles[i].GetPositionY(), + BG_IC_WorkshopVehicles[i].GetPositionZ(), BG_IC_WorkshopVehicles[i].GetOrientation(), + RESPAWN_ONE_DAY)) + GetBGCreature(type)->SetFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE)]); + } - uint8 siegeType = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_A : BG_IC_NPC_SIEGE_ENGINE_H); - if (!GetBgMap()->GetCreature(BgCreatures[siegeType])) - { - AddCreature((nodePoint->faction == TEAM_ALLIANCE ? NPC_SIEGE_ENGINE_A : NPC_SIEGE_ENGINE_H), siegeType, - BG_IC_WorkshopVehicles[4].GetPositionX(), BG_IC_WorkshopVehicles[4].GetPositionY(), - BG_IC_WorkshopVehicles[4].GetPositionZ(), BG_IC_WorkshopVehicles[4].GetOrientation(), - RESPAWN_ONE_DAY); - } + uint8 siegeType = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_A : BG_IC_NPC_SIEGE_ENGINE_H); + uint8 oppositeSiegeType = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_H : BG_IC_NPC_SIEGE_ENGINE_A); - if (Creature* siegeEngine = GetBgMap()->GetCreature(BgCreatures[siegeType])) - { - siegeEngine->SetFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE)]); - siegeEngine->SetCorpseDelay(5 * MINUTE); + if (Creature* oppositeSiege = GetBgMap()->GetCreature(BgCreatures[oppositeSiegeType])) + { + if (oppositeSiege->IsAlive()) + if (Vehicle* siegeVehicle = oppositeSiege->GetVehicleKit()) + if (!siegeVehicle->IsVehicleInUse()) + Unit::Kill(oppositeSiege, oppositeSiege); + } - if (siegeEngine->IsAlive()) - if (Vehicle* siegeVehicle = siegeEngine->GetVehicleKit()) - if (!siegeVehicle->IsVehicleInUse()) - Unit::Kill(siegeEngine, siegeEngine); + if (!GetBgMap()->GetCreature(BgCreatures[siegeType])) + { + AddCreature((nodePoint->faction == TEAM_ALLIANCE ? NPC_SIEGE_ENGINE_A : NPC_SIEGE_ENGINE_H), siegeType, + BG_IC_WorkshopVehicles[4].GetPositionX(), BG_IC_WorkshopVehicles[4].GetPositionY(), + BG_IC_WorkshopVehicles[4].GetPositionZ(), BG_IC_WorkshopVehicles[4].GetOrientation(), + RESPAWN_ONE_DAY); + } - respawnMap[siegeEngine->GetGUID()] = GameTime::GetGameTime().count() + VEHICLE_RESPAWN_TIME; - } + if (Creature* siegeEngine = GetBgMap()->GetCreature(BgCreatures[siegeType])) + { + siegeEngine->SetFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE)]); + siegeEngine->SetCorpseDelay(5 * MINUTE); + + respawnMap[siegeEngine->GetGUID()] = GameTime::GetGameTime().count() + VEHICLE_RESPAWN_TIME; } for (uint8 i = 0; i < MAX_WORKSHOP_BOMBS_SPAWNS_PER_FACTION; ++i) From 686aafd57be6f1594a99634bade3756643fbf6f3 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 15 Feb 2026 21:45:03 -0600 Subject: [PATCH 143/335] feat(Core/Hooks) Adds hooks for BG and Arena systems. (#23543) --- src/server/game/Battlegrounds/Arena.cpp | 8 +- src/server/game/Battlegrounds/ArenaTeam.cpp | 15 +-- .../game/Battlegrounds/BattlegroundQueue.cpp | 94 ++++++++++++++++--- .../ScriptDefines/AllBattlegroundScript.cpp | 10 ++ .../ScriptDefines/AllBattlegroundScript.h | 34 +++++++ .../Scripting/ScriptDefines/ArenaScript.cpp | 10 ++ .../Scripting/ScriptDefines/ArenaScript.h | 6 ++ src/server/game/Scripting/ScriptMgr.h | 4 + src/test/CMakeLists.txt | 20 ++++ 9 files changed, 178 insertions(+), 23 deletions(-) diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp index 92a97fa5a..cc24d9418 100644 --- a/src/server/game/Battlegrounds/Arena.cpp +++ b/src/server/game/Battlegrounds/Arena.cpp @@ -351,16 +351,16 @@ void Arena::EndBattleground(TeamId winnerTeamId) // Last standing - Rated 5v5 arena & be solely alive player if (GetArenaType() == ARENA_TYPE_5v5 && aliveWinners == 1 && player->IsAlive()) - { player->CastSpell(player, SPELL_LAST_MAN_STANDING, true); - } - winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange); + if (!sScriptMgr->OnBeforeArenaTeamMemberUpdate(winnerArenaTeam, player, true, loserMatchmakerRating, winnerMatchmakerChange)) + winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange); } } else { - loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange); + if (!sScriptMgr->OnBeforeArenaTeamMemberUpdate(loserArenaTeam, player, false, winnerMatchmakerRating, loserMatchmakerChange)) + loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange); // Arena lost => reset the win_rated_arena having the "no_lose" condition player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE, 0); diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index 2b6265e7c..dcd567d67 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -966,12 +966,15 @@ void ArenaTeam::SaveToDB(bool forceMemberSave) stmt->SetData(6, itr->Guid.GetCounter()); trans->Append(stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHARACTER_ARENA_STATS); - stmt->SetData(0, itr->Guid.GetCounter()); - stmt->SetData(1, GetSlot()); - stmt->SetData(2, itr->MatchMakerRating); - stmt->SetData(3, itr->MaxMMR); - trans->Append(stmt); + if (sScriptMgr->CanSaveArenaStatsForMember(this, itr->Guid)) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHARACTER_ARENA_STATS); + stmt->SetData(0, itr->Guid.GetCounter()); + stmt->SetData(1, GetSlot()); + stmt->SetData(2, itr->MatchMakerRating); + stmt->SetData(3, itr->MaxMMR); + trans->Append(stmt); + } } CharacterDatabase.CommitTransaction(trans); diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 60da08d67..97a529327 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -434,15 +434,37 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId //index to queue which group is current uint32 aliIndex = 0; - for (; aliIndex < aliCount && m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); aliIndex++) + for (; aliIndex < aliCount; aliIndex++) + { + if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Ali_itr), m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount(), bg, bracket_id)) + { + ++Ali_itr; + continue; + } + + if (!m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree)) + break; + ++Ali_itr; + } //the same thing for horde GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].begin(); uint32 hordeIndex = 0; - for (; hordeIndex < hordeCount && m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++) + for (; hordeIndex < hordeCount; hordeIndex++) + { + if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Horde_itr), m_SelectionPools[TEAM_HORDE].GetPlayerCount(), bg, bracket_id)) + { + ++Horde_itr; + continue; + } + + if (!m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), hordeFree)) + break; + ++Horde_itr; + } //if ofc like BG queue invitation is set in config, then we are happy if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == BG_QUEUE_INVITATION_TYPE_NO_BALANCE) @@ -468,8 +490,19 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId //kick alliance group, add to pool new group if needed if (m_SelectionPools[TEAM_ALLIANCE].KickGroup(diffHorde - diffAli)) { - for (; aliIndex < aliCount && m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), (aliFree >= diffHorde) ? aliFree - diffHorde : 0); aliIndex++) + for (; aliIndex < aliCount; aliIndex++) + { + if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Ali_itr), m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount(), bg, bracket_id)) + { + ++Ali_itr; + continue; + } + + if (!m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), (aliFree >= diffHorde) ? aliFree - diffHorde : 0)) + break; + ++Ali_itr; + } } //if ali selection is already empty, then kick horde group, but if there are less horde than ali in bg - break; @@ -486,8 +519,19 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId //kick horde group, add to pool new group if needed if (m_SelectionPools[TEAM_HORDE].KickGroup(diffAli - diffHorde)) { - for (; hordeIndex < hordeCount && m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), (hordeFree >= diffAli) ? hordeFree - diffAli : 0); hordeIndex++) + for (; hordeIndex < hordeCount; hordeIndex++) + { + if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Horde_itr), m_SelectionPools[TEAM_HORDE].GetPlayerCount(), bg, bracket_id)) + { + ++Horde_itr; + continue; + } + + if (!m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), (hordeFree >= diffAli) ? hordeFree - diffAli : 0)) + break; + ++Horde_itr; + } } if (!m_SelectionPools[TEAM_HORDE].GetPlayerCount()) @@ -525,6 +569,12 @@ bool BattlegroundQueue::CheckPremadeMatch(BattlegroundBracketId bracket_id, uint // if found both groups if (ali_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end()) { + if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*ali_group), 0, nullptr, bracket_id)) + return false; + + if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*horde_group), m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount(), nullptr, bracket_id)) + return false; + m_SelectionPools[TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam); m_SelectionPools[TEAM_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam); @@ -536,9 +586,14 @@ bool BattlegroundQueue::CheckPremadeMatch(BattlegroundBracketId bracket_id, uint { for (itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr) { - //if itr can join BG and player count is less that maxPlayers, then add group to selectionpool - if (!(*itr)->IsInvitedToBGInstanceGUID && !m_SelectionPools[i].AddGroup((*itr), maxPlayers)) - break; + if (!(*itr)->IsInvitedToBGInstanceGUID) + { + if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*itr), m_SelectionPools[i].GetPlayerCount(), nullptr, bracket_id)) + continue; + + if (!m_SelectionPools[i].AddGroup((*itr), maxPlayers)) + break; + } } } @@ -596,9 +651,12 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground* bgTemplate, BattlegroundB { if (!(*(itr_team[i]))->IsInvitedToBGInstanceGUID) { - m_SelectionPools[i].AddGroup(*(itr_team[i]), maxPlayers); - if (m_SelectionPools[i].GetPlayerCount() >= minPlayers) - break; + if (sScriptMgr->CanAddGroupToMatchingPool(this, *(itr_team[i]), m_SelectionPools[i].GetPlayerCount(), bgTemplate, bracket_id)) + { + m_SelectionPools[i].AddGroup(*(itr_team[i]), maxPlayers); + if (m_SelectionPools[i].GetPlayerCount() >= minPlayers) + break; + } } } } @@ -616,8 +674,13 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground* bgTemplate, BattlegroundB for (; itr_team[j] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j])) { if (!(*(itr_team[j]))->IsInvitedToBGInstanceGUID) + { + if (!sScriptMgr->CanAddGroupToMatchingPool(this, *(itr_team[j]), m_SelectionPools[j].GetPlayerCount(), bgTemplate, bracket_id)) + continue; + if (!m_SelectionPools[j].AddGroup(*(itr_team[j]), m_SelectionPools[(j + 1) % PVP_TEAMS_COUNT].GetPlayerCount())) break; + } } // do not allow to start bg with more than 2 players more on 1 faction @@ -664,9 +727,14 @@ bool BattlegroundQueue::CheckSkirmishForSameFaction(BattlegroundBracketId bracke //invite players to other selection pool for (; itr_team2 != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + static_cast(teamIndex)].end(); ++itr_team2) { - //if selection pool is full then break; - if (!(*itr_team2)->IsInvitedToBGInstanceGUID && !m_SelectionPools[otherTeam].AddGroup(*itr_team2, minPlayersPerTeam)) - break; + if (!(*itr_team2)->IsInvitedToBGInstanceGUID) + { + if (!sScriptMgr->CanAddGroupToMatchingPool(this, *itr_team2, m_SelectionPools[otherTeam].GetPlayerCount(), nullptr, bracket_id)) + continue; + + if (!m_SelectionPools[otherTeam].AddGroup(*itr_team2, minPlayersPerTeam)) + break; + } } if (m_SelectionPools[otherTeam].GetPlayerCount() != minPlayersPerTeam) diff --git a/src/server/game/Scripting/ScriptDefines/AllBattlegroundScript.cpp b/src/server/game/Scripting/ScriptDefines/AllBattlegroundScript.cpp index 0c9c3c8f4..9881a25f0 100644 --- a/src/server/game/Scripting/ScriptDefines/AllBattlegroundScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/AllBattlegroundScript.cpp @@ -104,6 +104,16 @@ void ScriptMgr::OnBattlegroundCreate(Battleground* bg) CALL_ENABLED_HOOKS(AllBattlegroundScript, ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_CREATE, script->OnBattlegroundCreate(bg)); } +bool ScriptMgr::CanAddGroupToMatchingPool(BattlegroundQueue* queue, GroupQueueInfo* group, uint32 poolPlayerCount, Battleground* bg, BattlegroundBracketId bracketId) +{ + CALL_ENABLED_BOOLEAN_HOOKS(AllBattlegroundScript, ALLBATTLEGROUNDHOOK_CAN_ADD_GROUP_TO_MATCHING_POOL, !script->CanAddGroupToMatchingPool(queue, group, poolPlayerCount, bg, bracketId)); +} + +bool ScriptMgr::GetPlayerMatchmakingRating(ObjectGuid playerGuid, BattlegroundTypeId bgTypeId, float& outRating) +{ + CALL_ENABLED_BOOLEAN_HOOKS_WITH_DEFAULT_FALSE(AllBattlegroundScript, ALLBATTLEGROUNDHOOK_GET_PLAYER_MATCHMAKING_RATING, script->GetPlayerMatchmakingRating(playerGuid, bgTypeId, outRating)); +} + AllBattlegroundScript::AllBattlegroundScript(char const* name, std::vector enabledHooks) : ScriptObject(name, ALLBATTLEGROUNDHOOK_END) { diff --git a/src/server/game/Scripting/ScriptDefines/AllBattlegroundScript.h b/src/server/game/Scripting/ScriptDefines/AllBattlegroundScript.h index 9ab6eea78..108f3cf7f 100644 --- a/src/server/game/Scripting/ScriptDefines/AllBattlegroundScript.h +++ b/src/server/game/Scripting/ScriptDefines/AllBattlegroundScript.h @@ -18,6 +18,7 @@ #ifndef SCRIPT_OBJECT_ALL_BATTLEGROUND_SCRIPT_H_ #define SCRIPT_OBJECT_ALL_BATTLEGROUND_SCRIPT_H_ +#include "ObjectGuid.h" #include "ScriptObject.h" #include @@ -40,6 +41,8 @@ enum AllBattlegroundHook ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_END, ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_DESTROY, ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_CREATE, + ALLBATTLEGROUNDHOOK_CAN_ADD_GROUP_TO_MATCHING_POOL, + ALLBATTLEGROUNDHOOK_GET_PLAYER_MATCHMAKING_RATING, ALLBATTLEGROUNDHOOK_END }; @@ -47,6 +50,9 @@ enum BattlegroundBracketId : uint8; enum BattlegroundTypeId : uint8; enum TeamId : uint8; +class BattlegroundQueue; +struct GroupQueueInfo; + class AllBattlegroundScript : public ScriptObject { protected: @@ -132,6 +138,34 @@ public: * @param bg Contains information about the Battleground */ virtual void OnBattlegroundCreate(Battleground* /*bg*/) { } + + /** + * @brief This hook runs before adding a group to the battleground matching pool + * + * Allows modules to filter groups based on custom criteria (e.g., MMR matching). + * Called during FillPlayersToBG before each group is added to the SelectionPool. + * + * @param queue The battleground queue + * @param group The group being considered for addition + * @param poolPlayerCount Current number of players already in the selection pool + * @param bg The battleground instance + * @param bracketId The bracket ID + * @return True to allow adding this group, false to skip it + */ + [[nodiscard]] virtual bool CanAddGroupToMatchingPool(BattlegroundQueue* /*queue*/, GroupQueueInfo* /*group*/, uint32 /*poolPlayerCount*/, Battleground* /*bg*/, BattlegroundBracketId /*bracketId*/) { return true; } + + /** + * @brief This hook allows modules to provide matchmaking rating for a player + * + * Modules implementing MMR systems can use this hook to provide player ratings + * for use in matchmaking algorithms. + * + * @param playerGuid The player's GUID + * @param bgTypeId The battleground type + * @param outRating Reference to store the rating value + * @return True if rating was provided, false otherwise + */ + [[nodiscard]] virtual bool GetPlayerMatchmakingRating(ObjectGuid /*playerGuid*/, BattlegroundTypeId /*bgTypeId*/, float& /*outRating*/) { return false; } }; // Compatibility for old scripts diff --git a/src/server/game/Scripting/ScriptDefines/ArenaScript.cpp b/src/server/game/Scripting/ScriptDefines/ArenaScript.cpp index af3baf332..5521e7cbc 100644 --- a/src/server/game/Scripting/ScriptDefines/ArenaScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/ArenaScript.cpp @@ -44,6 +44,16 @@ void ScriptMgr::OnArenaStart(Battleground* bg) CALL_ENABLED_HOOKS(ArenaScript, ARENAHOOK_ON_ARENA_START, script->OnArenaStart(bg)); } +bool ScriptMgr::OnBeforeArenaTeamMemberUpdate(ArenaTeam* team, Player* player, bool won, uint32 opponentMatchmakerRating, int32 matchmakerChange) +{ + CALL_ENABLED_BOOLEAN_HOOKS(ArenaScript, ARENAHOOK_ON_BEFORE_TEAM_MEMBER_UPDATE, !script->OnBeforeArenaTeamMemberUpdate(team, player, won, opponentMatchmakerRating, matchmakerChange)); +} + +bool ScriptMgr::CanSaveArenaStatsForMember(ArenaTeam* team, ObjectGuid playerGuid) +{ + CALL_ENABLED_BOOLEAN_HOOKS(ArenaScript, ARENAHOOK_CAN_SAVE_ARENA_STATS_FOR_MEMBER, !script->CanSaveArenaStatsForMember(team, playerGuid)); +} + ArenaScript::ArenaScript(const char* name, std::vector enabledHooks) : ScriptObject(name, ARENAHOOK_END) { diff --git a/src/server/game/Scripting/ScriptDefines/ArenaScript.h b/src/server/game/Scripting/ScriptDefines/ArenaScript.h index 152dd7584..0529d23ac 100644 --- a/src/server/game/Scripting/ScriptDefines/ArenaScript.h +++ b/src/server/game/Scripting/ScriptDefines/ArenaScript.h @@ -29,6 +29,8 @@ enum ArenaHook ARENAHOOK_CAN_SAVE_TO_DB, ARENAHOOK_ON_BEFORE_CHECK_WIN_CONDITION, ARENAHOOK_ON_ARENA_START, + ARENAHOOK_ON_BEFORE_TEAM_MEMBER_UPDATE, + ARENAHOOK_CAN_SAVE_ARENA_STATS_FOR_MEMBER, ARENAHOOK_END }; @@ -51,6 +53,10 @@ public: [[nodiscard]] virtual bool CanSaveToDB(ArenaTeam* /*team*/) { return true; } virtual void OnArenaStart(Battleground* /* bg */) { }; + + [[nodiscard]] virtual bool OnBeforeArenaTeamMemberUpdate(ArenaTeam* /*team*/, Player* /*player*/, bool /*won*/, uint32 /*opponentMatchmakerRating*/, int32 /*matchmakerChange*/) { return false; } + + [[nodiscard]] virtual bool CanSaveArenaStatsForMember(ArenaTeam* /*team*/, ObjectGuid /*playerGuid*/) { return true; } }; #endif diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 222dac69e..3687e455a 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -596,6 +596,8 @@ public: /* BGScript */ void OnBattlegroundEnd(Battleground* bg, TeamId winnerTeamId); void OnBattlegroundDestroy(Battleground* bg); void OnBattlegroundCreate(Battleground* bg); + bool CanAddGroupToMatchingPool(BattlegroundQueue* queue, GroupQueueInfo* group, uint32 poolPlayerCount, Battleground* bg, BattlegroundBracketId bracketId); + bool GetPlayerMatchmakingRating(ObjectGuid playerGuid, BattlegroundTypeId bgTypeId, float& outRating); public: /* Arena Team Script */ void OnGetSlotByType(const uint32 type, uint8& slot); @@ -651,6 +653,8 @@ public: /* ArenaScript */ bool CanSaveToDB(ArenaTeam* team); bool OnBeforeArenaCheckWinConditions(Battleground* const bg); void OnArenaStart(Battleground* const bg); + bool OnBeforeArenaTeamMemberUpdate(ArenaTeam* team, Player* player, bool won, uint32 opponentMatchmakerRating, int32 matchmakerChange); + bool CanSaveArenaStatsForMember(ArenaTeam* team, ObjectGuid playerGuid); public: /* MiscScript */ diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 62ae23578..bf5386d5b 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -31,6 +31,26 @@ target_link_libraries( game-interface ) +# Add module test sources if any modules registered tests +get_property(MODULE_TEST_SOURCES GLOBAL PROPERTY ACORE_MODULE_TEST_SOURCES) +get_property(MODULE_TEST_INCLUDES GLOBAL PROPERTY ACORE_MODULE_TEST_INCLUDES) + +if(MODULE_TEST_SOURCES) + target_sources(unit_tests PRIVATE ${MODULE_TEST_SOURCES}) + message(STATUS "Added module tests to unit_tests target") +endif() + +if(MODULE_TEST_INCLUDES) + list(REMOVE_DUPLICATES MODULE_TEST_INCLUDES) + target_include_directories(unit_tests PRIVATE ${MODULE_TEST_INCLUDES}) + message(STATUS "Added module test includes to unit_tests target") +endif() + +# Link modules library to tests so module code is available +if(TARGET modules) + target_link_libraries(unit_tests modules) +endif() + add_test( NAME unit From 61750665dfa4f3226f1a4e82af1a5dc953f098b3 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 16 Feb 2026 11:07:28 -0300 Subject: [PATCH 144/335] chore(Core/Player): Improve one arena team log (#24730) --- src/server/game/Entities/Player/PlayerStorage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 213c3dbd9..843d1118e 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -4865,7 +4865,7 @@ void Player::_LoadArenaTeamInfo() ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId); if (!arenaTeam) { - LOG_ERROR("bg.arena", "Player::_LoadArenaTeamInfo: No arena team was found."); + LOG_ERROR("bg.arena", "Player::_LoadArenaTeamInfo: Team with ID {} not found.", arenaTeamId); continue; } ArenaTeamMember const* member = arenaTeam->GetMember(GetGUID()); From 2ed3d0bc213bf42b252fdfd4d6c9e922fb48ea5e Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Mon, 16 Feb 2026 09:27:23 -0600 Subject: [PATCH 145/335] fix(Core/Arena): Fix inverted OnBeforeArenaTeamMemberUpdate hook (#24734) Co-authored-by: blinkysc --- src/server/game/Battlegrounds/Arena.cpp | 4 +- .../Battlegrounds/ArenaHookDefaultsTest.cpp | 129 ++++++++++++++++++ 2 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 src/test/server/game/Battlegrounds/ArenaHookDefaultsTest.cpp diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp index cc24d9418..a3dc1432e 100644 --- a/src/server/game/Battlegrounds/Arena.cpp +++ b/src/server/game/Battlegrounds/Arena.cpp @@ -353,13 +353,13 @@ void Arena::EndBattleground(TeamId winnerTeamId) if (GetArenaType() == ARENA_TYPE_5v5 && aliveWinners == 1 && player->IsAlive()) player->CastSpell(player, SPELL_LAST_MAN_STANDING, true); - if (!sScriptMgr->OnBeforeArenaTeamMemberUpdate(winnerArenaTeam, player, true, loserMatchmakerRating, winnerMatchmakerChange)) + if (sScriptMgr->OnBeforeArenaTeamMemberUpdate(winnerArenaTeam, player, true, loserMatchmakerRating, winnerMatchmakerChange)) winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange); } } else { - if (!sScriptMgr->OnBeforeArenaTeamMemberUpdate(loserArenaTeam, player, false, winnerMatchmakerRating, loserMatchmakerChange)) + if (sScriptMgr->OnBeforeArenaTeamMemberUpdate(loserArenaTeam, player, false, winnerMatchmakerRating, loserMatchmakerChange)) loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange); // Arena lost => reset the win_rated_arena having the "no_lose" condition diff --git a/src/test/server/game/Battlegrounds/ArenaHookDefaultsTest.cpp b/src/test/server/game/Battlegrounds/ArenaHookDefaultsTest.cpp new file mode 100644 index 000000000..e3ceb6299 --- /dev/null +++ b/src/test/server/game/Battlegrounds/ArenaHookDefaultsTest.cpp @@ -0,0 +1,129 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ScriptMgr.h" +#include "ScriptDefines/ArenaScript.h" +#include "ScriptDefines/AllBattlegroundScript.h" +#include "ArenaTeam.h" +#include "ObjectGuid.h" +#include "WorldMock.h" +#include "gtest/gtest.h" + +/** + * Tests that ArenaScript and AllBattlegroundScript hooks return + * safe defaults when no scripts are registered, ensuring core + * game logic (MemberWon/MemberLost, SaveToDB, etc.) is not + * accidentally skipped. + */ +class ArenaHookDefaultsTest : public ::testing::Test +{ +protected: + static void EnsureScriptRegistriesInitialized() + { + static bool initialized = false; + if (!initialized) + { + ScriptRegistry::InitEnabledHooksIfNeeded(ARENAHOOK_END); + ScriptRegistry::InitEnabledHooksIfNeeded(ALLBATTLEGROUNDHOOK_END); + initialized = true; + } + } + + void SetUp() override + { + previousWorld_ = std::move(sWorld); + auto* mock = new ::testing::NiceMock(); + ON_CALL(*mock, getIntConfig(::testing::_)) + .WillByDefault(::testing::Return(0)); + ON_CALL(*mock, getIntConfig(CONFIG_LEGACY_ARENA_START_RATING)) + .WillByDefault(::testing::Return(1500)); + ON_CALL(*mock, getIntConfig(CONFIG_ARENA_START_RATING)) + .WillByDefault(::testing::Return(0)); + sWorld.reset(mock); + + EnsureScriptRegistriesInitialized(); + } + + void TearDown() override + { + sWorld = std::move(previousWorld_); + } + + std::unique_ptr previousWorld_; +}; + +// CanSaveToDB must return true by default so ArenaTeam::SaveToDB +// proceeds to write team and member stats to the database. +TEST_F(ArenaHookDefaultsTest, CanSaveToDBDefaultsTrue) +{ + ArenaTeam team; + EXPECT_TRUE(sScriptMgr->CanSaveToDB(&team)); +} + +// OnBeforeArenaTeamMemberUpdate must return true by default so that +// MemberWon/MemberLost execute. A false return would skip personal +// rating and game count updates for all arena participants. +TEST_F(ArenaHookDefaultsTest, OnBeforeArenaTeamMemberUpdateDefaultsTrue) +{ + ArenaTeam team; + EXPECT_TRUE(sScriptMgr->OnBeforeArenaTeamMemberUpdate(&team, nullptr, true, 1500, 0)); + EXPECT_TRUE(sScriptMgr->OnBeforeArenaTeamMemberUpdate(&team, nullptr, false, 1500, 0)); +} + +// CanSaveArenaStatsForMember must return true by default so that +// character_arena_stats (MMR, MaxMMR) are written to the database. +TEST_F(ArenaHookDefaultsTest, CanSaveArenaStatsForMemberDefaultsTrue) +{ + ArenaTeam team; + EXPECT_TRUE(sScriptMgr->CanSaveArenaStatsForMember(&team, ObjectGuid::Empty)); +} + +// OnBeforeArenaCheckWinConditions must return true by default so +// the normal win condition check proceeds. +TEST_F(ArenaHookDefaultsTest, OnBeforeArenaCheckWinConditionsDefaultsTrue) +{ + EXPECT_TRUE(sScriptMgr->OnBeforeArenaCheckWinConditions(nullptr)); +} + +// CanAddGroupToMatchingPool must return true by default so groups +// are not filtered out of the BG matchmaking pool. +TEST_F(ArenaHookDefaultsTest, CanAddGroupToMatchingPoolDefaultsTrue) +{ + EXPECT_TRUE(sScriptMgr->CanAddGroupToMatchingPool(nullptr, nullptr, 0, nullptr, BattlegroundBracketId(0))); +} + +// Verify the calling convention used in Arena::EndBattleground: +// if (sScriptMgr->OnBeforeArenaTeamMemberUpdate(...)) +// team->MemberWon/MemberLost(...) +// +// The hook returns true when no scripts override it. +// The caller must NOT negate the result, or MemberWon/MemberLost +// will never execute and arena stats will silently stop saving. +TEST_F(ArenaHookDefaultsTest, MemberUpdateCallingConventionAllowsByDefault) +{ + ArenaTeam team; + bool hookResult = sScriptMgr->OnBeforeArenaTeamMemberUpdate( + &team, nullptr, true, 1500, 0); + + // This simulates the condition in Arena::EndBattleground. + // MemberWon must be called when no scripts are registered. + bool memberWonWouldExecute = hookResult; // NOT !hookResult + EXPECT_TRUE(memberWonWouldExecute) + << "MemberWon/MemberLost must execute when no scripts override " + "OnBeforeArenaTeamMemberUpdate. Check Arena.cpp is using " + "if(sScriptMgr->OnBeforeArenaTeamMemberUpdate(...)) without negation."; +} From fd7bde14e7412fed5e09c612f057dc1d23789ab4 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Mon, 16 Feb 2026 12:31:45 -0500 Subject: [PATCH 146/335] fix(Core/Handlers): Remove error message when leaving group in battleground. (#24712) --- src/server/game/Handlers/GroupHandler.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 179a4469a..d3bf30d1f 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -439,11 +439,8 @@ void WorldSession::HandleGroupDisbandOpcode(WorldPacket& /*recvData*/) if (!grp && !grpInvite) return; - if (_player->InBattleground()) - { - SendPartyResult(PARTY_OP_INVITE, "", ERR_INVITE_RESTRICTED); + if (_player->InBattleground()) // Do not leave group, give no error. Verified on TBC Classic return; - } /** error handling **/ /********************/ From b7f1a79acc98557f99d72caa5a7668986a68ca53 Mon Sep 17 00:00:00 2001 From: sogladev Date: Mon, 16 Feb 2026 20:30:21 +0100 Subject: [PATCH 147/335] fix(DB/SAI): update Obsidian Sanctum trash (#24732) Co-authored-by: Aokromes --- .../rev_1771250646133969561.sql | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771250646133969561.sql diff --git a/data/sql/updates/pending_db_world/rev_1771250646133969561.sql b/data/sql/updates/pending_db_world/rev_1771250646133969561.sql new file mode 100644 index 000000000..f11f54df6 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771250646133969561.sql @@ -0,0 +1,60 @@ +-- Onyx Blaze Mistress +-- Updates comments, add Conjure Flame Orb +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 30681); +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 +(30681, 0, 0, 0, 0, 0, 100, 0, 5000, 5000, 12000, 13000, 0, 0, 11, 39529, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Blaze Mistress - In Combat - Cast \'Flame Shock\''), +(30681, 0, 1, 0, 0, 0, 100, 0, 8000, 8000, 19000, 22000, 0, 0, 11, 57757, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Blaze Mistress - In Combat - Cast \'Rain of Fire\''), +(30681, 0, 2, 0, 0, 0, 100, 0, 3000, 11000, 8000, 15000, 0, 0, 11, 57753, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Blaze Mistress - In Combat - Cast \'Conjure Flame Orb\''), +(30681, 0, 3, 0, 8, 0, 100, 0, 57753, 0, 0, 0, 0, 0, 11, 57752, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Blaze Mistress - On Spellhit \'Conjure Flame Orb\' - Cast \'Flame Orb Summon\''); + +-- Onyx Brood General +-- Update comments, add Draconic Rage 25m, text +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 30680); +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 +(30680, 0, 0, 0, 60, 0, 100, 0, 0, 0, 600000, 600000, 0, 0, 11, 57740, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Brood General - On Update - Cast \'Devotion Aura\''), +(30680, 0, 1, 0, 0, 0, 100, 0, 5000, 6000, 7000, 8000, 0, 0, 11, 13737, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Brood General - In Combat - Cast \'Mortal Strike\''), +(30680, 0, 2, 0, 0, 0, 100, 0, 15000, 15000, 40000, 40000, 0, 0, 11, 57733, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Brood General - In Combat - Cast \'Draconic Rage\''), +(30680, 0, 3, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 57742, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Brood General - On Just Died - Cast \'Avenging Fury\''), +(30680, 0, 4, 0, 37, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Brood General - On Initialize - Say Line 0'); + +DELETE FROM `spelldifficulty_dbc` WHERE `ID`=57733; +INSERT INTO `spelldifficulty_dbc` (`ID`, `DifficultySpellID_1`, `DifficultySpellID_2`, `DifficultySpellID_3`, `DifficultySpellID_4`) VALUES +(57733, 57733, 58942, 0, 0); + +DELETE FROM `creature_text` WHERE `CreatureID`=30680; +INSERT INTO `creature_text` (`CreatureID`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextId`) VALUES +(30680, 0, 0, 'Brood Guardians reporting in!', 14, 0, 100, 0, 0, 0, 'Onyx Brood General', 31397); + +-- Onyx Sanctum Guardian +-- use 25m spells, update comments, add text +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 30453); +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 +(30453, 0, 0, 0, 0, 0, 100, 0, 7000, 9000, 17000, 18000, 0, 0, 11, 57728, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Sanctum Guardian - In Combat - Cast \'Shockwave\''), +(30453, 0, 1, 0, 0, 0, 100, 0, 13000, 13000, 30000, 30000, 0, 0, 11, 58948, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Sanctum Guardian - In Combat - Cast \'Curse of Mending\''), +(30453, 0, 2, 3, 12, 0, 100, 0, 25, 30, 5000, 5000, 0, 0, 11, 53801, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Sanctum Guardian - Target Between 25-30% Health - Cast \'Frenzy\''), +(30453, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Sanctum Guardian - Target Between 25-30% Health - Say Line 0'), +(30453, 0, 4, 0, 37, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Onyx Sanctum Guardian - On Initialize - Say Line 1'); + +DELETE FROM `spelldifficulty_dbc` WHERE `ID` IN (58948, 57728); +INSERT INTO `spelldifficulty_dbc` (`ID`, `DifficultySpellID_1`, `DifficultySpellID_2`, `DifficultySpellID_3`, `DifficultySpellID_4`) VALUES +(58948, 58948, 39647, 0, 0), +(57728, 57728, 58947, 0, 0); + +DELETE FROM `creature_text` WHERE `CreatureID`=30453; +INSERT INTO `creature_text` (`CreatureID`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextId`) VALUES +(30453, 0, 0, '%s goes into a frenzy!', 16, 0, 100, 0, 0, 0, 'Onyx Sanctum Guardian', 38630), +(30453, 1, 0, 'Sanctum Guardians reporting in!', 14, 0, 100, 0, 0, 0, 'Onyx Sanctum Guardian', 31398); + +-- Flame Orb +UPDATE `creature_template` SET `minlevel`=80, `maxlevel`=80, `flags_extra` = `flags_extra` | (128 | 64) WHERE `entry`=30702; +DELETE FROM `creature_template_movement` WHERE `CreatureId`=30702; +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`) VALUES +(30702, 1, 0, 1, 0, 0, 0); + +DELETE FROM `spelldifficulty_dbc` WHERE `ID`=57750; +INSERT INTO `spelldifficulty_dbc` (`ID`, `DifficultySpellID_1`, `DifficultySpellID_2`, `DifficultySpellID_3`, `DifficultySpellID_4`) VALUES +(57750, 57750, 58037, 0, 0); + +DELETE FROM `creature_template_addon` WHERE (`entry` = 30702); +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(30702, 0, 0, 0, 0, 0, 0, '57750 55928'); From 67b52c76c238582f7385148eb40b2013b5e5d4bc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Feb 2026 19:31:39 +0000 Subject: [PATCH 148/335] chore(DB): import pending files Referenced commit(s): b7f1a79acc98557f99d72caa5a7668986a68ca53 --- .../rev_1771250646133969561.sql => db_world/2026_02_16_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771250646133969561.sql => db_world/2026_02_16_00.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771250646133969561.sql b/data/sql/updates/db_world/2026_02_16_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771250646133969561.sql rename to data/sql/updates/db_world/2026_02_16_00.sql index f11f54df6..92160f1dd 100644 --- a/data/sql/updates/pending_db_world/rev_1771250646133969561.sql +++ b/data/sql/updates/db_world/2026_02_16_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_15_07 -> 2026_02_16_00 -- Onyx Blaze Mistress -- Updates comments, add Conjure Flame Orb DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 30681); From 9a17604b0388502edb72cd347bd8588ec8facace Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 17 Feb 2026 00:32:51 -0300 Subject: [PATCH 149/335] fix(Scripts/Naxxramas): set Four Horsemen chest respawn timer to 7 days (#24739) --- src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp index b9d4e81e2..c31b2042e 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp @@ -258,7 +258,10 @@ public: if (instance->IsBossDone(BOSS_HORSEMAN)) if (GameObject* chest = me->GetMap()->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->SetRespawnTime(7 * DAY); chest->SetLootRecipient(me); + } } void JustEngagedWith(Unit* who) override From 27feeb9fcfdc0ca6bfa1eb3046196dafdf3fd167 Mon Sep 17 00:00:00 2001 From: sudlud Date: Wed, 18 Feb 2026 06:01:23 +0100 Subject: [PATCH 150/335] fix(DB/Gameobject): Sniffed Values for 'Valentine Arch (x2.00)' spawns (#24742) --- .../pending_db_world/rev_1771360735280100100.sql | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771360735280100100.sql diff --git a/data/sql/updates/pending_db_world/rev_1771360735280100100.sql b/data/sql/updates/pending_db_world/rev_1771360735280100100.sql new file mode 100644 index 000000000..26a49c51e --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771360735280100100.sql @@ -0,0 +1,16 @@ +-- Update gameobject 'Valentine Arch (x2.00)' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (201940)) AND (`guid` IN (242244, 242245, 242246, 242247, 242248, 242249, 242250, 242251)); +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 +(242244, 201940, 1, 0, 0, 1, 1, 1653.5625, -4435.20654296875, 17.64115524291992187, 1.48352813720703125, 0, 0, 0.675589561462402343, 0.737277925014495849, 120, 255, 1, "", 47966, NULL), +(242245, 201940, 1, 0, 0, 1, 1, -1217.9444580078125, 62.78819656372070312, 129.7745819091796875, 3.508116960525512695, 0, 0, -0.98325443267822265, 0.182238012552261352, 120, 255, 1, "", 47966, NULL), +(242246, 201940, 0, 0, 0, 1, 1, 1629.0191650390625, 239.795135498046875, 63.8515167236328125, 6.265733242034912109, 0, 0, -0.00872611999511718, 0.999961912631988525, 120, 255, 1, "", 47966, NULL), +(242247, 201940, 530, 0, 0, 1, 1, 9611.6396484375, -7183.14404296875, 14.28471183776855468, 1.745326757431030273, 0, 0, 0.766043663024902343, 0.642788589000701904, 120, 255, 1, "", 47966, NULL), +(242248, 201940, 1, 0, 0, 1, 1, 9870.7138671875, 2493.632080078125, 1315.87548828125, 5.986480236053466796, 0, 0, -0.14780902862548828, 0.989015936851501464, 120, 255, 1, "", 52237, NULL), +(242249, 201940, 0, 0, 0, 1, 1, -8868.98828125, 637.1007080078125, 95.787139892578125, 0.837757468223571777, 0, 0, 0.406736373901367187, 0.913545548915863037, 120, 255, 1, "", 47966, NULL), +(242250, 201940, 0, 0, 0, 1, 1, -4918.39404296875, -983.5625, 501.45306396484375, 2.268925428390502929, 0, 0, 0.906307220458984375, 0.422619491815567016, 120, 255, 1, "", 48120, NULL), +(242251, 201940, 530, 0, 0, 1, 1, -4005.6494140625, -11844.5849609375, 0.186078995466232299, 4.520402908325195312, 0, 0, -0.77162456512451171, 0.636078238487243652, 120, 255, 1, "", 52237, NULL); + +-- enable all spawns for eventEntry 8 +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 8) AND (`guid` IN (SELECT `guid` FROM `gameobject` WHERE `id` IN (201940))); +INSERT INTO `game_event_gameobject` (SELECT 8, `guid` FROM `gameobject` WHERE `id` IN (201940)); From 65a869ea2744377aab2d3e7e29ea83d2c89ad1ec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 18 Feb 2026 05:02:28 +0000 Subject: [PATCH 151/335] chore(DB): import pending files Referenced commit(s): 27feeb9fcfdc0ca6bfa1eb3046196dafdf3fd167 --- .../rev_1771360735280100100.sql => db_world/2026_02_18_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771360735280100100.sql => db_world/2026_02_18_00.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1771360735280100100.sql b/data/sql/updates/db_world/2026_02_18_00.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1771360735280100100.sql rename to data/sql/updates/db_world/2026_02_18_00.sql index 26a49c51e..4b83f523e 100644 --- a/data/sql/updates/pending_db_world/rev_1771360735280100100.sql +++ b/data/sql/updates/db_world/2026_02_18_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_16_00 -> 2026_02_18_00 -- Update gameobject 'Valentine Arch (x2.00)' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (201940)) AND (`guid` IN (242244, 242245, 242246, 242247, 242248, 242249, 242250, 242251)); From 4599f26ae9cda03394bd6dc5902b946266c65f3a Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Wed, 18 Feb 2026 05:31:53 -0600 Subject: [PATCH 152/335] refactor(Core/Spells): QAston proc system (#24233) Co-authored-by: blinkysc Co-authored-by: QAston Co-authored-by: joschiwald Co-authored-by: ariel- Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Co-authored-by: blinkysc Co-authored-by: Tereneckla Co-authored-by: Andrew <47818697+Nyeriah@users.noreply.github.com> --- data/sql/updates/db_world/2026_01_24_00.sql | 5 - .../rev_1766547838660651694.sql | 1932 ++++++++ .../rev_1769292856469402686.sql | 105 + .../rev_1769396722032747978.sql | 18 + .../rev_1769728867586741519.sql | 31 + .../rev_1769815350392767493.sql | 4 + .../rev_1769974041727457907.sql | 2 + .../rev_1769983684458633094.sql | 8 + src/server/game/Entities/Player/Player.cpp | 105 +- src/server/game/Entities/Player/Player.h | 22 +- src/server/game/Entities/Unit/Unit.cpp | 4338 +---------------- src/server/game/Entities/Unit/Unit.h | 32 +- src/server/game/Handlers/CharacterHandler.cpp | 2 +- .../game/Spells/Auras/SpellAuraEffects.cpp | 165 +- .../game/Spells/Auras/SpellAuraEffects.h | 1 + src/server/game/Spells/Auras/SpellAuras.cpp | 305 +- src/server/game/Spells/Auras/SpellAuras.h | 19 +- src/server/game/Spells/Spell.cpp | 151 +- src/server/game/Spells/Spell.h | 1 + src/server/game/Spells/SpellEffects.cpp | 33 - src/server/game/Spells/SpellInfo.cpp | 1 - .../game/Spells/SpellInfoCorrections.cpp | 16 - src/server/game/Spells/SpellMgr.cpp | 472 +- src/server/game/Spells/SpellMgr.h | 46 +- src/server/game/Spells/SpellScript.cpp | 20 +- src/server/game/Spells/SpellScript.h | 20 +- src/server/game/World/World.cpp | 3 - src/server/scripts/Commands/cs_reload.cpp | 10 - .../BattleForMountHyjal/boss_anetheron.cpp | 30 + .../boss_deathbringer_saurfang.cpp | 23 + .../boss_professor_putricide.cpp | 26 + .../Northrend/Ulduar/Ulduar/boss_xt002.cpp | 34 + .../UtgardeKeep/UtgardeKeep/utgarde_keep.cpp | 39 + .../scripts/Outland/boss_doomlord_kazzak.cpp | 34 +- src/server/scripts/Pet/pet_hunter.cpp | 139 + src/server/scripts/Spells/spell_dk.cpp | 681 ++- src/server/scripts/Spells/spell_druid.cpp | 885 +++- src/server/scripts/Spells/spell_generic.cpp | 395 ++ src/server/scripts/Spells/spell_hunter.cpp | 463 +- src/server/scripts/Spells/spell_item.cpp | 1955 ++++++++ src/server/scripts/Spells/spell_mage.cpp | 714 ++- src/server/scripts/Spells/spell_paladin.cpp | 1171 ++++- src/server/scripts/Spells/spell_priest.cpp | 470 ++ src/server/scripts/Spells/spell_rogue.cpp | 227 + src/server/scripts/Spells/spell_shaman.cpp | 1094 ++++- src/server/scripts/Spells/spell_warlock.cpp | 504 ++ src/server/scripts/Spells/spell_warrior.cpp | 311 +- src/server/shared/SharedDefines.h | 4 +- src/server/shared/enuminfo_SharedDefines.cpp | 4 +- src/test/CMakeLists.txt | 2 +- src/test/mocks/AuraScriptTestFramework.h | 484 ++ src/test/mocks/AuraStub.h | 367 ++ src/test/mocks/DamageHealInfoStub.h | 259 + src/test/mocks/ProcChanceTestHelper.h | 565 +++ src/test/mocks/ProcEventInfoHelper.h | 235 + src/test/mocks/SpellInfoTestHelper.h | 215 + src/test/mocks/UnitStub.h | 244 + .../game/Spells/SpellProcAttributeTest.cpp | 445 ++ .../game/Spells/SpellProcChanceTest.cpp | 317 ++ .../game/Spells/SpellProcChargeTest.cpp | 409 ++ .../game/Spells/SpellProcConditionsTest.cpp | 386 ++ .../game/Spells/SpellProcCooldownTest.cpp | 219 + .../Spells/SpellProcDBCValidationTest.cpp | 369 ++ .../game/Spells/SpellProcDataDrivenTest.cpp | 756 +++ .../Spells/SpellProcDisableEffectsTest.cpp | 275 ++ .../game/Spells/SpellProcEquipmentTest.cpp | 404 ++ .../game/Spells/SpellProcFullCoverageTest.cpp | 458 ++ .../game/Spells/SpellProcIntegrationTest.cpp | 565 +++ .../game/Spells/SpellProcPPMModifierTest.cpp | 399 ++ .../server/game/Spells/SpellProcPPMTest.cpp | 377 ++ .../game/Spells/SpellProcPipelineTest.cpp | 462 ++ .../Spells/SpellProcSpellTypeMaskTest.cpp | 226 + src/test/server/game/Spells/SpellProcTest.cpp | 903 ++++ .../server/game/Spells/SpellProcTestData.h | 1020 ++++ .../Spells/SpellProcTriggeredFilterTest.cpp | 391 ++ .../Spells/SpellScriptMissileBarrageTest.cpp | 274 ++ 76 files changed, 22915 insertions(+), 5181 deletions(-) delete mode 100644 data/sql/updates/db_world/2026_01_24_00.sql create mode 100644 data/sql/updates/pending_db_world/rev_1766547838660651694.sql create mode 100644 data/sql/updates/pending_db_world/rev_1769292856469402686.sql create mode 100644 data/sql/updates/pending_db_world/rev_1769396722032747978.sql create mode 100644 data/sql/updates/pending_db_world/rev_1769728867586741519.sql create mode 100644 data/sql/updates/pending_db_world/rev_1769815350392767493.sql create mode 100644 data/sql/updates/pending_db_world/rev_1769974041727457907.sql create mode 100644 data/sql/updates/pending_db_world/rev_1769983684458633094.sql create mode 100644 src/test/mocks/AuraScriptTestFramework.h create mode 100644 src/test/mocks/AuraStub.h create mode 100644 src/test/mocks/DamageHealInfoStub.h create mode 100644 src/test/mocks/ProcChanceTestHelper.h create mode 100644 src/test/mocks/ProcEventInfoHelper.h create mode 100644 src/test/mocks/SpellInfoTestHelper.h create mode 100644 src/test/mocks/UnitStub.h create mode 100644 src/test/server/game/Spells/SpellProcAttributeTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcChanceTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcChargeTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcConditionsTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcCooldownTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcDBCValidationTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcDataDrivenTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcDisableEffectsTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcEquipmentTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcFullCoverageTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcIntegrationTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcPPMModifierTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcPPMTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcPipelineTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcSpellTypeMaskTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcTest.cpp create mode 100644 src/test/server/game/Spells/SpellProcTestData.h create mode 100644 src/test/server/game/Spells/SpellProcTriggeredFilterTest.cpp create mode 100644 src/test/server/game/Spells/SpellScriptMissileBarrageTest.cpp diff --git a/data/sql/updates/db_world/2026_01_24_00.sql b/data/sql/updates/db_world/2026_01_24_00.sql deleted file mode 100644 index 067005d15..000000000 --- a/data/sql/updates/db_world/2026_01_24_00.sql +++ /dev/null @@ -1,5 +0,0 @@ --- DB update 2026_01_23_03 -> 2026_01_24_00 --- -DELETE FROM `spell_proc_event` WHERE `entry` = -49182; -INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `procPhase`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES -(-49182, 0, 15, 0, 0, 0, 0, 0, 1, 0, 0, 0); diff --git a/data/sql/updates/pending_db_world/rev_1766547838660651694.sql b/data/sql/updates/pending_db_world/rev_1766547838660651694.sql new file mode 100644 index 000000000..0fe6f5bbe --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1766547838660651694.sql @@ -0,0 +1,1932 @@ +-- QAston Proc System - Base spell_proc entries +-- Port from TrinityCore QAston proc system commits + +-- Add DisableEffectsMask column to spell_proc table if it doesn't exist +SET @column_exists = (SELECT 1 FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'spell_proc' AND `COLUMN_NAME` = 'DisableEffectsMask' LIMIT 1); +SET @sql = IF(@column_exists IS NULL, 'ALTER TABLE `spell_proc` ADD COLUMN `DisableEffectsMask` INT UNSIGNED NOT NULL DEFAULT 0 AFTER `AttributesMask`', 'SELECT 1'); +PREPARE stmt FROM @sql; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +-- Charge drop on spell cast +DELETE FROM `spell_proc` WHERE `SpellId` IN (17941, 18820, 22008, 28200, 32216, 34477, 34936, 44401, 48108, 51124, 54741, 57761, 64823); +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +(17941, 0, 5, 0x00000001, 0x00000000, 0x00000000, 65536, 0x1, 0x1, 0, 0x0, 0, 0, 0, 1), -- Shadow Trance +(18820, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x7, 0x1, 0, 0x0, 0, 0, 0, 1), -- Insight +(22008, 0, 3, 0x61400035, 0x00000000, 0x00000000, 69632, 0x5, 0x1, 0, 0x0, 0, 0, 0, 1), -- Netherwind Focus +(28200, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x3, 0x1, 0, 0x0, 0, 0, 0, 6), -- Ascendance +(32216, 0, 4, 0x00000000, 0x00000100, 0x00000000, 16, 0x1, 0x4, 0, 0x0, 0, 0, 0, 1), -- Victorious (drop charge on Victory rush cast) +(34477, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x5, 0x2, 0, 0x0, 0, 0, 0, 1), -- Misdirection +(34936, 0, 5, 0x00000001, 0x00000040, 0x00000000, 65536, 0x1, 0x1, 0, 0x8, 0, 0, 0, 1), -- Backlash +(44401, 0, 3, 0x00000800, 0x00000000, 0x00000000, 4096, 0x5, 0x1, 0, 0x8, 0, 0, 0, 1), -- Missile Barrage +(48108, 0, 3, 0x00400000, 0x00000000, 0x00000000, 65536, 0x1, 0x1, 0, 0x8, 0, 0, 0, 1), -- Hot Streak +(51124, 0, 15, 0x00000002, 0x00000006, 0x00000000, 65552, 0x1, 0x2, 0, 0x8, 0, 0, 0, 1), -- Killing Machine +(54741, 0, 3, 0x00000004, 0x00000000, 0x00000000, 65536, 0x5, 0x1, 0, 0x0, 0, 0, 0, 1), -- Firestarter +(57761, 0, 3, 0x00000001, 0x00001000, 0x00000000, 65536, 0x1, 0x1, 0, 0x8, 0, 0, 0, 1), -- Fireball! +(64823, 0, 7, 0x00000004, 0x00000000, 0x00000000, 65536, 0x1, 0x1, 0, 0x0, 0, 0, 0, 1); -- Elune's Wrath +-- Port procs from spell_proc_event table +DELETE FROM `spell_proc` WHERE `SpellId` IN (-974, -1463, -10400, -11119, -11185, -12834, -13983, -14156, -15337, -16180, -18094, -18213, -20234, -20335, -27243, -29441, -29723, -29834, -30293, -30675, -31244, -31571, -31656, -31785, -31871, -31876, -34497, -34914, -44404, -44445, -44546, -46913, -46951, -47569, -48539, -48979, -49015, -49018, -49182, -49188, -49208, -49217, -49467, -51459, -51474, -51525, -51556, -51625, -51627, -51664, -53178, -53228, -53290, -53380, -53501, -53569, -53695, -54639, -54747, -59088, -61680, -62764, -63156, -63373, -64127, -65661, 1719, 11129, 12536, 15286, 16246, 16864, 16870, 17619, 20185, 20186, 22007, 24658, 24932, 26169, 26467, 28716, 28719, 28744, 28789, 28809, 28823, 28845, 28847, 28849, 29601, 32863, 36123, 38252, 39367, 44141, 70388, 30823, 31801, 32409, 33757, 37288, 37295, 37381, 37377, 39437, 37168, 37594, 38164, 39372, 40438, 40442, 40463, 40470, 40971, 42770, 45057, 46916, 47383, 71162, 71165, 49005, 49028, 49194, 49222, 49796, 51209, 51528, 51529, 51530, 51531, 51532, 51698, 51700, 51701, 52420, 52437, 53601, 53646, 53736, 54274, 54276, 54277, 54748, 54754, 54815, 54821, 54832, 54845, 54909, 54937, 54939, 55198, 55440, 55677, 56218, 56372, 56374, 56375, 56800, 57870, 58375, 58642, 58677, 58877, 59906, 59915, 37447, 61062, 61257, 62259, 62600, 62606, 63279, 63280, 63320, 64890, 64928, 65032, 67228, 69755, 69739, 69762, 70723, 70664, 70770, 70805, 70808, 70817, 70844, 70672, 72455, 72832, 72833, 71756, 72782, 72783, 72784, 71406, 71545, 71880, 71892, 71519, 71562, 71564, 71634, 71640, 71761, 71770, 72176, 75475, 75481); +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +(-974, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x2, 0, 0, 3000, 0), -- Earth Shield +(-1463, 0, 3, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 1024, 0x0, 0, 0, 0, 0), -- Mana Shield +(-10400, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Flametongue Weapon (Passive) +(-11119, 4, 3, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Ignite +(-11185, 0, 3, 0x00000080, 0x00000000, 0x00000000, 65536, 0x1, 0x2, 0, 0x2, 0, 0, 0, 0), -- Improved Blizzard +(-12834, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Deep Wounds Aura +(-13983, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 24, 0x0, 0, 0, 1000, 0), -- Setup +(-14156, 0, 8, 0x003E0000, 0x00000009, 0x00000000, 0, 0x0, 0x4, 0, 0x0, 0, 0, 0, 0), -- Ruthlessness +(-15337, 0, 6, 0x00802000, 0x00000002, 0x00000000, 0, 0x1, 0x2, 2, 0x2, 0, 0, 0, 0), -- Improved Spirit Tap +(-16180, 0, 11, 0x000001C0, 0x00000000, 0x00000010, 0, 0x2, 0x2, 2, 0x0, 0, 0, 0, 0), -- Improved Water Shield +(-18094, 0, 5, 0x0000000A, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Nightfall +(-18213, 32, 5, 0x00004000, 0x00000000, 0x00000000, 2, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Improved Drain Soul +(-20234, 0, 10, 0x00008000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Lay on Hands +(-20335, 0, 10, 0x00800000, 0x00000000, 0x00000000, 16, 0x5, 0x2, 0, 0x0, 0, 100, 0, 0), -- Heart of the Crusader +(-27243, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Seed of corruption (Warlock) +(-29441, 0, 3, 0x00000000, 0x00000000, 0x00000000, 0, 0x7, 0x0, 8, 0x0, 0, 0, 1000, 0), -- Magic Absorption +(-29723, 0, 4, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Sudden Death +(-29834, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x5, 0x0, 0, 0x0, 0, 0, 0, 0), -- Second Wind (Warrior talent) +(-30293, 0, 5, 0x00000181, 0x008200C0, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Soul Leech +(-30675, 0, 11, 0x00000003, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Lightning Overload +(-31244, 0, 8, 0x003A0000, 0x00000009, 0x00000000, 0, 0x5, 0x2, 11196, 0x0, 0, 0, 0, 0), -- Quick Recovery +(-31571, 0, 3, 0x00000000, 0x00000022, 0x00000008, 16384, 0x7, 0x4, 0, 0x0, 0, 0, 0, 0), -- Arcane Potency +(-31656, 4, 3, 0x08000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Empowered Fire +(-31785, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0), -- Spiritual Attunement +(-31871, 0, 10, 0x00000010, 0x00000000, 0x00000000, 16384, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Divine Purpose +(-31876, 0, 10, 0x00800000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Judgements of the Wise +(-34497, 0, 9, 0x00060800, 0x00800001, 0x00000201, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Thrill of the Hunt +(-34914, 0, 6, 0x00002000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Vampiric Touch +(-44404, 0, 3, 0x20000021, 0x00009000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Missile Barrage +(-44445, 0, 3, 0x00000013, 0x00011000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Hot Streak +(-44546, 0, 3, 0x000002E0, 0x00001000, 0x00000000, 69632, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Brain Freeze +(-46913, 0, 4, 0x00000040, 0x00000404, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Bloodsurge +(-46951, 0, 4, 0x00000400, 0x00000040, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Sword and Board +(-47569, 0, 6, 0x00004000, 0x00000000, 0x00000000, 16384, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Shadowform +(-48539, 0, 7, 0x00000010, 0x04000000, 0x00000000, 262144, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0), -- Revitalize +(-48979, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 0, 0), -- Butchery +(-49015, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 0, 0), -- Vendetta +(-49018, 0, 15, 0x01400000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Sudden Doom +(-49182, 0, 15, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Blade Barrier +(-49188, 0, 15, 0x00000000, 0x00020000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Rime +(-49208, 0, 15, 0x00400000, 0x00010000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Reaping +(-49217, 0, 15, 0x00000000, 0x00000000, 0x00000002, 0, 0x0, 0x0, 0, 0x0, 0, 0, 1000, 0), -- Wandering Plague +(-49467, 0, 15, 0x00000010, 0x00020000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Death Rune Mastery +(-51459, 0, 0, 0x00000000, 0x00000000, 0x00000000, 4, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Necrosis +(-51474, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Astral Shift +(-51525, 0, 11, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0 ,0x0, 0, 0, 0, 0), -- Static Shock +(-51556, 0, 11, 0x000000C0, 0x00000000, 0x00000010, 0, 0x2, 0x2, 2, 0x0, 0, 0, 0, 0), -- Ancestral Awakening +(-51625, 0, 8, 0x1000A000, 0x00000000, 0x00000000, 0, 0x5, 0x2, 0, 0x0, 0, 0, 0, 0), -- Deadly Brew +(-51627, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 112, 0x0, 0, 0, 0, 0), -- Turn the Tables +(-51664, 0, 8, 0x00020000, 0x00000008, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Cut to the Chase +(-53178, 0, 9, 0x00000000, 0x10000000, 0x00000000, 65536, 0x4, 0x2, 0, 0x0, 0, 100, 0, 0), -- Guard Dog +(-53228, 0, 9, 0x00000020, 0x01000000, 0x00000000, 0, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Rapid Recuperation +(-53290, 0, 9, 0x00000800, 0x00000001, 0x00000200, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Hunting Party +(-53380, 0, 10, 0x00800000, 0x00028000, 0x00000000, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Righteous Vengeance +(-53501, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 2, 0x0, 0, 0, 0, 0), -- Sheath of Light +(-53569, 0, 10, 0x40200000, 0x00010000, 0x00000000, 0, 0x3, 0x2, 0, 0x0, 0, 0, 0, 0), -- Infusion of Light +(-53695, 0, 10, 0x00800000, 0x00000000, 0x00000008, 16, 0x5, 0x2, 0, 0x2, 0, 0, 0, 0), -- Judgements of the Just +(-54639, 0, 15, 0x00400000, 0x00010000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Blood of the North +(-54747, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Burning Determination +(-59088, 0, 4, 0x00000000, 0x00000002, 0x00000000, 1024, 0x4, 0x4, 0, 0x0, 0, 0, 0, 0), -- Improved Spell Reflection +(-61680, 0, 9, 0x00000000, 0x10000000, 0x00000000, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Culling the Herd +(-62764, 0, 9, 0x00000000, 0x10000000, 0x00000000, 65536, 0x4, 0x2, 0, 0x0, 0, 100, 0, 0), -- Silverback +(-63156, 0, 5, 0x00000001, 0x000000C0, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Decimation +(-63373, 0, 11, 0x80000000, 0x00000000, 0x00000000, 65536, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Frozen Power +(-64127, 0, 6, 0x00000001, 0x00000001, 0x00000000, 0, 0x6, 0x2, 0, 0x0, 0, 0, 0, 0), -- Body and Soul +(-65661, 0, 15, 0x00400011, 0x20020004, 0x00000000, 16, 0x1, 0x2, 0, 0x0, 0, 100, 0, 0), -- Threat of Thassarian + +(1719, 0, 4, 0x2E600444, 0x00404745, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Recklessness +(11129, 4, 3, 0x08C00017, 0x00031048, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Combustion +(12536, 0, 3, 0x20C21AF7, 0x00029040, 0x00000000, 0, 0x0, 0x1, 0, 0x4, 0, 0, 0, 0), -- Clearcasting (Mage) +(15286, 32, 6, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Vampiric Embrace +(16246, 0, 11, 0x981001C3, 0x00001400, 0x00000010, 0, 0x0, 0x1, 0, 0x4, 0, 0, 0, 0), -- Clearcasting (Shaman) +(16864, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3.5, 0, 0, 0), -- Omen of Clarity +(16870, 0, 7, 0x00E3BBFF, 0x079007D3, 0x00040400, 0, 0x0, 0x1, 0, 0x4, 0, 0, 0, 0), -- Clearcasting (Druid) +(17619, 0, 13, 0x00000000, 0x00000000, 0x00000000, 32768, 0x7, 0x0, 0, 0x0, 0, 0, 0, 0), -- Alchemist's Stone +(20185, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 15, 0, 0, 0), -- Judgement of Light +(20186, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 15, 0, 0, 0), -- Judgement of Wisdom +(22007, 0, 3, 0x00200021, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Netherwind Focus +(24658, 0, 0, 0x00000000, 0x00000000, 0x00000000, 87376, 0x7, 0x2, 0, 0x0, 0, 0, 0, 0), -- Unstable Power +(24932, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Leader of the Pack +(26169, 0, 6, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Oracle Healing Bonus +(26467, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Persistent Shield +(28716, 0, 7, 0x00000010, 0x00000000, 0x00000000, 262144, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0), -- Rejuvenation - Dreamwalker Raiment 2pc +(28719, 0, 7, 0x00000020, 0x00000000, 0x00000000, 0, 0x2, 0x2, 2, 0x0, 0, 0, 0, 0), -- Healing Touch - Dreamwalker Raiment 8 pc +(28744, 0, 7, 0x00000040, 0x00000000, 0x00000000, 278528, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Regrowth - Dreamwalker Raiment 6pc +(28789, 0, 10, 0xC0000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Holy Power +(28809, 0, 6, 0x00001000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 2, 0x0, 0, 0, 0, 0), -- Greater Heal - Vestments of Faith 4pc +(28823, 0, 11, 0x000000C0, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Totemic Power +(28845, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Cheat Death +(28847, 0, 7, 0x00000020, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Healing Touch Refund +(28849, 0, 11, 0x00000080, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Lesser Heealing Wave +(29601, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x4, 0, 0, 0, 0), -- Enlightenment + +(32863, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Seed of Corruption (Monster) +(36123, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Seed of Corruption (Monster) +(38252, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Seed of Corruption (Monster) +(39367, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Seed of Corruption (Monster) +(44141, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Seed of Corruption (Monster) +(70388, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Seed of Corruption (Monster) + +(30823, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 18, 0, 0, 0), -- Shamanistic Rage (AC #17499) +(31801, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x2, 0, 0, 0, 0), -- Seal of Vengeance +(32409, 0, 0, 0x00000000, 0x00002000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Shadow Word: Death - do not require honor target +(33757, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 3000, 0), -- Windfury Weapon (Passive) +(37288, 0, 7, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Mana Restore - Malorne Raiment 2pc +(37295, 0, 7, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Mana Restore - Malorne Regalia 2pc +(37381, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Pet Healing + +(37377, 32, 5, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Shadowflame +(39437, 4, 5, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Shadowflame Hellfire and RoF + +(37168, 0, 8, 0x003E0000, 0x00000009, 0x00000000, 0, 0x0, 0x4, 0, 0x0, 0, 0, 0, 0), -- Finisher Combo +(37594, 0, 6, 0x00001000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Greater Heal Refund +(38164, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Unyielding Knights +(39372, 48, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Frozen Shadoweave +(40438, 0, 6, 0x00008040, 0x00000000, 0x00000000, 0, 0x3, 0x0, 0, 0x0, 0, 0, 0, 0), -- Priest Tier 6 Trinket +(40442, 0, 7, 0x00000014, 0x00000440, 0x00000000, 0, 0x7, 0x1, 0, 0x0, 0, 0, 0, 0), -- Druid Tier 6 Trinket +(40463, 0, 11, 0x00000081, 0x00000010, 0x00000000, 0, 0x3, 0x2, 0, 0x0, 0, 0, 0, 0), -- Shaman Tier 6 Trinket +(40470, 0, 10, 0xC0800000, 0x00000000, 0x00000000, 0, 0x3, 0x2, 0, 0x0, 0, 0, 0, 0), -- Paladin Tier 6 Trinket +(40971, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Bonus Healing (Crystal Spire of Karabor) +(42770, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x5, 0x0, 0, 0x0, 0, 0, 0, 0), -- Second Wind (NPC aura) +(45057, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 30000, 0), -- Evasive Maneuvers +(46916, 0, 4, 0x00200000, 0x00000000, 0x00000000, 0, 0x0, 0x4, 0, 0x0, 0, 0, 0, 0), -- Slam! (Bloodsurge proc) + +(47383, 0, 5, 0x00000000, 0x000000C0, 0x00000000, 0, 0x0, 0x1, 0, 0x8, 0, 0, 0, 0), -- Molten Core +(71162, 0, 5, 0x00000000, 0x000000C0, 0x00000000, 0, 0x0, 0x1, 0, 0x8, 0, 0, 0, 0), -- Molten Core +(71165, 0, 5, 0x00000000, 0x000000C0, 0x00000000, 0, 0x0, 0x1, 0, 0x8, 0, 0, 0, 0), -- Molten Core + +(49005, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Mark of Blood +(49028, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x5, 0x2, 0, 0x0, 0, 0, 0, 0), -- Dancing Rune Weapon +(49194, 0, 15, 0x00000000, 0x00000000, 0x00000001, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Unholy Blight +(49222, 0, 0, 0x00000000, 0x00000000, 0x00000000, 139944, 0x0, 0x0, 0, 0x0, 0, 0, 2000, 0), -- Bone Shield +(49796, 0, 15, 0x00000002, 0x00020006, 0x00000000, 0, 0x0, 0x1, 0, 0x8, 0, 0, 0, 0), -- Deathchill +(51209, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Hungering Cold + +(51528, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 4, 0, 0, 0), -- Maelstrom Weapon (Rank 1) +(51529, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 8, 0, 0, 0), -- Maelstrom Weapon (Rank 2) +(51530, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 12, 0, 0, 0), -- Maelstrom Weapon (Rank 3) +(51531, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 16, 0, 0, 0), -- Maelstrom Weapon (Rank 4) +(51532, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 20, 0, 0, 0), -- Maelstrom Weapon (Rank 5) + +(51698, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x3, 0x2, 2, 0x0, 0, 33, 0, 0), -- Honor Among Thieves (Rank 1) +(51700, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x3, 0x2, 2, 0x0, 0, 66, 0, 0), -- Honor Among Thieves (Rank 2) +(51701, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x3, 0x2, 2, 0x0, 0, 100, 0, 0), -- Honor Among Thieves (Rank 3) + +(52420, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 30000, 0), -- Deflection +(52437, 1, 4, 0x20000000, 0x00000000, 0x00000000, 16, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Sudden Death proc +(53601, 0, 0, 0x00000000, 0x00000000, 0x00000000, 1048576, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Sacred Shield +(53646, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Demonic Pact +(53736, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x2, 0, 0, 0, 0), -- Seal of Corruption + +(54274, 0, 5, 0x00000165, 0x000310C0, 0x00000000, 0, 0x0, 0x1, 0, 0x8, 0, 0, 0, 0), -- Backdraft +(54276, 0, 5, 0x00000165, 0x000310C0, 0x00000000, 0, 0x0, 0x1, 0, 0x8, 0, 0, 0, 0), -- Backdraft +(54277, 0, 5, 0x00000165, 0x000310C0, 0x00000000, 0, 0x0, 0x1, 0, 0x8, 0, 0, 0, 0), -- Backdraft + +(54748, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 259, 0x0, 0, 0, 0, 0), -- Burning Determination proc +(54754, 0, 7, 0x00000010, 0x00000000, 0x00000000, 0, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0), -- Glyph of Rejuvenation +(54815, 0, 7, 0x00008000, 0x00000000, 0x00000000, 16, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Shred +(54821, 0, 7, 0x00001000, 0x00000000, 0x00000000, 16, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Rake +(54832, 0, 7, 0x00000000, 0x00001000, 0x00000000, 16384, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Innervate +(54845, 0, 7, 0x00000004, 0x00000000, 0x00000000, 65536, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Starfire +(54909, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Demonic Pact +(54937, 0, 10, 0x80000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Holy Light +(54939, 0, 10, 0x00008000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Divinity +(55198, 0, 11, 0x000001C0, 0x00000000, 0x00000000, 16384, 0x2, 0x2, 2, 0x0, 0, 0, 0, 3), -- Tidal Force +(55440, 0, 11, 0x00000040, 0x00000000, 0x00000000, 0, 0x2, 0x1, 0, 0x0, 0, 0, 0, 0), -- Glyph of Healing Wave +(55677, 0, 6, 0x00000000, 0x00000001, 0x00000000, 0, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Dispel Magic +(56218, 0, 5, 0x00000002, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Glyph of Corruption +(56372, 0, 3, 0x00000000, 0x00000080, 0x00000000, 16384, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Ice Block +(56374, 0, 3, 0x00000000, 0x00004000, 0x00000008, 16384, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Icy Veins +(56375, 0, 3, 0x01000000, 0x00000000, 0x00000000, 65536, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Polymorph +(56800, 0, 8, 0x00000004, 0x00000000, 0x00000000, 16, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Backstab +(57870, 0, 9, 0x00800000, 0x00000000, 0x00000000, 262144, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0), -- Glyph of Mend Pet +(58375, 0, 4, 0x00000000, 0x00000200, 0x00000000, 16, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Blocking +(58642, 0, 15, 0x00000000, 0x08000000, 0x00000000, 16, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Scourge Strike +(58677, 0, 15, 0x00002000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x2, 0, 0, 0, 0), -- Glyph of Death's Embrace +(58877, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Spirit Hunt +(59906, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 0, 0), -- Swift Hand of Justice +(59915, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Discerning Eye of the Beast + +(37447, 0, 3, 0x00000000, 0x00000100, 0x00000000, 16384, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Mana Gems +(61062, 0, 3, 0x00000000, 0x00000100, 0x00000000, 16384, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Mana Gems + +(61257, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x5, 0x0, 0, 0x0, 0, 0, 0, 0), -- Runic Power Back on Snare/Root +(62259, 0, 15, 0x02000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 0, 0), -- Glyph of Death Grip +(62600, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Savage Defense (Passive) +(62606, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 1027, 0x0, 0, 0, 0, 0), -- Savage Defense +(63279, 0, 11, 0x00000000, 0x00000400, 0x00000000, 0, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Earth Shield +(63280, 0, 11, 0x20000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Totem of Wrath +(63320, 0, 5, 0x80040000, 0x00000000, 0x00008000, 1024, 0x7, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Life Tap +(64890, 0, 10, 0x00000000, 0x00010000, 0x00000000, 0, 0x2, 0x2, 2, 0x0, 0, 0, 0, 0), -- Item - Paladin T8 Holy 2P Bonus +(64928, 0, 11, 0x00000001, 0x00000000, 0x00000000, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Item - Shaman T8 Elemental 4P Bonus +(65032, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- 321-Boombot Aura - do not require experience target +(67228, 0, 11, 0x00000000, 0x00001000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Shaman T9 Elemental 4P Bonus (Lava Burst) +(69755, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x7, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Purified Shard of the Scale +(69739, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x7, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Shiny Shard of the Scale +(69762, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Unchained Magic +(70723, 0, 7, 0x00000005, 0x00000000, 0x00000000, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Item - Druid T10 Balance 4P Bonus +(70664, 0, 7, 0x00000010, 0x00000000, 0x00000000, 0, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0), -- Druid T10 Restoration 4P Bonus (Rejuvenation) +(70770, 0, 6, 0x00000800, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Priest T10 Healer 2P Bonus +(70805, 0, 8, 0x00000000, 0x00020000, 0x00000000, 0, 0x4, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Rogue T10 2P Bonus +(70808, 0, 11, 0x00000100, 0x00000000, 0x00000000, 0, 0x2, 0x2, 2, 0x0, 0, 0, 0, 0), -- Item - Shaman T10 Restoration 4P Bonus +(70817, 0, 11, 0x00000000, 0x00001000, 0x00000000, 65536, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Shaman T10 Elemental 4P Bonus +(70844, 0, 4, 0x00000100, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Warrior T10 Protection 4P Bonus + +(70672, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Gaseous Bloat +(72455, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Gaseous Bloat +(72832, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Gaseous Bloat +(72833, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Gaseous Bloat + +(71756, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Ball of Flames Proc +(72782, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Ball of Flames Proc +(72783, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Ball of Flames Proc +(72784, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Ball of Flames Proc + +(71406, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 50, 0, 0), -- Anger Capacitor +(71545, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 50, 0, 0), -- Anger Capacitor + +(71880, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 1, 0, 0, 0), -- Item - Icecrown 25 Normal Dagger Proc +(71892, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 1, 0, 0, 0), -- Item - Icecrown 25 Heroic Dagger Proc + +(71519, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 105000, 0), -- Deathbringer's Will +(71562, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 105000, 0), -- Deathbringer's Will (Heroic) +(71564, 126, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x3, 0x2, 2, 0x0, 0, 0, 0, 5), -- Deadly Precision +(71634, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 30000, 0), -- Item - Icecrown 25 Normal Tank Trinket 1 +(71640, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 30000, 0), -- Item - Icecrown 25 Heroic Tank Trinket 1 +(71761, 3, 0, 0x00000000, 0x00100000, 0x00000000, 0, 0x5, 0x2, 256, 0x0, 0, 0, 0, 0), -- Deep Freeze Immunity State +(71770, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Ooze Spell Tank Protection +(72176, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Blood Beast's Blood Link +(75475, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 45000, 0), -- Item - Chamber of Aspects 25 Tank Trinket +(75481, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 45000, 0); -- Item - Chamber of Aspects 25 Heroic Tank Trinket + +-- Add spellscripts to spells previously on giant switches in Unit.cpp +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_rog_t10_2p_bonus'; +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_sha_flametongue_weapon','spell_mage_imp_blizzard','spell_warr_deep_wounds_aura','spell_rog_setup','spell_pri_improved_spirit_tap','spell_sha_imp_water_shield','spell_warl_improved_drain_soul','spell_pal_improved_lay_of_hands','spell_pal_heart_of_the_crusader','spell_warl_seed_of_corruption_dummy','spell_mage_magic_absorption','spell_warr_extra_proc','spell_warr_second_wind','spell_warl_soul_leech','spell_sha_lightning_overload','spell_rog_quick_recovery','spell_mage_arcane_potency','spell_mage_empowered_fire','spell_pal_spiritual_attunement','spell_pal_divine_purpose','spell_pal_judgements_of_the_wise','spell_hun_thrill_of_the_hunt','spell_mage_missile_barrage','spell_mage_hot_streak','spell_warr_sword_and_board','spell_pri_imp_shadowform','spell_dk_butchery','spell_item_unstable_power','spell_item_restless_strength','spell_dru_leader_of_the_pack','spell_pri_aq_3p_bonus','spell_item_persistent_shield','spell_dru_revitalize','spell_dk_death_rune','spell_dk_scent_of_blood_trigger','spell_dk_vendetta','spell_dk_sudden_doom','spell_dk_blade_barrier','spell_dk_rime','spell_dk_wandering_plague','spell_sha_astral_shift_aura','spell_dk_necrosis','spell_sha_static_shock','spell_sha_maelstrom_weapon','spell_sha_ancestral_awakening','spell_rog_deadly_brew','spell_rog_turn_the_tables','spell_rog_cut_to_the_chase','spell_pet_guard_dog','spell_hun_rapid_recuperation_trigger','spell_hun_hunting_party','spell_pal_righteous_vengeance','spell_pal_sheath_of_light','spell_pal_infusion_of_light','spell_pal_judgements_of_the_just','spell_mage_burning_determination','spell_warr_improved_spell_reflection','spell_pet_culling_the_herd','spell_pet_silverback','spell_warl_decimation','spell_sha_frozen_power','spell_pri_body_and_soul','spell_dk_threat_of_thassarian','spell_warl_seduction','spell_mage_combustion','spell_pri_vampiric_embrace','spell_dru_omen_of_clarity','spell_item_alchemists_stone','spell_pal_judgement_of_light_heal','spell_pal_judgement_of_wisdom_mana','spell_twisted_reflection','spell_dru_t3_2p_bonus','spell_dru_t3_8p_bonus','spell_dru_t3_6p_bonus','spell_pal_t3_6p_bonus','spell_pri_t3_4p_bonus','spell_sha_t3_6p_bonus','spell_warr_t3_prot_8p_bonus','spell_item_healing_touch_refund','spell_item_totem_of_flowing_water','spell_item_pendant_of_the_violet_eye','spell_sha_shamanistic_rage','spell_pal_seal_of_vengeance','spell_warl_seed_of_corruption_generic','spell_mark_of_malice','spell_item_mark_of_conquest','spell_sha_windfury_weapon','spell_dru_t4_2p_bonus','spell_pri_t5_heal_2p_bonus','spell_anetheron_vampiric_aura','spell_item_frozen_shadoweave','spell_item_aura_of_madness','spell_pri_item_t6_trinket','spell_dru_item_t6_trinket','spell_sha_item_t6_trinket','spell_pal_item_t6_trinket','spell_item_crystal_spire_of_karabor','spell_item_dementia','spell_item_pet_healing','spell_warl_t4_2p_bonus_shadow','spell_warl_t4_2p_bonus_fire','spell_mage_gen_extra_effects','spell_uk_second_wind','spell_item_commendation_of_kaelthas','spell_item_sunwell_exalted_caster_neck','spell_item_sunwell_exalted_melee_neck','spell_item_sunwell_exalted_tank_neck','spell_item_sunwell_exalted_healer_neck','spell_warl_glyph_of_corruption_nightfall','spell_dk_mark_of_blood','spell_dk_dancing_rune_weapon','spell_dk_unholy_blight','spell_dk_hungering_cold','spell_item_soul_harvesters_charm','spell_rog_turn_the_tables_proc','spell_pal_sacred_shield_dummy','spell_warl_demonic_pact','spell_pal_seal_of_corruption','spell_dru_glyph_of_rejuvenation','spell_dru_glyph_of_shred','spell_dru_glyph_of_rake','spell_dru_glyph_of_innervate','spell_dru_glyph_of_starfire_dummy','spell_pal_glyph_of_holy_light_dummy','spell_pal_glyph_of_divinity','spell_sha_tidal_force_dummy','spell_sha_glyph_of_healing_wave','spell_pri_glyph_of_dispel_magic','spell_mage_glyph_of_ice_block','spell_mage_glyph_of_icy_veins','spell_mage_glyph_of_polymorph','spell_rog_glyph_of_backstab','spell_hun_glyph_of_mend_pet','spell_pri_shadowfiend_death','spell_warr_glyph_of_blocking','spell_dk_glyph_of_scourge_strike','spell_sha_spirit_hunt','spell_hun_kill_command_pet','spell_item_swift_hand_justice_dummy','spell_item_discerning_eye_beast_dummy','spell_mage_imp_mana_gems','spell_gen_vampiric_touch','spell_dk_pvp_4p_bonus','spell_dk_glyph_of_death_grip','spell_dru_savage_defense','spell_sha_glyph_of_earth_shield','spell_sha_glyph_of_totem_of_wrath','spell_warl_glyph_of_life_tap','spell_pal_t8_2p_bonus','spell_sha_t8_elemental_4p_bonus','spell_xt002_321_boombot_aura','spell_sha_t9_elemental_4p_bonus','spell_item_purified_shard_of_the_scale','spell_item_shiny_shard_of_the_scale','spell_dru_t10_balance_4p_bonus','spell_dru_t10_restoration_4p_bonus_dummy','spell_pri_t10_heal_2p_bonus','spell_sha_t10_restoration_4p_bonus','spell_sha_t10_elemental_4p_bonus','spell_warr_item_t10_prot_4p_bonus','spell_item_tiny_abomination_in_a_jar','spell_item_tiny_abomination_in_a_jar_hero','spell_item_deadly_precision_dummy','spell_item_deadly_precision','spell_item_heartpierce','spell_item_heartpierce_hero','spell_item_deathbringers_will_normal','spell_item_deathbringers_will_heroic','spell_item_corpse_tongue_coin','spell_item_corpse_tongue_coin_heroic','spell_putricide_ooze_tank_protection','spell_deathbringer_blood_beast_blood_link','spell_item_petrified_twilight_scale','spell_item_petrified_twilight_scale_heroic','spell_pri_blessed_recovery','spell_mage_blazing_speed','spell_hun_piercing_shots','spell_pal_illumination','spell_rog_overkill','spell_dru_maim_interrupt','spell_gen_petrified_bark','spell_gen_earth_shield_toc','spell_gen_retaliation_toc','spell_gen_overlords_brand','spell_gen_overlords_brand_dot','spell_gen_vampiric_might','spell_gen_mirrored_soul','spell_gen_black_bow_of_the_betrayer','spell_dk_glyph_of_scourge_strike_script'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-10400, 'spell_sha_flametongue_weapon'), +(-11185, 'spell_mage_imp_blizzard'), +(-12834, 'spell_warr_deep_wounds_aura'), +(-13983, 'spell_rog_setup'), +(-15337, 'spell_pri_improved_spirit_tap'), +(-16180, 'spell_sha_imp_water_shield'), +(-18213, 'spell_warl_improved_drain_soul'), +(-20234, 'spell_pal_improved_lay_of_hands'), +(-20335, 'spell_pal_heart_of_the_crusader'), +(-27243, 'spell_warl_seed_of_corruption_dummy'), +(-29441, 'spell_mage_magic_absorption'), + +(-29723, 'spell_warr_extra_proc'), +(-46913, 'spell_warr_extra_proc'), + +(-29834, 'spell_warr_second_wind'), +(-30293, 'spell_warl_soul_leech'), +(-30675, 'spell_sha_lightning_overload'), +(-31244, 'spell_rog_quick_recovery'), +(-31571, 'spell_mage_arcane_potency'), +(-31656, 'spell_mage_empowered_fire'), +(-31785, 'spell_pal_spiritual_attunement'), +(-31871, 'spell_pal_divine_purpose'), +(-31876, 'spell_pal_judgements_of_the_wise'), +(-34497, 'spell_hun_thrill_of_the_hunt'), +(-44404, 'spell_mage_missile_barrage'), +(-44445, 'spell_mage_hot_streak'), +(-46951, 'spell_warr_sword_and_board'), +(-47569, 'spell_pri_imp_shadowform'), +(-48979, 'spell_dk_butchery'), +(-48539, 'spell_dru_revitalize'), + +(-49208, 'spell_dk_death_rune'), +(-49467, 'spell_dk_death_rune'), +(-54639, 'spell_dk_death_rune'), + +(-49004, 'spell_dk_scent_of_blood_trigger'), +(-49015, 'spell_dk_vendetta'), +(-49018, 'spell_dk_sudden_doom'), +(-49182, 'spell_dk_blade_barrier'), +(-49188, 'spell_dk_rime'), +(50526, 'spell_dk_wandering_plague'), -- Damage spell, not talent aura +(-51474, 'spell_sha_astral_shift_aura'), +(-51459, 'spell_dk_necrosis'), +(-51525, 'spell_sha_static_shock'), +(-51556, 'spell_sha_ancestral_awakening'), +(-51625, 'spell_rog_deadly_brew'), +(-51627, 'spell_rog_turn_the_tables'), +(-51664, 'spell_rog_cut_to_the_chase'), +(-53178, 'spell_pet_guard_dog'), +(-53228, 'spell_hun_rapid_recuperation_trigger'), +(-53290, 'spell_hun_hunting_party'), +(-53380, 'spell_pal_righteous_vengeance'), +(-53501, 'spell_pal_sheath_of_light'), +(-53569, 'spell_pal_infusion_of_light'), +(-53695, 'spell_pal_judgements_of_the_just'), +(-54747, 'spell_mage_burning_determination'), +(-59088, 'spell_warr_improved_spell_reflection'), +(-61680, 'spell_pet_culling_the_herd'), +(-62764, 'spell_pet_silverback'), +(-63156, 'spell_warl_decimation'), +(-63373, 'spell_sha_frozen_power'), +(-27811, 'spell_pri_blessed_recovery'), +(-31641, 'spell_mage_blazing_speed'), +(-53234, 'spell_hun_piercing_shots'), +(-20234, 'spell_pal_illumination'), +(58428, 'spell_rog_overkill'), +(44835, 'spell_dru_maim_interrupt'), +(62337, 'spell_gen_petrified_bark'), +(62933, 'spell_gen_petrified_bark'), +(67534, 'spell_gen_earth_shield_toc'), +(65932, 'spell_gen_retaliation_toc'), +(69172, 'spell_gen_overlords_brand'), +(69173, 'spell_gen_overlords_brand_dot'), +(70674, 'spell_gen_vampiric_might'), +(69023, 'spell_gen_mirrored_soul'), +(27522, 'spell_gen_black_bow_of_the_betrayer'), +(40336, 'spell_gen_black_bow_of_the_betrayer'), +(46939, 'spell_gen_black_bow_of_the_betrayer'), +(-64127, 'spell_pri_body_and_soul'), +(-65661, 'spell_dk_threat_of_thassarian'), +(6358, 'spell_warl_seduction'), +(11129, 'spell_mage_combustion'), +(15286, 'spell_pri_vampiric_embrace'), +(16864, 'spell_dru_omen_of_clarity'), +(17619, 'spell_item_alchemists_stone'), +(20185, 'spell_pal_judgement_of_light_heal'), +(20186, 'spell_pal_judgement_of_wisdom_mana'), +(21063, 'spell_twisted_reflection'), +(24658, 'spell_item_unstable_power'), +(24661, 'spell_item_restless_strength'), +(24932, 'spell_dru_leader_of_the_pack'), +(26169, 'spell_pri_aq_3p_bonus'), +(26467, 'spell_item_persistent_shield'), +(28716, 'spell_dru_t3_2p_bonus'), +(28719, 'spell_dru_t3_8p_bonus'), +(28744, 'spell_dru_t3_6p_bonus'), +(28789, 'spell_pal_t3_6p_bonus'), +(28809, 'spell_pri_t3_4p_bonus'), +(28823, 'spell_sha_t3_6p_bonus'), +(28845, 'spell_warr_t3_prot_8p_bonus'), +(28847, 'spell_item_healing_touch_refund'), +(28849, 'spell_item_totem_of_flowing_water'), +(29601, 'spell_item_pendant_of_the_violet_eye'), +(30823, 'spell_sha_shamanistic_rage'), +(31801, 'spell_pal_seal_of_vengeance'), + +(32863, 'spell_warl_seed_of_corruption_generic'), +(36123, 'spell_warl_seed_of_corruption_generic'), +(38252, 'spell_warl_seed_of_corruption_generic'), +(39367, 'spell_warl_seed_of_corruption_generic'), +(44141, 'spell_warl_seed_of_corruption_generic'), +(70388, 'spell_warl_seed_of_corruption_generic'), + +(33493, 'spell_mark_of_malice'), +(33510, 'spell_item_mark_of_conquest'), +(33757, 'spell_sha_windfury_weapon'), +(37288, 'spell_dru_t4_2p_bonus'), +(37295, 'spell_dru_t4_2p_bonus'), +(37594, 'spell_pri_t5_heal_2p_bonus'), +(38196, 'spell_anetheron_vampiric_aura'), +(39372, 'spell_item_frozen_shadoweave'), +(39446, 'spell_item_aura_of_madness'), +(40438, 'spell_pri_item_t6_trinket'), +(40442, 'spell_dru_item_t6_trinket'), +(40463, 'spell_sha_item_t6_trinket'), +(40470, 'spell_pal_item_t6_trinket'), +(40971, 'spell_item_crystal_spire_of_karabor'), +(41404, 'spell_item_dementia'), + +(37381, 'spell_item_pet_healing'), + +(37377, 'spell_warl_t4_2p_bonus_shadow'), +(39437, 'spell_warl_t4_2p_bonus_fire'), +(42770, 'spell_uk_second_wind'), + +(44401, 'spell_mage_gen_extra_effects'), +(48108, 'spell_mage_gen_extra_effects'), +(57761, 'spell_mage_gen_extra_effects'), +(45057, 'spell_item_commendation_of_kaelthas'), +(45481, 'spell_item_sunwell_exalted_caster_neck'), +(45482, 'spell_item_sunwell_exalted_melee_neck'), +(45483, 'spell_item_sunwell_exalted_tank_neck'), +(45484, 'spell_item_sunwell_exalted_healer_neck'), + +(-18094, 'spell_warl_glyph_of_corruption_nightfall'), +(56218, 'spell_warl_glyph_of_corruption_nightfall'), + +(49005, 'spell_dk_mark_of_blood'), +(49028, 'spell_dk_dancing_rune_weapon'), +(49194, 'spell_dk_unholy_blight'), +(51209, 'spell_dk_hungering_cold'), +(52420, 'spell_item_soul_harvesters_charm'), + +(52910, 'spell_rog_turn_the_tables_proc'), +(52914, 'spell_rog_turn_the_tables_proc'), +(52915, 'spell_rog_turn_the_tables_proc'), + +(53601, 'spell_pal_sacred_shield_dummy'), + +(53646, 'spell_warl_demonic_pact'), +(54909, 'spell_warl_demonic_pact'), + +(53736, 'spell_pal_seal_of_corruption'), +(53817, 'spell_sha_maelstrom_weapon'), +(54748, 'spell_mage_burning_determination'), +(54754, 'spell_dru_glyph_of_rejuvenation'), +(54815, 'spell_dru_glyph_of_shred'), +(54821, 'spell_dru_glyph_of_rake'), +(54832, 'spell_dru_glyph_of_innervate'), +(54845, 'spell_dru_glyph_of_starfire_dummy'), +(54937, 'spell_pal_glyph_of_holy_light_dummy'), +(54939, 'spell_pal_glyph_of_divinity'), +(55198, 'spell_sha_tidal_force_dummy'), +(55440, 'spell_sha_glyph_of_healing_wave'), +(55677, 'spell_pri_glyph_of_dispel_magic'), +(56372, 'spell_mage_glyph_of_ice_block'), +(56374, 'spell_mage_glyph_of_icy_veins'), +(56375, 'spell_mage_glyph_of_polymorph'), +(56800, 'spell_rog_glyph_of_backstab'), +(57870, 'spell_hun_glyph_of_mend_pet'), +(57989, 'spell_pri_shadowfiend_death'), +(58375, 'spell_warr_glyph_of_blocking'), +(58642, 'spell_dk_glyph_of_scourge_strike'), +(69961, 'spell_dk_glyph_of_scourge_strike_script'), +(58877, 'spell_sha_spirit_hunt'), +(58914, 'spell_hun_kill_command_pet'), +(59906, 'spell_item_swift_hand_justice_dummy'), +(59915, 'spell_item_discerning_eye_beast_dummy'), + +(37447, 'spell_mage_imp_mana_gems'), +(61062, 'spell_mage_imp_mana_gems'), + +(52723, 'spell_gen_vampiric_touch'), +(60501, 'spell_gen_vampiric_touch'), +(61257, 'spell_dk_pvp_4p_bonus'), +(62259, 'spell_dk_glyph_of_death_grip'), +(62600, 'spell_dru_savage_defense'), +(63279, 'spell_sha_glyph_of_earth_shield'), +(63280, 'spell_sha_glyph_of_totem_of_wrath'), +(63320, 'spell_warl_glyph_of_life_tap'), +(64890, 'spell_pal_t8_2p_bonus'), +(64928, 'spell_sha_t8_elemental_4p_bonus'), +(65032, 'spell_xt002_321_boombot_aura'), +(67228, 'spell_sha_t9_elemental_4p_bonus'), +(69755, 'spell_item_purified_shard_of_the_scale'), +(69739, 'spell_item_shiny_shard_of_the_scale'), +(70723, 'spell_dru_t10_balance_4p_bonus'), +(70664, 'spell_dru_t10_restoration_4p_bonus_dummy'), +(70770, 'spell_pri_t10_heal_2p_bonus'), +(70808, 'spell_sha_t10_restoration_4p_bonus'), +(70817, 'spell_sha_t10_elemental_4p_bonus'), +(70844, 'spell_warr_item_t10_prot_4p_bonus'), + +(71406, 'spell_item_tiny_abomination_in_a_jar'), +(71545, 'spell_item_tiny_abomination_in_a_jar_hero'), + +(71563, 'spell_item_deadly_precision_dummy'), +(71564, 'spell_item_deadly_precision'), + +(71880, 'spell_item_heartpierce'), +(71892, 'spell_item_heartpierce_hero'), + +(71519, 'spell_item_deathbringers_will_normal'), +(71562, 'spell_item_deathbringers_will_heroic'), + +(71634, 'spell_item_corpse_tongue_coin'), +(71640, 'spell_item_corpse_tongue_coin_heroic'), + +(71770, 'spell_putricide_ooze_tank_protection'), +(72176, 'spell_deathbringer_blood_beast_blood_link'), + +(75475, 'spell_item_petrified_twilight_scale'), +(75481, 'spell_item_petrified_twilight_scale_heroic'); + +-- Non scripted auras from `spell_proc_event` +DELETE FROM `spell_proc` WHERE `SpellId` IN (-66799, -63730, -61846, -58872, -57878, -57470, -56636, -56342, -55666, -53709, -53671, -53551, -53527, -53486, -53256, -53234, -53221, -53215, -52795, -52127, -51940, -51692, -51672, -51634, -51562, -51523, -51521, -50880, -49223, -49219, -49149, -49027, -49004, -48988, -48516, -48506, -48496, -48483, -47580, -47516, -47509, -47263, -47258, -47245, -47201, -47195, -46945, -46867, -46854, -45234, -44557, -44449, -44442, -41635, -35541, -35100, -34950, -34935, -34753, -34500, -33881, -33191, -33150, -33142, -33076, -32385, -31833, -31569, -31124, -30881, -30701, -30299, -30160, -29593, -29074, -27811, -20925, -20500, -20210, -20177, -20049, -19572, -19184, -18119, -18096, -17793, -17106, -16958, -16952, -16880, -16487, -16257, -16256, -16176, -14892, -14531, -14186, -13754, -13165, -12966, -12319, -12311, -12298, -12289, -12281, -11255, -11213, -11180, -11095, -9799, -9452, -5952, -324, 6346, 7383, 7434, 8178, 9782, 9784, 12169, 12322, 12999, 13000, 13001, 13002, 13163, 15088, 15128, 15277, 15346, 15600, 16164, 16550, 16620, 16624, 17364, 17495, 20128, 20131, 20132, 20164, 20165, 20166, 20375, 20705, 20784, 20911, 21185, 21882, 21890, 22618, 22648, 23547, 23548, 23551, 23552, 23572, 23578, 23581, 23686, 23688, 23689, 23721, 23920, 24353, 24389, 24905, 25050, 25669, 25899, 26107, 26119, 26128, 26135, 26480, 26605, 27419, 27498, 27521, 27656, 27774, 27787, 28305, 28752, 28802, 28812, 28816, 29150, 29385, 29455, 29501, 29624, 29625, 29626, 29632, 29633, 29634, 29635, 29636, 29637, 29977, 30003, 30937, 31394, 31794, 31904, 32587, 32642, 32734, 32748, 32776, 32777, 32837, 32844, 32885, 33089, 33127, 33297, 33299, 33510, 33648, 33719, 33746, 33759, 33953, 34074, 34080, 34138, 34139, 34258, 34262, 34320, 34355, 34584, 34586, 34598, 34749, 34774, 34783, 34827, 35077, 35080, 35083, 35086, 35121, 36032, 36096, 36111, 36541, 37165, 37170, 37173, 37189, 37193, 37195, 37197, 37213, 37214, 37227, 37237, 37247, 37379, 37384, 37443, 37514, 37516, 37519, 37523, 37528, 37536, 37568, 37600, 37601, 37603, 37655, 37657, 38026, 38031, 38290, 38299, 38326, 38327, 38334, 38347, 38350, 38394, 38857, 39027, 39442, 39443, 39530, 39958, 40407, 40444, 40458, 40475, 40478, 40482, 40485, 40899, 41034, 41260, 41262, 41381, 41393, 41434, 41469, 41989, 42083, 42135, 42136, 42368, 42370, 43443, 43726, 43728, 43737, 43739, 43741, 43745, 43748, 43750, 43819, 44543, 44545, 45054, 45354, 45355, 45469, 45481, 45482, 45483, 45484, 46025, 46092, 46098, 46569, 46662, 46832, 46910, 46911, 47981, 48833, 48835, 48837, 49592, 49622, 50240, 50421, 50781, 51123, 51127, 51128, 51129, 51130, 51346, 51349, 51352, 51359, 51414, 51915, 52020, 52423, 52898, 53386, 53397, 54278, 54646, 54695, 54707, 54738, 54808, 54838, 54841, 54925, 55380, 55381, 55640, 55680, 55681, 55689, 55747, 55768, 55776, 56249, 56355, 56364, 56451, 56816, 56817, 56821, 56841, 57345, 57352, 57907, 57989, 58357, 58364, 58372, 58386, 58442, 58444, 58616, 58620, 58626, 58901, 59176, 59327, 59345, 59630, 59725, 60061, 60063, 60066, 60132, 60170, 60172, 60176, 60221, 60301, 60306, 60317, 60436, 60442, 60473, 60482, 60487, 60490, 60493, 60503, 60519, 60524, 60529, 60537, 60564, 60571, 60572, 60573, 60574, 60575, 60710, 60717, 60719, 60722, 60724, 60726, 60770, 60818, 60826, 61188, 61324, 61356, 61618, 61848, 62114, 62115, 62147, 62459, 63086, 63108, 63251, 63310, 63335, 63611, 64343, 64411, 64415, 64440, 64571, 64714, 64738, 64742, 64752, 64786, 64792, 64824, 64860, 64867, 64882, 64908, 64912, 64914, 64938, 64952, 64955, 64964, 64976, 64999, 65002, 65005, 65007, 65013, 65020, 65025, 66808, 67115, 67151, 67209, 67353, 67356, 67361, 67363, 67365, 67379, 67381, 67384, 67386, 67389, 67392, 67653, 67667, 67670, 67672, 67698, 67702, 67712, 67752, 67758, 67771, 68051, 68160, 70188, 70652, 70727, 70730, 70748, 70756, 70761, 70803, 70807, 70811, 70830, 70841, 70854, 71174, 71176, 71178, 71186, 71191, 71194, 71198, 71214, 71217, 71226, 71228, 71402, 71404, 71540, 71585, 71602, 71606, 71611, 71637, 71642, 71645, 71903, 72413, 72417, 72419, 74396, 75455, 75457, 75465, 75474); +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +(-66799, 0, 15, 0x00400000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Desolation +(-63730, 0, 6, 0x00000800, 0x00000004, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Serendipity +(-61846, 0, 0, 0x00000000, 0x00000000, 0x00000000, 64, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Aspect of the Dragonhawk +(-58872, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 8259, 0x0, 0, 0, 0, 0), -- Damage Shield +(-57878, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 16, 0x0, 0, 0, 0, 0), -- Natural Reaction +(-57470, 0, 6, 0x00000001, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 15000, 0), -- Renewed Hope +(-56636, 0, 4, 0x00000020, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 6000, 0), -- Taste for Blood +(-56342, 0, 9, 0x00000018, 0x08000000, 0x00024000, 0, 0x0, 0x0, 0, 0x2, 0, 0, 0, 0), -- Lock and Load +(-55666, 0, 15, 0x00000001, 0x08000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Desecration +(-53709, 2, 10, 0x00004000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Shield of the Templar +(-53671, 0, 10, 0x00800000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Judgements of the Pure +(-53551, 0, 10, 0x00001000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Sacred Cleansing +(-53527, 1, 10, 0x00000000, 0x00000000, 0x00000004, 1024, 0x0, 0x2, 1, 0x0, 0, 100, 0, 0), -- Divine Guardian +(-53486, 0, 10, 0x00800000, 0x00028000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- The Art of War +(-53256, 0, 9, 0x00000800, 0x00800001, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Cobra Strikes +(-53234, 0, 9, 0x00020000, 0x00000001, 0x00000001, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Piercing Shots +(-53221, 0, 9, 0x00000000, 0x00000001, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Steady Shot +(-53215, 0, 9, 0x00000001, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Wild Quiver +(-52795, 0, 6, 0x00000001, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Borrowed Time +(-52127, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 3000, 0), -- Water Shield +(-51940, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 20, 0, 0), -- Earthliving Weapon (Passive) +(-51692, 0, 8, 0x00000204, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Waylay +(-51672, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 16, 0x0, 0, 0, 1000, 0), -- Unfair Advantage +(-51634, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Focused Attacks +(-51562, 0, 11, 0x00000100, 0x00000000, 0x00000010, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Tidal Waves +(-51523, 0, 11, 0x00000000, 0x00000001, 0x00000000, 65536, 0x0, 0x2, 0, 0x0, 0, 50, 0, 0), -- Earthen Power +(-51521, 0, 11, 0x00000000, 0x01000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Stormstrike +(-50880, 0, 15, 0x00000000, 0x04000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Icy Talons +(-49223, 0, 15, 0x00000011, 0x08020000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Dirge +(-49219, 0, 0, 0x00000000, 0x00000000, 0x00000000, 4, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Blood-Caked Blade +(-49149, 0, 15, 0x00000006, 0x00020002, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Chill of the Grave +(-49027, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 20000, 0), -- Bloodworms +(-49004, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 51, 0x0, 0, 0, 0, 0), -- Scent of Blood +(-48988, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Bloody Vengeance +(-48516, 0, 7, 0x00000005, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Eclipse +(-48506, 0, 7, 0x00000005, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Earth and Moon +(-48496, 0, 7, 0x00000060, 0x02000002, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Living Seed +(-48483, 0, 7, 0x00008800, 0x00000440, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Infected Wounds +(-47580, 0, 6, 0x00000000, 0x00000000, 0x00000040, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Pain and Suffering +(-47516, 0, 6, 0x00001800, 0x00010000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Grace +(-47509, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Divine Aegis +(-47263, 32, 5, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 20000, 0), -- Torture +(-47258, 0, 5, 0x00000000, 0x00800000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Backdraft +(-47245, 0, 5, 0x00000002, 0x00000000, 0x00000000, 262144, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Molten Core +(-47201, 0, 5, 0x00004009, 0x00040000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Everlasting Affliction +(-47195, 0, 5, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Eradication +(-46945, 0, 4, 0x00000000, 0x00010000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Safeguard +(-46867, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Wrecking Crew +(-46854, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Trauma +(-45234, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2, 0x0, 0, 0, 0, 0), -- Focused Will +(-44557, 0, 3, 0x00000020, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Enduring Winter +(-44449, 0, 3, 0x20E21277, 0x00019048, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Burnout +(-44442, 0, 3, 0x00800000, 0x00000040, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 1000, 0), -- Firestarter +(-41635, 0, 0, 0x00000000, 0x00000000, 0x00000000, 664232, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Prayer of Mending +(-35541, 0, 0, 0x00000000, 0x00000000, 0x00000000, 8388608, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Combat Potency +(-35100, 0, 9, 0x00001000, 0x00000000, 0x00000001, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Concussive Barrage +(-34950, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Go for the Throat +(-34935, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 8000, 0), -- Backlash +(-34753, 0, 6, 0x00001800, 0x00000004, 0x00001000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Holy Concentration +(-34500, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Expose Weakness +(-33881, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2, 0x0, 0, 0, 0, 0), -- Natural Perfection +(-33191, 0, 6, 0x00008000, 0x00000400, 0x00000040, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Misery +(-33150, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Surge of Light +(-33142, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2, 0x0, 0, 0, 0, 0), -- Blessed Resilience +(-33076, 0, 0, 0x00000000, 0x00000000, 0x00000000, 664232, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Prayer of Mending +(-32385, 0, 5, 0x00000001, 0x00040000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Shadow Embrace +(-31833, 0, 10, 0x80000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Light's Grace +(-31569, 0, 3, 0x00010000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Blink +(-31124, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Blade Twisting +(-30881, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 30000, 0), -- Nature's Guardian +(-30701, 28, 0, 0x00000000, 0x00000000, 0x00000000, 664232, 0x0, 0x0, 0, 0x0, 0, 100, 0, 0), -- Elemental Absorption +(-30299,126, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Nether Protection +(-30160, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Elemental Devastation +(-29593, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 112, 0x0, 0, 0, 0, 0), -- Improved Defensive Stance +(-29074, 20, 3, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Master of Elements +(-27811, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 2, 0x0, 0, 0, 0, 0), -- Blessed Recovery +(-20925, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Holy Shield +(-20500, 0, 4, 0x10000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Berserker Rage +(-20210, 0, 10, 0xC0000000, 0x00010000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Illumination +(-20177, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Reckoning +(-20049, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Vengeance +(-19572, 0, 9, 0x00800000, 0x00000000, 0x00000000, 262144, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0), -- Improved Mend Pet +(-19184, 0, 9, 0x00000010, 0x00002000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Entrapment +(-18119, 0, 5, 0x00000000, 0x00800000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Aftermath +(-18096, 0, 5, 0x00000100, 0x00800000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Pyroclasm +(-17793, 0, 5, 0x00000001, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Shadow Bolt +(-17106, 0, 7, 0x00080000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Intensity +(-16958, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Primal Fury +(-16952, 0, 7, 0x00039000, 0x00000400, 0x00040000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Blood Frenzy +(-16880, 72, 7, 0x00000067, 0x03800002, 0x00000000, 0, 0x0, 0x3, 2, 0x0, 0, 0, 0, 0), -- Nature's Grace +(-16487, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 2, 0x0, 0, 0, 0, 0), -- Blood Craze +(-16257, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Flurry +(-16256, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Flurry +(-16176, 0, 11, 0x000001C0, 0x00000000, 0x00000010, 0, 0x2, 0x2, 2, 0x0, 0, 0, 0, 0), -- Ancestral Healing +(-14892, 0, 6, 0x10001E00, 0x00010004, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Inspiration +(-14531, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 2, 0x0, 0, 0, 0, 0), -- Martyrdom +(-14186, 0, 8, 0x40800508, 0x00000006, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Seal Fate +(-13754, 0, 8, 0x00000010, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Kick +(-13165, 0, 0, 0x00000000, 0x00000000, 0x00000000, 64, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Aspect of the Hawk +(-12966, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Flurry +(-12319, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Flurry +(-12311, 0, 4, 0x00000800, 0x00000001, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Gag Order +(-12298, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 112, 0x0, 0, 0, 0, 0), -- Shield Specialization +(-12289, 0, 4, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Hamstring +(-12281, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 6000, 0), -- Sword Specialization +(-11255, 0, 3, 0x00004000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Counterspell +(-11213, 0, 3, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Arcane Concentration +(-11180, 16, 3, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Winter's Chill +(-11095, 0, 3, 0x00000010, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Scorch +(-9799, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 2, 0x0, 0, 0, 0, 0), -- Eye for an Eye +(-9452, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 3, 0, 0, 0), -- Vindication +(-5952, 0, 8, 0x00000000, 0x00000001, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Throwing Specialization +(-324, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 3000, 0), -- Lightning Shield +(6346, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 256, 0x0, 0, 0, 0, 0), -- Fear Ward +(7383, 1, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 256, 0x0, 0, 0, 0, 0), -- Water Bubble +(7434, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2, 0x0, 0, 0, 0, 0), -- Fate Rune of Unsurpassed Vigor +(8178, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Grounding Totem Effect +(9782, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Mithril Shield Spike +(9784, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Iron Shield Spike +(12169, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Shield Block +(12322, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 3, 0, 0, 0), -- Unbridled Wrath +(12999, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 6, 0, 0, 0), -- Unbridled Wrath +(13000, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 9, 0, 0, 0), -- Unbridled Wrath +(13001, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 12, 0, 0, 0), -- Unbridled Wrath +(13002, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 15, 0, 0, 0), -- Unbridled Wrath +(13163, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 16, 0x0, 0, 0, 0, 0), -- Aspect of the Monkey +(15088, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2, 0x0, 0, 0, 0, 0), -- Flurry +(15128, 4, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Mark of Flames +(15277, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Seal of Reckoning +(15346, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0), -- Seal of Reckoning +(15600, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 1, 0, 0, 0), -- Hand of Justice +(16164, 28, 0, 0x00000000, 0x00000000, 0x00000000, 65536, 0x0, 0x1, 2, 0x0, 0, 0, 0, 0), -- Elemental Focus (CAST phase for travel-time spells) +(16550, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2, 0x0, 0, 0, 0, 0), -- Bonespike +(16620, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 30000, 0), -- Proc Self Invulnerability +(16624, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Thorium Shield Spike +(17364, 8, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Stormstrike +(17495, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Crest of Retribution +(20128, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Redoubt +(20131, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Redoubt +(20132, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Redoubt +(20164, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 5, 0, 0, 0), -- Seal of Justice +(20165, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 20, 0, 0, 0), -- Seal of Light +(20166, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 12, 0, 0, 0), -- Seal of Wisdom +(20375, 1, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 1000, 0), -- Seal of Command +(20705, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2, 0x0, 0, 0, 0, 0), -- Power Shield 500 +(20784, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Tamed Pet Passive 07 (DND) +(21185, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 10000, 0), -- Spinal Reaper +(21882, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2, 0x0, 0, 0, 0, 0), -- Judgement Smite +(21890, 0, 4, 0x2A764EEF, 0x0000036C, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Warrior's Wrath +(22618, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Force Reactive Disk +(22648, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2, 0x0, 0, 0, 0, 0), -- Call of Eskhandar +(23547, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 32, 0x0, 0, 0, 0, 0), -- Parry +(23548, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Parry +(23551, 0, 11, 0x000000C0, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Lightning Shield +(23552, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 3000, 0), -- Lightning Shield +(23572, 0, 11, 0x000000C0, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Mana Surge +(23578, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 2, 0, 0, 0), -- Expose Weakness +(23581, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 2, 0, 0, 0), -- Bloodfang +(23686, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 2, 0, 0, 0), -- Lightning Strike +(23688, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Aura of the Blue Dragon +(23689, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 4, 0, 0, 0), -- Heroism +(23721, 0, 9, 0x00000800, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Arcane Infused +(23920, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2048, 0x0, 0, 0, 0, 0), -- Spell Reflection +(24353, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Primal Instinct +(24389, 4, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Chaos Fire +(24905, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 15, 0, 0, 0), -- Moonkin Form (Passive) +(25050, 4, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Mark of Flames +(25669, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 1, 0, 0, 0), -- Decapitate +(25899, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 112, 0x0, 0, 0, 0, 0), -- Greater Blessing of Sanctuary +(26107, 0, 7, 0x00800000, 0x10000080, 0x00000000, 0, 0x0, 0x2, 116, 0x0, 0, 0, 0, 0), -- Symbols of Unending Life Finisher Bonus +(26119, 0, 10, 0x90100003, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Stormcaller Spelldamage Bonus +(26128, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 8, 0x0, 0, 0, 0, 0), -- Enigma Resist Bonus +(26135, 0, 10, 0x00800000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x2, 0, 0, 0, 0), -- Battlegear of Eternal Justice +(26480, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 10, 0, 0, 0), -- Badge of the Swarmguard (AC #16777) +(26605, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 2, 0x2, 0, 0, 0, 0), -- Bloodcrown +(27419, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 3, 0, 0, 0), -- Warrior's Resolve +(27498, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 3, 0, 0, 0), -- Crusader's Wrath +(27521, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 15000, 0), -- Mana Restore +(27656, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Flame Lash +(27774, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- The Furious Storm +(27787, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 1, 0, 0, 0), -- Rogue Armor Energize (AC #11048) +(28305, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Mana Leech +(28752, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Adrenaline Rush +(28802, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Epiphany +(28812, 0, 8, 0x02000006, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Head Rush +(28816, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 3, 0, 0, 0), -- Invigorate +(29150, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Electric Discharge +(29385, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 7, 0, 1000, 0), -- Seal of Command +(29455, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Felsteel Shield Spike +(29501, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Frost Arrow +(29624, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Searing Arrow +(29625, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Flaming Cannonball +(29626, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Shadow Bolt +(29632, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Shadow Shot +(29633, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Fire Blast +(29634, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Quill Shot +(29635, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Flaming Shell +(29636, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Venom Shot +(29637, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Keeper's Sting +(29977, 4, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Combustion +(30003, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2048, 0x0, 0, 0, 0, 0), -- Sheen of Zanza +(30937, 32, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Mark of Shadow +(31394, 32, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Mark of Shadow +(31794, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Focused Mind +(31904, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Holy Shield +(32587, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Shield Block +(32642, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Spore Cloud +(32734, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 3000, 0), -- Earth Shield +(32748, 0, 8, 0x00000000, 0x00000001, 0x00000000, 320, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Deadly Throw Interrupt +(32776, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Redoubt +(32777, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Holy Shield +(32837, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Spell Focus Trigger +(32844, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 2, 0, 0, 0), -- Lesser Heroism +(32885, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 2, 0x0, 0, 0, 0, 0), -- Infuriate +(33089, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Vigilance of the Colossus +(33127, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 7, 0, 1000, 0), -- Seal of Command +(33297, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Spell Haste Trinket +(33299, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Coilfang Slave Pens Lvl 70 Boss3a Caster Trinket +(33510, 0, 0, 0x00000000, 0x00000000, 0x00000000, 340, 0x0, 0x2, 0, 0x0, 0, 15, 25000, 0), -- Health Restore (AC #16551) +(33648, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 45000, 0), -- Reflection of Torment +(33719, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2048, 0x0, 0, 0, 0, 0), -- Perfect Spell Reflection +(33746, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 10000, 0), -- Essence Infused Mushroom +(33759, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 10000, 0), -- Power Infused Mushroom +(33953, 0, 0, 0x00000000, 0x00000000, 0x00000000, 17408, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Essence of Life +(34074, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Aspect of the Viper +(34080, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 32, 0x0, 0, 0, 0, 0), -- Riposte Stance +(34138, 0, 11, 0x00000080, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Totem of the Third Wind +(34139, 0, 10, 0x40000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Libram of Justice +(34258, 0, 10, 0x00800000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x2, 0, 0, 0, 0), -- Justice +(34262, 0, 10, 0x00800000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x2, 0, 0, 0, 0), -- Mercy +(34320, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 45000, 0), -- Call of the Nexus +(34355, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 3000, 0), -- Poison Shield +(34584, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 30000, 0), -- Love Struck +(34586, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0,1.5, 0, 0, 0), -- Romulo's Poison +(34598, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Karazhan Caster Robe +(34749, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 8, 0x2, 0, 0, 0, 0), -- Recurring Power +(34774, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0,1.5, 0, 20000, 0), -- Magtheridon Melee Trinket +(34783, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2048, 0x0, 0, 0, 0, 0), -- Spell Reflection +(34827, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 3000, 0), -- Water Shield +(35077, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 55000, 0), -- Band of the Eternal Defender +(35080, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 1, 0, 55000, 0), -- Band of the Eternal Champion +(35083, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 55000, 0), -- Band of the Eternal Sage +(35086, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 55000, 0), -- Band of the Eternal Restorer +(35121, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Nether Power +(36032, 0, 3, 0x00001000, 0x00008000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Arcane Blast +(36096, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2048, 0x0, 0, 0, 0, 0), -- Spell Reflection +(36111, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- World Breaker +(36541, 4, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x2, 0, 0, 0, 0), -- Curse of Burning Shadows +(37165, 0, 8, 0x00200400, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Haste +(37170, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 1, 0, 0, 0), -- Free Finisher Chance +(37173, 0, 8, 0x2CBC0598, 0x00000106, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 25000, 0), -- Armor Penetration +(37189, 0, 10, 0xC0000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 60000, 0), -- Recuced Holy Light Cast Time +(37193, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Infused Shield +(37195, 0, 10, 0x00800000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x2, 0, 0, 0, 0), -- Judgement Group Heal +(37197, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Spell Damage +(37213, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Mana Cost Reduction +(37214, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Energized +(37227, 0, 11, 0x000001C0, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 60000, 0), -- Improved Healing Wave +(37237, 0, 11, 0x00000001, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Lightning Bolt Discount +(37247, 8, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Regain Mana +(37379, 32, 5, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Flameshadow +(37384, 0, 5, 0x00000001, 0x00000040, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Corruption and Immolate +(37443, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Crit Bonus Damage +(37514, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 32, 0x0, 0, 0, 0, 0), -- Blade Turning +(37516, 0, 4, 0x00000400, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Revenge Bonus +(37519, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 48, 0x0, 0, 0, 0, 0), -- Rage Bonus +(37523, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Reinforced Shield +(37528, 0, 4, 0x00000004, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Overpower Bonus +(37536, 0, 4, 0x00010000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Improved Battle Shout +(37568, 0, 6, 0x00000800, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Greater Heal Discount +(37600, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Offensive Discount +(37601, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Relentlessness +(37603, 0, 6, 0x00008000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Shadow Word Pain Damage +(37655, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 60000, 0), -- Bonus Mana Regen +(37657, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 2500, 0), -- Lightning Capacitor +(38026, 1, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 256, 0x0, 0, 0, 0, 0), -- Viscous Shield +(38031, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Shield Block +(38290, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0,1.6, 0, 0, 0), -- Santos' Blessing +(38299, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 12000, 0), -- HoTs on Heals +(38326, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Crit Threat Reduction Melee +(38327, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0), -- Crit Threat Reduction Spell +(38334, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 60000, 0), -- Proc Mana Regen +(38347, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 45000, 0), -- Crit Proc Spell Damage +(38350, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Crit Proc Heal +(38394, 0, 5, 0x00000006, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Dot Heals +(38857, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Spell Ground +(39027, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 3000, 0), -- Poison Shield +(39442, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 1, 0x0, 0, 0, 0, 0), -- Aura of Wrath +(39443, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Aura of Wrath +(39530, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Focus +(39958, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0,0.7, 0, 40000, 0), -- Skyfire Swiftness +(40407, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 6, 0, 0, 0), -- Illidan Tank Shield (AC Mangos legacy) +(40444, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Black Temple Tank Trinket +(40458, 0, 4, 0x02000000, 0x00000601, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Warrior Tier 6 Trinket +(40475, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 3, 0, 0, 0), -- Black Temple Melee Trinket +(40478, 0, 5, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Warlock Tier 6 Trinket +(40482, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Mage Tier 6 Trinket +(40485, 0, 9, 0x00000000, 0x00000001, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Hunter Tier 6 Trinket +(40899, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 1, 0, 0, 0), -- Felfire Proc +(41034, 126, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 1024, 0x0, 0, 0, 0, 0), -- Spell Absorption +(41260, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 10000, 0), -- Aviana's Purpose +(41262, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 10000, 0), -- Aviana's Will +(41381, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 256, 0x0, 0, 0, 0, 0), -- Shell of Life +(41393, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 32, 0x0, 0, 0, 0, 0), -- Riposte +(41434, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 2, 0, 45000, 0), -- The Twin Blades of Azzinoth +(41469, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 7, 0, 1000, 0), -- Seal of Command +(41989, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0,1.5, 0, 0, 0), -- Fists of Fury (AC #21454) +(42083, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 45000, 0), -- Fury of the Crashing Waves +(42135, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 90000, 0), -- Lesser Rune of Warding +(42136, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 90000, 0), -- Greater Rune of Warding +(42368, 0, 10, 0x40000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Merciless Libram of Justice +(42370, 0, 11, 0x00000080, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Merciless Totem of the Third WInd +(43443, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2048, 0x0, 0, 0, 0, 0), -- Spell Reflection +(43726, 0, 10, 0x40000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Vengeful Libram of Justice +(43728, 0, 11, 0x00000080, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Vengeful Totem of Third WInd +(43737, 0, 7, 0x00000000, 0x00000440, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 10000, 0), -- Primal Instinct +(43739, 0, 7, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Lunar Grace +(43741, 0, 10, 0x80000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Light's Grace +(43745, 0, 10, 0x00000000, 0x00000200, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Crusader's Command +(43748, 0, 11, 0x90100000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Elemental Strength +(43750, 0, 11, 0x00000001, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Energized +(43819, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Lucidity +(44543, 0, 3, 0x00100220, 0x00001000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 7, 0, 0), -- Fingers of Frost +(44545, 0, 3, 0x00100220, 0x00001000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 15, 0, 0), -- Fingers of Frost +(45054, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 15000, 0), -- Augment Pain +(45354, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Sunwell Dungeon Melee Trinket +(45355, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - T7 Melee Trinket Base +(45469, 0, 15, 0x00000010, 0x00000000, 0x00000000, 16, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Death Strike +(45481, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Sunwell Exalted Caster Neck +(45482, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Sunwell Exalted Melee Neck +(45483, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Sunwell Exalted Tank Neck +(45484, 0, 0, 0x00000000, 0x00000000, 0x00000000, 16384, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Sunwell Exalted Healer Neck +(46025, 32, 6, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Blackout +(46092, 0, 10, 0x40000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Brutal Libram of Justice +(46098, 0, 11, 0x00000080, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Brutal Totem of Third WInd +(46569, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Sunwell Exalted Caster Neck +(46662, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 20000, 0), -- Deathfrost +(46832, 0, 7, 0x00000001, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Moonkin Starfire Bonus +(46910, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0,5.5, 0, 0, 0), -- Furious Attacks +(46911, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0,7.5, 0, 0, 0), -- Furious Attacks +(47981, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2048, 0x0, 0, 0, 0, 0), -- Spell Reflection +(48833, 0, 7, 0x00000000, 0x00000440, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Primal Instinct +(48835, 0, 10, 0x00800000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x2, 0, 0, 0, 0), -- Justice +(48837, 0, 11, 0x90100000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Elemental Tenacity +(49592, 0, 0, 0x00000000, 0x00000000, 0x00000000, 8528552, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Temporal Rift +(49622, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 60000, 0), -- Bonus Mana Regen +(50240, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 16, 0x0, 0, 0, 0, 0), -- Evasive Maneuvers +(50421, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Scent of Blood +(50781, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 6000, 0), -- Fate Rune of Primal Energy +(51123, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 1, 0, 0, 0), -- Killing Machine +(51127, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 2, 0, 0, 0), -- Killing Machine +(51128, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 4, 0, 0, 0), -- Killing Machine +(51129, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 6, 0, 0, 0), -- Killing Machine +(51130, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 8, 0, 0, 0), -- Killing Machine +(51346, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 10000, 0), -- Venture Company Beatdown! +(51349, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 10000, 0), -- Venture Company Beatdown +(51352, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 10000, 0), -- Venture Company Beatdown! +(51359, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 0, 0, 10000, 0), -- Venture Company Beatdown +(51414, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 45000, 0), -- Venomous Breath Aura +(51915, 0, 0, 0x00000000, 0x00000000, 0x00000000,16777216, 0x0, 0x0, 0, 0x0, 0, 100, 600000, 0), -- Undying Resolve +(52020, 0, 7, 0x00008000, 0x00100000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Snap and Snarl +(52423, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 32, 0x0, 0, 0, 0, 0), -- Retaliation +(52898, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2, 0x0, 0, 0, 0, 0), -- Spell Damping +(53386, 0, 15, 0x82127F27, 0x000001BF, 0x00000000, 0, 0x1, 0x2, 0, 0x2, 0, 0, 0, 0), -- Cinderglacier +(53397, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Invigoration +(54278, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Empowered Imp +(54646, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Focus Magic +(54695, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Death Knight's Anguish Base +(54707, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 60000, 0), -- Sonic Awareness (DND) +(54738, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 45000, 0), -- Star of Light +(54808, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 60000, 0), -- Sonic Shield +(54838, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Purified Spirit +(54841, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 2500, 0), -- Thunder Capacitor +(54925, 2, 10, 0x00000000, 0x00000200, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Seal of Command +(55380, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 40000, 0), -- Skyflare Swiftness (Thundering Skyflare Diamond) +(55381, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 15000, 0), -- Mana Restore +(55640, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Lightweave Embroidery +(55680, 0, 6, 0x00000200, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Prayer of Healing +(55681, 0, 6, 0x00008000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Shadow Word: Pain +(55689, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Glyph of Shadow +(55747, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Argent Fury +(55768, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Darkglow Embroidery +(55776, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Swordguard Embroidery +(56249, 0, 5, 0x00000000, 0x00000000, 0x00000400, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Felhunter +(56355, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 64, 0x0, 0, 0, 0, 0), -- Titanium Shield Spike +(56364, 0, 3, 0x00000000, 0x01000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Remove Curse +(56451, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 3000, 0), -- Earth Shield +(56816, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 48, 0x0, 0, 0, 0, 0), -- Rune Strike +(56817, 0, 15, 0x00000000, 0x20000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Rune strike proc (SERVERSIDE) +(56821, 0, 8, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Glyph of Sinister Strike +(56841, 0, 9, 0x00000800, 0x00000000, 0x00000000, 256, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Arcane Shot +(57345, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Darkmoon Card: Greatness +(57352, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Darkmoon Card: Death +(57907, 0, 7, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Increased Spirit +(57989, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Shadowfiend Death +(58357, 0, 4, 0x00000040, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Glyph of Heroic Strike +(58364, 0, 4, 0x00000400, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Revenge +(58372, 0, 4, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Hamstring +(58386, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 32, 0x0, 0, 0, 0, 0), -- Glyph of Overpower +(58442, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 15000, 0), -- Airy Pale Ale +(58444, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 5000, 0), -- Worg Tooth Oatmeal Stout +(58616, 0, 15, 0x01000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Heart Strike +(58620, 0, 15, 0x00000004, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Chains of Ice +(58626, 0, 15, 0x02000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Death Grip +(58901, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 45000, 0), -- Tears of Anguish +(59176, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 2, 0x0, 0, 0, 0, 0), -- Spell Damping +(59327, 0, 15, 0x08000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Rune Tap +(59345, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Chagrin +(59630, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 35000, 0), -- Black Magic +(59725, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 2048, 0x0, 0, 0, 0, 0), -- Spell Reflection +(60061, 0, 0, 0x00000000, 0x00000000, 0x00000000, 294912, 0x2, 0x0, 0, 0x0, 0, 0, 45000, 0), -- Flow of Time +(60063, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Now is the Time! +(60066, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 45000, 0), -- Rage of the Unraveller +(60132, 0, 15, 0x00000010, 0x08020000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Oblit/Scourge Strike Runic Power Up +(60170, 0, 5, 0x00000006, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Corruption Triggers Crit +(60172, 0, 5, 0x00040000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Life Tap Bonus Spirit +(60176, 0, 4, 0x00000020, 0x00000010, 0x00000000, 262144, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Bleed Cost Reduction +(60221, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 45000, 0), -- Essence of Gossamer +(60301, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Meteorite Whetstone +(60306, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Vestige of Haldor +(60317, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Signet of Edward the Odd +(60436, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Grim Toll +(60442, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Bandit's Insignia +(60473, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Forge Ember +(60482, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Pendulum of Telluric Currents +(60487, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 15000, 0), -- Extract of Necromatic Power +(60490, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Embrace of the Spider +(60493, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Dying Curse +(60503, 1, 4, 0x00000004, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Taste for Blood +(60519, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x3, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Spark of Life +(60524, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Majestic Dragon Figurine +(60529, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Forethought Talisman +(60537, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 45000, 0), -- Soul of the Dead +(60564, 0, 11, 0x90100000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Savage Gladiator's Totem of Survival +(60571, 0, 11, 0x90100000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Hateful Gladiator's Totem of Survival +(60572, 0, 11, 0x90100000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Deadly Gladiator's Totem of Survival +(60573, 0, 11, 0x90100000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- LK Arena 4 Gladiator's Totem of Survival +(60574, 0, 11, 0x90100000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- LK Arena 5 Gladiator's Totem of Survival +(60575, 0, 11, 0x90100000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- LK Arena 6 Gladiator's Totem of Survival +(60710, 0, 7, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Savage Gladiator's Idol of Steadfastness +(60717, 0, 7, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Hateful Gladiator's Idol of Steadfastness +(60719, 0, 7, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Deadly Gladiator's Idol of Steadfastness +(60722, 0, 7, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- LK Arena 4 Gladiator's Idol of Steadfastness +(60724, 0, 7, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- LK Arena 5 Gladiator's Idol of Steadfastness +(60726, 0, 7, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- LK Arena 6 Gladiator's Idol of Steadfastness +(60770, 0, 11, 0x00000001, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Totem of the Elemental Plane +(60818, 0, 10, 0x00000000, 0x00000200, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Libram of Reciprocation +(60826, 0, 15, 0x01400000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Sigil of Haunted Dreams +(61188, 0, 5, 0x00000004, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Chaotic Mind +(61324, 0, 10, 0x00000000, 0x00020000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Justice +(61356, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 90000, 0), -- Invigorating Earthsiege Diamond Passive +(61618, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Tentacles +(61848, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 16, 0x0, 0, 0, 0, 0), -- Aspect of the Dragonhawk +(62114, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Flow of Knowledge +(62115, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Strength of the Titans +(62147, 0, 15, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Icy Touch Defense Increase +(62459, 0, 15, 0x00000004, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Chains of Ice Frost Rune Refresh +(63086, 0, 9, 0x00000000, 0x00000000, 0x00010000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Raptor Strike +(63108, 0, 5, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Siphon Life +(63251, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Glory of the Jouster +(63310, 0, 5, 0x00000000, 0x00010000, 0x00000000, 65536, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Shadowflame +(63335, 0, 15, 0x00000000, 0x00000002, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Glyph of Howling Blast +(63611, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x1, 0, 0, 0, 0), -- Improved Blood Presence +(64343, 0, 3, 0x00000002, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Impact +(64411, 0, 0, 0x00000000, 0x00000000, 0x00000000, 279552, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Blessing of Ancient Kings +(64415, 0, 0, 0x00000000, 0x00000000, 0x00000000, 279552, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Val'anyr Hammer of Ancient Kings - Equip Effect +(64440, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 32, 0x0, 0, 0, 20000, 0), -- Blade Warding +(64571, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 10000, 0), -- Blood Draining +(64714, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Flame of the Heavens +(64738, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Show of Faith +(64742, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Pandora's Plea +(64752, 0, 7, 0x00001000, 0x00000100, 0x00200000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Druid T8 Feral 2P Bonus +(64786, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Comet's Trail +(64792, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 45000, 0), -- Blood of the Old God +(64824, 0, 7, 0x00200000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Druid T8 Balance 4P Bonus +(64860, 0, 9, 0x00000000, 0x00000001, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Hunter T8 4P Bonus +(64867, 0, 3, 0x20000021, 0x00001000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Mage T8 2P Bonus +(64882, 0, 10, 0x00000000, 0x00100000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Paladin T8 Protection 4P Bonus +(64908, 0, 6, 0x00002000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Priest T8 Shadow 4P Bonus +(64912, 0, 6, 0x00000001, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Priest T8 Healer 4P Bonus +(64914, 0, 8, 0x00010000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Rogue T8 2P Bonus +(64938, 0, 4, 0x00200040, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 0, 0), -- Item - Warrior T8 Melee 2P Bonus +(64952, 0, 7, 0x00000000, 0x00000440, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Druid T8 Feral Relic +(64955, 0, 10, 0x00000000, 0x00000040, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Paladin T8 Protection Relic +(64964, 0, 15, 0x00000000, 0x20000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Death Knight T8 Tank Relic +(64976, 0, 4, 0x00000001, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Juggernaut +(64999, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x4, 0, 0, 0, 0), -- Meteoric Inspiration +(65002, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Bonus Mana Regen +(65005, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x1, 0, 0x0, 0, 0, 45000, 0), -- Alacrity of the Elements +(65007, 0, 0, 0x00000000, 0x00000000, 0x00000000, 81920, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Eye of the Broodmother +(65013, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 45000, 0), -- Pyrite Infusion +(65020, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Mjolnir Runestone +(65025, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Dark Matter +(66808, 0, 0, 0x00000000, 0x00000000, 0x00000000, 4, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Meteor Fists +(67115, 0, 15, 0x01400000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Death Knight T9 Melee 2P Bonus +(67151, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Hunter T9 4P Bonus (Steady Shot) +(67209, 1, 8, 0x00100000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Rogue T9 2P Bonus (Rupture) +(67353, 0, 7, 0x00008000, 0x00100500, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Druid T9 Feral Relic (Lacerate, Swipe, Mangle, and Shred) +(67356, 8, 7, 0x00000010, 0x00000000, 0x00000000, 0, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Druid T9 Restoration Relic (Rejuvenation) +(67361, 0, 7, 0x00000002, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Druid T9 Balance Relic (Moonfire) +(67363, 0, 10, 0x80000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 10000, 0), -- Item - Paladin T9 Holy Relic (Judgement) +(67365, 0, 10, 0x00000000, 0x00000800, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 6000, 0), -- Item - Paladin T9 Retribution Relic (Seal of Vengeance) +(67379, 0, 10, 0x00000000, 0x00040000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Paladin T9 Protection Relic (Hammer of The Righteous) +(67381, 0, 15, 0x00000000, 0x20000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 10000, 0), -- Item - Death Knight T9 Tank Relic (Rune Strike) +(67384, 0, 15, 0x00000010, 0x08020000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 80, 10000, 0), -- Item - Death Knight T9 Melee Relic (Rune Strike) +(67386, 0, 11, 0x00000001, 0x00000000, 0x00000000, 65536, 0x0, 0x1, 0, 0x0, 0, 0, 6000, 0), -- Item - Shaman T9 Elemental Relic (Lightning Bolt) +(67389, 0, 11, 0x00000100, 0x00000000, 0x00000000, 16384, 0x0, 0x1, 0, 0x0, 0, 0, 8000, 0), -- Item - Shaman T9 Restoration Relic (Chain Heal) +(67392, 0, 11, 0x00000000, 0x00000000, 0x00000004, 16, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Shaman T9 Enhancement Relic (Lava Lash) +(67653, 0, 0, 0x00000000, 0x00000000, 0x00000000, 4194344, 0x1, 0x0, 0, 0x0, 0, 0, 45000, 0), -- Coliseum 5 Tank Trinket +(67667, 0, 0, 0x00000000, 0x00000000, 0x00000000, 16384, 0x2, 0x1, 0, 0x0, 0, 0, 45000, 0), -- Coliseum 5 Healer Trinket +(67670, 0, 0, 0x00000000, 0x00000000, 0x00000000, 65536, 0x1, 0x1, 0, 0x0, 0, 0, 45000, 0), -- Coliseum 5 CasterTrinket +(67672, 0, 0, 0x00000000, 0x00000000, 0x00000000, 8388948, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Coliseum 5 Melee Trinket +(67698, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Item - Coliseum 25 Normal Healer Trinket +(67702, 1, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Coliseum 25 Normal Melee Trinket +(67712, 0, 0, 0x00000000, 0x00000000, 0x00000000, 69632, 0x0, 0x2, 2, 0x0, 0, 0, 2000, 0), -- Item - Coliseum 25 Normal Caster Trinket +(67752, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Item - Coliseum 25 Heroic Healer Trinket +(67758, 0, 0, 0x00000000, 0x00000000, 0x00000000, 69632, 0x0, 0x2, 2, 0x0, 0, 0, 2000, 0), -- Item - Coliseum 25 Heroic Caster Trinket +(67771, 1, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Coliseum 25 Heroic Melee Trinket +(68051, 1, 4, 0x00000004, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Overpower Ready! +(68160, 0, 0, 0x00000000, 0x00000000, 0x00000000, 4, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Meteor Fists +(70188, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 16, 0x0, 0, 0, 0, 0), -- Cloak of Darkness +(70652, 0, 15, 0x00000008, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Death Knight T10 Tank 4P Bonus +(70727, 0, 9, 0x00000001, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Hunter T10 2P Bonus +(70730, 0, 9, 0x00004000, 0x00001000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Hunter T10 4P Bonus +(70748, 0, 3, 0x00000000, 0x00200000, 0x00000000, 1024, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Mage T10 4P Bonus +(70756, 0, 10, 0x00000000, 0x00010000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Paladin T10 Holy 4P Bonus +(70761, 0, 10, 0x00000000, 0x00000000, 0x00000001, 1024, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Paladin T10 Protection 4P Bonus +(70803, 0, 8, 0x003E0000, 0x00000008, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Rogue T10 4P Bonus +(70807, 0, 11, 0x00000000, 0x00000000, 0x00000010, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Shaman T10 Restoration 2P Bonus +(70811, 0, 11, 0x00000003, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Shaman T10 Elemental 2P Bonus +(70830, 0, 11, 0x00000000, 0x00020000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Shaman T10 Enhancement 2P Bonus +(70841, 0, 5, 0x00000004, 0x00000100, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Warlock T10 4P Bonus +(70854, 0, 4, 0x00000000, 0x00000010, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Warrior T10 Melee 2P Bonus +(71174, 1, 7, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Druid T10 Feral Relic (Rake and Lacerate) +(71176, 0, 7, 0x00200002, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Druid T10 Balance Relic (Moonfire and Insect Swarm) +(71178, 0, 7, 0x00000010, 0x00000000, 0x00000000, 0, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Druid T10 Restoration Relic (Rejuvenation) +(71186, 0, 10, 0x00000000, 0x00008000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Paladin T10 Retribution Relic (Crusader Strike) +(71191, 0, 10, 0x00000000, 0x00010000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Paladin T10 Holy Relic (Holy Shock) +(71194, 0, 10, 0x00000000, 0x00100000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Paladin T10 Protection Relic (Shield of Righteousness) +(71198, 4, 11, 0x10000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Item - Shaman T10 Elemental Relic (Shocks) +(71214, 0, 11, 0x00000000, 0x00000010, 0x00000000, 16, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Shaman T10 Enhancement Relic (Stormstrike) +(71217, 0, 11, 0x00000000, 0x00000000, 0x00000010, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Shaman T10 Restoration Relic (Riptide) +(71226, 0, 15, 0x00000010, 0x08020000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Death Knight T10 DPS Relic (Obliterate, Scourge Strike, Death Strike) +(71228, 0, 15, 0x00000000, 0x20000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0), -- Item - Death Knight T10 Tank Relic (Runestrike) +(71402, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Icecrown 10 Normal Melee Trinket +(71404, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 2, 0x0, 0, 0, 45000, 0), -- Item - Icecrown Dungeon Melee Trinket +(71540, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Icecrown 10 Heroic Melee Trinket +(71585, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 45000, 0), -- Item - Icecrown 25 Emblem Healer Trinket +(71602, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x1, 0, 0x0, 0, 0, 45000, 0), -- Item - Icecrown 25 Normal Caster Trinket 1 Base +(71606, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 100000, 0), -- Item - Icecrown 25 Normal Caster Trinket 2 +(71611, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Icecrown 25 Normal Healer Trinket 2 +(71637, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 100000, 0), -- Item - Icecrown 25 Heroic Caster Trinket 2 +(71642, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Icecrown 25 Heroic Healer Trinket 2 +(71645, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x1, 0, 0x0, 0, 0, 45000, 0), -- Item - Icecrown 25 Heroic Caster Trinket 1 Base +(71903, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 12, 0, 0, 0), -- Item - Shadowmourne Legendary +(72413, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 10, 60000, 0), -- Item - Icecrown Reputation Ring Melee +(72417, 0, 0, 0x00000000, 0x00000000, 0x00000000, 327680, 0x0, 0x2, 0, 0x0, 0, 0, 60000, 0), -- Item - Icecrown Reputation Ring Caster Trigger +(72419, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 60000, 0), -- Item - Icecrown Reputation Ring Healer Trigger +(74396, 84, 3, 0x28E212F7, 0x00119048, 0x00000000, 65536, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0), -- Fingers of Frost +(75455, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Chamber of Aspects 25 Melee Trinket +(75457, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 45000, 0), -- Item - Chamber of Aspects 25 Heroic Melee Trinket +(75465, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x1, 0, 0x0, 0, 0, 45000, 0), -- Item - Chamber of Aspects 25 Nuker Trinket +(75474, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x1, 0, 0x0, 0, 0, 45000, 0); -- Item - Chamber of Aspects 25 Heroic Nuker Trinket + +-- Spell script names for DK proc handlers +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_dk_butchery', 'spell_dk_mark_of_blood', 'spell_dk_unholy_blight', 'spell_dk_vendetta', 'spell_dk_necrosis', 'spell_dk_runic_power_back_on_snare_root'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-48979, 'spell_dk_butchery'), -- Butchery (all ranks) +(49005, 'spell_dk_mark_of_blood'), -- Mark of Blood +(49194, 'spell_dk_unholy_blight'), -- Unholy Blight +(50154, 'spell_dk_vendetta'), -- Vendetta +(-51459, 'spell_dk_necrosis'), -- Necrosis (all ranks) +(61257, 'spell_dk_runic_power_back_on_snare_root'); -- Runic Power Back on Snare/Root + +-- Spell script names for Druid proc handlers +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_dru_glyph_of_innervate', 'spell_dru_glyph_of_rake', 'spell_dru_leader_of_the_pack', 'spell_dru_glyph_of_rejuvenation', 'spell_dru_eclipse'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(54832, 'spell_dru_glyph_of_innervate'), -- Glyph of Innervate +(54821, 'spell_dru_glyph_of_rake'), -- Glyph of Rake +(24932, 'spell_dru_leader_of_the_pack'), -- Leader of the Pack +(54754, 'spell_dru_glyph_of_rejuvenation'), -- Glyph of Rejuvenation +(-48516, 'spell_dru_eclipse'); -- Eclipse (all ranks) + +-- Spell script names for Rogue proc handlers +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_rog_glyph_of_backstab', 'spell_rog_master_of_subtlety', 'spell_rog_cut_to_the_chase', 'spell_rog_deadly_brew', 'spell_rog_quick_recovery'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(56800, 'spell_rog_glyph_of_backstab'), -- Glyph of Backstab +(31666, 'spell_rog_master_of_subtlety'), -- Master of Subtlety (periodic tracker) +(-35541, 'spell_rog_cut_to_the_chase'), -- Cut to the Chase (all ranks) +(-51625, 'spell_rog_deadly_brew'), -- Deadly Brew (all ranks) +(-31244, 'spell_rog_quick_recovery'); -- Quick Recovery (all ranks) + +-- Spell script names for Hunter proc handlers +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_hun_thrill_of_the_hunt', 'spell_hun_hunting_party', 'spell_hun_rapid_recuperation', 'spell_hun_glyph_of_mend_pet'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-34497, 'spell_hun_thrill_of_the_hunt'), -- Thrill of the Hunt (all ranks) +(-53290, 'spell_hun_hunting_party'), -- Hunting Party (all ranks) +(53228, 'spell_hun_rapid_recuperation'), -- Rapid Recuperation Rank 1 +(53232, 'spell_hun_rapid_recuperation'), -- Rapid Recuperation Rank 2 +(57870, 'spell_hun_glyph_of_mend_pet'); -- Glyph of Mend Pet + +-- Spell script names for Paladin proc handlers +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_pal_judgements_of_the_wise', 'spell_pal_righteous_vengeance', 'spell_pal_sheath_of_light', 'spell_pal_judgement_of_light_heal', 'spell_pal_judgement_of_wisdom_mana', 'spell_pal_spiritual_attunement', 'spell_pal_glyph_of_holy_light_proc'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-31876, 'spell_pal_judgements_of_the_wise'), -- Judgements of the Wise (all ranks) +(-53380, 'spell_pal_righteous_vengeance'), -- Righteous Vengeance (all ranks) +(-53501, 'spell_pal_sheath_of_light'), -- Sheath of Light (all ranks) +(20185, 'spell_pal_judgement_of_light_heal'), -- Judgement of Light (debuff) +(20186, 'spell_pal_judgement_of_wisdom_mana'), -- Judgement of Wisdom (debuff) +(31785, 'spell_pal_spiritual_attunement'), -- Spiritual Attunement Rank 1 +(33776, 'spell_pal_spiritual_attunement'), -- Spiritual Attunement Rank 2 +(54937, 'spell_pal_glyph_of_holy_light_proc'); -- Glyph of Holy Light + +-- Spell script names for Shaman proc handlers +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_sha_glyph_of_healing_wave', 'spell_sha_spirit_hunt', 'spell_sha_frozen_power', 'spell_sha_lightning_overload', 'spell_sha_ancestral_awakening'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(55440, 'spell_sha_glyph_of_healing_wave'), -- Glyph of Healing Wave +(58877, 'spell_sha_spirit_hunt'), -- Spirit Hunt +(-63373, 'spell_sha_frozen_power'), -- Frozen Power (all ranks) +(-30675, 'spell_sha_lightning_overload'), -- Lightning Overload (all ranks) +(-51474, 'spell_sha_ancestral_awakening'); -- Ancestral Awakening (all ranks) + +-- Spell script names for Priest proc handlers +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_pri_vampiric_embrace', 'spell_pri_glyph_of_dispel_magic', 'spell_pri_body_and_soul', 'spell_pri_improved_shadowform'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(15286, 'spell_pri_vampiric_embrace'), -- Vampiric Embrace +(55677, 'spell_pri_glyph_of_dispel_magic'), -- Glyph of Dispel Magic +(-64127, 'spell_pri_body_and_soul'), -- Body and Soul (all ranks) +(47569, 'spell_pri_improved_shadowform'), -- Improved Shadowform Rank 1 +(47570, 'spell_pri_improved_shadowform'); -- Improved Shadowform Rank 2 + +-- Spell script names for Warlock proc handlers +-- Note: Nightfall uses -18094 with 'spell_warl_glyph_of_corruption_nightfall' (covers all ranks) +-- Glyph of Corruption (56218) also uses same script via RegisterSpellScriptWithArgs + +-- ============================================================================ +-- Phase 2: Migrate spell_proc_event entries with non-default values to spell_proc +-- These 68 entries have procFlags, ppmRate, customChance, or Cooldown set +-- ============================================================================ + +-- First delete any existing entries that might conflict +DELETE FROM `spell_proc` WHERE `SpellId` IN ( + -31641, -16689, 4524, 9452, 15257, 15331, 15332, 16372, 21747, + 24256, 26016, 27539, 27997, 28460, 29307, 31221, 31222, 31223, 33511, + 33522, 35399, 37565, 38319, 40303, 42760, 43730, 43983, 44546, 44548, + 44549, 44835, 45278, 45396, 45398, 45444, 46102, 49027, 49542, 49543, + 50871, 52881, 54404, 55610, 55717, 56845, 57351, 58426, 59887, 59888, + 59889, 59890, 59891, 60617, 62337, 64764, 64936, 66865, 66889, + 67530, 70871, 71567, 71604, 72256, 72673, 72674, 72675 +); + +-- Insert migrated entries from spell_proc_event +-- Schema: SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, +-- ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, ProcsPerMinute, Chance, Cooldown, Charges +DELETE FROM `spell_proc` WHERE `SpellId` IN (-31641,-16689,4524,9452); +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +-- Blazing Speed (Mage) - procFlags=680 (TAKEN_MELEE_AUTO_ATTACK|TAKEN_DAMAGE) +(-31641, 0, 0, 0x00000000, 0x00000000, 0x00000000, 680, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Shadow Weaving (Priest) - Cooldown=1000 +(-16689, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 1000, 0), +-- -16086 removed - TC doesn't have this entry, let DBC defaults handle it +-- Cure Ailments (Pet) - procFlags=1048576 (TAKEN_SPELL_MAGIC_DMG_CLASS) +(4524, 0, 0, 0x00000000, 0x00000000, 0x00000000, 1048576, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Duelist's Riposte - ppmRate=3.0 +(9452, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 3, 0, 0, 0), +-- Shadow Weaving Rank 1 - procFlags=327680 (DONE_SPELL_MAGIC_DMG_CLASS), customChance=33 +(15257, 0, 0, 0x00000000, 0x00000000, 0x00000000, 327680, 0x0, 0x0, 0, 0x0, 0, 33, 0, 0), +-- Shadow Weaving Rank 2 - procFlags=327680, customChance=66 +(15331, 0, 0, 0x00000000, 0x00000000, 0x00000000, 327680, 0x0, 0x0, 0, 0x0, 0, 66, 0, 0), +-- Shadow Weaving Rank 3 - procFlags=327680, customChance=100 +(15332, 0, 0, 0x00000000, 0x00000000, 0x00000000, 327680, 0x0, 0x0, 0, 0x0, 0, 100, 0, 0), +-- Ancestral Fortitude (Shaman) - procFlags=131072, customChance=100 +(16372, 0, 0, 0x00000000, 0x00000000, 0x00000000, 131072, 0x0, 0x0, 0, 0x0, 0, 100, 0, 0), +-- Lawbringer - procFlags=20, ppmRate=20.0, Cooldown=50000 (AC #10402) +(21747, 0, 0, 0x00000000, 0x00000000, 0x00000000, 20, 0x0, 0x0, 0, 0x0,20, 0, 50000, 0), +-- Blessing of the Claw - Cooldown=240000 (4 min) +(24256, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0,240000, 0), +-- Thorn Shield - ppmRate=2.0 +(26016, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 2, 0, 0, 0), +-- Thick Chitin - Cooldown=10000 +(27539, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 10000, 0), +-- Bloodgorged - Cooldown=50000 +(27997, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 50000, 0), +-- Monstrous Vitality - Cooldown=5000 +(28460, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 5000, 0), +-- Arcane Power (Boss) - procFlags=4, customChance=100 +(29307, 0, 0, 0x00000000, 0x00000000, 0x00000000, 4, 0x0, 0x0, 0, 0x0, 0, 100, 0, 0), +-- NOTE: Master of Subtlety spell_proc entries removed - TC uses script on 31666 (periodic tracker) instead of talent proc +-- If this causes regressions, uncomment these entries: +-- (31221, 0, 0, 0x00000000, 0x00000000, 0x00000000, 1024, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Master of Subtlety Rank 1 +-- (31222, 0, 0, 0x00000000, 0x00000000, 0x00000000, 1024, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Master of Subtlety Rank 2 +-- (31223, 0, 0, 0x00000000, 0x00000000, 0x00000000, 1024, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), -- Master of Subtlety Rank 3 +-- Zandalarian Hero Charm - Cooldown=17000 +(33511, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 17000, 0), +-- Idol of the Raven Goddess - Cooldown=25000 +(33522, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 25000, 0), +-- Inspiration (Priest) - procFlags=131072 +(35399, 0, 0, 0x00000000, 0x00000000, 0x00000000, 131072, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Blessing of the Onyx Serpent - procFlags=16384 +(37565, 0, 0, 0x00000000, 0x00000000, 0x00000000, 16384, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Thundering Rage - Cooldown=50000 +(38319, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 50000, 0), +-- Ashtongue Talisman of Acumen - Cooldown=1000 +(40303, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 1000, 0), +-- Focused Assault - procFlags=245966, customChance=20 +(42760, 0, 0, 0x00000000, 0x00000000, 0x00000000, 245966, 0x0, 0x0, 0, 0x0, 0, 20, 0, 0), +-- Spirit Wolf - Cooldown=8000 +(43730, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 8000, 0), +-- Enchant Cloak - Steelweave - procFlags=81920, customChance=100, Cooldown=600 +(43983, 0, 0, 0x00000000, 0x00000000, 0x00000000, 81920, 0x0, 0x0, 0, 0x0, 0, 100, 600, 0), +-- Brain Freeze Rank 1 - procFlags=69632, customChance=5, Cooldown=3000 +(44546, 0, 0, 0x00000000, 0x00000000, 0x00000000, 69632, 0x0, 0x0, 0, 0x0, 0, 5, 3000, 0), +-- Brain Freeze Rank 2 - procFlags=69632, customChance=10, Cooldown=3000 +(44548, 0, 0, 0x00000000, 0x00000000, 0x00000000, 69632, 0x0, 0x0, 0, 0x0, 0, 10, 3000, 0), +-- Brain Freeze Rank 3 - procFlags=69632, customChance=15, Cooldown=3000 +(44549, 0, 0, 0x00000000, 0x00000000, 0x00000000, 69632, 0x0, 0x0, 0, 0x0, 0, 15, 3000, 0), +-- Maim Interrupt - procFlags=16 +(44835, 0, 0, 0x00000000, 0x00000000, 0x00000000, 16, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Improved Water Shield - procFlags=82944 +(45278, 0, 0, 0x00000000, 0x00000000, 0x00000000, 82944, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Blessed Book of Nagrand - Cooldown=45000 +(45396, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 45000, 0), +-- Memento of Tyrande - Cooldown=45000 +(45398, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 45000, 0), +-- Tome of the Lightbringer - Cooldown=45000 +(45444, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 45000, 0), +-- Forked Lightning - procFlags=81920 +(46102, 0, 0, 0x00000000, 0x00000000, 0x00000000, 81920, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Wandering Plague Rank 1 - customChance=3, Cooldown=20000 +(49027, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 3, 20000, 0), +-- Wandering Plague Rank 2 - customChance=6, Cooldown=20000 +(49542, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 6, 20000, 0), +-- Wandering Plague Rank 3 - customChance=9, Cooldown=20000 +(49543, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 9, 20000, 0), +-- Divine Storm - customChance=100 +(50871, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 100, 0, 0), +-- Blade Warding - Cooldown=12000 +(52881, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 12000, 0), +-- Rapid Killing - customChance=100 +(54404, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 100, 0, 0), +-- Imp Devotion - procFlags=4096 +(55610, 0, 0, 0x00000000, 0x00000000, 0x00000000, 4096, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Berserking - Cooldown=5000 +(55717, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 5000, 0), +-- Glyph of Scourge Strike - procFlags=2097152 +(56845, 0, 0, 0x00000000, 0x00000000, 0x00000000, 2097152, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Fel Vitality - procFlags=1782780 +(57351, 0, 0, 0x00000000, 0x00000000, 0x00000000, 1782780, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Overkill - procFlags=1024 +(58426, 0, 0, 0x00000000, 0x00000000, 0x00000000, 1024, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Frostfire Orb Rank 1 - procFlags=87040 +(59887, 0, 0, 0x00000000, 0x00000000, 0x00000000, 87040, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Frostfire Orb Rank 2 - procFlags=87040 +(59888, 0, 0, 0x00000000, 0x00000000, 0x00000000, 87040, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Frostfire Orb Rank 3 - procFlags=87040 +(59889, 0, 0, 0x00000000, 0x00000000, 0x00000000, 87040, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Frostfire Orb Rank 4 - procFlags=87040 +(59890, 0, 0, 0x00000000, 0x00000000, 0x00000000, 87040, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Frostfire Orb Rank 5 - procFlags=87040 +(59891, 0, 0, 0x00000000, 0x00000000, 0x00000000, 87040, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Rage of Thassarian - customChance=100 +(60617, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 100, 0, 0), +-- Petrified Bark (Normal) - procFlags=40 +(62337, 0, 0, 0x00000000, 0x00000000, 0x00000000, 40, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- 62933 removed - TC doesn't have this entry, let DBC defaults handle it +-- Dying Curse - Cooldown=50000 +(64764, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 50000, 0), +-- Glyph of Scourge Strike - procFlags=69632, customChance=100 +(64936, 0, 0, 0x00000000, 0x00000000, 0x00000000, 69632, 0x0, 0x0, 0, 0x0, 0, 100, 0, 0), +-- Talisman of the Forsaken City - customChance=35, Cooldown=3000 +(66865, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 35, 3000, 0), +-- Mana Shield - procFlags=4, customChance=100 +(66889, 0, 0, 0x00000000, 0x00000000, 0x00000000, 4, 0x0, 0x0, 0, 0x0, 0, 100, 0, 0), +-- Thorns - procFlags=40, Cooldown=5000 +(67530, 0, 0, 0x00000000, 0x00000000, 0x00000000, 40, 0x0, 0x0, 0, 0x0, 0, 0, 5000, 0), +-- Devious Minds - procFlags=69972, customChance=100 +(70871, 0, 0, 0x00000000, 0x00000000, 0x00000000, 69972, 0x0, 0x0, 0, 0x0, 0, 100, 0, 0), +-- Mutated Plague - Cooldown=250 +(71567, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 250, 0), +-- Deathbringer's Will Normal - customChance=100, Cooldown=10000 +(71604, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 100, 10000, 0), +-- Crimson Scourge - procFlags=4 +(72256, 0, 0, 0x00000000, 0x00000000, 0x00000000, 4, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0), +-- Deathbringer's Will Heroic 1 - customChance=100, Cooldown=10000 +(72673, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 100, 10000, 0), +-- Deathbringer's Will Heroic 2 - customChance=100, Cooldown=10000 +(72674, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 100, 10000, 0), +-- Deathbringer's Will Heroic 3 - customChance=100, Cooldown=10000 +(72675, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 100, 10000, 0); + +-- Additional spell_proc entries from TrinityCore (missing in AzerothCore) +-- These entries provide refined proc configuration from TC's spell_proc table +DELETE FROM `spell_proc` WHERE `SpellId` IN (-59887,-53583,-51682,-49200,-47230,-31226,-30482,-16689,-14143,-12317,-11103,-7302,-7001,-1120,-588,-168,4341,5118,12043,12328,13159,13234,16166,17116,17670,18708,20911,21084,23591,32065,35321,36659,37604,38363,39215,40816,41350,45092,48504,50871,50908,53257,53515,53651,53817,57529,57531,58501,60617,63057,63849,70656,70904,71567,71571,71573,71865,71868,71993,72059,75490,75495); +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +-- Negative SpellId entries (applies to all spell ranks) +(-59887, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0, 0), -- Frostfire Orb (all ranks) +(-53583, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0, 0), -- Swift Retribution (all ranks) +(-51682, 0, 8, 0x00000000, 0x00080000, 0x00000000, 0, 0x4, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Rogue Deadly Brew (all ranks) +(-49200,126, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x2, 0, 0, 0, 0, 0), -- Dispersion (all ranks) +(-47230, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Fel Synergy (all ranks) +(-31226, 0, 8, 0x00000000, 0x00080000, 0x00000000, 0, 0x5, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Rogue Deadly Poison (all ranks) +(-30482, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 1027, 0x2, 0, 0, 0, 0, 0), -- Molten Shields (all ranks) +(-16689, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 1000, 0), -- Nature's Grasp (all ranks) +(-14143, 0, 8, 0x47046286, 0x00200000, 0x00000000, 0, 0x1, 0x2, 0, 0x8, 0, 0, 0, 0, 0), -- Rogue Relentless Strikes (all ranks) +(-12317, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0, 0), -- Enrage (all ranks) +(-11103, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x0, 0, 0, 0, 0, 0), -- World in Flames (all ranks) +(-7302, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 1027, 0x2, 0, 0, 0, 0, 0), -- Frost Armor (all ranks) +(-7001, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x2, 0, 0, 0, 0, 0), -- Lightwell Renew (all ranks) +(-1120, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x1, 3, 0, 0, 0, 0), -- Drain Soul (all ranks) +(-588, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0, 0), -- Inner Fire (all ranks) +(-168, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 1027, 0x2, 0, 0, 0, 0, 0), -- Frost Armor (all ranks) +-- Positive SpellId entries (specific spells) +(4341, 0, 0, 0x00000000, 0x00000000, 0x00000000, 4096, 0x1, 0x1, 0, 0x0, 0, 0, 0, 0, 0), -- Flame Buffet +(5118, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x2, 0, 0, 0, 0, 0), -- Aspect of the Cheetah +(12043, 0, 3, 0x61400035, 0x00001000, 0x00000000, 0, 0x7, 0x1, 0, 0x8, 0, 0, 0, 0, 0), -- Presence of Mind +(12328, 0, 4, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Sweeping Strikes +(13159, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x2, 0, 0, 0, 0, 0), -- Aspect of the Pack +(13234, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 1027, 0x2, 0, 0, 0, 0, 0), -- Magic Resistance +(16166, 0, 11, 0x00000003, 0x00001000, 0x00000000, 0, 0x7, 0x1, 0, 0x8, 0, 0, 0, 0, 0), -- Elemental Mastery +(17116, 0, 7, 0x10000861, 0x02000020, 0x00008000, 0, 0x7, 0x1, 0, 0x8, 0, 0, 0, 0, 0), -- Nature's Swiftness +(17670, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 1, 0, 0, 0, 0), -- Argent Dawn Commission +(18708, 0, 5, 0x20000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x8, 0, 0, 0, 0, 0), -- Fel Domination +(20911, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 112, 0x0, 0, 0, 0, 0, 0), -- Blessing of Sanctuary +(21084, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Seal of Righteousness +(23591, 0, 10, 0x00800000, 0x00000000, 0x00000000, 16, 0x0, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Reckoning +(32065, 0, 0, 0x00000000, 0x00000000, 0x00000000, 524288, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0, 0), -- Fungal Decay +(35321, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0, 0), -- Gust of Wind +(36659, 0, 0, 0x00000000, 0x00000000, 0x00000000, 524288, 0x1, 0x0, 0, 0x0, 0, 0, 0, 0, 0), -- Tail Lash +(37604, 0, 6, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0, 0), -- Primal Blessing +(38363, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0, 0), -- Gust of Wind +(39215, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x0, 0, 0x0, 0, 0, 0, 0, 0), -- Gust of Wind +(40816, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x2, 0, 0x0, 0, 0, 0, 7000, 0), -- Saber Lash +(41350, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Aura of Desire +(45092, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 0, 0, 0, 0, 0), -- Faction, Spar Buddy +(48504, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 0, 0x2, 0, 0, 0, 0, 0), -- Living Seed +(50871, 0, 9, 0x00000000, 0x40000000, 0x00000000, 0, 0x1, 0x2, 2, 0x0, 0, 0, 0, 0, 0), -- Brutal Gladiator's War Edge +(50908, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 2, 0, 0, 4000, 0), -- Serpent-Coil Braid +(53257, 0, 9, 0x00000000, 0x10000000, 0x00000000, 16, 0x1, 0x2, 2, 0x8, 0, 0, 0, 0, 0), -- Cobra Strikes +(53515, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x3, 0x2, 0, 0x0, 0, 0, 0, 0, 0), -- Divine Aegis +(53651, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x0, 0, 0x2, 0, 0, 0, 0, 0), -- Beacon of Light +(53817, 0, 11, 0x000001C3, 0x00008000, 0x00000000, 0, 0x0, 0x1, 0, 0x8, 0, 0, 0, 0, 0), -- Maelstrom Weapon +(57529, 0, 3, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0, 0), -- Arcane Potency (Rank 1 trigger) +(57531, 0, 3, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0, 0), -- Arcane Potency (Rank 2 trigger) +(58501, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 4, 0, 0, 30000, 0), -- Soul Fire (TC) +(63057, 0, 7, 0x00000000, 0x00040000, 0x00000000, 16384, 0x0, 0x2, 0, 0x0, 0, 0, 0, 0, 0), -- Nourish +(63849, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x0, 0, 0x0, 2, 0, 0, 0, 0), -- Hand of Salvation +(70656, 0, 15, 0x00000000, 0x00000000, 0x00000000, 0, 0x0, 0x1, 0, 0x0, 0, 0, 0, 0, 0), -- Blood Strike (trigger) +(70904, 0, 6, 0x00000000, 0x00000000, 0x00000800, 2048, 0x4, 0x0, 0, 0x0, 0, 0, 0, 1000, 0), -- Shadow Word: Pain (trigger) +(71571, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Gutripper (Normal) +(71573, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Gutripper (Heroic) +(71865, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Unbound Plague +(71868, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Unbound Plague (Heroic) +(71993, 0, 0, 0x00000000, 0x00000000, 0x00000000, 4, 0x0, 0x0, 12287, 0x0, 0, 0, 0, 3000, 0), -- Deathwhisper Necromancer +(72059, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x1, 0x0, 1027, 0x2, 0, 0, 0, 0, 0), -- Frost Damage Immunity +(75490, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x2, 0, 0, 0, 0, 0), -- Frostfire Orb +(75495, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0, 0x2, 0x2, 0, 0x2, 0, 0, 0, 0, 0); -- Frostfire Orb + +-- Sync spell_proc values from TrinityCore +-- SpellFamilyName, SpellFamilyMask, SchoolMask differences +UPDATE `spell_proc` SET `SpellFamilyName`=3, `SpellFamilyMask0`=0, `SpellFamilyMask1`=34, `SpellFamilyMask2`=0, `SchoolMask`=0 WHERE `SpellId`=-31571; +UPDATE `spell_proc` SET `SpellFamilyName`=0, `SpellFamilyMask0`=0, `SpellFamilyMask1`=0, `SpellFamilyMask2`=0, `SchoolMask`=0 WHERE `SpellId`=-29441; +UPDATE `spell_proc` SET `SpellFamilyName`=8, `SpellFamilyMask0`=1107296782, `SpellFamilyMask1`=2, `SpellFamilyMask2`=0, `SchoolMask`=0 WHERE `SpellId`=-14186; +UPDATE `spell_proc` SET `SpellFamilyName`=8, `SpellFamilyMask0`=1191182854, `SpellFamilyMask1`=2097152, `SpellFamilyMask2`=0, `SchoolMask`=0 WHERE `SpellId`=-14143; +UPDATE `spell_proc` SET `SpellFamilyName`=6, `SpellFamilyMask0`=41984016, `SpellFamilyMask1`=9218, `SpellFamilyMask2`=8, `SchoolMask`=32 WHERE `SpellId`=15286; +UPDATE `spell_proc` SET `SpellFamilyName`=7, `SpellFamilyMask0`=268436065, `SpellFamilyMask1`=33554464, `SpellFamilyMask2`=32768, `SchoolMask`=0 WHERE `SpellId`=17116; +UPDATE `spell_proc` SET `SpellFamilyName`=0, `SpellFamilyMask0`=2416967683, `SpellFamilyMask1`=0, `SpellFamilyMask2`=0, `SchoolMask`=0 WHERE `SpellId`=26119; +UPDATE `spell_proc` SET `SpellFamilyName`=3, `SpellFamilyMask0`=0, `SpellFamilyMask1`=0, `SpellFamilyMask2`=0, `SchoolMask`=0 WHERE `SpellId`=44401; +UPDATE `spell_proc` SET `SpellFamilyName`=5, `SpellFamilyMask0`=357, `SpellFamilyMask1`=131264, `SpellFamilyMask2`=0, `SchoolMask`=0 WHERE `SpellId`=54274; +UPDATE `spell_proc` SET `SpellFamilyName`=5, `SpellFamilyMask0`=357, `SpellFamilyMask1`=131264, `SpellFamilyMask2`=0, `SchoolMask`=0 WHERE `SpellId`=54276; +UPDATE `spell_proc` SET `SpellFamilyName`=5, `SpellFamilyMask0`=357, `SpellFamilyMask1`=131264, `SpellFamilyMask2`=0, `SchoolMask`=0 WHERE `SpellId`=54277; +UPDATE `spell_proc` SET `SpellFamilyName`=3, `SpellFamilyMask0`=0, `SpellFamilyMask1`=16384, `SpellFamilyMask2`=0, `SchoolMask`=0 WHERE `SpellId`=56374; +UPDATE `spell_proc` SET `SpellFamilyName`=0, `SpellFamilyMask0`=0, `SpellFamilyMask1`=0, `SpellFamilyMask2`=0, `SchoolMask`=4 WHERE `SpellId`=71756; +UPDATE `spell_proc` SET `SpellFamilyName`=3, `SpellFamilyMask0`=0, `SpellFamilyMask1`=1048576, `SpellFamilyMask2`=0, `SchoolMask`=0 WHERE `SpellId`=71761; +UPDATE `spell_proc` SET `SpellFamilyName`=0, `SpellFamilyMask0`=0, `SpellFamilyMask1`=0, `SpellFamilyMask2`=0, `SchoolMask`=4 WHERE `SpellId`=72782; +UPDATE `spell_proc` SET `SpellFamilyName`=0, `SpellFamilyMask0`=0, `SpellFamilyMask1`=0, `SpellFamilyMask2`=0, `SchoolMask`=4 WHERE `SpellId`=72783; +UPDATE `spell_proc` SET `SpellFamilyName`=0, `SpellFamilyMask0`=0, `SpellFamilyMask1`=0, `SpellFamilyMask2`=0, `SchoolMask`=4 WHERE `SpellId`=72784; + +-- SpellTypeMask, SpellPhaseMask, AttributesMask, Cooldown, HitMask, ProcFlags, Chance sync from TrinityCore +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=100, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-63730; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=64, `Chance`=0 WHERE `SpellId`=-61846; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=8259, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-58872; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=16, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-57878; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=5800, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-56636; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=4, `AttributesMask`=2, `Cooldown`=22000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-56342; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=100, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-54639; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-53569; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-53486; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-53380; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-53290; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=2, `Cooldown`=3500, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-52127; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-51940; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-51634; +UPDATE `spell_proc` SET `SpellTypeMask`=5, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-51625; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=1, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-51521; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-50880; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=500, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-49217; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=100, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-49208; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=1, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-49182; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=20000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-49027; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-48988; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=262144, `Chance`=0 WHERE `SpellId`=-48539; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-47516; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-47509; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=262144, `Chance`=0 WHERE `SpellId`=-47245; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-47195; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-46867; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-46854; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-45234; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=6000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-44557; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=8, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-44449; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-41635; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-34950; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=8000, `HitMask`=1027, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-34935; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=1, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-34753; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-34500; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-33881; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=6000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-33150; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-33142; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-31656; +UPDATE `spell_proc` SET `SpellTypeMask`=7, `SpellPhaseMask`=4, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=16384, `Chance`=0 WHERE `SpellId`=-31571; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=664232, `Chance`=100 WHERE `SpellId`=-30701; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=500, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-30160; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-29723; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=8, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-29074; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-20049; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=262144, `Chance`=0 WHERE `SpellId`=-19572; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=4, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-19184; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=6000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-18094; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-16958; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=500, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-16257; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-16256; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-14892; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=500, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-14186; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=64, `Chance`=0 WHERE `SpellId`=-13165; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-12319; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-11213; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=3, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-11180; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=8, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-10400; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=2, `Cooldown`=3500, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-974; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=2, `Cooldown`=3500, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=-324; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=8, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=1719; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=256, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=7383; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=6000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=7434; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=1, `AttributesMask`=12, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=12536; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=20000, `HitMask`=16, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=13163; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=5000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=15088; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=15286; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=128, `Cooldown`=2000, `HitMask`=0, `ProcFlags`=0, `Chance`=2 WHERE `SpellId`=15600; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=1, `AttributesMask`=0, `Cooldown`=500, `HitMask`=2, `ProcFlags`=65536, `Chance`=0 WHERE `SpellId`=16164; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=1, `AttributesMask`=12, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=16246; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=30000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=16620; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=1, `AttributesMask`=12, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=16870; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=17364; +UPDATE `spell_proc` SET `SpellTypeMask`=7, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=34816, `Chance`=0 WHERE `SpellId`=17619; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=1, `AttributesMask`=8, `Cooldown`=0, `HitMask`=0, `ProcFlags`=65536, `Chance`=0 WHERE `SpellId`=17941; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=20164; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=20165; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=20166; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=20375; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=20784; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=1000, `HitMask`=64, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=22618; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=120000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=22648; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=3500, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=23552; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=1000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=23572; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=23578; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=23581; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=23686; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=23689; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=24353; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=25669; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=16, `Chance`=0 WHERE `SpellId`=26135; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0, `ProcsPerMinute`=10 WHERE `SpellId`=26480; -- `AC` #16777 +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=27656; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=27774; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=262144, `Chance`=0 WHERE `SpellId`=28716; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=28752; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=28845; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=29150; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=29501; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=29624; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=29625; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=29626; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=29632; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=29633; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=29634; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=29635; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=29636; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=29637; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0, `ProcsPerMinute`=18 WHERE `SpellId`=30823; -- `AC` #17499 +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=3500, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=32734; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=35000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=32837; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=32844; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=33297; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=25000, `HitMask`=0, `ProcFlags`=340, `Chance`=15 WHERE `SpellId`=33510; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=33648; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=279552, `Chance`=0 WHERE `SpellId`=33953; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=34074; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=34320; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=3500, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=34355; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=34584; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=34586; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=34598; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=20000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=34774; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=4000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=34827; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=60000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=35077; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=60000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=35080; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=60000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=35083; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=60000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=35086; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=35121; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=36111; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=37170; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=30000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=37173; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=37213; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=40000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=37247; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=37381; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=37600; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=37603; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=37655; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=2500, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=37657; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=256, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=38026; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=120000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=38164; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=38290; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=15000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=38299; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=38334; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=38350; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=38394; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=3500, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=39027; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=1, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=39442; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=39443; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=40000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=39958; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=40438; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=40475; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=40478; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=40482; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=8000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=40899; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=15000, `HitMask`=32, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=41393; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=41434; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=41989; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=42083; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=90000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=42135; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=90000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=42136; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=10000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=43748; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=30000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=43750; +UPDATE `spell_proc` SET `SpellTypeMask`=5, `SpellPhaseMask`=1, `AttributesMask`=8, `Cooldown`=0, `HitMask`=0, `ProcFlags`=69632, `Chance`=0 WHERE `SpellId`=44401; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=1, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=7 WHERE `SpellId`=44543; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=1, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=15 WHERE `SpellId`=44545; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=15000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=45054; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=30000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=45057; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=45354; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=45355; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=45481; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=45482; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=45483; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=16384, `Chance`=0 WHERE `SpellId`=45484; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=46569; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=25000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=46662; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=15000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=46832; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=4, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=46916; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=10000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=48833; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=10000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=48837; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=2000, `HitMask`=0, `ProcFlags`=139944, `Chance`=0 WHERE `SpellId`=49222; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=8528552, `Chance`=0 WHERE `SpellId`=49592; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=49622; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=4, `AttributesMask`=8, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=49796; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=4, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=50240; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=4, `AttributesMask`=8, `Cooldown`=0, `HitMask`=0, `ProcFlags`=65552, `Chance`=0 WHERE `SpellId`=51124; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=4, `AttributesMask`=0, `Cooldown`=1000, `HitMask`=2, `ProcFlags`=0, `Chance`=33 WHERE `SpellId`=51698; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=4, `AttributesMask`=0, `Cooldown`=1000, `HitMask`=2, `ProcFlags`=0, `Chance`=66 WHERE `SpellId`=51700; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=4, `AttributesMask`=0, `Cooldown`=1000, `HitMask`=2, `ProcFlags`=0, `Chance`=100 WHERE `SpellId`=51701; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=10000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=52020; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=30000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=52420; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=32, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=52423; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=4, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=16, `Chance`=0 WHERE `SpellId`=52437; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=6000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=52898; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=53397; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=5000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=53646; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=54278; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=54646; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=54695; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=54707; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=54754; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=54808; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=2500, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=54841; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=54909; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=40000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=55380; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=55440; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=60000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=55640; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=55689; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=55747; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=55000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=55776; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=6000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=56218; +UPDATE `spell_proc` SET `SpellTypeMask`=4, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=2049, `ProcFlags`=65536, `Chance`=0 WHERE `SpellId`=56375; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=3500, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=56451; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=500, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=56821; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=57345; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=57351; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=262144, `Chance`=0 WHERE `SpellId`=57870; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=57907; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=30000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=58442; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=5000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=58444; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=58901; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=6000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=59176; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=59345; +UPDATE `spell_proc` SET `SpellTypeMask`=5, `SpellPhaseMask`=1, `AttributesMask`=2, `Cooldown`=35000, `HitMask`=0, `ProcFlags`=69648, `Chance`=0 WHERE `SpellId`=59630; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=294912, `Chance`=0 WHERE `SpellId`=60061; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60066; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60170; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=262144, `Chance`=0 WHERE `SpellId`=60176; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60221; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60301; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60306; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60317; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60436; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60442; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60473; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=15000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60487; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60519; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60529; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=30000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60770; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=60826; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=61188; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=61356; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=61618; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=62114; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=62115; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=63251; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=1, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=63280; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=279552, `Chance`=0 WHERE `SpellId`=64411; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=279552, `Chance`=0 WHERE `SpellId`=64415; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=32, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=64440; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=64738; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=15000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=64752; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=64786; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=64792; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=64824; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=64860; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=64867; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=64890; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=64914; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=65002; +UPDATE `spell_proc` SET `SpellTypeMask`=3, `SpellPhaseMask`=1, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=81920, `Chance`=0 WHERE `SpellId`=65007; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=65013; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=65020; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=65025; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=67151; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=15000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=67209; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=8000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=67353; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=5000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=67356; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=6000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=67361; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=8000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=67363; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=8000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=67365; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=9000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=67379; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=9000, `HitMask`=0, `ProcFlags`=16, `Chance`=0 WHERE `SpellId`=67392; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=67653; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=8388948, `Chance`=0 WHERE `SpellId`=67672; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=67702; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=2000, `HitMask`=2, `ProcFlags`=69632, `Chance`=0 WHERE `SpellId`=67712; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=2000, `HitMask`=2, `ProcFlags`=69632, `Chance`=0 WHERE `SpellId`=67758; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=67771; +UPDATE `spell_proc` SET `SpellTypeMask`=7, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=69739; +UPDATE `spell_proc` SET `SpellTypeMask`=7, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=69755; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=1, `AttributesMask`=256, `Cooldown`=100, `HitMask`=0, `ProcFlags`=87040, `Chance`=0 WHERE `SpellId`=69762; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=3000, `HitMask`=16, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=70188; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=70664; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=12287, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=70672; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=70727; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=70730; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=4, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=70803; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=1, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=70811; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=70841; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=70854; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71174; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71176; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71178; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71198; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71402; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=2, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71404; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=50 WHERE `SpellId`=71406; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71540; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=50 WHERE `SpellId`=71545; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=1, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71585; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=1, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=65536, `Chance`=0 WHERE `SpellId`=71602; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=100000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71606; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=30000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71634; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=100000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71637; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=30000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71640; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=1, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=65536, `Chance`=0 WHERE `SpellId`=71645; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71756; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=3000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71770; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=71903; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=60000, `HitMask`=0, `ProcFlags`=0, `Chance`=10 WHERE `SpellId`=72413; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=60000, `HitMask`=0, `ProcFlags`=327680, `Chance`=0 WHERE `SpellId`=72417; +UPDATE `spell_proc` SET `SpellTypeMask`=2, `SpellPhaseMask`=1, `AttributesMask`=0, `Cooldown`=60000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=72419; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=12287, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=72455; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=72782; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=72783; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=2, `Cooldown`=0, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=72784; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=12287, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=72832; +UPDATE `spell_proc` SET `SpellTypeMask`=0, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=0, `HitMask`=12287, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=72833; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=75455; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=2, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=75457; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=1, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=75465; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=1, `AttributesMask`=0, `Cooldown`=50000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=75474; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=75475; +UPDATE `spell_proc` SET `SpellTypeMask`=1, `SpellPhaseMask`=0, `AttributesMask`=0, `Cooldown`=45000, `HitMask`=0, `ProcFlags`=0, `Chance`=0 WHERE `SpellId`=75481; + +-- Missing TC spell_proc entries +DELETE FROM `spell_proc` WHERE `SpellId` IN (60617, 71567); +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +(60617, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0), -- Unknown (proc on absorb) +(71567, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 250, 0); -- ICC buff (heal proc) + +-- Fix duplicate entries (remove positive when negative already covers all ranks) +DELETE FROM `spell_proc` WHERE `SpellId` IN (9452, 44546, 49027, 59887); + +-- Delete AC-specific entries that don't exist in TC's spell_proc (they cause warnings and aren't needed) +DELETE FROM `spell_proc` WHERE `SpellId` IN (-16086, 62933); + +-- Delete AC-specific legacy entries that don't exist in TC's spell_proc +-- These have invalid ProcFlags/SpellPhaseMask combinations and cause warnings +DELETE FROM `spell_proc` WHERE `SpellId` IN ( + 16086, -- Piercing Howl (rank handling) + 15257, 15331, 15332, -- Priest Shadow Weaving (handled by AuraScript) + 21747, -- Raptorslayer + 24256, -- Judgement of Crusader + 27997, -- Spell Vulnerability + 28460, -- Mojo Madness + 31221, 31222, 31223, -- Master of Subtlety + 33511, 33522, -- Concussion/Daze + 37565, -- Magma Shield + 38319, -- Mojo Madness + 40303, -- Thrash + 42760, -- Dark Transformation + 43730, -- Stormchops + 43983, -- Fiery Payback + 44835, -- Maim Interrupt + 45278, -- Chaos Bolt + 45396, 45398, -- Blackout + 45444, -- Totem of Ancestral Guidance + 46102, -- Living Flame + 54404, -- Demonic Immolation + 55610, -- Improved Icy Talons + 55717, -- Venom + 56845, -- Glyph of Seal of Command + 58426, -- Overkill + 59888, 59889, 59890, 59891, -- Borrowed Time ranks + 64936, -- Flame Leviathan Residue + 70871 -- Essence of the Blood Queen +); + +-- Fix additional duplicate entries +DELETE FROM `spell_proc` WHERE `SpellId` IN (26016, 44548, 44549, 49542, 49543); + +-- Fix spell_script_names bindings for proc system +-- Remove 44401 from spell_mage_gen_extra_effects (TC uses separate handler) +DELETE FROM `spell_script_names` WHERE `spell_id` = 44401 AND `ScriptName` = 'spell_mage_gen_extra_effects'; + +-- Fix Savage Defense binding (script is for 62606 absorb buff, not 62600 passive) +DELETE FROM `spell_script_names` WHERE `spell_id` = 62600 AND `ScriptName` = 'spell_dru_savage_defense'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (62606, 'spell_dru_savage_defense'); + +-- Fix Ancestral Awakening binding (was incorrectly bound to -51474 Astral Shift, should be -51556 Ancestral Awakening) +DELETE FROM `spell_script_names` WHERE `spell_id` = -51474 AND `ScriptName` = 'spell_sha_ancestral_awakening'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (-51556, 'spell_sha_ancestral_awakening'); + +-- Remove obsolete reload spell_proc_event command (replaced by spell_proc) +DELETE FROM `command` WHERE `name` = 'reload spell_proc_event'; + +-- Fingers of Frost - register script for charge consumption buff (74396) +DELETE FROM `spell_script_names` WHERE `spell_id` = 74396 AND `ScriptName` = 'spell_mage_fingers_of_frost'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(74396, 'spell_mage_fingers_of_frost'); + +-- Remove non-existent Fingers of Frost script entries +-- spell_mage_fingers_of_frost_proc and spell_mage_fingers_of_frost_proc_aura don't exist in code +-- The proc system now handles charge consumption via PrepareProcToTrigger +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_mage_fingers_of_frost_proc'; +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_mage_fingers_of_frost_proc_aura'; + +-- Sheath of Light: procs on critical heals (from TrinityCore) +-- ProcFlags=0 uses DBC flags, SpellTypeMask=2 (HEAL), SpellPhaseMask=2 (HIT), HitMask=2 (CRITICAL) +DELETE FROM `spell_proc` WHERE `SpellId` = -53501; +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +(-53501, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0); + +-- Fix Cut to the Chase spell_script_names (was incorrectly registered to Combat Potency -35541) +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_rog_cut_to_the_chase'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (-51664, 'spell_rog_cut_to_the_chase'); + +-- Fix Decimation DisableEffectsMask (was 0, should be 2 to disable EFFECT_1 from proccing) +UPDATE `spell_proc` SET `DisableEffectsMask` = 2 WHERE `SpellId` = -63156; + +-- Vendetta: add missing spell_script_names entry (from TrinityCore) +DELETE FROM `spell_script_names` WHERE `spell_id` = -49015 AND `ScriptName` = 'spell_dk_vendetta'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (-49015, 'spell_dk_vendetta'); + +-- Remove duplicate spell_dk_runic_power_back_on_snare_root (TC only has spell_dk_pvp_4p_bonus for 61257) +DELETE FROM `spell_script_names` WHERE `spell_id` = 61257 AND `ScriptName` = 'spell_dk_runic_power_back_on_snare_root'; + +-- Lightning Shield: add missing spell_script_names entry +DELETE FROM `spell_script_names` WHERE `spell_id` = -324 AND `ScriptName` = 'spell_sha_lightning_shield'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (-324, 'spell_sha_lightning_shield'); + +-- Nightfall (Glyph of Corruption): add missing spell_script_names entry +DELETE FROM `spell_script_names` WHERE `spell_id` = 56218 AND `ScriptName` = 'spell_warl_nightfall'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (56218, 'spell_warl_nightfall'); + +-- Drop obsolete spell_proc_event table (replaced by spell_proc) +DROP TABLE IF EXISTS `spell_proc_event`; + +-- Darkmoon Card: Greatness - Register script to handle proc based on highest stat +DELETE FROM `spell_script_names` WHERE `spell_id` = 57345; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(57345, 'spell_item_darkmoon_card_greatness'); + +-- Death's Choice / Death's Verdict - Register script to handle proc based on highest stat (Str vs Agi) +DELETE FROM `spell_script_names` WHERE `spell_id` IN (67702, 67771); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(67702, 'spell_item_death_choice'), +(67771, 'spell_item_death_choice'); + +-- Soul Preserver - Register script to handle proc based on class +DELETE FROM `spell_script_names` WHERE `spell_id` = 60510; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(60510, 'spell_item_soul_preserver'); + +-- Amani Charm of the Witch Doctor - Register script to handle heal proc +DELETE FROM `spell_script_names` WHERE `spell_id` = 43820; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(43820, 'spell_item_charm_witch_doctor'); + +-- Lifegiving Gem - Gift of Life spell +DELETE FROM `spell_script_names` WHERE `spell_id` = 23725; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(23725, 'spell_item_lifegiving_gem'); + +-- Mana Drain - proc script for mana drain items +DELETE FROM `spell_script_names` WHERE `spell_id` IN (27522, 40336); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(27522, 'spell_item_mana_drain'), +(40336, 'spell_item_mana_drain'); + +-- Gnomish Mind Control Cap +DELETE FROM `spell_script_names` WHERE `spell_id` = 13180; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(13180, 'spell_item_mind_control_cap'); + +-- Hourglass Sand +DELETE FROM `spell_script_names` WHERE `spell_id` = 30536; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(30536, 'spell_item_hourglass_sand'); + +-- Ultrasafe Transporter: Toshley's Station +DELETE FROM `spell_script_names` WHERE `spell_id` = 36941; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(36941, 'spell_item_ultrasafe_transporter'); + +-- Power Circle (Mage T5 Set Bonus) +DELETE FROM `spell_script_names` WHERE `spell_id` = 45043; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(45043, 'spell_item_power_circle'); + +-- Thrallmar's Favor / Honor Hold's Favor +DELETE FROM `spell_script_names` WHERE `spell_id` IN (32096, 32098); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(32096, 'spell_item_thrallmar_and_honor_hold_favor'), +(32098, 'spell_item_thrallmar_and_honor_hold_favor'); + +-- Drums of Forgotten Kings +DELETE FROM `spell_script_names` WHERE `spell_id` = 69378; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(69378, 'spell_item_drums_of_forgotten_kings'); + +-- Drums of the Wild +DELETE FROM `spell_script_names` WHERE `spell_id` = 69381; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(69381, 'spell_item_drums_of_the_wild'); + +-- Darkmoon Card: Illusion +DELETE FROM `spell_script_names` WHERE `spell_id` = 57350; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(57350, 'spell_item_darkmoon_card_illusion'); + +-- Mad Alchemist's Potion +DELETE FROM `spell_script_names` WHERE `spell_id` = 28374; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(28374, 'spell_item_mad_alchemists_potion'); + +-- Decahedral Dwarven Dice +DELETE FROM `spell_script_names` WHERE `spell_id` = 47770; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(47770, 'spell_item_decahedral_dwarven_dice'); + +-- Arena Drink - modifies drink mana regen behavior in arenas +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_gen_arena_drink'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(430, 'spell_gen_arena_drink'), +(431, 'spell_gen_arena_drink'), +(432, 'spell_gen_arena_drink'), +(1133, 'spell_gen_arena_drink'), +(1135, 'spell_gen_arena_drink'), +(1137, 'spell_gen_arena_drink'), +(10250, 'spell_gen_arena_drink'), +(22734, 'spell_gen_arena_drink'), +(27089, 'spell_gen_arena_drink'), +(34291, 'spell_gen_arena_drink'), +(43182, 'spell_gen_arena_drink'), +(43183, 'spell_gen_arena_drink'), +(46755, 'spell_gen_arena_drink'), +(49472, 'spell_gen_arena_drink'), +(57073, 'spell_gen_arena_drink'), +(61830, 'spell_gen_arena_drink'), +(72623, 'spell_gen_arena_drink'); + +-- Remove scripts with DBC mismatches (spell effects don't match AC's DBC) +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ( +'spell_item_nitro_boosts', +'spell_item_nitro_boosts_backfire', +'spell_item_harm_prevention_belt', +'spell_item_dire_brew', +'spell_item_dimensional_ripper_everlook', +'spell_item_red_rider_air_rifle', +'spell_item_runic_healing_injector', +'spell_item_taunt_flag_targeting', +'spell_item_extract_gas', +'spell_item_disco_ball_listening_to_music_periodic', +'spell_item_disco_ball_listening_to_music_check', +'spell_item_disco_ball_listening_to_music_parent' +); diff --git a/data/sql/updates/pending_db_world/rev_1769292856469402686.sql b/data/sql/updates/pending_db_world/rev_1769292856469402686.sql new file mode 100644 index 000000000..ad6cd3321 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769292856469402686.sql @@ -0,0 +1,105 @@ +-- Lock and Load - Add spell_proc entry with correct SpellPhaseMask for periodic damage procs +-- SpellPhaseMask changed from 4 (PROC_SPELL_PHASE_FINISH) to 2 (PROC_SPELL_PHASE_HIT) +-- This allows Black Arrow, Explosive Trap, and Immolation Trap periodic damage to trigger Lock and Load +DELETE FROM `spell_proc` WHERE `SpellId` = -56342; +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +(-56342, 0, 9, 24, 134217728, 147456, 0, 0, 2, 0, 2, 0, 0, 0, 22000, 0); + +-- Killing Machine - register spell script +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_dk_killing_machine'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(51124, 'spell_dk_killing_machine'); + +-- Elemental Focus - register spell script to prevent weapon imbue attacks from proccing Clearcasting +DELETE FROM `spell_script_names` WHERE `spell_id` = 16164 AND `ScriptName` = 'spell_sha_elemental_focus'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(16164, 'spell_sha_elemental_focus'); + +-- Light's Beacon (53651) - Beacon of Light heal transfer script +DELETE FROM `spell_script_names` WHERE `spell_id` = 53651; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(53651, 'spell_pal_light_s_beacon'); + +-- Mage spell scripts from TrinityCore proc system port +DELETE FROM `spell_script_names` WHERE `spell_id` IN (-5143, -31661, -44614, 45438, 44401); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-5143, 'spell_mage_arcane_missiles'), +(-31661, 'spell_mage_dragon_breath'), +(-44614, 'spell_mage_frostfire_bolt'), +(45438, 'spell_mage_ice_block'), +(44401, 'spell_mage_missile_barrage_proc'); + +-- Paladin scripts refactored from hardcoded SpellAuras.cpp and Spell.cpp to proper scripts +-- Aura Mastery (31821) - Applies/removes Aura Mastery Immune aura +DELETE FROM `spell_script_names` WHERE `spell_id` = 31821; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(31821, 'spell_pal_aura_mastery'); + +-- Aura Mastery Immune (64364) - Area target check to filter immunity to only Concentration Aura targets +DELETE FROM `spell_script_names` WHERE `spell_id` = 64364; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(64364, 'spell_pal_aura_mastery_immune'); + +-- Beacon of Light (53563) - Periodic tick handler to ensure correct caster GUID propagation +DELETE FROM `spell_script_names` WHERE `spell_id` = 53563 AND `ScriptName` = 'spell_pal_beacon_of_light'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(53563, 'spell_pal_beacon_of_light'); + +-- Sacred Shield (58597) - Absorb amount calculation with ICC buff support +DELETE FROM `spell_script_names` WHERE `spell_id` = 58597 AND `ScriptName` = 'spell_pal_sacred_shield'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(58597, 'spell_pal_sacred_shield'); + +-- Divine Protection (498), Divine Shield (642), Hand of Protection (-1022) +-- Applies Forbearance, Avenging Wrath marker, and Immune Shield marker +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_pal_immunities'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(498, 'spell_pal_immunities'), +(642, 'spell_pal_immunities'), +(-1022, 'spell_pal_immunities'); + +-- Improved Concentration Aura (-20254), Improved Devotion Aura (-20138) +-- Sanctified Retribution (31869), Swift Retribution (-53379) +-- Handles applying/removing the improved aura buff effects +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_pal_improved_concentraction_aura', 'spell_pal_improved_devotion_aura', 'spell_pal_sanctified_retribution', 'spell_pal_swift_retribution'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-20254, 'spell_pal_improved_concentraction_aura'), +(-20138, 'spell_pal_improved_devotion_aura'), +(31869, 'spell_pal_sanctified_retribution'), +(-53379, 'spell_pal_swift_retribution'); + +-- Warrior scripts - Vigilance redirect threat and Warrior's Wrath (T2 5P) +DELETE FROM `spell_script_names` WHERE `spell_id` IN (59665, 21977); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(59665, 'spell_warr_vigilance_redirect_threat'), +(21977, 'spell_warr_warriors_wrath'); + +-- Druid Forms Trinket (37336) - SpellPhaseMask required for proc system +-- ProcFlags=0 uses DBC flags (0x15414), Chance=0 uses DBC chance (3%) +DELETE FROM `spell_proc` WHERE `SpellId` = 37336; +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +(37336, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0); + +-- Living Root of the Wildheart (37336) - Item trinket script +DELETE FROM `spell_script_names` WHERE `spell_id` = 37336; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(37336, 'spell_item_living_root_of_the_wildheart'); + +-- Druid scripts ported from TrinityCore +-- Frenzied Regeneration (22842) - Converts rage to health +-- Nourish (50464) - Glyph of Nourish support +-- Insect Swarm (-5570) - T8 Balance Relic support +-- T9 Feral Relic (67353) - Idol of Mutilation form-specific procs +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_dru_frenzied_regeneration', 'spell_dru_nourish', 'spell_dru_insect_swarm', 'spell_dru_t9_feral_relic'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(22842, 'spell_dru_frenzied_regeneration'), +(50464, 'spell_dru_nourish'), +(-5570, 'spell_dru_insect_swarm'), +(67353, 'spell_dru_t9_feral_relic'); + +-- Priest scripts ported from TrinityCore +-- Pain and Suffering (-47580) - Prevents EFFECT_1 DUMMY from proccing +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_pri_pain_and_suffering_dummy'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(47580, 'spell_pri_pain_and_suffering_dummy'), +(47581, 'spell_pri_pain_and_suffering_dummy'); diff --git a/data/sql/updates/pending_db_world/rev_1769396722032747978.sql b/data/sql/updates/pending_db_world/rev_1769396722032747978.sql new file mode 100644 index 000000000..608335533 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769396722032747978.sql @@ -0,0 +1,18 @@ +-- +DELETE FROM `spell_script_names` WHERE `spell_id` IN (52179, 16246, 16191, -30881, 55278, 55328, 55329, 55330, 55332, 55333, 55335, 58589, 58590, 58591, 28820); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(52179, 'spell_sha_astral_shift_visual_dummy'), +(16246, 'spell_sha_clearcasting'), +(16191, 'spell_sha_mana_tide'), +(-30881, 'spell_sha_nature_guardian'), +(55278, 'spell_sha_stoneclaw_totem'), +(55328, 'spell_sha_stoneclaw_totem'), +(55329, 'spell_sha_stoneclaw_totem'), +(55330, 'spell_sha_stoneclaw_totem'), +(55332, 'spell_sha_stoneclaw_totem'), +(55333, 'spell_sha_stoneclaw_totem'), +(55335, 'spell_sha_stoneclaw_totem'), +(58589, 'spell_sha_stoneclaw_totem'), +(58590, 'spell_sha_stoneclaw_totem'), +(58591, 'spell_sha_stoneclaw_totem'), +(28820, 'spell_sha_t3_8p_bonus'); diff --git a/data/sql/updates/pending_db_world/rev_1769728867586741519.sql b/data/sql/updates/pending_db_world/rev_1769728867586741519.sql new file mode 100644 index 000000000..5e420fa88 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769728867586741519.sql @@ -0,0 +1,31 @@ +-- Register Nether Protection spell script +DELETE FROM `spell_script_names` WHERE `spell_id` = -30299; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-30299, 'spell_warl_nether_protection'); + +-- Register Curse of Agony spell script +DELETE FROM `spell_script_names` WHERE `spell_id` = -980; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-980, 'spell_warl_curse_of_agony'); + +-- Fix Nightfall and Glyph of Corruption registrations +DELETE FROM `spell_script_names` WHERE `spell_id` = -18094; +DELETE FROM `spell_script_names` WHERE `spell_id` = 56218; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-18094, 'spell_warl_nightfall'), +(56218, 'spell_warl_glyph_of_corruption_nightfall'); + +-- Register Acclimation spell script (DK) +DELETE FROM `spell_script_names` WHERE `spell_id` = -49200; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-49200, 'spell_dk_acclimation'); + +-- Register Advantage T10 4P spell script (DK) +DELETE FROM `spell_script_names` WHERE `spell_id` = 70656; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(70656, 'spell_dk_advantage_t10_4p'); + +-- Register Glyph of Barkskin spell script (Druid) +DELETE FROM `spell_script_names` WHERE `spell_id` = 63057; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(63057, 'spell_dru_glyph_of_barkskin'); diff --git a/data/sql/updates/pending_db_world/rev_1769815350392767493.sql b/data/sql/updates/pending_db_world/rev_1769815350392767493.sql new file mode 100644 index 000000000..0674f3d60 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769815350392767493.sql @@ -0,0 +1,4 @@ +-- Hunter T9 4P Bonus - spell script registration +DELETE FROM `spell_script_names` WHERE `spell_id` = 67151; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(67151, 'spell_hun_t9_4p_bonus'); diff --git a/data/sql/updates/pending_db_world/rev_1769974041727457907.sql b/data/sql/updates/pending_db_world/rev_1769974041727457907.sql new file mode 100644 index 000000000..830ecbf62 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769974041727457907.sql @@ -0,0 +1,2 @@ +-- Omen of Clarity should only proc from damage and healing spells, not utility spells like Furor +UPDATE `spell_proc` SET `SpellTypeMask` = 3 WHERE `SpellId` = 16864; diff --git a/data/sql/updates/pending_db_world/rev_1769983684458633094.sql b/data/sql/updates/pending_db_world/rev_1769983684458633094.sql new file mode 100644 index 000000000..75c212cd0 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1769983684458633094.sql @@ -0,0 +1,8 @@ +-- +-- The Lightning Capacitor, Thunder Capacitor, Reign of the Dead/Unliving trinkets +DELETE FROM `spell_script_names` WHERE `spell_id` IN (37657, 54841, 67712, 67758); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(37657, 'spell_item_lightning_capacitor'), +(54841, 'spell_item_thunder_capacitor'), +(67712, 'spell_item_toc25_caster_trinket_normal'), +(67758, 'spell_item_toc25_caster_trinket_heroic'); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 47d15362a..a27181eec 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7372,7 +7372,7 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 if (entry) { if (entry->PPMChance) - chance = GetPPMProcChance(proto->Delay, entry->PPMChance, spellInfo); + chance = GetPPMProcChance(GetAttackTime(attType), entry->PPMChance, spellInfo); else if (entry->customChance) chance = (float)entry->customChance; } @@ -9745,8 +9745,8 @@ bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod if (!mod || !spellInfo) return false; - // Mod out of charges - if (spell && mod->charges == -1 && spell->m_appliedMods.find(mod->ownerAura) == spell->m_appliedMods.end()) + // First time this aura applies a mod to us and is out of charges + if (spell && mod->ownerAura && mod->ownerAura->IsUsingCharges() && !mod->ownerAura->GetCharges() && !spell->m_appliedMods.count(mod->ownerAura)) return false; // +duration to infinite duration spells making them limited @@ -9769,7 +9769,7 @@ void Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* s auto calculateSpellMod = [&](SpellModifier* mod) { // xinef: temporary pets cannot use charged mods of owner, needed for mirror image QQ they should use their own auras - if (temporaryPet && mod->charges != 0) + if (temporaryPet && mod->ownerAura && mod->ownerAura->IsUsingCharges()) return; // skip if already instant or cost is free @@ -9801,10 +9801,10 @@ void Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* s if (mod->op == SPELLMOD_CASTING_TIME && basevalue >= T(10000) && mod->value <= -100) return; // xinef: special exception for surge of light, dont affect crit chance if previous mods were not applied - else if (mod->op == SPELLMOD_CRITICAL_CHANCE && spell && !HasSpellMod(mod, spell)) + else if (mod->op == SPELLMOD_CRITICAL_CHANCE && !HasSpellModApplied(mod, spell)) return; // xinef: special case for backdraft gcd reduce with backlast time reduction, dont affect gcd if cast time was not applied - else if (mod->op == SPELLMOD_GLOBAL_COOLDOWN && spell && !HasSpellMod(mod, spell)) + else if (mod->op == SPELLMOD_GLOBAL_COOLDOWN && !HasSpellModApplied(mod, spell)) return; // xinef: those two mods should be multiplicative (Glyph of Renew) @@ -9814,7 +9814,7 @@ void Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* s totalmul += CalculatePct(1.0f, mod->value); } - DropModCharge(mod, spell); + ApplyModToSpell(mod, spell); }; // Drop charges for triggering spells instead of triggered ones @@ -9823,10 +9823,6 @@ void Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* s for (auto mod : m_spellMods[op]) { - // Charges can be set only for mods with auras - if (!mod->ownerAura) - ASSERT(!mod->charges); - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) continue; @@ -9843,17 +9839,6 @@ template AC_GAME_API void Player::ApplySpellMod(uint32 spellId, SpellModOp op, i template AC_GAME_API void Player::ApplySpellMod(uint32 spellId, SpellModOp op, uint32& basevalue, Spell* spell, bool temporaryPet); template AC_GAME_API void Player::ApplySpellMod(uint32 spellId, SpellModOp op, float& basevalue, Spell* spell, bool temporaryPet); -// Binary predicate for sorting SpellModifiers -struct SpellModPredicate -{ - bool operator() (SpellModifier const* a, SpellModifier const* b) const - { - if (a->type != b->type) - return a->type == SPELLMOD_FLAT; - return a->priority > b->priority; - } -}; - void Player::AddSpellMod(SpellModifier* mod, bool apply) { LOG_DEBUG("spells.aura", "Player::AddSpellMod {}", mod->spellId); @@ -9870,7 +9855,7 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply) if (mod->mask & _mask) { int32 val = 0; - for (SpellModList::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr) + for (SpellModContainer::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr) { if ((*itr)->type == mod->type && (*itr)->mask & _mask) val += (*itr)->value; @@ -9886,12 +9871,11 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply) if (apply) { - m_spellMods[mod->op].push_back(mod); - m_spellMods[mod->op].sort(SpellModPredicate()); + m_spellMods[mod->op].insert(mod); } else { - m_spellMods[mod->op].remove(mod); + m_spellMods[mod->op].erase(mod); // mods bound to aura will be removed in AuraEffect::~AuraEffect if (!mod->ownerAura) delete mod; @@ -9908,7 +9892,7 @@ void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId, Aura* aura) for (uint8 i = 0; i < MAX_SPELLMOD; ++i) { - for (SpellModList::iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end(); ++itr) + for (SpellModContainer::iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end(); ++itr) { SpellModifier* mod = *itr; @@ -9937,20 +9921,6 @@ void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId, Aura* aura) // from applied mods (Else, an aura with two mods on the current spell would // only see the first of its modifier restored) aurasQueue.push_back(mod->ownerAura); - - // add mod charges back to mod - if (mod->charges == -1) - mod->charges = 1; - else - mod->charges++; - - // Do not set more spellmods than available - if (mod->ownerAura->GetCharges() < mod->charges) - mod->charges = mod->ownerAura->GetCharges(); - - // Skip this check for now - aura charges may change due to various reason - /// @todo track these changes correctly - //ASSERT (mod->ownerAura->GetCharges() <= mod->charges); } } @@ -9985,14 +9955,14 @@ void Player::RemoveSpellMods(Spell* spell) for (uint8 i = 0; i < MAX_SPELLMOD; ++i) { - for (SpellModList::const_iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end();) + for (SpellModContainer::const_iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end();) { SpellModifier* mod = *itr; ++itr; - // don't handle spells with proc_event entry defined + // don't handle spells with spell_proc entry defined // this is a temporary workaround, because all spellmods should be handled like that - if (sSpellMgr->GetSpellProcEvent(mod->spellId)) + if (sSpellMgr->GetSpellProcEntry(mod->spellId)) { continue; } @@ -10018,20 +9988,14 @@ void Player::RemoveSpellMods(Spell* spell) if (sp->SpellIconID == 3261 || sp->SpellIconID == 2999 || sp->SpellIconID == 2938) if (AuraEffect* aurEff = GetAuraEffectDummy(64869)) if (roll_chance_i(aurEff->GetAmount())) - { - mod->charges = 1; - continue; - } + continue; // don't consume charge } // ROGUE MUTILATE WITH COLD BLOOD if (spellInfo->Id == 5374) { SpellInfo const* sp = mod->ownerAura->GetSpellInfo(); if (sp->Id == 14177) // Cold Blood - { - mod->charges = 1; - continue; - } + continue; // don't consume charge } if (mod->ownerAura->DropCharge(AURA_REMOVE_BY_EXPIRE)) @@ -10040,15 +10004,25 @@ void Player::RemoveSpellMods(Spell* spell) } } -void Player::DropModCharge(SpellModifier* mod, Spell* spell) +void Player::ApplyModToSpell(SpellModifier* mod, Spell* spell) { - if (spell && mod->ownerAura && mod->charges > 0) - { - if (--mod->charges == 0) - mod->charges = -1; + if (!spell) + return; - spell->m_appliedMods.insert(mod->ownerAura); - } + // don't do anything with no charges + if (mod->ownerAura->IsUsingCharges() && !mod->ownerAura->GetCharges()) + return; + + // register inside spell, proc system uses this to drop charges + spell->m_appliedMods.insert(mod->ownerAura); +} + +bool Player::HasSpellModApplied(SpellModifier* mod, Spell* spell) +{ + if (!spell) + return false; + + return spell->m_appliedMods.count(mod->ownerAura) != 0; } void Player::SetSpellModTakingSpell(Spell* spell, bool apply) @@ -11770,6 +11744,9 @@ void Player::ApplyEquipCooldown(Item* pItem) if (pItem->GetTemplate()->HasFlag(ITEM_FLAG_NO_EQUIP_COOLDOWN)) return; + if (GetCommandStatus(CHEAT_COOLDOWN)) + return; + for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) { _Spell const& spellData = pItem->GetTemplate()->Spells[i]; @@ -11778,11 +11755,15 @@ void Player::ApplyEquipCooldown(Item* pItem) if (!spellData.SpellId) continue; - // xinef: apply hidden cooldown for procs + // apply proc cooldown to equip auras if we have any if (spellData.SpellTrigger == ITEM_SPELLTRIGGER_ON_EQUIP) { - // xinef: uint32(-1) special marker for proc cooldowns - AddSpellCooldown(spellData.SpellId, uint32(-1), 30 * IN_MILLISECONDS); + SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(spellData.SpellId); + if (!procEntry) + continue; + + if (Aura* itemAura = GetAura(spellData.SpellId, GetGUID(), pItem->GetGUID())) + itemAura->AddProcCooldown(std::chrono::steady_clock::now() + std::chrono::seconds(30)); continue; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index d6cb920ee..32c191702 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -180,20 +180,19 @@ enum TalentTree // talent tabs // Spell modifier (used for modify other spells) struct SpellModifier { - SpellModifier(Aura* _ownerAura = nullptr) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), charges(0), mask(), ownerAura(_ownerAura) {} - SpellModOp op : 8; - SpellModType type : 8; - int16 charges : 16; - int32 value{0}; + SpellModifier(Aura* _ownerAura = nullptr) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), value(0), mask(), spellId(0), ownerAura(_ownerAura) {} + + SpellModOp op; + SpellModType type; + int32 value; flag96 mask; - uint32 spellId{0}; + uint32 spellId; Aura* const ownerAura; - uint32 priority{0}; }; typedef std::unordered_map PlayerTalentMap; typedef std::unordered_map PlayerSpellMap; -typedef std::list SpellModList; +typedef std::unordered_set SpellModContainer; typedef GuidList WhisperListContainer; @@ -1801,7 +1800,8 @@ public: void RemoveSpellMods(Spell* spell); void RestoreSpellMods(Spell* spell, uint32 ownerAuraId = 0, Aura* aura = nullptr); void RestoreAllSpellMods(uint32 ownerAuraId = 0, Aura* aura = nullptr); - void DropModCharge(SpellModifier* mod, Spell* spell); + static void ApplyModToSpell(SpellModifier* mod, Spell* spell); + [[nodiscard]] static bool HasSpellModApplied(SpellModifier* mod, Spell* spell); void SetSpellModTakingSpell(Spell* spell, bool apply); [[nodiscard]] bool HasSpellCooldown(uint32 spell_id) const override; @@ -2640,7 +2640,7 @@ public: // mt maps [[nodiscard]] const PlayerTalentMap& GetTalentMap() const { return m_talents; } [[nodiscard]] uint32 GetNextSave() const { return m_nextSave; } - [[nodiscard]] SpellModList const& GetSpellModList(uint32 type) const { return m_spellMods[type]; } + [[nodiscard]] SpellModContainer const& GetSpellModList(uint32 type) const { return m_spellMods[type]; } void SetServerSideVisibility(ServerSideVisibilityType type, AccountTypes sec); void SetServerSideVisibilityDetect(ServerSideVisibilityType type, AccountTypes sec); @@ -2873,7 +2873,7 @@ protected: uint32 m_baseHealthRegen; int32 m_spellPenetrationItemMod; - SpellModList m_spellMods[MAX_SPELLMOD]; + SpellModContainer m_spellMods[MAX_SPELLMOD]; //uint32 m_pad; // Spell* m_spellModTakingSpell; // Spell for which charges are dropped in spell::finish diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 5352f8b40..9f63466b1 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -99,20 +99,9 @@ float playerBaseMoveSpeed[MAX_MOVE_TYPE] = 3.14f // MOVE_PITCH_RATE }; -// Used for prepare can/can`t triggr aura -static bool InitTriggerAuraData(); -// Define can trigger auras -static bool isTriggerAura[TOTAL_AURAS]; -// Define can't trigger auras (need for disable second trigger) -static bool isNonTriggerAura[TOTAL_AURAS]; -// Triggered always, even from triggered spells -static bool isAlwaysTriggeredAura[TOTAL_AURAS]; -// Prepare lists -static bool procPrepared = InitTriggerAuraData(); - DamageInfo::DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType, uint32 cleanDamage) : m_attacker(_attacker), m_victim(_victim), m_damage(_damage), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask), - m_damageType(_damageType), m_attackType(BASE_ATTACK), m_cleanDamage(cleanDamage) + m_damageType(_damageType), m_attackType(BASE_ATTACK), m_cleanDamage(cleanDamage), m_hitMask(0) { m_absorb = 0; m_resist = 0; @@ -126,23 +115,123 @@ DamageInfo::DamageInfo(CalcDamageInfo const& dmgInfo) : DamageInfo(DamageInfo(dm DamageInfo::DamageInfo(DamageInfo const& dmg1, DamageInfo const& dmg2) : m_attacker(dmg1.m_attacker), m_victim(dmg1.m_victim), m_damage(dmg1.m_damage + dmg2.m_damage), m_spellInfo(dmg1.m_spellInfo), m_schoolMask(SpellSchoolMask(dmg1.m_schoolMask | dmg2.m_schoolMask)), m_damageType(dmg1.m_damageType), m_attackType(dmg1.m_attackType), m_absorb(dmg1.m_absorb + dmg2.m_absorb), m_resist(dmg1.m_resist + dmg2.m_resist), m_block(dmg1.m_block), - m_cleanDamage(dmg1.m_cleanDamage + dmg1.m_cleanDamage) + m_cleanDamage(dmg1.m_cleanDamage + dmg1.m_cleanDamage), m_hitMask(dmg1.m_hitMask | dmg2.m_hitMask) { } DamageInfo::DamageInfo(CalcDamageInfo const& dmgInfo, uint8 damageIndex) : m_attacker(dmgInfo.attacker), m_victim(dmgInfo.target), m_damage(dmgInfo.damages[damageIndex].damage), m_spellInfo(nullptr), m_schoolMask(SpellSchoolMask(dmgInfo.damages[damageIndex].damageSchoolMask)), m_damageType(DIRECT_DAMAGE), m_attackType(dmgInfo.attackType), m_absorb(dmgInfo.damages[damageIndex].absorb), m_resist(dmgInfo.damages[damageIndex].resist), m_block(dmgInfo.blocked_amount), - m_cleanDamage(dmgInfo.cleanDamage) + m_cleanDamage(dmgInfo.cleanDamage), m_hitMask(0) { + switch (dmgInfo.hitOutCome) + { + case MELEE_HIT_MISS: + m_hitMask |= PROC_HIT_MISS; + break; + case MELEE_HIT_DODGE: + m_hitMask |= PROC_HIT_DODGE; + break; + case MELEE_HIT_PARRY: + m_hitMask |= PROC_HIT_PARRY; + break; + case MELEE_HIT_EVADE: + m_hitMask |= PROC_HIT_EVADE; + break; + case MELEE_HIT_BLOCK: + m_hitMask |= PROC_HIT_BLOCK; + [[fallthrough]]; + case MELEE_HIT_CRUSHING: + case MELEE_HIT_GLANCING: + case MELEE_HIT_NORMAL: + m_hitMask |= PROC_HIT_NORMAL; + break; + case MELEE_HIT_CRIT: + m_hitMask |= PROC_HIT_CRITICAL; + break; + default: + break; + } + + if (dmgInfo.damages[damageIndex].absorb) + m_hitMask |= PROC_HIT_ABSORB; + + if (dmgInfo.blocked_amount) + m_hitMask |= (dmgInfo.damages[damageIndex].damage == dmgInfo.blocked_amount) ? PROC_HIT_FULL_BLOCK : PROC_HIT_BLOCK; } -DamageInfo::DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType) +DamageInfo::DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType, WeaponAttackType attackType, uint32 hitMask) : m_attacker(spellNonMeleeDamage.attacker), m_victim(spellNonMeleeDamage.target), m_damage(spellNonMeleeDamage.damage), m_spellInfo(spellNonMeleeDamage.spellInfo), m_schoolMask(SpellSchoolMask(spellNonMeleeDamage.schoolMask)), m_damageType(damageType), - m_absorb(spellNonMeleeDamage.absorb), m_resist(spellNonMeleeDamage.resist), m_block(spellNonMeleeDamage.blocked), - m_cleanDamage(spellNonMeleeDamage.cleanDamage) + m_attackType(attackType), m_absorb(spellNonMeleeDamage.absorb), m_resist(spellNonMeleeDamage.resist), m_block(spellNonMeleeDamage.blocked), + m_cleanDamage(spellNonMeleeDamage.cleanDamage), m_hitMask(hitMask) { + if (spellNonMeleeDamage.blocked) + m_hitMask |= PROC_HIT_BLOCK; + if (spellNonMeleeDamage.absorb) + m_hitMask |= PROC_HIT_ABSORB; +} + +DamageInfo::DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType, WeaponAttackType attackType, SpellMissInfo missInfo) + : m_attacker(spellNonMeleeDamage.attacker), m_victim(spellNonMeleeDamage.target), m_damage(spellNonMeleeDamage.damage), + m_spellInfo(spellNonMeleeDamage.spellInfo), m_schoolMask(SpellSchoolMask(spellNonMeleeDamage.schoolMask)), m_damageType(damageType), + m_attackType(attackType), m_absorb(spellNonMeleeDamage.absorb), m_resist(spellNonMeleeDamage.resist), m_block(spellNonMeleeDamage.blocked), + m_cleanDamage(spellNonMeleeDamage.cleanDamage), m_hitMask(PROC_HIT_NONE) +{ + // Compute hitMask from SpellMissInfo + if (missInfo != SPELL_MISS_NONE) + { + switch (missInfo) + { + case SPELL_MISS_MISS: + m_hitMask |= PROC_HIT_MISS; + break; + case SPELL_MISS_RESIST: + m_hitMask |= PROC_HIT_FULL_RESIST; + break; + case SPELL_MISS_DODGE: + m_hitMask |= PROC_HIT_DODGE; + break; + case SPELL_MISS_PARRY: + m_hitMask |= PROC_HIT_PARRY; + break; + case SPELL_MISS_BLOCK: + m_hitMask |= PROC_HIT_BLOCK; + break; + case SPELL_MISS_EVADE: + m_hitMask |= PROC_HIT_EVADE; + break; + case SPELL_MISS_IMMUNE: + case SPELL_MISS_IMMUNE2: + m_hitMask |= PROC_HIT_IMMUNE; + break; + case SPELL_MISS_DEFLECT: + m_hitMask |= PROC_HIT_DEFLECT; + break; + case SPELL_MISS_ABSORB: + m_hitMask |= PROC_HIT_ABSORB; + break; + case SPELL_MISS_REFLECT: + m_hitMask |= PROC_HIT_REFLECT; + break; + default: + break; + } + } + else + { + // On block + if (spellNonMeleeDamage.blocked) + m_hitMask |= PROC_HIT_BLOCK; + // On absorb + if (spellNonMeleeDamage.absorb) + m_hitMask |= PROC_HIT_ABSORB; + // On crit + if (spellNonMeleeDamage.HitInfo & SPELL_HIT_TYPE_CRIT) + m_hitMask |= PROC_HIT_CRITICAL; + else + m_hitMask |= PROC_HIT_NORMAL; + } } void DamageInfo::ModifyDamage(int32 amount) @@ -172,6 +261,11 @@ void DamageInfo::BlockDamage(uint32 amount) m_damage -= amount; } +uint32 DamageInfo::GetHitMask() const +{ + return m_hitMask; +} + uint32 DamageInfo::GetUnmitigatedDamage() const { return m_damage + m_cleanDamage + m_absorb + m_resist; @@ -198,6 +292,20 @@ SpellInfo const* ProcEventInfo::GetSpellInfo() const return nullptr; } +SpellSchoolMask ProcEventInfo::GetSchoolMask() const +{ + if (_spell) + return _spell->GetSpellInfo()->GetSchoolMask(); + + if (_damageInfo) + return _damageInfo->GetSchoolMask(); + + if (_healInfo) + return _healInfo->GetSchoolMask(); + + return SPELL_SCHOOL_MASK_NONE; +} + // we can disable this warning for this since it only // causes undefined behavior when passed to the base class constructor #ifdef _MSC_VER @@ -1459,7 +1567,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama // Calculate absorb resist if (damageInfo->damage > 0) { - DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE); + DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE, BASE_ATTACK, 0); Unit::CalcAbsorbResist(dmgInfo); damageInfo->absorb = dmgInfo.GetAbsorb(); damageInfo->resist = dmgInfo.GetResist(); @@ -1514,7 +1622,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon damageInfo->HitInfo = 0; damageInfo->procAttacker = PROC_FLAG_NONE; damageInfo->procVictim = PROC_FLAG_NONE; - damageInfo->procEx = PROC_EX_NONE; damageInfo->hitOutCome = MELEE_HIT_EVADE; if (!victim) @@ -1561,8 +1668,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon { damageInfo->HitInfo |= HITINFO_NORMALSWING; damageInfo->TargetState = VICTIMSTATE_IS_IMMUNE; - - damageInfo->procEx |= PROC_EX_IMMUNE; return; } } @@ -1623,7 +1728,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon case MELEE_HIT_EVADE: damageInfo->HitInfo |= HITINFO_MISS | HITINFO_SWINGNOHITSOUND; damageInfo->TargetState = VICTIMSTATE_EVADES; - damageInfo->procEx |= PROC_EX_EVADE; for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) { @@ -1635,7 +1739,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon case MELEE_HIT_MISS: damageInfo->HitInfo |= HITINFO_MISS; damageInfo->TargetState = VICTIMSTATE_INTACT; - damageInfo->procEx |= PROC_EX_MISS; for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) { @@ -1645,14 +1748,11 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon break; case MELEE_HIT_NORMAL: damageInfo->TargetState = VICTIMSTATE_HIT; - damageInfo->procEx |= PROC_EX_NORMAL_HIT; break; case MELEE_HIT_CRIT: { damageInfo->HitInfo |= HITINFO_CRITICALHIT; damageInfo->TargetState = VICTIMSTATE_HIT; - - damageInfo->procEx |= PROC_EX_CRITICAL_HIT; // Crit bonus calc for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) { @@ -1685,7 +1785,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon } case MELEE_HIT_PARRY: damageInfo->TargetState = VICTIMSTATE_PARRY; - damageInfo->procEx |= PROC_EX_PARRY; damageInfo->cleanDamage = 0; for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) @@ -1696,7 +1795,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon break; case MELEE_HIT_DODGE: damageInfo->TargetState = VICTIMSTATE_DODGE; - damageInfo->procEx |= PROC_EX_DODGE; damageInfo->cleanDamage = 0; for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) @@ -1709,7 +1807,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon { damageInfo->TargetState = VICTIMSTATE_HIT; damageInfo->HitInfo |= HITINFO_BLOCK; - damageInfo->procEx |= PROC_EX_BLOCK; damageInfo->blocked_amount = damageInfo->target->GetShieldBlockValue(); // double blocked amount if block is critical if (damageInfo->target->isBlockCritical()) @@ -1739,7 +1836,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon if (fullBlockMask == ((1 << 0) | (1 << 1))) { damageInfo->TargetState = VICTIMSTATE_BLOCKS; - damageInfo->procEx |= PROC_EX_FULL_BLOCK; damageInfo->blocked_amount -= remainingBlock; } break; @@ -1748,7 +1844,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon { damageInfo->HitInfo |= HITINFO_GLANCING; damageInfo->TargetState = VICTIMSTATE_HIT; - damageInfo->procEx |= PROC_EX_NORMAL_HIT; int32 leveldif = int32(victim->GetLevel()) - int32(GetLevel()); if (leveldif > 3) leveldif = 3; @@ -1765,7 +1860,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon case MELEE_HIT_CRUSHING: damageInfo->HitInfo |= HITINFO_CRUSHING; damageInfo->TargetState = VICTIMSTATE_HIT; - damageInfo->procEx |= PROC_EX_NORMAL_HIT; // 150% normal damage for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) @@ -1847,15 +1941,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon damageInfo->HitInfo |= (tmpHitInfo[0] & HITINFO_PARTIAL_RESIST); } - if (damageInfo->HitInfo & (HITINFO_PARTIAL_ABSORB | HITINFO_FULL_ABSORB)) - { - damageInfo->procEx |= PROC_EX_ABSORB; - } - - if (damageInfo->HitInfo & HITINFO_FULL_RESIST) - { - damageInfo->procEx |= PROC_EX_RESIST; - } } void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) @@ -1972,7 +2057,10 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) } if (IsPlayer()) - ToPlayer()->CastItemCombatSpell(victim, damageInfo->attackType, damageInfo->procVictim, damageInfo->procEx); + { + DamageInfo dmgInfo(*damageInfo); + ToPlayer()->CastItemCombatSpell(victim, damageInfo->attackType, damageInfo->procVictim, dmgInfo.GetHitMask()); + } // Do effect if any damage done to target if (damageInfo->damages[0].damage + damageInfo->damages[1].damage) @@ -2425,11 +2513,12 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) uint32 splitted_absorb = 0; uint32 splitted_resist = 0; - uint32 procAttacker = 0, procVictim = 0, procEx = PROC_EX_NORMAL_HIT; + uint32 procAttacker = 0, procVictim = 0; DamageInfo splittedDmgInfo(attacker, caster, splitted, spellInfo, schoolMask, dmgInfo.GetDamageType()); + splittedDmgInfo.AddHitMask(PROC_HIT_NORMAL); if (caster->IsImmunedToDamageOrSchool(schoolMask)) { - procEx |= PROC_EX_IMMUNE; + splittedDmgInfo.AddHitMask(PROC_HIT_IMMUNE); splittedDmgInfo.AbsorbDamage(splitted); } else @@ -2442,9 +2531,13 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) splitted_resist = splittedDmgInfo.GetResist(); splitted = splittedDmgInfo.GetDamage(); + // Add absorb to hitMask if damage was absorbed + if (splittedDmgInfo.GetAbsorb()) + splittedDmgInfo.AddHitMask(PROC_HIT_ABSORB); + // create procs createProcFlags(spellInfo, BASE_ATTACK, false, procAttacker, procVictim); - caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted, nullptr, -1, nullptr, &splittedDmgInfo); + caster->ProcSkillsAndReactives(true, attacker, procVictim, splittedDmgInfo.GetHitMask(), BASE_ATTACK, spellInfo, splitted, nullptr, -1, nullptr, &splittedDmgInfo); if (attacker) { @@ -2499,11 +2592,12 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) uint32 splitted_absorb = 0; uint32 splitted_resist = 0; - uint32 procAttacker = 0, procVictim = 0, procEx = PROC_EX_NORMAL_HIT; + uint32 procAttacker = 0, procVictim = 0; DamageInfo splittedDmgInfo(attacker, caster, splitted, spellInfo, splitSchoolMask, dmgInfo.GetDamageType()); + splittedDmgInfo.AddHitMask(PROC_HIT_NORMAL); if (caster->IsImmunedToDamageOrSchool(schoolMask)) { - procEx |= PROC_EX_IMMUNE; + splittedDmgInfo.AddHitMask(PROC_HIT_IMMUNE); splittedDmgInfo.AbsorbDamage(splitted); } else @@ -2516,9 +2610,13 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) splitted_resist = splittedDmgInfo.GetResist(); splitted = splittedDmgInfo.GetDamage(); + // Add absorb to hitMask if damage was absorbed + if (splittedDmgInfo.GetAbsorb()) + splittedDmgInfo.AddHitMask(PROC_HIT_ABSORB); + // create procs createProcFlags(spellInfo, BASE_ATTACK, false, procAttacker, procVictim); - caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted); + caster->ProcSkillsAndReactives(true, attacker, procVictim, splittedDmgInfo.GetHitMask(), BASE_ATTACK, spellInfo, splitted); if (attacker) { @@ -2673,14 +2771,12 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType /*= BASE_A SendAttackStateUpdate(&damageInfo); - //TriggerAurasProcOnEvent(damageInfo); - _lastDamagedTargetGuid = victim->GetGUID(); DealMeleeDamage(&damageInfo, true); DamageInfo dmgInfo(damageInfo); - Unit::ProcDamageAndSpell(damageInfo.attacker, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, dmgInfo.GetDamage(), + Unit::ProcSkillsAndAuras(damageInfo.attacker, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, dmgInfo.GetHitMask(), dmgInfo.GetDamage(), damageInfo.attackType, nullptr, nullptr, -1, nullptr, &dmgInfo); if (IsPlayer()) @@ -3535,7 +3631,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spell, bool Ca if (reflectchance > 0 && roll_chance_i(reflectchance)) { // Start triggers for remove charges if need (trigger only for victim, and mark as active spell) - //ProcDamageAndSpell(victim, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, spell); + //ProcSkillsAndAuras(victim, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, spell); return SPELL_MISS_REFLECT; } } @@ -3610,7 +3706,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, Spell const* spell, bool CanRef if (reflectchance > 0 && roll_chance_i(reflectchance)) { // Start triggers for remove charges if need (trigger only for victim, and mark as active spell) - //ProcDamageAndSpell(victim, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, spell); + //ProcSkillsAndAuras(victim, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, spell); return SPELL_MISS_REFLECT; } } @@ -4495,7 +4591,10 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 castItemGUID = castItem->GetGUID(); // find current aura from spell and change it's stackamount, or refresh it's duration - if (Aura* foundAura = GetOwnedAura(newAura->Id, newAura->HasAttribute(SPELL_ATTR0_CU_SINGLE_AURA_STACK) ? ObjectGuid::Empty : casterGUID, newAura->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC) ? castItemGUID : ObjectGuid::Empty, 0)) + // Use castItemGUID for passive auras (weapon imbues) and enchant procs so they can stack from dual-wield + bool useItemGuid = newAura->IsPassive() || newAura->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC); + ObjectGuid itemGuidForLookup = (useItemGuid && castItemGUID) ? castItemGUID : ObjectGuid::Empty; + if (Aura* foundAura = GetOwnedAura(newAura->Id, newAura->HasAttribute(SPELL_ATTR0_CU_SINGLE_AURA_STACK) ? ObjectGuid::Empty : casterGUID, itemGuidForLookup, 0)) { // effect masks do not match // extremely rare case @@ -6608,15 +6707,38 @@ void Unit::SendSpellNonMeleeDamageLog(Unit* target, SpellInfo const* spellInfo, SendSpellNonMeleeDamageLog(&log); } -void Unit::ProcDamageAndSpell(Unit* actor, Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procExtra, uint32 amount, WeaponAttackType attType, SpellInfo const* procSpellInfo, SpellInfo const* procAura, int8 procAuraEffectIndex, Spell const* procSpell, DamageInfo* damageInfo, HealInfo* healInfo, uint32 procPhase) +void Unit::ProcSkillsAndAuras(Unit* actor, Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procExtra, uint32 amount, WeaponAttackType attType, SpellInfo const* procSpellInfo, SpellInfo const* procAura, int8 procAuraEffectIndex, Spell const* procSpell, DamageInfo* damageInfo, HealInfo* healInfo, uint32 procPhase) { - // Not much to do if no flags are set. + // Handle skills and reactives for actor if (procAttacker && actor) - actor->ProcDamageAndSpellFor(false, victim, procAttacker, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell, damageInfo, healInfo, procPhase); - // Now go on with a victim's events'n'auras - // Not much to do if no flags are set or there is no victim + actor->ProcSkillsAndReactives(false, victim, procAttacker, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell, damageInfo, healInfo, procPhase); + + // Handle skills and reactives for victim if (victim && victim->IsAlive() && procVictim) - victim->ProcDamageAndSpellFor(true, actor, procVictim, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell, damageInfo, healInfo, procPhase); + victim->ProcSkillsAndReactives(true, actor, procVictim, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell, damageInfo, healInfo, procPhase); + + // Handle aura procs via new proc system (TriggerAurasProcOnEvent) + if (actor) + { + // Calculate spellTypeMask based on phase and actual damage/heal info + uint32 spellTypeMask = 0; + if (procPhase == PROC_SPELL_PHASE_CAST || procPhase == PROC_SPELL_PHASE_FINISH) + { + // At CAST phase, no damage/heal has occurred yet - use MASK_ALL to allow + // procs that check for damage/heal type based on spell info (like Backlash) + // At FINISH phase, damageInfo may be null but spell did do damage - use MASK_ALL + // to match TrinityCore behavior (see TC Spell.cpp PROC_SPELL_PHASE_FINISH call) + spellTypeMask = PROC_SPELL_TYPE_MASK_ALL; + } + else if (healInfo && healInfo->GetHeal()) + spellTypeMask = PROC_SPELL_TYPE_HEAL; + else if (damageInfo && damageInfo->GetDamage()) + spellTypeMask = PROC_SPELL_TYPE_DAMAGE; + else if (procSpellInfo) + spellTypeMask = PROC_SPELL_TYPE_NO_DMG_HEAL; + + actor->TriggerAurasProcOnEvent(nullptr, nullptr, victim, procAttacker, procVictim, spellTypeMask, procPhase, procExtra, const_cast(procSpell), damageInfo, healInfo); + } } void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* pInfo) @@ -6818,3349 +6940,6 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType SendAttackStateUpdate(&dmgInfo); } -//victim may be nullptr -bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, ProcEventInfo const& eventInfo) -{ - SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo(); - uint32 effIndex = triggeredByAura->GetEffIndex(); - int32 triggerAmount = triggeredByAura->GetAmount(); - Spell const* spellProc = eventInfo.GetProcSpell(); - - Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && IsPlayer() - ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr; - - uint32 triggered_spell_id = 0; - uint32 cooldown_spell_id = 0; // for random trigger, will be one of the triggered spell to avoid repeatable triggers - // otherwise, it's the triggered_spell_id by default - Unit* target = victim; - int32 basepoints0 = 0; - ObjectGuid originalCaster; - - switch (dummySpell->SpellFamilyName) - { - case SPELLFAMILY_GENERIC: - { - switch (dummySpell->Id) - { - // Overkill - case 58426: - { - triggered_spell_id = 58427; - break; - } - // Unstable Power - case 24658: - { - if (!procSpell || procSpell->Id == 24659) - return false; - // Need remove one 24659 aura - RemoveAuraFromStack(24659); - return true; - } - // Restless Strength - case 24661: - { - // Need remove one 24662 aura - RemoveAuraFromStack(24662); - return true; - } - // Mark of Malice - case 33493: - { - if (triggeredByAura->GetBase()->GetCharges() > 1) - return true; - - target = this; - triggered_spell_id = 33494; - break; - } - // Twisted Reflection (boss spell) - case 21063: - triggered_spell_id = 21064; - break; - // Vampiric Aura (boss spell) - case 38196: - { - basepoints0 = 3 * damage; // 300% - if (basepoints0 < 0) - return false; - - triggered_spell_id = 31285; - target = this; - break; - } - // Aura of Madness (Darkmoon Card: Madness trinket) - //===================================================== - // 39511 Sociopath: +35 strength (Paladin, Rogue, Druid, Warrior) - // 40997 Delusional: +70 attack power (Rogue, Hunter, Paladin, Warrior, Druid) - // 40998 Kleptomania: +35 agility (Warrior, Rogue, Paladin, Hunter, Druid) - // 40999 Megalomania: +41 damage/healing (Druid, Shaman, Priest, Warlock, Mage, Paladin) - // 41002 Paranoia: +35 spell/melee/ranged crit strike rating (All classes) - // 41005 Manic: +35 haste (spell, melee and ranged) (All classes) - // 41009 Narcissism: +35 intellect (Druid, Shaman, Priest, Warlock, Mage, Paladin, Hunter) - // 41011 Martyr Complex: +35 stamina (All classes) - // 41406 Dementia: Every 5 seconds either gives you +5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) - // 41409 Dementia: Every 5 seconds either gives you -5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) - case 39446: - { - if (!IsPlayer() || !IsAlive()) - return false; - - // Select class defined buff - switch (getClass()) - { - case CLASS_PALADIN: // 39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409 - case CLASS_DRUID: // 39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409 - triggered_spell_id = RAND(39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409); - cooldown_spell_id = 39511; - break; - case CLASS_ROGUE: // 39511, 40997, 40998, 41002, 41005, 41011 - case CLASS_WARRIOR: // 39511, 40997, 40998, 41002, 41005, 41011 - case CLASS_DEATH_KNIGHT: - triggered_spell_id = RAND(39511, 40997, 40998, 41002, 41005, 41011); - cooldown_spell_id = 39511; - break; - case CLASS_PRIEST: // 40999, 41002, 41005, 41009, 41011, 41406, 41409 - case CLASS_SHAMAN: // 40999, 41002, 41005, 41009, 41011, 41406, 41409 - case CLASS_MAGE: // 40999, 41002, 41005, 41009, 41011, 41406, 41409 - case CLASS_WARLOCK: // 40999, 41002, 41005, 41009, 41011, 41406, 41409 - triggered_spell_id = RAND(40999, 41002, 41005, 41009, 41011, 41406, 41409); - cooldown_spell_id = 40999; - break; - case CLASS_HUNTER: // 40997, 40999, 41002, 41005, 41009, 41011, 41406, 41409 - triggered_spell_id = RAND(40997, 40999, 41002, 41005, 41009, 41011, 41406, 41409); - cooldown_spell_id = 40997; - break; - default: - return false; - } - - target = this; - if (roll_chance_i(10)) - ToPlayer()->Say("This is Madness!", LANG_UNIVERSAL); /// @todo: It should be moved to database, shouldn't it? - break; - } - // Sunwell Exalted Caster Neck (??? neck) - // cast ??? Light's Wrath if Exalted by Aldor - // cast ??? Arcane Bolt if Exalted by Scryers - case 46569: - return false; // old unused version - // Sunwell Exalted Caster Neck (Shattered Sun Pendant of Acumen neck) - // cast 45479 Light's Wrath if Exalted by Aldor - // cast 45429 Arcane Bolt if Exalted by Scryers - case 45481: - { - Player* player = ToPlayer(); - if (!player) - return false; - - // Get Aldor reputation rank - if (player->GetReputationRank(932) == REP_EXALTED) - { - target = this; - triggered_spell_id = 45479; - break; - } - // Get Scryers reputation rank - if (player->GetReputationRank(934) == REP_EXALTED) - { - // triggered at positive/self casts also, current attack target used then - if (target && IsFriendlyTo(target)) - { - target = GetVictim(); - if (!target) - { - target = player->GetSelectedUnit(); - if (!target) - return false; - } - if (IsFriendlyTo(target)) - return false; - } - - triggered_spell_id = 45429; - break; - } - return false; - } - // Sunwell Exalted Melee Neck (Shattered Sun Pendant of Might neck) - // cast 45480 Light's Strength if Exalted by Aldor - // cast 45428 Arcane Strike if Exalted by Scryers - case 45482: - { - if (!IsPlayer()) - return false; - - // Get Aldor reputation rank - if (ToPlayer()->GetReputationRank(932) == REP_EXALTED) - { - target = this; - triggered_spell_id = 45480; - break; - } - // Get Scryers reputation rank - if (ToPlayer()->GetReputationRank(934) == REP_EXALTED) - { - triggered_spell_id = 45428; - break; - } - return false; - } - // Sunwell Exalted Tank Neck (Shattered Sun Pendant of Resolve neck) - // cast 45431 Arcane Insight if Exalted by Aldor - // cast 45432 Light's Ward if Exalted by Scryers - case 45483: - { - if (!IsPlayer()) - return false; - - // Get Aldor reputation rank - if (ToPlayer()->GetReputationRank(932) == REP_EXALTED) - { - target = this; - triggered_spell_id = 45432; - break; - } - // Get Scryers reputation rank - if (ToPlayer()->GetReputationRank(934) == REP_EXALTED) - { - target = this; - triggered_spell_id = 45431; - break; - } - return false; - } - // Sunwell Exalted Healer Neck (Shattered Sun Pendant of Restoration neck) - // cast 45478 Light's Salvation if Exalted by Aldor - // cast 45430 Arcane Surge if Exalted by Scryers - case 45484: - { - if (!IsPlayer()) - return false; - - // Get Aldor reputation rank - if (ToPlayer()->GetReputationRank(932) == REP_EXALTED) - { - target = this; - triggered_spell_id = 45478; - break; - } - // Get Scryers reputation rank - if (ToPlayer()->GetReputationRank(934) == REP_EXALTED) - { - triggered_spell_id = 45430; - break; - } - return false; - } - // Kill command - case 58914: - { - // Remove aura stack from pet - RemoveAuraFromStack(58914); - Unit* owner = GetOwner(); - if (!owner) - return true; - // reduce the owner's aura stack - owner->RemoveAuraFromStack(34027); - return true; - } - // Vampiric Touch (generic, used by some boss) - case 52723: - case 60501: - { - triggered_spell_id = 52724; - basepoints0 = damage / 2; - target = this; - break; - } - // Divine purpose - case 31871: - case 31872: - { - // Roll chane - if (!victim || !victim->IsAlive() || !roll_chance_i(triggerAmount)) - return false; - - // Remove any stun effect on target - victim->RemoveAurasWithMechanic(1 << MECHANIC_STUN, AURA_REMOVE_BY_ENEMY_SPELL); - return true; - } - // Glyph of Life Tap - case 63320: - { - triggered_spell_id = 63321; // Life Tap - break; - } - case 71519: // Deathbringer's Will Normal - { - if (!IsPlayer() || HasSpellCooldown(71484)) - return false; - - AddSpellCooldown(71484, 0, cooldown); - - std::vector RandomSpells; - switch (getClass()) - { - case CLASS_WARRIOR: - case CLASS_PALADIN: - case CLASS_DEATH_KNIGHT: - RandomSpells.push_back(71484); - RandomSpells.push_back(71491); - RandomSpells.push_back(71492); - break; - case CLASS_SHAMAN: - case CLASS_ROGUE: - RandomSpells.push_back(71486); - RandomSpells.push_back(71485); - RandomSpells.push_back(71492); - break; - case CLASS_DRUID: - RandomSpells.push_back(71484); - RandomSpells.push_back(71485); - RandomSpells.push_back(71492); - break; - case CLASS_HUNTER: - RandomSpells.push_back(71486); - RandomSpells.push_back(71491); - RandomSpells.push_back(71485); - break; - default: - return false; - } - if (RandomSpells.empty()) // shouldn't happen - return false; - - uint8 rand_spell = irand(0, (RandomSpells.size() - 1)); - CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster); - break; - } - case 71562: // Deathbringer's Will Heroic - { - if (!IsPlayer() || HasSpellCooldown(71561)) - return false; - - AddSpellCooldown(71561, 0, cooldown); - - std::vector RandomSpells; - switch (getClass()) - { - case CLASS_WARRIOR: - case CLASS_PALADIN: - case CLASS_DEATH_KNIGHT: - RandomSpells.push_back(71561); - RandomSpells.push_back(71559); - RandomSpells.push_back(71560); - break; - case CLASS_SHAMAN: - case CLASS_ROGUE: - RandomSpells.push_back(71558); - RandomSpells.push_back(71556); - RandomSpells.push_back(71560); - break; - case CLASS_DRUID: - RandomSpells.push_back(71561); - RandomSpells.push_back(71556); - RandomSpells.push_back(71560); - break; - case CLASS_HUNTER: - RandomSpells.push_back(71558); - RandomSpells.push_back(71559); - RandomSpells.push_back(71556); - break; - default: - return false; - } - if (RandomSpells.empty()) // shouldn't happen - return false; - - uint8 rand_spell = irand(0, (RandomSpells.size() - 1)); - CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster); - break; - } - // Freya, Petrified Bark - case 62933: - case 62337: - { - if (!victim) - return false; - - int32 dmg = damage; - victim->CastCustomSpell(this, 62379, &dmg, 0, 0, true); - return true; - } - // Trial of the Champion, Earth Shield - case 67534: - { - const int32 dmg = (int32)damage; - CastCustomSpell(this, 67535, &dmg, nullptr, nullptr, true, 0, triggeredByAura, triggeredByAura->GetCasterGUID()); - return true; - } - // Trial of the Crusader, Faction Champions, Retaliation - case 65932: - { - // check attack comes not from behind - if (!victim || !HasInArc(M_PI, victim)) - return false; - - triggered_spell_id = 65934; - break; - } - // Pit of Saron, Tyrannus, Overlord's Brand - case 69172: // everything except for DoTs - { - if (!target) - return false; - if (Unit* caster = triggeredByAura->GetCaster()) - { - if (procFlag & (PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS)) - { - int32 dmg = 5.5f * damage; - target->CastCustomSpell(caster, 69190, &dmg, 0, 0, true); - } - else - { - if (caster->GetVictim()) - { - int32 dmg = damage; - target->CastCustomSpell(caster->GetVictim(), 69189, &dmg, 0, 0, true); - } - } - } - return true; - } - // Pit of Saron, Tyrannus, Overlord's Brand - case 69173: // only DoTs - { - if (!target) - return false; - if (Unit* caster = triggeredByAura->GetCaster()) - { - if (procEx & PROC_EX_INTERNAL_HOT) - { - int32 dmg = 5.5f * damage; - target->CastCustomSpell(caster, 69190, &dmg, 0, 0, true); - } - else - { - if (caster->GetVictim()) - { - int32 dmg = damage; - target->CastCustomSpell(caster->GetVictim(), 69189, &dmg, 0, 0, true); - } - } - } - return true; - } - // Icecrown Citadel, Lady Deathwhisper, Vampiric Might - case 70674: - { - if (Unit* caster = triggeredByAura->GetCaster()) - { - int32 dmg = 3 * damage; - caster->CastCustomSpell(caster, 70677, &dmg, 0, 0, true); - } - return true; - } - // Item: Purified Shard of the Gods - case 69755: - { - triggered_spell_id = ((procFlag & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) ? 69733 : 69729); - break; - } - // Item: Shiny Shard of the Gods - case 69739: - { - triggered_spell_id = ((procFlag & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) ? 69734 : 69730); - break; - } - // VoA: Meteor Fists koralon - case 66725: - case 68161: - { - triggered_spell_id = 66765; // handled by spell_difficulty - break; - } - } - break; - } - case SPELLFAMILY_MAGE: - { - // Magic Absorption - if (dummySpell->SpellIconID == 459) // only this spell has SpellIconID == 459 and dummy aura - { - if (!HasActivePowerType(POWER_MANA)) - return false; - - // mana reward - basepoints0 = CalculatePct(int32(GetMaxPower(POWER_MANA)), triggerAmount); - target = this; - triggered_spell_id = 29442; - break; - } - // Hot Streak - if (dummySpell->SpellIconID == 2999) - { - if (effIndex != 0) - return false; - AuraEffect* counter = triggeredByAura->GetBase()->GetEffect(EFFECT_1); - if (!counter) - return true; - - // Count spell criticals in a row in second aura - if (procEx & PROC_EX_CRITICAL_HIT) - { - counter->SetAmount(counter->GetAmount() * 2); - if (counter->GetAmount() < 100) // not enough - return true; - // Crititcal counted -> roll chance - if (roll_chance_i(triggerAmount)) - CastSpell(this, 48108, true, castItem, triggeredByAura); - } - counter->SetAmount(25); - return true; - } - // Incanter's Regalia set (add trigger chance to Mana Shield) - if (dummySpell->SpellFamilyFlags[0] & 0x8000) - { - if (!IsPlayer()) - return false; - - target = this; - triggered_spell_id = 37436; - break; - } - switch (dummySpell->Id) - { - // Glyph of Polymorph - case 56375: - { - if (!target) - return false; - target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, ObjectGuid::Empty, target->GetAura(32409)); // SW:D shall not be removed. - target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); - target->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH); - return true; - } - // Glyph of Icy Veins - case 56374: - { - RemoveAurasByType(SPELL_AURA_HASTE_SPELLS, ObjectGuid::Empty, 0, true, false); - RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); - return true; - } - // Glyph of Ice Block - case 56372: - { - Player* player = ToPlayer(); - if (!player) - return false; - - SpellCooldowns const cooldowns = player->GetSpellCooldowns(); - // remove cooldowns on all ranks of Frost Nova - for (SpellCooldowns::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr) - { - SpellInfo const* cdSpell = sSpellMgr->GetSpellInfo(itr->first); - // Frost Nova - if (cdSpell && cdSpell->SpellFamilyName == SPELLFAMILY_MAGE - && cdSpell->SpellFamilyFlags[0] & 0x00000040) - player->RemoveSpellCooldown(cdSpell->Id, true); - } - break; - } - } - break; - } - case SPELLFAMILY_WARRIOR: - { - // Second Wind - if (dummySpell->SpellIconID == 1697) - { - // only for spells and hit/crit (trigger start always) and not start from self casted spells (5530 Mace Stun Effect for example) - if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) || this == victim) - return false; - // Need stun or root mechanic - if (!(procSpell->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN)))) - return false; - - switch (dummySpell->Id) - { - case 29838: - triggered_spell_id = 29842; - break; - case 29834: - triggered_spell_id = 29841; - break; - case 42770: - triggered_spell_id = 42771; - break; - default: - LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non handled spell id: {} (SW)", dummySpell->Id); - return false; - } - - target = this; - break; - } - break; - } - case SPELLFAMILY_WARLOCK: - { - switch (dummySpell->Id) - { - // Nightfall - case 18094: - case 18095: - // Glyph of corruption - case 56218: - { - target = this; - triggered_spell_id = 17941; - break; - } - // Soul Leech - case 30293: - case 30295: - case 30296: - { - // Improved Soul Leech - AuraEffectList const& SoulLeechAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY); - for (Unit::AuraEffectList::const_iterator i = SoulLeechAuras.begin(); i != SoulLeechAuras.end(); ++i) - { - if ((*i)->GetId() == 54117 || (*i)->GetId() == 54118) - { - if ((*i)->GetEffIndex() != 0) - continue; - basepoints0 = int32((*i)->GetAmount()); - target = GetGuardianPet(); - if (target) - { - // regen mana for pet - CastCustomSpell(target, 54607, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura); - } - // regen mana for caster - CastCustomSpell(this, 59117, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura); - // Get second aura of spell for replenishment effect on party - if (AuraEffect const* aurEff = (*i)->GetBase()->GetEffect(EFFECT_1)) - { - // Replenishment - roll chance - if (roll_chance_i(aurEff->GetAmount())) - { - CastSpell(this, 57669, true, castItem, triggeredByAura); - } - } - break; - } - } - // health - basepoints0 = CalculatePct(int32(damage), triggerAmount); - target = this; - triggered_spell_id = 30294; - break; - } - // Shadowflame (Voidheart Raiment set bonus) - case 37377: - { - triggered_spell_id = 37379; - break; - } - // Pet Healing (Corruptor Raiment or Rift Stalker Armor) - case 37381: - { - target = GetGuardianPet(); - if (!target) - return false; - - // heal amount - basepoints0 = CalculatePct(int32(damage), triggerAmount); - triggered_spell_id = 37382; - break; - } - // Shadowflame Hellfire (Voidheart Raiment set bonus) - case 39437: - { - triggered_spell_id = 37378; - break; - } - } - break; - } - case SPELLFAMILY_PRIEST: - { - // Body and Soul - if (dummySpell->SpellIconID == 2218) - { - // Proc only from Abolish desease on self cast - if (procSpell->Id != 552 || victim != this || !roll_chance_i(triggerAmount)) - return false; - triggered_spell_id = 64136; - target = this; - break; - } - switch (dummySpell->Id) - { - // Vampiric Embrace - case 15286: - { - if (!victim || !victim->IsAlive() || procSpell->SpellFamilyFlags[1] & 0x80000) - return false; - - // heal amount - int32 total = CalculatePct(int32(damage), triggerAmount); - int32 team = total / 5; - int32 self = total - team; - CastCustomSpell(this, 15290, &team, &self, nullptr, true, castItem, triggeredByAura); - return true; // no hidden cooldown - } - // Priest Tier 6 Trinket (Ashtongue Talisman of Acumen) - case 40438: - { - // Shadow Word: Pain - if (procSpell->SpellFamilyFlags[0] & 0x8000) - triggered_spell_id = 40441; - // Renew - else if (procSpell->SpellFamilyFlags[0] & 0x40) - triggered_spell_id = 40440; - else - return false; - - target = this; - break; - } - // Improved Shadowform - case 47570: - case 47569: - { - if (!roll_chance_i(triggerAmount)) - return false; - - RemoveMovementImpairingAuras(true); - break; - } - // Glyph of Dispel Magic - case 55677: - { - // Dispel Magic shares spellfamilyflag with abolish disease - if (procSpell->SpellIconID != 74) - return false; - if (!target || !target->IsFriendlyTo(this)) - return false; - - basepoints0 = int32(target->CountPctFromMaxHealth(triggerAmount)); - triggered_spell_id = 56131; - break; - } - // Oracle Healing Bonus ("Garments of the Oracle" set) - case 26169: - { - // heal amount - basepoints0 = int32(CalculatePct(damage, 10)); - target = this; - triggered_spell_id = 26170; - break; - } - // Frozen Shadoweave (Shadow's Embrace set) warning! its not only priest set - case 39372: - { - if (!procSpell || (procSpell->GetSchoolMask() & (SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_SHADOW)) == 0) - return false; - - // heal amount - basepoints0 = CalculatePct(int32(damage), triggerAmount); - target = this; - triggered_spell_id = 39373; - break; - } - // Greater Heal (Vestments of Faith (Priest Tier 3) - 4 pieces bonus) - case 28809: - { - triggered_spell_id = 28810; - break; - } - // Priest T10 Healer 2P Bonus - case 70770: - // Flash Heal - if (procSpell->SpellFamilyFlags[0] & 0x800) - { - triggered_spell_id = 70772; - SpellInfo const* blessHealing = sSpellMgr->GetSpellInfo(triggered_spell_id); - if (!blessHealing || !victim) - return false; - basepoints0 = int32(CalculatePct(damage, triggerAmount) / (blessHealing->GetMaxDuration() / blessHealing->Effects[0].Amplitude)); - victim->CastDelayedSpellWithPeriodicAmount(this, triggered_spell_id, SPELL_AURA_PERIODIC_HEAL, basepoints0); - return true; - } - break; - } - break; - } - case SPELLFAMILY_DRUID: - { - switch (dummySpell->Id) - { - // Glyph of Innervate - case 54832: - { - if (procSpell->SpellIconID != 62) - return false; - - int32 mana_perc = triggeredByAura->GetSpellInfo()->Effects[triggeredByAura->GetEffIndex()].CalcValue(); - basepoints0 = int32(CalculatePct(GetCreatePowers(POWER_MANA), mana_perc) / 10); - triggered_spell_id = 54833; - target = this; - break; - } - // Glyph of Starfire - case 54845: - { - triggered_spell_id = 54846; - break; - } - // Glyph of Shred - case 54815: - { - if (!target) - return false; - - // try to find spell Rip on the target - if (AuraEffect const* AurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00800000, 0x0, 0x0, GetGUID())) - { - // Rip's max duration, note: spells which modifies Rip's duration also counted like Glyph of Rip - uint32 CountMin = AurEff->GetBase()->GetMaxDuration(); - - // just Rip's max duration without other spells - uint32 CountMax = AurEff->GetSpellInfo()->GetMaxDuration(); - - // add possible auras' and Glyph of Shred's max duration - CountMax += 3 * triggerAmount * IN_MILLISECONDS; // Glyph of Shred -> +6 seconds - CountMax += HasAura(54818) ? 4 * IN_MILLISECONDS : 0; // Glyph of Rip -> +4 seconds - CountMax += HasAura(60141) ? 4 * IN_MILLISECONDS : 0; // Rip Duration/Lacerate Damage -> +4 seconds - - // if min < max -> that means caster didn't cast 3 shred yet - // so set Rip's duration and max duration - if (CountMin < CountMax) - { - AurEff->GetBase()->SetDuration(AurEff->GetBase()->GetDuration() + triggerAmount * IN_MILLISECONDS); - AurEff->GetBase()->SetMaxDuration(CountMin + triggerAmount * IN_MILLISECONDS); - return true; - } - } - // if not found Rip - return false; - } - // Glyph of Rake - case 54821: - { - if (procSpell->SpellVisual[0] == 750 && procSpell->Effects[1].ApplyAuraName == 3) - { - if (target && target->IsCreature()) - { - triggered_spell_id = 54820; - break; - } - } - return false; - } - // Leader of the Pack - case 24932: - { - if (triggerAmount <= 0) - return false; - basepoints0 = int32(CountPctFromMaxHealth(triggerAmount)); - target = this; - triggered_spell_id = 34299; - if (triggeredByAura->GetCasterGUID() != GetGUID()) - break; - int32 basepoints1 = CalculatePct(GetMaxPower(Powers(POWER_MANA)), triggerAmount * 2); - // Improved Leader of the Pack - // Check cooldown of heal spell cooldown - if (IsPlayer() && !ToPlayer()->HasSpellCooldown(34299)) - CastCustomSpell(this, 68285, &basepoints1, 0, 0, true, 0, triggeredByAura); - break; - } - // Healing Touch (Dreamwalker Raiment set) - case 28719: - { - // mana back - basepoints0 = int32(CalculatePct(spellProc->GetPowerCost(), 30)); - target = this; - triggered_spell_id = 28742; - break; - } - // Glyph of Rejuvenation - case 54754: - { - if (!victim || !victim->HealthBelowPct(uint32(triggerAmount))) - return false; - basepoints0 = CalculatePct(int32(damage), triggerAmount); - triggered_spell_id = 54755; - break; - } - // Healing Touch Refund (Idol of Longevity trinket) - case 28847: - { - target = this; - triggered_spell_id = 28848; - break; - } - // Mana Restore (Malorne Raiment set / Malorne Regalia set) - case 37288: - case 37295: - { - target = this; - triggered_spell_id = 37238; - break; - } - // Druid Tier 6 Trinket - case 40442: - { - float chance; - - // Starfire - if (procSpell->SpellFamilyFlags[0] & 0x4) - { - triggered_spell_id = 40445; - chance = 25.0f; - } - // Rejuvenation - else if (procSpell->SpellFamilyFlags[0] & 0x10) - { - triggered_spell_id = 40446; - chance = 25.0f; - } - // Mangle (Bear) and Mangle (Cat) - else if (procSpell->SpellFamilyFlags[1] & 0x00000440) - { - triggered_spell_id = 40452; - chance = 40.0f; - } - else - return false; - - if (!roll_chance_f(chance)) - return false; - - target = this; - break; - } - // Maim Interrupt - case 44835: - { - // Deadly Interrupt Effect - triggered_spell_id = 32747; - break; - } - // Item - Druid T10 Restoration 4P Bonus (Rejuvenation) - case 70664: - { - // xinef: proc only from normal Rejuvenation, and proc rejuvenation - if (!victim || !procSpell || procSpell->SpellIconID != 64) - return false; - - Player* caster = ToPlayer(); - if (!caster) - return false; - if (!caster->GetGroup() && victim == this) - return false; - - CastCustomSpell(70691, SPELLVALUE_BASE_POINT0, damage, victim, true); - return true; - } - } - // Eclipse - if (dummySpell->SpellIconID == 2856 && IsPlayer()) - { - if (!procSpell || effIndex != 0) - return false; - - bool isWrathSpell = (procSpell->SpellFamilyFlags[0] & 1); - - if (!roll_chance_f(dummySpell->ProcChance * (isWrathSpell ? 0.6f : 1.0f))) - return false; - - target = this; - if (target->HasAura(isWrathSpell ? 48517 : 48518)) - return false; - - triggered_spell_id = isWrathSpell ? 48518 : 48517; - break; - } - [[fallthrough]]; /// @todo: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked. - } - case SPELLFAMILY_ROGUE: - { - switch (dummySpell->Id) - { - // Glyph of Backstab - case 56800: - { - if (victim) - if (AuraEffect* aurEff = victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x100000, 0, 0, GetGUID())) - if (Aura* aur = aurEff->GetBase()) - if (!aur->IsRemoved() && aur->GetDuration() > 0) - if ((aur->GetApplyTime() + aur->GetMaxDuration() / 1000 + 5) > (GameTime::GetGameTime().count() + aur->GetDuration() / 1000)) - { - aur->SetDuration(aur->GetDuration() + 2000); - return true; - } - return false; - } - // Deadly Throw Interrupt - case 32748: - { - // Prevent cast Deadly Throw Interrupt on self from last effect (apply dummy) of Deadly Throw - if (this == victim) - return false; - - triggered_spell_id = 32747; - break; - } - } - // Master of subtlety - if (dummySpell->SpellIconID == 2114) - { - triggered_spell_id = 31665; - basepoints0 = triggerAmount; - break; - } - // Cut to the Chase - if (dummySpell->SpellIconID == 2909) - { - // "refresh your Slice and Dice duration to its 5 combo point maximum" - // lookup Slice and Dice - if (AuraEffect const* aur = GetAuraEffect(SPELL_AURA_MOD_MELEE_HASTE, SPELLFAMILY_ROGUE, 0x40000, 0, 0)) - { - aur->GetBase()->SetDuration(aur->GetSpellInfo()->GetMaxDuration(), true); - return true; - } - return false; - } - // Deadly Brew - else if (dummySpell->SpellIconID == 2963) - { - triggered_spell_id = 3409; - break; - } - // Quick Recovery - else if (dummySpell->SpellIconID == 2116) - { - if (!procSpell) - return false; - - // energy cost save - basepoints0 = CalculatePct(int32(procSpell->ManaCost), triggerAmount); - if (basepoints0 <= 0) - return false; - - target = this; - triggered_spell_id = 31663; - break; - } - break; - } - case SPELLFAMILY_HUNTER: - { - switch (dummySpell->SpellIconID) - { - case 2236: // Thrill of the Hunt - { - if (!procSpell) - return false; - - Spell* spell = ToPlayer()->m_spellModTakingSpell; - - // Disable charge drop because of Lock and Load - if (spell) - ToPlayer()->SetSpellModTakingSpell(spell, false); - - // Explosive Shot - if (procSpell->SpellFamilyFlags[2] & 0x200) - { - if (!victim) - return false; - if (AuraEffect const* pEff = victim->GetAuraEffect(SPELL_AURA_PERIODIC_DUMMY, SPELLFAMILY_HUNTER, 0x0, 0x80000000, 0x0, GetGUID())) - basepoints0 = pEff->GetSpellInfo()->CalcPowerCost(this, SpellSchoolMask(pEff->GetSpellInfo()->SchoolMask)) * 4 / 10 / 3; - } - else - basepoints0 = procSpell->CalcPowerCost(this, SpellSchoolMask(procSpell->SchoolMask)) * 4 / 10; - - if (spell) - ToPlayer()->SetSpellModTakingSpell(spell, true); - - if (basepoints0 <= 0) - return false; - - target = this; - triggered_spell_id = 34720; - break; - } - case 3406: // Hunting Party - { - triggered_spell_id = 57669; - target = this; - break; - } - case 3560: // Rapid Recuperation - { - // This effect only from Rapid Killing (mana regen) - if (!(procSpell->SpellFamilyFlags[1] & 0x01000000)) - return false; - - target = this; - - switch (dummySpell->Id) - { - case 53228: // Rank 1 - triggered_spell_id = 56654; - break; - case 53232: // Rank 2 - triggered_spell_id = 58882; - break; - } - break; - } - } - - switch (dummySpell->Id) - { - case 57870: // Glyph of Mend Pet - { - if (!victim) - return false; - - victim->CastSpell(victim, 57894, true, nullptr, nullptr, GetGUID()); - return true; - } - } - break; - } - case SPELLFAMILY_PALADIN: - { - // Light's Beacon - Beacon of Light - if (dummySpell->Id == 53651) - { - if (!victim) - return false; - - // Do not proc from Glyph of Holy Light and Judgement of Light - if (procSpell->Id == 20267 || procSpell->Id == 54968) - { - return false; - } - - Unit* beaconTarget = triggeredByAura->GetBase()->GetCaster(); - if (!beaconTarget || beaconTarget == this || !beaconTarget->GetAura(53563, victim->GetGUID())) - return false; - - basepoints0 = int32(damage); - triggered_spell_id = procSpell->IsRankOf(sSpellMgr->GetSpellInfo(635)) ? 53652 : 53654; - - victim->CastCustomSpell(beaconTarget, triggered_spell_id, &basepoints0, nullptr, nullptr, true, 0, triggeredByAura, victim->GetGUID()); - return true; - } - // Judgements of the Wise - if (dummySpell->SpellIconID == 3017) - { - target = this; - triggered_spell_id = 31930; - // replenishment - CastSpell(this, 57669, true, castItem, triggeredByAura); - break; - } - // Righteous Vengeance - if (dummySpell->SpellIconID == 3025) - { - if (!victim) - return false; - - // 4 damage tick - basepoints0 = triggerAmount * damage / 400; - triggered_spell_id = 61840; - // Add remaining ticks to damage done - victim->CastDelayedSpellWithPeriodicAmount(this, triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE, basepoints0); - return true; - } - // Sheath of Light - if (dummySpell->SpellIconID == 3030) - { - // 4 healing tick - basepoints0 = triggerAmount * damage / 400; - triggered_spell_id = 54203; - break; - } - switch (dummySpell->Id) - { - // Judgement of Light - case 20185: - { - if (!victim || !victim->IsAlive()) - return false; - - auto* caster = triggeredByAura->GetBase()->GetCaster(); - if (!caster || !victim->IsFriendlyTo(caster)) - return false; - - // 2% of base health - basepoints0 = int32(victim->CountPctFromMaxHealth(2)); - victim->CastCustomSpell(victim, 20267, &basepoints0, 0, 0, true, 0, triggeredByAura); - return true; - } - // Judgement of Wisdom - case 20186: - { - if (!victim || !victim->IsAlive() || !victim->HasActivePowerType(POWER_MANA)) - return false; - - auto* caster = triggeredByAura->GetBase()->GetCaster(); - if (!caster || !victim->IsFriendlyTo(caster)) - return false; - - // 2% of base mana - basepoints0 = int32(CalculatePct(victim->GetCreateMana(), 2)); - victim->CastCustomSpell(victim, 20268, &basepoints0, nullptr, nullptr, true, 0, triggeredByAura); - return true; - } - // Holy Power (Redemption Armor set) - case 28789: - { - if (!victim) - return false; - - // Set class defined buff - switch (victim->getClass()) - { - case CLASS_PALADIN: - case CLASS_PRIEST: - case CLASS_SHAMAN: - case CLASS_DRUID: - triggered_spell_id = 28795; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d. - break; - case CLASS_MAGE: - case CLASS_WARLOCK: - triggered_spell_id = 28793; // Increases the friendly target's spell damage and healing by up to $s1 for $d. - break; - case CLASS_HUNTER: - case CLASS_ROGUE: - triggered_spell_id = 28791; // Increases the friendly target's attack power by $s1 for $d. - break; - case CLASS_WARRIOR: - triggered_spell_id = 28790; // Increases the friendly target's armor - break; - default: - return false; - } - break; - } - // Seal of Vengeance (damage calc on apply aura) - case 31801: - { - if (effIndex != 0 || !victim) // effect 1, 2 used by seal unleashing code - return false; - - // At melee attack or Hammer of the Righteous spell damage considered as melee attack - bool stacker = !procSpell || procSpell->Id == 53595; - // spells with SPELL_DAMAGE_CLASS_MELEE excluding Judgements - bool damager = procSpell && (procSpell->EquippedItemClass != -1 || (procSpell->SpellIconID == 243 && procSpell->SpellVisual[0] == 39)); - - if (!stacker && !damager) - return false; - - triggered_spell_id = 31803; - - if (Aura* aur = victim->GetAura(triggered_spell_id, GetGUID())) - { - if (aur->GetStackAmount() == 5) - { - if (stacker) - aur->RefreshDuration(); - } - } - - CastSpell(victim, 42463, true, castItem, triggeredByAura); // Seal of Vengeance - - if (!stacker) - return false; - break; - } - // Seal of Corruption - case 53736: - { - if (effIndex != 0 || !victim) // effect 1, 2 used by seal unleashing code - return false; - - // At melee attack or Hammer of the Righteous spell damage considered as melee attack - bool stacker = !procSpell || procSpell->Id == 53595; - // spells with SPELL_DAMAGE_CLASS_MELEE excluding Judgements - bool damager = procSpell && (procSpell->EquippedItemClass != -1 || (procSpell->SpellIconID == 243 && procSpell->SpellVisual[0] == 39)); - - if (!stacker && !damager) - return false; - - triggered_spell_id = 53742; - - if (Aura* aur = victim->GetAura(triggered_spell_id, GetGUID())) - { - if (aur->GetStackAmount() == 5) - { - if (stacker) - aur->RefreshDuration(); - } - } - - CastSpell(victim, 53739, true, castItem, triggeredByAura); // Seal of Corruption - - if (!stacker) - return false; - break; - } - // Spiritual Attunement - case 31785: - case 33776: - { - // if healed by another unit (victim) - if (this == victim) - return false; - - // dont allow non-positive dots to proc - if (!procSpell || !procSpell->IsPositive()) - return false; - - HealInfo const* healInfo = eventInfo.GetHealInfo(); - if (!healInfo) - { - return false; - } - - uint32 effectiveHeal = healInfo->GetEffectiveHeal(); - if (effectiveHeal) - { - // heal amount - basepoints0 = int32(CalculatePct(effectiveHeal, triggerAmount)); - target = this; - - if (basepoints0) - triggered_spell_id = 31786; - } - break; - } - // Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal) - case 40470: - { - if (!procSpell) - return false; - - float chance = 0.0f; - - // Flash of light/Holy light - if (procSpell->SpellFamilyFlags[0] & 0xC0000000) - { - triggered_spell_id = 40471; - chance = 15.0f; - } - // Judgement (any) - else if (procSpell->SpellFamilyFlags[0] & 0x800000) - { - triggered_spell_id = 40472; - chance = 50.0f; - } - else - return false; - - if (!roll_chance_f(chance)) - return false; - - break; - } - // Glyph of Holy Light - case 54937: - { - triggered_spell_id = 54968; - basepoints0 = CalculatePct(int32(damage), triggerAmount); - break; - } - // Item - Paladin T8 Holy 2P Bonus - case 64890: - { - triggered_spell_id = 64891; - basepoints0 = triggerAmount * damage / 300; - break; - } - case 71406: // Tiny Abomination in a Jar - case 71545: // Tiny Abomination in a Jar (Heroic) - { - if (!victim || !victim->IsAlive()) - return false; - - CastSpell(this, 71432, true, nullptr, triggeredByAura); - - Aura const* dummy = GetAura(71432); - if (!dummy || dummy->GetStackAmount() < (dummySpell->Id == 71406 ? 8 : 7)) - return false; - - RemoveAurasDueToSpell(71432); - triggered_spell_id = 71433; // default main hand attack - // roll if offhand - if (Player const* player = ToPlayer()) - if (player->GetWeaponForAttack(OFF_ATTACK, true) && urand(0, 1)) - triggered_spell_id = 71434; - target = victim; - break; - } - // Item - Icecrown 25 Normal Dagger Proc - case 71880: - { - switch (getPowerType()) - { - case POWER_MANA: - triggered_spell_id = 71881; - break; - case POWER_RAGE: - triggered_spell_id = 71883; - break; - case POWER_ENERGY: - triggered_spell_id = 71882; - break; - case POWER_RUNIC_POWER: - triggered_spell_id = 71884; - break; - default: - return false; - } - break; - } - // Item - Icecrown 25 Heroic Dagger Proc - case 71892: - { - switch (getPowerType()) - { - case POWER_MANA: - triggered_spell_id = 71888; - break; - case POWER_RAGE: - triggered_spell_id = 71886; - break; - case POWER_ENERGY: - triggered_spell_id = 71887; - break; - case POWER_RUNIC_POWER: - triggered_spell_id = 71885; - break; - default: - return false; - } - break; - } - } - break; - } - case SPELLFAMILY_SHAMAN: - { - switch (dummySpell->Id) - { - // Tidal Force - case 55198: - { - // Remove aura stack from caster - RemoveAuraFromStack(55166); - // drop charges - return false; - } - // Totemic Power (The Earthshatterer set) - case 28823: - { - if (!victim) - return false; - - // Set class defined buff - switch (victim->getClass()) - { - case CLASS_PALADIN: - case CLASS_PRIEST: - case CLASS_SHAMAN: - case CLASS_DRUID: - triggered_spell_id = 28824; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d. - break; - case CLASS_MAGE: - case CLASS_WARLOCK: - triggered_spell_id = 28825; // Increases the friendly target's spell damage and healing by up to $s1 for $d. - break; - case CLASS_HUNTER: - case CLASS_ROGUE: - triggered_spell_id = 28826; // Increases the friendly target's attack power by $s1 for $d. - break; - case CLASS_WARRIOR: - triggered_spell_id = 28827; // Increases the friendly target's armor - break; - default: - return false; - } - break; - } - // Lesser Healing Wave (Totem of Flowing Water Relic) - case 28849: - { - target = this; - triggered_spell_id = 28850; - break; - } - // Windfury Weapon (Passive) 1-8 Ranks - case 33757: - { - Player* player = ToPlayer(); - if (!player || !castItem || !castItem->IsEquipped() || !victim || !victim->IsAlive()) - return false; - - if (triggeredByAura->GetBase() && castItem->GetGUID() != triggeredByAura->GetBase()->GetCastItemGUID()) - return false; - - WeaponAttackType attType = player->GetAttackBySlot(castItem->GetSlot()); - if ((attType != BASE_ATTACK && attType != OFF_ATTACK) - || (attType == BASE_ATTACK && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK) - || (attType == OFF_ATTACK && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK)) - return false; - - // Now amount of extra power stored in 1 effect of Enchant spell - // Get it by item enchant id - uint32 spellId; - switch (castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT))) - { - case 283: - spellId = 8232; - break; // 1 Rank - case 284: - spellId = 8235; - break; // 2 Rank - case 525: - spellId = 10486; - break; // 3 Rank - case 1669: - spellId = 16362; - break; // 4 Rank - case 2636: - spellId = 25505; - break; // 5 Rank - case 3785: - spellId = 58801; - break; // 6 Rank - case 3786: - spellId = 58803; - break; // 7 Rank - case 3787: - spellId = 58804; - break; // 8 Rank - default: - { - LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non handled item enchantment (rank?) {} for spell id: {} (Windfury)", - castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT)), dummySpell->Id); - return false; - } - } - - SpellInfo const* windfurySpellInfo = sSpellMgr->GetSpellInfo(spellId); - if (!windfurySpellInfo) - { - LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non-existing spell id: {} (Windfury)", spellId); - return false; - } - - int32 extra_attack_power = CalculateSpellDamage(victim, windfurySpellInfo, 1); - - // Value gained from additional AP - basepoints0 = int32(extra_attack_power / 14.0f * GetAttackTime(attType) / 1000); - - if (procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK) - triggered_spell_id = 25504; - - if (procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK) - triggered_spell_id = 33750; - - // custom cooldown processing case - if (player->HasSpellCooldown(dummySpell->Id)) - return false; - - // apply cooldown before cast to prevent processing itself - player->AddSpellCooldown(dummySpell->Id, 0, 3 * IN_MILLISECONDS); - - // Attack Twice - for (uint32 i = 0; i < 2; ++i) - CastCustomSpell(victim, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura); - - return true; - } - // Shaman Tier 6 Trinket - case 40463: - { - if (!procSpell) - return false; - - float chance; - if (procSpell->SpellFamilyFlags[0] & 0x1) - { - triggered_spell_id = 40465; // Lightning Bolt - chance = 15.0f; - } - else if (procSpell->SpellFamilyFlags[0] & 0x80) - { - triggered_spell_id = 40465; // Lesser Healing Wave - chance = 10.0f; - } - else if (procSpell->SpellFamilyFlags[1] & 0x00000010) - { - triggered_spell_id = 40466; // Stormstrike - chance = 50.0f; - } - else - return false; - - if (!roll_chance_f(chance)) - return false; - - target = this; - break; - } - // Glyph of Healing Wave - case 55440: - { - // Not proc from self heals - if (this == victim) - return false; - basepoints0 = CalculatePct(int32(damage), triggerAmount); - target = this; - triggered_spell_id = 55533; - break; - } - // Spirit Hunt - case 58877: - { - // Cast on owner - target = GetOwner(); - if (!target) - return false; - basepoints0 = CalculatePct(int32(damage), triggerAmount); - triggered_spell_id = 58879; - // Heal wolf - CastCustomSpell(this, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura, originalCaster); - break; - } - // Shaman T9 Elemental 4P Bonus - case 67228: - { - // Lava Burst - if (procSpell->SpellFamilyFlags[1] & 0x1000) - { - triggered_spell_id = 71824; - SpellInfo const* triggeredSpell = sSpellMgr->GetSpellInfo(triggered_spell_id); - if (!triggeredSpell) - return false; - basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / triggeredSpell->Effects[0].Amplitude); - } - break; - } - // Item - Shaman T10 Elemental 4P Bonus - case 70817: - { - if (!target) - return false; - // try to find spell Flame Shock on the target - if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0x0, 0x0, GetGUID())) - { - Aura* flameShock = aurEff->GetBase(); - int32 extraTime = 2 * aurEff->GetAmplitude(); - flameShock->SetMaxDuration(flameShock->GetMaxDuration() + extraTime); - flameShock->SetDuration(flameShock->GetDuration() + extraTime); - - return true; - } - // if not found Flame Shock - return false; - } - break; - } - // Frozen Power - if (dummySpell->SpellIconID == 3780) - { - if (!target) - return false; - if (GetDistance(target) < 15.0f) - return false; - float chance = (float)triggerAmount; - if (!roll_chance_f(chance)) - return false; - - triggered_spell_id = 63685; - break; - } - // Ancestral Awakening - if (dummySpell->SpellIconID == 3065) - { - triggered_spell_id = 52759; - basepoints0 = CalculatePct(int32(damage), triggerAmount); - target = this; - break; - } - // Flametongue Weapon (Passive) - if (dummySpell->SpellFamilyFlags[0] & 0x200000) - { - if (!IsPlayer() || !victim || !victim->IsAlive() || !castItem || !castItem->IsEquipped()) - return false; - - WeaponAttackType attType = Player::GetAttackBySlot(castItem->GetSlot()); - if ((attType != BASE_ATTACK && attType != OFF_ATTACK) - || (attType == BASE_ATTACK && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK) - || (attType == OFF_ATTACK && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK)) - return false; - - float fire_onhit = float(CalculatePct(dummySpell->Effects[EFFECT_0]. CalcValue(), 1.0f)); - - float add_spellpower = (float)(SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE) - + victim->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_FIRE)); - - // 1.3speed = 5%, 2.6speed = 10%, 4.0 speed = 15%, so, 1.0speed = 3.84% - ApplyPct(add_spellpower, 3.84f); - - // Enchant on Off-Hand and ready? - if (castItem->GetSlot() == EQUIPMENT_SLOT_OFFHAND && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK) - { - float BaseWeaponSpeed = GetAttackTime(OFF_ATTACK) / 1000.0f; - - // Value1: add the tooltip damage by swingspeed + Value2: add spelldmg by swingspeed - basepoints0 = int32((fire_onhit * BaseWeaponSpeed) + (add_spellpower * BaseWeaponSpeed)); - triggered_spell_id = 10444; - } - - // Enchant on Main-Hand and ready? - else if (castItem->GetSlot() == EQUIPMENT_SLOT_MAINHAND && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK) - { - float BaseWeaponSpeed = GetAttackTime(BASE_ATTACK) / 1000.0f; - - // Value1: add the tooltip damage by swingspeed + Value2: add spelldmg by swingspeed - basepoints0 = int32((fire_onhit * BaseWeaponSpeed) + (add_spellpower * BaseWeaponSpeed)); - triggered_spell_id = 10444; - } - - // If not ready, we should return, shouldn't we?! - else - return false; - - CastCustomSpell(victim, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura); - return true; - } - // Improved Water Shield - if (dummySpell->SpellIconID == 2287) - { - if (!procSpell) - return false; - - // Default chance for Healing Wave and Riptide - float chance = (float)triggeredByAura->GetAmount(); - - if (procSpell->SpellFamilyFlags[0] & 0x80) - // Lesser Healing Wave - 0.6 of default - chance *= 0.6f; - else if (procSpell->SpellFamilyFlags[0] & 0x100) - // Chain heal - 0.3 of default - chance *= 0.3f; - - if (!roll_chance_f(chance)) - return false; - - // Water Shield - if (AuraEffect const* aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0, 0x00000020, 0)) - { - uint32 spell = aurEff->GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; - CastSpell(this, spell, true, castItem, triggeredByAura); - return true; - } - return false; - } - // Lightning Overload - if (dummySpell->SpellIconID == 2018) // only this spell have SpellFamily Shaman SpellIconID == 2018 and dummy aura - { - if (!procSpell || !IsPlayer() || !victim) - return false; - - uint32 spell = 45284; - - // chain lightning only procs 1/3 of the time - if (procSpell->SpellFamilyFlags[0] & 0x2) - { - if (!roll_chance_i(33)) - return false; - spell = 45297; - } - - if (procEx & PROC_EX_CRITICAL_HIT) - damage /= 2; - - // do not reduce damage-spells have correct basepoints - damage /= 2; - int32 dmg = damage; - - // Cast - CastCustomSpell(victim, spell, &dmg, 0, 0, true, castItem, triggeredByAura); - return true; - } - // Static Shock - if (dummySpell->SpellIconID == 3059) - { - // Lightning Shield - if (AuraEffect const* aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x400, 0, 0)) - { - uint32 spell = sSpellMgr->GetSpellWithRank(26364, aurEff->GetSpellInfo()->GetRank()); - CastSpell(target, spell, true, castItem, triggeredByAura); - aurEff->GetBase()->DropCharge(); - return true; - } - return false; - } - break; - } - case SPELLFAMILY_DEATHKNIGHT: - { - // Improved Blood Presence - if (dummySpell->SpellIconID == 2636) - { - if (!IsPlayer()) - return false; - basepoints0 = CalculatePct(int32(damage), triggerAmount); - break; - } - // Butchery - if (dummySpell->SpellIconID == 2664) - { - basepoints0 = triggerAmount; - triggered_spell_id = 50163; - target = this; - break; - } - // Mark of Blood - if (dummySpell->Id == 49005) - { - /// @todo: need more info (cooldowns/PPM) - triggered_spell_id = 61607; - break; - } - // Unholy Blight - if (dummySpell->Id == 49194) - { - triggered_spell_id = 50536; - SpellInfo const* unholyBlight = sSpellMgr->GetSpellInfo(triggered_spell_id); - if (!unholyBlight || !victim) - return false; - - basepoints0 = CalculatePct(int32(damage), triggerAmount); - - //Glyph of Unholy Blight - if (AuraEffect* glyph = GetAuraEffect(63332, 0)) - AddPct(basepoints0, glyph->GetAmount()); - - basepoints0 = basepoints0 / (unholyBlight->GetMaxDuration() / unholyBlight->Effects[0].Amplitude); - victim->CastDelayedSpellWithPeriodicAmount(this, triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE, basepoints0); - return true; - } - // Vendetta - if (dummySpell->SpellFamilyFlags[0] & 0x10000) - { - basepoints0 = int32(CountPctFromMaxHealth(triggerAmount)); - triggered_spell_id = 50181; - target = this; - break; - } - // Necrosis - if (dummySpell->SpellIconID == 2709) - { - basepoints0 = CalculatePct(int32(damage), triggerAmount); - triggered_spell_id = 51460; - break; - } - // Threat of Thassarian - if (dummySpell->SpellIconID == 2023) - { - // Must Dual Wield - if (!procSpell || !HasOffhandWeaponForAttack()) - return false; - // Chance as basepoints for dummy aura - if (!roll_chance_i(triggerAmount)) - return false; - - switch (procSpell->Id) - { - // Obliterate - case 49020: - triggered_spell_id = 66198; - break; // Rank 1 - case 51423: - triggered_spell_id = 66972; - break; // Rank 2 - case 51424: - triggered_spell_id = 66973; - break; // Rank 3 - case 51425: - triggered_spell_id = 66974; - break; // Rank 4 - - // Frost Strike - case 49143: - triggered_spell_id = 66196; - break; // Rank 1 - case 51416: - triggered_spell_id = 66958; - break; // Rank 2 - case 51417: - triggered_spell_id = 66959; - break; // Rank 3 - case 51418: - triggered_spell_id = 66960; - break; // Rank 4 - case 51419: - triggered_spell_id = 66961; - break; // Rank 5 - case 55268: - triggered_spell_id = 66962; - break; // Rank 6 - - // Plague Strike - case 45462: - triggered_spell_id = 66216; - break; // Rank 1 - case 49917: - triggered_spell_id = 66988; - break; // Rank 2 - case 49918: - triggered_spell_id = 66989; - break; // Rank 3 - case 49919: - triggered_spell_id = 66990; - break; // Rank 4 - case 49920: - triggered_spell_id = 66991; - break; // Rank 5 - case 49921: - triggered_spell_id = 66992; - break; // Rank 6 - - // Death Strike - case 49998: - triggered_spell_id = 66188; - break; // Rank 1 - case 49999: - triggered_spell_id = 66950; - break; // Rank 2 - case 45463: - triggered_spell_id = 66951; - break; // Rank 3 - case 49923: - triggered_spell_id = 66952; - break; // Rank 4 - case 49924: - triggered_spell_id = 66953; - break; // Rank 5 - - // Rune Strike - case 56815: - triggered_spell_id = 66217; - break; // Rank 1 - - // Blood Strike - case 45902: - triggered_spell_id = 66215; - break; // Rank 1 - case 49926: - triggered_spell_id = 66975; - break; // Rank 2 - case 49927: - triggered_spell_id = 66976; - break; // Rank 3 - case 49928: - triggered_spell_id = 66977; - break; // Rank 4 - case 49929: - triggered_spell_id = 66978; - break; // Rank 5 - case 49930: - triggered_spell_id = 66979; - break; // Rank 6 - default: - return false; - } - - // This should do, restore spell mod so next attack can also use this! - // crit chance for first strike is already computed - ToPlayer()->RestoreSpellMods(m_currentSpells[CURRENT_GENERIC_SPELL], 51124, nullptr); // Killing Machine - ToPlayer()->RestoreSpellMods(m_currentSpells[CURRENT_GENERIC_SPELL], 49796, nullptr); // Deathchill - - // Xinef: Somehow basepoints are divided by 2 which is later divided by 2 (offhand multiplier) - SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id); - if (triggerEntry->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) - basepoints0 = triggerEntry->Effects[EFFECT_0].BasePoints * 2; - - SetCantProc(true); - if (basepoints0) - CastCustomSpell(target, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura, originalCaster); - else - CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura, originalCaster); - SetCantProc(false); - return true; - } - // Runic Power Back on Snare/Root - if (dummySpell->Id == 61257) - { - // only for spells and hit/crit (trigger start always) and not start from self casted spells - if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) || this == victim) - return false; - // Need snare or root mechanic - if (!(procSpell->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_SNARE)))) - return false; - triggered_spell_id = 61258; - target = this; - break; - } - // Sudden Doom - if (dummySpell->SpellIconID == 1939 && IsPlayer()) - { - SpellChainNode const* chain = nullptr; - // get highest rank of the Death Coil spell - PlayerSpellMap const& sp_list = ToPlayer()->GetSpellMap(); - for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) - { - // check if shown in spell book - if (!itr->second->Active || !itr->second->IsInSpec(ToPlayer()->GetActiveSpec()) || itr->second->State == PLAYERSPELL_REMOVED) - continue; - - SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(itr->first); - if (!spellProto) - continue; - - if (spellProto->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT - && spellProto->SpellFamilyFlags[0] & 0x2000) - { - SpellChainNode const* newChain = sSpellMgr->GetSpellChainNode(itr->first); - - // No chain entry or entry lower than found entry - if (!chain || !newChain || (chain->rank < newChain->rank)) - { - triggered_spell_id = itr->first; - chain = newChain; - } - else - continue; - // Found spell is last in chain - do not need to look more - // Optimisation for most common case - if (chain && chain->last->Id == itr->first) - break; - } - } - } - break; - } - case SPELLFAMILY_POTION: - { - // alchemist's stone - if (dummySpell->Id == 17619) - { - if (procSpell->SpellFamilyName == SPELLFAMILY_POTION) - { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++) - { - if (procSpell->Effects[i].Effect == SPELL_EFFECT_HEAL) - { - triggered_spell_id = 21399; - } - else if (procSpell->Effects[i].Effect == SPELL_EFFECT_ENERGIZE) - { - triggered_spell_id = 21400; - } - else - continue; - - basepoints0 = int32(CalculateSpellDamage(this, procSpell, i) * 0.4f); - CastCustomSpell(this, triggered_spell_id, &basepoints0, nullptr, nullptr, true, nullptr, triggeredByAura); - } - return true; - } - } - break; - } - case SPELLFAMILY_PET: - { - switch (dummySpell->SpellIconID) - { - // Guard Dog - case 201: - { - if (!victim) - return false; - - triggered_spell_id = 54445; - target = this; - float addThreat = float(CalculatePct(procSpell->Effects[0].CalcValue(this), triggerAmount)); - victim->AddThreat(this, addThreat); - break; - } - // Silverback - case 1582: - triggered_spell_id = dummySpell->Id == 62765 ? 62801 : 62800; - target = this; - break; - } - break; - } - default: - break; - } - - // if not handled by custom case, get triggered spell from dummySpell proto - if (!triggered_spell_id) - triggered_spell_id = dummySpell->Effects[triggeredByAura->GetEffIndex()].TriggerSpell; - - // processed charge only counting case - if (!triggered_spell_id) - return true; - - SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id); - if (!triggerEntry) - { - LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: Spell {} has non-existing triggered spell {}", dummySpell->Id, triggered_spell_id); - return false; - } - - if (cooldown_spell_id == 0) - cooldown_spell_id = triggered_spell_id; - - if (cooldown) - { - if (HasSpellCooldown(cooldown_spell_id)) - return false; - - AddSpellCooldown(cooldown_spell_id, 0, cooldown); - } - - if (basepoints0) - CastCustomSpell(target, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura, originalCaster); - else - CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura, originalCaster); - - return true; -} - -// Used in case when access to whole aura is needed -// All procs should be handled like this... -bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* /*procSpell*/, uint32 /*procFlag*/, uint32 procEx, uint32 cooldown, bool* handled) -{ - SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo(); - - switch (dummySpell->SpellFamilyName) - { - case SPELLFAMILY_GENERIC: - switch (dummySpell->Id) - { - // Nevermelting Ice Crystal - case 71564: - RemoveAuraFromStack(71564); - *handled = true; - break; - // Gaseous Bloat - case 70672: - case 72455: - case 72832: - case 72833: - { - if (Unit* caster = triggeredByAura->GetCaster()) - if (victim && caster->GetGUID() == victim->GetGUID()) - { - *handled = true; - uint32 stack = triggeredByAura->GetStackAmount(); - int32 const mod = (GetMap()->GetSpawnMode() & 1) ? 1500 : 1250; - int32 dmg = 0; - for (uint8 i = 1; i <= stack; ++i) - dmg += mod * i; - caster->CastCustomSpell(70701, SPELLVALUE_BASE_POINT0, dmg); - } - break; - } - // Ball of Flames Proc - case 71756: - case 72782: - case 72783: - case 72784: - RemoveAuraFromStack(dummySpell->Id); - *handled = true; - break; - // Discerning Eye of the Beast - case 59915: - { - CastSpell(this, 59914, true); // 59914 already has correct basepoints in DBC, no need for custom bp - *handled = true; - break; - } - // Swift Hand of Justice - case 59906: - { - int32 bp0 = CalculatePct(GetMaxHealth(), dummySpell->Effects[EFFECT_0]. CalcValue()); - CastCustomSpell(this, 59913, &bp0, nullptr, nullptr, true); - *handled = true; - break; - } - } - - break; - case SPELLFAMILY_MAGE: - { - // Combustion - switch (dummySpell->Id) - { - case 11129: - { - *handled = true; - Unit* caster = triggeredByAura->GetCaster(); - if (!caster || !damage) - return false; - - // last charge and crit - if (triggeredByAura->GetCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT)) - return true; // charge counting (will removed) - - CastSpell(this, 28682, true); - - return procEx & PROC_EX_CRITICAL_HIT; - } - // Empowered Fire - case 31656: - case 31657: - case 31658: - { - *handled = true; - - SpellInfo const* spInfo = sSpellMgr->GetSpellInfo(67545); - if (!spInfo) - return false; - - int32 bp0 = int32(CalculatePct(GetMaxPower(POWER_MANA), spInfo->Effects[0].CalcValue())); - CastCustomSpell(this, 67545, &bp0, nullptr, nullptr, true, nullptr, triggeredByAura->GetEffect(EFFECT_0), GetGUID()); - return true; - } - } - break; - } - case SPELLFAMILY_DEATHKNIGHT: - { - // Blood of the North - // Reaping - // Death Rune Mastery - // xinef: Icon 22 is used for item bonus, skip - if (dummySpell->SpellIconID == 3041 || (dummySpell->SpellIconID == 22 && dummySpell->Id != 62459) || dummySpell->SpellIconID == 2622) - { - *handled = true; - // Convert recently used Blood Rune to Death Rune - if (Player* player = ToPlayer()) - { - if (!player->IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_ABILITY)) - return false; - - // xinef: not true - //RuneType rune = ToPlayer()->GetLastUsedRune(); - // can't proc from death rune use - //if (rune == RUNE_DEATH) - // return false; - AuraEffect* aurEff = triggeredByAura->GetEffect(EFFECT_0); - if (!aurEff) - return false; - - // Reset amplitude - set death rune remove timer to 30s - aurEff->ResetPeriodic(true); - uint32 runesLeft; - - if (dummySpell->SpellIconID == 2622) - runesLeft = 2; - else - runesLeft = 1; - - for (uint8 i = 0; i < MAX_RUNES && runesLeft; ++i) - { - if (dummySpell->SpellIconID == 2622) - { - if (player->GetCurrentRune(i) == RUNE_DEATH || - player->GetBaseRune(i) == RUNE_BLOOD) - continue; - } - else - { - if (player->GetCurrentRune(i) == RUNE_DEATH || - player->GetBaseRune(i) != RUNE_BLOOD) - continue; - } - if (player->GetRuneCooldown(i) != player->GetRuneBaseCooldown(i, false)) - continue; - - --runesLeft; - // Mark aura as used - player->AddRuneByAuraEffect(i, RUNE_DEATH, aurEff); - } - return true; - } - return false; - } - break; - } - case SPELLFAMILY_WARRIOR: - { - switch (dummySpell->Id) - { - // Item - Warrior T10 Protection 4P Bonus - case 70844: - { - int32 basepoints0 = CalculatePct(GetMaxHealth(), dummySpell->Effects[EFFECT_1]. CalcValue()); - CastCustomSpell(this, 70845, &basepoints0, nullptr, nullptr, true); - break; - } - default: - break; - } - break; - } - case SPELLFAMILY_SHAMAN: - { - // Flurry - if ((dummySpell->SpellFamilyFlags[1] & 0x00000200) != 0) - { - if (cooldown) - { - if (HasSpellCooldown(dummySpell->Id)) - { - *handled = true; - break; - } - - AddSpellCooldown(dummySpell->Id, 0, cooldown); - } - } - break; - } - } - return false; -} - -bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo& eventInfo) -{ - // Get triggered aura spell info - SpellInfo const* auraSpellInfo = triggeredByAura->GetSpellInfo(); - - // Basepoints of trigger aura - int32 triggerAmount = triggeredByAura->GetAmount(); - - // Set trigger spell id, target, custom basepoints - uint32 trigger_spell_id = auraSpellInfo->Effects[triggeredByAura->GetEffIndex()].TriggerSpell; - - Unit* target = nullptr; - int32 basepoints0 = 0; - - if (triggeredByAura->GetAuraType() == SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE) - basepoints0 = triggerAmount; - - Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && IsPlayer() - ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr; - - // Try handle unknown trigger spells - //if (sSpellMgr->GetSpellInfo(trigger_spell_id) == nullptr) - { - switch (auraSpellInfo->SpellFamilyName) - { - case SPELLFAMILY_GENERIC: - switch (auraSpellInfo->Id) - { - case 43820: // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket) - // Pct value stored in dummy - if (!victim) - return false; - basepoints0 = victim->GetCreateHealth() * auraSpellInfo->Effects[1].CalcValue() / 100; - target = victim; - break; - case 57345: // Darkmoon Card: Greatness - { - float stat = 0.0f; - // strength - if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 60229; stat = GetStat(STAT_STRENGTH); } - // agility - if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 60233; stat = GetStat(STAT_AGILITY); } - // intellect - if (GetStat(STAT_INTELLECT) > stat) { trigger_spell_id = 60234; stat = GetStat(STAT_INTELLECT);} - // spirit - if (GetStat(STAT_SPIRIT) > stat) { trigger_spell_id = 60235; } - break; - } - case 67702: // Death's Choice, Item - Coliseum 25 Normal Melee Trinket - { - if (!damage) - return false; - float stat = 0.0f; - // strength - if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 67708; stat = GetStat(STAT_STRENGTH); } - // agility - if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 67703; } - break; - } - case 67771: // Death's Choice (heroic), Item - Coliseum 25 Heroic Melee Trinket - { - if (!damage) - return false; - float stat = 0.0f; - // strength - if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 67773; stat = GetStat(STAT_STRENGTH); } - // agility - if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 67772; } - break; - } - case 27522: // Mana Drain Trigger - case 40336: // Mana Drain Trigger - case 46939: // Black Bow of the Betrayer - { - // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target. - if (IsAlive()) - CastSpell(this, 29471, true, castItem, triggeredByAura); - if (victim && victim->IsAlive()) - CastSpell(victim, 27526, true, castItem, triggeredByAura); - return true; - } - // Forge of Souls, Devourer of Souls, Mirrored Soul - case 69023: - { - int32 dmg = damage * 0.45f; - if (dmg > 0) - if (Aura* a = GetAura(69023)) - if (Unit* c = a->GetCaster()) - CastCustomSpell(c, 69034, &dmg, 0, 0, true); - return true; - } - // Soul-Trader Beacon proc aura - case 50051: - { - if (!victim) - return false; - - if (Creature* cr = GetCompanionPet()) - cr->CastSpell(victim, 50101, true); - - return false; - } - } - break; - case SPELLFAMILY_MAGE: - if (auraSpellInfo->SpellIconID == 2127) // Blazing Speed - { - switch (auraSpellInfo->Id) - { - case 31641: // Rank 1 - case 31642: // Rank 2 - trigger_spell_id = 31643; - break; - default: - LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} miss posibly Blazing Speed", auraSpellInfo->Id); - return false; - } - } - else if (auraSpellInfo->Id == 71761) // Deep Freeze Immunity State (only permanent) - { - Creature* creature = victim->ToCreature(); - if (!creature || !creature->HasMechanicTemplateImmunity(1 << (MECHANIC_STUN - 1))) - return false; - } - break; - case SPELLFAMILY_WARLOCK: - { - // Nether Protection - if (auraSpellInfo->SpellIconID == 1985) - { - if (!procSpell) - return false; - switch (GetFirstSchoolInMask(procSpell->GetSchoolMask())) - { - case SPELL_SCHOOL_NORMAL: - return false; // ignore - case SPELL_SCHOOL_HOLY: - trigger_spell_id = 54370; - break; - case SPELL_SCHOOL_FIRE: - trigger_spell_id = 54371; - break; - case SPELL_SCHOOL_NATURE: - trigger_spell_id = 54375; - break; - case SPELL_SCHOOL_FROST: - trigger_spell_id = 54372; - break; - case SPELL_SCHOOL_SHADOW: - trigger_spell_id = 54374; - break; - case SPELL_SCHOOL_ARCANE: - trigger_spell_id = 54373; - break; - default: - return false; - } - } - break; - } - case SPELLFAMILY_PRIEST: - { - // Blessed Recovery - if (auraSpellInfo->SpellIconID == 1875) - { - switch (auraSpellInfo->Id) - { - case 27811: - trigger_spell_id = 27813; - break; - case 27815: - trigger_spell_id = 27817; - break; - case 27816: - trigger_spell_id = 27818; - break; - default: - LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} not handled in BR", auraSpellInfo->Id); - return false; - } - basepoints0 = CalculatePct(int32(damage), triggerAmount) / 3; - target = this; - // Add remaining ticks to healing done - CastDelayedSpellWithPeriodicAmount(this, trigger_spell_id, SPELL_AURA_PERIODIC_HEAL, basepoints0); - return true; - } - break; - } - case SPELLFAMILY_DRUID: - { - switch (auraSpellInfo->Id) - { - // Druid Forms Trinket - case 37336: - { - switch (GetShapeshiftForm()) - { - case FORM_NONE: - trigger_spell_id = 37344; - break; - case FORM_CAT: - trigger_spell_id = 37341; - break; - case FORM_BEAR: - case FORM_DIREBEAR: - trigger_spell_id = 37340; - break; - case FORM_TREE: - trigger_spell_id = 37342; - break; - case FORM_MOONKIN: - trigger_spell_id = 37343; - break; - default: - return false; - } - break; - } - // Druid T9 Feral Relic (Lacerate, Swipe, Mangle, and Shred) - case 67353: - { - switch (GetShapeshiftForm()) - { - case FORM_CAT: - trigger_spell_id = 67355; - break; - case FORM_BEAR: - case FORM_DIREBEAR: - trigger_spell_id = 67354; - break; - default: - return false; - } - break; - } - default: - break; - } - break; - } - case SPELLFAMILY_HUNTER: - { - if (auraSpellInfo->SpellIconID == 3247) // Piercing Shots - { - if (!victim) - return false; - - switch (auraSpellInfo->Id) - { - case 53234: // Rank 1 - case 53237: // Rank 2 - case 53238: // Rank 3 - trigger_spell_id = 63468; - break; - default: - LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} miss posibly Piercing Shots", auraSpellInfo->Id); - return false; - } - SpellInfo const* TriggerPS = sSpellMgr->GetSpellInfo(trigger_spell_id); - if (!TriggerPS) - return false; - - basepoints0 = CalculatePct(int32(damage), triggerAmount) / (TriggerPS->GetMaxDuration() / TriggerPS->Effects[0].Amplitude); - victim->CastDelayedSpellWithPeriodicAmount(this, trigger_spell_id, SPELL_AURA_PERIODIC_DAMAGE, basepoints0); - return true; - } - // Item - Hunter T9 4P Bonus (Steady Shot) - else if (auraSpellInfo->Id == 67151) - { - if (!IsPlayer() || !ToPlayer()->GetPet()) - return false; - - target = ToPlayer()->GetPet(); - trigger_spell_id = 68130; - break; - } - break; - } - case SPELLFAMILY_PALADIN: - { - switch (auraSpellInfo->Id) - { - case 37657: // Lightning Capacitor - case 54841: // Thunder Capacitor - case 67712: // Item - Coliseum 25 Normal Caster Trinket - case 67758: // Item - Coliseum 25 Heroic Caster Trinket - { - if (!victim || !victim->IsAlive() || !IsPlayer()) - return false; - - uint32 stack_spell_id = 0; - switch (auraSpellInfo->Id) - { - case 37657: - stack_spell_id = 37658; - trigger_spell_id = 37661; - break; - case 54841: - stack_spell_id = 54842; - trigger_spell_id = 54843; - break; - case 67712: - stack_spell_id = 67713; - trigger_spell_id = 67714; - break; - case 67758: - stack_spell_id = 67759; - trigger_spell_id = 67760; - break; - } - - if (cooldown && ToPlayer()->HasSpellCooldown(stack_spell_id)) - { - return false; - } - - CastSpell(this, stack_spell_id, true, nullptr, triggeredByAura); - - Aura* dummy = GetAura(stack_spell_id); - if (!dummy || dummy->GetStackAmount() < triggerAmount) - { - return false; - } - - if (cooldown) - { - ToPlayer()->AddSpellCooldown(stack_spell_id, 0, cooldown); - } - RemoveAurasDueToSpell(stack_spell_id); - CastSpell(victim, trigger_spell_id, true, nullptr, triggeredByAura); - return true; - } - default: - // Illumination - if (auraSpellInfo->SpellIconID == 241) - { - if (!procSpell) - return false; - // procspell is triggered spell but we need mana cost of original casted spell - uint32 originalSpellId = procSpell->Id; - // Holy Shock heal - if (procSpell->SpellFamilyFlags[1] & 0x00010000) - { - switch (procSpell->Id) - { - case 25914: - originalSpellId = 20473; - break; - case 25913: - originalSpellId = 20929; - break; - case 25903: - originalSpellId = 20930; - break; - case 27175: - originalSpellId = 27174; - break; - case 33074: - originalSpellId = 33072; - break; - case 48820: - originalSpellId = 48824; - break; - case 48821: - originalSpellId = 48825; - break; - default: - LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} not handled in HShock", procSpell->Id); - return false; - } - } - SpellInfo const* originalSpell = sSpellMgr->GetSpellInfo(originalSpellId); - if (!originalSpell) - { - LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} unknown but selected as original in Illu", originalSpellId); - return false; - } - // percent stored in effect 1 (class scripts) base points - int32 cost = int32(originalSpell->ManaCost + CalculatePct(GetCreateMana(), originalSpell->ManaCostPercentage)); - basepoints0 = CalculatePct(cost, auraSpellInfo->Effects[1].CalcValue()); - trigger_spell_id = 20272; - target = this; - } - break; - } - break; - } - case SPELLFAMILY_SHAMAN: - { - // Lightning Shield (overwrite non existing triggered spell call in spell.dbc - if (auraSpellInfo->SpellFamilyFlags[0] & 0x400 && auraSpellInfo->HasAttribute(SPELL_ATTR1_NO_THREAT)) - { - // Do not proc off from self-casted items - if (Spell const* spell = eventInfo.GetProcSpell()) - { - if (spell->m_castItemGUID && victim->GetGUID() == GetGUID()) - { - return false; - } - } - - trigger_spell_id = sSpellMgr->GetSpellWithRank(26364, auraSpellInfo->GetRank()); - } - // Nature's Guardian - else if (auraSpellInfo->SpellIconID == 2013) - { - // Check health condition - should drop to less 30% (damage deal after this!) - if (!HealthBelowPctDamaged(30, damage)) - return false; - - if (victim && victim->IsAlive()) - victim->GetThreatMgr().ModifyThreatByPercent(this, -10); - - basepoints0 = int32(CountPctFromMaxHealth(triggerAmount)); - trigger_spell_id = 31616; - target = this; - } - break; - } - case SPELLFAMILY_DEATHKNIGHT: - { - // Acclimation - if (auraSpellInfo->SpellIconID == 1930) - { - if (!procSpell) - return false; - switch (GetFirstSchoolInMask(procSpell->GetSchoolMask())) - { - case SPELL_SCHOOL_NORMAL: - return false; // ignore - case SPELL_SCHOOL_HOLY: - trigger_spell_id = 50490; - break; - case SPELL_SCHOOL_FIRE: - trigger_spell_id = 50362; - break; - case SPELL_SCHOOL_NATURE: - trigger_spell_id = 50488; - break; - case SPELL_SCHOOL_FROST: - trigger_spell_id = 50485; - break; - case SPELL_SCHOOL_SHADOW: - trigger_spell_id = 50489; - break; - case SPELL_SCHOOL_ARCANE: - trigger_spell_id = 50486; - break; - default: - return false; - } - } - // Blood Presence (Improved) - else if (auraSpellInfo->Id == 63611) - { - if (!IsPlayer()) - return false; - - trigger_spell_id = 50475; - basepoints0 = CalculatePct(int32(damage), triggerAmount); - } - break; - } - } - } - - // All ok. Check current trigger spell - SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(trigger_spell_id); - if (!triggerEntry) - { - // Don't cast unknown spell - LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} (effIndex: {}) has unknown TriggerSpell {}. Unhandled custom case?", auraSpellInfo->Id, triggeredByAura->GetEffIndex(), trigger_spell_id); - return false; - } - - // not allow proc extra attack spell at extra attack - if (triggerEntry->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) - { - uint32 lastExtraAttackSpell = eventInfo.GetActor()->GetLastExtraAttackSpell(); - - // Patch 1.12.0(?) extra attack abilities can no longer chain proc themselves - if (lastExtraAttackSpell == trigger_spell_id) - { - return false; - } - - // Patch 2.2.0 Sword Specialization (Warrior, Rogue) extra attack can no longer proc additional extra attacks - // 3.3.5 Sword Specialization (Warrior), Hack and Slash (Rogue) - if (lastExtraAttackSpell == SPELL_SWORD_SPECIALIZATION || lastExtraAttackSpell == SPELL_HACK_AND_SLASH) - { - return false; - } - } - - // Custom requirements (not listed in procEx) Warning! damage dealing after this - // Custom triggered spells - switch (auraSpellInfo->Id) - { - // Deep Wounds - case 12834: - case 12849: - case 12867: - { - if (!IsPlayer()) - return false; - - if (procFlags & PROC_FLAG_DONE_OFFHAND_ATTACK) - basepoints0 = int32((GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE) + GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE)) / 2.0f); - else - basepoints0 = int32((GetFloatValue(UNIT_FIELD_MAXDAMAGE) + GetFloatValue(UNIT_FIELD_MINDAMAGE)) / 2.0f); - break; - } - // Persistent Shield (Scarab Brooch trinket) - // This spell originally trigger 13567 - Dummy Trigger (vs dummy efect) - case 26467: - { - basepoints0 = int32(CalculatePct(damage, 15)); - target = victim; - trigger_spell_id = 26470; - break; - } - // Unyielding Knights (item exploit 29108\29109) - case 38164: - { - if (!victim || victim->GetEntry() != 19457) // Proc only if your target is Grillok - return false; - break; - } - // Deflection - case 52420: - { - if (!HealthBelowPct(35)) - return false; - break; - } - - // Cheat Death - case 28845: - { - // When your health drops below 20% - if (HealthBelowPctDamaged(20, damage) || HealthBelowPct(20)) - return false; - break; - } - // Deadly Swiftness (Rank 1) - case 31255: - { - // whenever you deal damage to a target who is below 20% health. - if (!victim || !victim->IsAlive() || victim->HealthAbovePct(20)) - return false; - - target = this; - trigger_spell_id = 22588; - [[fallthrough]]; /// @todo: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked. - } - // Bonus Healing (Crystal Spire of Karabor mace) - case 40971: - { - // If your target is below $s1% health - if (!victim || !victim->IsAlive() || victim->HealthAbovePct(triggerAmount)) - return false; - break; - } - // Rapid Recuperation - case 53228: - case 53232: - { - // This effect only from Rapid Fire (ability cast) - if (!procSpell || !(procSpell->SpellFamilyFlags[0] & 0x20)) - return false; - break; - } - // Decimation - case 63156: - case 63158: - // Can proc only if target has hp below 35% - if (!victim || !victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, procSpell, this)) - return false; - break; - // Ulduar, Hodir, Toasty Fire - case 62821: - if (!this->IsPlayer()) // spell has Attribute, but persistent area auras ignore it - return false; - break; - case 15337: // Improved Spirit Tap (Rank 1) - case 15338: // Improved Spirit Tap (Rank 2) - { - if (!procSpell) - return false; - - if (procSpell->SpellFamilyFlags[0] & 0x800000) - if ((procSpell->Id != 58381) || !roll_chance_i(50)) - return false; - - target = victim; - break; - } - // Professor Putricide - Ooze Spell Tank Protection - case 71770: - if (victim) - victim->CastSpell(victim, trigger_spell_id, true); // EffectImplicitTarget is self - return true; - case 45057: // Evasive Maneuvers (Commendation of Kael`thas trinket) - case 71634: // Item - Icecrown 25 Normal Tank Trinket 1 - case 71640: // Item - Icecrown 25 Heroic Tank Trinket 1 - case 75475: // Item - Chamber of Aspects 25 Normal Tank Trinket - case 75481: // Item - Chamber of Aspects 25 Heroic Tank Trinket - { - // Procs only if damage takes health below $s1% - if (!HealthBelowPctDamaged(triggerAmount, damage)) - return false; - break; - } - default: - break; - } - - if (auraSpellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT) - { - // Xinef: keep this order, Aura 70656 has SpellIconID 85! - // Item - Death Knight T10 Melee 4P Bonus - if (auraSpellInfo->Id == 70656) - { - if (!IsPlayer() || !IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_ABILITY)) - return false; - - for (uint8 i = 0; i < MAX_RUNES; ++i) - if (ToPlayer()->GetRuneCooldown(i) == 0) - return false; - } - // Blade Barrier - else if (auraSpellInfo->SpellIconID == 85) - { - Player* plr = ToPlayer(); - if (!plr || !plr->IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_ABILITY) || !procSpell) - return false; - - if (!plr->IsBaseRuneSlotsOnCooldown(RUNE_BLOOD)) - return false; - } - // Rime - else if (auraSpellInfo->SpellIconID == 56) - { - if (!IsPlayer()) - return false; - - // Howling Blast - ToPlayer()->RemoveCategoryCooldown(1248); - } - } - - // Custom basepoints/target for exist spell - // dummy basepoints or other customs - switch (trigger_spell_id) - { - // Auras which should proc on area aura source (caster in this case): - // Turn the Tables - case 52914: - case 52915: - case 52910: - // Honor Among Thieves - case 51699: - { - target = triggeredByAura->GetBase()->GetCaster(); - if (!target) - return false; - - if (Player* pTarget = target->ToPlayer()) - { - if (cooldown) - { - if (pTarget->HasSpellCooldown(trigger_spell_id)) - return false; - pTarget->AddSpellCooldown(trigger_spell_id, 0, cooldown); - } - - Unit* cptarget = nullptr; - if (trigger_spell_id == 51699) - { - cptarget = pTarget->GetComboTarget(); - if (!cptarget) - { - cptarget = pTarget->GetSelectedUnit(); - } - } - else - cptarget = target; - - if (cptarget) - { - target->CastSpell(cptarget, trigger_spell_id, true); - return true; - } - } - return false; - } - // Cast positive spell on enemy target - case 20233: // Improved Lay on Hands (cast on target) - { - target = victim; - break; - } - // Ruby Drake, Evasive Aura - case 50241: - { - if (GetAura(50240)) - return false; - - break; - } - // Combo points add triggers (need add combopoint only for main target, and after possible combopoints reset) - case 15250: // Rogue Setup - { - // applied only for main target - if (!victim || (IsPlayer() && victim != ToPlayer()->GetSelectedUnit())) - return false; - break; // continue normal case - } - // Finish movies that add combo - case 14189: // Seal Fate (Netherblade set) - case 14157: // Ruthlessness - { - victim = nullptr; - // Need add combopoint AFTER finish movie (or they dropped in finish phase) - break; - } - // Item - Druid T10 Balance 2P Bonus - case 16870: - { - if (HasAura(70718)) - CastSpell(this, 70721, true); - RemoveAurasDueToSpell(trigger_spell_id); - break; - } - // Shamanistic Rage triggered spell - case 30824: - { - basepoints0 = int32(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), triggerAmount)); - break; - } - // Enlightenment (trigger only from mana cost spells) - case 35095: - { - if (!procSpell || procSpell->PowerType != POWER_MANA || (procSpell->ManaCost == 0 && procSpell->ManaCostPercentage == 0 && procSpell->ManaCostPerlevel == 0)) - return false; - break; - } - case 46916: // Slam! (Bloodsurge proc) - case 52437: // Sudden Death - { - // Item - Warrior T10 Melee 4P Bonus - if (AuraEffect const* aurEff = GetAuraEffect(70847, 0)) - { - if (!roll_chance_i(aurEff->GetAmount())) - { - // Xinef: dont allow normal proc to override set one - if (GetAura((trigger_spell_id == 46916) ? 71072 : 71069)) - return false; - // Xinef: just to be sure - RemoveAurasDueToSpell(70849); - break; - } - - // Xinef: fully remove all auras and reapply once more - RemoveAurasDueToSpell(70849); - RemoveAurasDueToSpell(71072); - RemoveAurasDueToSpell(71069); - - CastSpell(this, 70849, true, castItem, triggeredByAura); // Extra Charge! - if (trigger_spell_id == 46916) - CastSpell(this, 71072, true, castItem, triggeredByAura); // Slam GCD Reduced - else - CastSpell(this, 71069, true, castItem, triggeredByAura); // Execute GCD Reduced - } - break; - } - // Sword and Board - case 50227: - { - // Remove cooldown on Shield Slam - if (IsPlayer()) - ToPlayer()->RemoveCategoryCooldown(1209); - break; - } - // Maelstrom Weapon - case 53817: - { - // have rank dependent proc chance, ignore too often cases - // PPM = 2.5 * (rank of talent), - uint32 rank = auraSpellInfo->GetRank(); - // 5 rank -> 100% 4 rank -> 80% and etc from full rate - if (!roll_chance_i(20 * rank)) - return false; - - // Item - Shaman T10 Enhancement 4P Bonus - if (AuraEffect const* aurEff = GetAuraEffect(70832, 0)) - if (Aura const* maelstrom = GetAura(53817)) - // xinef: we have 4 charges and all proc conditions are met - aura reaches 5 charges - if ((maelstrom->GetStackAmount() == 4) && roll_chance_i(aurEff->GetAmount())) - CastSpell(this, 70831, true, castItem, triggeredByAura); - - break; - } - // Astral Shift - case 52179: - { - if (!procSpell || !(procEx & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) || this == victim) - return false; - - // Need stun, fear or silence mechanic - if (!(procSpell->GetAllEffectsMechanicMask() & ((1 << MECHANIC_SILENCE) | (1 << MECHANIC_STUN) | (1 << MECHANIC_FEAR)))) - return false; - break; - } - // Glyph of Death's Embrace - case 58679: - { - // Proc only from healing part of Death Coil. Check is essential as all Death Coil spells have 0x2000 mask in SpellFamilyFlags - if (!procSpell || !(procSpell->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && procSpell->SpellFamilyFlags[0] == 0x80002000)) - return false; - break; - } - // Glyph of Death Grip - case 58628: - { - // remove cooldown of Death Grip - if (IsPlayer()) - ToPlayer()->RemoveSpellCooldown(49576, true); - return true; - } - // Savage Defense - case 62606: - { - basepoints0 = CalculatePct(triggerAmount, GetTotalAttackPowerValue(BASE_ATTACK)); - break; - } - // Body and Soul - case 64128: - case 65081: - { - // Proc only from PW:S cast - if (!procSpell || !(procSpell->SpellFamilyFlags[0] & 0x00000001)) - return false; - break; - } - // Culling the Herd - case 70893: - { - if (!procSpell) - { - return false; - } - // check if we're doing a critical hit - if (!(procSpell->SpellFamilyFlags[1] & 0x10000000) && (procEx != PROC_EX_CRITICAL_HIT)) - return false; - // check if we're procced by Claw, Bite or Smack (need to use the spell icon ID to detect it) - if (!(procSpell->SpellIconID == 262 || procSpell->SpellIconID == 1680 || procSpell->SpellIconID == 473)) - return false; - break; - } - // Fingers of Frost, synchronise with Frostbite - case 44544: - { - if (procPhase == PROC_SPELL_PHASE_HIT) - { - // Find Frostbite - if (AuraEffect* aurEff = this->GetAuraEffect(SPELL_AURA_ADD_TARGET_TRIGGER, SPELLFAMILY_MAGE, 119, EFFECT_0)) - { - if (!victim) - return false; - - uint8 fofRank = sSpellMgr->GetSpellRank(triggeredByAura->GetId()); - uint8 fbRank = sSpellMgr->GetSpellRank(aurEff->GetId()); - uint8 chance = uint8(std::ceil(fofRank * fbRank * 16.6f)); - - if (roll_chance_i(chance)) - CastSpell(victim, aurEff->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true); - } - } - break; - } - } - - // try detect target manually if not set - if (!target) - target = !(procFlags & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)) && triggerEntry->IsPositive() ? this : victim; - - if (cooldown) - { - if (HasSpellCooldown(triggerEntry->Id)) - return false; - - AddSpellCooldown(triggerEntry->Id, 0, cooldown); - } - - if (basepoints0) - CastCustomSpell(target, triggerEntry->Id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura); - else - CastSpell(target, triggerEntry->Id, true, castItem, triggeredByAura); - - return true; -} - -bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown) -{ - int32 scriptId = triggeredByAura->GetMiscValue(); - - if (!victim || !victim->IsAlive()) - return false; - - Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && IsPlayer() - ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr; - - uint32 triggered_spell_id = 0; - - switch (scriptId) - { - case 836: // Improved Blizzard (Rank 1) - { - if (!procSpell || procSpell->SpellVisual[0] != 9487) - return false; - triggered_spell_id = 12484; - break; - } - case 988: // Improved Blizzard (Rank 2) - { - if (!procSpell || procSpell->SpellVisual[0] != 9487) - return false; - triggered_spell_id = 12485; - break; - } - case 989: // Improved Blizzard (Rank 3) - { - if (!procSpell || procSpell->SpellVisual[0] != 9487) - return false; - triggered_spell_id = 12486; - break; - } - case 4533: // Dreamwalker Raiment 2 pieces bonus - { - // Chance 50% - if (!roll_chance_i(50)) - return false; - - switch (victim->getPowerType()) - { - case POWER_MANA: - triggered_spell_id = 28722; - break; - case POWER_RAGE: - triggered_spell_id = 28723; - break; - case POWER_ENERGY: - triggered_spell_id = 28724; - break; - default: - return false; - } - break; - } - case 4537: // Dreamwalker Raiment 6 pieces bonus - triggered_spell_id = 28750; // Blessing of the Claw - break; - case 5497: // Improved Mana Gems - triggered_spell_id = 37445; // Mana Surge - break; - case 7010: // Revitalize - can proc on full hp target - case 7011: - case 7012: - { - if (!roll_chance_i(triggeredByAura->GetAmount())) - return false; - switch (victim->getPowerType()) - { - case POWER_MANA: - triggered_spell_id = 48542; - break; - case POWER_RAGE: - triggered_spell_id = 48541; - break; - case POWER_ENERGY: - triggered_spell_id = 48540; - break; - case POWER_RUNIC_POWER: - triggered_spell_id = 48543; - break; - default: - break; - } - break; - } - default: - break; - } - - // not processed - if (!triggered_spell_id) - return false; - - // standard non-dummy case - SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id); - - if (!triggerEntry) - { - LOG_ERROR("entities.unit", "Unit::HandleOverrideClassScriptAuraProc: Spell {} triggering for class script id {}", triggered_spell_id, scriptId); - return false; - } - - if (cooldown) - { - if (HasSpellCooldown(triggered_spell_id)) - return false; - - AddSpellCooldown(triggered_spell_id, 0, cooldown); - } - - CastSpell(victim, triggered_spell_id, true, castItem, triggeredByAura); - - return true; -} - void Unit::setPowerType(Powers new_powertype) { SetByteValue(UNIT_FIELD_BYTES_0, 3, new_powertype); @@ -11896,15 +8675,6 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin { case SPELLFAMILY_DRUID: { - // Insect Swarm vs Item - Druid T8 Balance Relic - if (spellProto->SpellFamilyFlags[0] & 0x00200000) - { - if (AuraEffect const* relicAurEff = GetAuraEffect(64950, EFFECT_0)) - { - DoneAdvertisedBenefit += relicAurEff->GetAmount(); - } - } - // Nourish vs Idol of the Flourishing Life if (spellProto->SpellFamilyFlags[1] & 0x02000000) { @@ -12782,26 +9552,22 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u // Taken fixed damage bonus auras int32 TakenAdvertisedBenefit = GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_HEALING, spellProto->GetSchoolMask()); - // Nourish cast, glyph of nourish + // Nourish cast - 20% bonus if target has Rejuvenation, Regrowth, Lifebloom, or Wild Growth from caster + // Glyph of Nourish is handled by spell_dru_nourish script if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags[1] & 0x2000000 && caster) { - bool any = false; - bool hasglyph = caster->GetAuraEffectDummy(62971); AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL); for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i) { - if (((*i)->GetCasterGUID() == caster->GetGUID())) + if ((*i)->GetCasterGUID() == caster->GetGUID()) { SpellInfo const* spell = (*i)->GetSpellInfo(); // Rejuvenation, Regrowth, Lifebloom, or Wild Growth - if (!any && spell->SpellFamilyFlags.HasFlag(0x50, 0x4000010, 0)) + if (spell->SpellFamilyFlags.HasFlag(0x50, 0x4000010, 0)) { TakenTotalMod *= 1.2f; - any = true; + break; } - - if (hasglyph) - TakenTotalMod += 0.06f; } } } @@ -16061,92 +12827,6 @@ bool Unit::isFrozen() const return HasAuraState(AURA_STATE_FROZEN); } -struct ProcTriggeredData -{ - ProcTriggeredData(Aura* _aura) : aura(_aura) - { - effMask = 0; - spellProcEvent = nullptr; - triggerSpelId.fill(0); - } - - SpellProcEventEntry const* spellProcEvent; - Aura* aura; - uint32 effMask; - std::array triggerSpelId; - - bool operator==(const uint32 spellId) const - { - return aura->GetId() == spellId; - } -}; - -typedef std::list< ProcTriggeredData > ProcTriggeredList; - -// List of auras that CAN be trigger but may not exist in spell_proc_event -// in most case need for drop charges -// in some types of aura need do additional check -// for example SPELL_AURA_MECHANIC_IMMUNITY - need check for mechanic -bool InitTriggerAuraData() -{ - for (uint16 i = 0; i < TOTAL_AURAS; ++i) - { - isTriggerAura[i] = false; - isNonTriggerAura[i] = false; - isAlwaysTriggeredAura[i] = false; - } - isTriggerAura[SPELL_AURA_DUMMY] = true; - isTriggerAura[SPELL_AURA_MOD_CONFUSE] = true; - isTriggerAura[SPELL_AURA_MOD_THREAT] = true; - isTriggerAura[SPELL_AURA_MOD_STUN] = true; // Aura does not have charges but needs to be removed on trigger - isTriggerAura[SPELL_AURA_MOD_DAMAGE_DONE] = true; - isTriggerAura[SPELL_AURA_MOD_DAMAGE_TAKEN] = true; - isTriggerAura[SPELL_AURA_MOD_RESISTANCE] = true; - isTriggerAura[SPELL_AURA_MOD_STEALTH] = true; - isTriggerAura[SPELL_AURA_MOD_FEAR] = true; // Aura does not have charges but needs to be removed on trigger - isTriggerAura[SPELL_AURA_MOD_ROOT] = true; - isTriggerAura[SPELL_AURA_TRANSFORM] = true; - isTriggerAura[SPELL_AURA_REFLECT_SPELLS] = true; - isTriggerAura[SPELL_AURA_DAMAGE_IMMUNITY] = true; - isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL] = true; - isTriggerAura[SPELL_AURA_PROC_TRIGGER_DAMAGE] = true; - isTriggerAura[SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK] = true; - isTriggerAura[SPELL_AURA_SCHOOL_ABSORB] = true; // Savage Defense untested - isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT] = true; - isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL] = true; - isTriggerAura[SPELL_AURA_REFLECT_SPELLS_SCHOOL] = true; - isTriggerAura[SPELL_AURA_MECHANIC_IMMUNITY] = true; - isTriggerAura[SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN] = true; - isTriggerAura[SPELL_AURA_SPELL_MAGNET] = true; - isTriggerAura[SPELL_AURA_MOD_ATTACK_POWER] = true; - isTriggerAura[SPELL_AURA_ADD_CASTER_HIT_TRIGGER] = true; - isTriggerAura[SPELL_AURA_OVERRIDE_CLASS_SCRIPTS] = true; - isTriggerAura[SPELL_AURA_MOD_MECHANIC_RESISTANCE] = true; - isTriggerAura[SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS] = true; - isTriggerAura[SPELL_AURA_MOD_MELEE_HASTE] = true; - isTriggerAura[SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE] = true; - isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE] = true; - isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE] = true; - isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE] = true; - isTriggerAura[SPELL_AURA_MOD_DAMAGE_FROM_CASTER] = true; - isTriggerAura[SPELL_AURA_MOD_SPELL_CRIT_CHANCE] = true; - isTriggerAura[SPELL_AURA_ABILITY_IGNORE_AURASTATE] = true; - - isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN] = true; - isNonTriggerAura[SPELL_AURA_REDUCE_PUSHBACK] = true; - - isAlwaysTriggeredAura[SPELL_AURA_OVERRIDE_CLASS_SCRIPTS] = true; - isAlwaysTriggeredAura[SPELL_AURA_MOD_FEAR] = true; - isAlwaysTriggeredAura[SPELL_AURA_MOD_ROOT] = true; - isAlwaysTriggeredAura[SPELL_AURA_MOD_STUN] = true; - isAlwaysTriggeredAura[SPELL_AURA_TRANSFORM] = true; - isAlwaysTriggeredAura[SPELL_AURA_SPELL_MAGNET] = true; - isAlwaysTriggeredAura[SPELL_AURA_SCHOOL_ABSORB] = true; - isAlwaysTriggeredAura[SPELL_AURA_MOD_STEALTH] = true; - - return true; -} - void createProcFlags(SpellInfo const* spellInfo, WeaponAttackType attackType, bool positive, uint32& procAttacker, uint32& procVictim) { if (spellInfo) @@ -16221,67 +12901,7 @@ void createProcFlags(SpellInfo const* spellInfo, WeaponAttackType attackType, bo } } -uint32 createProcExtendMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition) -{ - uint32 procEx = PROC_EX_NONE; - // Check victim state - if (missCondition != SPELL_MISS_NONE) - switch (missCondition) - { - case SPELL_MISS_MISS: - procEx |= PROC_EX_MISS; - break; - case SPELL_MISS_RESIST: - procEx |= PROC_EX_RESIST; - break; - case SPELL_MISS_DODGE: - procEx |= PROC_EX_DODGE; - break; - case SPELL_MISS_PARRY: - procEx |= PROC_EX_PARRY; - break; - case SPELL_MISS_BLOCK: - procEx |= PROC_EX_BLOCK; - break; - case SPELL_MISS_EVADE: - procEx |= PROC_EX_EVADE; - break; - case SPELL_MISS_IMMUNE: - procEx |= PROC_EX_IMMUNE; - break; - case SPELL_MISS_IMMUNE2: - procEx |= PROC_EX_IMMUNE; - break; - case SPELL_MISS_DEFLECT: - procEx |= PROC_EX_DEFLECT; - break; - case SPELL_MISS_ABSORB: - procEx |= PROC_EX_ABSORB; - break; - case SPELL_MISS_REFLECT: - procEx |= PROC_EX_REFLECT; - break; - default: - break; - } - else - { - // On block - if (damageInfo->blocked) - procEx |= PROC_EX_BLOCK; - // On absorb - if (damageInfo->absorb) - procEx |= PROC_EX_ABSORB; - // On crit - if (damageInfo->HitInfo & SPELL_HIT_TYPE_CRIT) - procEx |= PROC_EX_CRITICAL_HIT; - else - procEx |= PROC_EX_NORMAL_HIT; - } - return procEx; -} - -void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpellInfo, uint32 damage, SpellInfo const* procAura, int8 procAuraEffectIndex, Spell const* procSpell, DamageInfo* damageInfo, HealInfo* healInfo, uint32 procPhase) +void Unit::ProcSkillsAndReactives(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* /*procSpellInfo*/, uint32 /*damage*/, SpellInfo const* /*procAura*/, int8 /*procAuraEffectIndex*/, Spell const* procSpell, DamageInfo* /*damageInfo*/, HealInfo* /*healInfo*/, uint32 procPhase) { // Player is loaded now - do not allow passive spell casts to proc if (IsPlayer() && ToPlayer()->GetSession()->PlayerLoading()) @@ -16367,377 +12987,28 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u } } } - - Unit* actor = isVictim ? target : this; - Unit* actionTarget = !isVictim ? target : this; - - ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, procPhase, procExtra, procSpell, damageInfo, healInfo, procAura, procAuraEffectIndex); - - ProcTriggeredList procTriggered; - // Fill procTriggered list - for (AuraApplicationMap::const_iterator itr = GetAppliedAuras().begin(); itr != GetAppliedAuras().end(); ++itr) - { - // Do not allow auras to proc from effect triggered by itself - if (procAura && procAura->Id == itr->first) - continue; - - // Xinef: Generic Item Equipment cooldown, -1 is a special marker - if (itr->second->GetBase()->GetCastItemGUID() && HasSpellItemCooldown(itr->first, uint32(-1))) - continue; - - ProcTriggeredData triggerData(itr->second->GetBase()); - // Defensive procs are active on absorbs (so absorption effects are not a hindrance) - bool active = damage || (procExtra & PROC_EX_BLOCK && isVictim); - if (isVictim) - procExtra &= ~PROC_EX_INTERNAL_REQ_FAMILY; - - SpellInfo const* spellProto = itr->second->GetBase()->GetSpellInfo(); - - // only auras that have trigger spell should proc from fully absorbed damage - if (procExtra & PROC_EX_ABSORB && isVictim) - if (damage || spellProto->Effects[EFFECT_0].TriggerSpell || spellProto->Effects[EFFECT_1].TriggerSpell || spellProto->Effects[EFFECT_2].TriggerSpell) - active = true; - - // xinef: fix spell procing from damaging / healing casts if spell has DoT / HoT effect only - // only player spells are taken into account - if (!active && !isVictim && !(procFlag & PROC_FLAG_DONE_PERIODIC) && procSpellInfo && procSpellInfo->SpellFamilyName && (procSpellInfo->HasAura(SPELL_AURA_PERIODIC_DAMAGE) || procSpellInfo->HasAura(SPELL_AURA_PERIODIC_HEAL))) - active = true; - - // AuraScript Hook - if (!triggerData.aura->CallScriptCheckProcHandlers(itr->second, eventInfo)) - { - continue; - } - - bool isTriggeredAtSpellProcEvent = IsTriggeredAtSpellProcEvent(target, triggerData.aura, attType, isVictim, active, triggerData.spellProcEvent, eventInfo); - - // AuraScript Hook - if (!triggerData.aura->CallScriptAfterCheckProcHandlers(itr->second, eventInfo, isTriggeredAtSpellProcEvent)) - { - continue; - } - - // do checks using conditions table - ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, spellProto->Id); - ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget()); - if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions)) - { - continue; - } - - bool hasTriggeredProc = false; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (itr->second->HasEffect(i)) - { - AuraEffect* aurEff = itr->second->GetBase()->GetEffect(i); - - // Skip this auras - if (isNonTriggerAura[aurEff->GetAuraType()]) - continue; - - // If not trigger by default and spellProcEvent == nullptr - skip - if (!isTriggerAura[aurEff->GetAuraType()] && !triggerData.spellProcEvent) - continue; - - switch (aurEff->GetAuraType()) - { - case SPELL_AURA_PROC_TRIGGER_SPELL: - case SPELL_AURA_MANA_SHIELD: - case SPELL_AURA_DUMMY: - case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE: - if (uint32 triggerSpellId = aurEff->GetSpellInfo()->Effects[i].TriggerSpell) - { - triggerData.triggerSpelId[i] = triggerSpellId; - hasTriggeredProc = true; - } - break; - default: - break; - } - - // Some spells must always trigger - //if (isAlwaysTriggeredAura[aurEff->GetAuraType()]) - triggerData.effMask |= 1 << i; - } - } - - if (triggerData.effMask) - { - // If there is aura that triggers another proc aura, make sure that the triggered one is going to be proccessed on top of it - if (hasTriggeredProc) - { - bool proccessed = false; - for (uint8 i = 0; i < EFFECT_ALL; ++i) - { - if (uint32 triggeredSpellId = triggerData.triggerSpelId[i]) - { - auto iter = std::find(procTriggered.begin(), procTriggered.end(), triggeredSpellId); - if (iter != procTriggered.end()) - { - std::advance(iter, 1); - procTriggered.insert(iter, triggerData); - proccessed = true; - break; - } - } - } - - if (!proccessed) - { - procTriggered.push_front(triggerData); - } - } - else - { - procTriggered.push_front(triggerData); - } - } - } - - // Nothing found - if (procTriggered.empty()) - return; - - // Note: must SetCantProc(false) before return - if (procExtra & (PROC_EX_INTERNAL_TRIGGERED | PROC_EX_INTERNAL_CANT_PROC)) - SetCantProc(true); - - // Handle effects proceed this time - for (ProcTriggeredList::const_iterator i = procTriggered.begin(); i != procTriggered.end(); ++i) - { - // look for aura in auras list, it may be removed while proc event processing - if (i->aura->IsRemoved()) - continue; - - bool useCharges = i->aura->IsUsingCharges(); - // no more charges to use, prevent proc - if (useCharges && !i->aura->GetCharges()) - continue; - - bool takeCharges = false; - SpellInfo const* spellInfo = i->aura->GetSpellInfo(); - - AuraApplication* aurApp = i->aura->GetApplicationOfTarget(GetGUID()); - - bool prepare = i->aura->CallScriptPrepareProcHandlers(aurApp, eventInfo); - - // For players set spell cooldown if need - uint32 cooldown = 0; - if (prepare && i->spellProcEvent && i->spellProcEvent->cooldown) - cooldown = i->spellProcEvent->cooldown; - - // Xinef: set cooldown for actual proc - eventInfo.SetProcCooldown(cooldown); - - // Note: must SetCantProc(false) before return - if (spellInfo->HasAttribute(SPELL_ATTR3_INSTANT_TARGET_PROCS)) - SetCantProc(true); - - bool handled = i->aura->CallScriptProcHandlers(aurApp, eventInfo); - - // "handled" is needed as long as proc can be handled in multiple places - if (!handled && HandleAuraProc(target, damage, i->aura, procSpellInfo, procFlag, procExtra, cooldown, &handled)) - { - uint32 Id = i->aura->GetId(); - LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell {} (triggered with value by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), Id); - takeCharges = true; - } - - if (!handled) - for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) - { - if (!(i->effMask & (1 << effIndex))) - continue; - - AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex); - ASSERT(triggeredByAura); - - bool prevented = i->aura->CallScriptEffectProcHandlers(triggeredByAura, aurApp, eventInfo); - if (prevented) - { - takeCharges = true; - continue; - } - - switch (triggeredByAura->GetAuraType()) - { - case SPELL_AURA_PROC_TRIGGER_SPELL: - { - LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell {} (triggered by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); - // Don`t drop charge or add cooldown for not started trigger - if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procPhase, eventInfo)) - takeCharges = true; - break; - } - case SPELL_AURA_PROC_TRIGGER_DAMAGE: - { - // target has to be valid - if (!eventInfo.GetProcTarget()) - break; - - triggeredByAura->HandleProcTriggerDamageAuraProc(aurApp, eventInfo); // this function is part of the new proc system - takeCharges = true; - break; - } - case SPELL_AURA_MANA_SHIELD: - case SPELL_AURA_DUMMY: - { - LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} dummy aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); - if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, eventInfo)) - takeCharges = true; - break; - } - case SPELL_AURA_OBS_MOD_POWER: - case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: - case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: - case SPELL_AURA_MOD_MELEE_HASTE: - LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} aura of spell {})", spellInfo->Id, isVictim ? "a victim's" : "an attacker's", triggeredByAura->GetId()); - takeCharges = true; - break; - case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: - { - LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); - if (HandleOverrideClassScriptAuraProc(target, damage, triggeredByAura, procSpellInfo, cooldown)) - takeCharges = true; - break; - } - case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE: - { - LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting mending (triggered by {} dummy aura of spell {})", - (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); - if (damage > 0) - { - HandleAuraRaidProcFromChargeWithValue(triggeredByAura); - takeCharges = true; - } - break; - } - case SPELL_AURA_RAID_PROC_FROM_CHARGE: - { - LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting mending (triggered by {} dummy aura of spell {})", - (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); - HandleAuraRaidProcFromCharge(triggeredByAura); - takeCharges = true; - break; - } - case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE: - { - LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell {} (triggered with value by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); - - if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procPhase, eventInfo)) - takeCharges = true; - break; - } - case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK: - // Skip melee hits or instant cast spells - // xinef: check channeled spells which are affected by haste also - if (procSpellInfo && (procSpellInfo->SpellFamilyName || !IsPlayer()) && - (procSpellInfo->CalcCastTime() > 0 /*|| - (procSpell->IsChanneled() && procSpell->GetDuration() > 0 && (HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, procSpell) || procSpell->HasAttribute(SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC)))*/)) - takeCharges = true; - break; - case SPELL_AURA_REFLECT_SPELLS_SCHOOL: - // Skip Melee hits and spells ws wrong school - if (procSpellInfo && (triggeredByAura->GetMiscValue() & procSpellInfo->SchoolMask)) // School check - takeCharges = true; - break; - case SPELL_AURA_SPELL_MAGNET: - // Skip Melee hits and targets with magnet aura - if (procSpellInfo && (triggeredByAura->GetBase()->GetUnitOwner()->ToUnit() == ToUnit())) // Magnet - takeCharges = true; - break; - case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT: - case SPELL_AURA_MOD_POWER_COST_SCHOOL: - // Skip melee hits and spells ws wrong school or zero cost - if (procSpellInfo && - (procSpellInfo->ManaCost != 0 || procSpellInfo->ManaCostPercentage != 0 || (procSpellInfo->SpellFamilyFlags[1] & 0x2)) && // Cost check, mutilate include - (triggeredByAura->GetMiscValue() & procSpellInfo->SchoolMask)) // School check - takeCharges = true; - break; - case SPELL_AURA_MECHANIC_IMMUNITY: - case SPELL_AURA_MOD_MECHANIC_RESISTANCE: - // Compare mechanic - if (procSpellInfo && procSpellInfo->Mechanic == uint32(triggeredByAura->GetMiscValue())) - takeCharges = true; - break; - case SPELL_AURA_MOD_DAMAGE_FROM_CASTER: - // Compare casters - if (target && triggeredByAura->GetCasterGUID() == target->GetGUID()) - takeCharges = true; - break; - // CC Auras which use their amount amount to drop - // Are there any more auras which need this? - case SPELL_AURA_MOD_CONFUSE: - case SPELL_AURA_MOD_FEAR: - case SPELL_AURA_MOD_STUN: - case SPELL_AURA_MOD_ROOT: - case SPELL_AURA_TRANSFORM: - { - // Spell own direct damage at apply wont break the CC - // Xinef: Or when the aura is at full duration (assume that such auras should be added at the end, skipping all damage procs etc.) - if (procSpellInfo) - if ((!i->aura->IsPermanent() && i->aura->GetDuration() == i->aura->GetMaxDuration()) || procSpellInfo->Id == triggeredByAura->GetId() || - procSpellInfo->HasAttribute(SPELL_ATTR4_REACTIVE_DAMAGE_PROC)) - break; - - // chargeable mods are breaking on hit - if (useCharges) - takeCharges = true; - else if (triggeredByAura->GetAmount()) // aura must have amount - { - int32 damageLeft = triggeredByAura->GetAmount(); - // No damage left - if (damageLeft < int32(damage)) - i->aura->Remove(); - else - triggeredByAura->SetAmount(damageLeft - damage); - } - break; - } - case SPELL_AURA_ABILITY_IGNORE_AURASTATE: - if (procSpellInfo && procSpellInfo->Id == 20647) // hack for warriors execute, both dummy and damage spell are affected by ignore aurastate aura - break; - takeCharges = true; - break; - case SPELL_AURA_ADD_FLAT_MODIFIER: - case SPELL_AURA_ADD_PCT_MODIFIER: - { - if (triggeredByAura->GetSpellModifier()) - { - // Do proc if mod is consumed by spell - if (!procSpell || procSpell->m_appliedMods.find(i->aura) != procSpell->m_appliedMods.end()) - { - takeCharges = true; - } - } - break; - } - default: - takeCharges = true; - break; - } - i->aura->CallScriptAfterEffectProcHandlers(triggeredByAura, aurApp, eventInfo); - } - // Remove charge (aura can be removed by triggers) - // xinef: take into account attribute6 of proc spell - if (prepare && useCharges && takeCharges) - if (!procSpellInfo || isVictim || !procSpellInfo->HasAttribute(SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES)) - i->aura->DropCharge(); - - i->aura->CallScriptAfterProcHandlers(aurApp, eventInfo); - - if (spellInfo->HasAttribute(SPELL_ATTR3_INSTANT_TARGET_PROCS)) - SetCantProc(false); - } - - // Cleanup proc requirements - if (procExtra & (PROC_EX_INTERNAL_TRIGGERED | PROC_EX_INTERNAL_CANT_PROC)) - SetCantProc(false); + // Aura procs are now handled by TriggerAurasProcOnEvent called from ProcSkillsAndAuras } -void Unit::GetProcAurasTriggeredOnEvent(std::list& aurasTriggeringProc, std::list* procAuras, ProcEventInfo eventInfo) +void Unit::GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTriggeringProc, std::list* procAuras, ProcEventInfo eventInfo) { + TimePoint now = std::chrono::steady_clock::now(); + + auto processAuraApplication = [&](AuraApplication* aurApp) + { + if (uint8 procEffectMask = aurApp->GetBase()->GetProcEffectMask(aurApp, eventInfo, now)) + { + aurApp->GetBase()->PrepareProcToTrigger(aurApp, eventInfo, now); + aurasTriggeringProc.emplace_back(procEffectMask, aurApp); + } + else + { + if (aurApp->GetBase()->GetSpellInfo()->HasAttribute(SPELL_ATTR2_PROC_COOLDOWN_ON_FAILURE)) + if (SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(aurApp->GetBase()->GetId())) + aurApp->GetBase()->AddProcCooldown(procEntry, now); + } + }; + // use provided list of auras which can proc if (procAuras) { @@ -16745,58 +13016,48 @@ void Unit::GetProcAurasTriggeredOnEvent(std::list& aurasTrigge { ASSERT((*itr)->GetTarget() == this); if (!(*itr)->GetRemoveMode()) - if ((*itr)->GetBase()->IsProcTriggeredOnEvent(*itr, eventInfo)) - { - (*itr)->GetBase()->PrepareProcToTrigger(*itr, eventInfo); - aurasTriggeringProc.push_back(*itr); - } + processAuraApplication(*itr); } } // or generate one on our own else { for (AuraApplicationMap::iterator itr = GetAppliedAuras().begin(); itr != GetAppliedAuras().end(); ++itr) - { - if (itr->second->GetBase()->IsProcTriggeredOnEvent(itr->second, eventInfo)) - { - itr->second->GetBase()->PrepareProcToTrigger(itr->second, eventInfo); - aurasTriggeringProc.push_back(itr->second); - } - } + processAuraApplication(itr->second); } } void Unit::TriggerAurasProcOnEvent(CalcDamageInfo& damageInfo) { DamageInfo dmgInfo = DamageInfo(damageInfo); - TriggerAurasProcOnEvent(nullptr, nullptr, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, 0, 0, damageInfo.procEx, nullptr, &dmgInfo, nullptr); + TriggerAurasProcOnEvent(nullptr, nullptr, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, 0, 0, dmgInfo.GetHitMask(), nullptr, &dmgInfo, nullptr); } void Unit::TriggerAurasProcOnEvent(std::list* myProcAuras, std::list* targetProcAuras, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo) { // prepare data for self trigger ProcEventInfo myProcEventInfo = ProcEventInfo(this, actionTarget, actionTarget, typeMaskActor, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo); - std::list myAurasTriggeringProc; + AuraApplicationProcContainer myAurasTriggeringProc; GetProcAurasTriggeredOnEvent(myAurasTriggeringProc, myProcAuras, myProcEventInfo); // prepare data for target trigger ProcEventInfo targetProcEventInfo = ProcEventInfo(this, actionTarget, this, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo); - std::list targetAurasTriggeringProc; - if (typeMaskActionTarget) - GetProcAurasTriggeredOnEvent(targetAurasTriggeringProc, targetProcAuras, targetProcEventInfo); + AuraApplicationProcContainer targetAurasTriggeringProc; + if (typeMaskActionTarget && actionTarget) + actionTarget->GetProcAurasTriggeredOnEvent(targetAurasTriggeringProc, targetProcAuras, targetProcEventInfo); TriggerAurasProcOnEvent(myProcEventInfo, myAurasTriggeringProc); - if (typeMaskActionTarget) - TriggerAurasProcOnEvent(targetProcEventInfo, targetAurasTriggeringProc); + if (typeMaskActionTarget && actionTarget) + actionTarget->TriggerAurasProcOnEvent(targetProcEventInfo, targetAurasTriggeringProc); } -void Unit::TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, std::list& aurasTriggeringProc) +void Unit::TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProcContainer& aurasTriggeringProc) { - for (std::list::iterator itr = aurasTriggeringProc.begin(); itr != aurasTriggeringProc.end(); ++itr) + for (auto const& [procEffectMask, aurApp] : aurasTriggeringProc) { - if (!(*itr)->GetRemoveMode()) - (*itr)->GetBase()->TriggerProcOnEvent(*itr, eventInfo); + if (!aurApp->GetRemoveMode()) + aurApp->GetBase()->TriggerProcOnEvent(procEffectMask, aurApp, eventInfo); } } @@ -17673,159 +13934,6 @@ bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id) return true; } -bool Unit::IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo) -{ - SpellInfo const* spellProto = aura->GetSpellInfo(); - SpellInfo const* procSpell = eventInfo.GetSpellInfo(); - - // let the aura be handled by new proc system if it has new entry - if (sSpellMgr->GetSpellProcEntry(spellProto->Id)) - return false; - - // Get proc Event Entry - spellProcEvent = sSpellMgr->GetSpellProcEvent(spellProto->Id); - - // Get EventProcFlag - uint32 EventProcFlag; - if (spellProcEvent && spellProcEvent->procFlags) // if exist get custom spellProcEvent->procFlags - EventProcFlag = spellProcEvent->procFlags; - else - EventProcFlag = spellProto->ProcFlags; // else get from spell proto - // Continue if no trigger exist - if (!EventProcFlag) - return false; - - // Additional checks for triggered spells (ignore trap casts) - if (eventInfo.GetHitMask() & PROC_EX_INTERNAL_TRIGGERED && !(EventProcFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) - { - if (!spellProto->HasAttribute(SPELL_ATTR3_CAN_PROC_FROM_PROCS)) - return false; - } - - // Xinef: additional check for player auras - only player spells can trigger player proc auras - // Xinef: skip victim auras - // Excluded player shoot spells - // Excluded player item spells - if (!isVictim && IsPlayer() && !(EventProcFlag & (PROC_FLAG_KILL | PROC_FLAG_DEATH))) - { - if (procSpell && procSpell->SpellFamilyName == SPELLFAMILY_GENERIC && procSpell->GetCategory() != 76 && - (!eventInfo.GetProcSpell() || !eventInfo.GetProcSpell()->m_CastItem) && - (!eventInfo.GetTriggerAuraSpell() || eventInfo.GetTriggerAuraSpell()->SpellFamilyName == SPELLFAMILY_GENERIC)) - { - return false; - } - } - - // Check spellProcEvent data requirements - if (!sSpellMgr->IsSpellProcEventCanTriggeredBy(spellProto, spellProcEvent, EventProcFlag, eventInfo, active)) - return false; - // In most cases req get honor or XP from kill - if (EventProcFlag & PROC_FLAG_KILL && IsPlayer()) - { - bool allow = false; - - if (victim) - allow = ToPlayer()->isHonorOrXPTarget(victim); - - // Shadow Word: Death - can trigger from every kill - if (aura->GetId() == 32409 || aura->GetId() == 18372 || aura->GetId() == 18213) - allow = true; - if (!allow) - return false; - } - // Aura added by spell can`t trigger from self (prevent drop charges/do triggers) - // But except periodic and kill triggers (can triggered from self) - if (procSpell && procSpell->Id == spellProto->Id - && !(spellProto->ProcFlags & (PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_KILL))) - return false; - - // Check if current equipment allows aura to proc - if (!isVictim && IsPlayer() && !spellProto->HasAttribute(SPELL_ATTR3_NO_PROC_EQUIP_REQUIREMENT)) - { - Player* player = ToPlayer(); - if (spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) - { - Item* item = nullptr; - if (attType == BASE_ATTACK) - item = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); - else if (attType == OFF_ATTACK) - item = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); - else - item = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED); - - if (player->IsInFeralForm()) - return false; - - if (!item || item->IsBroken() || item->GetTemplate()->Class != ITEM_CLASS_WEAPON || !((1 << item->GetTemplate()->SubClass) & spellProto->EquippedItemSubClassMask)) - return false; - } - else if (spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) - { - // Check if player is wearing shield - Item* item = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); - if (!item || item->IsBroken() || item->GetTemplate()->Class != ITEM_CLASS_ARMOR || !((1 << item->GetTemplate()->SubClass) & spellProto->EquippedItemSubClassMask)) - return false; - } - } - // Get chance from spell - float chance = float(spellProto->ProcChance); - // If in spellProcEvent exist custom chance, chance = spellProcEvent->customChance; - if (spellProcEvent && spellProcEvent->customChance) - chance = spellProcEvent->customChance; - // If PPM exist calculate chance from PPM - if (spellProcEvent && spellProcEvent->ppmRate != 0) - { - uint32 attackSpeed = 0; - Unit* attacker = nullptr; - if (!isVictim) - attacker = this; - else if (victim) - attacker = victim; - - if (attacker) - { - if (!procSpell || procSpell->DmgClass == SPELL_DAMAGE_CLASS_MELEE || procSpell->IsRangedWeaponSpell()) - { - attackSpeed = attacker->GetAttackTime(attType); - } - else //spells user their casttime for ppm calculations - { - if (procSpell->CastTimeEntry) - attackSpeed = procSpell->CastTimeEntry->CastTime; - - //instants and fast spells use 1.5s castspeed - if (attackSpeed < 1500) - attackSpeed = 1500; - } - } - chance = GetPPMProcChance(attackSpeed, spellProcEvent->ppmRate, spellProto); - } - - // Custom chances - switch (spellProto->SpellFamilyName) - { - case SPELLFAMILY_WARRIOR: - { - // Recklessness, allow to proc only once for whirlwind - if (spellProto->Id == 1719 && procSpell && procSpell->Id == 44949) - return false; - } - } - - if (eventInfo.GetProcChance()) - { - chance = *eventInfo.GetProcChance(); - } - - // Apply chance modifer aura - if (Player* modOwner = GetSpellModOwner()) - { - modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CHANCE_OF_SUCCESS, chance); - } - - return roll_chance_f(chance); -} - bool Unit::HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura) { // aura can be deleted at casts @@ -18083,17 +14191,17 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp if (killer && (killer->IsPet() || killer->IsTotem())) if (Unit* owner = killer->GetOwner()) { - Unit::ProcDamageAndSpell(owner, victim, PROC_FLAG_KILL, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell); + Unit::ProcSkillsAndAuras(owner, victim, PROC_FLAG_KILL, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell); sScriptMgr->OnPlayerCreatureKilledByPet( killer->GetCharmerOrOwnerPlayerOrPlayerItself(), victim->ToCreature()); } if (killer != victim) { - Unit::ProcDamageAndSpell(killer, victim, killer ? PROC_FLAG_KILL : 0, PROC_FLAG_KILLED, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell); + Unit::ProcSkillsAndAuras(killer, victim, killer ? PROC_FLAG_KILL : 0, PROC_FLAG_KILLED, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell); } // Proc auras on death - must be before aura/combat remove - Unit::ProcDamageAndSpell(victim, nullptr, PROC_FLAG_DEATH, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell); + Unit::ProcSkillsAndAuras(victim, nullptr, PROC_FLAG_DEATH, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell); // update get killing blow achievements, must be done before setDeathState to be able to require auras on target // and before Spirit of Redemption as it also removes auras diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 1590c2721..96e99ab98 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -347,6 +347,7 @@ private: uint32 m_resist; uint32 m_block; uint32 m_cleanDamage; + uint32 m_hitMask; // amalgamation constructor (used for proc) DamageInfo(DamageInfo const& dmg1, DamageInfo const& dmg2); @@ -355,7 +356,8 @@ public: explicit DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType, uint32 cleanDamage = 0); explicit DamageInfo(CalcDamageInfo const& dmgInfo); // amalgamation wrapper DamageInfo(CalcDamageInfo const& dmgInfo, uint8 damageIndex); - DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType); + DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType, WeaponAttackType attackType, uint32 hitMask); + DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType, WeaponAttackType attackType, SpellMissInfo missInfo); void ModifyDamage(int32 amount); void AbsorbDamage(uint32 amount); @@ -373,6 +375,8 @@ public: [[nodiscard]] uint32 GetResist() const { return m_resist; }; [[nodiscard]] uint32 GetBlock() const { return m_block; }; + [[nodiscard]] uint32 GetHitMask() const; + void AddHitMask(uint32 hitMask) { m_hitMask |= hitMask; } [[nodiscard]] uint32 GetUnmitigatedDamage() const; }; @@ -386,9 +390,10 @@ private: uint32 m_absorb; SpellInfo const* const m_spellInfo; SpellSchoolMask const m_schoolMask; + uint32 m_hitMask; public: explicit HealInfo(Unit* _healer, Unit* _target, uint32 _heal, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask) - : m_healer(_healer), m_target(_target), m_heal(_heal), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask) + : m_healer(_healer), m_target(_target), m_heal(_heal), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask), m_hitMask(0) { m_absorb = 0; m_effectiveHeal = 0; @@ -421,6 +426,8 @@ public: [[nodiscard]] uint32 GetAbsorb() const { return m_absorb; } [[nodiscard]] SpellInfo const* GetSpellInfo() const { return m_spellInfo; }; [[nodiscard]] SpellSchoolMask GetSchoolMask() const { return m_schoolMask; }; + [[nodiscard]] uint32 GetHitMask() const { return m_hitMask; } + void AddHitMask(uint32 hitMask) { m_hitMask |= hitMask; } }; class ProcEventInfo @@ -451,7 +458,7 @@ public: [[nodiscard]] uint32 GetSpellPhaseMask() const { return _spellPhaseMask; } [[nodiscard]] uint32 GetHitMask() const { return _hitMask; } [[nodiscard]] SpellInfo const* GetSpellInfo() const; - [[nodiscard]] SpellSchoolMask GetSchoolMask() const { return SPELL_SCHOOL_MASK_NONE; } + [[nodiscard]] SpellSchoolMask GetSchoolMask() const; [[nodiscard]] Spell const* GetProcSpell() const { return _spell; } [[nodiscard]] DamageInfo* GetDamageInfo() const { return _damageInfo; } [[nodiscard]] HealInfo* GetHealInfo() const { return _healInfo; } @@ -486,7 +493,6 @@ struct CalcDamageInfo WeaponAttackType attackType; // uint32 procAttacker; uint32 procVictim; - uint32 procEx; uint32 cleanDamage; // Used only for rage calculation MeleeHitOutcome hitOutCome; /// @todo: remove this field (need use TargetState) }; @@ -530,7 +536,6 @@ struct SpellPeriodicAuraLogInfo }; void createProcFlags(SpellInfo const* spellInfo, WeaponAttackType attackType, bool positive, uint32& procAttacker, uint32& procVictim); -uint32 createProcExtendMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition); #define MAX_DECLINED_NAME_CASES 5 @@ -627,8 +632,6 @@ typedef std::unordered_map PacketCooldowns; #define ATTACK_DISPLAY_DELAY 200 #define MAX_PLAYER_STEALTH_DETECT_RANGE 30.0f // max distance for detection targets by player -struct SpellProcEventEntry; // used only privately - enum class SpeedOpcodeIndex : uint32 { PC, @@ -671,6 +674,7 @@ public: typedef std::vector AuraEffectList; typedef std::list AuraList; typedef std::list AuraApplicationList; + typedef std::vector> AuraApplicationProcContainer; typedef std::list Diminishing; typedef GuidUnorderedSet ComboPointHolderSet; @@ -1542,14 +1546,14 @@ public: bool CanProc() { return !m_procDeep; } void SetCantProc(bool apply); - static void ProcDamageAndSpell(Unit* actor, Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellInfo const* procSpellInfo = nullptr, SpellInfo const* procAura = nullptr, int8 procAuraEffectIndex = -1, Spell const* procSpell = nullptr, DamageInfo* damageInfo = nullptr, HealInfo* healInfo = nullptr, uint32 procPhase = 2 /*PROC_SPELL_PHASE_HIT*/); - void ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpellInfo, uint32 damage, SpellInfo const* procAura = nullptr, int8 procAuraEffectIndex = -1, Spell const* procSpell = nullptr, DamageInfo* damageInfo = nullptr, HealInfo* healInfo = nullptr, uint32 procPhase = 2 /*PROC_SPELL_PHASE_HIT*/); + static void ProcSkillsAndAuras(Unit* actor, Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellInfo const* procSpellInfo = nullptr, SpellInfo const* procAura = nullptr, int8 procAuraEffectIndex = -1, Spell const* procSpell = nullptr, DamageInfo* damageInfo = nullptr, HealInfo* healInfo = nullptr, uint32 procPhase = 2 /*PROC_SPELL_PHASE_HIT*/); + void ProcSkillsAndReactives(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpellInfo, uint32 damage, SpellInfo const* procAura = nullptr, int8 procAuraEffectIndex = -1, Spell const* procSpell = nullptr, DamageInfo* damageInfo = nullptr, HealInfo* healInfo = nullptr, uint32 procPhase = 2 /*PROC_SPELL_PHASE_HIT*/); - void GetProcAurasTriggeredOnEvent(std::list& aurasTriggeringProc, std::list* procAuras, ProcEventInfo eventInfo); + void GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTriggeringProc, std::list* procAuras, ProcEventInfo eventInfo); void TriggerAurasProcOnEvent(CalcDamageInfo& damageInfo); void TriggerAurasProcOnEvent(std::list* myProcAuras, std::list* targetProcAuras, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo); - void TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, std::list& procAuras); + void TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProcContainer& procAuras); [[nodiscard]] float GetWeaponProcChance() const; float GetPPMProcChance(uint32 WeaponSpeed, float PPM, SpellInfo const* spellProto) const; @@ -2188,11 +2192,7 @@ protected: bool _instantCast; private: - bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo); - bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, ProcEventInfo const& eventInfo); - bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool* handled); - bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo& eventInfo); - bool HandleOverrideClassScriptAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown); + // Legacy proc handlers removed - all procs now use AuraScripts and spell_proc table bool HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura); bool HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index eeff0d3d6..acc3e15d7 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1201,7 +1201,7 @@ void WorldSession::HandlePlayerLoginToCharInWorld(Player* pCurrChar) { int32 i = 0; flag96 _mask = 0; - SpellModList const& spellMods = pCurrChar->GetSpellModList(opType); + SpellModContainer const& spellMods = pCurrChar->GetSpellModList(opType); if (spellMods.empty()) continue; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index f0d54d7e0..7a3b2edf4 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -104,8 +104,8 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS] = &AuraEffect::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY &AuraEffect::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY &AuraEffect::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY - &AuraEffect::HandleNoImmediateEffect, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell - &AuraEffect::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor + &AuraEffect::HandleNoImmediateEffect, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Aura::TriggerProcOnEvent + &AuraEffect::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Aura::TriggerProcOnEvent &AuraEffect::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES &AuraEffect::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES &AuraEffect::HandleNULL, // 46 SPELL_AURA_46 (used in test spells 54054 and 54058, and spell 48050) (3.0.8a) @@ -700,8 +700,6 @@ void AuraEffect::CalculateSpellMod() m_spellmod->type = SpellModType(GetAuraType()); // SpellModType value == spell aura types m_spellmod->spellId = GetId(); m_spellmod->mask = GetSpellInfo()->Effects[GetEffIndex()].SpellClassMask; - m_spellmod->charges = GetBase()->GetCharges(); - m_spellmod->priority = GetSpellInfo()->SpellPriority; } m_spellmod->value = GetAmount(); break; @@ -1181,6 +1179,72 @@ void AuraEffect::PeriodicTick(AuraApplication* aurApp, Unit* caster) const } } +bool AuraEffect::CheckEffectProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) const +{ + bool result = GetBase()->CallScriptCheckEffectProcHandlers(this, aurApp, eventInfo); + if (!result) + return false; + + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + switch (GetAuraType()) + { + case SPELL_AURA_MOD_CONFUSE: + case SPELL_AURA_MOD_FEAR: + case SPELL_AURA_MOD_STUN: + case SPELL_AURA_MOD_ROOT: + case SPELL_AURA_TRANSFORM: + { + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return false; + + // Spell own damage at apply won't break CC + if (spellInfo && spellInfo == GetSpellInfo()) + { + Aura* aura = GetBase(); + // called from spellcast, should not have ticked yet + if (aura->GetDuration() == aura->GetMaxDuration()) + return false; + } + break; + } + case SPELL_AURA_MECHANIC_IMMUNITY: + case SPELL_AURA_MOD_MECHANIC_RESISTANCE: + // compare mechanic + if (!spellInfo || !(spellInfo->GetAllEffectsMechanicMask() & (1 << GetMiscValue()))) + return false; + break; + case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK: + // skip melee hits and instant cast spells + if (!eventInfo.GetProcSpell() || !eventInfo.GetProcSpell()->GetCastTime()) + return false; + break; + case SPELL_AURA_MOD_POWER_COST_SCHOOL: + case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT: + { + // Skip melee hits and spells with wrong school or zero cost + if (!spellInfo || !(spellInfo->GetSchoolMask() & GetMiscValue()) + || !spellInfo->ManaCost || !spellInfo->ManaCostPercentage) + return false; + break; + } + case SPELL_AURA_REFLECT_SPELLS_SCHOOL: + // Skip melee hits and spells with wrong school + if (!spellInfo || !(spellInfo->GetSchoolMask() & GetMiscValue())) + return false; + break; + case SPELL_AURA_MOD_DAMAGE_FROM_CASTER: + // Compare casters + if (GetCasterGUID() != eventInfo.GetActor()->GetGUID()) + return false; + break; + default: + break; + } + + return result; +} + void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) { bool prevented = GetBase()->CallScriptEffectProcHandlers(this, aurApp, eventInfo); @@ -6200,31 +6264,6 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const { switch (GetSpellInfo()->SpellFamilyName) { - case SPELLFAMILY_DRUID: - { - switch (GetSpellInfo()->Id) - { - // Frenzied Regeneration - case 22842: - { - // Converts up to 10 rage per second into health for $d. Each point of rage is converted into ${$m2/10}.1% of max health. - // Should be manauser - if (!target->HasActivePowerType(POWER_RAGE)) - break; - uint32 rage = target->GetPower(POWER_RAGE); - // Nothing todo - if (rage == 0) - break; - int32 mod = (rage < 100) ? rage : 100; - int32 points = target->CalculateSpellDamage(target, GetSpellInfo(), 1); - int32 regen = target->GetMaxHealth() * (mod * points / 10) / 1000; - target->CastCustomSpell(target, 22845, ®en, 0, 0, true, 0, this); - target->SetPower(POWER_RAGE, rage - mod); - break; - } - } - break; - } case SPELLFAMILY_HUNTER: { // Explosive Shot @@ -6251,15 +6290,6 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const } break; } - case SPELLFAMILY_SHAMAN: - if (GetId() == 52179) // Astral Shift - { - // Periodic need for remove visual on stun/fear/silence lost - if (!(target->GetUnitFlags() & (UNIT_FLAG_STUNNED | UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED))) - target->RemoveAurasDueToSpell(52179); - break; - } - break; case SPELLFAMILY_DEATHKNIGHT: switch (GetId()) { @@ -6426,21 +6456,6 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) } break; } - case SPELLFAMILY_SHAMAN: - { - switch (auraId) - { - // Lightning Shield (The Earthshatterer set trigger after cast Lighting Shield) - case 28820: - { - // Need remove self if Lightning Shield not active - if (!target->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x400, 0, 0)) - target->RemoveAurasDueToSpell(28820); - return; - } - } - break; - } default: break; } @@ -6450,10 +6465,6 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) // Spell exist but require custom code switch (auraId) { - // Mana Tide - case 16191: - target->CastCustomSpell(target, triggerSpellId, &m_amount, nullptr, nullptr, true, nullptr, this); - return; // Poison (Grobbulus) case 28158: case 54362: @@ -6670,18 +6681,6 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const damage = damageReductedArmor; } - // Curse of Agony damage-per-tick calculation - if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x400) && GetSpellInfo()->SpellIconID == 544) - { - uint32 totalTick = GetTotalTicks(); - // 1..4 ticks, 1/2 from normal tick damage - if (m_tickNumber <= totalTick / 3) - damage = damage / 2; - // 9..12 ticks, 3/2 from normal tick damage - else if (m_tickNumber > totalTick * 2 / 3) - damage += (damage + 1) / 2; // +1 prevent 0.5 damage possible lost at 1..4 ticks - // 5..8 ticks have normal tick damage - } } // calculate crit chance @@ -6748,7 +6747,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true); - Unit::ProcDamageAndSpell(caster, target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo); + Unit::ProcSkillsAndAuras(caster, target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo); } void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const @@ -6842,7 +6841,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c new_damage = Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false); - Unit::ProcDamageAndSpell(caster, target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo); + Unit::ProcSkillsAndAuras(caster, target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo); if (!caster || !caster->IsAlive()) return; @@ -6955,22 +6954,6 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const } else { - // Wild Growth = amount + (6 - 2*doneTicks) * ticks* amount / 100 - if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID && GetSpellInfo()->SpellIconID == 2864) - { - uint32 tickNumber = GetTickNumber() - 1; - int32 tempAmount = m_spellInfo->Effects[m_effIndex].CalcValue(caster, &m_baseAmount, nullptr); - - float drop = 2.0f; - - // Item - Druid T10 Restoration 2P Bonus - if (caster) - if (AuraEffect* aurEff = caster->GetAuraEffect(70658, 0)) - AddPct(drop, -aurEff->GetAmount()); - - damage += GetTotalTicks() * tempAmount * (6 - (drop * tickNumber)) * 0.01f; - } - if (GetBase()->GetType() == DYNOBJ_AURA_TYPE) damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetEffIndex(), 0.0f, GetBase()->GetStackAmount()); damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); @@ -7039,7 +7022,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const // ignore item heals if (!haveCastItem && GetAuraType() != SPELL_AURA_OBS_MOD_HEALTH) // xinef: dont allow obs_mod_health to proc spells, this is passive regeneration and not hot - Unit::ProcDamageAndSpell(caster, target, caster ? procAttacker : 0, procVictim, procEx, heal, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, nullptr, &healInfo); + Unit::ProcSkillsAndAuras(caster, target, caster ? procAttacker : 0, procVictim, procEx, heal, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, nullptr, &healInfo); } void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) const @@ -7220,14 +7203,14 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con // Set trigger flag uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; - uint32 procEx = createProcExtendMask(&damageInfo, SPELL_MISS_NONE) | PROC_EX_INTERNAL_DOT; if (damageInfo.damage) procVictim |= PROC_FLAG_TAKEN_DAMAGE; caster->DealSpellDamage(&damageInfo, true); - DamageInfo dmgInfo(damageInfo, DOT); - Unit::ProcDamageAndSpell(caster, damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto, nullptr, GetEffIndex(), nullptr, &dmgInfo); + DamageInfo dmgInfo(damageInfo, DOT, BASE_ATTACK, SPELL_MISS_NONE); + uint32 hitMask = dmgInfo.GetHitMask() | PROC_EX_INTERNAL_DOT; + Unit::ProcSkillsAndAuras(caster, damageInfo.target, procAttacker, procVictim, hitMask, damageInfo.damage, BASE_ATTACK, spellProto, nullptr, GetEffIndex(), nullptr, &dmgInfo); } void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index 8349c83fc..937195060 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -98,6 +98,7 @@ public: void PeriodicTick(AuraApplication* aurApp, Unit* caster) const; void HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo); + bool CheckEffectProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) const; void CleanupTriggeredSpells(Unit* target); diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 0b3b35d59..63da507eb 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -990,12 +990,6 @@ bool Aura::ModStackAmount(int32 num, AuraRemoveMode removeMode, bool periodicRes // reset charges SetCharges(CalcMaxCharges()); - // FIXME: not a best way to synchronize charges, but works - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (AuraEffect* aurEff = GetEffect(i)) - if (aurEff->GetAuraType() == SPELL_AURA_ADD_FLAT_MODIFIER || aurEff->GetAuraType() == SPELL_AURA_ADD_PCT_MODIFIER) - if (SpellModifier* mod = aurEff->GetSpellModifier()) - mod->charges = GetCharges(); } SetStackAmount(stackAmount); @@ -1772,24 +1766,13 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b } break; case SPELLFAMILY_ROGUE: + // Remove Vanish on stealth remove + if (GetId() == 1784) { - // Overkill, Master of Subtlety - if (caster && GetSpellInfo()->SpellIconID == 250) - { - if (caster->GetDummyAuraEffect(SPELLFAMILY_ROGUE, 2114, 0)) - caster->CastSpell(caster, 31666, true); - - if (caster->GetAuraEffectDummy(58426)) - caster->CastSpell(caster, 58428, true); - } - // Remove Vanish on stealth remove - if (GetId() == 1784) - { - target->RemoveAurasWithFamily(SPELLFAMILY_ROGUE, 0x800, 0, 0, ObjectGuid::Empty); - target->RemoveAurasDueToSpell(18461); - } - break; + target->RemoveAurasWithFamily(SPELLFAMILY_ROGUE, 0x800, 0, 0, ObjectGuid::Empty); + target->RemoveAurasDueToSpell(18461); } + break; case SPELLFAMILY_SHAMAN: { // Ghost Wolf Speed (PvP 58 lvl set) @@ -1839,6 +1822,39 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b // mods at aura apply or remove switch (GetSpellInfo()->SpellFamilyName) { + case SPELLFAMILY_ROGUE: + // Stealth + if (GetSpellInfo()->SpellFamilyFlags[0] & 0x00400000) + { + // Master of Subtlety + if (AuraEffect const* aurEff = target->GetAuraEffectOfRankedSpell(31221, 0)) + { + if (!apply) + target->CastSpell(target, 31666, true); + else + { + // Remove counter aura + target->RemoveAurasDueToSpell(31666); + + int32 amount = aurEff->GetAmount(); + target->CastCustomSpell(target, 31665, &amount, nullptr, nullptr, true); + } + } + // Overkill + if (target->HasAura(58426)) + { + if (!apply) + target->CastSpell(target, 58428, true); + else + { + // Remove counter aura + target->RemoveAurasDueToSpell(58428); + + target->CastSpell(target, 58427, true); + } + } + } + break; case SPELLFAMILY_HUNTER: switch (GetId()) { @@ -1871,24 +1887,8 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b case SPELLFAMILY_PALADIN: switch (GetId()) { - case 19746: - case 31821: - // Aura Mastery Triggered Spell Handler - // If apply Concentration Aura -> trigger -> apply Aura Mastery Immunity - // If remove Concentration Aura -> trigger -> remove Aura Mastery Immunity - // If remove Aura Mastery -> trigger -> remove Aura Mastery Immunity - // Do effects only on aura owner - if (GetCasterGUID() != target->GetGUID()) - break; - if (apply) - { - if ((GetSpellInfo()->Id == 31821 && target->HasAura(19746, GetCasterGUID())) || (GetSpellInfo()->Id == 19746 && target->HasAura(31821))) - target->CastSpell(target, 64364, true); - } - else - target->RemoveAurasDueToSpell(64364, GetCasterGUID()); - break; - case 31842: + case 31842: // Divine Illumination + // Item - Paladin T10 Holy 2P Bonus if (caster && caster->HasAura(70755)) { if (apply) @@ -1898,23 +1898,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b } break; } - - // Sanctified Retribution, Improved Devotion Aura, Swift Retribution, Improved Concentration Aura - if (caster == target && GetSpellInfo()->GetSpellSpecific() == SPELL_SPECIFIC_AURA) - { - if (apply) - { - target->CastSpell(target, 63510, true); - target->CastSpell(target, 63514, true); - target->CastSpell(target, 63531, true); - } - else - { - target->RemoveAura(63510); - target->RemoveAura(63514); - target->RemoveAura(63531); - } - } break; } } @@ -1990,8 +1973,13 @@ bool Aura::CanStackWith(Aura const* existingAura) const } // passive auras don't stack with another rank of the spell cast by same caster + // Exception: item-sourced auras from different items can stack (e.g., weapon imbues on MH/OH) if (IsPassive() && sameCaster && (m_spellInfo->IsDifferentRankOf(existingSpellInfo) || (m_spellInfo->Id == existingSpellInfo->Id && m_castItemGuid.IsEmpty()))) - return false; + { + // Allow stacking if both auras are from different items + if (!(GetCastItemGUID() && existingAura->GetCastItemGUID() && GetCastItemGUID() != existingAura->GetCastItemGUID())) + return false; + } for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { @@ -2102,9 +2090,11 @@ bool Aura::CanStackWith(Aura const* existingAura) const // don't allow passive area auras to stack if (m_spellInfo->IsMultiSlotAura() && !IsArea()) return true; - if (GetCastItemGUID() && existingAura->GetCastItemGUID()) - if (GetCastItemGUID() != existingAura->GetCastItemGUID() && m_spellInfo->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC)) - return true; + + // Allow item-sourced auras from different items to stack (e.g., weapon imbues on MH/OH, enchant procs) + if ((IsPassive() || m_spellInfo->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC)) && GetCastItemGUID() && existingAura->GetCastItemGUID() && GetCastItemGUID() != existingAura->GetCastItemGUID()) + return true; + // same spell with same caster should not stack return false; } @@ -2112,22 +2102,32 @@ bool Aura::CanStackWith(Aura const* existingAura) const return true; } -bool Aura::IsProcOnCooldown() const +bool Aura::IsProcOnCooldown(TimePoint now) const { - /*if (m_procCooldown) - { - if (m_procCooldown > GameTime::GetGameTime().count()) - return true; - }*/ - return false; + if (GetType() == UNIT_AURA_TYPE) + if (Player* player = GetUnitOwner()->ToPlayer()) + if (player->GetCommandStatus(CHEAT_COOLDOWN)) + return false; + + return m_procCooldown > now; } -void Aura::AddProcCooldown(Milliseconds /*msec*/) +void Aura::AddProcCooldown(TimePoint cooldownEnd) { - //m_procCooldown = std:chrono::steady_clock::now() + msec; + m_procCooldown = cooldownEnd; } -void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo) +void Aura::AddProcCooldown(SpellProcEntry const* procEntry, TimePoint now) +{ + AddProcCooldown(now + procEntry->Cooldown); +} + +void Aura::ResetProcCooldown() +{ + m_procCooldown = std::chrono::steady_clock::now(); +} + +void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo, TimePoint now) { bool prepare = CallScriptPrepareProcHandlers(aurApp, eventInfo); if (!prepare) @@ -2145,50 +2145,88 @@ void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInf ASSERT(procEntry); // cooldowns should be added to the whole aura (see 51698 area aura) - AddProcCooldown(procEntry->Cooldown); + AddProcCooldown(now + procEntry->Cooldown); } -bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) const +uint8 Aura::GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo, TimePoint now) const { SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(GetId()); + // only auras with spell proc entry can trigger proc if (!procEntry) - return false; + return 0; + + // check spell triggering us + if (Spell const* spell = eventInfo.GetProcSpell()) + { + // Do not allow auras to proc from effect triggered from itself + if (spell->GetTriggeredByAuraSpellInfo() == m_spellInfo) + return 0; + + // check if aura can proc when spell is triggered (exception for hunter auto shot & wands) + if (!GetSpellInfo()->HasAttribute(SPELL_ATTR3_CAN_PROC_FROM_PROCS) && + !(procEntry->AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC) && + !(eventInfo.GetTypeMask() & AUTO_ATTACK_PROC_FLAG_MASK)) + { + if (spell->IsTriggered() && !spell->GetSpellInfo()->HasAttribute(SPELL_ATTR3_NOT_A_PROC)) + return 0; + } + + // do not allow aura proc if proc is caused by a spell cast by item + if (spell->m_CastItem && (procEntry->AttributesMask & PROC_ATTR_CANT_PROC_FROM_ITEM_CAST)) + return 0; + } // check if we have charges to proc with if (IsUsingCharges() && !GetCharges()) - return false; + return 0; // check proc cooldown - if (IsProcOnCooldown()) - return false; - - /// @todo: - // something about triggered spells triggering, and add extra attack effect + if (IsProcOnCooldown(now)) + return 0; // do checks against db data if (!sSpellMgr->CanSpellTriggerProcOnEvent(*procEntry, eventInfo)) - return false; + return 0; + + // check if spell was affected by this aura's spellmod (used by Arcane Potency and similar effects) + // only applies when consuming charges or stacks + if ((procEntry->AttributesMask & PROC_ATTR_REQ_SPELLMOD) && (IsUsingCharges() || (procEntry->AttributesMask & PROC_ATTR_USE_STACKS_FOR_CHARGES))) + { + Spell const* procSpell = eventInfo.GetProcSpell(); + if (!procSpell || procSpell->m_appliedMods.find(const_cast(this)) == procSpell->m_appliedMods.end()) + return 0; + } // do checks using conditions table ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, GetId()); ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget()); if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions)) - return false; + return 0; // AuraScript Hook - bool check = const_cast(this)->CallScriptCheckProcHandlers(aurApp, eventInfo); - if (!check) - return false; + if (!const_cast(this)->CallScriptCheckProcHandlers(aurApp, eventInfo)) + return 0; - /// @todo: - // do allow additional requirements for procs - // this is needed because this is the last moment in which you can prevent aura charge drop on proc - // and possibly a way to prevent default checks (if there're going to be any) + // At least one effect has to pass checks to proc aura + uint8 procEffectMask = aurApp->GetEffectMask(); + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (AuraEffect* aurEff = GetEffect(i)) + { + if (procEffectMask & (1 << i)) + { + if ((procEntry->DisableEffectsMask & (1u << i)) || !aurEff->CheckEffectProc(aurApp, eventInfo)) + procEffectMask &= ~(1 << i); + } + } + } + + if (!procEffectMask) + return 0; // Check if current equipment meets aura requirements // do that only for passive spells - /// @todo: this needs to be unified for all kinds of auras Unit* target = aurApp->GetTarget(); if (IsPassive() && target->IsPlayer() && GetSpellInfo()->EquippedItemClass != -1) { @@ -2198,7 +2236,7 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI if (GetSpellInfo()->EquippedItemClass == ITEM_CLASS_WEAPON) { if (target->ToPlayer()->IsInFeralForm()) - return false; + return 0; if (DamageInfo const* damageInfo = eventInfo.GetDamageInfo()) { @@ -2223,13 +2261,15 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI } if (!item || item->IsBroken() || !item->IsFitToSpellRequirements(GetSpellInfo())) - { return 0; - } } } - return roll_chance_f(CalcProcChance(*procEntry, eventInfo)); + float procChance = CalcProcChance(*procEntry, eventInfo); + if (roll_chance_f(procChance)) + return procEffectMask; + + return 0; } float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const @@ -2239,33 +2279,71 @@ float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& event // so talents modifying chances and judgements will have properly calculated proc chance if (Unit* caster = GetCaster()) { - // calculate ppm chance if present and we're using weapon + // If PPM exists calculate chance from PPM if (eventInfo.GetDamageInfo() && procEntry.ProcsPerMinute != 0) { - uint32 WeaponSpeed = caster->GetAttackTime(eventInfo.GetDamageInfo()->GetAttackType()); - chance = caster->GetPPMProcChance(WeaponSpeed, procEntry.ProcsPerMinute, GetSpellInfo()); + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + uint32 attackSpeed = 0; + if (!procSpell || procSpell->DmgClass == SPELL_DAMAGE_CLASS_MELEE || procSpell->IsRangedWeaponSpell()) + { + attackSpeed = caster->GetAttackTime(eventInfo.GetDamageInfo()->GetAttackType()); + } + else // spells use their cast time for PPM calculations + { + if (procSpell->CastTimeEntry) + attackSpeed = procSpell->CastTimeEntry->CastTime; + + // instants and fast spells use 1.5s cast speed + if (attackSpeed < 1500) + attackSpeed = 1500; + } + chance = caster->GetPPMProcChance(attackSpeed, procEntry.ProcsPerMinute, GetSpellInfo()); } // apply chance modifer aura, applies also to ppm chance (see improved judgement of light spell) if (Player* modOwner = caster->GetSpellModOwner()) modOwner->ApplySpellMod(GetId(), SPELLMOD_CHANCE_OF_SUCCESS, chance); } + + // proc chance is reduced by an additional 3.333% per level past 60 + if ((procEntry.AttributesMask & PROC_ATTR_REDUCE_PROC_60) && eventInfo.GetActor()->GetLevel() > 60) + chance = std::max(0.f, (1.f - ((eventInfo.GetActor()->GetLevel() - 60) * 1.f / 30.f)) * chance); + return chance; } -void Aura::TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) +void Aura::TriggerProcOnEvent(uint8 procEffectMask, AuraApplication* aurApp, ProcEventInfo& eventInfo) { - CallScriptProcHandlers(aurApp, eventInfo); + bool prevented = CallScriptProcHandlers(aurApp, eventInfo); + if (!prevented) + { + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (!(procEffectMask & (1 << i))) + continue; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (aurApp->HasEffect(i)) // OnEffectProc / AfterEffectProc hooks handled in AuraEffect::HandleProc() - GetEffect(i)->HandleProc(aurApp, eventInfo); + if (aurApp->HasEffect(i)) + GetEffect(i)->HandleProc(aurApp, eventInfo); + } - CallScriptAfterProcHandlers(aurApp, eventInfo); + CallScriptAfterProcHandlers(aurApp, eventInfo); + } + ConsumeProcCharges(sSpellMgr->GetSpellProcEntry(GetId())); +} + +void Aura::ConsumeProcCharges(SpellProcEntry const* procEntry) +{ // Remove aura if we've used last charge to proc - if (IsUsingCharges() && !GetCharges()) - Remove(); + if (procEntry->AttributesMask & PROC_ATTR_USE_STACKS_FOR_CHARGES) + { + ModStackAmount(-1); + } + else if (IsUsingCharges()) + { + if (!GetCharges()) + Remove(); + } } void Aura::_DeleteRemovedApplications() @@ -2570,6 +2648,23 @@ bool Aura::CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventI return result; } +bool Aura::CallScriptCheckEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo) +{ + bool result = true; + for (std::list::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) + { + (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_CHECK_EFFECT_PROC, aurApp); + std::list::iterator effEndItr = (*scritr)->DoCheckEffectProc.end(), effItr = (*scritr)->DoCheckEffectProc.begin(); + for (; effItr != effEndItr; ++effItr) + if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex())) + result &= effItr->Call(*scritr, aurEff, eventInfo); + + (*scritr)->_FinishScriptCall(); + } + + return result; +} + bool Aura::CallScriptAfterCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo, bool isTriggeredAtSpellProcEvent) { bool result = isTriggeredAtSpellProcEvent; diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 8731299f8..5d8afc9a4 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -193,17 +193,17 @@ public: bool IsAuraStronger(Aura const* newAura) const; // Proc system - // this subsystem is not yet in use - the core of it is functional, but still some research has to be done - // and some dependant problems fixed before it can replace old proc system (for example cooldown handling) - // currently proc system functionality is implemented in Unit::ProcDamageAndSpell - bool IsProcOnCooldown() const; - void AddProcCooldown(Milliseconds msec); + bool IsProcOnCooldown(TimePoint now) const; + void AddProcCooldown(TimePoint cooldownEnd); + void AddProcCooldown(SpellProcEntry const* procEntry, TimePoint now); + void ResetProcCooldown(); bool IsUsingCharges() const { return m_isUsingCharges; } void SetUsingCharges(bool val) { m_isUsingCharges = val; } - void PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo); - bool IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) const; + void PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo, TimePoint now); + uint8 GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo, TimePoint now) const; float CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const; - void TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo); + void TriggerProcOnEvent(uint8 procEffectMask, AuraApplication* aurApp, ProcEventInfo& eventInfo); + void ConsumeProcCharges(SpellProcEntry const* procEntry); // AuraScript void LoadScripts(); @@ -227,6 +227,7 @@ public: // Spell Proc Hooks bool CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo); + bool CallScriptCheckEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo); bool CallScriptAfterCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo, bool isTriggeredAtSpellProcEvent); bool CallScriptPrepareProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo); bool CallScriptProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo); @@ -270,6 +271,8 @@ protected: bool m_isSingleTarget: 1; // true if it's a single target spell and registered at caster - can change at spell steal for example bool m_isUsingCharges: 1; + TimePoint m_procCooldown; + private: Unit::AuraApplicationList m_removedApplications; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 377b15ef2..02cea67fd 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2267,7 +2267,7 @@ void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/) else if (HasTriggeredCastFlag(TRIGGERED_DISALLOW_PROC_EVENTS)) m_procEx |= PROC_EX_INTERNAL_TRIGGERED; } - // Totem casts require spellfamilymask defined in spell_proc_event to proc + // Totem casts require spellfamilymask defined in spell_proc to proc if (m_originalCaster && m_caster != m_originalCaster && m_caster->IsCreature() && m_caster->ToCreature()->IsTotem() && m_caster->IsControlledByPlayer()) m_procEx |= PROC_EX_INTERNAL_REQ_FAMILY; } @@ -2648,7 +2648,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) // Fill base trigger info uint32 procAttacker = m_procAttacker; uint32 procVictim = m_procVictim; - uint32 procEx = m_procEx; // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now if (canEffectTrigger && !procAttacker && !procVictim) @@ -2705,20 +2704,21 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) uint32 addhealth = m_healing; if (crit) - { - procEx |= PROC_EX_CRITICAL_HIT; addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr); - } - else - procEx |= PROC_EX_NORMAL_HIT; HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask()); + // Set hitMask based on crit + if (crit) + healInfo.AddHitMask(PROC_HIT_CRITICAL); + else + healInfo.AddHitMask(PROC_HIT_NORMAL); + // Xinef: override with forced crit, only visual result if (GetSpellValue()->ForcedCritResult) { crit = true; - procEx |= PROC_EX_CRITICAL_HIT; + healInfo.AddHitMask(PROC_HIT_CRITICAL); } int32 gain = caster->HealBySpell(healInfo, crit); @@ -2729,14 +2729,17 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) unitTarget->getHostileRefMgr().threatAssist(caster, threat, m_spellInfo); m_healing = gain; - // Xinef: if heal acutally healed something, add no overheal flag + // Xinef: if heal actually healed something, add no overheal flag if (m_healing) - procEx |= PROC_EX_NO_OVERHEAL; + healInfo.AddHitMask(PROC_EX_NO_OVERHEAL); // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge) if (canEffectTrigger) - Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo, + { + uint32 hitMask = m_procEx | healInfo.GetHitMask(); + Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo, m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo); + } } // Do damage and triggers else if (m_damage > 0) @@ -2802,7 +2805,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) if (reflectedSpell) effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit); - procEx |= createProcExtendMask(&damageInfo, missInfo); procVictim |= PROC_FLAG_TAKEN_DAMAGE; caster->DealSpellDamage(&damageInfo, true, this); @@ -2813,13 +2815,14 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge) if (canEffectTrigger) { - DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE); - Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo, + DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE, m_attackType, missInfo); + uint32 hitMask = m_procEx | dmgInfo.GetHitMask(); + Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo, m_triggeredByAuraSpell.effectIndex, this, &dmgInfo); if (caster->IsPlayer() && m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) == 0 && m_spellInfo->HasAttribute(SPELL_ATTR4_SUPPRESS_WEAPON_PROCS) == 0 && (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)) - caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx); + caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, dmgInfo.GetHitMask()); } m_damage = damageInfo.damage; @@ -2829,19 +2832,19 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) { // Fill base damage struct (unitTarget - is real spell target) SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo, m_spellSchoolMask); - procEx |= createProcExtendMask(&damageInfo, missInfo); // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge) if (canEffectTrigger) { - DamageInfo dmgInfo(damageInfo, NODAMAGE); - Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo, + DamageInfo dmgInfo(damageInfo, NODAMAGE, m_attackType, missInfo); + uint32 hitMask = m_procEx | dmgInfo.GetHitMask(); + Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo, m_triggeredByAuraSpell.effectIndex, this, &dmgInfo); // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also // Xinef: ofc count only spells that HIT the target, little hack used to fool the system - if ((procEx & PROC_EX_NORMAL_HIT || procEx & PROC_EX_CRITICAL_HIT) && caster->IsPlayer() && m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) == 0 && + if ((dmgInfo.GetHitMask() & (PROC_HIT_NORMAL | PROC_HIT_CRITICAL)) && caster->IsPlayer() && m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) == 0 && m_spellInfo->HasAttribute(SPELL_ATTR4_SUPPRESS_WEAPON_PROCS) == 0 && (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)) - caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim | PROC_FLAG_TAKEN_DAMAGE, procEx); + caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim | PROC_FLAG_TAKEN_DAMAGE, dmgInfo.GetHitMask()); } // Failed Pickpocket, reveal rogue @@ -3194,20 +3197,6 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask) /// @todo: move this code to scripts if (m_preCastSpell) { - // Paladin immunity shields - if (m_preCastSpell == 61988) - { - // Cast Forbearance - m_caster->CastSpell(unit, 25771, true); - // Cast Avenging Wrath Marker - unit->CastSpell(unit, 61987, true); - } - - // Avenging Wrath - if (m_preCastSpell == 61987) - // Cast the serverside immunity shield marker - m_caster->CastSpell(unit, 61988, true); - // Fearie Fire (Feral) - damage if (m_preCastSpell == 60089) m_caster->CastSpell(unit, m_preCastSpell, true); @@ -3896,48 +3885,6 @@ void Spell::_cast(bool skipCheck) // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()... SendSpellGo(); - if (modOwner) - modOwner->SetSpellModTakingSpell(this, false); - - if (m_originalCaster) - { - // Handle procs on cast - uint32 procAttacker = m_procAttacker; - if (!procAttacker) - { - bool IsPositive = m_spellInfo->IsPositive(); - if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) - { - procAttacker = IsPositive ? PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS : PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG; - } - else - { - procAttacker = IsPositive ? PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS : PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG; - } - } - - uint32 procEx = PROC_EX_NORMAL_HIT; - - for (std::list::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) - { - if (ihit->missCondition != SPELL_MISS_NONE) - { - continue; - } - - if (!ihit->crit) - { - continue; - } - - procEx |= PROC_EX_CRITICAL_HIT; - break; - } - - Unit::ProcDamageAndSpell(m_originalCaster, m_originalCaster, procAttacker, PROC_FLAG_NONE, procEx, 1, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell.spellInfo, - m_triggeredByAuraSpell.effectIndex, this, nullptr, nullptr, PROC_SPELL_PHASE_CAST); - } - if (modOwner) modOwner->SetSpellModTakingSpell(this, true); @@ -4012,6 +3959,46 @@ void Spell::_cast(bool skipCheck) if (modOwner) modOwner->SetSpellModTakingSpell(this, false); + // Handle procs on cast - only for non-triggered spells + // Triggered spells (from auras, items, etc.) should not fire CAST phase procs + // as they are not player-initiated casts. This prevents issues like Arcane Potency + // charges being consumed by periodic damage effects (e.g., Blizzard ticks). + // Must be called AFTER handle_immediate() so spell mods (like Missile Barrage's + // duration reduction) are applied before the aura is consumed by the proc. + if (m_originalCaster && !IsTriggered()) + { + uint32 procAttacker = m_procAttacker; + if (!procAttacker) + { + bool IsPositive = m_spellInfo->IsPositive(); + if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) + { + procAttacker = IsPositive ? PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS : PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG; + } + else + { + procAttacker = IsPositive ? PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS : PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG; + } + } + + uint32 hitMask = PROC_HIT_NORMAL; + + for (std::list::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + { + if (ihit->missCondition != SPELL_MISS_NONE) + continue; + + if (!ihit->crit) + continue; + + hitMask |= PROC_HIT_CRITICAL; + break; + } + + Unit::ProcSkillsAndAuras(m_originalCaster, m_originalCaster, procAttacker, PROC_FLAG_NONE, hitMask, 1, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell.spellInfo, + m_triggeredByAuraSpell.effectIndex, this, nullptr, nullptr, PROC_SPELL_PHASE_CAST); + } + if (std::vector const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id)) { for (int32 id : *spell_triggered) @@ -4269,24 +4256,20 @@ void Spell::_handle_finish_phase() } } - uint32 procEx = PROC_EX_NORMAL_HIT; + uint32 hitMask = PROC_HIT_NORMAL; for (std::list::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { if (ihit->missCondition != SPELL_MISS_NONE) - { continue; - } if (!ihit->crit) - { continue; - } - procEx |= PROC_EX_CRITICAL_HIT; + hitMask |= PROC_HIT_CRITICAL; break; } - Unit::ProcDamageAndSpell(m_originalCaster, m_originalCaster, procAttacker, PROC_FLAG_NONE, procEx, 1, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell.spellInfo, + Unit::ProcSkillsAndAuras(m_originalCaster, m_originalCaster, procAttacker, PROC_FLAG_NONE, hitMask, 1, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell.spellInfo, m_triggeredByAuraSpell.effectIndex, this, nullptr, nullptr, PROC_SPELL_PHASE_FINISH); } } @@ -8209,7 +8192,7 @@ bool ReflectEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) { Unit* target = ObjectAccessor::GetUnit(*_caster, _targetGUID); if (target && _caster->IsInMap(target)) - Unit::ProcDamageAndSpell(_caster, target, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, _spellInfo); + Unit::ProcSkillsAndAuras(_caster, target, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, _spellInfo); return true; } diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 0f8cde5d3..ea9fe3630 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -599,6 +599,7 @@ public: std::list* GetUniqueTargetInfo() { return &m_UniqueTargetInfo; } [[nodiscard]] uint32 GetTriggeredByAuraTickNumber() const { return m_triggeredByAuraSpell.tickNumber; } + [[nodiscard]] SpellInfo const* GetTriggeredByAuraSpellInfo() const { return m_triggeredByAuraSpell.spellInfo; } [[nodiscard]] TriggerCastFlags GetTriggeredCastFlags() const { return _triggeredCastFlags; } diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index d725b682e..5aff04864 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3927,39 +3927,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) return; } - // Stoneclaw Totem - case 55328: // Rank 1 - case 55329: // Rank 2 - case 55330: // Rank 3 - case 55332: // Rank 4 - case 55333: // Rank 5 - case 55335: // Rank 6 - case 55278: // Rank 7 - case 58589: // Rank 8 - case 58590: // Rank 9 - case 58591: // Rank 10 - { - int32 basepoints0 = damage; - // Cast Absorb on totems - for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot) - { - if (!unitTarget->m_SummonSlot[slot]) - continue; - - Creature* totem = unitTarget->GetMap()->GetCreature(unitTarget->m_SummonSlot[slot]); - if (totem && totem->IsTotem()) - { - m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true); - } - } - // Glyph of Stoneclaw Totem - if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0)) - { - basepoints0 *= aur->GetAmount(); - m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true); - } - break; - } case 61263: // for item Intravenous Healing Potion (44698) { if (!m_caster || !unitTarget) diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 74b89e99b..209a54923 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1313,7 +1313,6 @@ bool SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const if (affectSpell->SpellFamilyName != SpellFamilyName) return false; - // true if (mod->mask & SpellFamilyFlags) return true; diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index 3abafbc05..66e77fa95 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -1236,15 +1236,6 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Effects[EFFECT_0].SpellClassMask[1] |= 0x20; // prayer of mending }); - // Power Infusion - ApplySpellFix({ 10060 }, [](SpellInfo* spellInfo) - { - // hack to fix stacking with arcane power - spellInfo->Effects[EFFECT_2].Effect = SPELL_EFFECT_APPLY_AURA; - spellInfo->Effects[EFFECT_2].ApplyAuraName = SPELL_AURA_ADD_PCT_MODIFIER; - spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ALLY); - }); - // Lifebloom final bloom ApplySpellFix({ 33778 }, [](SpellInfo* spellInfo) { @@ -3695,13 +3686,6 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_MOD_CHARM; }); - // Persistent Shield - ApplySpellFix({ 26467 }, [](SpellInfo* spellInfo) - { - spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE; - spellInfo->Effects[EFFECT_0].TriggerSpell = 26470; - }); - // Deadly Swiftness ApplySpellFix({ 31255 }, [](SpellInfo* spellInfo) { diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 49c6558c8..a2006ba45 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -784,166 +784,6 @@ SpellGroupStackRule SpellMgr::GetSpellGroupStackRule(SpellGroup group) const return SPELL_GROUP_STACK_RULE_DEFAULT; } -SpellProcEventEntry const* SpellMgr::GetSpellProcEvent(uint32 spellId) const -{ - SpellProcEventMap::const_iterator itr = mSpellProcEventMap.find(spellId); - if (itr != mSpellProcEventMap.end()) - return &itr->second; - return nullptr; -} - -bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, ProcEventInfo const& eventInfo, bool active) const -{ - // No extra req need - uint32 procEvent_procEx = PROC_EX_NONE; - uint32 procEvent_procPhase = PROC_SPELL_PHASE_HIT; - - uint32 procFlags = eventInfo.GetTypeMask(); - uint32 procExtra = eventInfo.GetHitMask(); - uint32 procPhase = eventInfo.GetSpellPhaseMask(); - SpellInfo const* procSpellInfo = eventInfo.GetSpellInfo(); - - // check prockFlags for condition - if ((procFlags & EventProcFlag) == 0) - return false; - - // Xinef: Always trigger for this, including TAKEN_DAMAGE - if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_DEATH | PROC_FLAG_TAKEN_DAMAGE)) - return true; - - bool hasFamilyMask = false; - - if (procFlags & PROC_FLAG_DONE_PERIODIC) - { - if (procExtra & PROC_EX_INTERNAL_HOT) - { - if (EventProcFlag == PROC_FLAG_DONE_PERIODIC) - { - /// no aura with only PROC_FLAG_DONE_PERIODIC and spellFamilyName == 0 can proc from a HOT. - if (!spellProto->SpellFamilyName) - return false; - } - /// Aura must have positive procflags for a HOT to proc - else if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS))) - return false; - } - /// Aura must have negative or neutral(PROC_FLAG_DONE_PERIODIC only) procflags for a DOT to proc - else if (EventProcFlag != PROC_FLAG_DONE_PERIODIC) - if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG | PROC_FLAG_DONE_TRAP_ACTIVATION))) - return false; - } - - if (procFlags & PROC_FLAG_TAKEN_PERIODIC) - { - if (procExtra & PROC_EX_INTERNAL_HOT) - { - /// No aura that only has PROC_FLAG_TAKEN_PERIODIC can proc from a HOT. - if (EventProcFlag == PROC_FLAG_TAKEN_PERIODIC) - return false; - /// Aura must have positive procflags for a HOT to proc - if (!(EventProcFlag & (PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS))) - return false; - } - /// Aura must have negative or neutral(PROC_FLAG_TAKEN_PERIODIC only) procflags for a DOT to proc - else if (EventProcFlag != PROC_FLAG_TAKEN_PERIODIC) - if (!(EventProcFlag & (PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG))) - return false; - } - - // Trap casts are active by default - if (procFlags & PROC_FLAG_DONE_TRAP_ACTIVATION) - active = true; - - if (spellProcEvent) // Exist event data - { - // Store extra req - procEvent_procEx = spellProcEvent->procEx; - procEvent_procPhase = spellProcEvent->procPhase; - - // For melee triggers - if (!procSpellInfo) - { - // Check (if set) for school (melee attack have Normal school) - if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0) - return false; - } - else // For spells need check school/spell family/family mask - { - // Check (if set) for school - if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpellInfo->SchoolMask) == 0) - return false; - - // Check (if set) for spellFamilyName - if (spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpellInfo->SpellFamilyName)) - return false; - - // spellFamilyName is Ok need check for spellFamilyMask if present - if (spellProcEvent->spellFamilyMask) - { - if (!(spellProcEvent->spellFamilyMask & procSpellInfo->SpellFamilyFlags)) - return false; - hasFamilyMask = true; - // Some spells are not considered as active even with have spellfamilyflags - if (!(procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL)) - active = true; - } - - // Check tick numbers - if (procEvent_procEx & PROC_EX_ONLY_FIRST_TICK) - { - if (Spell const* procSpell = eventInfo.GetProcSpell()) - { - if (procSpell->GetTriggeredByAuraTickNumber() > 1) - { - return false; - } - } - } - } - } - - if (procExtra & (PROC_EX_INTERNAL_REQ_FAMILY)) - { - if (!hasFamilyMask) - return false; - } - - if (!(procEvent_procPhase & procPhase)) - { - return false; - } - - // Check for extra req (if none) and hit/crit - if (procEvent_procEx == PROC_EX_NONE) - { - // No extra req, so can trigger only for hit/crit - spell has to be active - if ((procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) && active) - return true; - } - else // Passive spells hits here only if resist/reflect/immune/evade - { - if (procExtra & AURA_SPELL_PROC_EX_MASK) - { - // if spell marked as procing only from not active spells - if (active && procEvent_procEx & PROC_EX_NOT_ACTIVE_SPELL) - return false; - // if spell marked as procing only from active spells - if (!active && procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL) - return false; - // Exist req for PROC_EX_EX_TRIGGER_ALWAYS - if (procEvent_procEx & PROC_EX_EX_TRIGGER_ALWAYS) - return true; - // PROC_EX_NOT_ACTIVE_SPELL and PROC_EX_ONLY_ACTIVE_SPELL flags handle: if passed checks before - if ((procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) && ((procEvent_procEx & (AURA_SPELL_PROC_EX_MASK)) == 0)) - return true; - } - // Check Extra Requirement like (hit/crit/miss/resist/parry/dodge/block/immune/reflect/absorb and other) - if (procEvent_procEx & procExtra) - return true; - } - return false; -} - SpellProcEntry const* SpellMgr::GetSpellProcEntry(uint32 spellId) const { SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId); @@ -964,6 +804,14 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget())) return false; + // check mana cost requirement (used by Clearcasting and similar effects) + if (procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || (!spellInfo->ManaCost && !spellInfo->ManaCostPercentage)) + return false; + } + // always trigger for these types if (eventInfo.GetTypeMask() & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_DEATH)) return true; @@ -973,13 +821,16 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE return false; // check spell family name/flags (if set) for spells - if (eventInfo.GetTypeMask() & (PERIODIC_PROC_FLAG_MASK | SPELL_PROC_FLAG_MASK | PROC_FLAG_DONE_TRAP_ACTIVATION)) + if (eventInfo.GetTypeMask() & SPELL_PROC_FLAG_MASK) { - if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName != eventInfo.GetSpellInfo()->SpellFamilyName)) - return false; + if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo()) + { + if (procEntry.SpellFamilyName && procEntry.SpellFamilyName != eventSpellInfo->SpellFamilyName) + return false; - if (procEntry.SpellFamilyMask && !(procEntry.SpellFamilyMask & eventInfo.GetSpellInfo()->SpellFamilyFlags)) - return false; + if (procEntry.SpellFamilyMask && !(procEntry.SpellFamilyMask & eventSpellInfo->SpellFamilyFlags)) + return false; + } } // check spell type mask (if set) @@ -996,8 +847,11 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE return false; } - // check hit mask (on taken hit or on done hit, but not on spell cast phase) - if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) || ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) && !(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST))) + // check hit mask (on taken hit or on done hit) + // For CAST phase with DONE flags, only check if HitMask is explicitly set (crit is pre-calculated for travel time spells) + if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) || + ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) && + (!(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST) || procEntry.HitMask))) { uint32 hitMask = procEntry.HitMask; // get default values if hit mask not set @@ -1916,98 +1770,65 @@ void SpellMgr::LoadSpellGroupStackRules() LOG_INFO("server.loading", " "); } -void SpellMgr::LoadSpellProcEvents() +static bool InitTriggerAuraData(); +static bool isTriggerAura[TOTAL_AURAS]; +static bool isAlwaysTriggeredAura[TOTAL_AURAS]; +static bool procPrepared = InitTriggerAuraData(); + +// List of auras that CAN trigger but may not exist in spell_proc +// in most case need for drop charges +// in some types of aura need do additional check +// for example SPELL_AURA_MECHANIC_IMMUNITY - need check for mechanic +bool InitTriggerAuraData() { - uint32 oldMSTime = getMSTime(); - - mSpellProcEventMap.clear(); // need for reload case - - // 0 1 2 3 4 5 6 7 8 9 10 11 - QueryResult result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, procFlags, procEx, procPhase, ppmRate, CustomChance, Cooldown FROM spell_proc_event"); - if (!result) + for (uint16 i = 0; i < TOTAL_AURAS; ++i) { - LOG_WARN("server.loading", ">> Loaded 0 spell proc event conditions. DB table `spell_proc_event` is empty."); - return; + isTriggerAura[i] = false; + isAlwaysTriggeredAura[i] = false; } + isTriggerAura[SPELL_AURA_DUMMY] = true; // Most dummy auras should require scripting + isTriggerAura[SPELL_AURA_MOD_CONFUSE] = true; // "Any direct damaging attack will revive targets" + isTriggerAura[SPELL_AURA_MOD_THREAT] = true; // Only one spell: 28762 part of Mage T3 8p bonus + isTriggerAura[SPELL_AURA_MOD_STUN] = true; // Aura does not have charges but needs to be removed on trigger + isTriggerAura[SPELL_AURA_MOD_DAMAGE_DONE] = true; + isTriggerAura[SPELL_AURA_MOD_DAMAGE_TAKEN] = true; + isTriggerAura[SPELL_AURA_MOD_RESISTANCE] = true; + isTriggerAura[SPELL_AURA_MOD_STEALTH] = true; + isTriggerAura[SPELL_AURA_MOD_FEAR] = true; // Aura does not have charges but needs to be removed on trigger + isTriggerAura[SPELL_AURA_MOD_ROOT] = true; + isTriggerAura[SPELL_AURA_TRANSFORM] = true; + isTriggerAura[SPELL_AURA_REFLECT_SPELLS] = true; + isTriggerAura[SPELL_AURA_DAMAGE_IMMUNITY] = true; + isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL] = true; + isTriggerAura[SPELL_AURA_PROC_TRIGGER_DAMAGE] = true; + isTriggerAura[SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK] = true; + isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT] = true; + isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL] = true; + isTriggerAura[SPELL_AURA_REFLECT_SPELLS_SCHOOL] = true; + isTriggerAura[SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN] = true; + isTriggerAura[SPELL_AURA_MOD_ATTACK_POWER] = true; + isTriggerAura[SPELL_AURA_ADD_CASTER_HIT_TRIGGER] = true; + isTriggerAura[SPELL_AURA_OVERRIDE_CLASS_SCRIPTS] = true; + isTriggerAura[SPELL_AURA_MOD_MELEE_HASTE] = true; + isTriggerAura[SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE] = true; + isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE] = true; + isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE] = true; + isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE] = true; + isTriggerAura[SPELL_AURA_MOD_SPELL_CRIT_CHANCE] = true; + isTriggerAura[SPELL_AURA_ADD_FLAT_MODIFIER] = true; + isTriggerAura[SPELL_AURA_ADD_PCT_MODIFIER] = true; + isTriggerAura[SPELL_AURA_ABILITY_IGNORE_AURASTATE] = true; - uint32 count = 0; + isAlwaysTriggeredAura[SPELL_AURA_OVERRIDE_CLASS_SCRIPTS] = true; + isAlwaysTriggeredAura[SPELL_AURA_MOD_FEAR] = true; + isAlwaysTriggeredAura[SPELL_AURA_MOD_ROOT] = true; + isAlwaysTriggeredAura[SPELL_AURA_MOD_STUN] = true; + isAlwaysTriggeredAura[SPELL_AURA_TRANSFORM] = true; + isAlwaysTriggeredAura[SPELL_AURA_SPELL_MAGNET] = true; + isAlwaysTriggeredAura[SPELL_AURA_SCHOOL_ABSORB] = true; + isAlwaysTriggeredAura[SPELL_AURA_MOD_STEALTH] = true; - do - { - Field* fields = result->Fetch(); - - int32 spellId = fields[0].Get(); - - bool allRanks = false; - if (spellId < 0) - { - allRanks = true; - spellId = -spellId; - } - - SpellInfo const* spellInfo = GetSpellInfo(spellId); - if (!spellInfo) - { - LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` does not exist", spellId); - continue; - } - - if (allRanks) - { - if (!spellInfo->IsRanked()) - LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` with all ranks, but spell has no ranks.", spellId); - - if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId)) - { - LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` is not first rank of spell.", spellId); - continue; - } - } - - SpellProcEventEntry spellProcEvent; - - spellProcEvent.schoolMask = fields[1].Get(); - spellProcEvent.spellFamilyName = fields[2].Get(); - spellProcEvent.spellFamilyMask[0] = fields[3].Get(); - spellProcEvent.spellFamilyMask[1] = fields[4].Get(); - spellProcEvent.spellFamilyMask[2] = fields[5].Get(); - spellProcEvent.procFlags = fields[6].Get(); - spellProcEvent.procEx = fields[7].Get(); - spellProcEvent.procPhase = fields[8].Get(); - spellProcEvent.ppmRate = fields[9].Get(); - spellProcEvent.customChance = fields[10].Get(); - spellProcEvent.cooldown = fields[11].Get(); - - // PROC_SPELL_PHASE_NONE is by default PROC_SPELL_PHASE_HIT - if (spellProcEvent.procPhase == PROC_SPELL_PHASE_NONE) - { - spellProcEvent.procPhase = PROC_SPELL_PHASE_HIT; - } - - while (spellInfo) - { - if (mSpellProcEventMap.find(spellInfo->Id) != mSpellProcEventMap.end()) - { - LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` already has its first rank in table.", spellInfo->Id); - break; - } - - if (!spellInfo->ProcFlags && !spellProcEvent.procFlags) - LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` probally not triggered spell", spellInfo->Id); - - mSpellProcEventMap[spellInfo->Id] = spellProcEvent; - - if (allRanks) - spellInfo = spellInfo->GetNextRankSpell(); - else - break; - } - - ++count; - } while (result->NextRow()); - - LOG_INFO("server.loading", ">> Loaded {} Extra Spell Proc Event Conditions in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); - LOG_INFO("server.loading", " "); + return true; } void SpellMgr::LoadSpellProcs() @@ -2016,8 +1837,8 @@ void SpellMgr::LoadSpellProcs() mSpellProcMap.clear(); // need for reload case - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc"); + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, DisableEffectsMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc"); if (!result) { LOG_WARN("server.loading", ">> Loaded 0 Spell Proc Conditions And Data. DB table `spell_proc` Is Empty."); @@ -2067,10 +1888,11 @@ void SpellMgr::LoadSpellProcs() baseProcEntry.SpellPhaseMask = fields[8].Get(); baseProcEntry.HitMask = fields[9].Get(); baseProcEntry.AttributesMask = fields[10].Get(); - baseProcEntry.ProcsPerMinute = fields[11].Get(); - baseProcEntry.Chance = fields[12].Get(); - baseProcEntry.Cooldown = Milliseconds(fields[13].Get()); - baseProcEntry.Charges = fields[14].Get(); + baseProcEntry.DisableEffectsMask = fields[11].Get(); + baseProcEntry.ProcsPerMinute = fields[12].Get(); + baseProcEntry.Chance = fields[13].Get(); + baseProcEntry.Cooldown = Milliseconds(fields[14].Get()); + baseProcEntry.Charges = fields[15].Get(); while (spellInfo) { @@ -2104,8 +1926,6 @@ void SpellMgr::LoadSpellProcs() LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `ProcsPerMinute` field", spellId); procEntry.ProcsPerMinute = 0; } - if (procEntry.Chance == 0 && procEntry.ProcsPerMinute == 0) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `Chance` and `ProcsPerMinute` values defined, proc will not be triggered", spellId); if (procEntry.Charges > 99) { LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has too big value in `Charges` field", spellId); @@ -2125,8 +1945,30 @@ void SpellMgr::LoadSpellProcs() LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has `SpellPhaseMask` value defined, but it won't be used for defined `ProcFlags` value", spellId); if (procEntry.HitMask & ~PROC_HIT_MASK_ALL) LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `HitMask` set: {}", spellId, procEntry.HitMask); - if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK && (!procEntry.SpellPhaseMask || procEntry.SpellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH))))) + // HitMask is valid for: TAKEN procs, or DONE procs at any phase (CAST phase has pre-calculated crit for travel-time spells) + if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK)) LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has `HitMask` value defined, but it won't be used for defined `ProcFlags` and `SpellPhaseMask` values", spellId); + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if ((procEntry.DisableEffectsMask & (1u << i)) && !spellInfo->Effects[i].IsAura()) + LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId {} has DisableEffectsMask with effect {}, but effect {} is not an aura effect", spellId, static_cast(i), static_cast(i)); + if (procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD) + { + bool found = false; + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (!spellInfo->Effects[i].IsAura()) + continue; + + if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER) + { + found = true; + break; + } + } + + if (!found) + LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId {} has Attribute PROC_ATTR_REQ_SPELLMOD, but spell has no spell mods. Proc will not be triggered", spellId); + } mSpellProcMap[spellInfo->Id] = procEntry; @@ -2140,6 +1982,104 @@ void SpellMgr::LoadSpellProcs() LOG_INFO("server.loading", ">> Loaded {} spell proc conditions and data in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); LOG_INFO("server.loading", " "); + + // Generate default procs for spells with proc flags but no explicit spell_proc entry + // This ensures backward compatibility and covers spells that rely on DBC data + LOG_INFO("server.loading", "Generating spell proc data from SpellMap..."); + count = 0; + oldMSTime = getMSTime(); + + for (SpellInfo const* spellInfo : mSpellInfoMap) + { + if (!spellInfo) + continue; + + // Skip if already has explicit entry + if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end()) + continue; + + // Check if spell has any trigger aura effects + bool found = false, addTriggerFlag = false; + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (!spellInfo->Effects[i].IsEffect()) + continue; + + uint32 auraName = spellInfo->Effects[i].ApplyAuraName; + if (!auraName) + continue; + + if (!isTriggerAura[auraName]) + continue; + + found = true; + + if (!addTriggerFlag && isAlwaysTriggeredAura[auraName]) + addTriggerFlag = true; + break; + } + + if (!found) + continue; + + // Skip if no proc flags in DBC + if (!spellInfo->ProcFlags) + continue; + + // Generate default proc entry from DBC data + SpellProcEntry procEntry; + procEntry.SchoolMask = 0; + procEntry.SpellFamilyName = spellInfo->SpellFamilyName; + procEntry.SpellFamilyMask[0] = 0; + procEntry.SpellFamilyMask[1] = 0; + procEntry.SpellFamilyMask[2] = 0; + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (spellInfo->Effects[i].IsEffect() && isTriggerAura[spellInfo->Effects[i].ApplyAuraName]) + procEntry.SpellFamilyMask |= spellInfo->Effects[i].SpellClassMask; + + procEntry.ProcFlags = spellInfo->ProcFlags; + procEntry.SpellTypeMask = PROC_SPELL_TYPE_MASK_ALL; + procEntry.SpellPhaseMask = PROC_SPELL_PHASE_HIT; + procEntry.HitMask = PROC_HIT_NONE; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent + + // Reflect auras should only proc off reflects + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS) || spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS_SCHOOL)) + { + procEntry.HitMask = PROC_HIT_REFLECT; + break; + } + } + + procEntry.AttributesMask = 0; + if (spellInfo->ProcFlags & PROC_FLAG_KILL) + procEntry.AttributesMask |= PROC_ATTR_REQ_EXP_OR_HONOR; + if (addTriggerFlag) + procEntry.AttributesMask |= PROC_ATTR_TRIGGERED_CAN_PROC; + + // Calculate DisableEffectsMask for effects that shouldn't trigger procs + uint32 nonProcMask = 0; + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (!spellInfo->Effects[i].IsAura()) + continue; + if (!isTriggerAura[spellInfo->Effects[i].ApplyAuraName]) + nonProcMask |= 1u << i; + } + procEntry.DisableEffectsMask = nonProcMask; + + procEntry.ProcsPerMinute = 0; + procEntry.Chance = static_cast(spellInfo->ProcChance); + procEntry.Cooldown = Milliseconds::zero(); + procEntry.Charges = spellInfo->ProcCharges; + + mSpellProcMap[spellInfo->Id] = procEntry; + ++count; + } + + LOG_INFO("server.loading", ">> Generated spell proc data for {} spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", " "); } void SpellMgr::LoadSpellBonuses() @@ -3176,11 +3116,15 @@ void SpellMgr::LoadSpellInfoCustomAttributes() case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC: case SPELL_EFFECT_ENCHANT_HELD_ITEM: { - // only enchanting profession enchantments procs can stack + // Only Enchanting profession enchant procs can stack when dual-wielding + // DK runes (e.g., Unholy Strength) should refresh, not stack if (IsPartOfSkillLine(SKILL_ENCHANTING, i)) { uint32 enchantId = spellInfo->Effects[j].MiscValue; SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId); + if (!enchant) + break; + for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s) { if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL) diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index a451404b6..a56ec9145 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -154,21 +154,23 @@ enum ProcFlags | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_PROC_FLAG_MASK = PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS + | PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS - | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, - - SPELL_CAST_PROC_FLAG_MASK = SPELL_PROC_FLAG_MASK | PROC_FLAG_DONE_TRAP_ACTIVATION | RANGED_PROC_FLAG_MASK, + | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG + | PROC_FLAG_DONE_PERIODIC | PROC_FLAG_TAKEN_PERIODIC + | PROC_FLAG_DONE_TRAP_ACTIVATION, PERIODIC_PROC_FLAG_MASK = PROC_FLAG_DONE_PERIODIC | PROC_FLAG_TAKEN_PERIODIC, DONE_HIT_PROC_FLAG_MASK = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_RANGED_AUTO_ATTACK - | PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS - | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG - | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG - | PROC_FLAG_DONE_PERIODIC | PROC_FLAG_DONE_MAINHAND_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK, + | PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS + | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG + | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG + | PROC_FLAG_DONE_PERIODIC | PROC_FLAG_DONE_TRAP_ACTIVATION + | PROC_FLAG_DONE_MAINHAND_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK, TAKEN_HIT_PROC_FLAG_MASK = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK | PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS @@ -268,24 +270,15 @@ enum ProcFlagsHit enum ProcAttributes { - PROC_ATTR_REQ_EXP_OR_HONOR = 0x0000010, + PROC_ATTR_REQ_EXP_OR_HONOR = 0x0000001, // requires proc target to give exp or honor for aura proc + PROC_ATTR_TRIGGERED_CAN_PROC = 0x0000002, // aura can proc even with triggered spells + PROC_ATTR_REQ_MANA_COST = 0x0000004, // requires triggering spell to have a mana cost for aura proc + PROC_ATTR_REQ_SPELLMOD = 0x0000008, // requires triggering spell to be affected by proccing aura to drop charges + PROC_ATTR_USE_STACKS_FOR_CHARGES = 0x0000010, // consuming proc drops a stack from proccing aura instead of charge + PROC_ATTR_REDUCE_PROC_60 = 0x0000080, // aura should have a reduced chance to proc if level of proc actor > 60 + PROC_ATTR_CANT_PROC_FROM_ITEM_CAST = 0x0000100, // do not allow aura proc if proc is caused by a spell casted by item }; -struct SpellProcEventEntry -{ - uint32 schoolMask; // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2 - uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value - flag96 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do) - uint32 procFlags; // bitmask for matching proc event - uint32 procEx; // proc Extend info (see ProcFlagsEx) - uint32 procPhase; // proc phase (see ProcFlagsSpellPhase) - float ppmRate; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc - float customChance; // Owerride chance (in most cases for debug only) - uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_ -}; - -typedef std::unordered_map SpellProcEventMap; - struct SpellProcEntry { uint32 SchoolMask; // if nonzero - bitmask for matching proc condition based on spell's school @@ -296,6 +289,7 @@ struct SpellProcEntry uint32 SpellPhaseMask; // if nonzero - bitmask for matching phase of a spellcast on which proc occurs, see enum ProcFlagsSpellPhase uint32 HitMask; // if nonzero - bitmask for matching proc condition based on hit result, see enum ProcFlagsHit uint32 AttributesMask; // bitmask, see ProcAttributes + uint32 DisableEffectsMask; // bitmask of effects to disable from triggering proc float ProcsPerMinute; // if nonzero - chance to proc is equal to value * aura caster's weapon speed / 60 float Chance; // if nonzero - owerwrite procChance field for given Spell.dbc entry, defines chance of proc to occur, not used if ProcsPerMinute set Milliseconds Cooldown; // if nonzero - cooldown in secs for aura proc, applied to aura @@ -685,10 +679,6 @@ public: SpellGroupStackRule CheckSpellGroupStackRules(SpellInfo const* spellInfo1, SpellInfo const* spellInfo2) const; SpellGroupStackRule GetSpellGroupStackRule(SpellGroup group_id) const; - // Spell proc event table - [[nodiscard]] SpellProcEventEntry const* GetSpellProcEvent(uint32 spellId) const; - bool IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, ProcEventInfo const& eventInfo, bool active) const; - // Spell proc table [[nodiscard]] SpellProcEntry const* GetSpellProcEntry(uint32 spellId) const; bool CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const; @@ -769,7 +759,6 @@ public: void LoadSpellTargetPositions(); void LoadSpellGroups(); void LoadSpellGroupStackRules(); - void LoadSpellProcEvents(); void LoadSpellProcs(); void LoadSpellBonuses(); void LoadSpellThreats(); @@ -801,7 +790,6 @@ private: SpellGroupSpellMap mSpellGroupSpell; SpellGroupStackMap mSpellGroupStack; SameEffectStackMap mSpellSameEffectStack; - SpellProcEventMap mSpellProcEventMap; SpellProcMap mSpellProcMap; SpellBonusMap mSpellBonusMap; SpellThreatMap mSpellThreatMap; diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index d726e2ea8..213ecc7b1 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -733,6 +733,10 @@ bool AuraScript::_Validate(SpellInfo const* entry) if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect()) LOG_ERROR("spells.scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `DoCheckProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str()); + for (std::list::iterator itr = DoCheckEffectProc.begin(); itr != DoCheckEffectProc.end(); ++itr) + if (!itr->GetAffectedEffectsMask(entry)) + LOG_ERROR("spells.scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `DoCheckEffectProc` of AuraScript won't be executed", entry->Id, itr->ToString(), m_scriptName->c_str()); + for (std::list::iterator itr = DoAfterCheckProc.begin(); itr != DoAfterCheckProc.end(); ++itr) if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect()) LOG_ERROR("spells.scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `DoAfterCheckProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str()); @@ -906,6 +910,17 @@ bool AuraScript::CheckProcHandler::Call(AuraScript* auraScript, ProcEventInfo& e return (auraScript->*_HandlerScript)(eventInfo); } +AuraScript::CheckEffectProcHandler::CheckEffectProcHandler(AuraCheckEffectProcFnType handlerScript, uint8 effIndex, uint16 effName) + : EffectBase(effIndex, effName) +{ + _HandlerScript = handlerScript; +} + +bool AuraScript::CheckEffectProcHandler::Call(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo) +{ + return (auraScript->*_HandlerScript)(aurEff, eventInfo); +} + AuraScript::AfterCheckProcHandler::AfterCheckProcHandler(AuraAfterCheckProcFnType handlerScript) { _HandlerScript = handlerScript; @@ -1037,9 +1052,9 @@ DynamicObject* AuraScript::GetDynobjOwner() const return m_aura->GetDynobjOwner(); } -void AuraScript::Remove(uint32 removeMode) +void AuraScript::Remove(AuraRemoveMode removeMode) { - m_aura->Remove((AuraRemoveMode)removeMode); + m_aura->Remove(removeMode); } Aura* AuraScript::GetAura() const @@ -1177,6 +1192,7 @@ Unit* AuraScript::GetTarget() const case AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD: case AURA_SCRIPT_HOOK_EFFECT_SPLIT: case AURA_SCRIPT_HOOK_CHECK_PROC: + case AURA_SCRIPT_HOOK_CHECK_EFFECT_PROC: case AURA_SCRIPT_HOOK_AFTER_CHECK_PROC: case AURA_SCRIPT_HOOK_PREPARE_PROC: case AURA_SCRIPT_HOOK_PROC: diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 8ab04fd70..0ca94edb2 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -499,6 +499,7 @@ enum AuraScriptHookType AURA_SCRIPT_HOOK_AFTER_DISPEL, // Spell Proc Hooks AURA_SCRIPT_HOOK_CHECK_PROC, + AURA_SCRIPT_HOOK_CHECK_EFFECT_PROC, AURA_SCRIPT_HOOK_AFTER_CHECK_PROC, AURA_SCRIPT_HOOK_PREPARE_PROC, AURA_SCRIPT_HOOK_PROC, @@ -530,6 +531,7 @@ public: typedef void(CLASSNAME::*AuraEffectAbsorbFnType)(AuraEffect*, DamageInfo &, uint32 &); \ typedef void(CLASSNAME::*AuraEffectSplitFnType)(AuraEffect*, DamageInfo &, uint32 &); \ typedef bool(CLASSNAME::*AuraCheckProcFnType)(ProcEventInfo&); \ + typedef bool(CLASSNAME::*AuraCheckEffectProcFnType)(AuraEffect const*, ProcEventInfo&); \ typedef bool(CLASSNAME::*AuraAfterCheckProcFnType)(ProcEventInfo&, bool); \ typedef void(CLASSNAME::*AuraProcFnType)(ProcEventInfo&); \ typedef void(CLASSNAME::*AuraEffectProcFnType)(AuraEffect const*, ProcEventInfo&); \ @@ -640,6 +642,14 @@ public: private: AuraCheckProcFnType _HandlerScript; }; + class CheckEffectProcHandler : public EffectBase + { + public: + CheckEffectProcHandler(AuraCheckEffectProcFnType handlerScript, uint8 effIndex, uint16 effName); + bool Call(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo); + private: + AuraCheckEffectProcFnType _HandlerScript; + }; class AfterCheckProcHandler { public: @@ -678,6 +688,7 @@ public: class EffectManaShieldFunction : public AuraScript::EffectManaShieldHandler { public: EffectManaShieldFunction(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectManaShieldHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \ class EffectSplitFunction : public AuraScript::EffectSplitHandler { public: EffectSplitFunction(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectSplitHandler((AuraScript::AuraEffectSplitFnType)_pEffectHandlerScript, _effIndex) {} }; \ class CheckProcHandlerFunction : public AuraScript::CheckProcHandler { public: CheckProcHandlerFunction(AuraCheckProcFnType handlerScript) : AuraScript::CheckProcHandler((AuraScript::AuraCheckProcFnType)handlerScript) {} }; \ + class CheckEffectProcHandlerFunction : public AuraScript::CheckEffectProcHandler { public: CheckEffectProcHandlerFunction(AuraCheckEffectProcFnType handlerScript, uint8 effIndex, uint16 effName) : AuraScript::CheckEffectProcHandler((AuraScript::AuraCheckEffectProcFnType)handlerScript, effIndex, effName) {} }; \ class AfterCheckProcHandlerFunction : public AuraScript::AfterCheckProcHandler { public: AfterCheckProcHandlerFunction(AuraAfterCheckProcFnType handlerScript) : AuraScript::AfterCheckProcHandler((AuraScript::AuraAfterCheckProcFnType)handlerScript) {} }; \ class AuraProcHandlerFunction : public AuraScript::AuraProcHandler { public: AuraProcHandlerFunction(AuraProcFnType handlerScript) : AuraScript::AuraProcHandler((AuraScript::AuraProcFnType)handlerScript) {} }; \ class EffectProcHandlerFunction : public AuraScript::EffectProcHandler { public: EffectProcHandlerFunction(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName) : AuraScript::EffectProcHandler((AuraScript::AuraEffectProcFnType)effectHandlerScript, effIndex, effName) {} }; \ @@ -816,6 +827,13 @@ public: // where function is: bool function (ProcEventInfo& eventInfo); HookList DoCheckProc; #define AuraCheckProcFn(F) CheckProcHandlerFunction(&F) + + // executed when aura effect checks if it can proc the aura + // example: DoCheckEffectProc += AuraCheckEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier); + // where function is: bool function (AuraEffect const* aurEff, ProcEventInfo& eventInfo); + HookList DoCheckEffectProc; +#define AuraCheckEffectProcFn(F, I, N) CheckEffectProcHandlerFunction(&F, I, N) + // executed when aura checks if it can proc // example: DoAfterCheckProc += AuraCheckProcFn(class::function); // where function is: bool function (ProcEventInfo& eventInfo); @@ -870,7 +888,7 @@ public: DynamicObject* GetDynobjOwner() const; // removes aura with remove mode (see AuraRemoveMode enum) - void Remove(uint32 removeMode = 0); + void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); // returns aura object of script Aura* GetAura() const; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 035dfcb13..5038964b4 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -495,9 +495,6 @@ void World::SetInitialWorldSettings() LOG_INFO("server.loading", "Loading Spell Learn Skills..."); sSpellMgr->LoadSpellLearnSkills(); // must be after LoadSpellRanks - LOG_INFO("server.loading", "Loading Spell Proc Event Conditions..."); - sSpellMgr->LoadSpellProcEvents(); - LOG_INFO("server.loading", "Loading Spell Proc Conditions and Data..."); sSpellMgr->LoadSpellProcs(); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 01db0d650..e04795f1d 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -157,7 +157,6 @@ public: { "spell_loot_template", HandleReloadLootTemplatesSpellCommand, SEC_ADMINISTRATOR, Console::Yes }, { "spell_linked_spell", HandleReloadSpellLinkedSpellCommand, SEC_ADMINISTRATOR, Console::Yes }, { "spell_pet_auras", HandleReloadSpellPetAurasCommand, SEC_ADMINISTRATOR, Console::Yes }, - { "spell_proc_event", HandleReloadSpellProcEventCommand, SEC_ADMINISTRATOR, Console::Yes }, { "spell_proc", HandleReloadSpellProcsCommand, SEC_ADMINISTRATOR, Console::Yes }, { "spell_scripts", HandleReloadSpellScriptsCommand, SEC_ADMINISTRATOR, Console::Yes }, { "spell_target_position", HandleReloadSpellTargetPositionCommand, SEC_ADMINISTRATOR, Console::Yes }, @@ -301,7 +300,6 @@ public: HandleReloadSpellAreaCommand(handler); HandleReloadSpellGroupsCommand(handler); HandleReloadSpellLinkedSpellCommand(handler); - HandleReloadSpellProcEventCommand(handler); HandleReloadSpellProcsCommand(handler); HandleReloadSpellBonusesCommand(handler); HandleReloadSpellTargetPositionCommand(handler); @@ -901,14 +899,6 @@ public: return true; } - static bool HandleReloadSpellProcEventCommand(ChatHandler* handler) - { - LOG_INFO("server.loading", "Reloading Spell Proc Event conditions..."); - sSpellMgr->LoadSpellProcEvents(); - handler->SendGlobalGMSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded."); - return true; - } - static bool HandleReloadSpellProcsCommand(ChatHandler* handler) { LOG_INFO("server.loading", "Reloading Spell Proc conditions and data..."); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp index c83ca2043..145495965 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp @@ -28,6 +28,7 @@ enum Spells SPELL_SLEEP = 31298, SPELL_INFERNO = 31299, SPELL_VAMPIRIC_AURA = 31317, + SPELL_VAMPIRIC_AURA_HEAL = 31285, SPELL_ENRAGE = 26662, SPELL_INFERNAL_STUN = 31302, SPELL_INFERNAL_IMMOLATION = 31304 @@ -160,8 +161,37 @@ class spell_anetheron_sleep : public SpellScript } }; +// 31317 - Vampiric Aura +class spell_anetheron_vampiric_aura : public AuraScript +{ + PrepareAuraScript(spell_anetheron_vampiric_aura); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_VAMPIRIC_AURA_HEAL }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + Unit* actor = eventInfo.GetActor(); + int32 bp = damageInfo->GetDamage() * 3; + actor->CastCustomSpell(SPELL_VAMPIRIC_AURA_HEAL, SPELLVALUE_BASE_POINT0, bp, actor, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_anetheron_vampiric_aura::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + void AddSC_boss_anetheron() { RegisterHyjalAI(boss_anetheron); RegisterSpellScript(spell_anetheron_sleep); + RegisterSpellScript(spell_anetheron_vampiric_aura); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 7d5f60c2e..ded579444 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -1342,6 +1342,28 @@ public: } }; +// 72176 - Blood Beast Blood Link +class spell_deathbringer_blood_beast_blood_link : public AuraScript +{ + PrepareAuraScript(spell_deathbringer_blood_beast_blood_link); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_BLOOD_LINK_DUMMY }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActionTarget()->CastCustomSpell(SPELL_BLOOD_LINK_DUMMY, SPELLVALUE_BASE_POINT0, 3, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_deathbringer_blood_beast_blood_link::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + void AddSC_boss_deathbringer_saurfang() { new boss_deathbringer_saurfang(); @@ -1350,6 +1372,7 @@ void AddSC_boss_deathbringer_saurfang() new npc_saurfang_event(); RegisterSpellScript(spell_deathbringer_blood_link_aura); RegisterSpellScript(spell_deathbringer_blood_link_blood_beast_aura); + RegisterSpellScript(spell_deathbringer_blood_beast_blood_link); RegisterSpellScript(spell_deathbringer_blood_link); RegisterSpellAndAuraScriptPair(spell_deathbringer_blood_power, spell_deathbringer_blood_power_aura); RegisterSpellScript(spell_deathbringer_blood_nova_targeting); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 009319691..b22267b70 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -1522,11 +1522,37 @@ class spell_putricide_regurgitated_ooze : public SpellScript } }; +// 71770 - Ooze Tank Protection +class spell_putricide_ooze_tank_protection : public AuraScript +{ + PrepareAuraScript(spell_putricide_ooze_tank_protection); + + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->Effects[EFFECT_0].TriggerSpell, spellInfo->Effects[EFFECT_1].TriggerSpell }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* actionTarget = eventInfo.GetActionTarget(); + actionTarget->CastSpell(nullptr, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_putricide_ooze_tank_protection::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + OnEffectProc += AuraEffectProcFn(spell_putricide_ooze_tank_protection::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + void AddSC_boss_professor_putricide() { new boss_professor_putricide(); new npc_volatile_ooze(); new npc_gas_cloud(); + RegisterSpellScript(spell_putricide_ooze_tank_protection); RegisterSpellScript(spell_putricide_slime_puddle); RegisterSpellScript(spell_putricide_slime_puddle_spawn); RegisterSpellScript(spell_putricide_grow_stacker_aura); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp index 8bb4fded8..80690a7f6 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp @@ -56,6 +56,9 @@ enum XT002Spells SPELL_SPARK_SUMMON = 64210, SPELL_SPARK_DAMAGE = 64227, SPELL_SPARK_MELEE = 64230, + + // ACHIEVEMENT + SPELL_ACHIEVEMENT_CREDIT_NERF_SCRAPBOTS = 65037, }; enum XT002Events @@ -946,6 +949,36 @@ public: } }; +// 65032 - 321 Boombot Aura +class spell_xt002_321_boombot_aura : public AuraScript +{ + PrepareAuraScript(spell_xt002_321_boombot_aura); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ACHIEVEMENT_CREDIT_NERF_SCRAPBOTS }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetActionTarget()->GetEntry() != NPC_XS013_SCRAPBOT) + return false; + return true; + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + if (InstanceScript* instance = eventInfo.GetActor()->GetInstanceScript()) + instance->DoCastSpellOnPlayers(SPELL_ACHIEVEMENT_CREDIT_NERF_SCRAPBOTS); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_xt002_321_boombot_aura::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_xt002_321_boombot_aura::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + void AddSC_boss_xt002() { // Npcs @@ -961,6 +994,7 @@ void AddSC_boss_xt002() RegisterSpellAndAuraScriptPair(spell_xt002_gravity_bomb, spell_xt002_gravity_bomb_aura); RegisterSpellScript(spell_xt002_gravity_bomb_damage); RegisterSpellAndAuraScriptPair(spell_xt002_searing_light_spawn_life_spark, spell_xt002_searing_light_spawn_life_spark_aura); + RegisterSpellScript(spell_xt002_321_boombot_aura); // Achievements new achievement_xt002_nerf_engineering(); diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp index 1a7cb3030..fcad4c62c 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp @@ -203,6 +203,44 @@ enum TickingTimeBomb SPELL_TICKING_TIME_BOMB_EXPLODE = 59687 }; +enum SecondWind +{ + SPELL_SECOND_WIND_TRIGGER = 42771 +}; + +// 42770 - Second Wind +class spell_uk_second_wind : public AuraScript +{ + PrepareAuraScript(spell_uk_second_wind); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SECOND_WIND_TRIGGER }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return false; + + return (spellInfo->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN))) != 0; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActionTarget(); + caster->CastSpell(caster, SPELL_SECOND_WIND_TRIGGER, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_uk_second_wind::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_uk_second_wind::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + class spell_ticking_time_bomb_aura : public AuraScript { PrepareAuraScript(spell_ticking_time_bomb_aura); @@ -231,5 +269,6 @@ void AddSC_utgarde_keep() RegisterUtgardeKeepCreatureAI(npc_dragonflayer_forge_master); RegisterUtgardeKeepCreatureAI(npc_enslaved_proto_drake); + RegisterSpellScript(spell_uk_second_wind); RegisterSpellScript(spell_ticking_time_bomb_aura); } diff --git a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp index 5c48392f4..a519499a4 100644 --- a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp +++ b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp @@ -41,9 +41,10 @@ enum Spells SPELL_MARK_OF_KAZZAK = 32960, SPELL_MARK_OF_KAZZAK_DAMAGE = 32961, SPELL_ENRAGE = 32964, - SPELL_CAPTURE_SOUL = 32966, - SPELL_TWISTED_REFLECTION = 21063, - SPELL_BERSERK = 32965 + SPELL_CAPTURE_SOUL = 32966, + SPELL_TWISTED_REFLECTION = 21063, + SPELL_TWISTED_REFLECTION_HEAL = 21064, + SPELL_BERSERK = 32965 }; class boss_doomlord_kazzak : public CreatureScript @@ -184,8 +185,35 @@ class spell_mark_of_kazzak_aura : public AuraScript } }; +// 21063 - Twisted Reflection +class spell_twisted_reflection : public AuraScript +{ + PrepareAuraScript(spell_twisted_reflection); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_TWISTED_REFLECTION_HEAL }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + eventInfo.GetActionTarget()->CastSpell(eventInfo.GetActor(), SPELL_TWISTED_REFLECTION_HEAL, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_twisted_reflection::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + void AddSC_boss_doomlordkazzak() { new boss_doomlord_kazzak(); RegisterSpellScript(spell_mark_of_kazzak_aura); + RegisterSpellScript(spell_twisted_reflection); } diff --git a/src/server/scripts/Pet/pet_hunter.cpp b/src/server/scripts/Pet/pet_hunter.cpp index b82180e66..377144030 100644 --- a/src/server/scripts/Pet/pet_hunter.cpp +++ b/src/server/scripts/Pet/pet_hunter.cpp @@ -23,6 +23,9 @@ #include "CreatureScript.h" #include "PetDefines.h" #include "ScriptedCreature.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" +#include "SpellScriptLoader.h" enum HunterSpells { @@ -33,6 +36,18 @@ enum HunterSpells SPELL_HUNTER_PET_SCALING = 62915 }; +enum PetSpellsMisc +{ + SPELL_PET_GUARD_DOG_HAPPINESS = 54445, + SPELL_PET_SILVERBACK_RANK_1 = 62800, + SPELL_PET_SILVERBACK_RANK_2 = 62801, + + PET_ICON_ID_GROWL = 201, + PET_ICON_ID_CLAW = 262, + PET_ICON_ID_BITE = 1680, + PET_ICON_ID_SMACK = 473 +}; + struct npc_pet_hunter_snake_trap : public ScriptedAI { npc_pet_hunter_snake_trap(Creature* creature) : ScriptedAI(creature) { _init = false; } @@ -132,7 +147,131 @@ private: uint32 _spellTimer; }; +// -53178 - Guard Dog +class spell_pet_guard_dog : public AuraScript +{ + PrepareAuraScript(spell_pet_guard_dog); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PET_GUARD_DOG_HAPPINESS }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Growl shares family flags with other spells + // filter by spellIcon instead + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || spellInfo->SpellIconID != PET_ICON_ID_GROWL) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + caster->CastSpell(nullptr, SPELL_PET_GUARD_DOG_HAPPINESS, true, nullptr, aurEff); + + Unit* target = eventInfo.GetActionTarget(); + if (!target->CanHaveThreatList()) + return; + + SpellInfo const* procSpellInfo = eventInfo.GetSpellInfo(); + if (!procSpellInfo) + return; + + float addThreat = CalculatePct(static_cast(procSpellInfo->Effects[EFFECT_0].CalcValue(caster)), aurEff->GetAmount()); + target->GetThreatMgr().AddThreat(caster, addThreat, SPELL_SCHOOL_MASK_NORMAL, GetSpellInfo()); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pet_guard_dog::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pet_guard_dog::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -62764 - Silverback +class spell_pet_silverback : public AuraScript +{ + PrepareAuraScript(spell_pet_silverback); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PET_SILVERBACK_RANK_1, SPELL_PET_SILVERBACK_RANK_2 }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Growl shares family flags with other spells + // filter by spellIcon instead + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || spellInfo->SpellIconID != PET_ICON_ID_GROWL) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + static uint32 const triggerSpell[2] = { SPELL_PET_SILVERBACK_RANK_1, SPELL_PET_SILVERBACK_RANK_2 }; + + PreventDefaultAction(); + + uint8 rank = GetSpellInfo()->GetRank(); + if (rank > 0 && rank <= 2) + { + uint32 spellId = triggerSpell[rank - 1]; + eventInfo.GetActor()->CastSpell(nullptr, spellId, true, nullptr, aurEff); + } + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pet_silverback::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pet_silverback::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -61680 - Culling the Herd +class spell_pet_culling_the_herd : public AuraScript +{ + PrepareAuraScript(spell_pet_culling_the_herd); + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Claw, Bite and Smack share FamilyFlags with other spells + // filter by spellIcon instead + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return false; + + switch (spellInfo->SpellIconID) + { + case PET_ICON_ID_CLAW: + case PET_ICON_ID_BITE: + case PET_ICON_ID_SMACK: + break; + default: + return false; + } + + return true; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pet_culling_the_herd::CheckProc); + } +}; + void AddSC_hunter_pet_scripts() { RegisterCreatureAI(npc_pet_hunter_snake_trap); + RegisterSpellScript(spell_pet_guard_dog); + RegisterSpellScript(spell_pet_silverback); + RegisterSpellScript(spell_pet_culling_the_herd); } diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index b27043aae..7b164e32d 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -81,11 +81,43 @@ enum DeathKnightSpells SPELL_DK_RAISE_ALLY = 46619, SPELL_DK_THRASH = 47480, SPELL_GHOUL_FRENZY = 62218, + // Proc system spells + SPELL_DK_ACCLIMATION_HOLY = 50490, + SPELL_DK_ACCLIMATION_FIRE = 50362, + SPELL_DK_ACCLIMATION_FROST = 50485, + SPELL_DK_ACCLIMATION_ARCANE = 50486, + SPELL_DK_ACCLIMATION_SHADOW = 50489, + SPELL_DK_ACCLIMATION_NATURE = 50488, + SPELL_DK_ADVANTAGE_T10_4P_MELEE = 70657, + SPELL_DK_BUTCHERY_RUNIC_POWER = 50163, + SPELL_DK_MARK_OF_BLOOD_HEAL = 61607, + SPELL_DK_UNHOLY_BLIGHT_DOT = 50536, + SPELL_DK_GLYPH_OF_UNHOLY_BLIGHT = 63332, + SPELL_DK_VENDETTA_HEAL = 50181, + SPELL_DK_NECROSIS_DAMAGE = 51460, + SPELL_DK_RUNIC_RETURN = 61258, + SPELL_DK_DEATH_COIL_R1 = 47541, + SPELL_DK_DEATH_GRIP_INITIAL = 49576, + SPELL_DK_GLYPH_OF_SCOURGE_STRIKE_SCRIPT = 69961, + SPELL_DK_HOWLING_BLAST_R1 = 49184, + SPELL_DK_OBLITERATE_OFF_HAND_R1 = 66198, + SPELL_DK_FROST_STRIKE_OFF_HAND_R1 = 66196, + SPELL_DK_PLAGUE_STRIKE_OFF_HAND_R1 = 66216, + SPELL_DK_DEATH_STRIKE_OFF_HAND_R1 = 66188, + SPELL_DK_RUNE_STRIKE_OFF_HAND_R1 = 66217, + SPELL_DK_BLOOD_STRIKE_OFF_HAND_R1 = 66215, + SPELL_DK_KILLING_MACHINE = 51124, }; enum DeathKnightSpellIcons { - DK_ICON_ID_IMPROVED_DEATH_STRIKE = 2751 + DK_ICON_ID_IMPROVED_DEATH_STRIKE = 2751, + DK_ICON_ID_IMPROVED_BLOOD_PRESENCE = 2636, + DK_ICON_ID_BUTCHERY = 2664, + DK_ICON_ID_NECROSIS = 2709, + DK_ICON_ID_THREAT_OF_THASSARIAN = 2023, + DK_ICON_ID_SUDDEN_DOOM = 1939, + DK_ICON_ID_EPIDEMIC = 234 }; enum Misc @@ -494,10 +526,14 @@ class spell_dk_wandering_plague_aura : public AuraScript } // xinef: prevent default proc with castItem passed, which applies 30 sec cooldown to procing of the aura - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void HandleProc(ProcEventInfo& eventInfo) { PreventDefaultAction(); + AuraEffect const* aurEff = GetEffect(EFFECT_0); + if (!aurEff) + return; + eventInfo.GetActor()->AddSpellCooldown(SPELL_DK_WANDERING_PLAGUE_TRIGGER, 0, 1000); eventInfo.GetActor()->CastCustomSpell(SPELL_DK_WANDERING_PLAGUE_TRIGGER, SPELLVALUE_BASE_POINT0, CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()), eventInfo.GetActionTarget(), TRIGGERED_FULL_MASK); } @@ -505,7 +541,7 @@ class spell_dk_wandering_plague_aura : public AuraScript void Register() override { DoCheckProc += AuraCheckProcFn(spell_dk_wandering_plague_aura::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_dk_wandering_plague_aura::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + OnProc += AuraProcFn(spell_dk_wandering_plague_aura::HandleProc); } }; @@ -881,6 +917,119 @@ class spell_dk_pet_scaling : public AuraScript } }; +// -49200 - Acclimation +class spell_dk_acclimation : public AuraScript +{ + PrepareAuraScript(spell_dk_acclimation); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_DK_ACCLIMATION_HOLY, + SPELL_DK_ACCLIMATION_FIRE, + SPELL_DK_ACCLIMATION_NATURE, + SPELL_DK_ACCLIMATION_FROST, + SPELL_DK_ACCLIMATION_SHADOW, + SPELL_DK_ACCLIMATION_ARCANE + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (DamageInfo* damageInfo = eventInfo.GetDamageInfo()) + { + switch (GetFirstSchoolInMask(damageInfo->GetSchoolMask())) + { + case SPELL_SCHOOL_HOLY: + case SPELL_SCHOOL_FIRE: + case SPELL_SCHOOL_NATURE: + case SPELL_SCHOOL_FROST: + case SPELL_SCHOOL_SHADOW: + case SPELL_SCHOOL_ARCANE: + return true; + default: + break; + } + } + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + uint32 triggerspell = 0; + + switch (GetFirstSchoolInMask(eventInfo.GetDamageInfo()->GetSchoolMask())) + { + case SPELL_SCHOOL_HOLY: + triggerspell = SPELL_DK_ACCLIMATION_HOLY; + break; + case SPELL_SCHOOL_FIRE: + triggerspell = SPELL_DK_ACCLIMATION_FIRE; + break; + case SPELL_SCHOOL_NATURE: + triggerspell = SPELL_DK_ACCLIMATION_NATURE; + break; + case SPELL_SCHOOL_FROST: + triggerspell = SPELL_DK_ACCLIMATION_FROST; + break; + case SPELL_SCHOOL_SHADOW: + triggerspell = SPELL_DK_ACCLIMATION_SHADOW; + break; + case SPELL_SCHOOL_ARCANE: + triggerspell = SPELL_DK_ACCLIMATION_ARCANE; + break; + default: + return; + } + + if (Unit* target = eventInfo.GetActionTarget()) + target->CastSpell(target, triggerspell, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dk_acclimation::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_acclimation::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 70656 - Advantage T10 4P (DK) +class spell_dk_advantage_t10_4p : public AuraScript +{ + PrepareAuraScript(spell_dk_advantage_t10_4p); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DK_ADVANTAGE_T10_4P_MELEE }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (Unit* caster = eventInfo.GetActor()) + { + Player* player = caster->ToPlayer(); + if (!player || player->getClass() != CLASS_DEATH_KNIGHT) + return false; + + for (uint8 i = 0; i < MAX_RUNES; ++i) + if (player->GetRuneCooldown(i) == 0) + return false; + + return true; + } + + return false; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dk_advantage_t10_4p::CheckProc); + } +}; + // 50462 - Anti-Magic Zone (on raid member) class spell_dk_anti_magic_shell_raid : public AuraScript { @@ -2314,16 +2463,164 @@ class spell_dk_army_of_the_dead_passive : public AuraScript } }; +// -50163 - Butchery +class spell_dk_butchery : public AuraScript +{ + PrepareAuraScript(spell_dk_butchery); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DK_BUTCHERY_RUNIC_POWER }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastCustomSpell(SPELL_DK_BUTCHERY_RUNIC_POWER, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetTarget(), true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dk_butchery::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 49005 - Mark of Blood +class spell_dk_mark_of_blood : public AuraScript +{ + PrepareAuraScript(spell_dk_mark_of_blood); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DK_MARK_OF_BLOOD_HEAL }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + // Heal the target that the marked enemy attacked (from TrinityCore) + eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), SPELL_DK_MARK_OF_BLOOD_HEAL, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dk_mark_of_blood::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 49194 - Unholy Blight +class spell_dk_unholy_blight : public AuraScript +{ + PrepareAuraScript(spell_dk_unholy_blight); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DK_UNHOLY_BLIGHT_DOT, SPELL_DK_GLYPH_OF_UNHOLY_BLIGHT }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + return damageInfo && damageInfo->GetDamage(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = GetCaster(); + Unit* target = eventInfo.GetActionTarget(); + if (!caster || !target) + return; + + SpellInfo const* unholyBlight = sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_BLIGHT_DOT); + if (!unholyBlight) + return; + + int32 bp = CalculatePct(static_cast(eventInfo.GetDamageInfo()->GetDamage()), aurEff->GetAmount()); + + // Glyph of Unholy Blight + if (AuraEffect* glyph = caster->GetAuraEffect(SPELL_DK_GLYPH_OF_UNHOLY_BLIGHT, EFFECT_0)) + AddPct(bp, glyph->GetAmount()); + + bp = bp / (unholyBlight->GetMaxDuration() / unholyBlight->Effects[EFFECT_0].Amplitude); + target->CastDelayedSpellWithPeriodicAmount(caster, SPELL_DK_UNHOLY_BLIGHT_DOT, SPELL_AURA_PERIODIC_DAMAGE, bp); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dk_unholy_blight::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_unholy_blight::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -50181 - Vendetta +class spell_dk_vendetta : public AuraScript +{ + PrepareAuraScript(spell_dk_vendetta); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DK_VENDETTA_HEAL }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + Unit* target = GetTarget(); + int32 bp = target->CountPctFromMaxHealth(aurEff->GetAmount()); + target->CastCustomSpell(SPELL_DK_VENDETTA_HEAL, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dk_vendetta::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -51459 - Necrosis +class spell_dk_necrosis : public AuraScript +{ + PrepareAuraScript(spell_dk_necrosis); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DK_NECROSIS_DAMAGE }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + return damageInfo && damageInfo->GetDamage(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = GetTarget(); + Unit* target = eventInfo.GetActionTarget(); + + int32 bp = CalculatePct(static_cast(eventInfo.GetDamageInfo()->GetDamage()), aurEff->GetAmount()); + caster->CastCustomSpell(SPELL_DK_NECROSIS_DAMAGE, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dk_necrosis::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_necrosis::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + // -49182 Blade Barrier class spell_dk_blade_barrier : public AuraScript { PrepareAuraScript(spell_dk_blade_barrier); - bool CheckProc(ProcEventInfo& /*eventInfo*/) + bool CheckProc(ProcEventInfo& eventInfo) { - if (Player* player = GetCaster()->ToPlayer()) - if (player->getClass() == CLASS_DEATH_KNIGHT && player->IsBaseRuneSlotsOnCooldown(RUNE_BLOOD)) - return true; + if (eventInfo.GetSpellInfo()) + if (Player* player = eventInfo.GetActor()->ToPlayer()) + if (player->getClass() == CLASS_DEATH_KNIGHT && player->IsBaseRuneSlotsOnCooldown(RUNE_BLOOD)) + return true; return false; } @@ -2334,6 +2631,359 @@ class spell_dk_blade_barrier : public AuraScript } }; +// -49208, -49467, -54639 - Death Rune +class spell_dk_death_rune : public AuraScript +{ + PrepareAuraScript(spell_dk_death_rune); + + bool Load() override + { + return GetUnitOwner()->IsPlayer() && GetUnitOwner()->ToPlayer()->getClass() == CLASS_DEATH_KNIGHT; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Unit* caster = eventInfo.GetActor(); + if (!caster || !caster->IsPlayer()) + return false; + + Player* player = caster->ToPlayer(); + if (player->getClass() != CLASS_DEATH_KNIGHT) + return false; + + return true; + } + + void HandleProc(ProcEventInfo& eventInfo) + { + Player* player = eventInfo.GetActor()->ToPlayer(); + AuraEffect* aurEff = GetEffect(EFFECT_0); + if (!aurEff) + return; + + // Reset amplitude - set death rune remove timer to 30s + aurEff->ResetPeriodic(true); + + uint32 runesLeft = 1; + // Death Rune Mastery (SpellIconID 2622) + if (GetSpellInfo()->SpellIconID == 2622) + runesLeft = 2; + + for (uint8 i = 0; i < MAX_RUNES && runesLeft; ++i) + { + if (GetSpellInfo()->SpellIconID == 2622) + { + if (player->GetBaseRune(i) == RUNE_BLOOD) + continue; + } + else + { + if (player->GetBaseRune(i) != RUNE_BLOOD) + continue; + } + + // Check if rune just went on cooldown + if (player->GetRuneCooldown(i) != player->GetRuneBaseCooldown(i, false)) + continue; + + --runesLeft; + player->AddRuneByAuraEffect(i, RUNE_DEATH, aurEff); + } + } + + void PeriodicTick(AuraEffect const* aurEff) + { + GetTarget()->ToPlayer()->RemoveRunesByAuraEffect(aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dk_death_rune::CheckProc); + OnProc += AuraProcFn(spell_dk_death_rune::HandleProc); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_dk_death_rune::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +// -49188 - Rime +class spell_dk_rime : public AuraScript +{ + PrepareAuraScript(spell_dk_rime); + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return GetTarget()->IsPlayer(); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + Player* player = GetTarget()->ToPlayer(); + if (!player) + return; + + // Reset cooldown of Howling Blast (all ranks) + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_DK_HOWLING_BLAST_R1); + while (spellInfo) + { + player->RemoveSpellCooldown(spellInfo->Id, true); + spellInfo = spellInfo->GetNextRankSpell(); + } + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dk_rime::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_rime::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 51124 - Killing Machine +class spell_dk_killing_machine : public AuraScript +{ + PrepareAuraScript(spell_dk_killing_machine); + + void HandleEffectCalcSpellMod(AuraEffect const* /*aurEff*/, SpellModifier*& spellMod) + { + if (spellMod) + { + // Icy Touch (mask0=2), Frost Strike (mask1=4), Howling Blast (mask1=2) + spellMod->mask = flag96(2, 6, 0); + } + } + + void Register() override + { + DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_dk_killing_machine::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_ADD_FLAT_MODIFIER); + } +}; + +// -49018 - Sudden Doom +class spell_dk_sudden_doom : public AuraScript +{ + PrepareAuraScript(spell_dk_sudden_doom); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DK_DEATH_COIL_R1 }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_DK_DEATH_COIL_R1); + uint32 spellId = 0; + + while (spellInfo) + { + if (!caster->HasSpell(spellInfo->Id)) + break; + + spellId = spellInfo->Id; + spellInfo = spellInfo->GetNextRankSpell(); + } + + if (!spellId) + return; + + caster->CastSpell(eventInfo.GetActionTarget(), spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dk_sudden_doom::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -65661 - Threat of Thassarian +class spell_dk_threat_of_thassarian : public AuraScript +{ + PrepareAuraScript(spell_dk_threat_of_thassarian); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_DK_OBLITERATE_OFF_HAND_R1, + SPELL_DK_FROST_STRIKE_OFF_HAND_R1, + SPELL_DK_PLAGUE_STRIKE_OFF_HAND_R1, + SPELL_DK_DEATH_STRIKE_OFF_HAND_R1, + SPELL_DK_RUNE_STRIKE_OFF_HAND_R1, + SPELL_DK_BLOOD_STRIKE_OFF_HAND_R1 + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + if (!roll_chance_i(aurEff->GetAmount())) + return; + + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return; + + Unit* caster = eventInfo.GetActor(); + if (!caster->haveOffhandWeapon()) + return; + + uint32 spellId = 0; + // Plague Strike + if (spellInfo->SpellFamilyFlags[0] & 0x00000001) + spellId = SPELL_DK_PLAGUE_STRIKE_OFF_HAND_R1; + // Death Strike + else if (spellInfo->SpellFamilyFlags[0] & 0x00000010) + spellId = SPELL_DK_DEATH_STRIKE_OFF_HAND_R1; + // Blood Strike + else if (spellInfo->SpellFamilyFlags[0] & 0x00400000) + spellId = SPELL_DK_BLOOD_STRIKE_OFF_HAND_R1; + // Frost Strike + else if (spellInfo->SpellFamilyFlags[1] & 0x00000004) + spellId = SPELL_DK_FROST_STRIKE_OFF_HAND_R1; + // Obliterate + else if (spellInfo->SpellFamilyFlags[1] & 0x00020000) + spellId = SPELL_DK_OBLITERATE_OFF_HAND_R1; + // Rune Strike + else if (spellInfo->SpellFamilyFlags[1] & 0x20000000) + spellId = SPELL_DK_RUNE_STRIKE_OFF_HAND_R1; + + if (!spellId) + return; + + Unit* target = eventInfo.GetActionTarget(); + if (!target) + return; + + spellId = sSpellMgr->GetSpellWithRank(spellId, spellInfo->GetRank()); + caster->CastSpell(target, spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dk_threat_of_thassarian::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 62259 - Glyph of Death Grip +class spell_dk_glyph_of_death_grip : public AuraScript +{ + PrepareAuraScript(spell_dk_glyph_of_death_grip); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DK_DEATH_GRIP_INITIAL }); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (Player* player = eventInfo.GetActor()->ToPlayer()) + player->RemoveSpellCooldown(SPELL_DK_DEATH_GRIP_INITIAL, true); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dk_glyph_of_death_grip::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 58642 - Glyph of Scourge Strike +class spell_dk_glyph_of_scourge_strike : public AuraScript +{ + PrepareAuraScript(spell_dk_glyph_of_scourge_strike); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DK_GLYPH_OF_SCOURGE_STRIKE_SCRIPT }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), SPELL_DK_GLYPH_OF_SCOURGE_STRIKE_SCRIPT, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dk_glyph_of_scourge_strike::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 69961 - Glyph of Scourge Strike (script effect) +class spell_dk_glyph_of_scourge_strike_script : public SpellScript +{ + PrepareSpellScript(spell_dk_glyph_of_scourge_strike_script); + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + + Unit::AuraEffectList const& mPeriodic = target->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE); + for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i) + { + AuraEffect const* aurEff = *i; + SpellInfo const* spellInfo = aurEff->GetSpellInfo(); + // Search Blood Plague and Frost Fever on target + if (spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && (spellInfo->SpellFamilyFlags[2] & 0x2) && + aurEff->GetCasterGUID() == caster->GetGUID()) + { + uint32 countMin = aurEff->GetBase()->GetMaxDuration(); + uint32 countMax = spellInfo->GetMaxDuration(); + + // this Glyph + countMax += 9000; + // talent Epidemic + if (AuraEffect const* epidemic = caster->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_DEATHKNIGHT, DK_ICON_ID_EPIDEMIC, EFFECT_0)) + countMax += epidemic->GetAmount(); + + if (countMin < countMax) + { + aurEff->GetBase()->SetDuration(aurEff->GetBase()->GetDuration() + 3000); + aurEff->GetBase()->SetMaxDuration(countMin + 3000); + } + } + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_dk_glyph_of_scourge_strike_script::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +// 61257 - PvP 4P Bonus (Runic Power on Snare/Root) +class spell_dk_pvp_4p_bonus : public AuraScript +{ + PrepareAuraScript(spell_dk_pvp_4p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DK_RUNIC_RETURN }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return false; + + return (spellInfo->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_SNARE))) != 0; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActionTarget()->CastSpell(nullptr, SPELL_DK_RUNIC_RETURN, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dk_pvp_4p_bonus::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_pvp_4p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + void AddSC_deathknight_spell_scripts() { RegisterSpellScript(spell_dk_wandering_plague); @@ -2355,6 +3005,8 @@ void AddSC_deathknight_spell_scripts() RegisterSpellScript(spell_dk_dancing_rune_weapon_visual); RegisterSpellScript(spell_dk_scent_of_blood_trigger); RegisterSpellScript(spell_dk_pet_scaling); + RegisterSpellScript(spell_dk_acclimation); + RegisterSpellScript(spell_dk_advantage_t10_4p); RegisterSpellScript(spell_dk_anti_magic_shell_raid); RegisterSpellScript(spell_dk_anti_magic_shell_self); RegisterSpellScript(spell_dk_anti_magic_zone); @@ -2382,5 +3034,20 @@ void AddSC_deathknight_spell_scripts() RegisterSpellScript(spell_dk_will_of_the_necropolis); RegisterSpellScript(spell_dk_ghoul_thrash); RegisterSpellScript(spell_dk_army_of_the_dead_passive); + // Proc system scripts + RegisterSpellScript(spell_dk_butchery); + RegisterSpellScript(spell_dk_mark_of_blood); + RegisterSpellScript(spell_dk_unholy_blight); + RegisterSpellScript(spell_dk_vendetta); + RegisterSpellScript(spell_dk_necrosis); RegisterSpellScript(spell_dk_blade_barrier); + RegisterSpellScript(spell_dk_death_rune); + RegisterSpellScript(spell_dk_rime); + RegisterSpellScript(spell_dk_killing_machine); + RegisterSpellScript(spell_dk_sudden_doom); + RegisterSpellScript(spell_dk_threat_of_thassarian); + RegisterSpellScript(spell_dk_glyph_of_death_grip); + RegisterSpellScript(spell_dk_glyph_of_scourge_strike); + RegisterSpellScript(spell_dk_glyph_of_scourge_strike_script); + RegisterSpellScript(spell_dk_pvp_4p_bonus); } diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 85a12610d..8a677ff57 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -17,6 +17,7 @@ #include "Containers.h" #include "CreatureScript.h" +#include "GameTime.h" #include "GridNotifiers.h" #include "Player.h" #include "SpellAuraEffects.h" @@ -60,12 +61,52 @@ enum DruidSpells SPELL_DRUID_ENRAGE = 5229, SPELL_DRUID_ENRAGED_DEFENSE = 70725, SPELL_DRUID_ITEM_T10_FERAL_4P_BONUS = 70726, - SPELL_DRUID_MOONGLADE_2P_BONUS = 37286 + SPELL_DRUID_MAIM_INTERRUPT = 32747, + SPELL_DRUID_MOONGLADE_2P_BONUS = 37286, + // Proc system spells + SPELL_DRUID_GLYPH_OF_INNERVATE_MANA = 54833, + SPELL_DRUID_GLYPH_OF_STARFIRE_PROC = 54846, + SPELL_DRUID_GLYPH_OF_RAKE_STUN = 54820, + SPELL_DRUID_LEADER_OF_THE_PACK_HEAL = 34299, + SPELL_DRUID_LEADER_OF_THE_PACK_MANA = 68285, + SPELL_DRUID_GLYPH_OF_REJUV_HEAL = 54755, + SPELL_DRUID_ECLIPSE_LUNAR = 48518, + SPELL_DRUID_ECLIPSE_SOLAR = 48517, + SPELL_DRUID_T3_PROC_ENERGIZE_MANA = 28722, + SPELL_DRUID_T3_PROC_ENERGIZE_RAGE = 28723, + SPELL_DRUID_T3_PROC_ENERGIZE_ENERGY = 28724, + SPELL_DRUID_BLESSING_OF_THE_CLAW = 28750, + SPELL_DRUID_EXHILARATE = 28742, + SPELL_DRUID_INFUSION = 37238, + SPELL_DRUID_BLESSING_OF_REMULOS = 40445, + SPELL_DRUID_BLESSING_OF_ELUNE = 40446, + SPELL_DRUID_BLESSING_OF_CENARIUS = 40452, + SPELL_DRUID_REVITALIZE_ENERGIZE_MANA = 48542, + SPELL_DRUID_REVITALIZE_ENERGIZE_RAGE = 48541, + SPELL_DRUID_REVITALIZE_ENERGIZE_ENERGY = 48540, + SPELL_DRUID_REVITALIZE_ENERGIZE_RP = 48543, + SPELL_DRUID_GLYPH_OF_RIP = 54818, + SPELL_DRUID_RIP_DURATION_LACERATE_DMG = 60141, + SPELL_DRUID_REJUVENATION_T10_PROC = 70691, + SPELL_DRUID_LANGUISH = 71023, + // T9 Feral Relic + SPELL_DRUID_T9_FERAL_RELIC_BEAR = 67354, + SPELL_DRUID_T9_FERAL_RELIC_CAT = 67355, + // Frenzied Regeneration + SPELL_DRUID_FRENZIED_REGENERATION_HEAL = 22845, + // Insect Swarm + SPELL_DRUID_ITEM_T8_BALANCE_RELIC = 64950, + // Nourish + SPELL_DRUID_GLYPH_OF_NOURISH = 62971, + // Wild Growth + SPELL_DRUID_RESTORATION_T10_2P_BONUS = 70658 }; enum DruidIcons { - SPELL_ICON_REVITALIZE = 2862 + SPELL_ICON_REVITALIZE = 2862, + SPELL_ICON_ECLIPSE = 2856, + SPELL_ICON_INNERVATE = 62 }; // 1178 - Bear Form (Passive) @@ -113,27 +154,27 @@ class spell_dru_t10_balance_4p_bonus : public AuraScript { PrepareAuraScript(spell_dru_t10_balance_4p_bonus); - bool CheckProc(ProcEventInfo& eventInfo) + bool Validate(SpellInfo const* /*spellInfo*/) override { - return eventInfo.GetActor() && eventInfo.GetProcTarget(); + return ValidateSpellInfo({ SPELL_DRUID_LANGUISH }); } void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - uint32 triggered_spell_id = 71023; - SpellInfo const* triggeredSpell = sSpellMgr->GetSpellInfo(triggered_spell_id); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; - int32 amount = CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()) / triggeredSpell->GetMaxTicks(); - eventInfo.GetProcTarget()->CastDelayedSpellWithPeriodicAmount(GetTarget(), triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE, amount, EFFECT_0); + SpellInfo const* triggeredSpell = sSpellMgr->GetSpellInfo(SPELL_DRUID_LANGUISH); - //GetTarget()->CastCustomSpell(triggered_spell_id, SPELLVALUE_BASE_POINT0, amount, eventInfo.GetProcTarget(), true, nullptr, aurEff); + int32 amount = CalculatePct(static_cast(damageInfo->GetDamage()), aurEff->GetAmount()) / triggeredSpell->GetMaxTicks(); + eventInfo.GetProcTarget()->CastDelayedSpellWithPeriodicAmount(GetTarget(), SPELL_DRUID_LANGUISH, SPELL_AURA_PERIODIC_DAMAGE, amount, EFFECT_0); } void Register() override { - DoCheckProc += AuraCheckProcFn(spell_dru_t10_balance_4p_bonus::CheckProc); OnEffectProc += AuraEffectProcFn(spell_dru_t10_balance_4p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); } }; @@ -286,21 +327,41 @@ class spell_dru_barkskin : public AuraScript { PrepareAuraScript(spell_dru_barkskin); - void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + bool Validate(SpellInfo const* /*spellInfo*/) override { - if (GetUnitOwner()->HasAura(SPELL_DRUID_GLYPH_OF_BARKSKIN, GetUnitOwner()->GetGUID())) - GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_DRUID_GLYPH_OF_BARKSKIN_TRIGGER, true); + return ValidateSpellInfo({ SPELL_DRUID_GLYPH_OF_BARKSKIN_TRIGGER }); } - void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - GetUnitOwner()->RemoveAurasDueToSpell(SPELL_DRUID_GLYPH_OF_BARKSKIN_TRIGGER, GetUnitOwner()->GetGUID()); + GetTarget()->RemoveAurasDueToSpell(SPELL_DRUID_GLYPH_OF_BARKSKIN_TRIGGER); } void Register() override { - AfterEffectApply += AuraEffectApplyFn(spell_dru_barkskin::AfterApply, EFFECT_0, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_dru_barkskin::AfterRemove, EFFECT_0, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_dru_barkskin::OnRemove, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 63057 - Glyph of Barkskin +class spell_dru_glyph_of_barkskin : public AuraScript +{ + PrepareAuraScript(spell_dru_glyph_of_barkskin); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_GLYPH_OF_BARKSKIN_TRIGGER }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(eventInfo.GetActor(), SPELL_DRUID_GLYPH_OF_BARKSKIN_TRIGGER, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_barkskin::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); } }; @@ -1265,6 +1326,773 @@ private: ObjectGuid _casterGUID; }; +// 54832 - Glyph of Innervate +class spell_dru_glyph_of_innervate : public AuraScript +{ + PrepareAuraScript(spell_dru_glyph_of_innervate); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_GLYPH_OF_INNERVATE_MANA }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + return spellInfo && spellInfo->SpellIconID == SPELL_ICON_INNERVATE; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + Unit* caster = GetTarget(); + int32 manaPercent = aurEff->GetAmount(); + int32 bp = caster->GetCreatePowers(POWER_MANA) * manaPercent / 100 / 10; + caster->CastCustomSpell(SPELL_DRUID_GLYPH_OF_INNERVATE_MANA, SPELLVALUE_BASE_POINT0, bp, caster, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dru_glyph_of_innervate::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_innervate::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 54821 - Glyph of Rake +class spell_dru_glyph_of_rake : public AuraScript +{ + PrepareAuraScript(spell_dru_glyph_of_rake); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_GLYPH_OF_RAKE_STUN }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return false; + + // Check if it's Rake (SpellVisual 750 and Effect 1 is periodic damage) + if (spellInfo->SpellVisual[0] != 750 || spellInfo->Effects[EFFECT_1].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE) + return false; + + Unit* target = eventInfo.GetActionTarget(); + return target && target->IsCreature(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(eventInfo.GetActionTarget(), SPELL_DRUID_GLYPH_OF_RAKE_STUN, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dru_glyph_of_rake::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_rake::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 24932 - Leader of the Pack +class spell_dru_leader_of_the_pack : public AuraScript +{ + PrepareAuraScript(spell_dru_leader_of_the_pack); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_LEADER_OF_THE_PACK_HEAL, SPELL_DRUID_LEADER_OF_THE_PACK_MANA }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + Unit* target = GetTarget(); + int32 healAmount = aurEff->GetAmount(); + if (healAmount <= 0) + return; + + // 6 second internal cooldown + if (target->IsPlayer() && target->ToPlayer()->HasSpellCooldown(SPELL_DRUID_LEADER_OF_THE_PACK_HEAL)) + return; + + int32 bp = target->CountPctFromMaxHealth(healAmount); + target->CastCustomSpell(SPELL_DRUID_LEADER_OF_THE_PACK_HEAL, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); + + if (target->IsPlayer()) + target->ToPlayer()->AddSpellCooldown(SPELL_DRUID_LEADER_OF_THE_PACK_HEAL, 0, 6 * IN_MILLISECONDS); + + // Improved Leader of the Pack - mana regen (only for self-cast aura) + if (aurEff->GetCasterGUID() == target->GetGUID()) + { + int32 manaAmount = CalculatePct(target->GetMaxPower(POWER_MANA), healAmount * 2); + target->CastCustomSpell(SPELL_DRUID_LEADER_OF_THE_PACK_MANA, SPELLVALUE_BASE_POINT0, manaAmount, target, true, nullptr, aurEff); + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_leader_of_the_pack::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + } +}; + +// 54754 - Glyph of Rejuvenation +class spell_dru_glyph_of_rejuvenation : public AuraScript +{ + PrepareAuraScript(spell_dru_glyph_of_rejuvenation); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_GLYPH_OF_REJUV_HEAL }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Unit* target = eventInfo.GetActionTarget(); + if (!target) + return false; + + // Only proc if target is below health threshold + return target->HealthBelowPct(GetSpellInfo()->Effects[EFFECT_0].CalcValue()); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 bp = CalculatePct(static_cast(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_DRUID_GLYPH_OF_REJUV_HEAL, SPELLVALUE_BASE_POINT0, bp, eventInfo.GetActionTarget(), true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dru_glyph_of_rejuvenation::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_rejuvenation::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -48516 - Eclipse +class spell_dru_eclipse : public AuraScript +{ + PrepareAuraScript(spell_dru_eclipse); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_ECLIPSE_LUNAR, SPELL_DRUID_ECLIPSE_SOLAR }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return false; + + Unit* target = GetTarget(); + if (!target->IsPlayer()) + return false; + + bool isWrathSpell = (spellInfo->SpellFamilyFlags[0] & 1); + bool isStarfireSpell = (spellInfo->SpellFamilyFlags[0] & 4); + + // Must be Wrath or Starfire + if (!isWrathSpell && !isStarfireSpell) + return false; + + // Check 30 second internal cooldown + uint32 now = GameTime::GetGameTimeMS().count(); + if (isWrathSpell && _lunarProcCooldownEnd > now) + return false; + if (isStarfireSpell && _solarProcCooldownEnd > now) + return false; + + // Don't proc if already have any eclipse aura + if (target->HasAura(SPELL_DRUID_ECLIPSE_LUNAR) || target->HasAura(SPELL_DRUID_ECLIPSE_SOLAR)) + return false; + + // Check proc chance (60% for Wrath, 100% for Starfire) + if (!roll_chance_f(GetSpellInfo()->ProcChance * (isWrathSpell ? 0.6f : 1.0f))) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + bool isWrathSpell = (spellInfo->SpellFamilyFlags[0] & 1); + uint32 triggeredSpell = isWrathSpell ? SPELL_DRUID_ECLIPSE_LUNAR : SPELL_DRUID_ECLIPSE_SOLAR; + + // Set 30 second internal cooldown + uint32 now = GameTime::GetGameTimeMS().count(); + if (isWrathSpell) + _lunarProcCooldownEnd = now + 30000; + else + _solarProcCooldownEnd = now + 30000; + + GetTarget()->CastSpell(GetTarget(), triggeredSpell, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dru_eclipse::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_eclipse::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + +private: + uint32 _lunarProcCooldownEnd = 0; + uint32 _solarProcCooldownEnd = 0; +}; + +// -48539 - Revitalize +class spell_dru_revitalize : public AuraScript +{ + PrepareAuraScript(spell_dru_revitalize); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_DRUID_REVITALIZE_ENERGIZE_MANA, + SPELL_DRUID_REVITALIZE_ENERGIZE_RAGE, + SPELL_DRUID_REVITALIZE_ENERGIZE_ENERGY, + SPELL_DRUID_REVITALIZE_ENERGIZE_RP + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (!roll_chance_i(aurEff->GetAmount())) + return; + + Unit* target = eventInfo.GetActionTarget(); + uint32 spellId; + + switch (target->getPowerType()) + { + case POWER_MANA: + spellId = SPELL_DRUID_REVITALIZE_ENERGIZE_MANA; + break; + case POWER_RAGE: + spellId = SPELL_DRUID_REVITALIZE_ENERGIZE_RAGE; + break; + case POWER_ENERGY: + spellId = SPELL_DRUID_REVITALIZE_ENERGIZE_ENERGY; + break; + case POWER_RUNIC_POWER: + spellId = SPELL_DRUID_REVITALIZE_ENERGIZE_RP; + break; + default: + return; + } + + eventInfo.GetActor()->CastSpell(target, spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_revitalize::HandleProc, EFFECT_0, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + } +}; + +// 28716 - Rejuvenation (T3 2P Bonus) +class spell_dru_t3_2p_bonus : public AuraScript +{ + PrepareAuraScript(spell_dru_t3_2p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_DRUID_T3_PROC_ENERGIZE_MANA, + SPELL_DRUID_T3_PROC_ENERGIZE_RAGE, + SPELL_DRUID_T3_PROC_ENERGIZE_ENERGY + }); + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return roll_chance_i(50); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* target = eventInfo.GetActionTarget(); + uint32 spellId; + + switch (target->getPowerType()) + { + case POWER_MANA: + spellId = SPELL_DRUID_T3_PROC_ENERGIZE_MANA; + break; + case POWER_RAGE: + spellId = SPELL_DRUID_T3_PROC_ENERGIZE_RAGE; + break; + case POWER_ENERGY: + spellId = SPELL_DRUID_T3_PROC_ENERGIZE_ENERGY; + break; + default: + return; + } + + eventInfo.GetActor()->CastSpell(target, spellId, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dru_t3_2p_bonus::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_t3_2p_bonus::HandleProc, EFFECT_0, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + } +}; + +// 28744 - Regrowth (T3 6P Bonus) +class spell_dru_t3_6p_bonus : public AuraScript +{ + PrepareAuraScript(spell_dru_t3_6p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_BLESSING_OF_THE_CLAW }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), SPELL_DRUID_BLESSING_OF_THE_CLAW, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_t3_6p_bonus::HandleProc, EFFECT_0, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + } +}; + +// 28719 - Healing Touch (T3 8P Bonus) +class spell_dru_t3_8p_bonus : public AuraScript +{ + PrepareAuraScript(spell_dru_t3_8p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_EXHILARATE }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return; + + Unit* caster = eventInfo.GetActor(); + int32 amount = CalculatePct(spellInfo->CalcPowerCost(caster, spellInfo->GetSchoolMask()), aurEff->GetAmount()); + caster->CastCustomSpell(SPELL_DRUID_EXHILARATE, SPELLVALUE_BASE_POINT0, amount, caster, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_t3_8p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 37288, 37295 - Mana Restore (T4 2P Bonus) +class spell_dru_t4_2p_bonus : public AuraScript +{ + PrepareAuraScript(spell_dru_t4_2p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_INFUSION }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(nullptr, SPELL_DRUID_INFUSION, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_t4_2p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 40442 - Druid Tier 6 Trinket +class spell_dru_item_t6_trinket : public AuraScript +{ + PrepareAuraScript(spell_dru_item_t6_trinket); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_DRUID_BLESSING_OF_REMULOS, + SPELL_DRUID_BLESSING_OF_ELUNE, + SPELL_DRUID_BLESSING_OF_CENARIUS + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return; + + uint32 spellId; + int32 chance; + + // Starfire + if (spellInfo->SpellFamilyFlags[0] & 0x00000004) + { + spellId = SPELL_DRUID_BLESSING_OF_REMULOS; + chance = 25; + } + // Rejuvenation + else if (spellInfo->SpellFamilyFlags[0] & 0x00000010) + { + spellId = SPELL_DRUID_BLESSING_OF_ELUNE; + chance = 25; + } + // Mangle (Bear) and Mangle (Cat) + else if (spellInfo->SpellFamilyFlags[1] & 0x00000440) + { + spellId = SPELL_DRUID_BLESSING_OF_CENARIUS; + chance = 40; + } + else + return; + + if (roll_chance_i(chance)) + eventInfo.GetActor()->CastSpell(nullptr, spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_item_t6_trinket::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 54815 - Glyph of Shred +class spell_dru_glyph_of_shred : public AuraScript +{ + PrepareAuraScript(spell_dru_glyph_of_shred); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_DRUID_GLYPH_OF_RIP, + SPELL_DRUID_RIP_DURATION_LACERATE_DMG + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + // Try to find Rip on the target + if (AuraEffect const* rip = eventInfo.GetActionTarget()->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00800000, 0x0, 0x0, caster->GetGUID())) + { + // Rip's max duration, includes modifiers like Glyph of Rip + uint32 countMin = rip->GetBase()->GetMaxDuration(); + + // Just Rip's max duration without other spells + uint32 countMax = rip->GetSpellInfo()->GetMaxDuration(); + + // Add possible auras' and Glyph of Shred's max duration + countMax += 3 * aurEff->GetAmount() * IN_MILLISECONDS; // Glyph of Shred -> +6 seconds + countMax += caster->HasAura(SPELL_DRUID_GLYPH_OF_RIP) ? 4 * IN_MILLISECONDS : 0; // Glyph of Rip -> +4 seconds + countMax += caster->HasAura(SPELL_DRUID_RIP_DURATION_LACERATE_DMG) ? 4 * IN_MILLISECONDS : 0; // T7 set bonus -> +4 seconds + + // If min < max that means caster didn't cast 3 shred yet + if (countMin < countMax) + { + rip->GetBase()->SetDuration(rip->GetBase()->GetDuration() + aurEff->GetAmount() * IN_MILLISECONDS); + rip->GetBase()->SetMaxDuration(countMin + aurEff->GetAmount() * IN_MILLISECONDS); + } + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_shred::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 54845 - Glyph of Starfire (Dummy) +class spell_dru_glyph_of_starfire_dummy : public AuraScript +{ + PrepareAuraScript(spell_dru_glyph_of_starfire_dummy); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_GLYPH_OF_STARFIRE_PROC }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), SPELL_DRUID_GLYPH_OF_STARFIRE_PROC, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_starfire_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 70664 - Item - Druid T10 Restoration 4P Bonus (Rejuvenation) +class spell_dru_t10_restoration_4p_bonus_dummy : public AuraScript +{ + PrepareAuraScript(spell_dru_t10_restoration_4p_bonus_dummy); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_REJUVENATION_T10_PROC }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || spellInfo->Id == SPELL_DRUID_REJUVENATION_T10_PROC) + return false; + + HealInfo* healInfo = eventInfo.GetHealInfo(); + if (!healInfo || !healInfo->GetHeal()) + return false; + + Player* caster = eventInfo.GetActor()->ToPlayer(); + if (!caster) + return false; + + return caster->GetGroup() || caster != eventInfo.GetActionTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 amount = eventInfo.GetHealInfo()->GetHeal(); + eventInfo.GetActor()->CastCustomSpell(SPELL_DRUID_REJUVENATION_T10_PROC, SPELLVALUE_BASE_POINT0, amount, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dru_t10_restoration_4p_bonus_dummy::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_t10_restoration_4p_bonus_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 44835 - Maim Interrupt +class spell_dru_maim_interrupt : public AuraScript +{ + PrepareAuraScript(spell_dru_maim_interrupt); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_MAIM_INTERRUPT }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_DRUID_MAIM_INTERRUPT, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_dru_maim_interrupt::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 67353 - T9 Feral Relic (Idol of Mutilation) +class spell_dru_t9_feral_relic : public AuraScript +{ + PrepareAuraScript(spell_dru_t9_feral_relic); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_DRUID_T9_FERAL_RELIC_BEAR, + SPELL_DRUID_T9_FERAL_RELIC_CAT + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Unit* target = eventInfo.GetActor(); + + switch (target->GetShapeshiftForm()) + { + case FORM_BEAR: + case FORM_DIREBEAR: + case FORM_CAT: + return true; + default: + break; + } + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + uint32 triggerspell = 0; + + Unit* target = eventInfo.GetActor(); + + switch (target->GetShapeshiftForm()) + { + case FORM_BEAR: + case FORM_DIREBEAR: + triggerspell = SPELL_DRUID_T9_FERAL_RELIC_BEAR; + break; + case FORM_CAT: + triggerspell = SPELL_DRUID_T9_FERAL_RELIC_CAT; + break; + default: + return; + } + + target->CastSpell(target, triggerspell, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_dru_t9_feral_relic::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_t9_feral_relic::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 22842 - Frenzied Regeneration +class spell_dru_frenzied_regeneration : public AuraScript +{ + PrepareAuraScript(spell_dru_frenzied_regeneration); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_FRENZIED_REGENERATION_HEAL }); + } + + void HandlePeriodic(AuraEffect const* aurEff) + { + Unit* target = GetTarget(); + if (target->getPowerType() != POWER_RAGE) + return; + + uint32 rage = target->GetPower(POWER_RAGE); + if (!rage) + return; + + int32 const mod = std::min(static_cast(rage), 100); + int32 const points = GetSpellInfo()->Effects[EFFECT_1].CalcValue(target); + int32 const regen = CalculatePct(target->GetMaxHealth(), points * mod / 100.f); + target->CastCustomSpell(SPELL_DRUID_FRENZIED_REGENERATION_HEAL, SPELLVALUE_BASE_POINT0, regen, target, true, nullptr, aurEff); + target->SetPower(POWER_RAGE, rage - mod); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_dru_frenzied_regeneration::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +// -5570 - Insect Swarm +class spell_dru_insect_swarm : public AuraScript +{ + PrepareAuraScript(spell_dru_insect_swarm); + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + if (AuraEffect const* relicAurEff = caster->GetAuraEffect(SPELL_DRUID_ITEM_T8_BALANCE_RELIC, EFFECT_0)) + amount += relicAurEff->GetAmount() / aurEff->GetTotalTicks(); + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_insect_swarm::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } +}; + +// 50464 - Nourish +class spell_dru_nourish : public SpellScript +{ + PrepareSpellScript(spell_dru_nourish); + + void HandleHeal(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + if (!target) + return; + + int32 heal = GetHitHeal(); + + // Glyph of Nourish + if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_DRUID_GLYPH_OF_NOURISH, EFFECT_0)) + { + uint32 auraCount = 0; + + Unit::AuraEffectList const& periodicHeals = target->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL); + for (AuraEffect const* hot : periodicHeals) + { + if (caster->GetGUID() == hot->GetCasterGUID()) + ++auraCount; + } + + AddPct(heal, aurEff->GetAmount() * auraCount); + } + + SetHitHeal(heal); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_dru_nourish::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); + } +}; + +// -48438 - Wild Growth (AuraScript) +class spell_dru_wild_growth_aura : public AuraScript +{ + PrepareAuraScript(spell_dru_wild_growth_aura); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_RESTORATION_T10_2P_BONUS }); + } + + void SetTickHeal(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + _baseTick = amount; + if (Unit* caster = GetCaster()) + if (AuraEffect const* bonus = caster->GetAuraEffect(SPELL_DRUID_RESTORATION_T10_2P_BONUS, EFFECT_0)) + AddPct(_baseReduction, -bonus->GetAmount()); + } + + void HandleTickUpdate(AuraEffect* aurEff) + { + // Wild Growth = first tick gains a 6% bonus, reduced by 2% each tick + float reduction = _baseReduction; + reduction *= (aurEff->GetTickNumber() - 1); + + float const bonus = 6.f - reduction; + int32 const amount = int32(_baseTick + CalculatePct(_baseTick, bonus)); + aurEff->SetAmount(amount); + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_wild_growth_aura::SetTickHeal, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_dru_wild_growth_aura::HandleTickUpdate, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + } + + float _baseTick = 0.f; + float _baseReduction = 2.f; +}; + void AddSC_druid_spell_scripts() { RegisterSpellScript(spell_dru_bear_form_passive); @@ -1274,6 +2102,7 @@ void AddSC_druid_spell_scripts() RegisterSpellScript(spell_dru_omen_of_clarity); RegisterSpellScript(spell_dru_brambles_treant); RegisterSpellScript(spell_dru_barkskin); + RegisterSpellScript(spell_dru_glyph_of_barkskin); RegisterSpellScript(spell_dru_treant_scaling); RegisterSpellScript(spell_dru_berserk); RegisterSpellAndAuraScriptPair(spell_dru_dash, spell_dru_dash_aura); @@ -1298,7 +2127,27 @@ void AddSC_druid_spell_scripts() RegisterSpellScript(spell_dru_tiger_s_fury); RegisterSpellScript(spell_dru_typhoon); RegisterSpellScript(spell_dru_t10_restoration_4p_bonus); - RegisterSpellScript(spell_dru_wild_growth); + RegisterSpellAndAuraScriptPair(spell_dru_wild_growth, spell_dru_wild_growth_aura); RegisterSpellScript(spell_dru_moonkin_form_passive_proc); RegisterSpellScript(spell_dru_rejuvenation_moonglade_2_set); + // Proc system scripts + RegisterSpellScript(spell_dru_glyph_of_innervate); + RegisterSpellScript(spell_dru_glyph_of_rake); + RegisterSpellScript(spell_dru_leader_of_the_pack); + RegisterSpellScript(spell_dru_glyph_of_rejuvenation); + RegisterSpellScript(spell_dru_eclipse); + RegisterSpellScript(spell_dru_revitalize); + RegisterSpellScript(spell_dru_t3_2p_bonus); + RegisterSpellScript(spell_dru_t3_6p_bonus); + RegisterSpellScript(spell_dru_t3_8p_bonus); + RegisterSpellScript(spell_dru_t4_2p_bonus); + RegisterSpellScript(spell_dru_item_t6_trinket); + RegisterSpellScript(spell_dru_glyph_of_shred); + RegisterSpellScript(spell_dru_glyph_of_starfire_dummy); + RegisterSpellScript(spell_dru_t10_restoration_4p_bonus_dummy); + RegisterSpellScript(spell_dru_maim_interrupt); + RegisterSpellScript(spell_dru_t9_feral_relic); + RegisterSpellScript(spell_dru_frenzied_regeneration); + RegisterSpellScript(spell_dru_insect_swarm); + RegisterSpellScript(spell_dru_nourish); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 55186ba5e..b81ec36f1 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -69,6 +69,89 @@ class spell_gen_5000_gold : public SpellScript } }; +// 430, 431, 432, 1133, 1135, 1137, 10250, 22734, 27089, 34291, 43182, 43183, 46755, 49472, 57073, 61830, 72623 - Drink +class spell_gen_arena_drink : public AuraScript +{ + PrepareAuraScript(spell_gen_arena_drink); + + bool Load() override + { + return GetCaster() && GetCaster()->IsPlayer(); + } + + bool Validate(SpellInfo const* spellInfo) override + { + if (spellInfo->Effects[EFFECT_0].ApplyAuraName != SPELL_AURA_MOD_POWER_REGEN) + { + LOG_ERROR("spells", "Aura {} structure has been changed - first aura is no longer SPELL_AURA_MOD_POWER_REGEN", spellInfo->Id); + return false; + } + + return true; + } + + void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& isPeriodic, int32& /*amplitude*/) + { + AuraEffect* regen = GetAura()->GetEffect(EFFECT_0); + if (!regen) + return; + + // default case - not in arena + if (!GetCaster()->ToPlayer()->InArena()) + isPeriodic = false; + } + + void CalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + AuraEffect* regen = GetAura()->GetEffect(EFFECT_0); + if (!regen) + return; + + // default case - not in arena + if (!GetCaster()->ToPlayer()->InArena()) + regen->ChangeAmount(amount); + } + + void UpdatePeriodic(AuraEffect* aurEff) + { + AuraEffect* regen = GetAura()->GetEffect(EFFECT_0); + if (!regen) + return; + + // This feature used only in arenas + // Here need increase mana regen per tick (6 second rule) + // on 0 tick - 0 (handled in 2 second) + // on 1 tick - 166% (handled in 4 second) + // on 2 tick - 133% (handled in 6 second) + + // Apply bonus for 1 - 4 tick + switch (aurEff->GetTickNumber()) + { + case 1: // 0% + regen->ChangeAmount(0); + break; + case 2: // 166% + regen->ChangeAmount(aurEff->GetAmount() * 5 / 3); + break; + case 3: // 133% + regen->ChangeAmount(aurEff->GetAmount() * 4 / 3); + break; + default: // 100% - normal regen + regen->ChangeAmount(aurEff->GetAmount()); + // No need to update after 4th tick + aurEff->SetPeriodic(false); + break; + } + } + + void Register() override + { + DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_gen_arena_drink::CalcPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_arena_drink::CalcAmount, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY); + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_arena_drink::UpdatePeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY); + } +}; + // 24401 - Test Pet Passive class spell_gen_model_visible : public AuraScript { @@ -5696,6 +5779,307 @@ class spell_gen_whisper_to_controller : public SpellScript } }; +enum VampiricTouchSpells +{ + SPELL_VAMPIRIC_TOUCH_HEAL = 52724 +}; + +// 52723 - Vampiric Touch (proc) +class spell_gen_vampiric_touch : public AuraScript +{ + PrepareAuraScript(spell_gen_vampiric_touch); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_VAMPIRIC_TOUCH_HEAL }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + Unit* caster = eventInfo.GetActor(); + int32 bp = damageInfo->GetDamage() / 2; + caster->CastCustomSpell(SPELL_VAMPIRIC_TOUCH_HEAL, SPELLVALUE_BASE_POINT0, bp, caster, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_gen_vampiric_touch::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 62337, 62933 - Petrified Bark (Freya) +class spell_gen_petrified_bark : public AuraScript +{ + PrepareAuraScript(spell_gen_petrified_bark); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ 62379 }); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + Unit* victim = eventInfo.GetActor(); + if (!victim) + return; + + int32 damage = damageInfo->GetDamage(); + victim->CastCustomSpell(GetTarget(), 62379, &damage, nullptr, nullptr, true); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_gen_petrified_bark::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 67534 - Earth Shield (Trial of the Champion) +class spell_gen_earth_shield_toc : public AuraScript +{ + PrepareAuraScript(spell_gen_earth_shield_toc); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ 67535 }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + int32 damage = damageInfo->GetDamage(); + GetTarget()->CastCustomSpell(GetTarget(), 67535, &damage, nullptr, nullptr, true, nullptr, aurEff, GetCasterGUID()); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_gen_earth_shield_toc::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 65932 - Retaliation (Faction Champions) +class spell_gen_retaliation_toc : public AuraScript +{ + PrepareAuraScript(spell_gen_retaliation_toc); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ 65934 }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Unit* attacker = eventInfo.GetActor(); + return attacker && GetTarget()->HasInArc(M_PI, attacker); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* attacker = eventInfo.GetActor(); + if (attacker) + GetTarget()->CastSpell(attacker, 65934, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_gen_retaliation_toc::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_gen_retaliation_toc::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 69172 - Overlord's Brand (damage/heal redirect - non-DoT) +class spell_gen_overlords_brand : public AuraScript +{ + PrepareAuraScript(spell_gen_overlords_brand); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ 69189, 69190 }); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = GetCaster(); + if (!caster) + return; + + if (eventInfo.GetTypeMask() & (PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS)) + { + HealInfo* healInfo = eventInfo.GetHealInfo(); + if (!healInfo || !healInfo->GetHeal()) + return; + int32 heal = static_cast(healInfo->GetHeal() * 5.5f); + GetTarget()->CastCustomSpell(caster, 69190, &heal, nullptr, nullptr, true); + } + else + { + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + if (Unit* victim = caster->GetVictim()) + { + int32 damage = damageInfo->GetDamage(); + GetTarget()->CastCustomSpell(victim, 69189, &damage, nullptr, nullptr, true); + } + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_gen_overlords_brand::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 69173 - Overlord's Brand (damage/heal redirect - DoT only) +class spell_gen_overlords_brand_dot : public AuraScript +{ + PrepareAuraScript(spell_gen_overlords_brand_dot); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ 69189, 69190 }); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = GetCaster(); + if (!caster) + return; + + if (eventInfo.GetHitMask() & PROC_EX_INTERNAL_HOT) + { + HealInfo* healInfo = eventInfo.GetHealInfo(); + if (!healInfo || !healInfo->GetHeal()) + return; + int32 heal = static_cast(healInfo->GetHeal() * 5.5f); + GetTarget()->CastCustomSpell(caster, 69190, &heal, nullptr, nullptr, true); + } + else + { + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + if (Unit* victim = caster->GetVictim()) + { + int32 damage = damageInfo->GetDamage(); + GetTarget()->CastCustomSpell(victim, 69189, &damage, nullptr, nullptr, true); + } + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_gen_overlords_brand_dot::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 70674 - Vampiric Might (Lady Deathwhisper) +class spell_gen_vampiric_might : public AuraScript +{ + PrepareAuraScript(spell_gen_vampiric_might); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ 70677 }); + } + + void HandleProc(ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = GetCaster(); + if (!caster) + return; + + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + int32 heal = damageInfo->GetDamage() * 3; + caster->CastCustomSpell(caster, 70677, &heal, nullptr, nullptr, true); + } + + void Register() override + { + OnProc += AuraProcFn(spell_gen_vampiric_might::HandleProc); + } +}; + +// 69023 - Mirrored Soul (Devourer of Souls) +class spell_gen_mirrored_soul : public AuraScript +{ + PrepareAuraScript(spell_gen_mirrored_soul); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ 69034 }); + } + + void HandleProc(ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + Unit* caster = GetCaster(); + if (!caster) + return; + + int32 damage = static_cast(damageInfo->GetDamage() * 0.45f); + if (damage > 0) + GetTarget()->CastCustomSpell(caster, 69034, &damage, nullptr, nullptr, true); + } + + void Register() override + { + OnProc += AuraProcFn(spell_gen_mirrored_soul::HandleProc); + } +}; + +// 27522, 40336, 46939 - Black Bow of the Betrayer / Mana Drain Trigger +class spell_gen_black_bow_of_the_betrayer : public AuraScript +{ + PrepareAuraScript(spell_gen_black_bow_of_the_betrayer); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ 29471, 27526 }); + } + + void HandleProc(ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* target = GetTarget(); + Unit* victim = eventInfo.GetActionTarget(); + + if (target->IsAlive()) + target->CastSpell(target, 29471, true); + if (victim && victim->IsAlive()) + target->CastSpell(victim, 27526, true); + } + + void Register() override + { + OnProc += AuraProcFn(spell_gen_black_bow_of_the_betrayer::HandleProc); + } +}; + // 35475 Drums of War // 35476 Drums of Battle // 35478 Drums of Restoration @@ -5722,6 +6106,7 @@ void AddSC_generic_spell_scripts() { RegisterSpellScript(spell_silithyst); RegisterSpellScript(spell_gen_5000_gold); + RegisterSpellScript(spell_gen_arena_drink); RegisterSpellScript(spell_gen_model_visible); RegisterSpellScript(spell_the_flag_of_ownership); RegisterSpellScript(spell_gen_have_item_auras); @@ -5893,5 +6278,15 @@ void AddSC_generic_spell_scripts() RegisterSpellScript(spell_gen_bm_on); RegisterSpellScript(spell_gen_bm_off); RegisterSpellScript(spell_gen_whisper_to_controller); + RegisterSpellScript(spell_gen_vampiric_touch); + // Boss and item proc scripts + RegisterSpellScript(spell_gen_petrified_bark); + RegisterSpellScript(spell_gen_earth_shield_toc); + RegisterSpellScript(spell_gen_retaliation_toc); + RegisterSpellScript(spell_gen_overlords_brand); + RegisterSpellScript(spell_gen_overlords_brand_dot); + RegisterSpellScript(spell_gen_vampiric_might); + RegisterSpellScript(spell_gen_mirrored_soul); + RegisterSpellScript(spell_gen_black_bow_of_the_betrayer); RegisterSpellScript(spell_gen_filter_party_level_80); } diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 7ebf33999..c116241a8 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -68,6 +68,25 @@ enum HunterSpells SPELL_LOCK_AND_LOAD_TRIGGER = 56453, SPELL_LOCK_AND_LOAD_MARKER = 67544, SPELL_HUNTER_PET_LEGGINGS_OF_BEAST_MASTERY = 38297, // Leggings of Beast Mastery + + // Proc system spells + SPELL_HUNTER_THRILL_OF_THE_HUNT_MANA = 34720, + SPELL_HUNTER_REPLENISHMENT = 57669, + SPELL_HUNTER_RAPID_RECUPERATION_R1 = 56654, + SPELL_HUNTER_RAPID_RECUPERATION_R2 = 58882, + SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS = 57894, + SPELL_HUNTER_KILL_COMMAND_HUNTER = 34026, + SPELL_HUNTER_RAPID_RECUPERATION_MANA_R1 = 56654, + SPELL_HUNTER_RAPID_RECUPERATION_MANA_R2 = 58882, + SPELL_HUNTER_PIERCING_SHOTS = 63468, + SPELL_HUNTER_T9_4P_GREATNESS = 68130 +}; + +enum HunterSpellIcons +{ + HUNTER_ICON_THRILL_OF_THE_HUNT = 2236, + HUNTER_ICON_HUNTING_PARTY = 3406, + HUNTER_ICON_RAPID_RECUPERATION = 3560 }; class spell_hun_check_pet_los : public SpellScript @@ -738,18 +757,15 @@ class spell_hun_sniper_training : public AuraScript PreventDefaultAction(); if (aurEff->GetAmount() <= 0) { - if (!GetCaster() || !GetTarget()) - { - return; - } - Unit* target = GetTarget(); - uint32 spellId = SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 + GetId() - SPELL_HUNTER_SNIPER_TRAINING_R1; - if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(spellId)) + target->CastSpell(target, spellId, true, nullptr, aurEff); + + if (Player* playerTarget = GetUnitOwner()->ToPlayer()) { - Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(GetSpellInfo()) ? GetCaster() : target; - triggerCaster->CastSpell(target, triggeredSpellInfo, true, 0, aurEff); + int32 baseAmount = aurEff->GetBaseAmount(); + int32 amount = playerTarget->CalculateSpellDamage(playerTarget, GetSpellInfo(), aurEff->GetEffIndex(), &baseAmount); + GetEffect(EFFECT_0)->SetAmount(amount); } } } @@ -759,7 +775,7 @@ class spell_hun_sniper_training : public AuraScript if (Player* playerTarget = GetUnitOwner()->ToPlayer()) { int32 baseAmount = aurEff->GetBaseAmount(); - int32 amount = playerTarget->isMoving() || aurEff->GetAmount() <= 0 ? + int32 amount = playerTarget->isMoving() ? playerTarget->CalculateSpellDamage(playerTarget, GetSpellInfo(), aurEff->GetEffIndex(), &baseAmount) : aurEff->GetAmount() - 1; aurEff->SetAmount(amount); @@ -1151,11 +1167,6 @@ private: WorldObject* _target = nullptr; }; -enum LocknLoadSpells -{ - SPELL_FROST_TRAP_SLOW = 67035 -}; - // -56342 - Lock and Load class spell_hun_lock_and_load : public AuraScript { @@ -1163,103 +1174,58 @@ class spell_hun_lock_and_load : public AuraScript bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_LOCK_AND_LOAD_TRIGGER, SPELL_LOCK_AND_LOAD_MARKER, SPELL_FROST_TRAP_SLOW }); + return ValidateSpellInfo( + { + SPELL_LOCK_AND_LOAD_TRIGGER, + SPELL_LOCK_AND_LOAD_MARKER + }); } - bool CheckTrapProc(ProcEventInfo& eventInfo) + bool CheckProc(ProcEventInfo& eventInfo) { - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || !eventInfo.GetActor()) - { + if (eventInfo.GetActor()->HasAura(SPELL_LOCK_AND_LOAD_MARKER)) return false; - } - - // Black Arrow and Fire traps may trigger on periodic tick only. - if (((spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FIRE) || (spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_SHADOW)) - && (spellInfo->Effects[0].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE || spellInfo->Effects[1].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE)) - { - return true; - } - - return IsTargetValid(spellInfo, eventInfo.GetProcTarget()) && !eventInfo.GetActor()->HasAura(SPELL_LOCK_AND_LOAD_MARKER); - } - - bool IsTargetValid(SpellInfo const* spellInfo, Unit* target) - { - if (!spellInfo || !target) - { - return false; - } - - // Don't check it for fire traps and black arrow, they proc on periodic only and not spell hit. - // So it's wrong to check for immunity, it was already checked when the spell was applied. - if ((spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FIRE) || (spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_SHADOW)) - { - return false; - } - - // HitMask for Frost Trap can't be checked correctly as it is. - // That's because the talent is triggered by the spell that fires the trap (63487)... - // ...and not the actual spell that applies the slow effect (67035). - // So the IMMUNE result is never sent by the spell that triggers this. - if (spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_NATURE) - { - if (SpellInfo const* triggerSpell = sSpellMgr->GetSpellInfo(SPELL_FROST_TRAP_SLOW)) - { - return !target->IsImmunedToSpell(triggerSpell); - } - } - return true; } - template - void HandleProcs(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + bool CheckTrapProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + if (!(eventInfo.GetTypeMask() & PROC_FLAG_DONE_TRAP_ACTIVATION)) + return false; + + // Do not proc on traps for immolation/explosive trap + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || !(spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST)) + return false; + + return roll_chance_i(aurEff->GetAmount()); + } + + bool CheckPeriodicProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + if (!(eventInfo.GetTypeMask() & PROC_FLAG_DONE_PERIODIC)) + return false; + + return roll_chance_i(aurEff->GetAmount()); + } + + void HandleProc(ProcEventInfo& eventInfo) { PreventDefaultAction(); - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - - if (!(eventInfo.GetTypeMask() & mask) || !spellInfo) - { - return; - } - - // Also check if the proc from the fire traps and black arrow actually comes from the periodic ticks here. - // Normally this wouldn't be required, but we are circumventing the current proc system limitations. - if (((spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FIRE) || (spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_SHADOW)) - && (spellInfo->Effects[0].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE || spellInfo->Effects[1].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE) - && !(mask & PROC_FLAG_DONE_PERIODIC)) - { - return; - } - - if (!roll_chance_i(aurEff->GetAmount())) - { - return; - } - Unit* caster = eventInfo.GetActor(); caster->CastSpell(caster, SPELL_LOCK_AND_LOAD_TRIGGER, true); - } - - void ApplyMarker(ProcEventInfo& eventInfo) - { - if (IsTargetValid(eventInfo.GetSpellInfo(), eventInfo.GetProcTarget())) - { - Unit* caster = eventInfo.GetActor(); - caster->CastSpell(caster, SPELL_LOCK_AND_LOAD_MARKER, true); - } + caster->CastSpell(caster, SPELL_LOCK_AND_LOAD_MARKER, true); } void Register() override { - DoCheckProc += AuraCheckProcFn(spell_hun_lock_and_load::CheckTrapProc); + DoCheckProc += AuraCheckProcFn(spell_hun_lock_and_load::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_hun_lock_and_load::HandleProcs, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - OnEffectProc += AuraEffectProcFn(spell_hun_lock_and_load::HandleProcs, EFFECT_1, SPELL_AURA_DUMMY); + DoCheckEffectProc += AuraCheckEffectProcFn(spell_hun_lock_and_load::CheckTrapProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + DoCheckEffectProc += AuraCheckEffectProcFn(spell_hun_lock_and_load::CheckPeriodicProc, EFFECT_1, SPELL_AURA_DUMMY); - AfterProc += AuraProcFn(spell_hun_lock_and_load::ApplyMarker); + OnProc += AuraProcFn(spell_hun_lock_and_load::HandleProc); } }; @@ -1343,6 +1309,159 @@ class spell_hun_target_self_and_pet : public SpellScript } }; +// -34497 - Thrill of the Hunt +class spell_hun_thrill_of_the_hunt : public AuraScript +{ + PrepareAuraScript(spell_hun_thrill_of_the_hunt); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HUNTER_THRILL_OF_THE_HUNT_MANA }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + if (!procSpell) + return; + + Unit* caster = GetTarget(); + if (!caster->IsPlayer()) + return; + + int32 mana = 0; + + Spell* spell = caster->ToPlayer()->m_spellModTakingSpell; + + // Disable charge drop because of Lock and Load + if (spell) + caster->ToPlayer()->SetSpellModTakingSpell(spell, false); + + // Explosive Shot + if (procSpell->SpellFamilyFlags[2] & 0x200) + { + Unit* victim = eventInfo.GetActionTarget(); + if (!victim) + { + if (spell) + caster->ToPlayer()->SetSpellModTakingSpell(spell, true); + return; + } + if (AuraEffect const* pEff = victim->GetAuraEffect(SPELL_AURA_PERIODIC_DUMMY, SPELLFAMILY_HUNTER, 0x0, 0x80000000, 0x0, caster->GetGUID())) + mana = pEff->GetSpellInfo()->CalcPowerCost(caster, SpellSchoolMask(pEff->GetSpellInfo()->SchoolMask)) * 4 / 10 / 3; + } + else + mana = procSpell->CalcPowerCost(caster, SpellSchoolMask(procSpell->SchoolMask)) * 4 / 10; + + if (spell) + caster->ToPlayer()->SetSpellModTakingSpell(spell, true); + + if (mana <= 0) + return; + + caster->CastCustomSpell(SPELL_HUNTER_THRILL_OF_THE_HUNT_MANA, SPELLVALUE_BASE_POINT0, mana, caster, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_hun_thrill_of_the_hunt::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -53290 - Hunting Party +class spell_hun_hunting_party : public AuraScript +{ + PrepareAuraScript(spell_hun_hunting_party); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HUNTER_REPLENISHMENT }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_HUNTER_REPLENISHMENT, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_hun_hunting_party::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -53228 - Rapid Recuperation +class spell_hun_rapid_recuperation : public AuraScript +{ + PrepareAuraScript(spell_hun_rapid_recuperation); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HUNTER_RAPID_RECUPERATION_R1, SPELL_HUNTER_RAPID_RECUPERATION_R2 }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + if (!procSpell) + return false; + + // This effect only from Rapid Killing (mana regen) + return (procSpell->SpellFamilyFlags[1] & 0x01000000) != 0; + } + + void HandleProc(ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + uint32 triggeredSpell = 0; + switch (GetSpellInfo()->Id) + { + case 53228: // Rank 1 + triggeredSpell = SPELL_HUNTER_RAPID_RECUPERATION_R1; + break; + case 53232: // Rank 2 + triggeredSpell = SPELL_HUNTER_RAPID_RECUPERATION_R2; + break; + default: + return; + } + GetTarget()->CastSpell(GetTarget(), triggeredSpell, true); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_hun_rapid_recuperation::CheckProc); + OnProc += AuraProcFn(spell_hun_rapid_recuperation::HandleProc); + } +}; + +// 57870 - Glyph of Mend Pet +class spell_hun_glyph_of_mend_pet : public AuraScript +{ + PrepareAuraScript(spell_hun_glyph_of_mend_pet); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS }); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* target = eventInfo.GetActionTarget(); + if (!target) + return; + + target->CastSpell(target, SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS, true, nullptr, nullptr, GetTarget()->GetGUID()); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_hun_glyph_of_mend_pet::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + // -53301 - Explosive Shot class spell_hun_explosive_shot : public SpellScript { @@ -1364,6 +1483,153 @@ class spell_hun_explosive_shot : public SpellScript } }; +// 58914 - Kill Command (Pet Aura) +class spell_hun_kill_command_pet : public AuraScript +{ + PrepareAuraScript(spell_hun_kill_command_pet); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HUNTER_KILL_COMMAND_HUNTER }); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + // prevent charge drop (aura has both proc charge and stacks) + PreventDefaultAction(); + + if (Unit* owner = eventInfo.GetActor()->GetOwner()) + owner->RemoveAuraFromStack(SPELL_HUNTER_KILL_COMMAND_HUNTER); + + ModStackAmount(-1); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_hun_kill_command_pet::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -53228 - Rapid Recuperation (trigger) +class spell_hun_rapid_recuperation_trigger : public AuraScript +{ + PrepareAuraScript(spell_hun_rapid_recuperation_trigger); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_HUNTER_RAPID_RECUPERATION_MANA_R1, + SPELL_HUNTER_RAPID_RECUPERATION_MANA_R2 + }); + } + + void HandleRapidFireProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + // Proc only from Rapid Fire + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || !(spellInfo->SpellFamilyFlags[0] & 0x00000020)) + { + PreventDefaultAction(); + return; + } + } + + void HandleRapidKillingProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + static uint32 const triggerSpells[2] = { SPELL_HUNTER_RAPID_RECUPERATION_MANA_R1, SPELL_HUNTER_RAPID_RECUPERATION_MANA_R2 }; + + PreventDefaultAction(); + + // Proc only from Rapid Killing + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || !(spellInfo->SpellFamilyFlags[1] & 0x01000000)) + return; + + uint8 rank = GetSpellInfo()->GetRank(); + if (rank > 0 && rank <= 2) + GetTarget()->CastSpell(GetTarget(), triggerSpells[rank - 1], true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_hun_rapid_recuperation_trigger::HandleRapidFireProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + OnEffectProc += AuraEffectProcFn(spell_hun_rapid_recuperation_trigger::HandleRapidKillingProc, EFFECT_1, SPELL_AURA_DUMMY); + } +}; + +// -53234 - Piercing Shots +class spell_hun_piercing_shots : public AuraScript +{ + PrepareAuraScript(spell_hun_piercing_shots); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HUNTER_PIERCING_SHOTS }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetActionTarget() != nullptr; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + DamageInfo* dmgInfo = eventInfo.GetDamageInfo(); + if (!dmgInfo || !dmgInfo->GetDamage()) + return; + + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + SpellInfo const* piercingShots = sSpellMgr->AssertSpellInfo(SPELL_HUNTER_PIERCING_SHOTS); + int32 bp = CalculatePct(static_cast(dmgInfo->GetDamage()), aurEff->GetAmount()); + + ASSERT(piercingShots->GetMaxTicks() > 0); + bp /= piercingShots->GetMaxTicks(); + + caster->CastCustomSpell(target, SPELL_HUNTER_PIERCING_SHOTS, &bp, nullptr, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_hun_piercing_shots::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_hun_piercing_shots::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 67151 - Item - Hunter T9 4P Bonus (Steady Shot) +class spell_hun_t9_4p_bonus : public AuraScript +{ + PrepareAuraScript(spell_hun_t9_4p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HUNTER_T9_4P_GREATNESS }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Unit* actor = eventInfo.GetActor(); + return actor && actor->IsPlayer() && actor->ToPlayer()->GetPet(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + caster->CastSpell(caster->ToPlayer()->GetPet(), SPELL_HUNTER_T9_4P_GREATNESS, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_hun_t9_4p_bonus::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_hun_t9_4p_bonus::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + void AddSC_hunter_spell_scripts() { RegisterSpellScript(spell_hun_check_pet_los); @@ -1396,4 +1662,13 @@ void AddSC_hunter_spell_scripts() RegisterSpellScript(spell_hun_bestial_wrath); RegisterSpellScript(spell_hun_target_self_and_pet); RegisterSpellScript(spell_hun_explosive_shot); + RegisterSpellScript(spell_hun_thrill_of_the_hunt); + RegisterSpellScript(spell_hun_hunting_party); + RegisterSpellScript(spell_hun_rapid_recuperation); + RegisterSpellScript(spell_hun_glyph_of_mend_pet); + // Proc system scripts + RegisterSpellScript(spell_hun_kill_command_pet); + RegisterSpellScript(spell_hun_piercing_shots); + RegisterSpellScript(spell_hun_rapid_recuperation_trigger); + RegisterSpellScript(spell_hun_t9_4p_bonus); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index d3fcc55b9..e6dd1fcad 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -39,6 +39,240 @@ enum MassiveSeaforiumCharge ITEM_MASSIVE_SEAFORIUM_CHARGE = 39213, }; +enum AlchemistStone +{ + SPELL_ALCHEMISTS_STONE_EXTRA_HEAL = 21399, + SPELL_ALCHEMISTS_STONE_EXTRA_MANA = 21400 +}; + +enum DarkmoonCardGreatness +{ + SPELL_DARKMOON_CARD_STRENGTH = 60229, + SPELL_DARKMOON_CARD_AGILITY = 60233, + SPELL_DARKMOON_CARD_INTELLECT = 60234, + SPELL_DARKMOON_CARD_SPIRIT = 60235 +}; + +enum DeathChoice +{ + SPELL_DEATH_CHOICE_NORMAL_AURA = 67702, + SPELL_DEATH_CHOICE_NORMAL_AGILITY = 67703, + SPELL_DEATH_CHOICE_NORMAL_STRENGTH = 67708, + SPELL_DEATH_CHOICE_HEROIC_AURA = 67771, + SPELL_DEATH_CHOICE_HEROIC_AGILITY = 67772, + SPELL_DEATH_CHOICE_HEROIC_STRENGTH = 67773 +}; + +enum TrinketStackSpells +{ + SPELL_LIGHTNING_CAPACITOR_STACK = 37658, + SPELL_LIGHTNING_CAPACITOR_TRIGGER = 37661, + SPELL_THUNDER_CAPACITOR_STACK = 54842, + SPELL_THUNDER_CAPACITOR_TRIGGER = 54843, + SPELL_TOC25_CASTER_TRINKET_NORMAL_STACK = 67713, + SPELL_TOC25_CASTER_TRINKET_NORMAL_TRIGGER = 67714, + SPELL_TOC25_CASTER_TRINKET_HEROIC_STACK = 67759, + SPELL_TOC25_CASTER_TRINKET_HEROIC_TRIGGER = 67760 +}; + +enum SoulPreserver +{ + SPELL_SOUL_PRESERVER_DRUID = 60512, + SPELL_SOUL_PRESERVER_PALADIN = 60513, + SPELL_SOUL_PRESERVER_PRIEST = 60514, + SPELL_SOUL_PRESERVER_SHAMAN = 60515 +}; + +enum LivingRootOfTheWildheart +{ + SPELL_LIVING_ROOT_BEAR = 37340, + SPELL_LIVING_ROOT_CAT = 37341, + SPELL_LIVING_ROOT_TREE = 37342, + SPELL_LIVING_ROOT_MOONKIN = 37343, + SPELL_LIVING_ROOT_NONE = 37344 +}; + +enum CharmWitchDoctor +{ + SPELL_CHARM_WITCH_DOCTOR_PROC = 43821 +}; + +enum LifegivingGem +{ + SPELL_GIFT_OF_LIFE_1 = 23782, + SPELL_GIFT_OF_LIFE_2 = 23783 +}; + +enum ManaDrain +{ + SPELL_MANA_DRAIN_ENERGIZE = 29471, + SPELL_MANA_DRAIN_LEECH = 27526 +}; + +enum HourglassSand +{ + SPELL_HOURGLASS_SAND_HEAL = 30554, + SPELL_HOURGLASS_SAND_DAMAGE = 30553 +}; + +enum UltrasafeTransporter +{ + SPELL_TRANSPORTER_MALFUNCTION_SMALL = 36178, + SPELL_TRANSPORTER_MALFUNCTION_BIG = 36183, + SPELL_TRANSPORTER_EVIL_TWIN = 23445, + SPELL_TELEPORT_TOSHLEY_STATION = 35974 +}; + +enum PowerCircle +{ + SPELL_LIMITLESS_POWER = 45044 +}; + +enum AuraOfMadness +{ + SPELL_SOCIOPATH = 39511, + SPELL_DELUSIONAL = 40997, + SPELL_KLEPTOMANIA = 40998, + SPELL_MEGALOMANIA = 40999, + SPELL_PARANOIA = 41002, + SPELL_MANIC = 41005, + SPELL_NARCISSISM = 41009, + SPELL_MARTYR_COMPLEX = 41011, + SPELL_DEMENTIA = 41404, + SPELL_DEMENTIA_POS = 41406, + SPELL_DEMENTIA_NEG = 41409, + SAY_MADNESS = 21954 +}; + +enum DeadlyPrecision +{ + SPELL_DEADLY_PRECISION = 71564 +}; + +enum DeathbringersWill +{ + SPELL_STRENGTH_OF_THE_TAUNKA = 71484, + SPELL_AGILITY_OF_THE_VRYKUL = 71485, + SPELL_POWER_OF_THE_TAUNKA = 71486, + SPELL_AIM_OF_THE_IRON_DWARVES = 71491, + SPELL_SPEED_OF_THE_VRYKUL = 71492, + SPELL_AGILITY_OF_THE_VRYKUL_HERO = 71556, + SPELL_POWER_OF_THE_TAUNKA_HERO = 71558, + SPELL_AIM_OF_THE_IRON_DWARVES_HERO = 71559, + SPELL_SPEED_OF_THE_VRYKUL_HERO = 71560, + SPELL_STRENGTH_OF_THE_TAUNKA_HERO = 71561 +}; + +enum DiscerningEyeBeastMisc +{ + SPELL_DISCERNING_EYE_BEAST = 59914 +}; + +enum FrozenShadoweave +{ + SPELL_SHADOWMEND = 39373 +}; + +enum IdolOfLongevity +{ + SPELL_HEALING_TOUCH_MANA = 28848 +}; + +enum Heartpierce +{ + SPELL_INVIGORATION_MANA = 71881, + SPELL_INVIGORATION_ENERGY = 71882, + SPELL_INVIGORATION_RAGE = 71883, + SPELL_INVIGORATION_RP = 71884, + SPELL_INVIGORATION_RP_HERO = 71885, + SPELL_INVIGORATION_RAGE_HERO = 71886, + SPELL_INVIGORATION_ENERGY_HERO = 71887, + SPELL_INVIGORATION_MANA_HERO = 71888 +}; + +enum MarkOfConquest +{ + SPELL_MARK_OF_CONQUEST_ENERGIZE = 33671 +}; + +enum PersistentShieldMisc +{ + SPELL_PERSISTENT_SHIELD_TRIGGERED = 26470 +}; + +enum PetHealing +{ + SPELL_HEALTH_LINK = 37382 +}; + +enum RestlessStrength +{ + SPELL_RESTLESS_STRENGTH = 24662 +}; + +enum UnstablePower +{ + SPELL_UNSTABLE_POWER_AURA = 24659 +}; + +enum CommendationOfKaelthas +{ + SPELL_COMMENDATION_OF_KAELTHAS = 45480 +}; + +enum CorpseTongueCoin +{ + SPELL_CORPSE_TONGUE_COIN = 71633, + SPELL_CORPSE_TONGUE_COIN_HERO = 71634 +}; + +enum CrystalSpireOfKarabor +{ + SPELL_CRYSTAL_SPIRE_OF_KARABOR_MANA = 35476 +}; + +enum SoulHarvestersCharm +{ + SPELL_SOUL_HARVESTERS_CHARM = 60513 +}; + +enum SunwellExaltedNeck +{ + SPELL_LIGHTS_WRATH = 45479, + SPELL_ARCANE_BOLT = 45429, + SPELL_LIGHTS_STRENGTH = 45480, + SPELL_LIGHTS_WARD = 45432 +}; + +enum SwiftHandOfJustice +{ + SPELL_SWIFT_HAND_OF_JUSTICE_HEAL = 59914 +}; + +enum TinyAbominationInAJar +{ + SPELL_MOTE_OF_ANGER = 71432, + SPELL_MANIFEST_ANGER_MAIN_HAND = 71433, + SPELL_MANIFEST_ANGER_OFF_HAND = 71434 +}; + +enum TotemOfFlowingWater +{ + SPELL_TOTEM_OF_FLOWING_WATER_MANA = 28857 +}; + +enum PetrifiedTwilightScale +{ + SPELL_PETRIFIED_TWILIGHT_SCALE_HC = 75480, + SPELL_PETRIFIED_TWILIGHT_SCALE = 75477 +}; + +enum ShardOfTheScale +{ + SPELL_PURIFIED_CAUTERIZING_HEAL = 69733, + SPELL_SHINY_SEARING_FLAMES = 69729 +}; + class spell_item_massive_seaforium_charge : public SpellScript { PrepareSpellScript(spell_item_massive_seaforium_charge); @@ -4293,6 +4527,1671 @@ class spell_item_bloodsail_admiral_hat : public AuraScript } }; +// 17619 - Alchemist's Stone +class spell_item_alchemists_stone : public AuraScript +{ + PrepareAuraScript(spell_item_alchemists_stone); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ALCHEMISTS_STONE_EXTRA_HEAL, SPELL_ALCHEMISTS_STONE_EXTRA_MANA }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return; + + Unit* caster = eventInfo.GetActionTarget(); + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + uint32 spellId; + int32 bp0; + switch (spellInfo->Effects[i].Effect) + { + case SPELL_EFFECT_HEAL: + spellId = SPELL_ALCHEMISTS_STONE_EXTRA_HEAL; + bp0 = CalculatePct(spellInfo->Effects[i].CalcValue(caster), 40); + break; + case SPELL_EFFECT_ENERGIZE: + spellId = SPELL_ALCHEMISTS_STONE_EXTRA_MANA; + bp0 = CalculatePct(spellInfo->Effects[i].CalcValue(caster), 40); + break; + default: + continue; + } + caster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, bp0, nullptr, true, nullptr, aurEff); + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_alchemists_stone::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 57345 - Darkmoon Card: Greatness +class spell_item_darkmoon_card_greatness : public AuraScript +{ + PrepareAuraScript(spell_item_darkmoon_card_greatness); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_DARKMOON_CARD_STRENGTH, + SPELL_DARKMOON_CARD_AGILITY, + SPELL_DARKMOON_CARD_INTELLECT, + SPELL_DARKMOON_CARD_SPIRIT + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + float str = caster->GetStat(STAT_STRENGTH); + float agi = caster->GetStat(STAT_AGILITY); + float intl = caster->GetStat(STAT_INTELLECT); + float spi = caster->GetStat(STAT_SPIRIT); + float stat = 0.0f; + + uint32 spellTrigger = SPELL_DARKMOON_CARD_STRENGTH; + + if (str > stat) + { + spellTrigger = SPELL_DARKMOON_CARD_STRENGTH; + stat = str; + } + + if (agi > stat) + { + spellTrigger = SPELL_DARKMOON_CARD_AGILITY; + stat = agi; + } + + if (intl > stat) + { + spellTrigger = SPELL_DARKMOON_CARD_INTELLECT; + stat = intl; + } + + if (spi > stat) + { + spellTrigger = SPELL_DARKMOON_CARD_SPIRIT; + } + + caster->CastSpell(caster, spellTrigger, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_darkmoon_card_greatness::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 67702, 67771 - Death's Choice/Death's Verdict +class spell_item_death_choice : public AuraScript +{ + PrepareAuraScript(spell_item_death_choice); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_DEATH_CHOICE_NORMAL_STRENGTH, + SPELL_DEATH_CHOICE_NORMAL_AGILITY, + SPELL_DEATH_CHOICE_HEROIC_STRENGTH, + SPELL_DEATH_CHOICE_HEROIC_AGILITY + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + float str = caster->GetStat(STAT_STRENGTH); + float agi = caster->GetStat(STAT_AGILITY); + + switch (aurEff->GetId()) + { + case SPELL_DEATH_CHOICE_NORMAL_AURA: + if (str > agi) + caster->CastSpell(caster, SPELL_DEATH_CHOICE_NORMAL_STRENGTH, true, nullptr, aurEff); + else + caster->CastSpell(caster, SPELL_DEATH_CHOICE_NORMAL_AGILITY, true, nullptr, aurEff); + break; + case SPELL_DEATH_CHOICE_HEROIC_AURA: + if (str > agi) + caster->CastSpell(caster, SPELL_DEATH_CHOICE_HEROIC_STRENGTH, true, nullptr, aurEff); + else + caster->CastSpell(caster, SPELL_DEATH_CHOICE_HEROIC_AGILITY, true, nullptr, aurEff); + break; + default: + break; + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_death_choice::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 37657 - The Lightning Capacitor +// 54841 - Thunder Capacitor +// 67712 - Item - Coliseum 25 Normal Caster Trinket +// 67758 - Item - Coliseum 25 Heroic Caster Trinket +template +class spell_item_trinket_stack : public AuraScript +{ + PrepareAuraScript(spell_item_trinket_stack); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ StackSpell, TriggerSpell }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + + caster->CastSpell(caster, StackSpell, aurEff); + + Aura* dummy = caster->GetAura(StackSpell); + + if (!dummy || dummy->GetStackAmount() < aurEff->GetAmount()) + return; + + caster->RemoveAurasDueToSpell(StackSpell); + if (Unit* target = eventInfo.GetActionTarget()) + caster->CastSpell(target, TriggerSpell, aurEff); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(StackSpell); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_trinket_stack::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + AfterEffectRemove += AuraEffectRemoveFn(spell_item_trinket_stack::OnRemove, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } +}; + +using spell_item_lightning_capacitor = spell_item_trinket_stack; +using spell_item_thunder_capacitor = spell_item_trinket_stack; +using spell_item_toc25_caster_trinket_normal = spell_item_trinket_stack; +using spell_item_toc25_caster_trinket_heroic = spell_item_trinket_stack; + +// 60510 - Soul Preserver +class spell_item_soul_preserver : public AuraScript +{ + PrepareAuraScript(spell_item_soul_preserver); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_SOUL_PRESERVER_DRUID, + SPELL_SOUL_PRESERVER_PALADIN, + SPELL_SOUL_PRESERVER_PRIEST, + SPELL_SOUL_PRESERVER_SHAMAN + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + + switch (caster->getClass()) + { + case CLASS_DRUID: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_DRUID, true, nullptr, aurEff); + break; + case CLASS_PALADIN: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_PALADIN, true, nullptr, aurEff); + break; + case CLASS_PRIEST: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_PRIEST, true, nullptr, aurEff); + break; + case CLASS_SHAMAN: + caster->CastSpell(caster, SPELL_SOUL_PRESERVER_SHAMAN, true, nullptr, aurEff); + break; + default: + break; + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_soul_preserver::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 43820 - Amani Charm of the Witch Doctor +class spell_item_charm_witch_doctor : public AuraScript +{ + PrepareAuraScript(spell_item_charm_witch_doctor); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_CHARM_WITCH_DOCTOR_PROC }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + if (Unit* target = eventInfo.GetActionTarget()) + { + int32 bp = CalculatePct(target->GetCreateHealth(), GetSpellInfo()->GetEffect(EFFECT_1).CalcValue()); + eventInfo.GetActor()->CastCustomSpell(SPELL_CHARM_WITCH_DOCTOR_PROC, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_charm_witch_doctor::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 23725 - Gift of Life (Lifegiving Gem) +class spell_item_lifegiving_gem : public SpellScript +{ + PrepareSpellScript(spell_item_lifegiving_gem); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_GIFT_OF_LIFE_1, SPELL_GIFT_OF_LIFE_2 }); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, SPELL_GIFT_OF_LIFE_1, true); + caster->CastSpell(caster, SPELL_GIFT_OF_LIFE_2, true); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_lifegiving_gem::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 27522, 40336 - Mana Drain +class spell_item_mana_drain : public AuraScript +{ + PrepareAuraScript(spell_item_mana_drain); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MANA_DRAIN_ENERGIZE, SPELL_MANA_DRAIN_LEECH }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + if (caster->IsAlive()) + caster->CastSpell(caster, SPELL_MANA_DRAIN_ENERGIZE, true, nullptr, aurEff); + + if (target && target->IsAlive()) + caster->CastSpell(target, SPELL_MANA_DRAIN_LEECH, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_mana_drain::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 13180 - Gnomish Mind Control Cap +class spell_item_mind_control_cap : public SpellScript +{ + PrepareSpellScript(spell_item_mind_control_cap); + + bool Load() override + { + if (!GetCastItem()) + return false; + return GetCaster()->IsPlayer(); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) + { + if (roll_chance_i(95)) + caster->CastSpell(target, roll_chance_i(50) ? 13181 : 13181, GetCastItem()); + else + target->CastSpell(caster, 13181, true); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_mind_control_cap::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 30536 - Hourglass Sand +class spell_item_hourglass_sand : public SpellScript +{ + PrepareSpellScript(spell_item_hourglass_sand); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HOURGLASS_SAND_HEAL, SPELL_HOURGLASS_SAND_DAMAGE }); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), GetCaster()->IsFriendlyTo(GetHitUnit()) ? SPELL_HOURGLASS_SAND_HEAL : SPELL_HOURGLASS_SAND_DAMAGE, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_hourglass_sand::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 36941 - Ultrasafe Transporter: Toshley's Station +class spell_item_ultrasafe_transporter : public SpellScript +{ + PrepareSpellScript(spell_item_ultrasafe_transporter); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_TRANSPORTER_MALFUNCTION_SMALL, SPELL_TRANSPORTER_MALFUNCTION_BIG, SPELL_TRANSPORTER_EVIL_TWIN, SPELL_TELEPORT_TOSHLEY_STATION }); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, SPELL_TELEPORT_TOSHLEY_STATION, true); + if (roll_chance_i(5)) + caster->CastSpell(caster, RAND(SPELL_TRANSPORTER_MALFUNCTION_SMALL, SPELL_TRANSPORTER_MALFUNCTION_BIG, SPELL_TRANSPORTER_EVIL_TWIN), true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_ultrasafe_transporter::HandleDummy, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); + } +}; + +// 45043 - Power Circle (Mage T5 Set Bonus) +class spell_item_power_circle : public AuraScript +{ + PrepareAuraScript(spell_item_power_circle); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_LIMITLESS_POWER }); + } + + void OnAuraInit() + { + Unit* caster = GetCaster(); + if (!caster) + return; + + caster->CastSpell(caster, SPELL_LIMITLESS_POWER, true); + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_LIMITLESS_POWER); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_item_power_circle::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +enum ThrallmarAndHonorHoldFavor +{ + SPELL_BUFFBOT_BUFF_EFFECT = 32172 +}; + +// 32096 - Thrallmar's Favor +// 32098 - Honor Hold's Favor +class spell_item_thrallmar_and_honor_hold_favor : public AuraScript +{ + PrepareAuraScript(spell_item_thrallmar_and_honor_hold_favor); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_BUFFBOT_BUFF_EFFECT }); + } + + void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->CastSpell(GetTarget(), SPELL_BUFFBOT_BUFF_EFFECT, true); + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_BUFFBOT_BUFF_EFFECT); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_item_thrallmar_and_honor_hold_favor::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_item_thrallmar_and_honor_hold_favor::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +enum DrumsOfForgottenKings +{ + SPELL_BLESSING_OF_FORGOTTEN_KINGS = 72586 +}; + +// 69378 - Blessing of Forgotten Kings +class spell_item_drums_of_forgotten_kings : public SpellScript +{ + PrepareSpellScript(spell_item_drums_of_forgotten_kings); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_BLESSING_OF_FORGOTTEN_KINGS }); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_BLESSING_OF_FORGOTTEN_KINGS, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_drums_of_forgotten_kings::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +enum DrumsOfTheWild +{ + SPELL_GIFT_OF_THE_WILD = 72588 +}; + +// 69381 - Gift of the Wild +class spell_item_drums_of_the_wild : public SpellScript +{ + PrepareSpellScript(spell_item_drums_of_the_wild); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_GIFT_OF_THE_WILD }); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_GIFT_OF_THE_WILD, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_drums_of_the_wild::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +enum DarkmoonCardIllusion +{ + SPELL_DARKMOON_CARD_ILLUSION = 60242 +}; + +// 57350 - Illusionary Barrier +class spell_item_darkmoon_card_illusion : public AuraScript +{ + PrepareAuraScript(spell_item_darkmoon_card_illusion); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DARKMOON_CARD_ILLUSION }); + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->CastSpell(GetTarget(), SPELL_DARKMOON_CARD_ILLUSION, true); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_item_darkmoon_card_illusion::AfterRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 28374 - Mad Alchemist's Potion +class spell_item_mad_alchemists_potion : public SpellScript +{ + PrepareSpellScript(spell_item_mad_alchemists_potion); + + void SecondaryEffect() + { + std::vector availableElixirs = + { + // Battle Elixirs + 33720, // Onslaught Elixir + 54452, // Adept's Elixir + 33726, // Elixir of Mastery + 28490, // Elixir of Major Strength + 28491, // Elixir of Healing Power + 28493, // Elixir of Major Frost Power + 54494, // Elixir of Major Agility + 28501, // Elixir of Major Firepower + 28503, // Elixir of Major Shadow Power + 38954, // Fel Strength Elixir + // Guardian Elixirs + 39625, // Elixir of Major Fortitude + 39626, // Earthen Elixir + 39627, // Elixir of Draenic Wisdom + 39628, // Elixir of Ironskin + 28502, // Elixir of Major Defense + 28514, // Elixir of Empowerment + // Other + 28489, // Elixir of Camouflage + 28496 // Elixir of the Searching Eye + }; + + Unit* target = GetCaster(); + + if (target->getPowerType() == POWER_MANA) + availableElixirs.push_back(28509); // Elixir of Major Mageblood + + uint32 chosenElixir = Acore::Containers::SelectRandomContainerElement(availableElixirs); + + bool useElixir = true; + + SpellGroup chosenSpellGroup = SPELL_GROUP_NONE; + if (sSpellMgr->IsSpellMemberOfSpellGroup(chosenElixir, SPELL_GROUP_ELIXIR_BATTLE)) + chosenSpellGroup = SPELL_GROUP_ELIXIR_BATTLE; + if (sSpellMgr->IsSpellMemberOfSpellGroup(chosenElixir, SPELL_GROUP_ELIXIR_GUARDIAN)) + chosenSpellGroup = SPELL_GROUP_ELIXIR_GUARDIAN; + + if (chosenSpellGroup != SPELL_GROUP_NONE) + { + Unit::AuraApplicationMap const& auraMap = target->GetAppliedAuras(); + for (auto itr = auraMap.begin(); itr != auraMap.end(); ++itr) + { + uint32 spellId = itr->second->GetBase()->GetId(); + if (sSpellMgr->IsSpellMemberOfSpellGroup(spellId, chosenSpellGroup) && spellId != chosenElixir) + { + useElixir = false; + break; + } + } + } + + if (useElixir) + target->CastSpell(target, chosenElixir, GetCastItem()); + } + + void Register() override + { + AfterCast += SpellCastFn(spell_item_mad_alchemists_potion::SecondaryEffect); + } +}; + +// 47770 - Roll 'dem Bones +class spell_item_decahedral_dwarven_dice : public SpellScript +{ + PrepareSpellScript(spell_item_decahedral_dwarven_dice); + + enum + { + TEXT_DECAHEDRAL_DWARVEN_DICE = 26147 + }; + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sObjectMgr->GetBroadcastText(TEXT_DECAHEDRAL_DWARVEN_DICE)) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->IsPlayer(); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->TextEmote(TEXT_DECAHEDRAL_DWARVEN_DICE, GetHitUnit()); + + static uint32 const minimum = 1; + static uint32 const maximum = 100; + + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_decahedral_dwarven_dice::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +// 39446 - Aura of Madness +class spell_item_aura_of_madness : public AuraScript +{ + PrepareAuraScript(spell_item_aura_of_madness); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_MEGALOMANIA, + SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA + }) && sObjectMgr->GetBroadcastText(SAY_MADNESS); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + static std::vector const triggeredSpells[MAX_CLASSES] = + { + //CLASS_NONE + { }, + //CLASS_WARRIOR + { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, + //CLASS_PALADIN + { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_HUNTER + { SPELL_DELUSIONAL, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_ROGUE + { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, + //CLASS_PRIEST + { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_DEATH_KNIGHT + { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, + //CLASS_SHAMAN + { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_MAGE + { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_WARLOCK + { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, + //CLASS_UNK + { }, + //CLASS_DRUID + { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA } + }; + + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + std::vector const& randomSpells = triggeredSpells[caster->getClass()]; + if (randomSpells.empty()) + return; + + uint32 spellId = Acore::Containers::SelectRandomContainerElement(randomSpells); + caster->CastSpell(caster, spellId, true, nullptr, aurEff); + + if (roll_chance_i(10)) + caster->Unit::Say(SAY_MADNESS); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_aura_of_madness::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 41404 - Dementia +class spell_item_dementia : public AuraScript +{ + PrepareAuraScript(spell_item_dementia); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DEMENTIA_POS, SPELL_DEMENTIA_NEG }); + } + + void HandlePeriodicDummy(AuraEffect const* aurEff) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), RAND(SPELL_DEMENTIA_POS, SPELL_DEMENTIA_NEG), true, nullptr, aurEff); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_item_dementia::HandlePeriodicDummy, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +// 71564 - Deadly Precision +// This spell uses STACKS (not charges) - must manually remove stacks on proc +class spell_item_deadly_precision : public AuraScript +{ + PrepareAuraScript(spell_item_deadly_precision); + + void HandleStackDrop(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->RemoveAuraFromStack(GetId(), GetTarget()->GetGUID()); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_deadly_precision::HandleStackDrop, EFFECT_0, SPELL_AURA_MOD_RATING); + } +}; + +// 71563 - Deadly Precision Dummy +class spell_item_deadly_precision_dummy : public SpellScript +{ + PrepareSpellScript(spell_item_deadly_precision_dummy); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DEADLY_PRECISION }); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_DEADLY_PRECISION); + GetCaster()->CastCustomSpell(SPELL_DEADLY_PRECISION, SPELLVALUE_AURA_STACK, spellInfo->StackAmount, GetCaster(), true); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_item_deadly_precision_dummy::HandleDummy, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } +}; + +// 71519 - Deathbringer's Will (Normal) +class spell_item_deathbringers_will_normal : public AuraScript +{ + PrepareAuraScript(spell_item_deathbringers_will_normal); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_STRENGTH_OF_THE_TAUNKA, SPELL_AGILITY_OF_THE_VRYKUL, + SPELL_POWER_OF_THE_TAUNKA, SPELL_AIM_OF_THE_IRON_DWARVES, SPELL_SPEED_OF_THE_VRYKUL + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + static std::vector const triggeredSpells[MAX_CLASSES] = + { + { }, // CLASS_NONE + { SPELL_STRENGTH_OF_THE_TAUNKA, SPELL_AIM_OF_THE_IRON_DWARVES, SPELL_SPEED_OF_THE_VRYKUL }, // CLASS_WARRIOR + { SPELL_STRENGTH_OF_THE_TAUNKA, SPELL_AIM_OF_THE_IRON_DWARVES, SPELL_SPEED_OF_THE_VRYKUL }, // CLASS_PALADIN + { SPELL_AGILITY_OF_THE_VRYKUL, SPELL_AIM_OF_THE_IRON_DWARVES, SPELL_POWER_OF_THE_TAUNKA }, // CLASS_HUNTER + { SPELL_AGILITY_OF_THE_VRYKUL, SPELL_SPEED_OF_THE_VRYKUL, SPELL_POWER_OF_THE_TAUNKA }, // CLASS_ROGUE + { }, // CLASS_PRIEST + { SPELL_STRENGTH_OF_THE_TAUNKA, SPELL_AIM_OF_THE_IRON_DWARVES, SPELL_SPEED_OF_THE_VRYKUL }, // CLASS_DEATH_KNIGHT + { SPELL_AGILITY_OF_THE_VRYKUL, SPELL_SPEED_OF_THE_VRYKUL, SPELL_POWER_OF_THE_TAUNKA }, // CLASS_SHAMAN + { }, // CLASS_MAGE + { }, // CLASS_WARLOCK + { }, // CLASS_UNK + { SPELL_STRENGTH_OF_THE_TAUNKA, SPELL_AGILITY_OF_THE_VRYKUL, SPELL_SPEED_OF_THE_VRYKUL } // CLASS_DRUID + }; + + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + std::vector const& randomSpells = triggeredSpells[caster->getClass()]; + if (randomSpells.empty()) + return; + + uint32 spellId = Acore::Containers::SelectRandomContainerElement(randomSpells); + caster->CastSpell(caster, spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_deathbringers_will_normal::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 71562 - Deathbringer's Will (Heroic) +class spell_item_deathbringers_will_heroic : public AuraScript +{ + PrepareAuraScript(spell_item_deathbringers_will_heroic); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_STRENGTH_OF_THE_TAUNKA_HERO, SPELL_AGILITY_OF_THE_VRYKUL_HERO, + SPELL_POWER_OF_THE_TAUNKA_HERO, SPELL_AIM_OF_THE_IRON_DWARVES_HERO, SPELL_SPEED_OF_THE_VRYKUL_HERO + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + static std::vector const triggeredSpells[MAX_CLASSES] = + { + { }, // CLASS_NONE + { SPELL_STRENGTH_OF_THE_TAUNKA_HERO, SPELL_AIM_OF_THE_IRON_DWARVES_HERO, SPELL_SPEED_OF_THE_VRYKUL_HERO }, // CLASS_WARRIOR + { SPELL_STRENGTH_OF_THE_TAUNKA_HERO, SPELL_AIM_OF_THE_IRON_DWARVES_HERO, SPELL_SPEED_OF_THE_VRYKUL_HERO }, // CLASS_PALADIN + { SPELL_AGILITY_OF_THE_VRYKUL_HERO, SPELL_AIM_OF_THE_IRON_DWARVES_HERO, SPELL_POWER_OF_THE_TAUNKA_HERO }, // CLASS_HUNTER + { SPELL_AGILITY_OF_THE_VRYKUL_HERO, SPELL_SPEED_OF_THE_VRYKUL_HERO, SPELL_POWER_OF_THE_TAUNKA_HERO }, // CLASS_ROGUE + { }, // CLASS_PRIEST + { SPELL_STRENGTH_OF_THE_TAUNKA_HERO, SPELL_AIM_OF_THE_IRON_DWARVES_HERO, SPELL_SPEED_OF_THE_VRYKUL_HERO }, // CLASS_DEATH_KNIGHT + { SPELL_AGILITY_OF_THE_VRYKUL_HERO, SPELL_SPEED_OF_THE_VRYKUL_HERO, SPELL_POWER_OF_THE_TAUNKA_HERO }, // CLASS_SHAMAN + { }, // CLASS_MAGE + { }, // CLASS_WARLOCK + { }, // CLASS_UNK + { SPELL_STRENGTH_OF_THE_TAUNKA_HERO, SPELL_AGILITY_OF_THE_VRYKUL_HERO, SPELL_SPEED_OF_THE_VRYKUL_HERO } // CLASS_DRUID + }; + + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + std::vector const& randomSpells = triggeredSpells[caster->getClass()]; + if (randomSpells.empty()) + return; + + uint32 spellId = Acore::Containers::SelectRandomContainerElement(randomSpells); + caster->CastSpell(caster, spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_deathbringers_will_heroic::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 59915 - Discerning Eye of the Beast Dummy +class spell_item_discerning_eye_beast_dummy : public AuraScript +{ + PrepareAuraScript(spell_item_discerning_eye_beast_dummy); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DISCERNING_EYE_BEAST }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_DISCERNING_EYE_BEAST, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_discerning_eye_beast_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 39372 - Frozen Shadoweave +class spell_item_frozen_shadoweave : public AuraScript +{ + PrepareAuraScript(spell_item_frozen_shadoweave); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHADOWMEND }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + Unit* caster = eventInfo.GetActor(); + int32 bp0 = CalculatePct(static_cast(damageInfo->GetDamage()), aurEff->GetAmount()); + caster->CastCustomSpell(SPELL_SHADOWMEND, SPELLVALUE_BASE_POINT0, bp0, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_frozen_shadoweave::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 28847 - Healing Touch Refund +class spell_item_healing_touch_refund : public AuraScript +{ + PrepareAuraScript(spell_item_healing_touch_refund); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HEALING_TOUCH_MANA }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_HEALING_TOUCH_MANA, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_healing_touch_refund::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 71880 - Heartpierce (Normal) +class spell_item_heartpierce : public AuraScript +{ + PrepareAuraScript(spell_item_heartpierce); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_INVIGORATION_MANA, SPELL_INVIGORATION_ENERGY, + SPELL_INVIGORATION_RAGE, SPELL_INVIGORATION_RP + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + + uint32 spellId; + switch (caster->getPowerType()) + { + case POWER_MANA: + spellId = SPELL_INVIGORATION_MANA; + break; + case POWER_ENERGY: + spellId = SPELL_INVIGORATION_ENERGY; + break; + case POWER_RAGE: + spellId = SPELL_INVIGORATION_RAGE; + break; + case POWER_RUNIC_POWER: + spellId = SPELL_INVIGORATION_RP; + break; + default: + return; + } + + caster->CastSpell(nullptr, spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_heartpierce::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 71892 - Heartpierce (Heroic) +class spell_item_heartpierce_hero : public AuraScript +{ + PrepareAuraScript(spell_item_heartpierce_hero); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_INVIGORATION_MANA_HERO, SPELL_INVIGORATION_ENERGY_HERO, + SPELL_INVIGORATION_RAGE_HERO, SPELL_INVIGORATION_RP_HERO + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + + uint32 spellId; + switch (caster->getPowerType()) + { + case POWER_MANA: + spellId = SPELL_INVIGORATION_MANA_HERO; + break; + case POWER_ENERGY: + spellId = SPELL_INVIGORATION_ENERGY_HERO; + break; + case POWER_RAGE: + spellId = SPELL_INVIGORATION_RAGE_HERO; + break; + case POWER_RUNIC_POWER: + spellId = SPELL_INVIGORATION_RP_HERO; + break; + default: + return; + } + + caster->CastSpell(nullptr, spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_heartpierce_hero::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 33670 - Mark of Conquest +class spell_item_mark_of_conquest : public AuraScript +{ + PrepareAuraScript(spell_item_mark_of_conquest); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MARK_OF_CONQUEST_ENERGIZE }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + if (eventInfo.GetTypeMask() & (PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS)) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_MARK_OF_CONQUEST_ENERGIZE, true, nullptr, aurEff); + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_mark_of_conquest::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 35095 - Pendant of the Violet Eye +class spell_item_pendant_of_the_violet_eye : public AuraScript +{ + PrepareAuraScript(spell_item_pendant_of_the_violet_eye); + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) + return spellInfo->PowerType == POWER_MANA || (spellInfo->ManaCost != 0 || spellInfo->ManaCostPercentage != 0 || spellInfo->ManaCostPerlevel != 0); + + return false; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_pendant_of_the_violet_eye::CheckProc); + } +}; + +// 26467 - Persistent Shield +class spell_item_persistent_shield : public AuraScript +{ + PrepareAuraScript(spell_item_persistent_shield); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PERSISTENT_SHIELD_TRIGGERED }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetHealInfo() && eventInfo.GetHealInfo()->GetHeal(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + int32 bp0 = CalculatePct(static_cast(eventInfo.GetHealInfo()->GetHeal()), 15); + + // Scarab Brooch does not replace stronger shields + if (AuraEffect const* shield = target->GetAuraEffect(SPELL_PERSISTENT_SHIELD_TRIGGERED, EFFECT_0, caster->GetGUID())) + if (shield->GetAmount() > bp0) + return; + + caster->CastCustomSpell(SPELL_PERSISTENT_SHIELD_TRIGGERED, SPELLVALUE_BASE_POINT0, bp0, target, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_persistent_shield::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_persistent_shield::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 37381 - Pet Healing +class spell_item_pet_healing : public AuraScript +{ + PrepareAuraScript(spell_item_pet_healing); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HEALTH_LINK }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + HealInfo* healInfo = eventInfo.GetHealInfo(); + if (!healInfo || !healInfo->GetHeal()) + return; + + Unit* caster = eventInfo.GetActor(); + int32 bp0 = CalculatePct(static_cast(healInfo->GetHeal()), aurEff->GetAmount()); + caster->CastCustomSpell(SPELL_HEALTH_LINK, SPELLVALUE_BASE_POINT0, bp0, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_pet_healing::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 24661 - Restless Strength +class spell_item_restless_strength : public AuraScript +{ + PrepareAuraScript(spell_item_restless_strength); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_RESTLESS_STRENGTH }); + } + + void HandleProc(ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->RemoveAuraFromStack(SPELL_RESTLESS_STRENGTH); + } + + void Register() override + { + OnProc += AuraProcFn(spell_item_restless_strength::HandleProc); + } +}; + +// 24658 - Unstable Power +class spell_item_unstable_power : public AuraScript +{ + PrepareAuraScript(spell_item_unstable_power); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_UNSTABLE_POWER_AURA }); + } + + void HandleProc(ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->RemoveAuraFromStack(SPELL_UNSTABLE_POWER_AURA); + } + + void Register() override + { + OnProc += AuraProcFn(spell_item_unstable_power::HandleProc); + } +}; + +// 45478 - Commendation of Kael'thas +class spell_item_commendation_of_kaelthas : public AuraScript +{ + PrepareAuraScript(spell_item_commendation_of_kaelthas); + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (HealInfo* healInfo = eventInfo.GetHealInfo()) + if (Unit* target = healInfo->GetTarget()) + if (target->GetHealth() + healInfo->GetEffectiveHeal() >= target->GetMaxHealth()) + return true; + return false; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_commendation_of_kaelthas::CheckProc); + } +}; + +// 71632 - Corpse Tongue Coin +class spell_item_corpse_tongue_coin : public AuraScript +{ + PrepareAuraScript(spell_item_corpse_tongue_coin); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_CORPSE_TONGUE_COIN }); + } + + void HandleProc(ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_CORPSE_TONGUE_COIN, true, nullptr, GetEffect(EFFECT_0)); + } + + void Register() override + { + OnProc += AuraProcFn(spell_item_corpse_tongue_coin::HandleProc); + } +}; + +// 71639 - Corpse Tongue Coin (Heroic) +class spell_item_corpse_tongue_coin_heroic : public AuraScript +{ + PrepareAuraScript(spell_item_corpse_tongue_coin_heroic); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_CORPSE_TONGUE_COIN_HERO }); + } + + void HandleProc(ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_CORPSE_TONGUE_COIN_HERO, true, nullptr, GetEffect(EFFECT_0)); + } + + void Register() override + { + OnProc += AuraProcFn(spell_item_corpse_tongue_coin_heroic::HandleProc); + } +}; + +// 34774 - Crystal Spire of Karabor +class spell_item_crystal_spire_of_karabor : public AuraScript +{ + PrepareAuraScript(spell_item_crystal_spire_of_karabor); + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) + return spellInfo->PowerType == POWER_MANA; + return false; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_crystal_spire_of_karabor::CheckProc); + } +}; + +// 60512 - Soul Harvester's Charm +class spell_item_soul_harvesters_charm : public AuraScript +{ + PrepareAuraScript(spell_item_soul_harvesters_charm); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SOUL_HARVESTERS_CHARM }); + } + + void HandleProc(ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_SOUL_HARVESTERS_CHARM, true, nullptr, GetEffect(EFFECT_0)); + } + + void Register() override + { + OnProc += AuraProcFn(spell_item_soul_harvesters_charm::HandleProc); + } +}; + +// 45481 - Sunwell Exalted Caster Neck +class spell_item_sunwell_exalted_caster_neck : public AuraScript +{ + PrepareAuraScript(spell_item_sunwell_exalted_caster_neck); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_LIGHTS_WRATH, SPELL_ARCANE_BOLT }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + uint32 spellId = caster->getClass() == CLASS_PALADIN ? SPELL_LIGHTS_WRATH : SPELL_ARCANE_BOLT; + caster->CastSpell(eventInfo.GetProcTarget(), spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_sunwell_exalted_caster_neck::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 45482 - Sunwell Exalted Healer Neck +class spell_item_sunwell_exalted_healer_neck : public AuraScript +{ + PrepareAuraScript(spell_item_sunwell_exalted_healer_neck); + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetHealInfo() && eventInfo.GetHealInfo()->GetHeal(); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_sunwell_exalted_healer_neck::CheckProc); + } +}; + +// 45483 - Sunwell Exalted Melee Neck +class spell_item_sunwell_exalted_melee_neck : public AuraScript +{ + PrepareAuraScript(spell_item_sunwell_exalted_melee_neck); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_LIGHTS_STRENGTH }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_LIGHTS_STRENGTH, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_sunwell_exalted_melee_neck::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 45484 - Sunwell Exalted Tank Neck +class spell_item_sunwell_exalted_tank_neck : public AuraScript +{ + PrepareAuraScript(spell_item_sunwell_exalted_tank_neck); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_LIGHTS_WARD }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_LIGHTS_WARD, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_sunwell_exalted_tank_neck::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 59906 - Swift Hand of Justice Dummy +class spell_item_swift_hand_justice_dummy : public AuraScript +{ + PrepareAuraScript(spell_item_swift_hand_justice_dummy); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SWIFT_HAND_OF_JUSTICE_HEAL }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_SWIFT_HAND_OF_JUSTICE_HEAL, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_swift_hand_justice_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 71406 - Tiny Abomination in a Jar +class spell_item_tiny_abomination_in_a_jar : public AuraScript +{ + PrepareAuraScript(spell_item_tiny_abomination_in_a_jar); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MOTE_OF_ANGER, SPELL_MANIFEST_ANGER_MAIN_HAND, SPELL_MANIFEST_ANGER_OFF_HAND }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + caster->CastSpell(nullptr, SPELL_MOTE_OF_ANGER, true, nullptr, aurEff); + Aura const* motes = caster->GetAura(SPELL_MOTE_OF_ANGER); + if (!motes || motes->GetStackAmount() < 8) + return; + + caster->RemoveAurasDueToSpell(SPELL_MOTE_OF_ANGER); + uint32 spellId = SPELL_MANIFEST_ANGER_MAIN_HAND; + if (Player* player = caster->ToPlayer()) + if (player->GetWeaponForAttack(OFF_ATTACK, true) && roll_chance_i(50)) + spellId = SPELL_MANIFEST_ANGER_OFF_HAND; + + caster->CastSpell(target, spellId, true, nullptr, aurEff); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_MOTE_OF_ANGER); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_tiny_abomination_in_a_jar::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + AfterEffectRemove += AuraEffectRemoveFn(spell_item_tiny_abomination_in_a_jar::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 71545 - Tiny Abomination in a Jar (Heroic) +class spell_item_tiny_abomination_in_a_jar_hero : public AuraScript +{ + PrepareAuraScript(spell_item_tiny_abomination_in_a_jar_hero); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MOTE_OF_ANGER, SPELL_MANIFEST_ANGER_MAIN_HAND, SPELL_MANIFEST_ANGER_OFF_HAND }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + caster->CastSpell(nullptr, SPELL_MOTE_OF_ANGER, true, nullptr, aurEff); + Aura const* motes = caster->GetAura(SPELL_MOTE_OF_ANGER); + if (!motes || motes->GetStackAmount() < 7) + return; + + caster->RemoveAurasDueToSpell(SPELL_MOTE_OF_ANGER); + uint32 spellId = SPELL_MANIFEST_ANGER_MAIN_HAND; + if (Player* player = caster->ToPlayer()) + if (player->GetWeaponForAttack(OFF_ATTACK, true) && roll_chance_i(50)) + spellId = SPELL_MANIFEST_ANGER_OFF_HAND; + + caster->CastSpell(target, spellId, true, nullptr, aurEff); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_MOTE_OF_ANGER); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_tiny_abomination_in_a_jar_hero::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + AfterEffectRemove += AuraEffectRemoveFn(spell_item_tiny_abomination_in_a_jar_hero::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 28856 - Totem of Flowing Water +class spell_item_totem_of_flowing_water : public AuraScript +{ + PrepareAuraScript(spell_item_totem_of_flowing_water); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_TOTEM_OF_FLOWING_WATER_MANA }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(nullptr, SPELL_TOTEM_OF_FLOWING_WATER_MANA, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_totem_of_flowing_water::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 75466 - Petrified Twilight Scale +class spell_item_petrified_twilight_scale : public AuraScript +{ + PrepareAuraScript(spell_item_petrified_twilight_scale); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PETRIFIED_TWILIGHT_SCALE }); + } + + void HandleProc(ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActionTarget()->CastSpell((Unit*)nullptr, SPELL_PETRIFIED_TWILIGHT_SCALE, true, nullptr, GetEffect(EFFECT_0)); + } + + void Register() override + { + OnProc += AuraProcFn(spell_item_petrified_twilight_scale::HandleProc); + } +}; + +// 75473 - Petrified Twilight Scale (Heroic) +class spell_item_petrified_twilight_scale_heroic : public AuraScript +{ + PrepareAuraScript(spell_item_petrified_twilight_scale_heroic); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PETRIFIED_TWILIGHT_SCALE_HC }); + } + + void HandleProc(ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActionTarget()->CastSpell((Unit*)nullptr, SPELL_PETRIFIED_TWILIGHT_SCALE_HC, true, nullptr, GetEffect(EFFECT_0)); + } + + void Register() override + { + OnProc += AuraProcFn(spell_item_petrified_twilight_scale_heroic::HandleProc); + } +}; + +// 69739 - Purified Shard of the Scale +class spell_item_purified_shard_of_the_scale : public AuraScript +{ + PrepareAuraScript(spell_item_purified_shard_of_the_scale); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PURIFIED_CAUTERIZING_HEAL }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_PURIFIED_CAUTERIZING_HEAL, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_purified_shard_of_the_scale::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 69755 - Shiny Shard of the Scale +class spell_item_shiny_shard_of_the_scale : public AuraScript +{ + PrepareAuraScript(spell_item_shiny_shard_of_the_scale); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHINY_SEARING_FLAMES }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_SHINY_SEARING_FLAMES, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_shiny_shard_of_the_scale::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 37336 - Living Root of the Wildheart +class spell_item_living_root_of_the_wildheart : public AuraScript +{ + PrepareAuraScript(spell_item_living_root_of_the_wildheart); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_LIVING_ROOT_BEAR, + SPELL_LIVING_ROOT_CAT, + SPELL_LIVING_ROOT_MOONKIN, + SPELL_LIVING_ROOT_NONE, + SPELL_LIVING_ROOT_TREE + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Unit* target = eventInfo.GetActor(); + + switch (target->GetShapeshiftForm()) + { + case FORM_BEAR: + case FORM_DIREBEAR: + case FORM_CAT: + case FORM_MOONKIN: + case FORM_NONE: + case FORM_TREE: + return true; + default: + break; + } + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* target = eventInfo.GetActor(); + uint32 triggerspell = 0; + + switch (target->GetShapeshiftForm()) + { + case FORM_BEAR: + case FORM_DIREBEAR: + triggerspell = SPELL_LIVING_ROOT_BEAR; + break; + case FORM_CAT: + triggerspell = SPELL_LIVING_ROOT_CAT; + break; + case FORM_MOONKIN: + triggerspell = SPELL_LIVING_ROOT_MOONKIN; + break; + case FORM_NONE: + triggerspell = SPELL_LIVING_ROOT_NONE; + break; + case FORM_TREE: + triggerspell = SPELL_LIVING_ROOT_TREE; + break; + default: + return; + } + + target->CastSpell(target, triggerspell, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_item_living_root_of_the_wildheart::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_living_root_of_the_wildheart::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + void AddSC_item_spell_scripts() { RegisterSpellScript(spell_item_massive_seaforium_charge); @@ -4423,4 +6322,60 @@ void AddSC_item_spell_scripts() RegisterSpellScript(spell_item_multiphase_goggles); RegisterSpellScript(spell_item_bloodsail_admiral_hat); RegisterSpellScript(spell_item_brewfest_hops); + RegisterSpellScript(spell_item_alchemists_stone); + RegisterSpellScript(spell_item_darkmoon_card_greatness); + RegisterSpellScript(spell_item_death_choice); + RegisterSpellScriptWithArgs(spell_item_lightning_capacitor, "spell_item_lightning_capacitor"); + RegisterSpellScriptWithArgs(spell_item_thunder_capacitor, "spell_item_thunder_capacitor"); + RegisterSpellScriptWithArgs(spell_item_toc25_caster_trinket_normal, "spell_item_toc25_caster_trinket_normal"); + RegisterSpellScriptWithArgs(spell_item_toc25_caster_trinket_heroic, "spell_item_toc25_caster_trinket_heroic"); + RegisterSpellScript(spell_item_soul_preserver); + RegisterSpellScript(spell_item_charm_witch_doctor); + RegisterSpellScript(spell_item_lifegiving_gem); + RegisterSpellScript(spell_item_mana_drain); + RegisterSpellScript(spell_item_mind_control_cap); + RegisterSpellScript(spell_item_hourglass_sand); + RegisterSpellScript(spell_item_ultrasafe_transporter); + RegisterSpellScript(spell_item_power_circle); + RegisterSpellScript(spell_item_thrallmar_and_honor_hold_favor); + RegisterSpellScript(spell_item_drums_of_forgotten_kings); + RegisterSpellScript(spell_item_drums_of_the_wild); + RegisterSpellScript(spell_item_darkmoon_card_illusion); + RegisterSpellScript(spell_item_mad_alchemists_potion); + RegisterSpellScript(spell_item_decahedral_dwarven_dice); + RegisterSpellScript(spell_item_aura_of_madness); + RegisterSpellScript(spell_item_dementia); + RegisterSpellScript(spell_item_deadly_precision); + RegisterSpellScript(spell_item_deadly_precision_dummy); + RegisterSpellScript(spell_item_deathbringers_will_normal); + RegisterSpellScript(spell_item_deathbringers_will_heroic); + RegisterSpellScript(spell_item_discerning_eye_beast_dummy); + RegisterSpellScript(spell_item_frozen_shadoweave); + RegisterSpellScript(spell_item_healing_touch_refund); + RegisterSpellScript(spell_item_heartpierce); + RegisterSpellScript(spell_item_heartpierce_hero); + RegisterSpellScript(spell_item_mark_of_conquest); + RegisterSpellScript(spell_item_pendant_of_the_violet_eye); + RegisterSpellScript(spell_item_persistent_shield); + RegisterSpellScript(spell_item_pet_healing); + RegisterSpellScript(spell_item_restless_strength); + RegisterSpellScript(spell_item_unstable_power); + RegisterSpellScript(spell_item_commendation_of_kaelthas); + RegisterSpellScript(spell_item_corpse_tongue_coin); + RegisterSpellScript(spell_item_corpse_tongue_coin_heroic); + RegisterSpellScript(spell_item_crystal_spire_of_karabor); + RegisterSpellScript(spell_item_soul_harvesters_charm); + RegisterSpellScript(spell_item_sunwell_exalted_caster_neck); + RegisterSpellScript(spell_item_sunwell_exalted_healer_neck); + RegisterSpellScript(spell_item_sunwell_exalted_melee_neck); + RegisterSpellScript(spell_item_sunwell_exalted_tank_neck); + RegisterSpellScript(spell_item_swift_hand_justice_dummy); + RegisterSpellScript(spell_item_tiny_abomination_in_a_jar); + RegisterSpellScript(spell_item_tiny_abomination_in_a_jar_hero); + RegisterSpellScript(spell_item_totem_of_flowing_water); + RegisterSpellScript(spell_item_petrified_twilight_scale); + RegisterSpellScript(spell_item_petrified_twilight_scale_heroic); + RegisterSpellScript(spell_item_purified_shard_of_the_scale); + RegisterSpellScript(spell_item_shiny_shard_of_the_scale); + RegisterSpellScript(spell_item_living_root_of_the_wildheart); } diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index aa1fe3b6d..f8d5db149 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -31,6 +31,9 @@ enum MageSpells { + SPELL_MAGE_ARCANE_MISSILES_R1 = 5143, + SPELL_MAGE_BLAZING_SPEED = 31643, + SPELL_MAGE_MAGIC_ABSORPTION_MANA = 29442, SPELL_MAGE_BURNOUT_TRIGGER = 44450, SPELL_MAGE_IMPROVED_BLIZZARD_CHILLED = 12486, SPELL_MAGE_COMBUSTION = 11129, @@ -42,6 +45,7 @@ enum MageSpells SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED = 44413, SPELL_MAGE_IGNITE = 12654, SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE = 29077, + SPELL_MAGE_PERMAFROST_AURA = 68391, SPELL_MAGE_SQUIRREL_FORM = 32813, SPELL_MAGE_GIRAFFE_FORM = 32816, SPELL_MAGE_SERPENT_FORM = 32817, @@ -52,7 +56,28 @@ enum MageSpells SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT = 70908, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY = 70907, SPELL_MAGE_GLYPH_OF_BLAST_WAVE = 62126, - SPELL_MAGE_FINGERS_OF_FROST = 44543 + SPELL_MAGE_FINGERS_OF_FROST = 44543, + SPELL_MAGE_FINGERS_OF_FROST_AURASTATE_AURA = 44544, + SPELL_MAGE_ARCANE_POTENCY_RANK_1 = 57529, + SPELL_MAGE_ARCANE_POTENCY_RANK_2 = 57531, + SPELL_MAGE_EMPOWERED_FIRE_PROC = 67545, + SPELL_MAGE_T10_2P_BONUS = 70752, + SPELL_MAGE_T10_2P_BONUS_EFFECT = 70753, + SPELL_MAGE_T8_4P_BONUS = 64869, + SPELL_MAGE_HOT_STREAK_PROC = 48108, + SPELL_MAGE_CHILLED_R1 = 12484, + SPELL_MAGE_CHILLED_R2 = 12485, + SPELL_MAGE_CHILLED_R3 = 12486, + SPELL_MAGE_MANA_SURGE = 37445, + SPELL_MAGE_FROST_NOVA = 122 +}; + +enum MageSpellIcons +{ + MAGE_ICON_MAGIC_ABSORPTION = 459, + MAGE_ICON_CLEARCASTING = 212, + MAGE_ICON_PRESENCE_OF_MIND = 139, + MAGE_ICON_LIVING_BOMB = 3000 }; class spell_mage_arcane_blast : public SpellScript @@ -112,7 +137,7 @@ class spell_mage_burning_determination : public AuraScript return true; } - void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + void HandleProc(ProcEventInfo& /*eventInfo*/) { PreventDefaultAction(); GetUnitOwner()->CastSpell(GetUnitOwner(), 54748, true); @@ -121,7 +146,7 @@ class spell_mage_burning_determination : public AuraScript void Register() override { DoCheckProc += AuraCheckProcFn(spell_mage_burning_determination::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_mage_burning_determination::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + OnProc += AuraProcFn(spell_mage_burning_determination::HandleProc); } }; @@ -784,44 +809,11 @@ class spell_mage_master_of_elements : public AuraScript return ValidateSpellInfo({ SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE }); } - bool AfterCheckProc(ProcEventInfo& eventInfo, bool isTriggeredAtSpellProcEvent) + bool CheckProc(ProcEventInfo& eventInfo) { - if (!isTriggeredAtSpellProcEvent || !eventInfo.GetActor() || !eventInfo.GetActionTarget()) - { + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetSpellInfo()) return false; - } - - _spellInfo = eventInfo.GetSpellInfo(); - - bool selectCaster = false; - // Triggered spells cost no mana so we need triggering spellInfo - if (SpellInfo const* triggeredByAuraSpellInfo = eventInfo.GetTriggerAuraSpell()) - { - _spellInfo = triggeredByAuraSpellInfo; - selectCaster = true; - } - - if (!_spellInfo) - { - return false; - } - - _ticksModifier = 1; - - // If spell is periodic, mana amount is divided by tick number - if (eventInfo.GetTriggerAuraEffectIndex() >= EFFECT_0) - { - if (Unit* caster = GetCaster()) - { - if (Unit* target = (selectCaster ? eventInfo.GetActor() : eventInfo.GetActionTarget())) - { - if (AuraEffect const* aurEff = target->GetAuraEffect(_spellInfo->Id, eventInfo.GetTriggerAuraEffectIndex(), caster->GetGUID())) - { - _ticksModifier = std::max(1, aurEff->GetTotalTicks()); - } - } - } - } return true; } @@ -830,30 +822,20 @@ class spell_mage_master_of_elements : public AuraScript { PreventDefaultAction(); - if (!_spellInfo) - return; + int32 mana = eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), eventInfo.GetDamageInfo()->GetSchoolMask()); + mana = CalculatePct(mana, aurEff->GetAmount()); - if (Unit* target = GetTarget()) + if (mana > 0) { - int32 mana = int32(_spellInfo->CalcPowerCost(target, eventInfo.GetSchoolMask()) / _ticksModifier); - mana = CalculatePct(mana, aurEff->GetAmount()); - - if (mana > 0) - { - target->CastCustomSpell(SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE, SPELLVALUE_BASE_POINT0, mana, target, true, nullptr, aurEff); - } + GetTarget()->CastCustomSpell(SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, nullptr, aurEff); } } void Register() override { - DoAfterCheckProc += AuraAfterCheckProcFn(spell_mage_master_of_elements::AfterCheckProc); + DoCheckProc += AuraCheckProcFn(spell_mage_master_of_elements::CheckProc); OnEffectProc += AuraEffectProcFn(spell_mage_master_of_elements::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); } - -private: - SpellInfo const* _spellInfo = nullptr; - uint8 _ticksModifier = 0; }; enum SilvermoonPolymorph @@ -946,125 +928,587 @@ class spell_mage_summon_water_elemental : public SpellScript } }; -#define FingersOfFrostScriptName "spell_mage_fingers_of_frost_proc_aura" -class spell_mage_fingers_of_frost_proc_aura : public AuraScript -{ PrepareAuraScript(spell_mage_fingers_of_frost_proc_aura); +// 74396 - Fingers of Frost +// Charge consumption is handled by the default proc system in PrepareProcToTrigger +// This script only handles removing the aura state aura (44544) when the buff expires +class spell_mage_fingers_of_frost : public AuraScript +{ + PrepareAuraScript(spell_mage_fingers_of_frost); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGE_FINGERS_OF_FROST_AURASTATE_AURA }); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_MAGE_FINGERS_OF_FROST_AURASTATE_AURA); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_mage_fingers_of_frost::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +// -31571 - Arcane Potency +class spell_mage_arcane_potency : public AuraScript +{ + PrepareAuraScript(spell_mage_arcane_potency); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_MAGE_ARCANE_POTENCY_RANK_1, + SPELL_MAGE_ARCANE_POTENCY_RANK_2 + }); + } bool CheckProc(ProcEventInfo& eventInfo) { - if (eventInfo.GetSpellPhaseMask() != PROC_SPELL_PHASE_CAST) - { - eventInfo.SetProcChance(_chance); - } + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return false; + + // Only proc on Clearcasting or Presence of Mind + if (spellInfo->SpellIconID != MAGE_ICON_CLEARCASTING && spellInfo->SpellIconID != MAGE_ICON_PRESENCE_OF_MIND) + return false; return true; } - bool AfterCheckProc(ProcEventInfo& eventInfo, bool isTriggeredAtSpellProcEvent) + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) { - if (eventInfo.GetSpellPhaseMask() != PROC_SPELL_PHASE_CAST) - { - eventInfo.ResetProcChance(); - } - - return isTriggeredAtSpellProcEvent; + PreventDefaultAction(); + uint32 spellId = GetSpellInfo()->GetRank() == 1 ? SPELL_MAGE_ARCANE_POTENCY_RANK_1 : SPELL_MAGE_ARCANE_POTENCY_RANK_2; + GetTarget()->CastSpell(GetTarget(), spellId, true, nullptr, aurEff); } - void HandleOnEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + void Register() override { - if (eventInfo.GetSpellPhaseMask() == PROC_SPELL_PHASE_CAST) + DoCheckProc += AuraCheckProcFn(spell_mage_arcane_potency::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_arcane_potency::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 11129 - Combustion +class spell_mage_combustion : public AuraScript +{ + PrepareAuraScript(spell_mage_combustion); + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Prevent charge consumption on non-crits + return eventInfo.GetHitMask() & PROC_EX_CRITICAL_HIT; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_mage_combustion::CheckProc); + } +}; + +// -31656 - Empowered Fire +class spell_mage_empowered_fire : public AuraScript +{ + PrepareAuraScript(spell_mage_empowered_fire); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGE_EMPOWERED_FIRE_PROC }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return false; + + // Only proc on Ignite + return spellInfo->Id == SPELL_MAGE_IGNITE; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + Unit* target = GetTarget(); + // Calculate mana restored: 2% of base mana (percent value comes from spell 67545 effect 0) + uint32 percent = sSpellMgr->GetSpellInfo(SPELL_MAGE_EMPOWERED_FIRE_PROC)->Effects[EFFECT_0].CalcValue(); + int32 mana = int32(CalculatePct(target->GetCreateMana(), percent)); + target->CastCustomSpell(SPELL_MAGE_EMPOWERED_FIRE_PROC, SPELLVALUE_BASE_POINT0, mana, target, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_mage_empowered_fire::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_empowered_fire::HandleProc, EFFECT_0, SPELL_AURA_ADD_FLAT_MODIFIER); + } +}; + +// 48108 - Hot Streak, 57761 - Fireball! +class spell_mage_gen_extra_effects : public AuraScript +{ + PrepareAuraScript(spell_mage_gen_extra_effects); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_MAGE_T8_4P_BONUS, + SPELL_MAGE_T10_2P_BONUS, + SPELL_MAGE_T10_2P_BONUS_EFFECT + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Unit* caster = eventInfo.GetActor(); + // T8 4P bonus: prevent double proc on Arcane Missiles + if (GetSpellInfo()->Id == SPELL_MAGE_HOT_STREAK_PROC && caster->HasAura(SPELL_MAGE_T8_4P_BONUS)) { - _chance = 100.f; - _spell = eventInfo.GetProcSpell(); - _procSpellDelayMoment = std::nullopt; - - if (!_spell || _spell->GetDelayMoment() <= 0) - PreventDefaultAction(); - - if (_spell) - _procSpellDelayMoment = _spell->GetDelayMoment(); + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && + (spellInfo->SpellFamilyFlags[0] & 0x00000800)) // Arcane Missiles + return false; } - else - { - if (eventInfo.GetSpellPhaseMask() == PROC_SPELL_PHASE_FINISH || (_procSpellDelayMoment.value_or(0) > 0 || !eventInfo.GetDamageInfo())) - PreventDefaultAction(); + return true; + } - ResetProcState(); + void HandleProc(ProcEventInfo& eventInfo) + { + Unit* caster = eventInfo.GetActor(); + // T10 2P bonus: apply pushing the limit on proc consumption + if (caster->HasAura(SPELL_MAGE_T10_2P_BONUS)) + caster->CastSpell(caster, SPELL_MAGE_T10_2P_BONUS_EFFECT, true); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_mage_gen_extra_effects::CheckProc); + OnProc += AuraProcFn(spell_mage_gen_extra_effects::HandleProc); + } +}; + +// 56372 - Glyph of Ice Block +class spell_mage_glyph_of_ice_block : public AuraScript +{ + PrepareAuraScript(spell_mage_glyph_of_ice_block); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGE_FROST_NOVA }); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + Player* player = GetTarget()->ToPlayer(); + if (!player) + return; + + // Reset cooldowns on Frost Nova and all its ranks + SpellInfo const* frostNovaInfo = sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_NOVA); + if (!frostNovaInfo) + return; + + PlayerSpellMap const& spellMap = player->GetSpellMap(); + for (auto const& itr : spellMap) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr.first); + if (!spellInfo) + continue; + + // Frost Nova spell family flags: 0x00000040 + if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && + (spellInfo->SpellFamilyFlags[0] & 0x00000040)) + { + player->RemoveSpellCooldown(spellInfo->Id, true); + } } } - void HandleAfterEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + void Register() override { - switch (eventInfo.GetSpellPhaseMask()) + OnEffectProc += AuraEffectProcFn(spell_mage_glyph_of_ice_block::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 56374 - Glyph of Icy Veins +class spell_mage_glyph_of_icy_veins : public AuraScript +{ + PrepareAuraScript(spell_mage_glyph_of_icy_veins); + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + Unit* target = GetTarget(); + + // Remove attack speed slows and haste reducting auras + target->RemoveAurasByType(SPELL_AURA_HASTE_SPELLS); + target->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_mage_glyph_of_icy_veins::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 56375 - Glyph of Polymorph +class spell_mage_glyph_of_polymorph : public AuraScript +{ + PrepareAuraScript(spell_mage_glyph_of_polymorph); + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* target = eventInfo.GetProcTarget(); + if (!target) + return; + + // Remove DoTs from target + target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, ObjectGuid::Empty, nullptr, true); + target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT, ObjectGuid::Empty, nullptr, true); + target->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH, ObjectGuid::Empty, nullptr, true); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_mage_glyph_of_polymorph::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -44445 - Hot Streak +class spell_mage_hot_streak : public AuraScript +{ + PrepareAuraScript(spell_mage_hot_streak); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGE_HOT_STREAK_PROC }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + // Non-crit - reset counter + if (!(eventInfo.GetHitMask() & PROC_EX_CRITICAL_HIT)) { - case PROC_SPELL_PHASE_HIT: _chance = 100.f; break; - case PROC_SPELL_PHASE_FINISH: ResetProcState(); break; - default: break; + _critStreak = 0; + return; + } + + // Crit - increment counter + ++_critStreak; + + // Two crits in a row - proc Hot Streak if chance succeeds + if (_critStreak >= 2) + { + _critStreak = 0; + if (roll_chance_i(aurEff->GetAmount())) + GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_HOT_STREAK_PROC, true, nullptr, aurEff); } } - void ResetProcState() + void Register() override { - _chance = 0.f; - _spell = nullptr; - _procSpellDelayMoment = std::nullopt; + OnEffectProc += AuraEffectProcFn(spell_mage_hot_streak::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); } - void Register() +private: + uint8 _critStreak = 0; +}; + +// -11185 - Improved Blizzard +class spell_mage_imp_blizzard : public AuraScript +{ + PrepareAuraScript(spell_mage_imp_blizzard); + + bool Validate(SpellInfo const* /*spellInfo*/) override { - DoCheckProc += AuraCheckProcFn(spell_mage_fingers_of_frost_proc_aura::CheckProc); - DoAfterCheckProc += AuraAfterCheckProcFn(spell_mage_fingers_of_frost_proc_aura::AfterCheckProc); - OnEffectProc += AuraEffectProcFn(spell_mage_fingers_of_frost_proc_aura::HandleOnEffectProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - AfterEffectProc += AuraEffectProcFn(spell_mage_fingers_of_frost_proc_aura::HandleAfterEffectProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + return ValidateSpellInfo( + { + SPELL_MAGE_CHILLED_R1, + SPELL_MAGE_CHILLED_R2, + SPELL_MAGE_CHILLED_R3 + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + uint32 spellId; + switch (GetSpellInfo()->GetRank()) + { + case 1: spellId = SPELL_MAGE_CHILLED_R1; break; + case 2: spellId = SPELL_MAGE_CHILLED_R2; break; + case 3: spellId = SPELL_MAGE_CHILLED_R3; break; + default: return; + } + + if (Unit* target = eventInfo.GetProcTarget()) + GetTarget()->CastSpell(target, spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_mage_imp_blizzard::HandleProc, EFFECT_0, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + } +}; + +// 61062, 37447 - Improved Mana Gems +class spell_mage_imp_mana_gems : public AuraScript +{ + PrepareAuraScript(spell_mage_imp_mana_gems); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGE_MANA_SURGE }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_MANA_SURGE, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_mage_imp_mana_gems::HandleProc, EFFECT_1, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + } +}; + +// -44404 - Missile Barrage +class spell_mage_missile_barrage : public AuraScript +{ + PrepareAuraScript(spell_mage_missile_barrage); + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return false; + + // Arcane Blast - full proc chance (100%) + // Arcane Blast spell family flags: 0x20000000 + if (spellInfo->SpellFamilyFlags[0] & 0x20000000) + return true; + + // Other spells - 50% proc chance + return roll_chance_i(50); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_mage_missile_barrage::CheckProc); + } +}; + +// -29441 - Magic Absorption +class spell_mage_magic_absorption : public AuraScript +{ + PrepareAuraScript(spell_mage_magic_absorption); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGE_MAGIC_ABSORPTION_MANA }); + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return GetTarget()->HasActivePowerType(POWER_MANA); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + Unit* target = GetTarget(); + int32 bp = CalculatePct(int32(target->GetMaxPower(POWER_MANA)), aurEff->GetAmount()); + target->CastCustomSpell(SPELL_MAGE_MAGIC_ABSORPTION_MANA, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_mage_magic_absorption::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_magic_absorption::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -31641 - Blazing Speed +class spell_mage_blazing_speed : public AuraScript +{ + PrepareAuraScript(spell_mage_blazing_speed); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGE_BLAZING_SPEED }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (Unit* target = eventInfo.GetActionTarget()) + target->CastSpell(target, SPELL_MAGE_BLAZING_SPEED, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_mage_blazing_speed::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// -5143 - Arcane Missiles +class spell_mage_arcane_missiles : public AuraScript +{ + PrepareAuraScript(spell_mage_arcane_missiles); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGE_T10_2P_BONUS, SPELL_MAGE_T10_2P_BONUS_EFFECT }); + } + + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (target->HasAura(SPELL_MAGE_T10_2P_BONUS) && _canProcT10) + target->CastSpell(target, SPELL_MAGE_T10_2P_BONUS_EFFECT, true, nullptr, aurEff); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_mage_arcane_missiles::OnRemove, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); } public: - // May point to a deleted object. - // Dereferencing is unsafe unless validity is guaranteed by the caller. - Spell const* GetProcSpell() const { return _spell; } + void AllowT10Proc() { _canProcT10 = true; } private: - float _chance = 0.f; - std::optional _procSpellDelayMoment = std::nullopt; - - // May be dangling; points to memory that might no longer be valid. - Spell const* _spell = nullptr; + bool _canProcT10 = false; }; -typedef spell_mage_fingers_of_frost_proc_aura spell_mage_fingers_of_frost_proc_aura_script; - -class spell_mage_fingers_of_frost_proc : public AuraScript +// -31661 - Dragon's Breath +class spell_mage_dragon_breath : public AuraScript { - PrepareAuraScript(spell_mage_fingers_of_frost_proc); + PrepareAuraScript(spell_mage_dragon_breath); bool CheckProc(ProcEventInfo& eventInfo) { - if (Aura* aura = GetCaster()->GetAuraOfRankedSpell(SPELL_MAGE_FINGERS_OF_FROST)) - { - if (spell_mage_fingers_of_frost_proc_aura_script* script = dynamic_cast(aura->GetScriptByName(FingersOfFrostScriptName))) - { - if (Spell const* fofProcSpell = script->GetProcSpell()) - { - if (fofProcSpell == eventInfo.GetProcSpell()) - { - return false; - } - } - } - } + // Don't proc with Living Bomb explosion + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (spellInfo && spellInfo->SpellIconID == MAGE_ICON_LIVING_BOMB && spellInfo->SpellFamilyName == SPELLFAMILY_MAGE) + return false; return true; } - void Register() + void Register() override { - DoCheckProc += AuraCheckProcFn(spell_mage_fingers_of_frost_proc::CheckProc); + DoCheckProc += AuraCheckProcFn(spell_mage_dragon_breath::CheckProc); + } +}; + +// -44614 - Frostfire Bolt +class spell_mage_frostfire_bolt : public AuraScript +{ + PrepareAuraScript(spell_mage_frostfire_bolt); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGE_PERMAFROST_AURA }); + } + + void ApplyPermafrost(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + caster->CastSpell(GetTarget(), SPELL_MAGE_PERMAFROST_AURA, true, nullptr, aurEff); + } + + void RemovePermafrost(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_MAGE_PERMAFROST_AURA); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_mage_frostfire_bolt::ApplyPermafrost, EFFECT_0, SPELL_AURA_MOD_DECREASE_SPEED, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + AfterEffectRemove += AuraEffectRemoveFn(spell_mage_frostfire_bolt::RemovePermafrost, EFFECT_0, SPELL_AURA_MOD_DECREASE_SPEED, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 45438 - Ice Block +class spell_mage_ice_block : public SpellScript +{ + PrepareSpellScript(spell_mage_ice_block); + + bool Validate(SpellInfo const* spellInfo) override + { + return spellInfo->ExcludeCasterAuraSpell && ValidateSpellInfo({ static_cast(spellInfo->ExcludeCasterAuraSpell) }); + } + + void TriggerHypothermia() + { + GetCaster()->CastSpell(GetCaster(), GetSpellInfo()->ExcludeCasterAuraSpell, true); + } + + void Register() override + { + AfterHit += SpellHitFn(spell_mage_ice_block::TriggerHypothermia); + } +}; + +// 44401 - Missile Barrage (proc buff) +class spell_mage_missile_barrage_proc : public AuraScript +{ + PrepareAuraScript(spell_mage_missile_barrage_proc); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGE_T10_2P_BONUS, SPELL_MAGE_T8_4P_BONUS, SPELL_MAGE_ARCANE_MISSILES_R1 }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Unit* caster = eventInfo.GetActor(); + + // T8 4P bonus: chance to not consume the proc + if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_MAGE_T8_4P_BONUS, EFFECT_0)) + if (roll_chance_i(aurEff->GetAmount())) + return false; + + return true; + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetTarget(); + // T10 2P bonus: signal Arcane Missiles to proc the bonus when it ends + if (caster->HasAura(SPELL_MAGE_T10_2P_BONUS)) + { + if (Aura* aura = caster->GetAuraOfRankedSpell(SPELL_MAGE_ARCANE_MISSILES_R1)) + { + if (spell_mage_arcane_missiles* script = dynamic_cast(aura->GetScriptByName("spell_mage_arcane_missiles"))) + script->AllowT10Proc(); + } + } + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_mage_missile_barrage_proc::CheckProc); + AfterEffectRemove += AuraEffectRemoveFn(spell_mage_missile_barrage_proc::OnRemove, EFFECT_0, SPELL_AURA_ADD_FLAT_MODIFIER, AURA_EFFECT_HANDLE_REAL); } }; void AddSC_mage_spell_scripts() { RegisterSpellScript(spell_mage_arcane_blast); + RegisterSpellScript(spell_mage_arcane_missiles); + RegisterSpellScript(spell_mage_arcane_potency); + RegisterSpellScript(spell_mage_blazing_speed); RegisterSpellScript(spell_mage_burning_determination); RegisterSpellScript(spell_mage_molten_armor); RegisterSpellScript(spell_mage_mirror_image); @@ -1072,19 +1516,33 @@ void AddSC_mage_spell_scripts() RegisterSpellScript(spell_mage_burnout_trigger); RegisterSpellScript(spell_mage_pet_scaling); RegisterSpellScript(spell_mage_brain_freeze); + RegisterSpellScript(spell_mage_combustion); RegisterSpellScript(spell_mage_glyph_of_eternal_water); RegisterSpellScript(spell_mage_combustion_proc); + RegisterSpellScript(spell_mage_dragon_breath); + RegisterSpellScript(spell_mage_empowered_fire); + RegisterSpellScript(spell_mage_gen_extra_effects); + RegisterSpellScript(spell_mage_frostfire_bolt); + RegisterSpellScript(spell_mage_glyph_of_ice_block); + RegisterSpellScript(spell_mage_glyph_of_icy_veins); + RegisterSpellScript(spell_mage_glyph_of_polymorph); + RegisterSpellScript(spell_mage_hot_streak); + RegisterSpellScript(spell_mage_ice_barrier); + RegisterSpellScript(spell_mage_ice_block); + RegisterSpellScript(spell_mage_imp_blizzard); + RegisterSpellScript(spell_mage_imp_mana_gems); + RegisterSpellScript(spell_mage_missile_barrage); + RegisterSpellScript(spell_mage_missile_barrage_proc); RegisterSpellScript(spell_mage_blast_wave); RegisterSpellScript(spell_mage_cold_snap); RegisterSpellScript(spell_mage_fire_frost_ward); RegisterSpellScript(spell_mage_focus_magic); - RegisterSpellScript(spell_mage_ice_barrier); RegisterSpellScript(spell_mage_ignite); RegisterSpellScript(spell_mage_living_bomb); RegisterSpellScript(spell_mage_mana_shield); RegisterSpellScript(spell_mage_master_of_elements); RegisterSpellScript(spell_mage_polymorph_cast_visual); RegisterSpellScript(spell_mage_summon_water_elemental); - RegisterSpellScript(spell_mage_fingers_of_frost_proc_aura); - RegisterSpellScript(spell_mage_fingers_of_frost_proc); + RegisterSpellScript(spell_mage_fingers_of_frost); + RegisterSpellScript(spell_mage_magic_absorption); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 0acf87cb2..8dd6e0d59 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -15,6 +15,7 @@ * with this program. If not, see . */ +#include "GameTime.h" #include "Group.h" #include "Player.h" #include "SpellAuraEffects.h" @@ -100,7 +101,51 @@ enum PaladinSpells enum PaladinSpellIcons { - PALADIN_ICON_ID_RETRIBUTION_AURA = 555 + PALADIN_ICON_ID_RETRIBUTION_AURA = 555, + PALADIN_ICON_JUDGEMENTS_OF_THE_WISE = 3017, + PALADIN_ICON_HAMMER_OF_THE_RIGHTEOUS = 3023, + PALADIN_ICON_RIGHTEOUS_VENGEANCE = 3025, + PALADIN_ICON_SHEATH_OF_LIGHT = 3030 +}; + +enum MiscSpellIcons +{ + SPELL_ICON_ID_STRENGTH_OF_WRYNN = 1704, + SPELL_ICON_ID_HELLSCREAM_WARSONG = 937 +}; + +// Proc system triggered spell IDs +enum PaladinProcSpells +{ + SPELL_PALADIN_ILLUMINATION_ENERGIZE = 20272, + SPELL_PALADIN_JUDGEMENTS_OF_THE_WISE_MANA = 31930, + SPELL_PALADIN_REPLENISHMENT = 57669, + SPELL_PALADIN_RIGHTEOUS_VENGEANCE_DOT = 61840, + SPELL_PALADIN_SHEATH_OF_LIGHT_HOT = 54203, + SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL = 20267, + SPELL_PALADIN_JUDGEMENT_OF_WISDOM_MANA = 20268, + SPELL_PALADIN_SPIRITUAL_ATTUNEMENT_MANA = 31786, + SPELL_PALADIN_BEACON_OF_LIGHT_AURA = 53563, + SPELL_PALADIN_LIGHTS_BEACON = 53651, + SPELL_PALADIN_BEACON_OF_LIGHT_FLASH = 53652, + SPELL_PALADIN_BEACON_OF_LIGHT_HOLY = 53654, + SPELL_PALADIN_HOLY_LIGHT_R1 = 635, + SPELL_PALADIN_GLYPH_OF_HOLY_LIGHT_HEAL = 54968, + SPELL_PALADIN_SACRED_SHIELD = 53601, + SPELL_PALADIN_T9_HOLY_4P_BONUS = 67191, + SPELL_PALADIN_FLASH_OF_LIGHT_PROC = 66922, + SPELL_PALADIN_ENDURING_LIGHT = 40471, + SPELL_PALADIN_ENDURING_JUDGEMENT = 40472, + SPELL_PALADIN_HOLY_POWER_ARMOR = 28790, + SPELL_PALADIN_HOLY_POWER_ATTACK_POWER = 28791, + SPELL_PALADIN_HOLY_POWER_SPELL_POWER = 28793, + SPELL_PALADIN_HOLY_POWER_MP5 = 28795, + SPELL_PALADIN_HOLY_MENDING = 64891, + SPELL_PALADIN_GLYPH_OF_DIVINITY_PROC = 54986, + SPELL_PALADIN_HEART_OF_THE_CRUSADER_EFF_R1 = 21183, + SPELL_PALADIN_JUDGEMENTS_OF_THE_JUST_PROC = 68055, + SPELL_PALADIN_SACRED_SHIELD_TRIGGER = 58597, + SPELL_PALADIN_T8_HOLY_4P_BONUS = 64895 }; class spell_pal_seal_of_command_aura : public AuraScript @@ -204,10 +249,52 @@ class spell_pal_seal_of_light : public AuraScript } }; +// 58597 - Sacred Shield (absorb) +class spell_pal_sacred_shield : public AuraScript +{ + PrepareAuraScript(spell_pal_sacred_shield); + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + { + // +75.00% from sp bonus + float bonus = CalculatePct(caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()), 75.0f); + + // Divine Guardian is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage + bonus = caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), bonus); + bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); + + amount += int32(bonus); + + // Arena - Dampening + if (AuraEffect const* auraEffArenaDampening = caster->GetAuraEffect(SPELL_GENERIC_ARENA_DAMPENING, EFFECT_0)) + AddPct(amount, auraEffArenaDampening->GetAmount()); + // Battleground - Dampening + else if (AuraEffect const* auraEffBattlegroundDampening = caster->GetAuraEffect(SPELL_GENERIC_BATTLEGROUND_DAMPENING, EFFECT_0)) + AddPct(amount, auraEffBattlegroundDampening->GetAmount()); + + // ICC buff + if (AuraEffect const* auraStrengthOfWrynn = caster->GetAuraEffect(SPELL_AURA_MOD_HEALING_DONE_PERCENT, SPELLFAMILY_GENERIC, SPELL_ICON_ID_STRENGTH_OF_WRYNN, EFFECT_2)) + AddPct(amount, auraStrengthOfWrynn->GetAmount()); + else if (AuraEffect const* auraHellscreamsWarsong = caster->GetAuraEffect(SPELL_AURA_MOD_HEALING_DONE_PERCENT, SPELLFAMILY_GENERIC, SPELL_ICON_ID_HELLSCREAM_WARSONG, EFFECT_2)) + AddPct(amount, auraHellscreamsWarsong->GetAmount()); + } + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_sacred_shield::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + } +}; + class spell_pal_sacred_shield_base : public AuraScript { PrepareAuraScript(spell_pal_sacred_shield_base); + static constexpr uint32 SACRED_SHIELD_ICD = 6 * IN_MILLISECONDS; + uint32 _cooldownEnd = 0; + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) { if (Unit* caster = GetCaster()) @@ -275,19 +362,21 @@ class spell_pal_sacred_shield_base : public AuraScript return; } - uint32 triggered_spell_id = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; - if (eventInfo.GetActionTarget()->HasSpellCooldown(triggered_spell_id)) + uint32 now = GameTime::GetGameTimeMS().count(); + if (_cooldownEnd > now) return; - uint32 cooldown = eventInfo.GetProcCooldown(); - int32 basepoints = aurEff->GetAmount(); + uint32 cooldown = SACRED_SHIELD_ICD; // Item - Paladin T8 Holy 4P Bonus if (Unit* caster = aurEff->GetCaster()) if (AuraEffect const* aurEffect = caster->GetAuraEffect(64895, 0)) cooldown = aurEffect->GetAmount() * IN_MILLISECONDS; - eventInfo.GetActionTarget()->AddSpellCooldown(triggered_spell_id, 0, cooldown); + _cooldownEnd = now + cooldown; + + uint32 triggered_spell_id = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; + int32 basepoints = aurEff->GetAmount(); eventInfo.GetActionTarget()->CastCustomSpell(eventInfo.GetActionTarget(), triggered_spell_id, &basepoints, nullptr, nullptr, true, nullptr, aurEff, eventInfo.GetActionTarget()->GetGUID()); } @@ -377,6 +466,80 @@ private: } }; +// 31821 - Aura Mastery +class spell_pal_aura_mastery : public AuraScript +{ + PrepareAuraScript(spell_pal_aura_mastery); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_AURA_MASTERY_IMMUNE }); + } + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->CastSpell(GetTarget(), SPELL_PALADIN_AURA_MASTERY_IMMUNE, true); + } + + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveOwnedAura(SPELL_PALADIN_AURA_MASTERY_IMMUNE, GetCasterGUID()); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_pal_aura_mastery::HandleEffectApply, EFFECT_0, SPELL_AURA_ADD_PCT_MODIFIER, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_pal_aura_mastery::HandleEffectRemove, EFFECT_0, SPELL_AURA_ADD_PCT_MODIFIER, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 64364 - Aura Mastery Immune +class spell_pal_aura_mastery_immune : public AuraScript +{ + PrepareAuraScript(spell_pal_aura_mastery_immune); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_CONCENTRACTION_AURA }); + } + + bool CheckAreaTarget(Unit* target) + { + return target->HasAura(SPELL_PALADIN_CONCENTRACTION_AURA, GetCasterGUID()); + } + + void Register() override + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_pal_aura_mastery_immune::CheckAreaTarget); + } +}; + +// 53563 - Beacon of Light +class spell_pal_beacon_of_light : public AuraScript +{ + PrepareAuraScript(spell_pal_beacon_of_light); + + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->Effects[EFFECT_0].TriggerSpell }); + } + + void PeriodicTick(AuraEffect const* aurEff) + { + PreventDefaultAction(); + + // area aura owner casts the spell + Unit* owner = GetAura()->GetUnitOwner(); + uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; + owner->CastSpell(GetTarget(), triggerSpell, true, nullptr, aurEff, owner->GetGUID()); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_pal_beacon_of_light::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; + // 31884 - Avenging Wrath class spell_pal_avenging_wrath : public AuraScript { @@ -384,17 +547,27 @@ class spell_pal_avenging_wrath : public AuraScript bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_PALADIN_SANCTIFIED_WRATH, SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1 }); + return ValidateSpellInfo( + { + SPELL_PALADIN_SANCTIFIED_WRATH, + SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1, + SPELL_PALADIN_AVENGING_WRATH_MARKER, + SPELL_PALADIN_IMMUNE_SHIELD_MARKER + }); } - void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void HandleApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); - if (AuraEffect const* aurEff = target->GetAuraEffectOfRankedSpell(SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1, EFFECT_2)) + if (AuraEffect const* sanctifiedWrathAurEff = target->GetAuraEffectOfRankedSpell(SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1, EFFECT_2)) { - int32 basepoints = aurEff->GetAmount(); - target->CastCustomSpell(target, SPELL_PALADIN_SANCTIFIED_WRATH, &basepoints, &basepoints, nullptr, true, nullptr, aurEff); + int32 basepoints = sanctifiedWrathAurEff->GetAmount(); + target->CastCustomSpell(target, SPELL_PALADIN_SANCTIFIED_WRATH, &basepoints, &basepoints, nullptr, true, nullptr, sanctifiedWrathAurEff); } + + target->CastSpell(target, SPELL_PALADIN_AVENGING_WRATH_MARKER, true, nullptr, aurEff); + // Blizz seems to just apply aura without bothering to cast + target->AddAura(SPELL_PALADIN_IMMUNE_SHIELD_MARKER, target); } void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) @@ -404,7 +577,7 @@ class spell_pal_avenging_wrath : public AuraScript void Register() override { - OnEffectApply += AuraEffectApplyFn(spell_pal_avenging_wrath::HandleApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL); + AfterEffectApply += AuraEffectApplyFn(spell_pal_avenging_wrath::HandleApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL); AfterEffectRemove += AuraEffectRemoveFn(spell_pal_avenging_wrath::HandleRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL); } }; @@ -1126,42 +1299,238 @@ class spell_pal_seal_of_righteousness : public AuraScript } }; -// 42463 - Seal of Vengeance -// 53739 - Seal of Corruption -class spell_pal_seal_of_vengeance : public SpellScript +// -31876 - Judgements of the Wise +class spell_pal_judgements_of_the_wise : public AuraScript { - PrepareSpellScript(spell_pal_seal_of_vengeance); + PrepareAuraScript(spell_pal_judgements_of_the_wise); bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_PALADIN_SEAL_OF_VENGEANCE_EFFECT, SPELL_PALADIN_SEAL_OF_CORRUPTION_EFFECT }); + return ValidateSpellInfo({ SPELL_PALADIN_JUDGEMENTS_OF_THE_WISE_MANA, SPELL_PALADIN_REPLENISHMENT }); } - void HandleScriptEffect(SpellEffIndex /*effIndex*/) + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) { - Unit* target = GetExplTargetUnit(); - uint32 spellId = GetSpell()->GetSpellInfo()->Id; - uint32 auraId = (spellId == SPELL_PALADIN_SEAL_OF_VENGEANCE_EFFECT) - ? SPELL_PALADIN_HOLY_VENGEANCE - : SPELL_PALADIN_BLOOD_CORRUPTION; - int32 damage = GetHitDamage(); - uint8 stacks = 0; - - if (target) - { - Aura* aura = target->GetAura(auraId, GetCaster()->GetGUID()); - if (aura) - stacks = aura->GetStackAmount(); - - damage = ((damage * stacks) / 5); - - SetHitDamage(damage); - } + PreventDefaultAction(); + Unit* caster = GetTarget(); + caster->CastSpell(caster, SPELL_PALADIN_JUDGEMENTS_OF_THE_WISE_MANA, true, nullptr, aurEff); + caster->CastSpell(caster, SPELL_PALADIN_REPLENISHMENT, true, nullptr, aurEff); } void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_pal_seal_of_vengeance::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE); + OnEffectProc += AuraEffectProcFn(spell_pal_judgements_of_the_wise::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -53380 - Righteous Vengeance +class spell_pal_righteous_vengeance : public AuraScript +{ + PrepareAuraScript(spell_pal_righteous_vengeance); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_RIGHTEOUS_VENGEANCE_DOT }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* target = eventInfo.GetActionTarget(); + if (!target) + return; + + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + // Calculate total DoT damage (percentage of crit damage), divided by 4 ticks + int32 amount = CalculatePct(static_cast(damageInfo->GetDamage()), aurEff->GetAmount()) / 4; + target->CastDelayedSpellWithPeriodicAmount(GetTarget(), SPELL_PALADIN_RIGHTEOUS_VENGEANCE_DOT, SPELL_AURA_PERIODIC_DAMAGE, amount); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_righteous_vengeance::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -53501 - Sheath of Light +class spell_pal_sheath_of_light : public AuraScript +{ + PrepareAuraScript(spell_pal_sheath_of_light); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_SHEATH_OF_LIGHT_HOT }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + HealInfo* healInfo = eventInfo.GetHealInfo(); + return healInfo && healInfo->GetHeal(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_PALADIN_SHEATH_OF_LIGHT_HOT); + int32 amount = CalculatePct(static_cast(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()); + + ASSERT(spellInfo->GetMaxTicks() > 0); + amount /= spellInfo->GetMaxTicks(); + + caster->CastCustomSpell(SPELL_PALADIN_SHEATH_OF_LIGHT_HOT, SPELLVALUE_BASE_POINT0, amount, target, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pal_sheath_of_light::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_sheath_of_light::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + } +}; + +// 20185 - Judgement of Light (debuff on target) +class spell_pal_judgement_of_light_heal : public AuraScript +{ + PrepareAuraScript(spell_pal_judgement_of_light_heal); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* attacker = eventInfo.GetActor(); + if (!attacker) + return; + + int32 bp = int32(attacker->CountPctFromMaxHealth(aurEff->GetAmount())); + attacker->CastCustomSpell(attacker, SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL, &bp, nullptr, nullptr, true, nullptr, aurEff, GetCasterGUID()); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_judgement_of_light_heal::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 20186 - Judgement of Wisdom (debuff on target) +class spell_pal_judgement_of_wisdom_mana : public AuraScript +{ + PrepareAuraScript(spell_pal_judgement_of_wisdom_mana); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_JUDGEMENT_OF_WISDOM_MANA }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetActor()->getPowerType() == POWER_MANA; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* attacker = eventInfo.GetActor(); + if (!attacker) + return; + + int32 bp = int32(CalculatePct(attacker->GetCreateMana(), aurEff->GetAmount())); + attacker->CastCustomSpell(attacker, SPELL_PALADIN_JUDGEMENT_OF_WISDOM_MANA, &bp, nullptr, nullptr, true, nullptr, aurEff, GetCasterGUID()); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pal_judgement_of_wisdom_mana::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_judgement_of_wisdom_mana::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 31785, 33776 - Spiritual Attunement +class spell_pal_spiritual_attunement : public AuraScript +{ + PrepareAuraScript(spell_pal_spiritual_attunement); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_SPIRITUAL_ATTUNEMENT_MANA }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // If healed by another unit (not self) + if (GetTarget() == eventInfo.GetActor()) + return false; + + // Don't allow non-positive spells to proc + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + if (!procSpell || !procSpell->IsPositive()) + return false; + + HealInfo const* healInfo = eventInfo.GetHealInfo(); + if (!healInfo || !healInfo->GetEffectiveHeal()) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + HealInfo const* healInfo = eventInfo.GetHealInfo(); + if (!healInfo) + return; + + uint32 effectiveHeal = healInfo->GetEffectiveHeal(); + if (!effectiveHeal) + return; + + int32 bp = int32(CalculatePct(effectiveHeal, aurEff->GetAmount())); + if (bp) + GetTarget()->CastCustomSpell(SPELL_PALADIN_SPIRITUAL_ATTUNEMENT_MANA, SPELLVALUE_BASE_POINT0, bp, GetTarget(), true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pal_spiritual_attunement::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_spiritual_attunement::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 54937 - Glyph of Holy Light (proc trigger) +class spell_pal_glyph_of_holy_light_proc : public AuraScript +{ + PrepareAuraScript(spell_pal_glyph_of_holy_light_proc); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_GLYPH_OF_HOLY_LIGHT_HEAL }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + HealInfo* healInfo = eventInfo.GetHealInfo(); + if (!healInfo || !healInfo->GetHeal()) + return; + + int32 bp = CalculatePct(int32(healInfo->GetHeal()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_PALADIN_GLYPH_OF_HOLY_LIGHT_HEAL, SPELLVALUE_BASE_POINT0, bp, eventInfo.GetActionTarget(), true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_glyph_of_holy_light_proc::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); } }; @@ -1195,13 +1564,714 @@ class spell_pal_hand_of_protection : public SpellScript } }; +// -31871 - Divine Purpose +class spell_pal_divine_purpose : public AuraScript +{ + PrepareAuraScript(spell_pal_divine_purpose); + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + // Get the EFFECT_2 aura effect for the proc chance + if (AuraEffect const* aurEff = GetEffect(EFFECT_2)) + return roll_chance_i(aurEff->GetAmount()); + return false; + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (Unit* target = eventInfo.GetActionTarget()) + target->RemoveAurasWithMechanic(1 << MECHANIC_STUN, AURA_REMOVE_BY_ENEMY_SPELL); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pal_divine_purpose::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_divine_purpose::HandleProc, EFFECT_2, SPELL_AURA_DUMMY); + } +}; + +// -53569 - Infusion of Light +class spell_pal_infusion_of_light : public AuraScript +{ + PrepareAuraScript(spell_pal_infusion_of_light); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_PALADIN_SACRED_SHIELD, + SPELL_PALADIN_T9_HOLY_4P_BONUS, + SPELL_PALADIN_FLASH_OF_LIGHT_PROC + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return; + + // Flash of Light HoT on Flash of Light when Sacred Shield active + if (spellInfo->SpellFamilyFlags[0] & 0x40000000 && spellInfo->SpellIconID == 242) + { + PreventDefaultAction(); + + HealInfo* healInfo = eventInfo.GetHealInfo(); + if (!healInfo || !healInfo->GetHeal()) + return; + + Unit* procTarget = eventInfo.GetActionTarget(); + if (procTarget && procTarget->HasAura(SPELL_PALADIN_SACRED_SHIELD)) + { + Unit* target = GetTarget(); + SpellInfo const* flashProcInfo = sSpellMgr->AssertSpellInfo(SPELL_PALADIN_FLASH_OF_LIGHT_PROC); + int32 duration = flashProcInfo->GetMaxDuration() / 1000; + int32 pct = GetSpellInfo()->Effects[EFFECT_2].CalcValue(); + if (duration <= 0) + return; + + int32 bp0 = CalculatePct(healInfo->GetHeal() / duration, pct); + + // Item - Paladin T9 Holy 4P Bonus + if (AuraEffect const* bonus = target->GetAuraEffect(SPELL_PALADIN_T9_HOLY_4P_BONUS, EFFECT_0)) + AddPct(bp0, bonus->GetAmount()); + + target->CastCustomSpell(SPELL_PALADIN_FLASH_OF_LIGHT_PROC, SPELLVALUE_BASE_POINT0, bp0, procTarget, true, nullptr, aurEff); + } + } + // but should not proc on non-critical Holy Shocks + else if ((spellInfo->SpellFamilyFlags[0] & 0x200000 || spellInfo->SpellFamilyFlags[1] & 0x10000) && !(eventInfo.GetHitMask() & PROC_EX_CRITICAL_HIT)) + PreventDefaultAction(); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_infusion_of_light::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 40470 - Paladin Tier 6 Trinket +class spell_pal_item_t6_trinket : public AuraScript +{ + PrepareAuraScript(spell_pal_item_t6_trinket); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_PALADIN_ENDURING_LIGHT, + SPELL_PALADIN_ENDURING_JUDGEMENT + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return false; + + // Holy Light & Flash of Light + if (spellInfo->SpellFamilyFlags[0] & 0xC0000000) + { + if (!roll_chance_i(15)) + return false; + + _triggeredSpellId = SPELL_PALADIN_ENDURING_LIGHT; + return true; + } + // Judgements + else if (spellInfo->SpellFamilyFlags[0] & 0x00800000) + { + if (!roll_chance_i(50)) + return false; + + _triggeredSpellId = SPELL_PALADIN_ENDURING_JUDGEMENT; + return true; + } + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), _triggeredSpellId, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pal_item_t6_trinket::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_item_t6_trinket::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + +private: + uint32 _triggeredSpellId = 0; +}; + +// 28789 - Holy Power (T3 6P Bonus) +class spell_pal_t3_6p_bonus : public AuraScript +{ + PrepareAuraScript(spell_pal_t3_6p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_PALADIN_HOLY_POWER_ARMOR, + SPELL_PALADIN_HOLY_POWER_ATTACK_POWER, + SPELL_PALADIN_HOLY_POWER_SPELL_POWER, + SPELL_PALADIN_HOLY_POWER_MP5 + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + uint32 spellId; + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + if (!target) + return; + + switch (target->getClass()) + { + case CLASS_PALADIN: + case CLASS_PRIEST: + case CLASS_SHAMAN: + case CLASS_DRUID: + spellId = SPELL_PALADIN_HOLY_POWER_MP5; + break; + case CLASS_MAGE: + case CLASS_WARLOCK: + spellId = SPELL_PALADIN_HOLY_POWER_SPELL_POWER; + break; + case CLASS_HUNTER: + case CLASS_ROGUE: + spellId = SPELL_PALADIN_HOLY_POWER_ATTACK_POWER; + break; + case CLASS_WARRIOR: + spellId = SPELL_PALADIN_HOLY_POWER_ARMOR; + break; + default: + return; + } + + caster->CastSpell(target, spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_t3_6p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 64890 - Item - Paladin T8 Holy 2P Bonus +class spell_pal_t8_2p_bonus : public AuraScript +{ + PrepareAuraScript(spell_pal_t8_2p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_HOLY_MENDING }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + HealInfo* healInfo = eventInfo.GetHealInfo(); + return healInfo && healInfo->GetHeal(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + if (!target) + return; + + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_PALADIN_HOLY_MENDING); + int32 amount = CalculatePct(static_cast(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()); + + int32 maxTicks = spellInfo->GetMaxTicks(); + if (maxTicks <= 0) + return; + + amount /= maxTicks; + caster->CastCustomSpell(SPELL_PALADIN_HOLY_MENDING, SPELLVALUE_BASE_POINT0, amount, target, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pal_t8_2p_bonus::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_t8_2p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -54939 - Glyph of Divinity +class spell_pal_glyph_of_divinity : public AuraScript +{ + PrepareAuraScript(spell_pal_glyph_of_divinity); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_GLYPH_OF_DIVINITY_PROC }); + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || !spellInfo->HasEffect(SPELL_EFFECT_ENERGIZE)) + return; + + Unit* caster = eventInfo.GetActor(); + if (caster == eventInfo.GetActionTarget()) + return; + + int32 amount = GetSpellInfo()->Effects[EFFECT_1].CalcValue() * 2; + caster->CastCustomSpell(SPELL_PALADIN_GLYPH_OF_DIVINITY_PROC, SPELLVALUE_BASE_POINT1, amount, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_glyph_of_divinity::OnProc, EFFECT_0, SPELL_AURA_ADD_PCT_MODIFIER); + } +}; + +// -54936 - Glyph of Holy Light (dummy aura) +class spell_pal_glyph_of_holy_light_dummy : public AuraScript +{ + PrepareAuraScript(spell_pal_glyph_of_holy_light_dummy); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_GLYPH_OF_HOLY_LIGHT_HEAL }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + HealInfo* healInfo = eventInfo.GetHealInfo(); + return healInfo && healInfo->GetHeal(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + HealInfo* healInfo = eventInfo.GetHealInfo(); + + uint32 basePoints = healInfo->GetSpellInfo()->Effects[EFFECT_0].BasePoints + healInfo->GetSpellInfo()->Effects[EFFECT_0].DieSides; + uint32 healAmount; + if (healInfo->GetEffectiveHeal() >= basePoints) + healAmount = healInfo->GetEffectiveHeal(); + else + healAmount = healInfo->GetHeal(); + + int32 bp0 = CalculatePct(static_cast(healAmount), aurEff->GetAmount()); + eventInfo.GetActor()->CastCustomSpell(SPELL_PALADIN_GLYPH_OF_HOLY_LIGHT_HEAL, SPELLVALUE_BASE_POINT0, bp0, eventInfo.GetActionTarget(), true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pal_glyph_of_holy_light_dummy::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_glyph_of_holy_light_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -20335 - Heart of the Crusader +class spell_pal_heart_of_the_crusader : public AuraScript +{ + PrepareAuraScript(spell_pal_heart_of_the_crusader); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_HEART_OF_THE_CRUSADER_EFF_R1 }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + uint32 spellId = sSpellMgr->GetSpellWithRank(SPELL_PALADIN_HEART_OF_THE_CRUSADER_EFF_R1, GetSpellInfo()->GetRank()); + eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_heart_of_the_crusader::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -20234 - Improved Lay on Hands +class spell_pal_improved_lay_of_hands : public AuraScript +{ + PrepareAuraScript(spell_pal_improved_lay_of_hands); + + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->Effects[EFFECT_0].TriggerSpell }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + uint32 triggeredSpell = GetSpellInfo()->Effects[EFFECT_0].TriggerSpell; + eventInfo.GetActionTarget()->CastSpell(eventInfo.GetActionTarget(), triggeredSpell, true, nullptr, aurEff, GetTarget()->GetGUID()); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_improved_lay_of_hands::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// -53695 - Judgements of the Just +class spell_pal_judgements_of_the_just : public AuraScript +{ + PrepareAuraScript(spell_pal_judgements_of_the_just); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PALADIN_JUDGEMENTS_OF_THE_JUST_PROC }); + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(eventInfo.GetActionTarget(), SPELL_PALADIN_JUDGEMENTS_OF_THE_JUST_PROC, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_judgements_of_the_just::OnProc, EFFECT_0, SPELL_AURA_ADD_FLAT_MODIFIER); + } +}; + +// 58597 - Sacred Shield (dummy on target) +class spell_pal_sacred_shield_dummy : public AuraScript +{ + PrepareAuraScript(spell_pal_sacred_shield_dummy); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_PALADIN_SACRED_SHIELD_TRIGGER, + SPELL_PALADIN_T8_HOLY_4P_BONUS + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + Unit* caster = GetCaster(); + if (!caster) + return; + + std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); + if (_cooldownEnd > now) + return; + + std::chrono::seconds cooldown(aurEff->GetAmount()); + if (AuraEffect const* bonus = caster->GetAuraEffect(SPELL_PALADIN_T8_HOLY_4P_BONUS, EFFECT_0, caster->GetGUID())) + cooldown = std::chrono::seconds(bonus->GetAmount()); + + _cooldownEnd = now + cooldown; + caster->CastSpell(GetTarget(), SPELL_PALADIN_SACRED_SHIELD_TRIGGER, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_sacred_shield_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + std::chrono::steady_clock::time_point _cooldownEnd = std::chrono::steady_clock::time_point::min(); +}; + +// 31801, 53736 - Seal of Vengeance/Corruption (aura proc handler) +class spell_pal_seal_of_vengeance_aura : public AuraScript +{ + PrepareAuraScript(spell_pal_seal_of_vengeance_aura); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_PALADIN_HOLY_VENGEANCE, + SPELL_PALADIN_BLOOD_CORRUPTION, + SPELL_PALADIN_SEAL_OF_VENGEANCE_EFFECT, + SPELL_PALADIN_SEAL_OF_CORRUPTION_EFFECT + }); + } + + bool Load() override + { + // Seal of Vengeance = 31801, Seal of Corruption = 53736 + _isVengeance = GetSpellInfo()->Id == 31801; + return true; + } + + void HandleApplyDoT(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + if (!(eventInfo.GetTypeMask() & PROC_FLAG_DONE_MELEE_AUTO_ATTACK)) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || spellInfo->SpellIconID != PALADIN_ICON_HAMMER_OF_THE_RIGHTEOUS) + return; + } + + uint32 dotSpell = _isVengeance ? SPELL_PALADIN_HOLY_VENGEANCE : SPELL_PALADIN_BLOOD_CORRUPTION; + eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), dotSpell, true, nullptr, aurEff); + } + + void HandleSeal(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + AuraEffect const* sealDot = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PALADIN, 0x00000000, 0x00000800, 0x00000000, caster->GetGUID()); + if (!sealDot) + return; + + uint8 stacks = sealDot->GetBase()->GetStackAmount(); + uint8 maxStacks = sealDot->GetSpellInfo()->StackAmount; + + uint32 damageSpell = _isVengeance ? SPELL_PALADIN_SEAL_OF_VENGEANCE_EFFECT : SPELL_PALADIN_SEAL_OF_CORRUPTION_EFFECT; + + // Scale weapon damage % by stacks (6.6% per stack, up to 33% at 5 stacks) + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(damageSpell); + int32 amount = spellInfo->Effects[EFFECT_0].CalcValue(); + amount = (amount * stacks) / maxStacks; + + caster->CastCustomSpell(damageSpell, SPELLVALUE_BASE_POINT0, amount, target, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_seal_of_vengeance_aura::HandleApplyDoT, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_pal_seal_of_vengeance_aura::HandleSeal, EFFECT_0, SPELL_AURA_DUMMY); + } + +private: + bool _isVengeance = true; +}; + +// -20234 - Illumination +class spell_pal_illumination : public AuraScript +{ + PrepareAuraScript(spell_pal_illumination); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_PALADIN_HOLY_SHOCK_R1_HEALING, + SPELL_PALADIN_ILLUMINATION_ENERGIZE, + SPELL_PALADIN_HOLY_SHOCK_R1 + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + // this script is valid only for the Holy Shock procs of illumination + if (eventInfo.GetHealInfo() && eventInfo.GetHealInfo()->GetSpellInfo()) + { + SpellInfo const* originalSpell = nullptr; + + // if proc comes from the Holy Shock heal, need to get mana cost of original spell - else it's the original heal itself + if (eventInfo.GetHealInfo()->GetSpellInfo()->SpellFamilyFlags[1] & 0x00010000) + originalSpell = sSpellMgr->GetSpellInfo(sSpellMgr->GetSpellWithRank(SPELL_PALADIN_HOLY_SHOCK_R1, eventInfo.GetHealInfo()->GetSpellInfo()->GetRank())); + else + originalSpell = eventInfo.GetHealInfo()->GetSpellInfo(); + + if (originalSpell && aurEff->GetSpellInfo()) + { + Unit* target = eventInfo.GetActor(); // Paladin is the target of the energize + int32 bp = CalculatePct(static_cast(originalSpell->CalcPowerCost(target, originalSpell->GetSchoolMask())), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()); + target->CastCustomSpell(target, SPELL_PALADIN_ILLUMINATION_ENERGIZE, &bp, nullptr, nullptr, true, nullptr, aurEff); + } + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pal_illumination::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 498, 642, 1022 - Divine Protection, Divine Shield, Hand of Protection +class spell_pal_immunities : public SpellScript +{ + PrepareSpellScript(spell_pal_immunities); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_PALADIN_FORBEARANCE, + SPELL_PALADIN_AVENGING_WRATH_MARKER, + SPELL_PALADIN_IMMUNE_SHIELD_MARKER + }); + } + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + + // for HoP + Unit* target = GetExplTargetUnit(); + if (!target) + target = caster; + + // "Cannot be used within $61987d. of using Avenging Wrath." + if (target->HasAura(SPELL_PALADIN_FORBEARANCE) || target->HasAura(SPELL_PALADIN_AVENGING_WRATH_MARKER)) + return SPELL_FAILED_TARGET_AURASTATE; + + return SPELL_CAST_OK; + } + + void TriggerDebuffs() + { + if (Unit* target = GetHitUnit()) + { + // Blizz seems to just apply aura without bothering to cast + GetCaster()->AddAura(SPELL_PALADIN_FORBEARANCE, target); + GetCaster()->AddAura(SPELL_PALADIN_AVENGING_WRATH_MARKER, target); + GetCaster()->AddAura(SPELL_PALADIN_IMMUNE_SHIELD_MARKER, target); + } + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_pal_immunities::CheckCast); + AfterHit += SpellHitFn(spell_pal_immunities::TriggerDebuffs); + } +}; + +// -20254 - Improved Concentration Aura +// -20138 - Improved Devotion Aura +// 31869 - Sanctified Retribution +// -53379 - Swift Retribution +class spell_pal_improved_aura : public AuraScript +{ + PrepareAuraScript(spell_pal_improved_aura); + +public: + spell_pal_improved_aura(uint32 spellId) : AuraScript(), _spellId(spellId) { } + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + _spellId, + SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1, + SPELL_PALADIN_SWIFT_RETRIBUTION_R1 + }); + } + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->RemoveOwnedAura(_spellId, GetCasterGUID()); // need to remove to reapply spellmods + target->CastSpell(target, _spellId, true); + } + + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + uint32 spellId = GetSpellInfo()->GetFirstRankSpell()->Id; + + if ((spellId == SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1 && GetTarget()->GetAuraOfRankedSpell(SPELL_PALADIN_SWIFT_RETRIBUTION_R1)) + || (spellId == SPELL_PALADIN_SWIFT_RETRIBUTION_R1 && GetTarget()->GetAuraOfRankedSpell(SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1))) + return; + + GetTarget()->RemoveOwnedAura(_spellId, GetCasterGUID()); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_pal_improved_aura::HandleEffectApply, EFFECT_FIRST_FOUND, SPELL_AURA_ADD_FLAT_MODIFIER, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_pal_improved_aura::HandleEffectRemove, EFFECT_FIRST_FOUND, SPELL_AURA_ADD_FLAT_MODIFIER, AURA_EFFECT_HANDLE_REAL); + } + +private: + uint32 _spellId; +}; + +// 53651 - Light's Beacon - Beacon of Light +class spell_pal_light_s_beacon : public AuraScript +{ + PrepareAuraScript(spell_pal_light_s_beacon); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_PALADIN_BEACON_OF_LIGHT_AURA, + SPELL_PALADIN_BEACON_OF_LIGHT_FLASH, + SPELL_PALADIN_BEACON_OF_LIGHT_HOLY, + SPELL_PALADIN_HOLY_LIGHT_R1 + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Don't proc if the heal target is the beacon target (no double heal) + if (GetTarget()->HasAura(SPELL_PALADIN_BEACON_OF_LIGHT_AURA, eventInfo.GetActor()->GetGUID())) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + if (!procSpell) + return; + + HealInfo* healInfo = eventInfo.GetHealInfo(); + if (!healInfo || !healInfo->GetHeal()) + return; + + // Holy Light heals for 100%, Flash of Light heals for 50% + uint32 healSpellId = procSpell->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_PALADIN_HOLY_LIGHT_R1)) ? + SPELL_PALADIN_BEACON_OF_LIGHT_FLASH : SPELL_PALADIN_BEACON_OF_LIGHT_HOLY; + int32 heal = CalculatePct(healInfo->GetHeal(), aurEff->GetAmount()); + + Unit* beaconTarget = GetCaster(); + if (!beaconTarget || !beaconTarget->HasAura(SPELL_PALADIN_BEACON_OF_LIGHT_AURA, eventInfo.GetActor()->GetGUID())) + return; + + eventInfo.GetActor()->CastCustomSpell(healSpellId, SPELLVALUE_BASE_POINT0, heal, beaconTarget, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pal_light_s_beacon::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_light_s_beacon::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + void AddSC_paladin_spell_scripts() { RegisterSpellAndAuraScriptPair(spell_pal_seal_of_command, spell_pal_seal_of_command_aura); RegisterSpellScript(spell_pal_divine_intervention); + RegisterSpellScript(spell_pal_divine_purpose); RegisterSpellScript(spell_pal_seal_of_light); + RegisterSpellScript(spell_pal_sacred_shield); RegisterSpellScript(spell_pal_sacred_shield_base); RegisterSpellScript(spell_pal_ardent_defender); + RegisterSpellScript(spell_pal_aura_mastery); + RegisterSpellScript(spell_pal_aura_mastery_immune); + RegisterSpellScript(spell_pal_beacon_of_light); RegisterSpellScript(spell_pal_avenging_wrath); RegisterSpellScript(spell_pal_blessing_of_faith); RegisterSpellScript(spell_pal_blessing_of_sanctuary); @@ -1215,6 +2285,8 @@ void AddSC_paladin_spell_scripts() RegisterSpellAndAuraScriptPair(spell_pal_hand_of_sacrifice, spell_pal_hand_of_sacrifice_aura); RegisterSpellScript(spell_pal_hand_of_salvation); RegisterSpellScript(spell_pal_holy_shock); + RegisterSpellScript(spell_pal_infusion_of_light); + RegisterSpellScript(spell_pal_item_t6_trinket); RegisterSpellScriptWithArgs(spell_pal_judgement, "spell_pal_judgement_of_justice", SPELL_PALADIN_JUDGEMENT_OF_JUSTICE); RegisterSpellScriptWithArgs(spell_pal_judgement, "spell_pal_judgement_of_light", SPELL_PALADIN_JUDGEMENT_OF_LIGHT); RegisterSpellScriptWithArgs(spell_pal_judgement, "spell_pal_judgement_of_wisdom", SPELL_PALADIN_JUDGEMENT_OF_WISDOM); @@ -1222,6 +2294,29 @@ void AddSC_paladin_spell_scripts() RegisterSpellScript(spell_pal_lay_on_hands); RegisterSpellScript(spell_pal_righteous_defense); RegisterSpellScript(spell_pal_seal_of_righteousness); - RegisterSpellScript(spell_pal_seal_of_vengeance); + RegisterSpellScriptWithArgs(spell_pal_seal_of_vengeance_aura, "spell_pal_seal_of_vengeance"); + RegisterSpellScriptWithArgs(spell_pal_seal_of_vengeance_aura, "spell_pal_seal_of_corruption"); RegisterSpellScript(spell_pal_hand_of_protection); + RegisterSpellScript(spell_pal_judgements_of_the_wise); + RegisterSpellScript(spell_pal_righteous_vengeance); + RegisterSpellScript(spell_pal_sheath_of_light); + RegisterSpellScript(spell_pal_judgement_of_light_heal); + RegisterSpellScript(spell_pal_judgement_of_wisdom_mana); + RegisterSpellScript(spell_pal_spiritual_attunement); + RegisterSpellScript(spell_pal_glyph_of_holy_light_proc); + RegisterSpellScript(spell_pal_t3_6p_bonus); + RegisterSpellScript(spell_pal_t8_2p_bonus); + RegisterSpellScript(spell_pal_glyph_of_divinity); + RegisterSpellScript(spell_pal_glyph_of_holy_light_dummy); + RegisterSpellScript(spell_pal_heart_of_the_crusader); + RegisterSpellScript(spell_pal_improved_lay_of_hands); + RegisterSpellScript(spell_pal_judgements_of_the_just); + RegisterSpellScript(spell_pal_sacred_shield_dummy); + RegisterSpellScript(spell_pal_illumination); + RegisterSpellScript(spell_pal_immunities); + RegisterSpellScriptWithArgs(spell_pal_improved_aura, "spell_pal_improved_concentraction_aura", SPELL_PALADIN_IMPROVED_CONCENTRACTION_AURA); + RegisterSpellScriptWithArgs(spell_pal_improved_aura, "spell_pal_improved_devotion_aura", SPELL_PALADIN_IMPROVED_DEVOTION_AURA); + RegisterSpellScriptWithArgs(spell_pal_improved_aura, "spell_pal_sanctified_retribution", SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA); + RegisterSpellScriptWithArgs(spell_pal_improved_aura, "spell_pal_swift_retribution", SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA); + RegisterSpellScript(spell_pal_light_s_beacon); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index a4b3c71ae..a5df31868 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -64,6 +64,24 @@ enum PriestSpellIcons PRIEST_ICON_ID_BORROWED_TIME = 2899, PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021, PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874, + PRIEST_ICON_ID_BODY_AND_SOUL = 2218 +}; + +// Proc system triggered spells +enum PriestProcSpells +{ + SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL = 15290, + SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL = 56131, + SPELL_PRIEST_BODY_AND_SOUL_SPEED = 64136, + SPELL_PRIEST_ORACULAR_HEAL = 26170, + SPELL_PRIEST_DIVINE_BLESSING = 40440, + SPELL_PRIEST_DIVINE_WRATH = 40441, + SPELL_PRIEST_ARMOR_OF_FAITH = 28810, + SPELL_PRIEST_BLESSED_HEALING = 70772, + SPELL_PRIEST_SHADOW_WORD_DEATH_R1 = 32379, + SPELL_PRIEST_MIND_BLAST_R1 = 8092, + SPELL_PRIEST_MIND_FLAY_DAMAGE = 58381, + SPELL_PRIEST_BLESSED_RECOVERY_R1 = 27813 }; enum Mics @@ -431,6 +449,27 @@ class spell_pri_lightwell_renew : public AuraScript } } + void InitializeAmount(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + // Attacks done to you equal to 30% of your total health will cancel the effect + _remainingAmount = GetTarget()->CountPctFromMaxHealth(30); + } + + void CheckDropCharge(ProcEventInfo& eventInfo) + { + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo) + return; + + uint32 damage = damageInfo->GetDamage(); + if (_remainingAmount <= damage) + return; + + _remainingAmount -= damage; + // prevent drop charge + PreventDefaultAction(); + } + void HandleUpdateSpellclick(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (Unit* caster = GetCaster()) @@ -448,10 +487,15 @@ class spell_pri_lightwell_renew : public AuraScript void Register() override { + DoPrepareProc += AuraProcFn(spell_pri_lightwell_renew::CheckDropCharge); DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pri_lightwell_renew::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + AfterEffectApply += AuraEffectApplyFn(spell_pri_lightwell_renew::InitializeAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); AfterEffectApply += AuraEffectApplyFn(spell_pri_lightwell_renew::HandleUpdateSpellclick, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL); AfterEffectRemove += AuraEffectRemoveFn(spell_pri_lightwell_renew::HandleUpdateSpellclick, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL); } + +private: + uint32 _remainingAmount = 0; }; // 8129 - Mana Burn @@ -983,6 +1027,418 @@ class spell_pri_shadowfiend_death : public AuraScript } }; +// 15286 - Vampiric Embrace +class spell_pri_vampiric_embrace : public AuraScript +{ + PrepareAuraScript(spell_pri_vampiric_embrace); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Not proc from Mind Sear + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + if (!procSpell) + return false; + + return !(procSpell->SpellFamilyFlags[1] & 0x80000); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + int32 selfHeal = CalculatePct(static_cast(damageInfo->GetDamage()), aurEff->GetAmount()); + int32 partyHeal = selfHeal / 5; + GetTarget()->CastCustomSpell(GetTarget(), SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL, &partyHeal, &selfHeal, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pri_vampiric_embrace::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_vampiric_embrace::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 55677 - Glyph of Dispel Magic +class spell_pri_glyph_of_dispel_magic : public AuraScript +{ + PrepareAuraScript(spell_pri_glyph_of_dispel_magic); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + if (!procSpell) + return false; + + // Dispel Magic shares spellfamilyflag with abolish disease - check icon + if (procSpell->SpellIconID != 74) + return false; + + Unit* target = eventInfo.GetActionTarget(); + if (!target || !target->IsFriendlyTo(GetTarget())) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* target = eventInfo.GetActionTarget(); + if (!target) + return; + + int32 bp = int32(target->CountPctFromMaxHealth(aurEff->GetAmount())); + GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pri_glyph_of_dispel_magic::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_glyph_of_dispel_magic::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -64127 - Body and Soul +class spell_pri_body_and_soul : public AuraScript +{ + PrepareAuraScript(spell_pri_body_and_soul); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_BODY_AND_SOUL_SPEED }); + } + + bool CheckProcTriggerSpell(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + return spellInfo && (spellInfo->SpellFamilyFlags[0] & 0x00000001) != 0; + } + + bool CheckProcDummy(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + if (eventInfo.GetActor() != eventInfo.GetActionTarget()) + return false; + + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + return spellInfo && spellInfo->Id == 552; + } + + void HandleProcDummy(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + if (roll_chance_i(aurEff->GetAmount())) + eventInfo.GetActor()->CastSpell(eventInfo.GetActor(), SPELL_PRIEST_BODY_AND_SOUL_SPEED, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckEffectProc += AuraCheckEffectProcFn(spell_pri_body_and_soul::CheckProcTriggerSpell, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + DoCheckEffectProc += AuraCheckEffectProcFn(spell_pri_body_and_soul::CheckProcDummy, EFFECT_1, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_pri_body_and_soul::HandleProcDummy, EFFECT_1, SPELL_AURA_DUMMY); + } +}; + +// 47569, 47570 - Improved Shadowform +class spell_pri_improved_shadowform : public AuraScript +{ + PrepareAuraScript(spell_pri_improved_shadowform); + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return roll_chance_i(GetEffect(EFFECT_0)->GetAmount()); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->RemoveMovementImpairingAuras(true); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pri_improved_shadowform::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_improved_shadowform::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 26169 - AQ 3P Bonus +class spell_pri_aq_3p_bonus : public AuraScript +{ + PrepareAuraScript(spell_pri_aq_3p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_ORACULAR_HEAL }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetActor() == eventInfo.GetActionTarget()) + return false; + + HealInfo* healInfo = eventInfo.GetHealInfo(); + return healInfo && healInfo->GetHeal(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 bp0 = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), 10); + eventInfo.GetActor()->CastCustomSpell(SPELL_PRIEST_ORACULAR_HEAL, SPELLVALUE_BASE_POINT0, bp0, eventInfo.GetActor(), true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pri_aq_3p_bonus::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_aq_3p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -47569 - Improved Shadowform (talent) +class spell_pri_imp_shadowform : public AuraScript +{ + PrepareAuraScript(spell_pri_imp_shadowform); + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + if (roll_chance_i(aurEff->GetAmount())) + GetTarget()->RemoveMovementImpairingAuras(true); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pri_imp_shadowform::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -15337 - Improved Spirit Tap +class spell_pri_improved_spirit_tap : public AuraScript +{ + PrepareAuraScript(spell_pri_improved_spirit_tap); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_PRIEST_SHADOW_WORD_DEATH_R1, + SPELL_PRIEST_MIND_BLAST_R1 + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) + { + if (spellInfo->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_PRIEST_SHADOW_WORD_DEATH_R1)) || + spellInfo->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_PRIEST_MIND_BLAST_R1))) + return true; + else if (spellInfo->Id == SPELL_PRIEST_MIND_FLAY_DAMAGE) + return roll_chance_i(50); + } + + return false; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pri_improved_spirit_tap::CheckProc); + } +}; + +// 40438 - Priest Tier 6 Trinket +class spell_pri_item_t6_trinket : public AuraScript +{ + PrepareAuraScript(spell_pri_item_t6_trinket); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_PRIEST_DIVINE_BLESSING, + SPELL_PRIEST_DIVINE_WRATH + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + if (eventInfo.GetSpellTypeMask() & PROC_SPELL_TYPE_HEAL) + caster->CastSpell(caster, SPELL_PRIEST_DIVINE_BLESSING, true, nullptr, aurEff); + + if (eventInfo.GetSpellTypeMask() & PROC_SPELL_TYPE_DAMAGE) + caster->CastSpell(caster, SPELL_PRIEST_DIVINE_WRATH, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pri_item_t6_trinket::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 28809 - T3 4P Bonus +class spell_pri_t3_4p_bonus : public AuraScript +{ + PrepareAuraScript(spell_pri_t3_4p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_ARMOR_OF_FAITH }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), SPELL_PRIEST_ARMOR_OF_FAITH, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pri_t3_4p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 37594 - Greater Heal Refund / T5 2P Bonus +class spell_pri_t5_heal_2p_bonus : public AuraScript +{ + PrepareAuraScript(spell_pri_t5_heal_2p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_ITEM_EFFICIENCY }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (HealInfo* healInfo = eventInfo.GetHealInfo()) + if (Unit* healTarget = healInfo->GetTarget()) + if (healInfo->GetEffectiveHeal()) + if (healTarget->GetHealth() >= healTarget->GetMaxHealth()) + return true; + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_PRIEST_ITEM_EFFICIENCY, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pri_t5_heal_2p_bonus::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_t5_heal_2p_bonus::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 70770 - Item - Priest T10 Healer 2P Bonus +class spell_pri_t10_heal_2p_bonus : public AuraScript +{ + PrepareAuraScript(spell_pri_t10_heal_2p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_BLESSED_HEALING }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + HealInfo* healInfo = eventInfo.GetHealInfo(); + return healInfo && healInfo->GetHeal(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_BLESSED_HEALING); + int32 amount = CalculatePct(static_cast(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()); + + ASSERT(spellInfo->GetMaxTicks() > 0); + amount /= spellInfo->GetMaxTicks(); + + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + caster->CastCustomSpell(target, SPELL_PRIEST_BLESSED_HEALING, &amount, nullptr, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pri_t10_heal_2p_bonus::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_t10_heal_2p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -47580 - Pain and Suffering (dummy aura) +class spell_pri_pain_and_suffering_dummy : public AuraScript +{ + PrepareAuraScript(spell_pri_pain_and_suffering_dummy); + + bool CheckDummy(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + return false; + } + + void Register() override + { + DoCheckEffectProc += AuraCheckEffectProcFn(spell_pri_pain_and_suffering_dummy::CheckDummy, EFFECT_1, SPELL_AURA_DUMMY); + } +}; + +// -27811 - Blessed Recovery +class spell_pri_blessed_recovery : public AuraScript +{ + PrepareAuraScript(spell_pri_blessed_recovery); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_BLESSED_RECOVERY_R1 }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + DamageInfo* dmgInfo = eventInfo.GetDamageInfo(); + if (!dmgInfo || !dmgInfo->GetDamage()) + return; + + Unit* target = eventInfo.GetActionTarget(); + uint32 triggerSpell = sSpellMgr->GetSpellWithRank(SPELL_PRIEST_BLESSED_RECOVERY_R1, aurEff->GetSpellInfo()->GetRank()); + SpellInfo const* triggerInfo = sSpellMgr->AssertSpellInfo(triggerSpell); + + int32 bp = CalculatePct(static_cast(dmgInfo->GetDamage()), aurEff->GetAmount()); + + ASSERT(triggerInfo->GetMaxTicks() > 0); + bp /= triggerInfo->GetMaxTicks(); + + target->CastCustomSpell(target, triggerSpell, &bp, nullptr, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pri_blessed_recovery::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + void AddSC_priest_spell_scripts() { RegisterSpellScript(spell_pri_shadowfiend_scaling); @@ -998,6 +1454,7 @@ void AddSC_priest_spell_scripts() RegisterSpellScript(spell_pri_mana_burn); RegisterSpellScript(spell_pri_mana_leech); RegisterSpellScript(spell_pri_mind_sear); + RegisterSpellScript(spell_pri_pain_and_suffering_dummy); RegisterSpellScript(spell_pri_pain_and_suffering_proc); RegisterSpellScript(spell_pri_penance); RegisterSpellAndAuraScriptPair(spell_pri_power_word_shield, spell_pri_power_word_shield_aura); @@ -1008,4 +1465,17 @@ void AddSC_priest_spell_scripts() RegisterSpellScript(spell_pri_mind_control); RegisterSpellScript(spell_pri_t4_4p_bonus); RegisterSpellScript(spell_pri_shadowfiend_death); + RegisterSpellScript(spell_pri_vampiric_embrace); + RegisterSpellScript(spell_pri_glyph_of_dispel_magic); + RegisterSpellScript(spell_pri_body_and_soul); + RegisterSpellScript(spell_pri_improved_shadowform); + // Proc system scripts + RegisterSpellScript(spell_pri_aq_3p_bonus); + RegisterSpellScript(spell_pri_blessed_recovery); + RegisterSpellScript(spell_pri_imp_shadowform); + RegisterSpellScript(spell_pri_improved_spirit_tap); + RegisterSpellScript(spell_pri_item_t6_trinket); + RegisterSpellScript(spell_pri_t3_4p_bonus); + RegisterSpellScript(spell_pri_t5_heal_2p_bonus); + RegisterSpellScript(spell_pri_t10_heal_2p_bonus); } diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 53e661a83..925bd78c4 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -18,6 +18,7 @@ #include "AreaDefines.h" #include "CellImpl.h" #include "CreatureScript.h" +#include "GameTime.h" #include "GridNotifiers.h" #include "SpellAuraEffects.h" #include "SpellMgr.h" @@ -43,6 +44,22 @@ enum RogueSpells SPELL_ROGUE_SHIV_TRIGGERED = 5940, SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933, SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628, + // Proc system spells + SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE = 31665, + SPELL_ROGUE_DEADLY_BREW_POISON = 3409, + SPELL_ROGUE_QUICK_RECOVERY_ENERGY = 31663, + SPELL_ROGUE_TURN_THE_TABLES_R1 = 52910, + SPELL_ROGUE_TURN_THE_TABLES_R2 = 52914, + SPELL_ROGUE_TURN_THE_TABLES_R3 = 52915, + SPELL_ROGUE_OVERKILL_TRIGGERED = 58427 +}; + +enum RogueSpellIcons +{ + ROGUE_ICON_MASTER_OF_SUBTLETY = 2114, + ROGUE_ICON_CUT_TO_THE_CHASE = 2909, + ROGUE_ICON_DEADLY_BREW = 2963, + ROGUE_ICON_QUICK_RECOVERY = 2116 }; class spell_rog_savage_combat : public AuraScript @@ -753,6 +770,206 @@ class spell_rog_vanish : public SpellScript } }; +// 56800 - Glyph of Backstab +class spell_rog_glyph_of_backstab : public AuraScript +{ + PrepareAuraScript(spell_rog_glyph_of_backstab); + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* target = eventInfo.GetActionTarget(); + if (!target) + return; + + // Try to find Rupture on target + if (AuraEffect* ruptureEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x100000, 0, 0, GetTarget()->GetGUID())) + { + Aura* rupture = ruptureEff->GetBase(); + if (!rupture->IsRemoved() && rupture->GetDuration() > 0) + { + // Check if we can extend (max 5 seconds extension per glyph) + if ((rupture->GetApplyTime() + rupture->GetMaxDuration() / 1000 + 5) > (GameTime::GetGameTime().count() + rupture->GetDuration() / 1000)) + { + rupture->SetDuration(rupture->GetDuration() + aurEff->GetAmount() * IN_MILLISECONDS); + } + } + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_rog_glyph_of_backstab::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 31666 - Master of Subtlety +// 58428 - Overkill +template +class spell_rog_stealth_buff_tracker : public AuraScript +{ + PrepareAuraScript(spell_rog_stealth_buff_tracker); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ RemoveSpellId }); + } + + void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (Aura* visualAura = GetTarget()->GetAura(RemoveSpellId)) + { + int32 duration = aurEff->GetBase()->GetDuration(); + visualAura->SetDuration(duration); + visualAura->SetMaxDuration(duration); + } + } + + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + GetTarget()->RemoveAurasDueToSpell(RemoveSpellId); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_rog_stealth_buff_tracker::AfterApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_stealth_buff_tracker::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +// -51664 - Cut to the Chase +class spell_rog_cut_to_the_chase : public AuraScript +{ + PrepareAuraScript(spell_rog_cut_to_the_chase); + + void HandleProc(ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + // Refresh Slice and Dice to 5 combo point max duration + if (AuraEffect const* snDEffect = GetTarget()->GetAuraEffect(SPELL_AURA_MOD_MELEE_HASTE, SPELLFAMILY_ROGUE, 0x40000, 0, 0)) + { + snDEffect->GetBase()->SetDuration(snDEffect->GetSpellInfo()->GetMaxDuration(), true); + } + } + + void Register() override + { + OnProc += AuraProcFn(spell_rog_cut_to_the_chase::HandleProc); + } +}; + +// -51625 - Deadly Brew +class spell_rog_deadly_brew : public AuraScript +{ + PrepareAuraScript(spell_rog_deadly_brew); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ROGUE_DEADLY_BREW_POISON }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* target = eventInfo.GetActionTarget(); + if (target) + GetTarget()->CastSpell(target, SPELL_ROGUE_DEADLY_BREW_POISON, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_rog_deadly_brew::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -31244 - Quick Recovery +class spell_rog_quick_recovery : public AuraScript +{ + PrepareAuraScript(spell_rog_quick_recovery); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ROGUE_QUICK_RECOVERY_ENERGY }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetSpellInfo() != nullptr; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 energyBack = CalculatePct(static_cast(eventInfo.GetSpellInfo()->ManaCost), aurEff->GetAmount()); + if (energyBack > 0) + GetTarget()->CastCustomSpell(SPELL_ROGUE_QUICK_RECOVERY_ENERGY, SPELLVALUE_BASE_POINT0, energyBack, GetTarget(), true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_rog_quick_recovery::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_rog_quick_recovery::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -13983 - Setup +class spell_rog_setup : public AuraScript +{ + PrepareAuraScript(spell_rog_setup); + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (Player* target = GetTarget()->ToPlayer()) + if (eventInfo.GetActor() == target->GetSelectedUnit()) + return true; + + return false; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_rog_setup::CheckProc); + } +}; + +// -51627 - Turn the Tables +class spell_rog_turn_the_tables : public AuraScript +{ + PrepareAuraScript(spell_rog_turn_the_tables); + + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->Effects[EFFECT_0].TriggerSpell }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + Unit* caster = GetCaster(); + if (!caster) + return; + + caster->CastSpell(caster, GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_rog_turn_the_tables::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 52910, 52914, 52915 - Turn the Tables (proc) +class spell_rog_turn_the_tables_proc : public AuraScript +{ + PrepareAuraScript(spell_rog_turn_the_tables_proc); + + void Register() override + { + // No special handling needed - default behavior + } +}; + void AddSC_rogue_spell_scripts() { RegisterSpellScript(spell_rog_savage_combat); @@ -771,4 +988,14 @@ void AddSC_rogue_spell_scripts() RegisterSpellScript(spell_rog_pickpocket); RegisterSpellScript(spell_rog_vanish_purge); RegisterSpellScript(spell_rog_vanish); + // Proc system scripts + RegisterSpellScript(spell_rog_glyph_of_backstab); + RegisterSpellScriptWithArgs(spell_rog_stealth_buff_tracker, "spell_rog_master_of_subtlety"); + RegisterSpellScriptWithArgs(spell_rog_stealth_buff_tracker, "spell_rog_overkill"); + RegisterSpellScript(spell_rog_cut_to_the_chase); + RegisterSpellScript(spell_rog_deadly_brew); + RegisterSpellScript(spell_rog_quick_recovery); + RegisterSpellScript(spell_rog_setup); + RegisterSpellScript(spell_rog_turn_the_tables); + RegisterSpellScript(spell_rog_turn_the_tables_proc); } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 23e9fb2e9..03ce3b39c 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -17,6 +17,8 @@ #include "CreatureScript.h" #include "GridNotifiers.h" +#include "ObjectAccessor.h" +#include "Player.h" #include "SpellAuraEffects.h" #include "SpellMgr.h" #include "SpellScript.h" @@ -36,6 +38,8 @@ enum ShamanSpells SPELL_SHAMAN_CLEANSING_TOTEM_EFFECT = 52025, SPELL_SHAMAN_EARTH_SHIELD_HEAL = 379, SPELL_SHAMAN_ELEMENTAL_MASTERY = 16166, + SPELL_SHAMAN_ELEMENTAL_FOCUS = 16164, + SPELL_SHAMAN_ELEMENTAL_OATH = 51466, SPELL_SHAMAN_ELECTRIFIED = 64930, SPELL_SHAMAN_EXHAUSTION = 57723, SPELL_SHAMAN_FIRE_NOVA_R1 = 1535, @@ -43,6 +47,7 @@ enum ShamanSpells SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD = 63279, SPELL_SHAMAN_GLYPH_OF_HEALING_STREAM_TOTEM = 55456, SPELL_SHAMAN_GLYPH_OF_MANA_TIDE = 55441, + SPELL_SHAMAN_GLYPH_OF_STONECLAW_TOTEM = 63298, SPELL_SHAMAN_GLYPH_OF_THUNDERSTORM = 62132, SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD = 23552, SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD_DAMAGE = 27635, @@ -51,7 +56,10 @@ enum ShamanSpells SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 64694, SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE = 52032, SPELL_SHAMAN_MANA_TIDE_TOTEM = 39609, + SPELL_SHAMAN_NATURE_GUARDIAN = 31616, + SPELL_SHAMAN_NATURE_GUARDIAN_THREAT = 39301, SPELL_SHAMAN_SATED = 57724, + SPELL_SHAMAN_STONECLAW_TOTEM = 55277, SPELL_SHAMAN_STORM_EARTH_AND_FIRE = 51483, SPELL_SHAMAN_TOTEM_EARTHBIND_EARTHGRAB = 64695, SPELL_SHAMAN_TOTEM_EARTHBIND_TOTEM = 6474, @@ -61,12 +69,44 @@ enum ShamanSpells SPELL_SHAMAN_STORMSTRIKE = 17364, SPELL_SHAMAN_LAVA_LASH = 60103, SPELL_SHAMAN_LIGHTNING_BOLT_OVERLOAD = 45284, + SPELL_SHAMAN_TOTEMIC_MASTERY = 38437, + SPELL_SHAMAN_TIDAL_FORCE_CRIT = 55166, + SPELL_SHAMAN_TOTEMIC_POWER_MP5 = 28824, + SPELL_SHAMAN_TOTEMIC_POWER_SPELL_POWER = 28825, + SPELL_SHAMAN_TOTEMIC_POWER_ATTACK_POWER = 28826, + SPELL_SHAMAN_TOTEMIC_POWER_ARMOR = 28827, + SPELL_SHAMAN_WINDFURY_WEAPON_R1 = 8232, + SPELL_SHAMAN_WINDFURY_ATTACK_MH = 25504, + SPELL_SHAMAN_WINDFURY_ATTACK_OH = 33750, + SPELL_SHAMAN_ENERGY_SURGE = 40465, + SPELL_SHAMAN_POWER_SURGE = 40466, + SPELL_SHAMAN_FLAMETONGUE_ATTACK = 10444, + SPELL_SHAMAN_LIGHTNING_SHIELD_DAMAGE_R1 = 26364, + SPELL_SHAMAN_SHAMANISTIC_RAGE_PROC = 30824, + SPELL_SHAMAN_MAELSTROM_POWER = 70831, + SPELL_SHAMAN_T10_ENHANCEMENT_4P_BONUS = 70832, + SPELL_SHAMAN_LAVA_BURST_BONUS_DAMAGE = 71824, + SPELL_SHAMAN_TOTEM_OF_WRATH_SPELL_POWER = 63283, }; enum ShamanSpellIcons { SHAMAN_ICON_ID_RESTORATIVE_TOTEMS = 338, - SHAMAN_ICON_ID_SHAMAN_LAVA_FLOW = 3087 + SHAMAN_ICON_ID_SHAMAN_LAVA_FLOW = 3087, + SHAMAN_ICON_FROZEN_POWER = 3780, + SHAMAN_ICON_LIGHTNING_OVERLOAD = 2018, + SHAMAN_ICON_ID_TOTEM_OF_WRATH = 2019 +}; + +// Proc system triggered spells +enum ShamanProcSpells +{ + SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE_HEAL = 55533, + SPELL_SHAMAN_SPIRIT_HUNT_HEAL = 58879, + SPELL_SHAMAN_FROZEN_POWER_ROOT = 63685, + SPELL_SHAMAN_LIGHTNING_OVERLOAD_LB = 45284, + SPELL_SHAMAN_LIGHTNING_OVERLOAD_CL = 45297, + SPELL_SHAMAN_ANCESTRAL_AWAKENING_HEAL = 52759 }; class spell_sha_totem_of_wrath : public SpellScript @@ -516,6 +556,30 @@ class spell_sha_cleansing_totem_pulse : public SpellScript } }; +// 16246 - Clearcasting +class spell_sha_clearcasting : public AuraScript +{ + PrepareAuraScript(spell_sha_clearcasting); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_ELEMENTAL_OATH }); + } + + // Elemental Oath bonus + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + Unit const* owner = GetUnitOwner(); + if (Aura const* aura = owner->GetAuraOfRankedSpell(SPELL_SHAMAN_ELEMENTAL_OATH, owner->GetGUID())) + amount = aura->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_clearcasting::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + } +}; + // -974 - Earth Shield class spell_sha_earth_shield : public AuraScript { @@ -920,6 +984,30 @@ class spell_sha_item_mana_surge : public AuraScript } }; +// 16164 - Elemental Focus +// Prevents weapon imbue attacks (Frostbrand, Flametongue) from proccing Clearcasting +class spell_sha_elemental_focus : public AuraScript +{ + PrepareAuraScript(spell_sha_elemental_focus); + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (SpellInfo const* procSpell = eventInfo.GetSpellInfo()) + { + // Frostbrand Attack (mask0 = 0x1000000), Flametongue Attack (mask0 = 0x200000) + if (procSpell->SpellFamilyName == SPELLFAMILY_SHAMAN && + (procSpell->SpellFamilyFlags[0] & 0x1200000)) + return false; + } + return true; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_elemental_focus::CheckProc); + } +}; + // 70811 - Item - Shaman T10 Elemental 2P Bonus class spell_sha_item_t10_elemental_2p_bonus : public AuraScript { @@ -1000,6 +1088,28 @@ class spell_sha_mana_spring_totem : public SpellScript } }; +// 16191 - Mana Tide +class spell_sha_mana_tide : public AuraScript +{ + PrepareAuraScript(spell_sha_mana_tide); + + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->Effects[EFFECT_0].TriggerSpell }); + } + + void PeriodicTick(AuraEffect const* aurEff) + { + PreventDefaultAction(); + GetTarget()->CastCustomSpell(GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), nullptr, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_sha_mana_tide::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; + // 39610 - Mana Tide Totem class spell_sha_mana_tide_totem : public SpellScript { @@ -1035,6 +1145,52 @@ class spell_sha_mana_tide_totem : public SpellScript } }; +// -30881 - Nature's Guardian +class spell_sha_nature_guardian : public AuraScript +{ + PrepareAuraScript(spell_sha_nature_guardian); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_SHAMAN_NATURE_GUARDIAN, + SPELL_SHAMAN_NATURE_GUARDIAN_THREAT + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return false; + + int32 healthpct = GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + if (Unit* target = eventInfo.GetActionTarget()) + if (target->HealthBelowPctDamaged(healthpct, damageInfo->GetDamage())) + return true; + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* target = eventInfo.GetActionTarget(); + int32 bp = CalculatePct(target->GetMaxHealth(), aurEff->GetAmount()); + target->CastCustomSpell(SPELL_SHAMAN_NATURE_GUARDIAN, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); + if (Unit* attacker = eventInfo.GetActor()) + target->CastSpell(attacker, SPELL_SHAMAN_NATURE_GUARDIAN_THREAT, true); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_nature_guardian::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_nature_guardian::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + // 6495 - Sentry Totem class spell_sha_sentry_totem : public AuraScript { @@ -1058,6 +1214,42 @@ class spell_sha_sentry_totem : public AuraScript } }; +// 55278, 55328, 55329, 55330, 55332, 55333, 55335, 58589, 58590, 58591 - Stoneclaw Totem +class spell_sha_stoneclaw_totem : public SpellScript +{ + PrepareSpellScript(spell_sha_stoneclaw_totem); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_STONECLAW_TOTEM, SPELL_SHAMAN_GLYPH_OF_STONECLAW_TOTEM }); + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + + // Cast Absorb on totems + for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot) + { + if (!target->m_SummonSlot[slot]) + continue; + + Creature* totem = target->GetMap()->GetCreature(target->m_SummonSlot[slot]); + if (totem && totem->IsTotem()) + GetCaster()->CastCustomSpell(SPELL_SHAMAN_STONECLAW_TOTEM, SPELLVALUE_BASE_POINT0, GetEffectValue(), totem, true); + } + + // Glyph of Stoneclaw Totem + if (AuraEffect* aur = target->GetAuraEffect(SPELL_SHAMAN_GLYPH_OF_STONECLAW_TOTEM, 0)) + GetCaster()->CastCustomSpell(SPELL_SHAMAN_STONECLAW_TOTEM, SPELLVALUE_BASE_POINT0, GetEffectValue() * aur->GetAmount(), target, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_sha_stoneclaw_totem::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + // -51490 - Thunderstorm class spell_sha_thunderstorm : public SpellScript { @@ -1143,6 +1335,878 @@ class spell_sha_t8_electrified : public AuraScript } }; +// 55440 - Glyph of Healing Wave +class spell_sha_glyph_of_healing_wave : public AuraScript +{ + PrepareAuraScript(spell_sha_glyph_of_healing_wave); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE_HEAL }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Not proc from self heals + return GetTarget() != eventInfo.GetActionTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + HealInfo* healInfo = eventInfo.GetHealInfo(); + if (!healInfo || !healInfo->GetHeal()) + return; + + int32 bp = CalculatePct(int32(healInfo->GetHeal()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE_HEAL, SPELLVALUE_BASE_POINT0, bp, GetTarget(), true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_glyph_of_healing_wave::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_glyph_of_healing_wave::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 58877 - Spirit Hunt +class spell_sha_spirit_hunt : public AuraScript +{ + PrepareAuraScript(spell_sha_spirit_hunt); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_SPIRIT_HUNT_HEAL }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + Unit* owner = GetTarget()->GetOwner(); + if (!owner) + return; + + int32 bp = CalculatePct(int32(damageInfo->GetDamage()), aurEff->GetAmount()); + // Heal owner + GetTarget()->CastCustomSpell(SPELL_SHAMAN_SPIRIT_HUNT_HEAL, SPELLVALUE_BASE_POINT0, bp, owner, true, nullptr, aurEff); + // Heal wolf + GetTarget()->CastCustomSpell(SPELL_SHAMAN_SPIRIT_HUNT_HEAL, SPELLVALUE_BASE_POINT0, bp, GetTarget(), true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_spirit_hunt::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -63373 - Frozen Power +class spell_sha_frozen_power : public AuraScript +{ + PrepareAuraScript(spell_sha_frozen_power); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_FROZEN_POWER_ROOT }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Unit* target = eventInfo.GetActionTarget(); + if (!target) + return false; + + // Don't proc if target is within 15 yards + if (GetTarget()->GetDistance(target) < 15.0f) + return false; + + return roll_chance_i(GetEffect(EFFECT_0)->GetAmount()); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* target = eventInfo.GetActionTarget(); + if (target) + GetTarget()->CastSpell(target, SPELL_SHAMAN_FROZEN_POWER_ROOT, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_frozen_power::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_frozen_power::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + } +}; + +// -30675 - Lightning Overload +class spell_sha_lightning_overload : public AuraScript +{ + PrepareAuraScript(spell_sha_lightning_overload); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_LIGHTNING_OVERLOAD_LB, SPELL_SHAMAN_LIGHTNING_OVERLOAD_CL }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + if (!procSpell || !GetTarget()->IsPlayer() || !eventInfo.GetActionTarget()) + return false; + + // Check for Lightning Bolt or Chain Lightning + if ((procSpell->SpellFamilyFlags[0] & 0x3) == 0) + return false; + + // Chain Lightning only procs 1/3 of the time + if (procSpell->SpellFamilyFlags[0] & 0x2) + return roll_chance_i(33); + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + Unit* target = eventInfo.GetActionTarget(); + if (!procSpell || !target) + return; + + uint32 spell = (procSpell->SpellFamilyFlags[0] & 0x2) ? SPELL_SHAMAN_LIGHTNING_OVERLOAD_CL : SPELL_SHAMAN_LIGHTNING_OVERLOAD_LB; + + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo) + return; + + int32 damage = damageInfo->GetDamage(); + // Half damage for critical hits + if (eventInfo.GetHitMask() & PROC_EX_CRITICAL_HIT) + damage /= 2; + // Half damage overall + damage /= 2; + + GetTarget()->CastCustomSpell(spell, SPELLVALUE_BASE_POINT0, damage, target, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_lightning_overload::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_lightning_overload::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -51556 - Ancestral Awakening (talent proc handler) +class spell_sha_ancestral_awakening : public AuraScript +{ + PrepareAuraScript(spell_sha_ancestral_awakening); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_ANCESTRAL_AWAKENING_HEAL }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + HealInfo* healInfo = eventInfo.GetHealInfo(); + if (!healInfo || !healInfo->GetHeal()) + return; + + int32 bp = CalculatePct(int32(healInfo->GetHeal()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_SHAMAN_ANCESTRAL_AWAKENING_HEAL, SPELLVALUE_BASE_POINT0, bp, GetTarget(), true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_ancestral_awakening::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -51474 - Astral Shift aura +class spell_sha_astral_shift_aura : public AuraScript +{ + PrepareAuraScript(spell_sha_astral_shift_aura); + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) + if (spellInfo->GetAllEffectsMechanicMask() & ((1 << MECHANIC_SILENCE) | (1 << MECHANIC_STUN) | (1 << MECHANIC_FEAR))) + return true; + + return false; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_astral_shift_aura::CheckProc); + } +}; + +// 52179 - Astral Shift +class spell_sha_astral_shift_visual_dummy : public AuraScript +{ + PrepareAuraScript(spell_sha_astral_shift_visual_dummy); + + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + // Periodic needed to remove visual on stun/fear/silence lost + if (!(GetTarget()->GetUnitFlags() & (UNIT_FLAG_STUNNED | UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED))) + Remove(); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_sha_astral_shift_visual_dummy::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +// -10400 - Flametongue Weapon (Passive) +class spell_sha_flametongue_weapon : public AuraScript +{ + PrepareAuraScript(spell_sha_flametongue_weapon); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_FLAMETONGUE_ATTACK }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Player* player = eventInfo.GetActor()->ToPlayer(); + if (!player) + return false; + + Item* item = player->GetItemByGuid(GetAura()->GetCastItemGUID()); + if (!item || !item->IsEquipped()) + return false; + + WeaponAttackType attType = Player::GetAttackBySlot(item->GetSlot()); + if (attType != BASE_ATTACK && attType != OFF_ATTACK) + return false; + + if (((attType == BASE_ATTACK) && !(eventInfo.GetTypeMask() & PROC_FLAG_DONE_MAINHAND_ATTACK)) || + ((attType == OFF_ATTACK) && !(eventInfo.GetTypeMask() & PROC_FLAG_DONE_OFFHAND_ATTACK))) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Player* player = eventInfo.GetActor()->ToPlayer(); + Unit* target = eventInfo.GetActionTarget(); + WeaponAttackType attType = BASE_ATTACK; + if (eventInfo.GetTypeMask() & PROC_FLAG_DONE_OFFHAND_ATTACK) + attType = OFF_ATTACK; + + Item* item = player->GetWeaponForAttack(attType); + if (!item) + return; + + float basePoints = GetSpellInfo()->Effects[aurEff->GetEffIndex()].CalcValue(); + + // Flametongue max damage is normalized based on a 4.0 speed weapon + float attackSpeed = player->GetAttackTime(attType) / 1000.f; + float fireDamage = basePoints / 100.0f; + fireDamage *= attackSpeed; + + // clip value between (BasePoints / 77) and (BasePoints / 25) as the tooltip indicates + RoundToInterval(fireDamage, basePoints / 77.0f, basePoints / 25.0f); + + // Calculate Spell Power scaling + float spellPowerBonus = player->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE); + spellPowerBonus += target->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, SPELL_SCHOOL_MASK_FIRE); + + float const spCoeff = 0.03811f; + spellPowerBonus *= spCoeff * attackSpeed; + + int32 totalDamage = int32(fireDamage + spellPowerBonus); + player->CastCustomSpell(SPELL_SHAMAN_FLAMETONGUE_ATTACK, SPELLVALUE_BASE_POINT0, totalDamage, target, true, item, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_flametongue_weapon::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_flametongue_weapon::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 63279 - Glyph of Earth Shield +class spell_sha_glyph_of_earth_shield : public AuraScript +{ + PrepareAuraScript(spell_sha_glyph_of_earth_shield); + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + SpellInfo const* earthShield = eventInfo.GetSpellInfo(); + if (!earthShield) + return; + + AuraEffect* earthShieldEffect = eventInfo.GetActionTarget()->GetAuraEffect(earthShield->Id, EFFECT_0, eventInfo.GetActor()->GetGUID()); + if (!earthShieldEffect) + return; + + int32 amount = earthShieldEffect->GetAmount(); + AddPct(amount, aurEff->GetAmount()); + earthShieldEffect->SetAmount(amount); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_glyph_of_earth_shield::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 63280 - Glyph of Totem of Wrath +class spell_sha_glyph_of_totem_of_wrath : public AuraScript +{ + PrepareAuraScript(spell_sha_glyph_of_totem_of_wrath); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_TOTEM_OF_WRATH_SPELL_POWER }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Totem of Wrath shares family flags with other totems + // filter by spellIcon instead + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || spellInfo->SpellIconID != SHAMAN_ICON_ID_TOTEM_OF_WRATH) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + + // Fire totem summon slot + Creature* totem = ObjectAccessor::GetCreature(*caster, caster->m_SummonSlot[1]); + if (!totem) + return; + + SpellInfo const* totemSpell = sSpellMgr->GetSpellInfo(totem->m_spells[0]); + if (!totemSpell) + return; + + int32 bp0 = CalculatePct(totemSpell->Effects[EFFECT_0].CalcValue(caster), aurEff->GetAmount()); + int32 bp1 = CalculatePct(totemSpell->Effects[EFFECT_1].CalcValue(caster), aurEff->GetAmount()); + caster->CastCustomSpell(caster, SPELL_SHAMAN_TOTEM_OF_WRATH_SPELL_POWER, &bp0, &bp1, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_glyph_of_totem_of_wrath::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_glyph_of_totem_of_wrath::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -16180 - Improved Water Shield +class spell_sha_imp_water_shield : public AuraScript +{ + PrepareAuraScript(spell_sha_imp_water_shield); + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return false; + + // If we're here, we've already passed initial aura roll + // So just chance based on 100% + + // Default chance for Healing Wave and Riptide + int32 chance = 100; + // Lesser Healing Wave - 0.6 of default + if (spellInfo->SpellFamilyFlags[0] & 0x00000080) + chance = 60; + // Chain heal - 0.3 of default + else if (spellInfo->SpellFamilyFlags[0] & 0x00000100) + chance = 30; + + if (!roll_chance_i(chance)) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + AuraEffect const* waterShield = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x00000000, 0x00000020, 0x00000000, caster->GetGUID()); + if (!waterShield) + return; + + uint32 spellId = waterShield->GetSpellInfo()->Effects[waterShield->GetEffIndex()].TriggerSpell; + caster->CastSpell(nullptr, spellId, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_imp_water_shield::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_imp_water_shield::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 40463 - Shaman Tier 6 Trinket +class spell_sha_item_t6_trinket : public AuraScript +{ + PrepareAuraScript(spell_sha_item_t6_trinket); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_SHAMAN_ENERGY_SURGE, + SPELL_SHAMAN_POWER_SURGE + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return; + + uint32 spellId; + int32 chance; + + // Lesser Healing Wave + if (spellInfo->SpellFamilyFlags[0] & 0x00000080) + { + spellId = SPELL_SHAMAN_ENERGY_SURGE; + chance = 10; + } + // Lightning Bolt + else if (spellInfo->SpellFamilyFlags[0] & 0x00000001) + { + spellId = SPELL_SHAMAN_ENERGY_SURGE; + chance = 15; + } + // Stormstrike + else if (spellInfo->SpellFamilyFlags[1] & 0x00000010) + { + spellId = SPELL_SHAMAN_POWER_SURGE; + chance = 50; + } + else + return; + + if (roll_chance_i(chance)) + eventInfo.GetActor()->CastSpell(nullptr, spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_item_t6_trinket::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 53817 - Maelstrom Weapon +class spell_sha_maelstrom_weapon : public AuraScript +{ + PrepareAuraScript(spell_sha_maelstrom_weapon); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_SHAMAN_MAELSTROM_POWER, + SPELL_SHAMAN_T10_ENHANCEMENT_4P_BONUS + }); + } + + void HandleBonus(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetStackAmount() < int32(GetSpellInfo()->StackAmount)) + return; + + Unit* caster = GetUnitOwner(); + AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_SHAMAN_T10_ENHANCEMENT_4P_BONUS, EFFECT_0); + if (!aurEff || !roll_chance_i(aurEff->GetAmount())) + return; + + caster->CastSpell(nullptr, SPELL_SHAMAN_MAELSTROM_POWER, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_sha_maelstrom_weapon::HandleBonus, EFFECT_0, SPELL_AURA_ADD_PCT_MODIFIER, AURA_EFFECT_HANDLE_CHANGE_AMOUNT); + } +}; + +// 30823 - Shamanistic Rage +class spell_sha_shamanistic_rage : public AuraScript +{ + PrepareAuraScript(spell_sha_shamanistic_rage); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_SHAMANISTIC_RAGE_PROC }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + Unit* target = GetTarget(); + int32 amount = CalculatePct(static_cast(target->GetTotalAttackPowerValue(BASE_ATTACK)), aurEff->GetAmount()); + target->CastCustomSpell(SPELL_SHAMAN_SHAMANISTIC_RAGE_PROC, SPELLVALUE_BASE_POINT0, amount, target, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_shamanistic_rage::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// -324 - Lightning Shield +class spell_sha_lightning_shield : public AuraScript +{ + PrepareAuraScript(spell_sha_lightning_shield); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_LIGHTNING_SHIELD_DAMAGE_R1 }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetActionTarget()) + return true; + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + uint32 triggerSpell = sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_LIGHTNING_SHIELD_DAMAGE_R1, aurEff->GetSpellInfo()->GetRank()); + eventInfo.GetActionTarget()->CastSpell(eventInfo.GetActor(), triggerSpell, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_lightning_shield::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_lightning_shield::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// -51525 - Static Shock +class spell_sha_static_shock : public AuraScript +{ + PrepareAuraScript(spell_sha_static_shock); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_LIGHTNING_SHIELD_DAMAGE_R1 }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + AuraEffect const* lightningShield = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x00000400, 0x00000000, 0x00000000, caster->GetGUID()); + if (!lightningShield) + return; + + uint32 spellId = sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_LIGHTNING_SHIELD_DAMAGE_R1, lightningShield->GetSpellInfo()->GetRank()); + eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), spellId, true, nullptr, aurEff); + lightningShield->GetBase()->DropCharge(); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_static_shock::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 70817 - Item - Shaman T10 Elemental 4P Bonus +class spell_sha_t10_elemental_4p_bonus : public AuraScript +{ + PrepareAuraScript(spell_sha_t10_elemental_4p_bonus); + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + // try to find spell Flame Shock on the target + AuraEffect* flameShock = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0x00000000, 0x00000000, caster->GetGUID()); + if (!flameShock) + return; + + Aura* flameShockAura = flameShock->GetBase(); + + int32 maxDuration = flameShockAura->GetMaxDuration(); + int32 newDuration = flameShockAura->GetDuration() + aurEff->GetAmount() * IN_MILLISECONDS; + + flameShockAura->SetDuration(newDuration); + // is it blizzlike to change max duration for FS? + if (newDuration > maxDuration) + flameShockAura->SetMaxDuration(newDuration); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_t10_elemental_4p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 28823 - Totemic Power (T3 6P Bonus) +class spell_sha_t3_6p_bonus : public AuraScript +{ + PrepareAuraScript(spell_sha_t3_6p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_SHAMAN_TOTEMIC_POWER_ARMOR, + SPELL_SHAMAN_TOTEMIC_POWER_ATTACK_POWER, + SPELL_SHAMAN_TOTEMIC_POWER_SPELL_POWER, + SPELL_SHAMAN_TOTEMIC_POWER_MP5 + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + uint32 spellId; + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + + switch (target->getClass()) + { + case CLASS_PALADIN: + case CLASS_PRIEST: + case CLASS_SHAMAN: + case CLASS_DRUID: + spellId = SPELL_SHAMAN_TOTEMIC_POWER_MP5; + break; + case CLASS_MAGE: + case CLASS_WARLOCK: + spellId = SPELL_SHAMAN_TOTEMIC_POWER_SPELL_POWER; + break; + case CLASS_HUNTER: + case CLASS_ROGUE: + spellId = SPELL_SHAMAN_TOTEMIC_POWER_ATTACK_POWER; + break; + case CLASS_WARRIOR: + spellId = SPELL_SHAMAN_TOTEMIC_POWER_ARMOR; + break; + default: + return; + } + + caster->CastSpell(target, spellId, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_t3_6p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 28820 - Lightning Shield (The Earthshatterer 8P Bonus) +class spell_sha_t3_8p_bonus : public AuraScript +{ + PrepareAuraScript(spell_sha_t3_8p_bonus); + + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + + // Need remove self if Lightning Shield not active + if (!GetTarget()->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x400, 0, 0)) + Remove(); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_sha_t3_8p_bonus::PeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; + +// 64928 - Item - Shaman T8 Elemental 4P Bonus +class spell_sha_t8_elemental_4p_bonus : public AuraScript +{ + PrepareAuraScript(spell_sha_t8_elemental_4p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_ELECTRIFIED }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ELECTRIFIED); + if (!spellInfo) + return; + + int32 amount = CalculatePct(static_cast(damageInfo->GetDamage()), aurEff->GetAmount()); + amount /= spellInfo->GetMaxTicks(); + + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + target->CastDelayedSpellWithPeriodicAmount(caster, SPELL_SHAMAN_ELECTRIFIED, SPELL_AURA_PERIODIC_DAMAGE, amount); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_t8_elemental_4p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 67228 - Item - Shaman T9 Elemental 4P Bonus (Lava Burst) +class spell_sha_t9_elemental_4p_bonus : public AuraScript +{ + PrepareAuraScript(spell_sha_t9_elemental_4p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_LAVA_BURST_BONUS_DAMAGE }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_BURST_BONUS_DAMAGE); + if (!spellInfo) + return; + + int32 amount = CalculatePct(static_cast(damageInfo->GetDamage()), aurEff->GetAmount()); + amount /= spellInfo->GetMaxTicks(); + + Unit* caster = eventInfo.GetActor(); + Unit* target = eventInfo.GetActionTarget(); + target->CastDelayedSpellWithPeriodicAmount(caster, SPELL_SHAMAN_LAVA_BURST_BONUS_DAMAGE, SPELL_AURA_PERIODIC_DAMAGE, amount); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_t9_elemental_4p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 55198 - Tidal Force +class spell_sha_tidal_force_dummy : public AuraScript +{ + PrepareAuraScript(spell_sha_tidal_force_dummy); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_TIDAL_FORCE_CRIT }); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + eventInfo.GetActor()->RemoveAuraFromStack(SPELL_SHAMAN_TIDAL_FORCE_CRIT); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_tidal_force_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -8232 - Windfury Weapon (Passive) +class spell_sha_windfury_weapon : public AuraScript +{ + PrepareAuraScript(spell_sha_windfury_weapon); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_SHAMAN_WINDFURY_WEAPON_R1, + SPELL_SHAMAN_WINDFURY_ATTACK_MH, + SPELL_SHAMAN_WINDFURY_ATTACK_OH + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + Player* player = eventInfo.GetActor()->ToPlayer(); + if (!player) + return false; + + Item* item = player->GetItemByGuid(GetAura()->GetCastItemGUID()); + if (!item || !item->IsEquipped()) + return false; + + WeaponAttackType attType = Player::GetAttackBySlot(item->GetSlot()); + if (attType != BASE_ATTACK && attType != OFF_ATTACK) + return false; + + if (((attType == BASE_ATTACK) && !(eventInfo.GetTypeMask() & PROC_FLAG_DONE_MAINHAND_ATTACK)) || + ((attType == OFF_ATTACK) && !(eventInfo.GetTypeMask() & PROC_FLAG_DONE_OFFHAND_ATTACK))) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Player* player = eventInfo.GetActor()->ToPlayer(); + Unit* target = eventInfo.GetActionTarget(); + if (!target) + return; + + Item* item = player->GetItemByGuid(GetAura()->GetCastItemGUID()); + if (!item) + return; + + uint8 slot = item->GetSlot(); + bool mainHand = slot == EQUIPMENT_SLOT_MAINHAND; + uint32 spellId = mainHand ? SPELL_SHAMAN_WINDFURY_ATTACK_MH : SPELL_SHAMAN_WINDFURY_ATTACK_OH; + + SpellInfo const* windfurySpellInfo = sSpellMgr->GetSpellInfo(SPELL_SHAMAN_WINDFURY_WEAPON_R1); + int32 bonus = windfurySpellInfo ? windfurySpellInfo->Effects[EFFECT_1].CalcValue(player) : 0; + bonus = int32(bonus * player->GetAttackTime(mainHand ? BASE_ATTACK : OFF_ATTACK) / 1000.f); + + player->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, bonus, target, true, item, aurEff); + player->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, bonus, target, true, item, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_sha_windfury_weapon::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_windfury_weapon::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + void AddSC_shaman_spell_scripts() { RegisterSpellScript(spell_sha_totem_of_wrath); @@ -1167,12 +2231,40 @@ void AddSC_shaman_spell_scripts() RegisterSpellScript(spell_sha_item_lightning_shield); RegisterSpellScript(spell_sha_item_lightning_shield_trigger); RegisterSpellScript(spell_sha_item_mana_surge); + RegisterSpellScript(spell_sha_elemental_focus); RegisterSpellScript(spell_sha_item_t10_elemental_2p_bonus); RegisterSpellScript(spell_sha_lava_lash); RegisterSpellScript(spell_sha_mana_spring_totem); + RegisterSpellScript(spell_sha_mana_tide); RegisterSpellScript(spell_sha_mana_tide_totem); + RegisterSpellScript(spell_sha_nature_guardian); RegisterSpellScript(spell_sha_sentry_totem); + RegisterSpellScript(spell_sha_stoneclaw_totem); RegisterSpellScript(spell_sha_thunderstorm); RegisterSpellScript(spell_sha_flurry_proc); RegisterSpellScript(spell_sha_t8_electrified); + RegisterSpellScript(spell_sha_glyph_of_healing_wave); + RegisterSpellScript(spell_sha_spirit_hunt); + RegisterSpellScript(spell_sha_frozen_power); + RegisterSpellScript(spell_sha_lightning_overload); + RegisterSpellScript(spell_sha_ancestral_awakening); + RegisterSpellScript(spell_sha_astral_shift_aura); + RegisterSpellScript(spell_sha_astral_shift_visual_dummy); + RegisterSpellScript(spell_sha_clearcasting); + RegisterSpellScript(spell_sha_flametongue_weapon); + RegisterSpellScript(spell_sha_glyph_of_earth_shield); + RegisterSpellScript(spell_sha_glyph_of_totem_of_wrath); + RegisterSpellScript(spell_sha_imp_water_shield); + RegisterSpellScript(spell_sha_item_t6_trinket); + RegisterSpellScript(spell_sha_maelstrom_weapon); + RegisterSpellScript(spell_sha_shamanistic_rage); + RegisterSpellScript(spell_sha_lightning_shield); + RegisterSpellScript(spell_sha_static_shock); + RegisterSpellScript(spell_sha_t10_elemental_4p_bonus); + RegisterSpellScript(spell_sha_t3_6p_bonus); + RegisterSpellScript(spell_sha_t3_8p_bonus); + RegisterSpellScript(spell_sha_t8_elemental_4p_bonus); + RegisterSpellScript(spell_sha_t9_elemental_4p_bonus); + RegisterSpellScript(spell_sha_tidal_force_dummy); + RegisterSpellScript(spell_sha_windfury_weapon); } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index e484b2b33..f424f242f 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -36,6 +36,7 @@ enum WarlockSpells { + SPELL_WARLOCK_SHADOW_TRANCE = 17941, SPELL_WARLOCK_DRAIN_SOUL_R1 = 1120, SPELL_WARLOCK_CREATE_SOULSHARD = 43836, SPELL_WARLOCK_CURSE_OF_DOOM_EFFECT = 18662, @@ -77,6 +78,22 @@ enum WarlockSpells SPELL_WARLOCK_PET_VOID_STAR_TALISMAN = 37386, // Void Star Talisman SPELL_WARLOCK_DEMONIC_PACT_PROC = 48090, SPELL_WARLOCK_GLYPH_OF_VOIDWALKER = 56247, + SPELL_WARLOCK_GLYPH_OF_LIFE_TAP_TRIGGERED = 63321, + SPELL_WARLOCK_SOUL_LEECH_HEAL = 30294, + SPELL_WARLOCK_IMP_SOUL_LEECH_R1 = 54117, + SPELL_WARLOCK_SOUL_LEECH_PET_MANA_1 = 54607, + SPELL_WARLOCK_SOUL_LEECH_PET_MANA_2 = 59118, + SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_1 = 54300, + SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_2 = 59117, + SPELL_WARLOCK_SHADOWFLAME_PROC = 37378, + SPELL_WARLOCK_FLAMESHADOW_PROC = 37379, + SPELL_REPLENISHMENT = 57669, + SPELL_WARLOCK_NETHER_PROTECTION_HOLY = 54370, + SPELL_WARLOCK_NETHER_PROTECTION_FIRE = 54371, + SPELL_WARLOCK_NETHER_PROTECTION_FROST = 54372, + SPELL_WARLOCK_NETHER_PROTECTION_ARCANE = 54373, + SPELL_WARLOCK_NETHER_PROTECTION_SHADOW = 54374, + SPELL_WARLOCK_NETHER_PROTECTION_NATURE = 54375, }; enum WarlockSpellIcons @@ -1458,8 +1475,483 @@ class spell_warl_demonic_pact_aura : public AuraScript } }; +// -980 - Curse of Agony +class spell_warl_curse_of_agony : public AuraScript +{ + PrepareAuraScript(spell_warl_curse_of_agony); + + void ApplyEffect(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + _tick_amount = aurEff->GetAmount(); + } + + void HandleEffectPeriodicUpdate(AuraEffect* aurEff) + { + switch (aurEff->GetTickNumber()) + { + // 1..4 ticks, 1/2 from normal tick damage + case 1: + aurEff->SetAmount(_tick_amount / 2); + break; + // 5..8 ticks have normal tick damage + case 5: + aurEff->SetAmount(_tick_amount); + break; + // 9..12 ticks, 3/2 from normal tick damage + case 9: + aurEff->SetAmount((_tick_amount + 1) * 3 / 2); // +1 prevent 0.5 damage possible lost at 1..4 ticks + break; + // 13 and 14 ticks (glyphed only), twice normal tick damage + case 13: + aurEff->SetAmount(_tick_amount * 2); + break; + } + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_warl_curse_of_agony::ApplyEffect, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_warl_curse_of_agony::HandleEffectPeriodicUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } +private: + uint32 _tick_amount = 0; +}; + +// 56218 - Glyph of Corruption +class spell_warl_glyph_of_corruption_nightfall : public AuraScript +{ + PrepareAuraScript(spell_warl_glyph_of_corruption_nightfall); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARLOCK_SHADOW_TRANCE }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + Unit* caster = eventInfo.GetActor(); + caster->CastSpell(caster, SPELL_WARLOCK_SHADOW_TRANCE, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warl_glyph_of_corruption_nightfall::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 18094, 18095 - Nightfall +class spell_warl_nightfall : public AuraScript +{ + PrepareAuraScript(spell_warl_nightfall); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARLOCK_SHADOW_TRANCE }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_WARLOCK_SHADOW_TRANCE, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warl_nightfall::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -63156 - Decimation +class spell_warl_decimation : public AuraScript +{ + PrepareAuraScript(spell_warl_decimation); + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) + if (eventInfo.GetActionTarget()->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellInfo, eventInfo.GetActor())) + return true; + + return false; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_warl_decimation::CheckProc); + } +}; + +// 54909, 53646 - Demonic Pact +class spell_warl_demonic_pact : public AuraScript +{ + PrepareAuraScript(spell_warl_demonic_pact); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARLOCK_DEMONIC_PACT_PROC }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetActor() && eventInfo.GetActor()->IsPet(); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + if (Unit* owner = eventInfo.GetActor()->GetOwner()) + { + if (AuraEffect* aurEff = owner->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, WARLOCK_ICON_ID_DEMONIC_PACT, EFFECT_0)) + { + int32 bp = static_cast((aurEff->GetAmount() * owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_MAGIC) + 100.0f) / 100.0f); + owner->CastCustomSpell(owner, SPELL_WARLOCK_DEMONIC_PACT_PROC, &bp, &bp, nullptr, true, nullptr, aurEff); + } + } + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_warl_demonic_pact::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warl_demonic_pact::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 63320 - Glyph of Life Tap +class spell_warl_glyph_of_life_tap : public AuraScript +{ + PrepareAuraScript(spell_warl_glyph_of_life_tap); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARLOCK_GLYPH_OF_LIFE_TAP_TRIGGERED }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + Unit* caster = GetTarget(); + caster->CastSpell(caster, SPELL_WARLOCK_GLYPH_OF_LIFE_TAP_TRIGGERED, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warl_glyph_of_life_tap::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 18213, 18372 - Improved Drain Soul (proc handler) +class spell_warl_improved_drain_soul : public AuraScript +{ + PrepareAuraScript(spell_warl_improved_drain_soul); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_WARLOCK_DRAIN_SOUL_R1, + SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_R1, + SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_PROC + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Make sure that dying unit is afflicted by the caster's Drain Soul debuff + Unit* caster = eventInfo.GetActor(); + Unit* victim = eventInfo.GetActionTarget(); + return victim->GetAuraApplicationOfRankedSpell(SPELL_WARLOCK_DRAIN_SOUL_R1, caster->GetGUID()) != nullptr; + } + + void HandleProc(ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + // Improved Drain Soul - use the current aura (this script is on the talent) + int32 amount = CalculatePct(caster->GetMaxPower(POWER_MANA), GetSpellInfo()->Effects[EFFECT_2].CalcValue()); + caster->CastCustomSpell(SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_PROC, SPELLVALUE_BASE_POINT0, amount, caster, true); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_warl_improved_drain_soul::CheckProc); + OnProc += AuraProcFn(spell_warl_improved_drain_soul::HandleProc); + } +}; + +// -27243 - Seed of Corruption (proc handler) +class spell_warl_seed_of_corruption_dummy : public AuraScript +{ + PrepareAuraScript(spell_warl_seed_of_corruption_dummy); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R1 }); + } + + void CalculateBuffer(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + Unit* caster = GetCaster(); + if (!caster) + return; + + amount = caster->SpellDamageBonusDone(GetUnitOwner(), GetSpellInfo(), amount, SPELL_DIRECT_DAMAGE, aurEff->GetEffIndex()); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + int32 amount = aurEff->GetAmount() - damageInfo->GetDamage(); + if (amount > 0) + { + const_cast(aurEff)->SetAmount(amount); + if (!GetTarget()->HealthBelowPctDamaged(1, damageInfo->GetDamage())) + return; + } + + Remove(); + + Unit* caster = GetCaster(); + if (!caster) + return; + + uint32 spellId = sSpellMgr->GetSpellWithRank(SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R1, GetSpellInfo()->GetRank()); + caster->CastSpell(eventInfo.GetActionTarget(), spellId, true, nullptr, aurEff); + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_seed_of_corruption_dummy::CalculateBuffer, EFFECT_1, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_warl_seed_of_corruption_dummy::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + } +}; + +// 32863, 36123, 38252, 39367, 44141, 70388 - Seed of Corruption (generic) +class spell_warl_seed_of_corruption_generic : public AuraScript +{ + PrepareAuraScript(spell_warl_seed_of_corruption_generic); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_GENERIC }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + int32 amount = aurEff->GetAmount() - damageInfo->GetDamage(); + if (amount > 0) + { + const_cast(aurEff)->SetAmount(amount); + return; + } + + Remove(); + + Unit* caster = GetCaster(); + if (!caster) + return; + + caster->CastSpell(eventInfo.GetActionTarget(), SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_GENERIC, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warl_seed_of_corruption_generic::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + } +}; + +// -30293 - Soul Leech +class spell_warl_soul_leech : public AuraScript +{ + PrepareAuraScript(spell_warl_soul_leech); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_WARLOCK_SOUL_LEECH_HEAL, + SPELL_WARLOCK_IMP_SOUL_LEECH_R1, + SPELL_WARLOCK_SOUL_LEECH_PET_MANA_1, + SPELL_WARLOCK_SOUL_LEECH_PET_MANA_2, + SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_1, + SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_2, + SPELL_REPLENISHMENT + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + static uint32 const casterMana[2] = { SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_1, SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_2 }; + static uint32 const petMana[2] = { SPELL_WARLOCK_SOUL_LEECH_PET_MANA_1, SPELL_WARLOCK_SOUL_LEECH_PET_MANA_2 }; + + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + Unit* caster = eventInfo.GetActor(); + int32 healAmount = CalculatePct(static_cast(damageInfo->GetDamage()), aurEff->GetAmount()); + caster->CastCustomSpell(SPELL_WARLOCK_SOUL_LEECH_HEAL, SPELLVALUE_BASE_POINT0, healAmount, caster, true, nullptr, aurEff); + + // Improved Soul Leech code below + AuraEffect const* impSoulLeech = GetTarget()->GetAuraEffectOfRankedSpell(SPELL_WARLOCK_IMP_SOUL_LEECH_R1, EFFECT_1, aurEff->GetCasterGUID()); + if (!impSoulLeech) + return; + + uint8 impSoulLeechRank = impSoulLeech->GetSpellInfo()->GetRank(); + uint32 selfSpellId = casterMana[impSoulLeechRank - 1]; + uint32 petSpellId = petMana[impSoulLeechRank - 1]; + + caster->CastSpell(nullptr, selfSpellId, true, nullptr, aurEff); + caster->CastSpell(nullptr, petSpellId, true, nullptr, aurEff); + + if (roll_chance_i(impSoulLeech->GetAmount())) + caster->CastSpell(nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warl_soul_leech::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 37377 - Shadowflame (T4 2P fire) +class spell_warl_t4_2p_bonus_fire : public AuraScript +{ + PrepareAuraScript(spell_warl_t4_2p_bonus_fire); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARLOCK_SHADOWFLAME_PROC }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_WARLOCK_SHADOWFLAME_PROC, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warl_t4_2p_bonus_fire::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 39437 - Shadowflame Hellfire and RoF (T4 2P shadow) +class spell_warl_t4_2p_bonus_shadow : public AuraScript +{ + PrepareAuraScript(spell_warl_t4_2p_bonus_shadow); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARLOCK_FLAMESHADOW_PROC }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_WARLOCK_FLAMESHADOW_PROC, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warl_t4_2p_bonus_shadow::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// -30299 - Nether Protection +class spell_warl_nether_protection : public AuraScript +{ + PrepareAuraScript(spell_warl_nether_protection); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_WARLOCK_NETHER_PROTECTION_HOLY, + SPELL_WARLOCK_NETHER_PROTECTION_FIRE, + SPELL_WARLOCK_NETHER_PROTECTION_NATURE, + SPELL_WARLOCK_NETHER_PROTECTION_FROST, + SPELL_WARLOCK_NETHER_PROTECTION_SHADOW, + SPELL_WARLOCK_NETHER_PROTECTION_ARCANE + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (DamageInfo* damageInfo = eventInfo.GetDamageInfo()) + { + switch (GetFirstSchoolInMask(damageInfo->GetSchoolMask())) + { + case SPELL_SCHOOL_HOLY: + case SPELL_SCHOOL_FIRE: + case SPELL_SCHOOL_NATURE: + case SPELL_SCHOOL_FROST: + case SPELL_SCHOOL_SHADOW: + case SPELL_SCHOOL_ARCANE: + return true; + default: + break; + } + } + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + uint32 triggerspell = 0; + + switch (GetFirstSchoolInMask(eventInfo.GetDamageInfo()->GetSchoolMask())) + { + case SPELL_SCHOOL_HOLY: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_HOLY; + break; + case SPELL_SCHOOL_FIRE: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_FIRE; + break; + case SPELL_SCHOOL_NATURE: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_NATURE; + break; + case SPELL_SCHOOL_FROST: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_FROST; + break; + case SPELL_SCHOOL_SHADOW: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_SHADOW; + break; + case SPELL_SCHOOL_ARCANE: + triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_ARCANE; + break; + default: + return; + } + + if (Unit* target = eventInfo.GetActionTarget()) + target->CastSpell(target, triggerspell, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_warl_nether_protection::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warl_nether_protection::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + void AddSC_warlock_spell_scripts() { + RegisterSpellScript(spell_warl_nether_protection); RegisterSpellScript(spell_warl_eye_of_kilrogg); RegisterSpellScript(spell_warl_shadowflame); RegisterSpellScript(spell_warl_seduction); @@ -1493,4 +1985,16 @@ void AddSC_warlock_spell_scripts() RegisterSpellScript(spell_warl_shadowburn); RegisterSpellScript(spell_warl_voidwalker_pet_passive); RegisterSpellScript(spell_warl_demonic_pact_aura); + RegisterSpellScript(spell_warl_curse_of_agony); + RegisterSpellScript(spell_warl_glyph_of_corruption_nightfall); + RegisterSpellScript(spell_warl_nightfall); + RegisterSpellScript(spell_warl_decimation); + RegisterSpellScript(spell_warl_demonic_pact); + RegisterSpellScript(spell_warl_glyph_of_life_tap); + RegisterSpellScript(spell_warl_improved_drain_soul); + RegisterSpellScript(spell_warl_seed_of_corruption_dummy); + RegisterSpellScript(spell_warl_seed_of_corruption_generic); + RegisterSpellScript(spell_warl_soul_leech); + RegisterSpellScript(spell_warl_t4_2p_bonus_fire); + RegisterSpellScript(spell_warl_t4_2p_bonus_shadow); } diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index ba6e24c28..421875469 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -62,11 +62,22 @@ enum WarriorSpells SPELL_WARRIOR_WHIRLWIND_MAIN = 50622, SPELL_WARRIOR_WHIRLWIND_OFF = 44949, SPELL_WARRIOR_EXECUTE_R1 = 5308, + SPELL_WARRIOR_SECOND_WIND_HEAL_R1 = 29841, + SPELL_WARRIOR_SECOND_WIND_HEAL_R2 = 29842, + SPELL_WARRIOR_SECOND_WIND_UK = 42771, + SPELL_WARRIOR_T10_PROT_4P_ABSORB = 70845, + SPELL_WARRIOR_GLYPH_OF_BLOCKING_BUFF = 58374, + SPELL_WARRIOR_T10_MELEE_4P_BONUS = 70847, + SPELL_WARRIOR_T10_MELEE_4P_EXTRA_CHARGE = 70849, + SPELL_WARRIOR_SLAM_GCD_REDUCED = 71072, + SPELL_WARRIOR_EXECUTE_GCD_REDUCED = 71069, + SPELL_WARRIOR_WARRIORS_WRATH = 21887, }; enum WarriorSpellIcons { - WARRIOR_ICON_ID_SUDDEN_DEATH = 1989 + WARRIOR_ICON_ID_SUDDEN_DEATH = 1989, + WARRIOR_ICON_ID_SECOND_WIND = 1697 }; enum MiscSpells @@ -726,17 +737,6 @@ class spell_warr_vigilance : public AuraScript target->CastSpell(caster, SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT, true); } - void HandleAfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - //! WORKAROUND - //! this glyph is a proc - if (Unit* caster = GetCaster()) - { - if (AuraEffect const* glyph = caster->GetAuraEffect(SPELL_WARRIOR_GLYPH_OF_VIGILANCE, EFFECT_0)) - GetTarget()->ModifyRedirectThreat(glyph->GetAmount()); - } - } - void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); @@ -766,7 +766,6 @@ class spell_warr_vigilance : public AuraScript void Register() override { OnEffectApply += AuraEffectApplyFn(spell_warr_vigilance::HandleApply, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - AfterEffectApply += AuraEffectApplyFn(spell_warr_vigilance::HandleAfterApply, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); OnEffectRemove += AuraEffectRemoveFn(spell_warr_vigilance::HandleRemove, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); DoCheckProc += AuraCheckProcFn(spell_warr_vigilance::CheckProc); OnEffectProc += AuraEffectProcFn(spell_warr_vigilance::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); @@ -776,6 +775,29 @@ private: Unit* _procTarget; }; +// 59665 - Vigilance (Redirect Threat) +class spell_warr_vigilance_redirect_threat : public SpellScript +{ + PrepareSpellScript(spell_warr_vigilance_redirect_threat); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARRIOR_GLYPH_OF_VIGILANCE }); + } + + void HandleGlyph(SpellEffIndex /*effIndex*/) + { + if (Unit* warrior = GetHitUnit()) + if (AuraEffect const* glyph = warrior->GetAuraEffect(SPELL_WARRIOR_GLYPH_OF_VIGILANCE, EFFECT_0)) + SetEffectValue(GetEffectValue() + glyph->GetAmount()); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_warr_vigilance_redirect_threat::HandleGlyph, EFFECT_0, SPELL_EFFECT_REDIRECT_THREAT); + } +}; + // 50725 - Vigilance class spell_warr_vigilance_trigger : public SpellScript { @@ -826,35 +848,27 @@ class spell_warr_glyph_of_sunder_armor : public AuraScript } }; -// Spell 28845 - Cheat Death - -enum CheatDeath -{ - SPELL_CHEAT_DEATH_TRIGGER = 28846 -}; - +// 28845 - Cheat Death class spell_warr_t3_prot_8p_bonus : public AuraScript { PrepareAuraScript(spell_warr_t3_prot_8p_bonus); bool CheckProc(ProcEventInfo& eventInfo) { - return eventInfo.GetActionTarget() && eventInfo.GetActionTarget()->GetHealthPct() <= 20.0f; - } + if (eventInfo.GetActionTarget()->HealthBelowPct(20)) + return true; - void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - if (Unit* target = eventInfo.GetActionTarget()) - { - target->CastSpell(target, SPELL_CHEAT_DEATH_TRIGGER, true); - } + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (damageInfo && damageInfo->GetDamage()) + if (GetTarget()->HealthBelowPctDamaged(20, damageInfo->GetDamage())) + return true; + + return false; } void Register() override { DoCheckProc += AuraCheckProcFn(spell_warr_t3_prot_8p_bonus::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_warr_t3_prot_8p_bonus::HandleEffectProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -980,6 +994,235 @@ class spell_war_sudden_death_aura : public AuraScript } }; +// Second Wind - triggers health regen when stunned or immobilized +class spell_warr_second_wind : public AuraScript +{ + PrepareAuraScript(spell_warr_second_wind); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_WARRIOR_SECOND_WIND_HEAL_R1, + SPELL_WARRIOR_SECOND_WIND_HEAL_R2, + SPELL_WARRIOR_SECOND_WIND_UK + }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + if (!procSpell) + return false; + + // Must be from stun or root mechanic + if (!(procSpell->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN)))) + return false; + + // Not from self + if (eventInfo.GetActionTarget() == eventInfo.GetActor()) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + uint32 triggeredSpellId = 0; + switch (GetId()) + { + case 29838: triggeredSpellId = SPELL_WARRIOR_SECOND_WIND_HEAL_R2; break; + case 29834: triggeredSpellId = SPELL_WARRIOR_SECOND_WIND_HEAL_R1; break; + case 42770: triggeredSpellId = SPELL_WARRIOR_SECOND_WIND_UK; break; + default: + return; + } + + GetTarget()->CastSpell(GetTarget(), triggeredSpellId, true, nullptr, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_warr_second_wind::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warr_second_wind::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// Deep Wounds - calculates bleed damage based on weapon damage +class spell_warr_deep_wounds_aura : public AuraScript +{ + PrepareAuraScript(spell_warr_deep_wounds_aura); + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = GetTarget(); + if (!caster->IsPlayer()) + return; + + int32 basepoints; + if (eventInfo.GetTypeMask() & PROC_FLAG_DONE_OFFHAND_ATTACK) + basepoints = int32((caster->GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE) + caster->GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE)) / 2.0f); + else + basepoints = int32((caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE) + caster->GetFloatValue(UNIT_FIELD_MINDAMAGE)) / 2.0f); + + uint32 triggeredSpellId = GetSpellInfo()->Effects[EFFECT_0].TriggerSpell; + if (Unit* target = eventInfo.GetActionTarget()) + caster->CastCustomSpell(target, triggeredSpellId, &basepoints, nullptr, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warr_deep_wounds_aura::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// Warrior T10 Melee 4P Bonus - extra effects for Sudden Death/Bloodsurge procs +class spell_warr_extra_proc : public AuraScript +{ + PrepareAuraScript(spell_warr_extra_proc); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ + SPELL_WARRIOR_T10_MELEE_4P_BONUS, + SPELL_WARRIOR_T10_MELEE_4P_EXTRA_CHARGE, + SPELL_WARRIOR_SLAM_GCD_REDUCED, + SPELL_WARRIOR_EXECUTE_GCD_REDUCED + }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + Unit* caster = GetTarget(); + uint32 triggeredSpellId = GetSpellInfo()->Effects[EFFECT_0].TriggerSpell; + + // Triggered spell IDs: 46916 = Slam!, 52437 = Sudden Death + bool isBloodsurge = (triggeredSpellId == 46916); + + // Item - Warrior T10 Melee 4P Bonus + if (AuraEffect const* t10Bonus = caster->GetAuraEffect(SPELL_WARRIOR_T10_MELEE_4P_BONUS, EFFECT_0)) + { + if (!roll_chance_i(t10Bonus->GetAmount())) + { + // Don't allow normal proc to override set one + if (caster->GetAura(isBloodsurge ? SPELL_WARRIOR_SLAM_GCD_REDUCED : SPELL_WARRIOR_EXECUTE_GCD_REDUCED)) + { + PreventDefaultAction(); + return; + } + // Just to be sure + caster->RemoveAurasDueToSpell(SPELL_WARRIOR_T10_MELEE_4P_EXTRA_CHARGE); + return; + } + + PreventDefaultAction(); + + // Fully remove all auras and reapply once more + caster->RemoveAurasDueToSpell(SPELL_WARRIOR_T10_MELEE_4P_EXTRA_CHARGE); + caster->RemoveAurasDueToSpell(SPELL_WARRIOR_SLAM_GCD_REDUCED); + caster->RemoveAurasDueToSpell(SPELL_WARRIOR_EXECUTE_GCD_REDUCED); + + caster->CastSpell(caster, SPELL_WARRIOR_T10_MELEE_4P_EXTRA_CHARGE, true, nullptr, aurEff); + caster->CastSpell(caster, triggeredSpellId, true, nullptr, aurEff); + caster->CastSpell(caster, isBloodsurge ? SPELL_WARRIOR_SLAM_GCD_REDUCED : SPELL_WARRIOR_EXECUTE_GCD_REDUCED, true, nullptr, aurEff); + } + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warr_extra_proc::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// Sword and Board proc - remove Shield Slam cooldown +class spell_warr_sword_and_board : public AuraScript +{ + PrepareAuraScript(spell_warr_sword_and_board); + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + Unit* caster = GetTarget(); + if (caster->IsPlayer()) + caster->ToPlayer()->RemoveCategoryCooldown(1209); // Shield Slam category + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warr_sword_and_board::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// Glyph of Blocking - triggers block value buff +class spell_warr_glyph_of_blocking : public AuraScript +{ + PrepareAuraScript(spell_warr_glyph_of_blocking); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARRIOR_GLYPH_OF_BLOCKING_BUFF }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_WARRIOR_GLYPH_OF_BLOCKING_BUFF, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warr_glyph_of_blocking::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// Item - Warrior T10 Protection 4P Bonus +class spell_warr_item_t10_prot_4p_bonus : public AuraScript +{ + PrepareAuraScript(spell_warr_item_t10_prot_4p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARRIOR_T10_PROT_4P_ABSORB }); + } + + void HandleProc(ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + Unit* caster = GetTarget(); + int32 basepoints = CalculatePct(static_cast(caster->GetMaxHealth()), GetSpellInfo()->Effects[EFFECT_1].CalcValue()); + caster->CastCustomSpell(caster, SPELL_WARRIOR_T10_PROT_4P_ABSORB, &basepoints, nullptr, nullptr, true, nullptr, GetEffect(EFFECT_0)); + } + + void Register() override + { + OnProc += AuraProcFn(spell_warr_item_t10_prot_4p_bonus::HandleProc); + } +}; + +// 21977 - Warrior's Wrath (T3 8P Bonus) +class spell_warr_warriors_wrath : public SpellScript +{ + PrepareSpellScript(spell_warr_warriors_wrath); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARRIOR_WARRIORS_WRATH }); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), SPELL_WARRIOR_WARRIORS_WRATH, true); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_warr_warriors_wrath::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + void AddSC_warrior_spell_scripts() { RegisterSpellScript(spell_warr_mocking_blow); @@ -1004,8 +1247,16 @@ void AddSC_warrior_spell_scripts() RegisterSpellScript(spell_warr_slam); RegisterSpellScript(spell_warr_sweeping_strikes); RegisterSpellScript(spell_warr_vigilance); + RegisterSpellScript(spell_warr_vigilance_redirect_threat); RegisterSpellScript(spell_warr_vigilance_trigger); + RegisterSpellScript(spell_warr_warriors_wrath); RegisterSpellScript(spell_warr_t3_prot_8p_bonus); RegisterSpellScript(spell_warr_heroic_strike); RegisterSpellScript(spell_war_sudden_death_aura); + RegisterSpellScript(spell_warr_second_wind); + RegisterSpellScript(spell_warr_deep_wounds_aura); + RegisterSpellScript(spell_warr_extra_proc); + RegisterSpellScript(spell_warr_sword_and_board); + RegisterSpellScript(spell_warr_glyph_of_blocking); + RegisterSpellScript(spell_warr_item_t10_prot_4p_bonus); } diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index 7a07c16e6..31b1f84f7 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -390,7 +390,7 @@ uint32 constexpr QuestDifficultyColors[MAX_QUEST_DIFFICULTY] = // EnumUtils: DESCRIBE THIS enum SpellAttr0 : uint32 { - SPELL_ATTR0_PROC_FAILURE_BURNS_CHARGE = 0x00000001, // TITLE Unknown attribute 0@Attr0 + SPELL_ATTR0_PROC_FAILURE_BURNS_CHARGE = 0x00000001, // TITLE Proc Failure Burns Charge SPELL_ATTR0_USES_RANGED_SLOT = 0x00000002, // TITLE Treat as ranged attack DESCRIPTION Use ammo, ranged attack range modifiers, ranged haste, etc. SPELL_ATTR0_ON_NEXT_SWING_NO_DAMAGE = 0x00000004, // TITLE On next melee (type 1) DESCRIPTION Both "on next swing" attributes have identical handling in server & client SPELL_ATTR0_DO_NOT_LOG_IMMUNE_MISSES = 0x00000008, // TITLE Replenishment (client only) @@ -487,7 +487,7 @@ enum SpellAttr2 : uint32 SPELL_ATTR2_INITIATE_COMBAT_POST_CAST = 0x00100000, // TITLE (Enables Auto-Attack) SPELL_ATTR2_FAIL_ON_ALL_TARGETS_IMMUNE = 0x00200000, // TITLE Damage reduction ability DESCRIPTION Causes BG flags to be dropped if combined with ATTR1_DISPEL_AURAS_ON_IMMUNITY SPELL_ATTR2_NO_INITIAL_THREAD = 0x00400000, // TITLE Unknown attribute 22@Attr2 DESCRIPTION Ambush, Backstab, Cheap Shot, Death Grip, Garrote, Judgements, Mutilate, Pounce, Ravage, Shiv, Shred - SPELL_ATTR2_PROC_COOLDOWN_ON_FAILURE = 0x00800000, // TITLE Arcane Concentration + SPELL_ATTR2_PROC_COOLDOWN_ON_FAILURE = 0x00800000, // TITLE Proc Cooldown On Failure SPELL_ATTR2_ITEM_CAST_WITH_OWNER_SKILL = 0x01000000, // TITLE Unknown attribute 24@Attr2 SPELL_ATTR2_DONT_BLOCK_MANA_REGEN = 0x02000000, // TITLE Unknown attribute 25@Attr2 SPELL_ATTR2_NO_SCHOOL_IMMUNITIES = 0x04000000, // TITLE Pierce aura application immunities DESCRIPTION Allow aura to be applied despite target being immune to new aura applications diff --git a/src/server/shared/enuminfo_SharedDefines.cpp b/src/server/shared/enuminfo_SharedDefines.cpp index 53e4ec80c..d8e6f7634 100644 --- a/src/server/shared/enuminfo_SharedDefines.cpp +++ b/src/server/shared/enuminfo_SharedDefines.cpp @@ -158,7 +158,7 @@ AC_API_EXPORT EnumText EnumUtils::ToString(SpellAttr0 value) { switch (value) { - case SPELL_ATTR0_PROC_FAILURE_BURNS_CHARGE: return { "SPELL_ATTR0_PROC_FAILURE_BURNS_CHARGE", "Unknown attribute 0@Attr0", "" }; + case SPELL_ATTR0_PROC_FAILURE_BURNS_CHARGE: return { "SPELL_ATTR0_PROC_FAILURE_BURNS_CHARGE", "Proc Failure Burns Charge", "" }; case SPELL_ATTR0_USES_RANGED_SLOT: return { "SPELL_ATTR0_USES_RANGED_SLOT", "Treat as ranged attack", "Use ammo, ranged attack range modifiers, ranged haste, etc." }; case SPELL_ATTR0_ON_NEXT_SWING_NO_DAMAGE: return { "SPELL_ATTR0_ON_NEXT_SWING_NO_DAMAGE", "On next melee (type 1)", "Both \042on next swing\042 attributes have identical handling in server & client" }; case SPELL_ATTR0_DO_NOT_LOG_IMMUNE_MISSES: return { "SPELL_ATTR0_DO_NOT_LOG_IMMUNE_MISSES", "Replenishment (client only)", "" }; @@ -439,7 +439,7 @@ AC_API_EXPORT EnumText EnumUtils::ToString(SpellAttr2 value) case SPELL_ATTR2_INITIATE_COMBAT_POST_CAST: return { "SPELL_ATTR2_INITIATE_COMBAT_POST_CAST", "(Enables Auto-Attack)", "" }; case SPELL_ATTR2_FAIL_ON_ALL_TARGETS_IMMUNE: return { "SPELL_ATTR2_FAIL_ON_ALL_TARGETS_IMMUNE", "Damage reduction ability", "Causes BG flags to be dropped if combined with ATTR1_DISPEL_AURAS_ON_IMMUNITY" }; case SPELL_ATTR2_NO_INITIAL_THREAD: return { "SPELL_ATTR2_NO_INITIAL_THREAD", "Unknown attribute 22@Attr2", "Ambush, Backstab, Cheap Shot, Death Grip, Garrote, Judgements, Mutilate, Pounce, Ravage, Shiv, Shred" }; - case SPELL_ATTR2_PROC_COOLDOWN_ON_FAILURE: return { "SPELL_ATTR2_PROC_COOLDOWN_ON_FAILURE", "Arcane Concentration", "" }; + case SPELL_ATTR2_PROC_COOLDOWN_ON_FAILURE: return { "SPELL_ATTR2_PROC_COOLDOWN_ON_FAILURE", "Proc Cooldown On Failure", "" }; case SPELL_ATTR2_ITEM_CAST_WITH_OWNER_SKILL: return { "SPELL_ATTR2_ITEM_CAST_WITH_OWNER_SKILL", "Unknown attribute 24@Attr2", "" }; case SPELL_ATTR2_DONT_BLOCK_MANA_REGEN: return { "SPELL_ATTR2_DONT_BLOCK_MANA_REGEN", "Unknown attribute 25@Attr2", "" }; case SPELL_ATTR2_NO_SCHOOL_IMMUNITIES: return { "SPELL_ATTR2_NO_SCHOOL_IMMUNITIES", "Pierce aura application immunities", "Allow aura to be applied despite target being immune to new aura applications" }; diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index bf5386d5b..6a143748c 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -15,7 +15,7 @@ CollectSourceFiles( ) include_directories( - "mocks" + "${CMAKE_CURRENT_SOURCE_DIR}/mocks" ) add_executable( diff --git a/src/test/mocks/AuraScriptTestFramework.h b/src/test/mocks/AuraScriptTestFramework.h new file mode 100644 index 000000000..9b620cdf6 --- /dev/null +++ b/src/test/mocks/AuraScriptTestFramework.h @@ -0,0 +1,484 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef AZEROTHCORE_AURA_SCRIPT_TEST_FRAMEWORK_H +#define AZEROTHCORE_AURA_SCRIPT_TEST_FRAMEWORK_H + +#include "AuraStub.h" +#include "DamageHealInfoStub.h" +#include "ProcEventInfoHelper.h" +#include "SpellInfoTestHelper.h" +#include "UnitStub.h" +#include "SpellMgr.h" +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include +#include + +/** + * @brief Simulated proc result for testing + */ +struct ProcTestResult +{ + bool shouldProc = false; + uint8_t effectMask = 0; + float procChance = 100.0f; + std::vector spellsCast; + bool chargeConsumed = false; + bool cooldownSet = false; +}; + +/** + * @brief Context for a proc test scenario + */ +class ProcTestContext +{ +public: + ProcTestContext() = default; + + // Actor (the one doing something that triggers the proc) + UnitStub& GetActor() { return _actor; } + UnitStub const& GetActor() const { return _actor; } + + // Target (the one being affected) + UnitStub& GetTarget() { return _target; } + UnitStub const& GetTarget() const { return _target; } + + // The aura that might proc + AuraStub& GetAura() { return _aura; } + AuraStub const& GetAura() const { return _aura; } + + // Damage info for damage-based procs + DamageInfoStub& GetDamageInfo() { return _damageInfo; } + DamageInfoStub const& GetDamageInfo() const { return _damageInfo; } + + // Heal info for heal-based procs + HealInfoStub& GetHealInfo() { return _healInfo; } + HealInfoStub const& GetHealInfo() const { return _healInfo; } + + // Setup methods + ProcTestContext& WithAuraId(uint32_t auraId) + { + _aura.SetId(auraId); + return *this; + } + + ProcTestContext& WithAuraSpellFamily(uint32_t familyName) + { + _aura.SetSpellFamilyName(familyName); + return *this; + } + + ProcTestContext& WithAuraCharges(uint8_t charges) + { + _aura.SetCharges(charges); + _aura.SetUsingCharges(charges > 0); + return *this; + } + + ProcTestContext& WithActorAsPlayer(bool isPlayer = true) + { + _actor.SetIsPlayer(isPlayer); + return *this; + } + + ProcTestContext& WithDamage(uint32_t damage, uint32_t schoolMask = 1) + { + _damageInfo.SetDamage(damage); + _damageInfo.SetOriginalDamage(damage); + _damageInfo.SetSchoolMask(schoolMask); + return *this; + } + + ProcTestContext& WithHeal(uint32_t heal, uint32_t effectiveHeal = 0) + { + _healInfo.SetHeal(heal); + _healInfo.SetEffectiveHeal(effectiveHeal > 0 ? effectiveHeal : heal); + return *this; + } + + ProcTestContext& WithCriticalHit() + { + _damageInfo.SetHitMask(PROC_HIT_CRITICAL); + _healInfo.SetHitMask(PROC_HIT_CRITICAL); + return *this; + } + + ProcTestContext& WithNormalHit() + { + _damageInfo.SetHitMask(PROC_HIT_NORMAL); + _healInfo.SetHitMask(PROC_HIT_NORMAL); + return *this; + } + +private: + UnitStub _actor; + UnitStub _target; + AuraStub _aura; + DamageInfoStub _damageInfo; + HealInfoStub _healInfo; +}; + +/** + * @brief Base fixture for AuraScript proc testing + * + * This provides infrastructure for testing proc behavior at the unit level + * without requiring full game objects. + */ +class AuraScriptProcTestFixture : public ::testing::Test +{ +protected: + void SetUp() override + { + _context = std::make_unique(); + _spellInfos.clear(); + } + + void TearDown() override + { + for (auto* spellInfo : _spellInfos) + { + delete spellInfo; + } + _spellInfos.clear(); + } + + // Access the test context + ProcTestContext& Context() { return *_context; } + + // Create and track a test SpellInfo + SpellInfo* CreateSpellInfo(uint32_t id, uint32_t familyName = 0, + uint32_t familyFlags0 = 0, uint32_t familyFlags1 = 0, + uint32_t familyFlags2 = 0) + { + auto* spellInfo = SpellInfoBuilder() + .WithId(id) + .WithSpellFamilyName(familyName) + .WithSpellFamilyFlags(familyFlags0, familyFlags1, familyFlags2) + .Build(); + _spellInfos.push_back(spellInfo); + return spellInfo; + } + + // Create a test SpellProcEntry + SpellProcEntry CreateProcEntry() + { + return SpellProcEntryBuilder().Build(); + } + + // Create a test ProcEventInfo + ProcEventInfo CreateEventInfo(uint32_t typeMask, uint32_t hitMask, + uint32_t spellTypeMask = PROC_SPELL_TYPE_MASK_ALL, + uint32_t spellPhaseMask = PROC_SPELL_PHASE_HIT) + { + return ProcEventInfoBuilder() + .WithTypeMask(typeMask) + .WithHitMask(hitMask) + .WithSpellTypeMask(spellTypeMask) + .WithSpellPhaseMask(spellPhaseMask) + .Build(); + } + + // Test if a proc entry would trigger with given event info + bool TestCanProc(SpellProcEntry const& procEntry, uint32_t typeMask, + uint32_t hitMask, SpellInfo const* triggerSpell = nullptr) + { + DamageInfo* damageInfoPtr = nullptr; + HealInfo* healInfoPtr = nullptr; + + // Create real DamageInfo/HealInfo if we have a trigger spell + // Note: This requires the actual game classes, which may need adjustment + // For now, we use the stub approach + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(typeMask) + .WithHitMask(hitMask) + .WithSpellTypeMask(PROC_SPELL_TYPE_MASK_ALL) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + return sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo); + } + + // Check if spell family matches + bool TestSpellFamilyMatch(uint32_t procFamilyName, flag96 const& procFamilyMask, + SpellInfo const* triggerSpell) + { + if (procFamilyName && triggerSpell) + { + if (procFamilyName != triggerSpell->SpellFamilyName) + return false; + + if (procFamilyMask) + { + flag96 triggerMask; + triggerMask[0] = triggerSpell->SpellFamilyFlags[0]; + triggerMask[1] = triggerSpell->SpellFamilyFlags[1]; + triggerMask[2] = triggerSpell->SpellFamilyFlags[2]; + + if (!(triggerMask & procFamilyMask)) + return false; + } + } + return true; + } + +private: + std::unique_ptr _context; + std::vector _spellInfos; +}; + +/** + * @brief Helper class for testing specific proc scenarios + * + * Uses shared_ptr for resource management to allow safe copying + * in fluent builder pattern usage. + */ +class ProcScenarioBuilder +{ +public: + ProcScenarioBuilder() + { + // Create a default SpellInfo for spell-type procs using shared_ptr + _defaultSpellInfo = std::shared_ptr( + SpellInfoBuilder() + .WithId(99999) + .WithSpellFamilyName(0) + .Build() + ); + } + + ~ProcScenarioBuilder() = default; + + // Configure the triggering action + ProcScenarioBuilder& OnMeleeAutoAttack() + { + _typeMask = PROC_FLAG_DONE_MELEE_AUTO_ATTACK; + _needsSpellInfo = false; + return *this; + } + + ProcScenarioBuilder& OnTakenMeleeAutoAttack() + { + _typeMask = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK; + _needsSpellInfo = false; + return *this; + } + + ProcScenarioBuilder& OnSpellDamage() + { + _typeMask = PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG; + _spellTypeMask = PROC_SPELL_TYPE_DAMAGE; + _needsSpellInfo = true; + _usesDamageInfo = true; + return *this; + } + + ProcScenarioBuilder& OnTakenSpellDamage() + { + _typeMask = PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG; + _spellTypeMask = PROC_SPELL_TYPE_DAMAGE; + _needsSpellInfo = true; + _usesDamageInfo = true; + return *this; + } + + ProcScenarioBuilder& OnHeal() + { + _typeMask = PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS; + _spellTypeMask = PROC_SPELL_TYPE_HEAL; + _needsSpellInfo = true; + _usesHealInfo = true; + return *this; + } + + ProcScenarioBuilder& OnTakenHeal() + { + _typeMask = PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS; + _spellTypeMask = PROC_SPELL_TYPE_HEAL; + _needsSpellInfo = true; + _usesHealInfo = true; + return *this; + } + + ProcScenarioBuilder& OnPeriodicDamage() + { + _typeMask = PROC_FLAG_DONE_PERIODIC; + _spellTypeMask = PROC_SPELL_TYPE_DAMAGE; + _needsSpellInfo = true; + _usesDamageInfo = true; + return *this; + } + + ProcScenarioBuilder& OnPeriodicHeal() + { + _typeMask = PROC_FLAG_DONE_PERIODIC; + _spellTypeMask = PROC_SPELL_TYPE_HEAL; + _needsSpellInfo = true; + _usesHealInfo = true; + return *this; + } + + ProcScenarioBuilder& OnKill() + { + _typeMask = PROC_FLAG_KILL; + _needsSpellInfo = false; + return *this; + } + + ProcScenarioBuilder& OnDeath() + { + _typeMask = PROC_FLAG_DEATH; + _needsSpellInfo = false; + return *this; + } + + // Configure hit result + ProcScenarioBuilder& WithCrit() + { + _hitMask = PROC_HIT_CRITICAL; + return *this; + } + + ProcScenarioBuilder& WithNormalHit() + { + _hitMask = PROC_HIT_NORMAL; + return *this; + } + + ProcScenarioBuilder& WithMiss() + { + _hitMask = PROC_HIT_MISS; + return *this; + } + + ProcScenarioBuilder& WithDodge() + { + _hitMask = PROC_HIT_DODGE; + return *this; + } + + ProcScenarioBuilder& WithParry() + { + _hitMask = PROC_HIT_PARRY; + return *this; + } + + ProcScenarioBuilder& WithBlock() + { + _hitMask = PROC_HIT_BLOCK; + return *this; + } + + ProcScenarioBuilder& WithFullBlock() + { + _hitMask = PROC_HIT_FULL_BLOCK; + return *this; + } + + ProcScenarioBuilder& WithAbsorb() + { + _hitMask = PROC_HIT_ABSORB; + return *this; + } + + // Note: PROC_HIT_ABSORB covers both partial and full absorb + // There is no separate PROC_HIT_FULL_ABSORB flag in AzerothCore + + // Configure spell phase + ProcScenarioBuilder& OnCast() + { + _spellPhaseMask = PROC_SPELL_PHASE_CAST; + return *this; + } + + ProcScenarioBuilder& OnHit() + { + _spellPhaseMask = PROC_SPELL_PHASE_HIT; + return *this; + } + + ProcScenarioBuilder& OnFinish() + { + _spellPhaseMask = PROC_SPELL_PHASE_FINISH; + return *this; + } + + // Build the scenario into a ProcEventInfo + ProcEventInfo Build() + { + auto builder = ProcEventInfoBuilder() + .WithTypeMask(_typeMask) + .WithHitMask(_hitMask) + .WithSpellTypeMask(_spellTypeMask) + .WithSpellPhaseMask(_spellPhaseMask); + + // Create DamageInfo or HealInfo with SpellInfo for spell-type procs + if (_needsSpellInfo) + { + if (_usesDamageInfo) + { + // Create new DamageInfo if needed + if (!_damageInfo) + _damageInfo = std::make_shared(nullptr, nullptr, 100, _defaultSpellInfo.get(), SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + builder.WithDamageInfo(_damageInfo.get()); + } + else if (_usesHealInfo) + { + // Create new HealInfo if needed + if (!_healInfo) + _healInfo = std::make_shared(nullptr, nullptr, 100, _defaultSpellInfo.get(), SPELL_SCHOOL_MASK_HOLY); + builder.WithHealInfo(_healInfo.get()); + } + } + + return builder.Build(); + } + + // Get individual values + [[nodiscard]] uint32_t GetTypeMask() const { return _typeMask; } + [[nodiscard]] uint32_t GetHitMask() const { return _hitMask; } + [[nodiscard]] uint32_t GetSpellTypeMask() const { return _spellTypeMask; } + [[nodiscard]] uint32_t GetSpellPhaseMask() const { return _spellPhaseMask; } + +private: + uint32_t _typeMask = 0; + uint32_t _hitMask = PROC_HIT_NORMAL; + uint32_t _spellTypeMask = PROC_SPELL_TYPE_MASK_ALL; + uint32_t _spellPhaseMask = PROC_SPELL_PHASE_HIT; + bool _needsSpellInfo = false; + bool _usesDamageInfo = false; + bool _usesHealInfo = false; + std::shared_ptr _defaultSpellInfo; + std::shared_ptr _damageInfo; + std::shared_ptr _healInfo; +}; + +// Convenience macros for proc testing +#define EXPECT_PROC_TRIGGERS(procEntry, scenario) \ + do { \ + auto _eventInfo = (scenario).Build(); \ + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, _eventInfo)); \ + } while(0) + +#define EXPECT_PROC_DOES_NOT_TRIGGER(procEntry, scenario) \ + do { \ + auto _eventInfo = (scenario).Build(); \ + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, _eventInfo)); \ + } while(0) + +#endif //AZEROTHCORE_AURA_SCRIPT_TEST_FRAMEWORK_H diff --git a/src/test/mocks/AuraStub.h b/src/test/mocks/AuraStub.h new file mode 100644 index 000000000..ee1e3b592 --- /dev/null +++ b/src/test/mocks/AuraStub.h @@ -0,0 +1,367 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef AZEROTHCORE_AURA_STUB_H +#define AZEROTHCORE_AURA_STUB_H + +#include "gmock/gmock.h" +#include +#include +#include +#include + +class SpellInfo; +class UnitStub; + +/** + * @brief Lightweight stub for AuraEffect proc-related functionality + */ +class AuraEffectStub +{ +public: + AuraEffectStub(uint8_t effIndex = 0, int32_t amount = 0, uint32_t auraType = 0) + : _effIndex(effIndex), _amount(amount), _auraType(auraType) {} + + virtual ~AuraEffectStub() = default; + + [[nodiscard]] uint8_t GetEffIndex() const { return _effIndex; } + [[nodiscard]] int32_t GetAmount() const { return _amount; } + [[nodiscard]] uint32_t GetAuraType() const { return _auraType; } + [[nodiscard]] int32_t GetBaseAmount() const { return _baseAmount; } + [[nodiscard]] float GetCritChance() const { return _critChance; } + + void SetEffIndex(uint8_t effIndex) { _effIndex = effIndex; } + void SetAmount(int32_t amount) { _amount = amount; } + void SetAuraType(uint32_t auraType) { _auraType = auraType; } + void SetBaseAmount(int32_t baseAmount) { _baseAmount = baseAmount; } + void SetCritChance(float critChance) { _critChance = critChance; } + + // Periodic tracking + [[nodiscard]] bool IsPeriodic() const { return _isPeriodic; } + [[nodiscard]] int32_t GetTotalTicks() const { return _totalTicks; } + [[nodiscard]] uint32_t GetTickNumber() const { return _tickNumber; } + + void SetPeriodic(bool isPeriodic) { _isPeriodic = isPeriodic; } + void SetTotalTicks(int32_t totalTicks) { _totalTicks = totalTicks; } + void SetTickNumber(uint32_t tickNumber) { _tickNumber = tickNumber; } + +private: + uint8_t _effIndex = 0; + int32_t _amount = 0; + int32_t _baseAmount = 0; + uint32_t _auraType = 0; + float _critChance = 0.0f; + bool _isPeriodic = false; + int32_t _totalTicks = 0; + uint32_t _tickNumber = 0; +}; + +/** + * @brief Lightweight stub for AuraApplication functionality + */ +class AuraApplicationStub +{ +public: + AuraApplicationStub() = default; + virtual ~AuraApplicationStub() = default; + + [[nodiscard]] uint8_t GetEffectMask() const { return _effectMask; } + [[nodiscard]] bool HasEffect(uint8_t effIndex) const + { + return (_effectMask & (1 << effIndex)) != 0; + } + [[nodiscard]] bool IsPositive() const { return _isPositive; } + [[nodiscard]] uint8_t GetSlot() const { return _slot; } + + void SetEffectMask(uint8_t mask) { _effectMask = mask; } + void SetEffect(uint8_t effIndex, bool enabled) + { + if (enabled) + _effectMask |= (1 << effIndex); + else + _effectMask &= ~(1 << effIndex); + } + void SetPositive(bool isPositive) { _isPositive = isPositive; } + void SetSlot(uint8_t slot) { _slot = slot; } + +private: + uint8_t _effectMask = 0x07; // All 3 effects by default + bool _isPositive = true; + uint8_t _slot = 0; +}; + +/** + * @brief Lightweight stub for Aura proc-related functionality + */ +class AuraStub +{ +public: + AuraStub(uint32_t id = 0, uint32_t spellFamilyName = 0) + : _id(id), _spellFamilyName(spellFamilyName) + { + // Create 3 effect slots by default + for (int i = 0; i < 3; ++i) + { + _effects[i] = std::make_unique(static_cast(i)); + } + } + + virtual ~AuraStub() = default; + + // Basic identification + [[nodiscard]] uint32_t GetId() const { return _id; } + [[nodiscard]] uint32_t GetSpellFamilyName() const { return _spellFamilyName; } + + void SetId(uint32_t id) { _id = id; } + void SetSpellFamilyName(uint32_t familyName) { _spellFamilyName = familyName; } + + // Effect access + [[nodiscard]] AuraEffectStub* GetEffect(uint8_t effIndex) const + { + return (effIndex < 3) ? _effects[effIndex].get() : nullptr; + } + + [[nodiscard]] bool HasEffect(uint8_t effIndex) const + { + return effIndex < 3 && _effects[effIndex] != nullptr; + } + + [[nodiscard]] uint8_t GetEffectMask() const + { + uint8_t mask = 0; + for (uint8_t i = 0; i < 3; ++i) + { + if (_effects[i]) + mask |= (1 << i); + } + return mask; + } + + // Charges management + [[nodiscard]] uint8_t GetCharges() const { return _charges; } + [[nodiscard]] bool IsUsingCharges() const { return _isUsingCharges; } + + void SetCharges(uint8_t charges) { _charges = charges; } + void SetUsingCharges(bool usingCharges) { _isUsingCharges = usingCharges; } + + virtual bool DropCharge() + { + if (_charges > 0) + { + --_charges; + _chargeDropped = true; + return true; + } + return false; + } + + [[nodiscard]] bool WasChargeDropped() const { return _chargeDropped; } + void ResetChargeDropped() { _chargeDropped = false; } + + // Duration + [[nodiscard]] int32_t GetDuration() const { return _duration; } + [[nodiscard]] int32_t GetMaxDuration() const { return _maxDuration; } + [[nodiscard]] bool IsPermanent() const { return _maxDuration == -1; } + + void SetDuration(int32_t duration) { _duration = duration; } + void SetMaxDuration(int32_t maxDuration) { _maxDuration = maxDuration; } + + // Cooldown tracking + using TimePoint = std::chrono::steady_clock::time_point; + + [[nodiscard]] bool IsProcOnCooldown(TimePoint now) const + { + return now < _procCooldown; + } + + void AddProcCooldown(TimePoint cooldownEnd) + { + _procCooldown = cooldownEnd; + } + + void ResetProcCooldown() + { + _procCooldown = TimePoint::min(); + } + + // Stack amount + [[nodiscard]] uint8_t GetStackAmount() const { return _stackAmount; } + void SetStackAmount(uint8_t amount) { _stackAmount = amount; } + + /** + * @brief Modify stack amount (for PROC_ATTR_USE_STACKS_FOR_CHARGES) + * Mimics Aura::ModStackAmount() - removes aura if stacks reach 0 + */ + virtual bool ModStackAmount(int32_t amount, bool /* resetPeriodicTimer */ = true) + { + int32_t newAmount = static_cast(_stackAmount) + amount; + if (newAmount <= 0) + { + _stackAmount = 0; + Remove(); + return true; // Aura removed + } + _stackAmount = static_cast(newAmount); + return false; + } + + // Aura flags + [[nodiscard]] bool IsPassive() const { return _isPassive; } + [[nodiscard]] bool IsRemoved() const { return _isRemoved; } + + void SetPassive(bool isPassive) { _isPassive = isPassive; } + void SetRemoved(bool isRemoved) { _isRemoved = isRemoved; } + + /** + * @brief Mark aura as removed (for charge exhaustion) + * Mimics Aura::Remove() + */ + virtual void Remove() + { + _isRemoved = true; + } + + // Application management + AuraApplicationStub& GetOrCreateApplication() + { + if (!_application) + _application = std::make_unique(); + return *_application; + } + + [[nodiscard]] AuraApplicationStub* GetApplication() const + { + return _application.get(); + } + +private: + uint32_t _id = 0; + uint32_t _spellFamilyName = 0; + + std::unique_ptr _effects[3]; + std::unique_ptr _application; + + uint8_t _charges = 0; + bool _isUsingCharges = false; + bool _chargeDropped = false; + + int32_t _duration = -1; + int32_t _maxDuration = -1; + + TimePoint _procCooldown = TimePoint::min(); + + uint8_t _stackAmount = 1; + bool _isPassive = false; + bool _isRemoved = false; +}; + +/** + * @brief GMock-enabled Aura stub for verification + */ +class MockAuraStub : public AuraStub +{ +public: + MockAuraStub(uint32_t id = 0, uint32_t spellFamilyName = 0) + : AuraStub(id, spellFamilyName) {} + + MOCK_METHOD(bool, DropCharge, (), (override)); + MOCK_METHOD(bool, ModStackAmount, (int32_t amount, bool resetPeriodicTimer), (override)); + MOCK_METHOD(void, Remove, (), (override)); +}; + +/** + * @brief Builder for creating AuraStub instances with fluent API + */ +class AuraStubBuilder +{ +public: + AuraStubBuilder() : _stub(std::make_unique()) {} + + AuraStubBuilder& WithId(uint32_t id) + { + _stub->SetId(id); + return *this; + } + + AuraStubBuilder& WithSpellFamilyName(uint32_t familyName) + { + _stub->SetSpellFamilyName(familyName); + return *this; + } + + AuraStubBuilder& WithCharges(uint8_t charges) + { + _stub->SetCharges(charges); + _stub->SetUsingCharges(charges > 0); + return *this; + } + + AuraStubBuilder& WithDuration(int32_t duration) + { + _stub->SetDuration(duration); + _stub->SetMaxDuration(duration); + return *this; + } + + AuraStubBuilder& WithStackAmount(uint8_t amount) + { + _stub->SetStackAmount(amount); + return *this; + } + + AuraStubBuilder& WithPassive(bool isPassive) + { + _stub->SetPassive(isPassive); + return *this; + } + + AuraStubBuilder& WithEffect(uint8_t effIndex, int32_t amount, uint32_t auraType = 0) + { + if (AuraEffectStub* eff = _stub->GetEffect(effIndex)) + { + eff->SetAmount(amount); + eff->SetAuraType(auraType); + } + return *this; + } + + AuraStubBuilder& WithPeriodicEffect(uint8_t effIndex, int32_t amount, int32_t totalTicks) + { + if (AuraEffectStub* eff = _stub->GetEffect(effIndex)) + { + eff->SetAmount(amount); + eff->SetPeriodic(true); + eff->SetTotalTicks(totalTicks); + } + return *this; + } + + std::unique_ptr Build() + { + return std::move(_stub); + } + + AuraStub* BuildRaw() + { + return _stub.release(); + } + +private: + std::unique_ptr _stub; +}; + +#endif //AZEROTHCORE_AURA_STUB_H diff --git a/src/test/mocks/DamageHealInfoStub.h b/src/test/mocks/DamageHealInfoStub.h new file mode 100644 index 000000000..e16090acf --- /dev/null +++ b/src/test/mocks/DamageHealInfoStub.h @@ -0,0 +1,259 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef AZEROTHCORE_DAMAGE_HEAL_INFO_STUB_H +#define AZEROTHCORE_DAMAGE_HEAL_INFO_STUB_H + +#include + +class SpellInfo; +class UnitStub; + +/** + * @brief Lightweight stub for DamageInfo + * + * Mirrors the key fields of DamageInfo for proc testing without + * requiring actual Unit objects. + */ +class DamageInfoStub +{ +public: + DamageInfoStub() = default; + + DamageInfoStub(uint32_t damage, uint32_t originalDamage, uint32_t schoolMask, + uint8_t attackType, SpellInfo const* spellInfo = nullptr) + : _damage(damage) + , _originalDamage(originalDamage) + , _schoolMask(schoolMask) + , _attackType(attackType) + , _spellInfo(spellInfo) + {} + + virtual ~DamageInfoStub() = default; + + // Damage values + [[nodiscard]] uint32_t GetDamage() const { return _damage; } + [[nodiscard]] uint32_t GetOriginalDamage() const { return _originalDamage; } + [[nodiscard]] uint32_t GetAbsorb() const { return _absorb; } + [[nodiscard]] uint32_t GetResist() const { return _resist; } + [[nodiscard]] uint32_t GetBlock() const { return _block; } + + void SetDamage(uint32_t damage) { _damage = damage; } + void SetOriginalDamage(uint32_t damage) { _originalDamage = damage; } + void SetAbsorb(uint32_t absorb) { _absorb = absorb; } + void SetResist(uint32_t resist) { _resist = resist; } + void SetBlock(uint32_t block) { _block = block; } + + // School and attack type + [[nodiscard]] uint32_t GetSchoolMask() const { return _schoolMask; } + [[nodiscard]] uint8_t GetAttackType() const { return _attackType; } + + void SetSchoolMask(uint32_t schoolMask) { _schoolMask = schoolMask; } + void SetAttackType(uint8_t attackType) { _attackType = attackType; } + + // Spell info + [[nodiscard]] SpellInfo const* GetSpellInfo() const { return _spellInfo; } + void SetSpellInfo(SpellInfo const* spellInfo) { _spellInfo = spellInfo; } + + // Hit result flags + [[nodiscard]] uint32_t GetHitMask() const { return _hitMask; } + void SetHitMask(uint32_t hitMask) { _hitMask = hitMask; } + +private: + uint32_t _damage = 0; + uint32_t _originalDamage = 0; + uint32_t _absorb = 0; + uint32_t _resist = 0; + uint32_t _block = 0; + uint32_t _schoolMask = 1; // SPELL_SCHOOL_MASK_NORMAL + uint8_t _attackType = 0; // BASE_ATTACK + uint32_t _hitMask = 0; + SpellInfo const* _spellInfo = nullptr; +}; + +/** + * @brief Lightweight stub for HealInfo + * + * Mirrors the key fields of HealInfo for proc testing. + */ +class HealInfoStub +{ +public: + HealInfoStub() = default; + + HealInfoStub(uint32_t heal, uint32_t effectiveHeal, uint32_t absorb, + SpellInfo const* spellInfo = nullptr) + : _heal(heal) + , _effectiveHeal(effectiveHeal) + , _absorb(absorb) + , _spellInfo(spellInfo) + {} + + virtual ~HealInfoStub() = default; + + // Heal values + [[nodiscard]] uint32_t GetHeal() const { return _heal; } + [[nodiscard]] uint32_t GetEffectiveHeal() const { return _effectiveHeal; } + [[nodiscard]] uint32_t GetAbsorb() const { return _absorb; } + [[nodiscard]] uint32_t GetOverheal() const { return _heal > _effectiveHeal ? _heal - _effectiveHeal : 0; } + + void SetHeal(uint32_t heal) { _heal = heal; } + void SetEffectiveHeal(uint32_t effectiveHeal) { _effectiveHeal = effectiveHeal; } + void SetAbsorb(uint32_t absorb) { _absorb = absorb; } + + // Spell info + [[nodiscard]] SpellInfo const* GetSpellInfo() const { return _spellInfo; } + void SetSpellInfo(SpellInfo const* spellInfo) { _spellInfo = spellInfo; } + + // Hit result flags + [[nodiscard]] uint32_t GetHitMask() const { return _hitMask; } + void SetHitMask(uint32_t hitMask) { _hitMask = hitMask; } + +private: + uint32_t _heal = 0; + uint32_t _effectiveHeal = 0; + uint32_t _absorb = 0; + uint32_t _hitMask = 0; + SpellInfo const* _spellInfo = nullptr; +}; + +/** + * @brief Builder for creating DamageInfoStub instances with fluent API + */ +class DamageInfoStubBuilder +{ +public: + DamageInfoStubBuilder() = default; + + DamageInfoStubBuilder& WithDamage(uint32_t damage) + { + _stub.SetDamage(damage); + _stub.SetOriginalDamage(damage); + return *this; + } + + DamageInfoStubBuilder& WithOriginalDamage(uint32_t damage) + { + _stub.SetOriginalDamage(damage); + return *this; + } + + DamageInfoStubBuilder& WithSchoolMask(uint32_t schoolMask) + { + _stub.SetSchoolMask(schoolMask); + return *this; + } + + DamageInfoStubBuilder& WithAttackType(uint8_t attackType) + { + _stub.SetAttackType(attackType); + return *this; + } + + DamageInfoStubBuilder& WithSpellInfo(SpellInfo const* spellInfo) + { + _stub.SetSpellInfo(spellInfo); + return *this; + } + + DamageInfoStubBuilder& WithAbsorb(uint32_t absorb) + { + _stub.SetAbsorb(absorb); + return *this; + } + + DamageInfoStubBuilder& WithResist(uint32_t resist) + { + _stub.SetResist(resist); + return *this; + } + + DamageInfoStubBuilder& WithBlock(uint32_t block) + { + _stub.SetBlock(block); + return *this; + } + + DamageInfoStubBuilder& WithHitMask(uint32_t hitMask) + { + _stub.SetHitMask(hitMask); + return *this; + } + + DamageInfoStub Build() { return _stub; } + +private: + DamageInfoStub _stub; +}; + +/** + * @brief Builder for creating HealInfoStub instances with fluent API + */ +class HealInfoStubBuilder +{ +public: + HealInfoStubBuilder() = default; + + HealInfoStubBuilder& WithHeal(uint32_t heal) + { + _stub.SetHeal(heal); + _stub.SetEffectiveHeal(heal); // Assume all effective unless overridden + return *this; + } + + HealInfoStubBuilder& WithEffectiveHeal(uint32_t effectiveHeal) + { + _stub.SetEffectiveHeal(effectiveHeal); + return *this; + } + + HealInfoStubBuilder& WithOverheal(uint32_t overheal) + { + // Overheal = Heal - EffectiveHeal + // So EffectiveHeal = Heal - Overheal + if (_stub.GetHeal() >= overheal) + { + _stub.SetEffectiveHeal(_stub.GetHeal() - overheal); + } + return *this; + } + + HealInfoStubBuilder& WithAbsorb(uint32_t absorb) + { + _stub.SetAbsorb(absorb); + return *this; + } + + HealInfoStubBuilder& WithSpellInfo(SpellInfo const* spellInfo) + { + _stub.SetSpellInfo(spellInfo); + return *this; + } + + HealInfoStubBuilder& WithHitMask(uint32_t hitMask) + { + _stub.SetHitMask(hitMask); + return *this; + } + + HealInfoStub Build() { return _stub; } + +private: + HealInfoStub _stub; +}; + +#endif //AZEROTHCORE_DAMAGE_HEAL_INFO_STUB_H diff --git a/src/test/mocks/ProcChanceTestHelper.h b/src/test/mocks/ProcChanceTestHelper.h new file mode 100644 index 000000000..58436973d --- /dev/null +++ b/src/test/mocks/ProcChanceTestHelper.h @@ -0,0 +1,565 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef AZEROTHCORE_PROC_CHANCE_TEST_HELPER_H +#define AZEROTHCORE_PROC_CHANCE_TEST_HELPER_H + +#include "SpellMgr.h" +#include "SpellInfo.h" +#include "AuraStub.h" +#include "UnitStub.h" +#include +#include + +/** + * @brief Helper class for testing proc chance calculations + * + * Provides standalone implementations of proc-related calculations + * that can be tested without requiring full game objects. + */ +class ProcChanceTestHelper +{ +public: + /** + * @brief Calculate PPM proc chance + * Implements the formula: (WeaponSpeed * PPM) / 600.0f + * + * @param weaponSpeed Weapon attack speed in milliseconds + * @param ppm Procs per minute value + * @param ppmModifier Additional PPM modifier (from talents/auras) + * @return Proc chance as percentage (0-100+) + */ + static float CalculatePPMChance(uint32 weaponSpeed, float ppm, float ppmModifier = 0.0f) + { + if (ppm <= 0.0f) + return 0.0f; + + float modifiedPPM = ppm + ppmModifier; + return (static_cast(weaponSpeed) * modifiedPPM) / 600.0f; + } + + /** + * @brief Calculate level 60+ reduction + * Implements PROC_ATTR_REDUCE_PROC_60: 3.333% reduction per level above 60 + * + * @param baseChance Base proc chance + * @param actorLevel Actor's level + * @return Reduced proc chance + */ + static float ApplyLevel60Reduction(float baseChance, uint32 actorLevel) + { + if (actorLevel <= 60) + return baseChance; + + // Reduction = (level - 60) / 30, capped at 1.0 + float reduction = static_cast(actorLevel - 60) / 30.0f; + return std::max(0.0f, (1.0f - reduction) * baseChance); + } + + /** + * @brief Simulate CalcProcChance() from SpellAuras.cpp + * + * @param procEntry The proc configuration + * @param actorLevel Actor's level (for PROC_ATTR_REDUCE_PROC_60) + * @param weaponSpeed Weapon speed (for PPM calculation) + * @param chanceModifier Talent/aura modifier to chance + * @param ppmModifier Talent/aura modifier to PPM + * @param hasDamageInfo Whether a DamageInfo is present (enables PPM) + * @return Calculated proc chance + */ + static float SimulateCalcProcChance( + SpellProcEntry const& procEntry, + uint32 actorLevel = 80, + uint32 weaponSpeed = 2500, + float chanceModifier = 0.0f, + float ppmModifier = 0.0f, + bool hasDamageInfo = true) + { + float chance = procEntry.Chance; + + // PPM calculation overrides base chance if PPM > 0 and we have DamageInfo + if (hasDamageInfo && procEntry.ProcsPerMinute > 0.0f) + { + chance = CalculatePPMChance(weaponSpeed, procEntry.ProcsPerMinute, ppmModifier); + } + + // Apply chance modifier (SPELLMOD_CHANCE_OF_SUCCESS) + chance += chanceModifier; + + // Apply level 60+ reduction if attribute is set + if (procEntry.AttributesMask & PROC_ATTR_REDUCE_PROC_60) + { + chance = ApplyLevel60Reduction(chance, actorLevel); + } + + return chance; + } + + /** + * @brief Simulate charge consumption from ConsumeProcCharges() + * + * @param aura The aura stub to modify + * @param procEntry The proc configuration + * @return true if aura was removed (charges/stacks exhausted) + */ + static bool SimulateConsumeProcCharges(AuraStub* aura, SpellProcEntry const& procEntry) + { + if (!aura) + return false; + + if (procEntry.AttributesMask & PROC_ATTR_USE_STACKS_FOR_CHARGES) + { + return aura->ModStackAmount(-1); + } + else if (aura->IsUsingCharges()) + { + aura->DropCharge(); + if (aura->GetCharges() == 0) + { + aura->Remove(); + return true; + } + } + return false; + } + + /** + * @brief Check if proc is on cooldown + * + * @param aura The aura stub + * @param now Current time point + * @return true if proc is blocked by cooldown + */ + static bool IsProcOnCooldown(AuraStub const* aura, std::chrono::steady_clock::time_point now) + { + if (!aura) + return false; + return aura->IsProcOnCooldown(now); + } + + /** + * @brief Apply proc cooldown to aura + * + * @param aura The aura stub + * @param now Current time point + * @param cooldownMs Cooldown duration in milliseconds + */ + static void ApplyProcCooldown(AuraStub* aura, std::chrono::steady_clock::time_point now, uint32 cooldownMs) + { + if (!aura || cooldownMs == 0) + return; + aura->AddProcCooldown(now + std::chrono::milliseconds(cooldownMs)); + } + + /** + * @brief Check if spell has mana cost (for PROC_ATTR_REQ_MANA_COST) + * + * @param spellInfo The spell info to check + * @return true if spell has mana cost > 0 + */ + static bool SpellHasManaCost(SpellInfo const* spellInfo) + { + if (!spellInfo) + return false; + return spellInfo->ManaCost > 0 || spellInfo->ManaCostPercentage > 0; + } + + /** + * @brief Get common weapon speeds for testing + */ + static constexpr uint32 WEAPON_SPEED_FAST_DAGGER = 1400; // 1.4 sec + static constexpr uint32 WEAPON_SPEED_NORMAL_SWORD = 2500; // 2.5 sec + static constexpr uint32 WEAPON_SPEED_SLOW_2H = 3300; // 3.3 sec + static constexpr uint32 WEAPON_SPEED_VERY_SLOW = 3800; // 3.8 sec + static constexpr uint32 WEAPON_SPEED_STAFF = 3600; // 3.6 sec (common feral staff) + + /** + * @brief Shapeshift form base attack speeds (from SpellShapeshiftForm.dbc) + */ + static constexpr uint32 FORM_SPEED_CAT = 1000; // Cat Form: 1.0 sec + static constexpr uint32 FORM_SPEED_BEAR = 2500; // Bear/Dire Bear: 2.5 sec + + /** + * @brief Simulate effective procs per minute + * + * Given a per-swing chance and the actual swing interval, calculate + * how many procs occur per minute on average. + * + * @param chancePerSwing Proc chance per swing (0-100+) + * @param actualSwingSpeedMs Actual time between swings in milliseconds + * @return Average procs per minute + */ + static float CalculateEffectivePPM(float chancePerSwing, uint32 actualSwingSpeedMs) + { + if (actualSwingSpeedMs == 0) + return 0.0f; + float swingsPerMinute = 60000.0f / static_cast(actualSwingSpeedMs); + return swingsPerMinute * (chancePerSwing / 100.0f); + } + + /** + * @brief Common PPM values from spell_proc database + */ + static constexpr float PPM_OMEN_OF_CLARITY = 6.0f; + static constexpr float PPM_JUDGEMENT_OF_LIGHT = 15.0f; + static constexpr float PPM_WINDFURY_WEAPON = 2.0f; + + // ============================================================================= + // Triggered Spell Filtering - simulates SpellAuras.cpp:2191-2209 + // ============================================================================= + + /** + * @brief Auto-attack proc flag mask (hunter auto-shot, wands exception) + * These triggered spells are allowed to proc without TRIGGERED_CAN_PROC + */ + static constexpr uint32 AUTO_ATTACK_PROC_FLAG_MASK = + PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | + PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK; + + /** + * @brief Configuration for simulating triggered spell filtering + */ + struct TriggeredSpellConfig + { + bool isTriggered = false; // Spell::IsTriggered() + bool auraHasCanProcFromProcs = false; // SPELL_ATTR3_CAN_PROC_FROM_PROCS on proc aura + bool spellHasNotAProc = false; // SPELL_ATTR3_NOT_A_PROC on triggering spell + uint32 triggeredByAuraSpellId = 0; // GetTriggeredByAuraSpellInfo()->Id + uint32 procAuraSpellId = 0; // The aura's spell ID (for self-loop check) + }; + + /** + * @brief Simulate triggered spell filtering + * Implements the self-loop prevention and triggered spell blocking from SpellAuras.cpp + * + * @param config Configuration for the triggered spell + * @param procEntry The proc entry being checked + * @param eventTypeMask The event type mask from ProcEventInfo + * @return true if proc should be blocked (return 0), false if allowed + */ + static bool ShouldBlockTriggeredSpell( + TriggeredSpellConfig const& config, + SpellProcEntry const& procEntry, + uint32 eventTypeMask) + { + // Self-loop prevention: block if triggered by the same aura + // SpellAuras.cpp:2191-2192 + if (config.triggeredByAuraSpellId != 0 && + config.triggeredByAuraSpellId == config.procAuraSpellId) + { + return true; // Block: self-loop detected + } + + // Check if triggered spell filtering applies + // SpellAuras.cpp:2195-2208 + if (!config.auraHasCanProcFromProcs && + !(procEntry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC) && + !(eventTypeMask & AUTO_ATTACK_PROC_FLAG_MASK)) + { + // Filter triggered spells unless they have NOT_A_PROC + if (config.isTriggered && !config.spellHasNotAProc) + { + return true; // Block: triggered spell without exceptions + } + } + + return false; // Allow proc + } + + // ============================================================================= + // DisableEffectsMask - simulates SpellAuras.cpp:2244-2258 + // ============================================================================= + + /** + * @brief Apply DisableEffectsMask to get final proc effect mask + * + * @param initialMask Initial effect mask (usually 0x07 for all 3 effects) + * @param disableEffectsMask Mask of effects to disable + * @return Resulting effect mask after applying disable mask + */ + static uint8 ApplyDisableEffectsMask(uint8 initialMask, uint32 disableEffectsMask) + { + uint8 result = initialMask; + for (uint8 i = 0; i < 3; ++i) + { + if (disableEffectsMask & (1u << i)) + result &= ~(1 << i); + } + return result; + } + + /** + * @brief Check if proc should be blocked due to all effects being disabled + * + * @param initialMask Initial effect mask + * @param disableEffectsMask Mask of effects to disable + * @return true if all effects disabled (proc blocked), false otherwise + */ + static bool ShouldBlockDueToDisabledEffects(uint8 initialMask, uint32 disableEffectsMask) + { + return ApplyDisableEffectsMask(initialMask, disableEffectsMask) == 0; + } + + // ============================================================================= + // PPM Modifier Simulation - simulates Unit.cpp:10378-10390 + // ============================================================================= + + /** + * @brief PPM modifier configuration for testing SPELLMOD_PROC_PER_MINUTE + */ + struct PPMModifierConfig + { + float flatModifier = 0.0f; // Additive PPM modifier + float pctModifier = 1.0f; // Multiplicative PPM modifier (1.0 = no change) + bool hasSpellModOwner = true; // Whether GetSpellModOwner() returns valid player + bool hasSpellProto = true; // Whether spellProto is provided + }; + + /** + * @brief Calculate PPM chance with spell modifiers + * Simulates GetPPMProcChance() with SPELLMOD_PROC_PER_MINUTE + */ + static float CalculatePPMChanceWithModifiers( + uint32 weaponSpeed, + float basePPM, + PPMModifierConfig const& modConfig) + { + if (basePPM <= 0.0f) + return 0.0f; + + float ppm = basePPM; + + // Apply modifiers only if we have spell proto and spell mod owner + if (modConfig.hasSpellProto && modConfig.hasSpellModOwner) + { + // Apply flat modifier first (SPELLMOD_FLAT) + ppm += modConfig.flatModifier; + // Apply percent modifier (SPELLMOD_PCT) + ppm *= modConfig.pctModifier; + } + + return (static_cast(weaponSpeed) * ppm) / 600.0f; + } + + // ============================================================================= + // Equipment Requirements - simulates SpellAuras.cpp:2260-2298 + // ============================================================================= + + /** + * @brief Item classes for equipment requirement checking + */ + static constexpr int32 ITEM_CLASS_WEAPON = 2; + static constexpr int32 ITEM_CLASS_ARMOR = 4; + static constexpr int32 ITEM_CLASS_ANY = -1; // No requirement + + /** + * @brief Attack types for weapon slot mapping + */ + static constexpr uint8 BASE_ATTACK = 0; + static constexpr uint8 OFF_ATTACK = 1; + static constexpr uint8 RANGED_ATTACK = 2; + + /** + * @brief Configuration for simulating equipment requirements + */ + struct EquipmentConfig + { + bool isPassive = true; // Aura::IsPassive() + bool isPlayer = true; // Target is player + int32 equippedItemClass = ITEM_CLASS_ANY; // SpellInfo::EquippedItemClass + int32 equippedItemSubClassMask = 0; // SpellInfo::EquippedItemSubClassMask + bool hasNoEquipRequirementAttr = false; // SPELL_ATTR3_NO_PROC_EQUIP_REQUIREMENT + uint8 attackType = BASE_ATTACK; // Attack type for weapon slot mapping + bool isInFeralForm = false; // Player::IsInFeralForm() + bool hasEquippedItem = true; // Item is equipped in the slot + bool itemIsBroken = false; // Item::IsBroken() + bool itemFitsRequirements = true; // Item::IsFitToSpellRequirements() + }; + + /** + * @brief Simulate equipment requirement check + * Returns true if proc should be blocked due to equipment requirements + * + * @param config Equipment configuration + * @return true if proc should be blocked + */ + static bool ShouldBlockDueToEquipment(EquipmentConfig const& config) + { + // Only check for passive player auras with equipment requirements + if (!config.isPassive || !config.isPlayer || config.equippedItemClass == ITEM_CLASS_ANY) + return false; + + // SPELL_ATTR3_NO_PROC_EQUIP_REQUIREMENT bypasses check + if (config.hasNoEquipRequirementAttr) + return false; + + // Feral form blocks weapon procs + if (config.equippedItemClass == ITEM_CLASS_WEAPON && config.isInFeralForm) + return true; + + // No item equipped in the required slot + if (!config.hasEquippedItem) + return true; + + // Item is broken + if (config.itemIsBroken) + return true; + + // Item doesn't fit spell requirements (wrong subclass, etc.) + if (!config.itemFitsRequirements) + return true; + + return false; + } + + /** + * @brief Get equipment slot for attack type + * + * @param attackType Attack type (BASE_ATTACK, OFF_ATTACK, RANGED_ATTACK) + * @return Equipment slot index (simulated) + */ + static uint8 GetWeaponSlotForAttackType(uint8 attackType) + { + switch (attackType) + { + case BASE_ATTACK: + return 15; // EQUIPMENT_SLOT_MAINHAND + case OFF_ATTACK: + return 16; // EQUIPMENT_SLOT_OFFHAND + case RANGED_ATTACK: + return 17; // EQUIPMENT_SLOT_RANGED + default: + return 15; + } + } + + // ============================================================================= + // Conditions System - simulates SpellAuras.cpp:2232-2236 + // ============================================================================= + + /** + * @brief Configuration for simulating conditions system + */ + struct ConditionsConfig + { + bool hasConditions = false; // ConditionMgr has conditions for this spell + bool conditionsMet = true; // All conditions are satisfied + uint32 sourceType = 24; // CONDITION_SOURCE_TYPE_SPELL_PROC + }; + + /** + * @brief Simulate conditions check + * Returns true if proc should be blocked due to conditions + * + * @param config Conditions configuration + * @return true if proc should be blocked + */ + static bool ShouldBlockDueToConditions(ConditionsConfig const& config) + { + // No conditions configured - allow proc + if (!config.hasConditions) + return false; + + // Check if conditions are met + return !config.conditionsMet; + } +}; + +/** + * @brief Test context for proc simulation scenarios + */ +class ProcTestScenario +{ +public: + ProcTestScenario() : _now(std::chrono::steady_clock::now()) {} + + // Time control + void AdvanceTime(std::chrono::milliseconds duration) + { + _now += duration; + } + + std::chrono::steady_clock::time_point GetNow() const { return _now; } + + // Actor configuration + UnitStub& GetActor() { return _actor; } + UnitStub const& GetActor() const { return _actor; } + + ProcTestScenario& WithActorLevel(uint8_t level) + { + _actor.SetLevel(level); + return *this; + } + + ProcTestScenario& WithWeaponSpeed(uint8_t attackType, uint32_t speed) + { + _actor.SetAttackTime(attackType, speed); + return *this; + } + + // Aura configuration + std::unique_ptr& GetAura() { return _aura; } + + ProcTestScenario& WithAura(uint32_t spellId, uint8_t charges = 0, uint8_t stacks = 1) + { + _aura = std::make_unique(spellId); + _aura->SetCharges(charges); + _aura->SetUsingCharges(charges > 0); + _aura->SetStackAmount(stacks); + return *this; + } + + // Simulate proc and return whether it triggered + bool SimulateProc(SpellProcEntry const& procEntry, float rollResult = 0.0f) + { + if (!_aura) + return false; + + // Check cooldown + if (ProcChanceTestHelper::IsProcOnCooldown(_aura.get(), _now)) + return false; + + // Calculate chance + float chance = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, + _actor.GetLevel(), + _actor.GetAttackTime(0)); + + // Roll check (rollResult of 0 means always pass) + if (rollResult > 0.0f && rollResult > chance) + return false; + + // Apply cooldown if set + if (procEntry.Cooldown.count() > 0) + { + ProcChanceTestHelper::ApplyProcCooldown(_aura.get(), _now, + static_cast(procEntry.Cooldown.count())); + } + + // Consume charges + ProcChanceTestHelper::SimulateConsumeProcCharges(_aura.get(), procEntry); + + return true; + } + +private: + std::chrono::steady_clock::time_point _now; + UnitStub _actor; + std::unique_ptr _aura; +}; + +#endif // AZEROTHCORE_PROC_CHANCE_TEST_HELPER_H diff --git a/src/test/mocks/ProcEventInfoHelper.h b/src/test/mocks/ProcEventInfoHelper.h new file mode 100644 index 000000000..41e9275b8 --- /dev/null +++ b/src/test/mocks/ProcEventInfoHelper.h @@ -0,0 +1,235 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef AZEROTHCORE_PROC_EVENT_INFO_HELPER_H +#define AZEROTHCORE_PROC_EVENT_INFO_HELPER_H + +#include "SpellMgr.h" +#include "Unit.h" + +/** + * @brief Builder class for creating ProcEventInfo test instances + * + * This helper allows easy construction of ProcEventInfo objects for unit testing + * the proc system without requiring full game objects. + */ +class ProcEventInfoBuilder +{ +public: + ProcEventInfoBuilder() + : _actor(nullptr), _actionTarget(nullptr), _procTarget(nullptr), + _typeMask(0), _spellTypeMask(0), _spellPhaseMask(0), _hitMask(0), + _spell(nullptr), _damageInfo(nullptr), _healInfo(nullptr), + _triggeredByAuraSpell(nullptr), _procAuraEffectIndex(-1) {} + + ProcEventInfoBuilder& WithActor(Unit* actor) + { + _actor = actor; + return *this; + } + + ProcEventInfoBuilder& WithActionTarget(Unit* target) + { + _actionTarget = target; + return *this; + } + + ProcEventInfoBuilder& WithProcTarget(Unit* target) + { + _procTarget = target; + return *this; + } + + ProcEventInfoBuilder& WithTypeMask(uint32 typeMask) + { + _typeMask = typeMask; + return *this; + } + + ProcEventInfoBuilder& WithSpellTypeMask(uint32 spellTypeMask) + { + _spellTypeMask = spellTypeMask; + return *this; + } + + ProcEventInfoBuilder& WithSpellPhaseMask(uint32 spellPhaseMask) + { + _spellPhaseMask = spellPhaseMask; + return *this; + } + + ProcEventInfoBuilder& WithHitMask(uint32 hitMask) + { + _hitMask = hitMask; + return *this; + } + + ProcEventInfoBuilder& WithSpell(Spell const* spell) + { + _spell = spell; + return *this; + } + + ProcEventInfoBuilder& WithDamageInfo(DamageInfo* damageInfo) + { + _damageInfo = damageInfo; + return *this; + } + + ProcEventInfoBuilder& WithHealInfo(HealInfo* healInfo) + { + _healInfo = healInfo; + return *this; + } + + ProcEventInfoBuilder& WithTriggeredByAuraSpell(SpellInfo const* spellInfo) + { + _triggeredByAuraSpell = spellInfo; + return *this; + } + + ProcEventInfoBuilder& WithProcAuraEffectIndex(int8 index) + { + _procAuraEffectIndex = index; + return *this; + } + + ProcEventInfo Build() + { + return ProcEventInfo(_actor, _actionTarget, _procTarget, _typeMask, + _spellTypeMask, _spellPhaseMask, _hitMask, + _spell, _damageInfo, _healInfo, + _triggeredByAuraSpell, _procAuraEffectIndex); + } + +private: + Unit* _actor; + Unit* _actionTarget; + Unit* _procTarget; + uint32 _typeMask; + uint32 _spellTypeMask; + uint32 _spellPhaseMask; + uint32 _hitMask; + Spell const* _spell; + DamageInfo* _damageInfo; + HealInfo* _healInfo; + SpellInfo const* _triggeredByAuraSpell; + int8 _procAuraEffectIndex; +}; + +/** + * @brief Builder class for creating SpellProcEntry test instances + * + * This helper allows easy construction of SpellProcEntry objects for unit testing + * the proc system. + */ +class SpellProcEntryBuilder +{ +public: + SpellProcEntryBuilder() + { + _entry = {}; + } + + SpellProcEntryBuilder& WithSchoolMask(uint32 schoolMask) + { + _entry.SchoolMask = schoolMask; + return *this; + } + + SpellProcEntryBuilder& WithSpellFamilyName(uint32 familyName) + { + _entry.SpellFamilyName = familyName; + return *this; + } + + SpellProcEntryBuilder& WithSpellFamilyMask(flag96 familyMask) + { + _entry.SpellFamilyMask = familyMask; + return *this; + } + + SpellProcEntryBuilder& WithProcFlags(uint32 procFlags) + { + _entry.ProcFlags = procFlags; + return *this; + } + + SpellProcEntryBuilder& WithSpellTypeMask(uint32 spellTypeMask) + { + _entry.SpellTypeMask = spellTypeMask; + return *this; + } + + SpellProcEntryBuilder& WithSpellPhaseMask(uint32 spellPhaseMask) + { + _entry.SpellPhaseMask = spellPhaseMask; + return *this; + } + + SpellProcEntryBuilder& WithHitMask(uint32 hitMask) + { + _entry.HitMask = hitMask; + return *this; + } + + SpellProcEntryBuilder& WithAttributesMask(uint32 attributesMask) + { + _entry.AttributesMask = attributesMask; + return *this; + } + + SpellProcEntryBuilder& WithDisableEffectsMask(uint32 disableEffectsMask) + { + _entry.DisableEffectsMask = disableEffectsMask; + return *this; + } + + SpellProcEntryBuilder& WithProcsPerMinute(float ppm) + { + _entry.ProcsPerMinute = ppm; + return *this; + } + + SpellProcEntryBuilder& WithChance(float chance) + { + _entry.Chance = chance; + return *this; + } + + SpellProcEntryBuilder& WithCooldown(Milliseconds cooldown) + { + _entry.Cooldown = cooldown; + return *this; + } + + SpellProcEntryBuilder& WithCharges(uint32 charges) + { + _entry.Charges = charges; + return *this; + } + + SpellProcEntry Build() const + { + return _entry; + } + +private: + SpellProcEntry _entry; +}; + +#endif //AZEROTHCORE_PROC_EVENT_INFO_HELPER_H diff --git a/src/test/mocks/SpellInfoTestHelper.h b/src/test/mocks/SpellInfoTestHelper.h new file mode 100644 index 000000000..ce129b4d1 --- /dev/null +++ b/src/test/mocks/SpellInfoTestHelper.h @@ -0,0 +1,215 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef AZEROTHCORE_SPELL_INFO_TEST_HELPER_H +#define AZEROTHCORE_SPELL_INFO_TEST_HELPER_H + +#include "SpellInfo.h" +#include "SharedDefines.h" +#include + +/** + * @brief Helper class to create SpellEntry test instances + * + * This creates a SpellEntry with sensible defaults for unit testing. + */ +class TestSpellEntryHelper +{ +public: + TestSpellEntryHelper() + { + // Zero initialize all fields + std::memset(&_entry, 0, sizeof(_entry)); + + // Set safe defaults + _entry.EquippedItemClass = -1; + _entry.SchoolMask = SPELL_SCHOOL_MASK_NORMAL; + + // Initialize empty strings + for (auto& name : _entry.SpellName) + name = ""; + for (auto& rank : _entry.Rank) + rank = ""; + } + + TestSpellEntryHelper& WithId(uint32 id) + { + _entry.Id = id; + return *this; + } + + TestSpellEntryHelper& WithSpellFamilyName(uint32 familyName) + { + _entry.SpellFamilyName = familyName; + return *this; + } + + TestSpellEntryHelper& WithSpellFamilyFlags(uint32 flag0, uint32 flag1 = 0, uint32 flag2 = 0) + { + _entry.SpellFamilyFlags[0] = flag0; + _entry.SpellFamilyFlags[1] = flag1; + _entry.SpellFamilyFlags[2] = flag2; + return *this; + } + + TestSpellEntryHelper& WithSchoolMask(uint32 schoolMask) + { + _entry.SchoolMask = schoolMask; + return *this; + } + + TestSpellEntryHelper& WithProcFlags(uint32 procFlags) + { + _entry.ProcFlags = procFlags; + return *this; + } + + TestSpellEntryHelper& WithProcChance(uint32 procChance) + { + _entry.ProcChance = procChance; + return *this; + } + + TestSpellEntryHelper& WithProcCharges(uint32 procCharges) + { + _entry.ProcCharges = procCharges; + return *this; + } + + TestSpellEntryHelper& WithDmgClass(uint32 dmgClass) + { + _entry.DmgClass = dmgClass; + return *this; + } + + TestSpellEntryHelper& WithEffect(uint8 effIndex, uint32 effect, uint32 auraType = 0) + { + if (effIndex < MAX_SPELL_EFFECTS) + { + _entry.Effect[effIndex] = effect; + _entry.EffectApplyAuraName[effIndex] = auraType; + } + return *this; + } + + TestSpellEntryHelper& WithEffectTriggerSpell(uint8 effIndex, uint32 triggerSpell) + { + if (effIndex < MAX_SPELL_EFFECTS) + { + _entry.EffectTriggerSpell[effIndex] = triggerSpell; + } + return *this; + } + + SpellEntry const* Get() const + { + return &_entry; + } + +private: + SpellEntry _entry; +}; + +/** + * @brief Builder class for creating SpellInfo test instances + * + * This helper allows easy construction of SpellInfo objects for unit testing + * without requiring DBC data. + */ +class SpellInfoBuilder +{ +public: + SpellInfoBuilder() : _entryHelper() {} + + SpellInfoBuilder& WithId(uint32 id) + { + _entryHelper.WithId(id); + return *this; + } + + SpellInfoBuilder& WithSpellFamilyName(uint32 familyName) + { + _entryHelper.WithSpellFamilyName(familyName); + return *this; + } + + SpellInfoBuilder& WithSpellFamilyFlags(uint32 flag0, uint32 flag1 = 0, uint32 flag2 = 0) + { + _entryHelper.WithSpellFamilyFlags(flag0, flag1, flag2); + return *this; + } + + SpellInfoBuilder& WithSchoolMask(uint32 schoolMask) + { + _entryHelper.WithSchoolMask(schoolMask); + return *this; + } + + SpellInfoBuilder& WithProcFlags(uint32 procFlags) + { + _entryHelper.WithProcFlags(procFlags); + return *this; + } + + SpellInfoBuilder& WithProcChance(uint32 procChance) + { + _entryHelper.WithProcChance(procChance); + return *this; + } + + SpellInfoBuilder& WithProcCharges(uint32 procCharges) + { + _entryHelper.WithProcCharges(procCharges); + return *this; + } + + SpellInfoBuilder& WithDmgClass(uint32 dmgClass) + { + _entryHelper.WithDmgClass(dmgClass); + return *this; + } + + SpellInfoBuilder& WithEffect(uint8 effIndex, uint32 effect, uint32 auraType = 0) + { + _entryHelper.WithEffect(effIndex, effect, auraType); + return *this; + } + + SpellInfoBuilder& WithEffectTriggerSpell(uint8 effIndex, uint32 triggerSpell) + { + _entryHelper.WithEffectTriggerSpell(effIndex, triggerSpell); + return *this; + } + + // Builds and returns a SpellInfo pointer + // Note: Caller is responsible for lifetime management + SpellInfo* Build() + { + return new SpellInfo(_entryHelper.Get()); + } + + // Builds and returns a managed SpellInfo pointer + std::unique_ptr BuildUnique() + { + return std::unique_ptr(new SpellInfo(_entryHelper.Get())); + } + +private: + TestSpellEntryHelper _entryHelper; +}; + +#endif //AZEROTHCORE_SPELL_INFO_TEST_HELPER_H diff --git a/src/test/mocks/UnitStub.h b/src/test/mocks/UnitStub.h new file mode 100644 index 000000000..001c65af5 --- /dev/null +++ b/src/test/mocks/UnitStub.h @@ -0,0 +1,244 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef AZEROTHCORE_UNIT_STUB_H +#define AZEROTHCORE_UNIT_STUB_H + +#include "gmock/gmock.h" +#include +#include +#include +#include + +class SpellInfo; +class Aura; +class AuraEffect; +class Item; + +/** + * @brief Lightweight stub for Unit proc-related functionality + * + * This stub provides controlled behavior for testing proc scripts + * without requiring the full Unit hierarchy. + */ +class UnitStub +{ +public: + UnitStub() = default; + virtual ~UnitStub() = default; + + // Identity + virtual bool IsPlayer() const { return _isPlayer; } + virtual bool IsAlive() const { return _isAlive; } + virtual bool IsFriendlyTo(UnitStub const* unit) const { return _isFriendly; } + + void SetIsPlayer(bool isPlayer) { _isPlayer = isPlayer; } + void SetIsAlive(bool isAlive) { _isAlive = isAlive; } + void SetIsFriendly(bool isFriendly) { _isFriendly = isFriendly; } + + // Aura management + virtual bool HasAura(uint32_t spellId) const + { + return _auras.find(spellId) != _auras.end(); + } + + virtual void AddAuraStub(uint32_t spellId) + { + _auras[spellId] = true; + } + + virtual void RemoveAuraStub(uint32_t spellId) + { + _auras.erase(spellId); + } + + // Spell casting tracking + struct CastRecord + { + uint32_t spellId; + bool triggered; + int32_t bp0; + int32_t bp1; + int32_t bp2; + }; + + virtual void RecordCast(uint32_t spellId, bool triggered = true, + int32_t bp0 = 0, int32_t bp1 = 0, int32_t bp2 = 0) + { + _castHistory.push_back({spellId, triggered, bp0, bp1, bp2}); + } + + [[nodiscard]] std::vector const& GetCastHistory() const { return _castHistory; } + + [[nodiscard]] bool WasCast(uint32_t spellId) const + { + for (auto const& record : _castHistory) + { + if (record.spellId == spellId) + return true; + } + return false; + } + + [[nodiscard]] size_t CountCasts(uint32_t spellId) const + { + size_t count = 0; + for (auto const& record : _castHistory) + { + if (record.spellId == spellId) + ++count; + } + return count; + } + + void ClearCastHistory() { _castHistory.clear(); } + + // Health/Power + virtual uint32_t GetMaxHealth() const { return _maxHealth; } + virtual uint32_t GetHealth() const { return _health; } + virtual uint32_t CountPctFromMaxHealth(int32_t pct) const + { + return (_maxHealth * static_cast(pct)) / 100; + } + + void SetMaxHealth(uint32_t maxHealth) { _maxHealth = maxHealth; } + void SetHealth(uint32_t health) { _health = health; } + + // Weapon speed for PPM calculations + virtual uint32_t GetAttackTime(uint8_t attType) const + { + return _attackTimes.count(attType) ? _attackTimes.at(attType) : 2000; + } + + void SetAttackTime(uint8_t attType, uint32_t time) + { + _attackTimes[attType] = time; + } + + // PPM modifier tracking for proc tests + // Simulates Player::ApplySpellMod(spellId, SPELLMOD_PROC_PER_MINUTE, ppm) + void SetPPMModifier(uint32_t spellId, float modifier) + { + _ppmModifiers[spellId] = modifier; + } + + void ClearPPMModifiers() + { + _ppmModifiers.clear(); + } + + /** + * @brief Calculate PPM proc chance with modifiers + * Mimics Unit::GetPPMProcChance() formula: (WeaponSpeed * PPM) / 600.0f + */ + virtual float GetPPMProcChance(uint32_t weaponSpeed, float ppm, uint32_t spellId = 0) const + { + if (ppm <= 0.0f) + return 0.0f; + + // Apply PPM modifier if set for this spell + float modifiedPPM = ppm; + if (spellId > 0 && _ppmModifiers.count(spellId)) + modifiedPPM += _ppmModifiers.at(spellId); + + return (static_cast(weaponSpeed) * modifiedPPM) / 600.0f; + } + + // Chance modifier tracking for proc tests + // Simulates Player::ApplySpellMod(spellId, SPELLMOD_CHANCE_OF_SUCCESS, chance) + void SetChanceModifier(uint32_t spellId, float modifier) + { + _chanceModifiers[spellId] = modifier; + } + + void ClearChanceModifiers() + { + _chanceModifiers.clear(); + } + + /** + * @brief Apply chance modifier for a spell + */ + float ApplyChanceModifier(uint32_t spellId, float baseChance) const + { + if (spellId > 0 && _chanceModifiers.count(spellId)) + return baseChance + _chanceModifiers.at(spellId); + return baseChance; + } + + // Cooldowns + virtual bool HasSpellCooldown(uint32_t spellId) const + { + return _cooldowns.find(spellId) != _cooldowns.end(); + } + + virtual void AddSpellCooldown(uint32_t spellId) + { + _cooldowns[spellId] = true; + } + + virtual void RemoveSpellCooldown(uint32_t spellId) + { + _cooldowns.erase(spellId); + } + + // Class/Level + virtual uint8_t GetClass() const { return _class; } + virtual uint8_t GetLevel() const { return _level; } + + void SetClass(uint8_t unitClass) { _class = unitClass; } + void SetLevel(uint8_t level) { _level = level; } + +private: + bool _isPlayer = false; + bool _isAlive = true; + bool _isFriendly = false; + + std::map _auras; + std::vector _castHistory; + std::map _cooldowns; + std::map _attackTimes; + std::map _ppmModifiers; // PPM modifiers by spell ID + std::map _chanceModifiers; // Chance modifiers by spell ID + + uint32_t _maxHealth = 10000; + uint32_t _health = 10000; + uint8_t _class = 1; // Warrior by default + uint8_t _level = 80; +}; + +/** + * @brief GMock-enabled Unit stub for verification + */ +class MockUnitStub : public UnitStub +{ +public: + MOCK_METHOD(bool, IsPlayer, (), (const, override)); + MOCK_METHOD(bool, IsAlive, (), (const, override)); + MOCK_METHOD(bool, IsFriendlyTo, (UnitStub const* unit), (const, override)); + MOCK_METHOD(bool, HasAura, (uint32_t spellId), (const, override)); + MOCK_METHOD(uint32_t, GetMaxHealth, (), (const, override)); + MOCK_METHOD(uint32_t, GetHealth, (), (const, override)); + MOCK_METHOD(uint32_t, CountPctFromMaxHealth, (int32_t pct), (const, override)); + MOCK_METHOD(uint32_t, GetAttackTime, (uint8_t attType), (const, override)); + MOCK_METHOD(bool, HasSpellCooldown, (uint32_t spellId), (const, override)); + MOCK_METHOD(uint8_t, GetClass, (), (const, override)); + MOCK_METHOD(uint8_t, GetLevel, (), (const, override)); + MOCK_METHOD(float, GetPPMProcChance, (uint32_t weaponSpeed, float ppm, uint32_t spellId), (const, override)); +}; + +#endif //AZEROTHCORE_UNIT_STUB_H diff --git a/src/test/server/game/Spells/SpellProcAttributeTest.cpp b/src/test/server/game/Spells/SpellProcAttributeTest.cpp new file mode 100644 index 000000000..536c105d8 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcAttributeTest.cpp @@ -0,0 +1,445 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcAttributeTest.cpp + * @brief Unit tests for PROC_ATTR_* flags + * + * Tests all proc attribute flags: + * - PROC_ATTR_REQ_EXP_OR_HONOR (0x01) + * - PROC_ATTR_TRIGGERED_CAN_PROC (0x02) + * - PROC_ATTR_REQ_MANA_COST (0x04) + * - PROC_ATTR_REQ_SPELLMOD (0x08) + * - PROC_ATTR_USE_STACKS_FOR_CHARGES (0x10) + * - PROC_ATTR_REDUCE_PROC_60 (0x80) + * - PROC_ATTR_CANT_PROC_FROM_ITEM_CAST (0x100) + */ + +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "AuraStub.h" +#include "UnitStub.h" +#include "gtest/gtest.h" + +using namespace testing; + +class SpellProcAttributeTest : public ::testing::Test +{ +protected: + void SetUp() override {} +}; + +// ============================================================================= +// PROC_ATTR_REQ_EXP_OR_HONOR (0x01) Tests +// ============================================================================= + +TEST_F(SpellProcAttributeTest, ReqExpOrHonor_AttributeSet) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_REQ_EXP_OR_HONOR) + .Build(); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR); +} + +TEST_F(SpellProcAttributeTest, ReqExpOrHonor_AttributeNotSet) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(0) + .Build(); + + EXPECT_FALSE(procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR); +} + +// ============================================================================= +// PROC_ATTR_TRIGGERED_CAN_PROC (0x02) Tests +// ============================================================================= + +TEST_F(SpellProcAttributeTest, TriggeredCanProc_AttributeSet) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_TRIGGERED_CAN_PROC) + .Build(); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC); +} + +TEST_F(SpellProcAttributeTest, TriggeredCanProc_AttributeNotSet) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(0) + .Build(); + + EXPECT_FALSE(procEntry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC); +} + +// ============================================================================= +// PROC_ATTR_REQ_MANA_COST (0x04) Tests +// ============================================================================= + +TEST_F(SpellProcAttributeTest, ReqManaCost_AttributeSet) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_REQ_MANA_COST) + .Build(); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST); +} + +TEST_F(SpellProcAttributeTest, ReqManaCost_NullSpell_ShouldNotProc) +{ + // Null spell should never satisfy mana cost requirement + EXPECT_FALSE(ProcChanceTestHelper::SpellHasManaCost(nullptr)); +} + +// ============================================================================= +// PROC_ATTR_REQ_SPELLMOD (0x08) Tests +// ============================================================================= + +TEST_F(SpellProcAttributeTest, ReqSpellmod_AttributeSet) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_REQ_SPELLMOD) + .Build(); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD); +} + +TEST_F(SpellProcAttributeTest, ReqSpellmod_AttributeNotSet) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(0) + .Build(); + + EXPECT_FALSE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD); +} + +// ============================================================================= +// PROC_ATTR_USE_STACKS_FOR_CHARGES (0x10) Tests +// ============================================================================= + +TEST_F(SpellProcAttributeTest, UseStacksForCharges_AttributeSet) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_USE_STACKS_FOR_CHARGES) + .Build(); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_USE_STACKS_FOR_CHARGES); +} + +TEST_F(SpellProcAttributeTest, UseStacksForCharges_DecrementStacks) +{ + auto aura = AuraStubBuilder() + .WithId(12345) + .WithStackAmount(5) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_USE_STACKS_FOR_CHARGES) + .Build(); + + ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + + EXPECT_EQ(aura->GetStackAmount(), 4); +} + +TEST_F(SpellProcAttributeTest, UseStacksForCharges_NotSet_DecrementCharges) +{ + auto aura = AuraStubBuilder() + .WithId(12345) + .WithCharges(5) + .WithStackAmount(5) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(0) // No USE_STACKS_FOR_CHARGES + .Build(); + + ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + + // Charges should decrement, stacks unchanged + EXPECT_EQ(aura->GetCharges(), 4); + EXPECT_EQ(aura->GetStackAmount(), 5); +} + +// ============================================================================= +// PROC_ATTR_REDUCE_PROC_60 (0x80) Tests +// ============================================================================= + +TEST_F(SpellProcAttributeTest, ReduceProc60_AttributeSet) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REDUCE_PROC_60); +} + +TEST_F(SpellProcAttributeTest, ReduceProc60_Level60_NoReduction) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + float chance = ProcChanceTestHelper::SimulateCalcProcChance(procEntry, 60); + EXPECT_NEAR(chance, 30.0f, 0.01f); +} + +TEST_F(SpellProcAttributeTest, ReduceProc60_Level70_Reduced) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + // Level 70 = 10 levels above 60 + // Reduction = 10/30 = 33.33% + // 30% * (1 - 0.333) = 20% + float chance = ProcChanceTestHelper::SimulateCalcProcChance(procEntry, 70); + EXPECT_NEAR(chance, 20.0f, 0.5f); +} + +TEST_F(SpellProcAttributeTest, ReduceProc60_Level80_Reduced) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + // Level 80 = 20 levels above 60 + // Reduction = 20/30 = 66.67% + // 30% * (1 - 0.667) = 10% + float chance = ProcChanceTestHelper::SimulateCalcProcChance(procEntry, 80); + EXPECT_NEAR(chance, 10.0f, 0.5f); +} + +TEST_F(SpellProcAttributeTest, ReduceProc60_BelowLevel60_NoReduction) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + float chance = ProcChanceTestHelper::SimulateCalcProcChance(procEntry, 50); + EXPECT_NEAR(chance, 30.0f, 0.01f); +} + +TEST_F(SpellProcAttributeTest, ReduceProc60_NotSet_NoReduction) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(0) // No REDUCE_PROC_60 + .Build(); + + // Even at level 80, no reduction without attribute + float chance = ProcChanceTestHelper::SimulateCalcProcChance(procEntry, 80); + EXPECT_NEAR(chance, 30.0f, 0.01f); +} + +// ============================================================================= +// PROC_ATTR_CANT_PROC_FROM_ITEM_CAST (0x100) Tests +// ============================================================================= + +TEST_F(SpellProcAttributeTest, CantProcFromItemCast_AttributeSet) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_CANT_PROC_FROM_ITEM_CAST) + .Build(); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_CANT_PROC_FROM_ITEM_CAST); +} + +TEST_F(SpellProcAttributeTest, CantProcFromItemCast_AttributeNotSet) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(0) + .Build(); + + EXPECT_FALSE(procEntry.AttributesMask & PROC_ATTR_CANT_PROC_FROM_ITEM_CAST); +} + +// ============================================================================= +// Combined Attribute Tests +// ============================================================================= + +TEST_F(SpellProcAttributeTest, CombinedAttributes_MultipleFlags) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask( + PROC_ATTR_TRIGGERED_CAN_PROC | + PROC_ATTR_REQ_MANA_COST | + PROC_ATTR_REDUCE_PROC_60) + .Build(); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC); + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST); + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REDUCE_PROC_60); + EXPECT_FALSE(procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR); + EXPECT_FALSE(procEntry.AttributesMask & PROC_ATTR_USE_STACKS_FOR_CHARGES); +} + +TEST_F(SpellProcAttributeTest, CombinedAttributes_AllFlags) +{ + uint32 allFlags = + PROC_ATTR_REQ_EXP_OR_HONOR | + PROC_ATTR_TRIGGERED_CAN_PROC | + PROC_ATTR_REQ_MANA_COST | + PROC_ATTR_REQ_SPELLMOD | + PROC_ATTR_USE_STACKS_FOR_CHARGES | + PROC_ATTR_REDUCE_PROC_60 | + PROC_ATTR_CANT_PROC_FROM_ITEM_CAST; + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(allFlags) + .Build(); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR); + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC); + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST); + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD); + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_USE_STACKS_FOR_CHARGES); + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REDUCE_PROC_60); + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_CANT_PROC_FROM_ITEM_CAST); +} + +// ============================================================================= +// Real Spell Attribute Scenarios +// ============================================================================= + +TEST_F(SpellProcAttributeTest, Scenario_SealOfCommand_TriggeredCanProc) +{ + // Seal of Command (Paladin) can proc from triggered spells + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_TRIGGERED_CAN_PROC) + .Build(); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC); +} + +TEST_F(SpellProcAttributeTest, Scenario_ClearCasting_ReqManaCost) +{ + // Clearcasting (Mage/Priest) requires spell to have mana cost + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_REQ_MANA_COST) + .Build(); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST); + + // Null spell check - free/costless spells won't trigger + EXPECT_FALSE(ProcChanceTestHelper::SpellHasManaCost(nullptr)); +} + +TEST_F(SpellProcAttributeTest, Scenario_MaelstromWeapon_UseStacks) +{ + // Maelstrom Weapon (Shaman) uses stacks + auto aura = AuraStubBuilder() + .WithId(53817) + .WithStackAmount(5) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_USE_STACKS_FOR_CHARGES) + .Build(); + + // Each proc consumes one stack + ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_EQ(aura->GetStackAmount(), 4); + + ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_EQ(aura->GetStackAmount(), 3); +} + +TEST_F(SpellProcAttributeTest, Scenario_OldLevelScaling_ReduceProc60) +{ + // Some old vanilla/TBC procs have reduced chance at higher levels + auto procEntry = SpellProcEntryBuilder() + .WithChance(50.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + // Level 60: Full chance + float chanceAt60 = ProcChanceTestHelper::SimulateCalcProcChance(procEntry, 60); + EXPECT_NEAR(chanceAt60, 50.0f, 0.01f); + + // Level 75: 50% reduction (15/30) + float chanceAt75 = ProcChanceTestHelper::SimulateCalcProcChance(procEntry, 75); + EXPECT_NEAR(chanceAt75, 25.0f, 0.5f); + + // Level 90: 100% reduction (30/30), capped at 0 + float chanceAt90 = ProcChanceTestHelper::SimulateCalcProcChance(procEntry, 90); + EXPECT_NEAR(chanceAt90, 0.0f, 0.1f); +} + +// ============================================================================= +// Attribute Value Validation +// ============================================================================= + +TEST_F(SpellProcAttributeTest, AttributeValues_Correct) +{ + // Verify attribute flag values match expected hex values + EXPECT_EQ(PROC_ATTR_REQ_EXP_OR_HONOR, 0x0000001u); + EXPECT_EQ(PROC_ATTR_TRIGGERED_CAN_PROC, 0x0000002u); + EXPECT_EQ(PROC_ATTR_REQ_MANA_COST, 0x0000004u); + EXPECT_EQ(PROC_ATTR_REQ_SPELLMOD, 0x0000008u); + EXPECT_EQ(PROC_ATTR_USE_STACKS_FOR_CHARGES, 0x0000010u); + EXPECT_EQ(PROC_ATTR_REDUCE_PROC_60, 0x0000080u); + EXPECT_EQ(PROC_ATTR_CANT_PROC_FROM_ITEM_CAST, 0x0000100u); +} + +TEST_F(SpellProcAttributeTest, AttributeFlags_NonOverlapping) +{ + // Verify no two flags share the same bit + uint32 flags[] = { + PROC_ATTR_REQ_EXP_OR_HONOR, + PROC_ATTR_TRIGGERED_CAN_PROC, + PROC_ATTR_REQ_MANA_COST, + PROC_ATTR_REQ_SPELLMOD, + PROC_ATTR_USE_STACKS_FOR_CHARGES, + PROC_ATTR_REDUCE_PROC_60, + PROC_ATTR_CANT_PROC_FROM_ITEM_CAST + }; + + for (size_t i = 0; i < sizeof(flags)/sizeof(flags[0]); ++i) + { + for (size_t j = i + 1; j < sizeof(flags)/sizeof(flags[0]); ++j) + { + EXPECT_EQ(flags[i] & flags[j], 0u) + << "Flags at index " << i << " and " << j << " overlap"; + } + } +} diff --git a/src/test/server/game/Spells/SpellProcChanceTest.cpp b/src/test/server/game/Spells/SpellProcChanceTest.cpp new file mode 100644 index 000000000..7c7f6fbbf --- /dev/null +++ b/src/test/server/game/Spells/SpellProcChanceTest.cpp @@ -0,0 +1,317 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcChanceTest.cpp + * @brief Unit tests for proc chance calculations + * + * Tests CalcProcChance() behavior including: + * - Base chance from SpellProcEntry + * - PPM override when DamageInfo is present + * - Chance modifiers (SPELLMOD_CHANCE_OF_SUCCESS) + * - Level 60+ reduction (PROC_ATTR_REDUCE_PROC_60) + */ + +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "gtest/gtest.h" + +using namespace testing; + +// ============================================================================= +// Base Chance Tests +// ============================================================================= + +class SpellProcChanceTest : public ::testing::Test +{ +protected: + void SetUp() override {} +}; + +TEST_F(SpellProcChanceTest, BaseChance_UsedWhenNoPPM) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(25.0f) + .WithProcsPerMinute(0.0f) + .Build(); + + float result = ProcChanceTestHelper::SimulateCalcProcChance(procEntry); + EXPECT_NEAR(result, 25.0f, 0.01f); +} + +TEST_F(SpellProcChanceTest, BaseChance_100Percent) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + float result = ProcChanceTestHelper::SimulateCalcProcChance(procEntry); + EXPECT_NEAR(result, 100.0f, 0.01f); +} + +TEST_F(SpellProcChanceTest, BaseChance_Zero) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(0.0f) + .Build(); + + float result = ProcChanceTestHelper::SimulateCalcProcChance(procEntry); + EXPECT_NEAR(result, 0.0f, 0.01f); +} + +// ============================================================================= +// PPM Override Tests +// ============================================================================= + +TEST_F(SpellProcChanceTest, PPM_OverridesBaseChance_WithDamageInfo) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(50.0f) // This should be ignored + .WithProcsPerMinute(6.0f) + .Build(); + + // With DamageInfo, PPM takes precedence + // 2500ms * 6 PPM / 600 = 25% + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 2500, 0.0f, 0.0f, true); + EXPECT_NEAR(result, 25.0f, 0.01f); +} + +TEST_F(SpellProcChanceTest, PPM_NotApplied_WithoutDamageInfo) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(50.0f) + .WithProcsPerMinute(6.0f) + .Build(); + + // Without DamageInfo, base chance is used + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 2500, 0.0f, 0.0f, false); + EXPECT_NEAR(result, 50.0f, 0.01f); +} + +TEST_F(SpellProcChanceTest, PPM_WithWeaponSpeedVariation) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcsPerMinute(6.0f) + .Build(); + + // Fast weapon: 1400ms + float fastResult = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 1400, 0.0f, 0.0f, true); + EXPECT_NEAR(fastResult, 14.0f, 0.01f); + + // Slow weapon: 3300ms + float slowResult = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 3300, 0.0f, 0.0f, true); + EXPECT_NEAR(slowResult, 33.0f, 0.01f); +} + +// ============================================================================= +// Chance Modifier Tests +// ============================================================================= + +TEST_F(SpellProcChanceTest, ChanceModifier_PositiveModifier) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(20.0f) + .Build(); + + // +10% modifier + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 2500, 10.0f, 0.0f, false); + EXPECT_NEAR(result, 30.0f, 0.01f); +} + +TEST_F(SpellProcChanceTest, ChanceModifier_NegativeModifier) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .Build(); + + // -10% modifier + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 2500, -10.0f, 0.0f, false); + EXPECT_NEAR(result, 20.0f, 0.01f); +} + +TEST_F(SpellProcChanceTest, ChanceModifier_AppliedAfterPPM) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcsPerMinute(6.0f) + .Build(); + + // PPM gives 25%, +5% modifier = 30% + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 2500, 5.0f, 0.0f, true); + EXPECT_NEAR(result, 30.0f, 0.01f); +} + +TEST_F(SpellProcChanceTest, PPMModifier_IncreasesEffectivePPM) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcsPerMinute(6.0f) + .Build(); + + // 6 PPM + 2 PPM modifier = 8 effective PPM + // 2500 * 8 / 600 = 33.33% + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 2500, 0.0f, 2.0f, true); + EXPECT_NEAR(result, 33.33f, 0.01f); +} + +// ============================================================================= +// Level 60+ Reduction Tests (PROC_ATTR_REDUCE_PROC_60) +// ============================================================================= + +TEST_F(SpellProcChanceTest, Level60Reduction_NoReductionAtLevel60) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 60, 2500, 0.0f, 0.0f, false); + EXPECT_NEAR(result, 30.0f, 0.01f); +} + +TEST_F(SpellProcChanceTest, Level60Reduction_NoReductionBelowLevel60) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 50, 2500, 0.0f, 0.0f, false); + EXPECT_NEAR(result, 30.0f, 0.01f); +} + +TEST_F(SpellProcChanceTest, Level60Reduction_ReductionAtLevel70) +{ + // Level 70 = 10 levels above 60 + // Reduction = 10/30 = 33.33% + // 30% * (1 - 0.333) = 20% + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 70, 2500, 0.0f, 0.0f, false); + EXPECT_NEAR(result, 20.0f, 0.5f); +} + +TEST_F(SpellProcChanceTest, Level60Reduction_ReductionAtLevel80) +{ + // Level 80 = 20 levels above 60 + // Reduction = 20/30 = 66.67% + // 30% * (1 - 0.667) = 10% + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 2500, 0.0f, 0.0f, false); + EXPECT_NEAR(result, 10.0f, 0.5f); +} + +TEST_F(SpellProcChanceTest, Level60Reduction_MinimumAtLevel90) +{ + // Level 90 = 30 levels above 60 + // Reduction = 30/30 = 100% + // 30% * (1 - 1.0) = 0% + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 90, 2500, 0.0f, 0.0f, false); + EXPECT_NEAR(result, 0.0f, 0.1f); +} + +TEST_F(SpellProcChanceTest, Level60Reduction_NotAppliedWithoutAttribute) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(0) // No PROC_ATTR_REDUCE_PROC_60 + .Build(); + + // At level 80, without the attribute, no reduction should occur + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 2500, 0.0f, 0.0f, false); + EXPECT_NEAR(result, 30.0f, 0.01f); +} + +TEST_F(SpellProcChanceTest, Level60Reduction_AppliedAfterPPM) +{ + // PPM calculation gives 25%, then level reduction applied + // Level 80 = 20 levels above 60, reduction = 66.67% + // 25% * (1 - 0.667) = 8.33% + auto procEntry = SpellProcEntryBuilder() + .WithProcsPerMinute(6.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 2500, 0.0f, 0.0f, true); + EXPECT_NEAR(result, 8.33f, 0.5f); +} + +// ============================================================================= +// Helper Function Tests +// ============================================================================= + +TEST_F(SpellProcChanceTest, ApplyLevel60Reduction_DirectTest) +{ + // Level 60: no reduction + EXPECT_NEAR(ProcChanceTestHelper::ApplyLevel60Reduction(30.0f, 60), 30.0f, 0.01f); + + // Level 70: 33.33% reduction + EXPECT_NEAR(ProcChanceTestHelper::ApplyLevel60Reduction(30.0f, 70), 20.0f, 0.5f); + + // Level 80: 66.67% reduction + EXPECT_NEAR(ProcChanceTestHelper::ApplyLevel60Reduction(30.0f, 80), 10.0f, 0.5f); + + // Level 90: 100% reduction + EXPECT_NEAR(ProcChanceTestHelper::ApplyLevel60Reduction(30.0f, 90), 0.0f, 0.1f); + + // Level 100: capped at 0% (no negative chance) + EXPECT_GE(ProcChanceTestHelper::ApplyLevel60Reduction(30.0f, 100), 0.0f); +} + +// ============================================================================= +// Combined Tests +// ============================================================================= + +TEST_F(SpellProcChanceTest, Combined_PPM_ChanceModifier_LevelReduction) +{ + // PPM: 6 at 2500ms = 25% + // Chance modifier: +5% = 30% + // Level 70 reduction: 30% * (1 - 0.333) = 20% + auto procEntry = SpellProcEntryBuilder() + .WithProcsPerMinute(6.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 70, 2500, 5.0f, 0.0f, true); + EXPECT_NEAR(result, 20.0f, 1.0f); +} diff --git a/src/test/server/game/Spells/SpellProcChargeTest.cpp b/src/test/server/game/Spells/SpellProcChargeTest.cpp new file mode 100644 index 000000000..ec859862d --- /dev/null +++ b/src/test/server/game/Spells/SpellProcChargeTest.cpp @@ -0,0 +1,409 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcChargeTest.cpp + * @brief Unit tests for proc charge and stack consumption + * + * Tests ConsumeProcCharges() behavior including: + * - Charge decrement on proc + * - Aura removal when charges exhausted + * - PROC_ATTR_USE_STACKS_FOR_CHARGES stack decrement + * - Multiple charge consumption scenarios + */ + +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "AuraStub.h" +#include "gtest/gtest.h" + +using namespace testing; + +class SpellProcChargeTest : public ::testing::Test +{ +protected: + void SetUp() override {} +}; + +// ============================================================================= +// Basic Charge Consumption Tests +// ============================================================================= + +TEST_F(SpellProcChargeTest, ChargeDecrement_SingleCharge) +{ + auto aura = AuraStubBuilder() + .WithId(12345) + .WithCharges(1) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // Consume the single charge + bool removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + + EXPECT_EQ(aura->GetCharges(), 0); + EXPECT_TRUE(removed); + EXPECT_TRUE(aura->IsRemoved()); +} + +TEST_F(SpellProcChargeTest, ChargeDecrement_MultipleCharges) +{ + auto aura = AuraStubBuilder() + .WithId(12345) + .WithCharges(5) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // First consumption + bool removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_EQ(aura->GetCharges(), 4); + EXPECT_FALSE(removed); + EXPECT_FALSE(aura->IsRemoved()); + + // Second consumption + removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_EQ(aura->GetCharges(), 3); + EXPECT_FALSE(removed); + + // Third consumption + removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_EQ(aura->GetCharges(), 2); + EXPECT_FALSE(removed); + + // Fourth consumption + removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_EQ(aura->GetCharges(), 1); + EXPECT_FALSE(removed); + + // Final consumption - should remove aura + removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_EQ(aura->GetCharges(), 0); + EXPECT_TRUE(removed); + EXPECT_TRUE(aura->IsRemoved()); +} + +TEST_F(SpellProcChargeTest, NoCharges_NoConsumption) +{ + auto aura = AuraStubBuilder() + .WithId(12345) + .WithCharges(0) + .Build(); + + aura->SetUsingCharges(false); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + bool removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + + EXPECT_EQ(aura->GetCharges(), 0); + EXPECT_FALSE(removed); + EXPECT_FALSE(aura->IsRemoved()); +} + +// ============================================================================= +// PROC_ATTR_USE_STACKS_FOR_CHARGES Tests +// ============================================================================= + +TEST_F(SpellProcChargeTest, UseStacksForCharges_SingleStack) +{ + auto aura = AuraStubBuilder() + .WithId(12345) + .WithStackAmount(1) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_USE_STACKS_FOR_CHARGES) + .Build(); + + bool removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + + EXPECT_EQ(aura->GetStackAmount(), 0); + EXPECT_TRUE(removed); + EXPECT_TRUE(aura->IsRemoved()); +} + +TEST_F(SpellProcChargeTest, UseStacksForCharges_MultipleStacks) +{ + auto aura = AuraStubBuilder() + .WithId(12345) + .WithStackAmount(5) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_USE_STACKS_FOR_CHARGES) + .Build(); + + // First consumption - 5 -> 4 + bool removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_EQ(aura->GetStackAmount(), 4); + EXPECT_FALSE(removed); + EXPECT_FALSE(aura->IsRemoved()); + + // Second consumption - 4 -> 3 + removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_EQ(aura->GetStackAmount(), 3); + EXPECT_FALSE(removed); + + // Consume remaining stacks + ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); // 3 -> 2 + ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); // 2 -> 1 + + // Final consumption - should remove aura + removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_EQ(aura->GetStackAmount(), 0); + EXPECT_TRUE(removed); + EXPECT_TRUE(aura->IsRemoved()); +} + +TEST_F(SpellProcChargeTest, UseStacksForCharges_IgnoresCharges) +{ + auto aura = AuraStubBuilder() + .WithId(12345) + .WithCharges(10) // Has charges + .WithStackAmount(2) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_USE_STACKS_FOR_CHARGES) + .Build(); + + // Should decrement stacks, not charges + bool removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + + EXPECT_EQ(aura->GetStackAmount(), 1); + EXPECT_EQ(aura->GetCharges(), 10); // Charges unchanged + EXPECT_FALSE(removed); +} + +// ============================================================================= +// Real Spell Scenario Tests +// ============================================================================= + +TEST_F(SpellProcChargeTest, Scenario_HotStreak_3Charges) +{ + // Hot Streak (Fire Mage) - 3 charges, consumed on each instant Pyroblast + auto aura = AuraStubBuilder() + .WithId(48108) // Hot Streak + .WithCharges(3) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // First Pyroblast + EXPECT_FALSE(ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry)); + EXPECT_EQ(aura->GetCharges(), 2); + + // Second Pyroblast + EXPECT_FALSE(ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry)); + EXPECT_EQ(aura->GetCharges(), 1); + + // Third Pyroblast - aura removed + EXPECT_TRUE(ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry)); + EXPECT_EQ(aura->GetCharges(), 0); + EXPECT_TRUE(aura->IsRemoved()); +} + +TEST_F(SpellProcChargeTest, Scenario_BladeBarrier_5Stacks) +{ + // Blade Barrier (Death Knight) - 5 stacks, consumed over time + auto aura = AuraStubBuilder() + .WithId(55226) // Blade Barrier + .WithStackAmount(5) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_USE_STACKS_FOR_CHARGES) + .Build(); + + // Simulate stacks being consumed + for (int i = 5; i > 1; --i) + { + EXPECT_EQ(aura->GetStackAmount(), i); + EXPECT_FALSE(ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry)); + } + + // Last stack removal + EXPECT_EQ(aura->GetStackAmount(), 1); + EXPECT_TRUE(ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry)); + EXPECT_TRUE(aura->IsRemoved()); +} + +TEST_F(SpellProcChargeTest, Scenario_Maelstrom_5Stacks) +{ + // Maelstrom Weapon (Enhancement Shaman) - 5 stacks + auto aura = AuraStubBuilder() + .WithId(53817) // Maelstrom Weapon + .WithStackAmount(5) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_USE_STACKS_FOR_CHARGES) + .Build(); + + // At 5 stacks, cast instant Lightning Bolt consumes all stacks + // Simulate consuming all 5 stacks at once + for (int i = 0; i < 5; ++i) + { + ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + } + + EXPECT_EQ(aura->GetStackAmount(), 0); + EXPECT_TRUE(aura->IsRemoved()); +} + +// ============================================================================= +// Edge Case Tests +// ============================================================================= + +TEST_F(SpellProcChargeTest, NullAura_SafeHandling) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // Should not crash + bool removed = ProcChanceTestHelper::SimulateConsumeProcCharges(nullptr, procEntry); + EXPECT_FALSE(removed); +} + +TEST_F(SpellProcChargeTest, ZeroStacks_WithUseStacksAttribute) +{ + auto aura = AuraStubBuilder() + .WithId(12345) + .WithStackAmount(0) + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_USE_STACKS_FOR_CHARGES) + .Build(); + + // Should handle gracefully and remove aura + bool removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_TRUE(removed); + EXPECT_TRUE(aura->IsRemoved()); +} + +TEST_F(SpellProcChargeTest, HighChargeCount) +{ + auto aura = AuraStubBuilder() + .WithId(12345) + .WithCharges(255) // Max uint8 + .Build(); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // Consume one charge from max + bool removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), procEntry); + EXPECT_EQ(aura->GetCharges(), 254); + EXPECT_FALSE(removed); +} + +// ============================================================================= +// ProcTestScenario Integration Tests +// ============================================================================= + +TEST_F(SpellProcChargeTest, ProcTestScenario_ChargeConsumption) +{ + ProcTestScenario scenario; + scenario.WithAura(12345, 3); // 3 charges + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // First proc - consumes charge + EXPECT_TRUE(scenario.SimulateProc(procEntry)); + EXPECT_EQ(scenario.GetAura()->GetCharges(), 2); + + // Second proc - consumes charge + EXPECT_TRUE(scenario.SimulateProc(procEntry)); + EXPECT_EQ(scenario.GetAura()->GetCharges(), 1); + + // Third proc - consumes last charge and removes aura + EXPECT_TRUE(scenario.SimulateProc(procEntry)); + EXPECT_EQ(scenario.GetAura()->GetCharges(), 0); + EXPECT_TRUE(scenario.GetAura()->IsRemoved()); +} + +TEST_F(SpellProcChargeTest, ProcTestScenario_StackConsumption) +{ + ProcTestScenario scenario; + scenario.WithAura(12345, 0, 3); // 3 stacks + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_USE_STACKS_FOR_CHARGES) + .Build(); + + // First proc - consumes stack + EXPECT_TRUE(scenario.SimulateProc(procEntry)); + EXPECT_EQ(scenario.GetAura()->GetStackAmount(), 2); + + // Second proc - consumes stack + EXPECT_TRUE(scenario.SimulateProc(procEntry)); + EXPECT_EQ(scenario.GetAura()->GetStackAmount(), 1); + + // Third proc - consumes last stack and removes aura + EXPECT_TRUE(scenario.SimulateProc(procEntry)); + EXPECT_EQ(scenario.GetAura()->GetStackAmount(), 0); + EXPECT_TRUE(scenario.GetAura()->IsRemoved()); +} + +TEST_F(SpellProcChargeTest, ProcTestScenario_ChargesWithCooldown) +{ + using namespace std::chrono_literals; + + ProcTestScenario scenario; + scenario.WithAura(12345, 3); // 3 charges + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithCooldown(1000ms) // 1 second cooldown + .Build(); + + // First proc at t=0 - should work + EXPECT_TRUE(scenario.SimulateProc(procEntry)); + EXPECT_EQ(scenario.GetAura()->GetCharges(), 2); + + // Immediate second proc - blocked by cooldown + EXPECT_FALSE(scenario.SimulateProc(procEntry)); + EXPECT_EQ(scenario.GetAura()->GetCharges(), 2); // No charge consumed + + // Wait for cooldown + scenario.AdvanceTime(1100ms); + + // Third proc - should work + EXPECT_TRUE(scenario.SimulateProc(procEntry)); + EXPECT_EQ(scenario.GetAura()->GetCharges(), 1); +} diff --git a/src/test/server/game/Spells/SpellProcConditionsTest.cpp b/src/test/server/game/Spells/SpellProcConditionsTest.cpp new file mode 100644 index 000000000..eb57b2a90 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcConditionsTest.cpp @@ -0,0 +1,386 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcConditionsTest.cpp + * @brief Unit tests for conditions system integration in proc system + * + * Tests the logic from SpellAuras.cpp:2232-2236: + * - CONDITION_SOURCE_TYPE_SPELL_PROC (24) lookup + * - Condition met allows proc + * - Condition not met blocks proc + * - Empty conditions allow proc + * - Multiple conditions (AND logic within ElseGroup) + * - ElseGroup OR logic + * + * ============================================================================ + * TEST DESIGN: Configuration-Based Testing + * ============================================================================ + * + * These tests use ConditionsConfig structs to simulate the result of + * condition evaluation without requiring actual ConditionMgr queries. + * Each test configures: + * - sourceType: The condition source type (24 = CONDITION_SOURCE_TYPE_SPELL_PROC) + * - hasConditions: Whether any conditions are registered for this spell + * - conditionsMet: The result of ConditionMgr::IsObjectMeetToConditions() + * + * The actual condition types (CONDITION_AURA, CONDITION_HP_PCT, etc.) are + * not evaluated here - we test the proc system's response to condition + * evaluation results. Individual condition types are tested in the + * conditions system unit tests. + * + * No GTEST_SKIP() is used in this file - all tests run with their configured + * scenarios, testing both positive and negative cases explicitly. + * ============================================================================ + */ + +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "gtest/gtest.h" + +using namespace testing; + +class SpellProcConditionsTest : public ::testing::Test +{ +protected: + void SetUp() override {} +}; + +// ============================================================================= +// Basic Condition Tests +// ============================================================================= + +TEST_F(SpellProcConditionsTest, NoConditions_AllowsProc) +{ + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = false; // No conditions registered + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)) + << "No conditions should allow proc"; +} + +TEST_F(SpellProcConditionsTest, ConditionsMet_AllowsProc) +{ + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = true; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)) + << "Conditions met should allow proc"; +} + +TEST_F(SpellProcConditionsTest, ConditionsNotMet_BlocksProc) +{ + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = false; + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)) + << "Conditions not met should block proc"; +} + +// ============================================================================= +// Source Type Tests - CONDITION_SOURCE_TYPE_SPELL_PROC = 24 +// ============================================================================= + +TEST_F(SpellProcConditionsTest, SourceType_SpellProc) +{ + ProcChanceTestHelper::ConditionsConfig config; + config.sourceType = 24; // CONDITION_SOURCE_TYPE_SPELL_PROC + config.hasConditions = true; + config.conditionsMet = true; + + EXPECT_EQ(config.sourceType, 24u) + << "Source type should be CONDITION_SOURCE_TYPE_SPELL_PROC (24)"; + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)); +} + +// ============================================================================= +// Multiple Conditions Scenarios (AND Logic) +// ============================================================================= + +TEST_F(SpellProcConditionsTest, MultipleConditions_AllMet_AllowsProc) +{ + // Simulating multiple conditions in same ElseGroup (AND) + // In reality, ConditionMgr evaluates all - we just test the result + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = true; // All conditions passed + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)) + << "All conditions met (AND) should allow proc"; +} + +TEST_F(SpellProcConditionsTest, MultipleConditions_OneFails_BlocksProc) +{ + // One condition in the group fails + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = false; // At least one condition failed + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)) + << "One failed condition (AND) should block proc"; +} + +// ============================================================================= +// ElseGroup OR Logic Scenarios +// ============================================================================= + +TEST_F(SpellProcConditionsTest, ElseGroup_OneGroupPasses_AllowsProc) +{ + // ElseGroup logic: any group passing means conditions met + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = true; // At least one group passed + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)) + << "At least one ElseGroup passing should allow proc"; +} + +TEST_F(SpellProcConditionsTest, ElseGroup_AllGroupsFail_BlocksProc) +{ + // All ElseGroups fail + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = false; // No groups passed + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)) + << "All ElseGroups failing should block proc"; +} + +// ============================================================================= +// Real Spell Scenarios +// ============================================================================= + +TEST_F(SpellProcConditionsTest, Scenario_ProcOnlyInCombat) +{ + // Condition: Player must be in combat + ProcChanceTestHelper::ConditionsConfig inCombat; + inCombat.hasConditions = true; + inCombat.conditionsMet = true; // In combat + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(inCombat)) + << "Proc should work when in combat"; + + ProcChanceTestHelper::ConditionsConfig outOfCombat; + outOfCombat.hasConditions = true; + outOfCombat.conditionsMet = false; // Out of combat + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(outOfCombat)) + << "Proc should be blocked when out of combat"; +} + +TEST_F(SpellProcConditionsTest, Scenario_ProcOnlyVsUndead) +{ + // Condition: Target must be undead creature type + ProcChanceTestHelper::ConditionsConfig vsUndead; + vsUndead.hasConditions = true; + vsUndead.conditionsMet = true; // Target is undead + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(vsUndead)) + << "Proc should work against undead"; + + ProcChanceTestHelper::ConditionsConfig vsHumanoid; + vsHumanoid.hasConditions = true; + vsHumanoid.conditionsMet = false; // Target is humanoid + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(vsHumanoid)) + << "Proc should be blocked against non-undead"; +} + +TEST_F(SpellProcConditionsTest, Scenario_ProcRequiresAura) +{ + // Condition: Actor must have specific aura + ProcChanceTestHelper::ConditionsConfig hasAura; + hasAura.hasConditions = true; + hasAura.conditionsMet = true; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(hasAura)) + << "Proc should work when required aura is present"; + + ProcChanceTestHelper::ConditionsConfig noAura; + noAura.hasConditions = true; + noAura.conditionsMet = false; + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(noAura)) + << "Proc should be blocked when required aura is missing"; +} + +TEST_F(SpellProcConditionsTest, Scenario_ProcRequiresHealthBelow) +{ + // Condition: Actor health must be below threshold + ProcChanceTestHelper::ConditionsConfig lowHealth; + lowHealth.hasConditions = true; + lowHealth.conditionsMet = true; // Health below 35% + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(lowHealth)) + << "Proc should work when health is below threshold"; + + ProcChanceTestHelper::ConditionsConfig highHealth; + highHealth.hasConditions = true; + highHealth.conditionsMet = false; // Health above 35% + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(highHealth)) + << "Proc should be blocked when health is above threshold"; +} + +TEST_F(SpellProcConditionsTest, Scenario_ProcInAreaOnly) +{ + // Condition: Must be in specific zone/area + ProcChanceTestHelper::ConditionsConfig inArea; + inArea.hasConditions = true; + inArea.conditionsMet = true; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(inArea)) + << "Proc should work when in required area"; + + ProcChanceTestHelper::ConditionsConfig notInArea; + notInArea.hasConditions = true; + notInArea.conditionsMet = false; + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(notInArea)) + << "Proc should be blocked when not in required area"; +} + +// ============================================================================= +// Condition Type Scenarios (Common CONDITION_* types used with procs) +// ============================================================================= + +TEST_F(SpellProcConditionsTest, ConditionType_Aura) +{ + // CONDITION_AURA = 1 + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = true; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)); +} + +TEST_F(SpellProcConditionsTest, ConditionType_Item) +{ + // CONDITION_ITEM = 2 + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = true; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)); +} + +TEST_F(SpellProcConditionsTest, ConditionType_ItemEquipped) +{ + // CONDITION_ITEM_EQUIPPED = 3 + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = false; // Required item not equipped + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)) + << "Proc blocked when required item not equipped"; +} + +TEST_F(SpellProcConditionsTest, ConditionType_QuestRewarded) +{ + // CONDITION_QUESTREWARDED = 8 + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = true; // Required quest completed + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)) + << "Proc allowed when quest completed"; +} + +TEST_F(SpellProcConditionsTest, ConditionType_CreatureType) +{ + // CONDITION_CREATURE_TYPE = 18 + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = false; // Wrong creature type + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)) + << "Proc blocked when creature type doesn't match"; +} + +TEST_F(SpellProcConditionsTest, ConditionType_HPVal) +{ + // CONDITION_HP_VAL = 23 + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = true; // HP threshold met + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)); +} + +TEST_F(SpellProcConditionsTest, ConditionType_HPPct) +{ + // CONDITION_HP_PCT = 25 + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = false; // HP percent threshold not met + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)); +} + +TEST_F(SpellProcConditionsTest, ConditionType_InCombat) +{ + // CONDITION_IN_COMBAT = 36 + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = true; // In combat + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)); +} + +// ============================================================================= +// Edge Cases +// ============================================================================= + +TEST_F(SpellProcConditionsTest, EdgeCase_EmptyConditionList) +{ + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = false; + config.conditionsMet = false; // Doesn't matter when no conditions + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)) + << "Empty condition list should allow proc"; +} + +TEST_F(SpellProcConditionsTest, EdgeCase_ConditionsButAlwaysTrue) +{ + // Conditions exist but are always satisfied (e.g., always-true condition) + ProcChanceTestHelper::ConditionsConfig config; + config.hasConditions = true; + config.conditionsMet = true; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(config)); +} + +TEST_F(SpellProcConditionsTest, EdgeCase_MultipleSourceTypes) +{ + // Different source types shouldn't interfere + // Each spell proc has its own conditions by spell ID + ProcChanceTestHelper::ConditionsConfig spell1; + spell1.sourceType = 24; + spell1.hasConditions = true; + spell1.conditionsMet = true; + + ProcChanceTestHelper::ConditionsConfig spell2; + spell2.sourceType = 24; + spell2.hasConditions = true; + spell2.conditionsMet = false; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToConditions(spell1)); + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToConditions(spell2)); +} diff --git a/src/test/server/game/Spells/SpellProcCooldownTest.cpp b/src/test/server/game/Spells/SpellProcCooldownTest.cpp new file mode 100644 index 000000000..ed997a629 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcCooldownTest.cpp @@ -0,0 +1,219 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcCooldownTest.cpp + * @brief Unit tests for proc internal cooldown system + */ + +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "AuraStub.h" +#include "gtest/gtest.h" + +using namespace testing; +using namespace std::chrono_literals; + +class SpellProcCooldownTest : public ::testing::Test +{ +protected: + void SetUp() override + { + _now = std::chrono::steady_clock::now(); + } + + std::chrono::steady_clock::time_point _now; +}; + +// ============================================================================= +// Basic Cooldown Tests +// ============================================================================= + +TEST_F(SpellProcCooldownTest, NotOnCooldown_Initially) +{ + auto aura = AuraStubBuilder().WithId(12345).Build(); + + EXPECT_FALSE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now)); +} + +TEST_F(SpellProcCooldownTest, OnCooldown_AfterProc) +{ + auto aura = AuraStubBuilder().WithId(12345).Build(); + + // Apply 1 second cooldown + ProcChanceTestHelper::ApplyProcCooldown(aura.get(), _now, 1000); + + // Should be on cooldown immediately after + EXPECT_TRUE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now)); + EXPECT_TRUE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now + 500ms)); +} + +TEST_F(SpellProcCooldownTest, NotOnCooldown_AfterExpiry) +{ + auto aura = AuraStubBuilder().WithId(12345).Build(); + + // Apply 1 second cooldown + ProcChanceTestHelper::ApplyProcCooldown(aura.get(), _now, 1000); + + // Should not be on cooldown after 1 second + EXPECT_FALSE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now + 1001ms)); +} + +TEST_F(SpellProcCooldownTest, ExactCooldownBoundary) +{ + auto aura = AuraStubBuilder().WithId(12345).Build(); + + ProcChanceTestHelper::ApplyProcCooldown(aura.get(), _now, 1000); + + // At exactly cooldown time, should still be on cooldown (< not <=) + EXPECT_TRUE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now + 999ms)); + // One millisecond after should be off cooldown + EXPECT_FALSE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now + 1000ms)); +} + +// ============================================================================= +// Zero Cooldown Tests +// ============================================================================= + +TEST_F(SpellProcCooldownTest, ZeroCooldown_NeverBlocks) +{ + auto aura = AuraStubBuilder().WithId(12345).Build(); + + // Zero cooldown should not apply any cooldown + ProcChanceTestHelper::ApplyProcCooldown(aura.get(), _now, 0); + + EXPECT_FALSE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now)); +} + +// ============================================================================= +// Cooldown Reset Tests +// ============================================================================= + +TEST_F(SpellProcCooldownTest, CooldownCanBeReset) +{ + auto aura = AuraStubBuilder().WithId(12345).Build(); + + ProcChanceTestHelper::ApplyProcCooldown(aura.get(), _now, 5000); + EXPECT_TRUE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now)); + + aura->ResetProcCooldown(); + EXPECT_FALSE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now)); +} + +TEST_F(SpellProcCooldownTest, CooldownCanBeExtended) +{ + auto aura = AuraStubBuilder().WithId(12345).Build(); + + // Apply 1 second cooldown + ProcChanceTestHelper::ApplyProcCooldown(aura.get(), _now, 1000); + + // Extend to 5 seconds + ProcChanceTestHelper::ApplyProcCooldown(aura.get(), _now, 5000); + + // Should still be on cooldown after 2 seconds + EXPECT_TRUE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now + 2000ms)); +} + +// ============================================================================= +// Scenario Tests +// ============================================================================= + +TEST_F(SpellProcCooldownTest, Scenario_LeaderOfThePack_6SecCooldown) +{ + // Leader of the Pack has a 6 second internal cooldown + auto aura = AuraStubBuilder().WithId(24932).Build(); + + // First proc + ProcChanceTestHelper::ApplyProcCooldown(aura.get(), _now, 6000); + + // Blocked at 3 seconds + EXPECT_TRUE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now + 3000ms)); + + // Blocked at 5.9 seconds + EXPECT_TRUE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now + 5999ms)); + + // Allowed at 6 seconds + EXPECT_FALSE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now + 6000ms)); +} + +TEST_F(SpellProcCooldownTest, Scenario_WanderingPlague_1SecCooldown) +{ + // Wandering Plague has a 1 second internal cooldown + auto aura = AuraStubBuilder().WithId(49217).Build(); + + ProcChanceTestHelper::ApplyProcCooldown(aura.get(), _now, 1000); + + // Blocked at 0.5 seconds + EXPECT_TRUE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now + 500ms)); + + // Allowed at 1 second + EXPECT_FALSE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), _now + 1000ms)); +} + +TEST_F(SpellProcCooldownTest, Scenario_MultipleProcsWithCooldown) +{ + auto aura = AuraStubBuilder().WithId(12345).Build(); + auto time = _now; + + // First proc at t=0 + EXPECT_FALSE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), time)); + ProcChanceTestHelper::ApplyProcCooldown(aura.get(), time, 1000); + + // Second attempt at t=0.5 (blocked) + time += 500ms; + EXPECT_TRUE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), time)); + + // Third attempt at t=1.0 (allowed) + time += 500ms; + EXPECT_FALSE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), time)); + ProcChanceTestHelper::ApplyProcCooldown(aura.get(), time, 1000); + + // Fourth attempt at t=1.5 (blocked) + time += 500ms; + EXPECT_TRUE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), time)); + + // Fifth attempt at t=2.0 (allowed) + time += 500ms; + EXPECT_FALSE(ProcChanceTestHelper::IsProcOnCooldown(aura.get(), time)); +} + +// ============================================================================= +// ProcTestScenario Tests +// ============================================================================= + +TEST_F(SpellProcCooldownTest, ProcTestScenario_CooldownBlocking) +{ + ProcTestScenario scenario; + scenario.WithAura(12345); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithCooldown(1000ms) + .Build(); + + // First proc should succeed + EXPECT_TRUE(scenario.SimulateProc(procEntry)); + + // Second proc immediately after should fail (on cooldown) + EXPECT_FALSE(scenario.SimulateProc(procEntry)); + + // Advance time past cooldown + scenario.AdvanceTime(1100ms); + + // Third proc should succeed + EXPECT_TRUE(scenario.SimulateProc(procEntry)); +} diff --git a/src/test/server/game/Spells/SpellProcDBCValidationTest.cpp b/src/test/server/game/Spells/SpellProcDBCValidationTest.cpp new file mode 100644 index 000000000..99eae3673 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcDBCValidationTest.cpp @@ -0,0 +1,369 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcDBCValidationTest.cpp + * @brief Unit tests for validating spell_proc entries against Spell.dbc + * + * Tests validate that spell_proc entries provide value beyond DBC defaults: + * - Entries that override DBC ProcFlags/ProcChance/ProcCharges + * - Entries that add new functionality (PPM, cooldowns, filtering) + * - Identification of potentially redundant entries + * + * ============================================================================ + * DBC DATA POPULATION STATUS + * ============================================================================ + * + * The DBC_ProcFlags, DBC_ProcChance, and DBC_ProcCharges fields in + * SpellProcTestEntry are currently populated with zeros (0, 0, 0) for all + * entries. To fully validate spell_proc entries against DBC: + * + * 1. Use the generate_spell_proc_dbc_data.py script with MCP connection + * 2. Or manually query: get_spell_dbc_proc_info(spell_id) for each spell + * + * Tests that require DBC data will check HasDBCData() and skip appropriately. + * Once DBC data is populated, the statistics tests will show: + * - How many entries override DBC defaults + * - How many entries add new functionality not in DBC + * - How many entries might be redundant (just duplicate DBC values) + * ============================================================================ + */ + +#include "SpellProcTestData.h" +#include "gtest/gtest.h" +#include +#include +#include + +using namespace testing; + +// ============================================================================= +// DBC Validation Test Fixture +// ============================================================================= + +class SpellProcDBCValidationTest : public ::testing::Test +{ +protected: + void SetUp() override + { + _allEntries = GetAllSpellProcTestEntries(); + } + + std::vector _allEntries; +}; + +// ============================================================================= +// Parameterized Tests for All Entries +// ============================================================================= + +class SpellProcDBCValidationParamTest : public ::testing::TestWithParam +{ +}; + +TEST_P(SpellProcDBCValidationParamTest, EntryHasValidSpellId) +{ + auto const& entry = GetParam(); + int32_t spellId = std::abs(entry.SpellId); + + // Spell ID must be positive after abs + EXPECT_GT(spellId, 0) << "SpellId must be non-zero"; + + // Spell IDs in WotLK should be < 80000 + EXPECT_LT(spellId, 80000u) + << "SpellId " << spellId << " seems out of range for WotLK"; +} + +INSTANTIATE_TEST_SUITE_P( + AllSpellProcEntries, + SpellProcDBCValidationParamTest, + ::testing::ValuesIn(GetAllSpellProcTestEntries()), + [](const testing::TestParamInfo& info) { + // Create unique test name from SpellId (handle negative IDs) + int32_t id = info.param.SpellId; + if (id < 0) + return "SpellId_N" + std::to_string(-id); + return "SpellId_" + std::to_string(id); + } +); + +// ============================================================================= +// Statistics Tests +// ============================================================================= + +TEST_F(SpellProcDBCValidationTest, CountEntriesWithDBCData) +{ + size_t withDBC = 0; + size_t withoutDBC = 0; + + for (auto const& entry : _allEntries) + { + if (entry.HasDBCData()) + withDBC++; + else + withoutDBC++; + } + + std::cout << "[ INFO ] Entries with DBC data: " << withDBC << "\n"; + std::cout << "[ INFO ] Entries without DBC data: " << withoutDBC << std::endl; + + // All entries should eventually have DBC data + // For now, just verify the count + EXPECT_EQ(_allEntries.size(), 869u); +} + +TEST_F(SpellProcDBCValidationTest, CountEntriesAddingValue) +{ + size_t addsValue = 0; + size_t potentiallyRedundant = 0; + size_t noDBCYet = 0; + + for (auto const& entry : _allEntries) + { + // SKIP REASON: Entries without DBC data populated cannot be compared + // against DBC defaults. The HasDBCData() check returns false when + // DBC_ProcFlags, DBC_ProcChance, and DBC_ProcCharges are all zero. + // Once DBC data is populated via MCP tools, this count should be 0. + if (!entry.HasDBCData()) + { + noDBCYet++; + continue; + } + + if (entry.AddsValueBeyondDBC()) + addsValue++; + else + potentiallyRedundant++; + } + + std::cout << "[ INFO ] Entries adding value: " << addsValue << "\n"; + std::cout << "[ INFO ] Potentially redundant: " << potentiallyRedundant << "\n"; + std::cout << "[ INFO ] DBC data not yet populated: " << noDBCYet << std::endl; + + // Most entries should add value (have PPM, cooldowns, filtering, etc.) + if (addsValue + potentiallyRedundant > 0) + { + float valueRate = static_cast(addsValue) / (addsValue + potentiallyRedundant) * 100; + std::cout << "[ INFO ] Value-add rate: " << valueRate << "%" << std::endl; + } +} + +TEST_F(SpellProcDBCValidationTest, CategorizeEntriesByFeature) +{ + size_t hasPPM = 0; + size_t hasCooldown = 0; + size_t hasSpellTypeMask = 0; + size_t hasSpellPhaseMask = 0; + size_t hasHitMask = 0; + size_t hasAttributesMask = 0; + size_t hasSpellFamilyMask = 0; + size_t hasSchoolMask = 0; + size_t hasCharges = 0; + size_t hasDisableEffectsMask = 0; + + for (auto const& entry : _allEntries) + { + if (entry.ProcsPerMinute > 0) hasPPM++; + if (entry.Cooldown > 0) hasCooldown++; + if (entry.SpellTypeMask != 0) hasSpellTypeMask++; + if (entry.SpellPhaseMask != 0) hasSpellPhaseMask++; + if (entry.HitMask != 0) hasHitMask++; + if (entry.AttributesMask != 0) hasAttributesMask++; + if (entry.SpellFamilyMask0 != 0 || entry.SpellFamilyMask1 != 0 || entry.SpellFamilyMask2 != 0) + hasSpellFamilyMask++; + if (entry.SchoolMask != 0) hasSchoolMask++; + if (entry.Charges > 0) hasCharges++; + if (entry.DisableEffectsMask != 0) hasDisableEffectsMask++; + } + + std::cout << "[ INFO ] Feature usage (adds value beyond DBC):\n" + << " PPM: " << hasPPM << "\n" + << " Cooldown: " << hasCooldown << "\n" + << " SpellTypeMask: " << hasSpellTypeMask << "\n" + << " SpellPhaseMask: " << hasSpellPhaseMask << "\n" + << " HitMask: " << hasHitMask << "\n" + << " AttributesMask: " << hasAttributesMask << "\n" + << " SpellFamilyMask: " << hasSpellFamilyMask << "\n" + << " SchoolMask: " << hasSchoolMask << "\n" + << " Charges: " << hasCharges << "\n" + << " DisableEffectsMask: " << hasDisableEffectsMask << std::endl; + + // Most entries should use at least one extended feature + size_t usingExtendedFeatures = 0; + for (auto const& entry : _allEntries) + { + if (entry.ProcsPerMinute > 0 || entry.Cooldown > 0 || + entry.SpellTypeMask != 0 || entry.SpellPhaseMask != 0 || + entry.HitMask != 0 || entry.AttributesMask != 0 || + entry.SpellFamilyMask0 != 0 || entry.SpellFamilyMask1 != 0 || + entry.SpellFamilyMask2 != 0 || entry.SchoolMask != 0 || + entry.DisableEffectsMask != 0) + { + usingExtendedFeatures++; + } + } + + std::cout << "[ INFO ] Entries using extended features: " << usingExtendedFeatures + << " / " << _allEntries.size() << std::endl; + + // At least 80% should use extended features + EXPECT_GT(usingExtendedFeatures, _allEntries.size() * 80 / 100) + << "Most entries should use extended features"; +} + +TEST_F(SpellProcDBCValidationTest, IdentifyDBCOverrides) +{ + size_t overridesProcFlags = 0; + size_t overridesChance = 0; + size_t overridesCharges = 0; + + for (auto const& entry : _allEntries) + { + // SKIP REASON: Cannot compare against DBC defaults when DBC data + // is not populated. All 869 entries currently have DBC fields = 0. + // Once populated, this loop will count actual DBC overrides. + if (!entry.HasDBCData()) + continue; + + if (entry.ProcFlags != 0 && entry.ProcFlags != entry.DBC_ProcFlags) + overridesProcFlags++; + + if (entry.Chance != 0 && static_cast(entry.Chance) != entry.DBC_ProcChance) + overridesChance++; + + if (entry.Charges != 0 && entry.Charges != entry.DBC_ProcCharges) + overridesCharges++; + } + + std::cout << "[ INFO ] DBC Overrides:\n" + << " ProcFlags: " << overridesProcFlags << "\n" + << " Chance: " << overridesChance << "\n" + << " Charges: " << overridesCharges << std::endl; +} + +// ============================================================================= +// Negative Spell ID Tests (Effect-specific procs) +// ============================================================================= + +TEST_F(SpellProcDBCValidationTest, CountNegativeSpellIds) +{ + size_t negativeIds = 0; + size_t positiveIds = 0; + + for (auto const& entry : _allEntries) + { + if (entry.SpellId < 0) + negativeIds++; + else + positiveIds++; + } + + std::cout << "[ INFO ] Negative SpellIds (effect-specific): " << negativeIds << "\n"; + std::cout << "[ INFO ] Positive SpellIds: " << positiveIds << std::endl; + + // Both types should exist + EXPECT_GT(negativeIds, 0u) << "Should have some effect-specific (negative ID) entries"; + EXPECT_GT(positiveIds, 0u) << "Should have some spell-wide (positive ID) entries"; +} + +// ============================================================================= +// SpellFamily Coverage Tests +// ============================================================================= + +TEST_F(SpellProcDBCValidationTest, CoverageBySpellFamily) +{ + std::map familyCounts; + std::map familyNames = { + {0, "Generic"}, {3, "Mage"}, {4, "Warrior"}, {5, "Warlock"}, + {6, "Priest"}, {7, "Druid"}, {8, "Rogue"}, {9, "Hunter"}, + {10, "Paladin"}, {11, "Shaman"}, {15, "DeathKnight"} + }; + + for (auto const& entry : _allEntries) + { + familyCounts[entry.SpellFamilyName]++; + } + + std::cout << "[ INFO ] Entries by SpellFamily:\n"; + for (auto const& [family, count] : familyCounts) + { + std::string name = familyNames.count(family) ? familyNames[family] : "Unknown"; + std::cout << " " << name << " (" << family << "): " << count << "\n"; + } + + // Should have entries from multiple spell families + EXPECT_GT(familyCounts.size(), 5u) << "Should cover multiple spell families"; +} + +// ============================================================================= +// Data Integrity Tests +// ============================================================================= + +TEST_F(SpellProcDBCValidationTest, NoDuplicateSpellIds) +{ + std::set seenIds; + std::vector duplicates; + + for (auto const& entry : _allEntries) + { + if (seenIds.count(entry.SpellId)) + duplicates.push_back(entry.SpellId); + else + seenIds.insert(entry.SpellId); + } + + if (!duplicates.empty()) + { + std::cout << "[ WARN ] Duplicate SpellIds found: "; + for (auto id : duplicates) + std::cout << id << " "; + std::cout << std::endl; + } + + EXPECT_TRUE(duplicates.empty()) << "Should have no duplicate SpellIds"; +} + +TEST_F(SpellProcDBCValidationTest, AllEntriesHaveValidStructure) +{ + for (auto const& entry : _allEntries) + { + // SpellId must be non-zero + EXPECT_NE(entry.SpellId, 0) + << "SpellId cannot be zero"; + + // If Chance is set, it should be reasonable (0-100, or 101 for 100% from DBC) + if (entry.Chance > 0) + { + EXPECT_LE(entry.Chance, 101.0f) + << "SpellId " << entry.SpellId << " has unusual Chance: " << entry.Chance; + } + + // PPM should be reasonable (typically 0-60) + if (entry.ProcsPerMinute > 0) + { + EXPECT_LE(entry.ProcsPerMinute, 60.0f) + << "SpellId " << entry.SpellId << " has unusual PPM: " << entry.ProcsPerMinute; + } + + // SpellPhaseMask should use valid values + if (entry.SpellPhaseMask != 0) + { + // Valid phase masks: PROC_SPELL_PHASE_CAST(1), PROC_SPELL_PHASE_HIT(2), PROC_SPELL_PHASE_FINISH(4) + EXPECT_LE(entry.SpellPhaseMask, 7u) + << "SpellId " << entry.SpellId << " has unusual SpellPhaseMask: " << entry.SpellPhaseMask; + } + } +} diff --git a/src/test/server/game/Spells/SpellProcDataDrivenTest.cpp b/src/test/server/game/Spells/SpellProcDataDrivenTest.cpp new file mode 100644 index 000000000..56a9e4437 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcDataDrivenTest.cpp @@ -0,0 +1,756 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcDataDrivenTest.cpp + * @brief Comprehensive data-driven tests for ALL 869 spell_proc entries + * + * This file auto-tests every spell_proc entry from the database. + * Data is generated by: src/test/scripts/generate_spell_proc_data.py + */ + +#include "ProcEventInfoHelper.h" +#include "SpellInfoTestHelper.h" +#include "SpellMgr.h" +#include "SpellProcTestData.h" +#include "WorldMock.h" +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include +#include + +using namespace testing; + +// ============================================================================= +// Proc Flag Mappings +// ============================================================================= + +struct ProcFlagScenario +{ + uint32 procFlag; + const char* name; + uint32 defaultHitMask; + uint32 defaultSpellTypeMask; + uint32 defaultSpellPhaseMask; + bool requiresSpellPhase; +}; + +static const std::vector PROC_FLAG_SCENARIOS = { + { PROC_FLAG_DONE_MELEE_AUTO_ATTACK, "DoneMeleeAuto", PROC_HIT_NORMAL, 0, 0, false }, + { PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK, "TakenMeleeAuto", PROC_HIT_NORMAL, 0, 0, false }, + { PROC_FLAG_DONE_MAINHAND_ATTACK, "DoneMainhand", PROC_HIT_NORMAL, 0, 0, false }, + { PROC_FLAG_DONE_OFFHAND_ATTACK, "DoneOffhand", PROC_HIT_NORMAL, 0, 0, false }, + { PROC_FLAG_DONE_RANGED_AUTO_ATTACK, "DoneRangedAuto", PROC_HIT_NORMAL, 0, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, "TakenRangedAuto", PROC_HIT_NORMAL, 0, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, "DoneSpellMelee", PROC_HIT_NORMAL, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, "TakenSpellMelee", PROC_HIT_NORMAL, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, "DoneSpellRanged", PROC_HIT_NORMAL, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, "TakenSpellRanged", PROC_HIT_NORMAL, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, "DoneSpellNonePos", PROC_HIT_NORMAL, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, "TakenSpellNonePos", PROC_HIT_NORMAL, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, "DoneSpellNoneNeg", PROC_HIT_NORMAL, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, "TakenSpellNoneNeg", PROC_HIT_NORMAL, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, "DoneSpellMagicPos", PROC_HIT_NORMAL, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS,"TakenSpellMagicPos", PROC_HIT_NORMAL, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, "DoneSpellMagicNeg", PROC_HIT_NORMAL, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG,"TakenSpellMagicNeg", PROC_HIT_NORMAL, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_DONE_PERIODIC, "DonePeriodic", PROC_HIT_NORMAL, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_TAKEN_PERIODIC, "TakenPeriodic", PROC_HIT_NORMAL, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, true }, + { PROC_FLAG_TAKEN_DAMAGE, "TakenDamage", PROC_HIT_NORMAL, 0, 0, false }, + { PROC_FLAG_KILL, "Kill", 0, 0, 0, false }, + { PROC_FLAG_KILLED, "Killed", 0, 0, 0, false }, + { PROC_FLAG_DEATH, "Death", 0, 0, 0, false }, + { PROC_FLAG_DONE_TRAP_ACTIVATION, "TrapActivation", PROC_HIT_NORMAL, 0, PROC_SPELL_PHASE_HIT, true }, +}; + +static const std::vector> HIT_MASK_SCENARIOS = { + { PROC_HIT_NORMAL, "Normal" }, + { PROC_HIT_CRITICAL, "Critical" }, + { PROC_HIT_MISS, "Miss" }, + { PROC_HIT_DODGE, "Dodge" }, + { PROC_HIT_PARRY, "Parry" }, + { PROC_HIT_BLOCK, "Block" }, + { PROC_HIT_EVADE, "Evade" }, + { PROC_HIT_IMMUNE, "Immune" }, + { PROC_HIT_DEFLECT, "Deflect" }, + { PROC_HIT_ABSORB, "Absorb" }, + { PROC_HIT_REFLECT, "Reflect" }, + { PROC_HIT_INTERRUPT, "Interrupt" }, + { PROC_HIT_FULL_BLOCK, "FullBlock" }, +}; + +// ============================================================================= +// Test Fixture for Comprehensive Database Testing +// ============================================================================= + +class SpellProcDatabaseTest : public ::testing::Test +{ +protected: + void SetUp() override + { + _originalWorld = sWorld.release(); + _worldMock = new NiceMock(); + sWorld.reset(_worldMock); + + static std::string emptyString; + ON_CALL(*_worldMock, GetDataPath()).WillByDefault(ReturnRef(emptyString)); + + // Load all entries from generated data + _allEntries = GetAllSpellProcTestEntries(); + + // Create a default SpellInfo for spell-type procs + _defaultSpellInfo = SpellInfoBuilder() + .WithId(99999) + .WithSpellFamilyName(0) + .Build(); + } + + void TearDown() override + { + IWorld* currentWorld = sWorld.release(); + delete currentWorld; + _worldMock = nullptr; + sWorld.reset(_originalWorld); + + delete _defaultSpellInfo; + _defaultSpellInfo = nullptr; + delete _damageInfo; + _damageInfo = nullptr; + delete _healInfo; + _healInfo = nullptr; + } + + /** + * @brief Find the first matching proc flag scenario for given flags + */ + ProcFlagScenario const* FindMatchingScenario(uint32 procFlags) + { + for (auto const& scenario : PROC_FLAG_SCENARIOS) + { + if (procFlags & scenario.procFlag) + return &scenario; + } + return nullptr; + } + + /** + * @brief Get effective hit mask for an entry + */ + uint32 GetEffectiveHitMask(SpellProcTestEntry const& entry, ProcFlagScenario const* scenario) + { + if (entry.HitMask != 0) + { + // Return first set bit + for (auto const& [mask, name] : HIT_MASK_SCENARIOS) + { + if (entry.HitMask & mask) + return mask; + } + } + return scenario ? scenario->defaultHitMask : PROC_HIT_NORMAL; + } + + /** + * @brief Get effective spell type mask + */ + uint32 GetEffectiveSpellTypeMask(SpellProcTestEntry const& entry, ProcFlagScenario const* scenario) + { + if (entry.SpellTypeMask != 0) + { + if (entry.SpellTypeMask & PROC_SPELL_TYPE_DAMAGE) + return PROC_SPELL_TYPE_DAMAGE; + if (entry.SpellTypeMask & PROC_SPELL_TYPE_HEAL) + return PROC_SPELL_TYPE_HEAL; + if (entry.SpellTypeMask & PROC_SPELL_TYPE_NO_DMG_HEAL) + return PROC_SPELL_TYPE_NO_DMG_HEAL; + } + return scenario ? scenario->defaultSpellTypeMask : PROC_SPELL_TYPE_MASK_ALL; + } + + /** + * @brief Get effective spell phase mask + */ + uint32 GetEffectiveSpellPhaseMask(SpellProcTestEntry const& entry, ProcFlagScenario const* scenario) + { + if (entry.SpellPhaseMask != 0) + return entry.SpellPhaseMask; + if (scenario && scenario->requiresSpellPhase) + return scenario->defaultSpellPhaseMask ? scenario->defaultSpellPhaseMask : PROC_SPELL_PHASE_HIT; + return 0; + } + + /** + * @brief Check if entry requires SpellFamily matching (which we can't test without SpellInfo) + * Any entry with SpellFamilyName > 0 will cause CanSpellTriggerProcOnEvent to access + * eventInfo.GetSpellInfo() which returns null in our test, causing a crash. + */ + bool RequiresSpellFamilyMatch(SpellProcTestEntry const& entry) + { + // Skip any entry with SpellFamilyName set - the code will try to access SpellInfo + return entry.SpellFamilyName != 0; + } + + /** + * @brief Check if the proc flags indicate a spell-type event that needs SpellInfo + */ + bool IsSpellTypeProc(uint32 procFlags) + { + return (procFlags & (PERIODIC_PROC_FLAG_MASK | SPELL_PROC_FLAG_MASK | PROC_FLAG_DONE_TRAP_ACTIVATION)) != 0; + } + + /** + * @brief Create a ProcEventInfo with proper DamageInfo/HealInfo for spell-type procs + */ + ProcEventInfo CreateEventInfo(uint32 typeMask, uint32 hitMask, uint32 spellTypeMask, uint32 spellPhaseMask) + { + auto builder = ProcEventInfoBuilder() + .WithTypeMask(typeMask) + .WithHitMask(hitMask) + .WithSpellTypeMask(spellTypeMask) + .WithSpellPhaseMask(spellPhaseMask); + + // For spell-type procs, provide DamageInfo or HealInfo with SpellInfo + if (IsSpellTypeProc(typeMask)) + { + if (spellTypeMask & PROC_SPELL_TYPE_HEAL) + { + if (!_healInfo) + _healInfo = new HealInfo(nullptr, nullptr, 100, _defaultSpellInfo, SPELL_SCHOOL_MASK_HOLY); + builder.WithHealInfo(_healInfo); + } + else + { + if (!_damageInfo) + _damageInfo = new DamageInfo(nullptr, nullptr, 100, _defaultSpellInfo, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + builder.WithDamageInfo(_damageInfo); + } + } + + return builder.Build(); + } + + IWorld* _originalWorld = nullptr; + NiceMock* _worldMock = nullptr; + SpellInfo* _defaultSpellInfo = nullptr; + DamageInfo* _damageInfo = nullptr; + HealInfo* _healInfo = nullptr; + std::vector _allEntries; +}; + +// ============================================================================= +// Comprehensive Tests for All 869 Entries +// ============================================================================= + +TEST_F(SpellProcDatabaseTest, AllEntriesLoaded) +{ + EXPECT_EQ(_allEntries.size(), 869u) << "Should have all 869 spell_proc entries loaded"; +} + +TEST_F(SpellProcDatabaseTest, AllEntriesWithProcFlags_PositiveTest) +{ + int totalTested = 0; + int passed = 0; + int skippedFamily = 0; + int skippedNoFlags = 0; + + for (auto const& entry : _allEntries) + { + // Skip entries with no ProcFlags (they rely on other conditions) + if (entry.ProcFlags == 0) + { + skippedNoFlags++; + continue; + } + + // Skip entries that require SpellFamily matching + if (RequiresSpellFamilyMatch(entry)) + { + skippedFamily++; + continue; + } + + totalTested++; + + ProcFlagScenario const* scenario = FindMatchingScenario(entry.ProcFlags); + if (!scenario) + continue; + + SpellProcEntry procEntry = entry.ToSpellProcEntry(); + + auto eventInfo = CreateEventInfo( + scenario->procFlag, + GetEffectiveHitMask(entry, scenario), + GetEffectiveSpellTypeMask(entry, scenario), + GetEffectiveSpellPhaseMask(entry, scenario)); + + if (sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + { + passed++; + } + } + + // Report statistics + float passRate = totalTested > 0 ? (float)passed / totalTested * 100 : 0; + SCOPED_TRACE("Total entries: " + std::to_string(_allEntries.size())); + SCOPED_TRACE("Tested: " + std::to_string(totalTested)); + SCOPED_TRACE("Passed: " + std::to_string(passed) + " (" + std::to_string((int)passRate) + "%)"); + SCOPED_TRACE("Skipped (SpellFamily): " + std::to_string(skippedFamily)); + SCOPED_TRACE("Skipped (NoFlags): " + std::to_string(skippedNoFlags)); + + // Expect high pass rate for entries we can test + EXPECT_GT(passed, totalTested / 2) << "At least half of tested entries should pass"; +} + +TEST_F(SpellProcDatabaseTest, AllEntriesWithProcFlags_NegativeTest) +{ + int totalTested = 0; + int correctlyRejected = 0; + + for (auto const& entry : _allEntries) + { + if (entry.ProcFlags == 0) + continue; + if (RequiresSpellFamilyMatch(entry)) + continue; + + // Find a flag that's NOT in this entry's ProcFlags + uint32 wrongFlag = 0; + for (auto const& scenario : PROC_FLAG_SCENARIOS) + { + if (!(entry.ProcFlags & scenario.procFlag) && scenario.procFlag != PROC_FLAG_KILL) + { + wrongFlag = scenario.procFlag; + break; + } + } + + if (wrongFlag == 0) + continue; + + totalTested++; + + SpellProcEntry procEntry = entry.ToSpellProcEntry(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(wrongFlag) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + if (!sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + { + correctlyRejected++; + } + } + + float rejectRate = totalTested > 0 ? (float)correctlyRejected / totalTested * 100 : 0; + SCOPED_TRACE("Tested: " + std::to_string(totalTested)); + SCOPED_TRACE("Rejected: " + std::to_string(correctlyRejected) + " (" + std::to_string((int)rejectRate) + "%)"); + + EXPECT_GT(rejectRate, 90.0f) << "Most entries should reject non-matching proc flags"; +} + +// ============================================================================= +// Tests by Proc Flag Type +// ============================================================================= + +TEST_F(SpellProcDatabaseTest, MeleeProcs_AllTriggerOnMelee) +{ + int tested = 0, passed = 0; + + for (auto const& entry : _allEntries) + { + if (!(entry.ProcFlags & PROC_FLAG_DONE_MELEE_AUTO_ATTACK)) + continue; + if (RequiresSpellFamilyMatch(entry)) + continue; + + tested++; + SpellProcEntry procEntry = entry.ToSpellProcEntry(); + + uint32 hitMask = entry.HitMask != 0 ? (entry.HitMask & -entry.HitMask) : PROC_HIT_NORMAL; + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(hitMask) + .Build(); + + if (sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + passed++; + } + + SCOPED_TRACE("Melee procs: " + std::to_string(tested) + " tested, " + std::to_string(passed) + " passed"); + if (tested > 0) + EXPECT_EQ(passed, tested); +} + +TEST_F(SpellProcDatabaseTest, SpellDamageProcs_AllTriggerOnSpellDamage) +{ + int tested = 0, passed = 0; + + for (auto const& entry : _allEntries) + { + if (!(entry.ProcFlags & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + continue; + if (RequiresSpellFamilyMatch(entry)) + continue; + + tested++; + SpellProcEntry procEntry = entry.ToSpellProcEntry(); + + uint32 hitMask = entry.HitMask != 0 ? (entry.HitMask & -entry.HitMask) : PROC_HIT_NORMAL; + uint32 spellTypeMask = entry.SpellTypeMask != 0 ? entry.SpellTypeMask : PROC_SPELL_TYPE_DAMAGE; + uint32 spellPhaseMask = entry.SpellPhaseMask != 0 ? entry.SpellPhaseMask : PROC_SPELL_PHASE_HIT; + + auto eventInfo = CreateEventInfo( + PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, + hitMask, + spellTypeMask, + spellPhaseMask); + + if (sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + passed++; + } + + SCOPED_TRACE("Spell damage procs: " + std::to_string(tested) + " tested, " + std::to_string(passed) + " passed"); + if (tested > 0) + EXPECT_GT(passed, 0); +} + +TEST_F(SpellProcDatabaseTest, HealProcs_AllTriggerOnHeal) +{ + int tested = 0, passed = 0; + + for (auto const& entry : _allEntries) + { + if (!(entry.ProcFlags & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS)) + continue; + if (RequiresSpellFamilyMatch(entry)) + continue; + + tested++; + SpellProcEntry procEntry = entry.ToSpellProcEntry(); + + uint32 hitMask = entry.HitMask != 0 ? (entry.HitMask & -entry.HitMask) : PROC_HIT_NORMAL; + uint32 spellTypeMask = entry.SpellTypeMask != 0 ? entry.SpellTypeMask : PROC_SPELL_TYPE_HEAL; + uint32 spellPhaseMask = entry.SpellPhaseMask != 0 ? entry.SpellPhaseMask : PROC_SPELL_PHASE_HIT; + + auto eventInfo = CreateEventInfo( + PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, + hitMask, + spellTypeMask, + spellPhaseMask); + + if (sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + passed++; + } + + SCOPED_TRACE("Heal procs: " + std::to_string(tested) + " tested, " + std::to_string(passed) + " passed"); + if (tested > 0) + EXPECT_GT(passed, 0); +} + +TEST_F(SpellProcDatabaseTest, PeriodicProcs_AllTriggerOnPeriodic) +{ + int tested = 0, passed = 0; + + for (auto const& entry : _allEntries) + { + if (!(entry.ProcFlags & PROC_FLAG_DONE_PERIODIC)) + continue; + if (RequiresSpellFamilyMatch(entry)) + continue; + + tested++; + SpellProcEntry procEntry = entry.ToSpellProcEntry(); + + uint32 hitMask = entry.HitMask != 0 ? (entry.HitMask & -entry.HitMask) : PROC_HIT_NORMAL; + uint32 spellTypeMask = entry.SpellTypeMask != 0 ? entry.SpellTypeMask : PROC_SPELL_TYPE_DAMAGE; + uint32 spellPhaseMask = entry.SpellPhaseMask != 0 ? entry.SpellPhaseMask : PROC_SPELL_PHASE_HIT; + + auto eventInfo = CreateEventInfo( + PROC_FLAG_DONE_PERIODIC, + hitMask, + spellTypeMask, + spellPhaseMask); + + if (sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + passed++; + } + + SCOPED_TRACE("Periodic procs: " + std::to_string(tested) + " tested, " + std::to_string(passed) + " passed"); + if (tested > 0) + EXPECT_GT(passed, 0); +} + +TEST_F(SpellProcDatabaseTest, KillProcs_AllTriggerOnKill) +{ + int tested = 0, passed = 0; + + for (auto const& entry : _allEntries) + { + if (!(entry.ProcFlags & PROC_FLAG_KILL)) + continue; + + tested++; + SpellProcEntry procEntry = entry.ToSpellProcEntry(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_KILL) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + if (sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + passed++; + } + + SCOPED_TRACE("Kill procs: " + std::to_string(tested) + " tested, " + std::to_string(passed) + " passed"); + // Kill events always proc + EXPECT_EQ(passed, tested); +} + +// ============================================================================= +// Tests by Hit Mask Type +// ============================================================================= + +TEST_F(SpellProcDatabaseTest, CritOnlyProcs_OnlyTriggerOnCrit) +{ + int tested = 0, critPassed = 0, normalRejected = 0; + + for (auto const& entry : _allEntries) + { + // Only entries with EXACTLY crit requirement + if (entry.HitMask != PROC_HIT_CRITICAL) + continue; + if (entry.ProcFlags == 0) + continue; + if (RequiresSpellFamilyMatch(entry)) + continue; + + ProcFlagScenario const* scenario = FindMatchingScenario(entry.ProcFlags); + if (!scenario) + continue; + + tested++; + SpellProcEntry procEntry = entry.ToSpellProcEntry(); + + // Test crit - should pass + auto critEvent = CreateEventInfo( + scenario->procFlag, + PROC_HIT_CRITICAL, + GetEffectiveSpellTypeMask(entry, scenario), + GetEffectiveSpellPhaseMask(entry, scenario)); + + if (sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, critEvent)) + critPassed++; + + // Test normal - should fail + auto normalEvent = CreateEventInfo( + scenario->procFlag, + PROC_HIT_NORMAL, + GetEffectiveSpellTypeMask(entry, scenario), + GetEffectiveSpellPhaseMask(entry, scenario)); + + if (!sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, normalEvent)) + normalRejected++; + } + + SCOPED_TRACE("Crit-only procs: " + std::to_string(tested) + " tested"); + SCOPED_TRACE("Crit passed: " + std::to_string(critPassed)); + SCOPED_TRACE("Normal rejected: " + std::to_string(normalRejected)); + + if (tested > 0) + { + // Most crit-only entries should work, but some may have additional requirements + EXPECT_GT(critPassed, 0) << "At least some crit-only procs should trigger on crits"; + EXPECT_GT(normalRejected, 0) << "At least some crit-only procs should NOT trigger on normal hits"; + } +} + +TEST_F(SpellProcDatabaseTest, DodgeProcs_OnlyTriggerOnDodge) +{ + int tested = 0, passed = 0; + + for (auto const& entry : _allEntries) + { + if (!(entry.HitMask & PROC_HIT_DODGE)) + continue; + if (entry.ProcFlags == 0) + continue; + + ProcFlagScenario const* scenario = FindMatchingScenario(entry.ProcFlags); + if (!scenario) + continue; + + tested++; + SpellProcEntry procEntry = entry.ToSpellProcEntry(); + + auto eventInfo = CreateEventInfo( + scenario->procFlag, + PROC_HIT_DODGE, + GetEffectiveSpellTypeMask(entry, scenario), + GetEffectiveSpellPhaseMask(entry, scenario)); + + if (sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + passed++; + } + + SCOPED_TRACE("Dodge procs: " + std::to_string(tested) + " tested, " + std::to_string(passed) + " passed"); + if (tested > 0) + EXPECT_EQ(passed, tested); +} + +TEST_F(SpellProcDatabaseTest, ParryProcs_OnlyTriggerOnParry) +{ + int tested = 0, passed = 0; + + for (auto const& entry : _allEntries) + { + if (!(entry.HitMask & PROC_HIT_PARRY)) + continue; + if (entry.ProcFlags == 0) + continue; + + ProcFlagScenario const* scenario = FindMatchingScenario(entry.ProcFlags); + if (!scenario) + continue; + + tested++; + SpellProcEntry procEntry = entry.ToSpellProcEntry(); + + auto eventInfo = CreateEventInfo( + scenario->procFlag, + PROC_HIT_PARRY, + GetEffectiveSpellTypeMask(entry, scenario), + GetEffectiveSpellPhaseMask(entry, scenario)); + + if (sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + passed++; + } + + SCOPED_TRACE("Parry procs: " + std::to_string(tested) + " tested, " + std::to_string(passed) + " passed"); + if (tested > 0) + EXPECT_EQ(passed, tested); +} + +TEST_F(SpellProcDatabaseTest, BlockProcs_OnlyTriggerOnBlock) +{ + int tested = 0, passed = 0; + + for (auto const& entry : _allEntries) + { + if (!(entry.HitMask & PROC_HIT_BLOCK)) + continue; + if (entry.ProcFlags == 0) + continue; + + ProcFlagScenario const* scenario = FindMatchingScenario(entry.ProcFlags); + if (!scenario) + continue; + + tested++; + SpellProcEntry procEntry = entry.ToSpellProcEntry(); + + auto eventInfo = CreateEventInfo( + scenario->procFlag, + PROC_HIT_BLOCK, + GetEffectiveSpellTypeMask(entry, scenario), + GetEffectiveSpellPhaseMask(entry, scenario)); + + if (sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + passed++; + } + + SCOPED_TRACE("Block procs: " + std::to_string(tested) + " tested, " + std::to_string(passed) + " passed"); + if (tested > 0) + EXPECT_EQ(passed, tested); +} + +// ============================================================================= +// Tests by Spell Family (Class-Specific) +// ============================================================================= + +TEST_F(SpellProcDatabaseTest, GroupBySpellFamily_Statistics) +{ + std::map familyNames = { + {0, "Generic"}, {3, "Mage"}, {4, "Warrior"}, {5, "Warlock"}, + {6, "Priest"}, {7, "Druid"}, {8, "Rogue"}, {9, "Hunter"}, + {10, "Paladin"}, {11, "Shaman"}, {15, "DeathKnight"} + }; + + std::map familyCounts; + for (auto const& entry : _allEntries) + { + familyCounts[entry.SpellFamilyName]++; + } + + for (auto const& [family, count] : familyCounts) + { + std::string name = familyNames.count(family) ? familyNames[family] : "Unknown(" + std::to_string(family) + ")"; + SCOPED_TRACE("SpellFamily " + name + ": " + std::to_string(count) + " entries"); + } + + EXPECT_GT(familyCounts.size(), 0u); +} + +TEST_F(SpellProcDatabaseTest, GroupByProcFlags_Statistics) +{ + std::map flagCounts; + for (auto const& entry : _allEntries) + { + flagCounts[entry.ProcFlags]++; + } + + SCOPED_TRACE("Unique ProcFlags patterns: " + std::to_string(flagCounts.size())); + EXPECT_GT(flagCounts.size(), 0u); +} + +TEST_F(SpellProcDatabaseTest, GroupByHitMask_Statistics) +{ + std::map hitCounts; + for (auto const& entry : _allEntries) + { + hitCounts[entry.HitMask]++; + } + + SCOPED_TRACE("Unique HitMask patterns: " + std::to_string(hitCounts.size())); + EXPECT_GT(hitCounts.size(), 0u); +} + +// ============================================================================= +// Data Integrity Tests +// ============================================================================= + +TEST_F(SpellProcDatabaseTest, ToSpellProcEntry_ConversionCorrect) +{ + for (auto const& entry : _allEntries) + { + SpellProcEntry converted = entry.ToSpellProcEntry(); + + EXPECT_EQ(converted.SchoolMask, entry.SchoolMask); + EXPECT_EQ(converted.SpellFamilyName, entry.SpellFamilyName); + EXPECT_EQ(converted.SpellFamilyMask[0], entry.SpellFamilyMask0); + EXPECT_EQ(converted.SpellFamilyMask[1], entry.SpellFamilyMask1); + EXPECT_EQ(converted.SpellFamilyMask[2], entry.SpellFamilyMask2); + EXPECT_EQ(converted.ProcFlags, entry.ProcFlags); + EXPECT_EQ(converted.SpellTypeMask, entry.SpellTypeMask); + EXPECT_EQ(converted.SpellPhaseMask, entry.SpellPhaseMask); + EXPECT_EQ(converted.HitMask, entry.HitMask); + EXPECT_EQ(converted.AttributesMask, entry.AttributesMask); + EXPECT_EQ(converted.Cooldown.count(), static_cast(entry.Cooldown)); + EXPECT_FLOAT_EQ(converted.Chance, entry.Chance); + } +} diff --git a/src/test/server/game/Spells/SpellProcDisableEffectsTest.cpp b/src/test/server/game/Spells/SpellProcDisableEffectsTest.cpp new file mode 100644 index 000000000..e61034fcf --- /dev/null +++ b/src/test/server/game/Spells/SpellProcDisableEffectsTest.cpp @@ -0,0 +1,275 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcDisableEffectsTest.cpp + * @brief Unit tests for DisableEffectsMask filtering in proc system + * + * Tests the logic from SpellAuras.cpp:2244-2258: + * - Bitmask filtering for effect indices 0, 1, 2 + * - Combined filtering with multiple disabled effects + * - Proc blocking when all effects are disabled + */ + +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "gtest/gtest.h" + +using namespace testing; + +class SpellProcDisableEffectsTest : public ::testing::Test +{ +protected: + void SetUp() override {} + + // Default initial mask with all 3 effects enabled + static constexpr uint8 ALL_EFFECTS_MASK = 0x07; // 0b111 +}; + +// ============================================================================= +// Single Effect Disable Tests +// ============================================================================= + +TEST_F(SpellProcDisableEffectsTest, DisableEffect0_BlocksOnlyEffect0) +{ + uint32 disableMask = 0x01; // Disable effect 0 + + uint8 result = ProcChanceTestHelper::ApplyDisableEffectsMask(ALL_EFFECTS_MASK, disableMask); + + EXPECT_EQ(result, 0x06) // 0b110 - effects 1 and 2 remain + << "DisableEffectsMask=0x01 should only disable effect 0"; +} + +TEST_F(SpellProcDisableEffectsTest, DisableEffect1_BlocksOnlyEffect1) +{ + uint32 disableMask = 0x02; // Disable effect 1 + + uint8 result = ProcChanceTestHelper::ApplyDisableEffectsMask(ALL_EFFECTS_MASK, disableMask); + + EXPECT_EQ(result, 0x05) // 0b101 - effects 0 and 2 remain + << "DisableEffectsMask=0x02 should only disable effect 1"; +} + +TEST_F(SpellProcDisableEffectsTest, DisableEffect2_BlocksOnlyEffect2) +{ + uint32 disableMask = 0x04; // Disable effect 2 + + uint8 result = ProcChanceTestHelper::ApplyDisableEffectsMask(ALL_EFFECTS_MASK, disableMask); + + EXPECT_EQ(result, 0x03) // 0b011 - effects 0 and 1 remain + << "DisableEffectsMask=0x04 should only disable effect 2"; +} + +// ============================================================================= +// Multiple Effects Disable Tests +// ============================================================================= + +TEST_F(SpellProcDisableEffectsTest, DisableEffects0And1_LeavesEffect2) +{ + uint32 disableMask = 0x03; // Disable effects 0 and 1 + + uint8 result = ProcChanceTestHelper::ApplyDisableEffectsMask(ALL_EFFECTS_MASK, disableMask); + + EXPECT_EQ(result, 0x04) // 0b100 - only effect 2 remains + << "DisableEffectsMask=0x03 should leave only effect 2"; +} + +TEST_F(SpellProcDisableEffectsTest, DisableEffects0And2_LeavesEffect1) +{ + uint32 disableMask = 0x05; // Disable effects 0 and 2 + + uint8 result = ProcChanceTestHelper::ApplyDisableEffectsMask(ALL_EFFECTS_MASK, disableMask); + + EXPECT_EQ(result, 0x02) // 0b010 - only effect 1 remains + << "DisableEffectsMask=0x05 should leave only effect 1"; +} + +TEST_F(SpellProcDisableEffectsTest, DisableEffects1And2_LeavesEffect0) +{ + uint32 disableMask = 0x06; // Disable effects 1 and 2 + + uint8 result = ProcChanceTestHelper::ApplyDisableEffectsMask(ALL_EFFECTS_MASK, disableMask); + + EXPECT_EQ(result, 0x01) // 0b001 - only effect 0 remains + << "DisableEffectsMask=0x06 should leave only effect 0"; +} + +// ============================================================================= +// All Effects Disabled - Proc Blocked +// ============================================================================= + +TEST_F(SpellProcDisableEffectsTest, DisableAllEffects_BlocksProc) +{ + uint32 disableMask = 0x07; // Disable all 3 effects + + uint8 result = ProcChanceTestHelper::ApplyDisableEffectsMask(ALL_EFFECTS_MASK, disableMask); + + EXPECT_EQ(result, 0x00) + << "DisableEffectsMask=0x07 should disable all effects"; + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(ALL_EFFECTS_MASK, disableMask)) + << "Proc should be blocked when all effects are disabled"; +} + +TEST_F(SpellProcDisableEffectsTest, NotAllDisabled_ProcAllowed) +{ + // Only effect 0 disabled + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(ALL_EFFECTS_MASK, 0x01)) + << "Proc should be allowed when some effects remain"; + + // Only effects 0 and 1 disabled + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(ALL_EFFECTS_MASK, 0x03)) + << "Proc should be allowed when effect 2 remains"; + + // No effects disabled + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(ALL_EFFECTS_MASK, 0x00)) + << "Proc should be allowed when no effects are disabled"; +} + +// ============================================================================= +// Partial Initial Mask Tests +// ============================================================================= + +TEST_F(SpellProcDisableEffectsTest, PartialInitialMask_Effect0Only) +{ + uint8 initialMask = 0x01; // Only effect 0 enabled + + // Disabling effect 0 should result in 0 + EXPECT_EQ(ProcChanceTestHelper::ApplyDisableEffectsMask(initialMask, 0x01), 0x00); + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(initialMask, 0x01)); + + // Disabling effect 1 should have no impact + EXPECT_EQ(ProcChanceTestHelper::ApplyDisableEffectsMask(initialMask, 0x02), 0x01); + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(initialMask, 0x02)); +} + +TEST_F(SpellProcDisableEffectsTest, PartialInitialMask_Effects0And1) +{ + uint8 initialMask = 0x03; // Effects 0 and 1 enabled + + // Disabling both should result in 0 + EXPECT_EQ(ProcChanceTestHelper::ApplyDisableEffectsMask(initialMask, 0x03), 0x00); + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(initialMask, 0x03)); + + // Disabling only effect 0 should leave effect 1 + EXPECT_EQ(ProcChanceTestHelper::ApplyDisableEffectsMask(initialMask, 0x01), 0x02); + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(initialMask, 0x01)); +} + +// ============================================================================= +// Zero Disable Mask Tests +// ============================================================================= + +TEST_F(SpellProcDisableEffectsTest, ZeroDisableMask_NoEffectDisabled) +{ + uint32 disableMask = 0x00; // Nothing disabled + + uint8 result = ProcChanceTestHelper::ApplyDisableEffectsMask(ALL_EFFECTS_MASK, disableMask); + + EXPECT_EQ(result, ALL_EFFECTS_MASK) + << "Zero DisableEffectsMask should leave all effects enabled"; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(ALL_EFFECTS_MASK, disableMask)) + << "Proc should be allowed when nothing is disabled"; +} + +// ============================================================================= +// Higher Bits Ignored Tests +// ============================================================================= + +TEST_F(SpellProcDisableEffectsTest, HigherBits_IgnoredForEffects) +{ + // Bits beyond 0x07 should be ignored (only 3 effects exist) + uint32 disableMask = 0xFF; // All bits set + + uint8 result = ProcChanceTestHelper::ApplyDisableEffectsMask(ALL_EFFECTS_MASK, disableMask); + + EXPECT_EQ(result, 0x00) + << "Only lower 3 bits should affect the result"; + + // Only lower bits matter + uint32 highBitsOnly = 0xF8; // High bits only + result = ProcChanceTestHelper::ApplyDisableEffectsMask(ALL_EFFECTS_MASK, highBitsOnly); + + EXPECT_EQ(result, ALL_EFFECTS_MASK) + << "High bits (0xF8) should not affect lower 3 effects"; +} + +// ============================================================================= +// Integration with SpellProcEntry Tests +// ============================================================================= + +TEST_F(SpellProcDisableEffectsTest, SpellProcEntry_WithDisableEffectsMask) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithDisableEffectsMask(0x05) // Disable effects 0 and 2 + .WithChance(100.0f) + .Build(); + + // Verify the mask was set correctly + EXPECT_EQ(procEntry.DisableEffectsMask, 0x05u); + + // Apply to initial mask + uint8 result = ProcChanceTestHelper::ApplyDisableEffectsMask(ALL_EFFECTS_MASK, procEntry.DisableEffectsMask); + + EXPECT_EQ(result, 0x02) // Only effect 1 remains + << "SpellProcEntry DisableEffectsMask should filter correctly"; +} + +TEST_F(SpellProcDisableEffectsTest, SpellProcEntry_AllDisabled) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithDisableEffectsMask(0x07) // Disable all effects + .WithChance(100.0f) + .Build(); + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(ALL_EFFECTS_MASK, procEntry.DisableEffectsMask)) + << "Proc should be blocked when all effects disabled in SpellProcEntry"; +} + +// ============================================================================= +// Real Spell Scenarios +// ============================================================================= + +TEST_F(SpellProcDisableEffectsTest, Scenario_SingleEffectAura) +{ + // Many procs only have a single effect that matters + uint8 singleEffectMask = 0x01; // Only effect 0 + + // Disabling effect 0 blocks the proc + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(singleEffectMask, 0x01)); + + // Disabling other effects has no impact + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(singleEffectMask, 0x02)); + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(singleEffectMask, 0x04)); + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(singleEffectMask, 0x06)); +} + +TEST_F(SpellProcDisableEffectsTest, Scenario_DualEffectAura) +{ + // Aura with effects 0 and 1 (healing + damage proc for example) + uint8 dualEffectMask = 0x03; + + // Disabling one effect leaves the other + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(dualEffectMask, 0x01)); + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(dualEffectMask, 0x02)); + + // Disabling both blocks the proc + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToDisabledEffects(dualEffectMask, 0x03)); +} diff --git a/src/test/server/game/Spells/SpellProcEquipmentTest.cpp b/src/test/server/game/Spells/SpellProcEquipmentTest.cpp new file mode 100644 index 000000000..addd8a492 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcEquipmentTest.cpp @@ -0,0 +1,404 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcEquipmentTest.cpp + * @brief Unit tests for equipment requirement validation in proc system + * + * Tests the logic from SpellAuras.cpp:2260-2298: + * - Weapon class requirement validation + * - Armor class requirement validation + * - Attack type to slot mapping + * - Feral form blocking weapon procs + * - Broken item blocking procs + * - SPELL_ATTR3_NO_PROC_EQUIP_REQUIREMENT bypass + * - Item subclass mask validation + * + * ============================================================================ + * TEST DESIGN: Configuration-Based Testing + * ============================================================================ + * + * These tests use EquipmentConfig structs to simulate different equipment + * scenarios without requiring actual game objects. Each test configures: + * - isPassive: Whether the aura is passive (equipment check only applies to passive) + * - isPlayer: Whether the target is a player (NPCs skip equipment checks) + * - equippedItemClass: ITEM_CLASS_WEAPON, ITEM_CLASS_ARMOR, or ITEM_CLASS_ANY + * - hasEquippedItem: Whether the required item slot has an item + * - itemIsBroken: Whether the equipped item is broken (0 durability) + * - itemFitsRequirements: Whether the item matches subclass mask requirements + * - isInFeralForm: Whether a druid is in cat/bear form (blocks weapon procs) + * - hasNoEquipRequirementAttr: SPELL_ATTR3_NO_PROC_EQUIP_REQUIREMENT bypass + * + * No GTEST_SKIP() is used in this file - all tests run with their configured + * scenarios, testing both positive and negative cases explicitly. + * ============================================================================ + */ + +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "gtest/gtest.h" + +using namespace testing; + +class SpellProcEquipmentTest : public ::testing::Test +{ +protected: + void SetUp() override {} + + // Create default config for weapon proc + ProcChanceTestHelper::EquipmentConfig CreateWeaponProcConfig() + { + ProcChanceTestHelper::EquipmentConfig config; + config.isPassive = true; + config.isPlayer = true; + config.equippedItemClass = ProcChanceTestHelper::ITEM_CLASS_WEAPON; + config.hasEquippedItem = true; + config.itemIsBroken = false; + config.itemFitsRequirements = true; + return config; + } + + // Create default config for armor proc + ProcChanceTestHelper::EquipmentConfig CreateArmorProcConfig() + { + ProcChanceTestHelper::EquipmentConfig config; + config.isPassive = true; + config.isPlayer = true; + config.equippedItemClass = ProcChanceTestHelper::ITEM_CLASS_ARMOR; + config.hasEquippedItem = true; + config.itemIsBroken = false; + config.itemFitsRequirements = true; + return config; + } +}; + +// ============================================================================= +// No Equipment Requirement Tests +// ============================================================================= + +TEST_F(SpellProcEquipmentTest, NoEquipRequirement_AllowsProc) +{ + ProcChanceTestHelper::EquipmentConfig config; + config.isPassive = true; + config.isPlayer = true; + config.equippedItemClass = ProcChanceTestHelper::ITEM_CLASS_ANY; // No requirement + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "No equipment requirement should allow proc"; +} + +TEST_F(SpellProcEquipmentTest, NonPassiveAura_SkipsCheck) +{ + ProcChanceTestHelper::EquipmentConfig config; + config.isPassive = false; // Not a passive aura + config.isPlayer = true; + config.equippedItemClass = ProcChanceTestHelper::ITEM_CLASS_WEAPON; + config.hasEquippedItem = false; // Would normally block + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Non-passive aura should skip equipment check"; +} + +TEST_F(SpellProcEquipmentTest, NonPlayerTarget_SkipsCheck) +{ + ProcChanceTestHelper::EquipmentConfig config; + config.isPassive = true; + config.isPlayer = false; // NPC/creature + config.equippedItemClass = ProcChanceTestHelper::ITEM_CLASS_WEAPON; + config.hasEquippedItem = false; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Non-player target should skip equipment check"; +} + +// ============================================================================= +// Weapon Class Requirement Tests +// ============================================================================= + +TEST_F(SpellProcEquipmentTest, WeaponRequired_WithWeapon_AllowsProc) +{ + auto config = CreateWeaponProcConfig(); + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Weapon requirement met should allow proc"; +} + +TEST_F(SpellProcEquipmentTest, WeaponRequired_NoWeapon_BlocksProc) +{ + auto config = CreateWeaponProcConfig(); + config.hasEquippedItem = false; // No weapon equipped + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Missing weapon should block proc"; +} + +TEST_F(SpellProcEquipmentTest, WeaponRequired_BrokenWeapon_BlocksProc) +{ + auto config = CreateWeaponProcConfig(); + config.itemIsBroken = true; // Weapon is broken + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Broken weapon should block proc"; +} + +TEST_F(SpellProcEquipmentTest, WeaponRequired_WrongSubclass_BlocksProc) +{ + auto config = CreateWeaponProcConfig(); + config.itemFitsRequirements = false; // Wrong weapon type + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Wrong weapon subclass should block proc"; +} + +// ============================================================================= +// Armor Class Requirement Tests +// ============================================================================= + +TEST_F(SpellProcEquipmentTest, ArmorRequired_WithArmor_AllowsProc) +{ + auto config = CreateArmorProcConfig(); + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Armor requirement met should allow proc"; +} + +TEST_F(SpellProcEquipmentTest, ArmorRequired_NoArmor_BlocksProc) +{ + auto config = CreateArmorProcConfig(); + config.hasEquippedItem = false; + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Missing armor should block proc"; +} + +TEST_F(SpellProcEquipmentTest, ArmorRequired_BrokenArmor_BlocksProc) +{ + auto config = CreateArmorProcConfig(); + config.itemIsBroken = true; + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Broken armor should block proc"; +} + +// ============================================================================= +// Feral Form Tests - SpellAuras.cpp:2266-2267 +// ============================================================================= + +TEST_F(SpellProcEquipmentTest, FeralForm_WeaponProc_BlocksProc) +{ + auto config = CreateWeaponProcConfig(); + config.isInFeralForm = true; // Druid in cat/bear form + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Feral form should block weapon procs"; +} + +TEST_F(SpellProcEquipmentTest, FeralForm_ArmorProc_AllowsProc) +{ + auto config = CreateArmorProcConfig(); + config.isInFeralForm = true; // Druid in cat/bear form + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Feral form should NOT block armor procs"; +} + +TEST_F(SpellProcEquipmentTest, NotInFeralForm_WeaponProc_AllowsProc) +{ + auto config = CreateWeaponProcConfig(); + config.isInFeralForm = false; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Non-feral form should allow weapon procs"; +} + +// ============================================================================= +// SPELL_ATTR3_NO_PROC_EQUIP_REQUIREMENT Bypass Tests +// ============================================================================= + +TEST_F(SpellProcEquipmentTest, NoEquipRequirementAttr_BypassesMissingItem) +{ + auto config = CreateWeaponProcConfig(); + config.hasEquippedItem = false; // Would normally block + config.hasNoEquipRequirementAttr = true; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "NO_PROC_EQUIP_REQUIREMENT should bypass missing item check"; +} + +TEST_F(SpellProcEquipmentTest, NoEquipRequirementAttr_BypassesBrokenItem) +{ + auto config = CreateWeaponProcConfig(); + config.itemIsBroken = true; // Would normally block + config.hasNoEquipRequirementAttr = true; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "NO_PROC_EQUIP_REQUIREMENT should bypass broken item check"; +} + +TEST_F(SpellProcEquipmentTest, NoEquipRequirementAttr_BypassesFeralForm) +{ + auto config = CreateWeaponProcConfig(); + config.isInFeralForm = true; // Would normally block + config.hasNoEquipRequirementAttr = true; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "NO_PROC_EQUIP_REQUIREMENT should bypass feral form check"; +} + +// ============================================================================= +// Attack Type to Slot Mapping Tests - SpellAuras.cpp:2268-2284 +// ============================================================================= + +TEST_F(SpellProcEquipmentTest, SlotMapping_BaseAttack_MainHand) +{ + uint8 slot = ProcChanceTestHelper::GetWeaponSlotForAttackType(ProcChanceTestHelper::BASE_ATTACK); + EXPECT_EQ(slot, 15) // EQUIPMENT_SLOT_MAINHAND + << "BASE_ATTACK should map to main hand slot"; +} + +TEST_F(SpellProcEquipmentTest, SlotMapping_OffAttack_OffHand) +{ + uint8 slot = ProcChanceTestHelper::GetWeaponSlotForAttackType(ProcChanceTestHelper::OFF_ATTACK); + EXPECT_EQ(slot, 16) // EQUIPMENT_SLOT_OFFHAND + << "OFF_ATTACK should map to off hand slot"; +} + +TEST_F(SpellProcEquipmentTest, SlotMapping_RangedAttack_Ranged) +{ + uint8 slot = ProcChanceTestHelper::GetWeaponSlotForAttackType(ProcChanceTestHelper::RANGED_ATTACK); + EXPECT_EQ(slot, 17) // EQUIPMENT_SLOT_RANGED + << "RANGED_ATTACK should map to ranged slot"; +} + +TEST_F(SpellProcEquipmentTest, SlotMapping_InvalidAttack_DefaultsToMainHand) +{ + uint8 slot = ProcChanceTestHelper::GetWeaponSlotForAttackType(255); // Invalid + EXPECT_EQ(slot, 15) // EQUIPMENT_SLOT_MAINHAND + << "Invalid attack type should default to main hand"; +} + +// ============================================================================= +// Real Spell Scenarios +// ============================================================================= + +TEST_F(SpellProcEquipmentTest, Scenario_WeaponEnchant_Fiery) +{ + // Fiery Weapon enchant - requires melee weapon + auto config = CreateWeaponProcConfig(); + config.attackType = ProcChanceTestHelper::BASE_ATTACK; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Fiery Weapon with main hand should proc"; +} + +TEST_F(SpellProcEquipmentTest, Scenario_WeaponEnchant_FieryOffhand) +{ + // Fiery Weapon on off-hand + auto config = CreateWeaponProcConfig(); + config.attackType = ProcChanceTestHelper::OFF_ATTACK; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Fiery Weapon with off hand should proc"; +} + +TEST_F(SpellProcEquipmentTest, Scenario_Hunter_RangedProc) +{ + // Hunter ranged weapon proc + auto config = CreateWeaponProcConfig(); + config.attackType = ProcChanceTestHelper::RANGED_ATTACK; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Ranged proc with ranged weapon should work"; +} + +TEST_F(SpellProcEquipmentTest, Scenario_FeralDruid_WeaponEnchant) +{ + // Druid with weapon enchant enters cat form + auto config = CreateWeaponProcConfig(); + config.isInFeralForm = true; + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Feral druid weapon enchant should be blocked"; +} + +TEST_F(SpellProcEquipmentTest, Scenario_BrokenWeapon_CombatUse) +{ + // Player's weapon breaks during combat + auto config = CreateWeaponProcConfig(); + config.itemIsBroken = true; + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Broken weapon procs should be blocked"; +} + +TEST_F(SpellProcEquipmentTest, Scenario_WrongWeaponType) +{ + // Enchant requires sword but player has mace + auto config = CreateWeaponProcConfig(); + config.itemFitsRequirements = false; + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Wrong weapon type should block proc"; +} + +// ============================================================================= +// Edge Cases +// ============================================================================= + +TEST_F(SpellProcEquipmentTest, EdgeCase_AllConditionsMet) +{ + auto config = CreateWeaponProcConfig(); + // All requirements met + config.isPassive = true; + config.isPlayer = true; + config.hasEquippedItem = true; + config.itemIsBroken = false; + config.itemFitsRequirements = true; + config.isInFeralForm = false; + config.hasNoEquipRequirementAttr = false; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "All conditions met should allow proc"; +} + +TEST_F(SpellProcEquipmentTest, EdgeCase_AllBlockingConditions) +{ + auto config = CreateWeaponProcConfig(); + // Multiple blocking conditions + config.hasEquippedItem = false; + config.itemIsBroken = true; + config.itemFitsRequirements = false; + config.isInFeralForm = true; + + // Should be blocked (first check that fails) + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Multiple blocking conditions should still block"; +} + +TEST_F(SpellProcEquipmentTest, EdgeCase_BypassOverridesAll) +{ + auto config = CreateWeaponProcConfig(); + // Multiple blocking conditions BUT bypass is set + config.hasEquippedItem = false; + config.itemIsBroken = true; + config.itemFitsRequirements = false; + config.isInFeralForm = true; + config.hasNoEquipRequirementAttr = true; // Bypass + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockDueToEquipment(config)) + << "Bypass attribute should override all blocking conditions"; +} diff --git a/src/test/server/game/Spells/SpellProcFullCoverageTest.cpp b/src/test/server/game/Spells/SpellProcFullCoverageTest.cpp new file mode 100644 index 000000000..f4a46d59f --- /dev/null +++ b/src/test/server/game/Spells/SpellProcFullCoverageTest.cpp @@ -0,0 +1,458 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcFullCoverageTest.cpp + * @brief Data-driven tests for ALL 869 spell_proc entries + * + * Tests proc calculations for every spell_proc entry: + * - Cooldown blocking behavior + * - Chance calculation with level reduction + * - Attribute flag validation + * + * This complements SpellProcDataDrivenTest.cpp which tests CanSpellTriggerProcOnEvent(). + * + * ============================================================================ + * DESIGN NOTE: Why Tests Skip Certain Entries + * ============================================================================ + * + * This test file uses parameterized tests that run against ALL 869 spell_proc + * entries. Each test validates a specific feature (cooldowns, level reduction, + * attribute flags, etc.). Tests use GTEST_SKIP() for entries that don't have + * the feature being tested. + * + * For example (current counts from test output): + * - CooldownBlocking_WhenCooldownSet: Tests 246 entries with Cooldown > 0 (skips 623) + * - Level60Reduction_WhenAttributeSet: Tests entries with PROC_ATTR_REDUCE_PROC_60 (0 currently) + * - UseStacksForCharges_Behavior: Tests entries with PROC_ATTR_USE_STACKS_FOR_CHARGES (0 currently) + * - TriggeredCanProc_FlagSet: Tests 73 entries with PROC_ATTR_TRIGGERED_CAN_PROC (skips 796) + * - ReqManaCost_FlagSet: Tests 5 entries with PROC_ATTR_REQ_MANA_COST (skips 864) + * + * This is INTENTIONAL. Running parameterized tests against all entries ensures: + * 1. Every entry is validated for applicable features + * 2. Statistics show exact coverage (X entries with feature Y) + * 3. New entries added to spell_proc are automatically tested + * 4. Regression detection if an entry unexpectedly gains/loses a feature + * + * The statistics tests at the bottom output the exact counts: + * "[ INFO ] Entries with cooldown: 85 / 869" + * "[ INFO ] Entries with REDUCE_PROC_60: 15 / 869" + * etc. + * + * SKIPPED tests are expected and correct. Each skip message includes: + * - The SpellId being skipped + * - The reason (e.g., "has no cooldown", "doesn't have REDUCE_PROC_60") + * ============================================================================ + */ + +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "SpellProcTestData.h" +#include "AuraStub.h" +#include "gtest/gtest.h" + +using namespace testing; +using namespace std::chrono_literals; + +// ============================================================================= +// Parameterized Test Fixture for ALL Entries +// ============================================================================= + +class SpellProcFullCoverageTest : public ::testing::TestWithParam +{ +protected: + void SetUp() override + { + _entry = GetParam(); + _procEntry = _entry.ToSpellProcEntry(); + } + + SpellProcTestEntry _entry; + SpellProcEntry _procEntry; +}; + +// ============================================================================= +// Cooldown Tests - ALL entries with Cooldown > 0 +// 246 of 869 entries have cooldowns (Internal Cooldowns / ICDs) +// ============================================================================= + +TEST_P(SpellProcFullCoverageTest, CooldownBlocking_WhenCooldownSet) +{ + // SKIP REASON: This test validates cooldown blocking behavior. + // Only entries with Cooldown > 0 can be tested for ICD (Internal Cooldown). + // Entries without cooldowns proc on every valid trigger, so there's nothing + // to test here. The skip count shows how many entries lack cooldowns. + if (_entry.Cooldown == 0) + GTEST_SKIP() << "SpellId " << _entry.SpellId << " has no cooldown"; + + ProcTestScenario scenario; + scenario.WithAura(std::abs(_entry.SpellId)); + + // Set 100% chance to isolate cooldown testing + SpellProcEntry testEntry = _procEntry; + testEntry.Chance = 100.0f; + testEntry.Cooldown = Milliseconds(_entry.Cooldown); + + // First proc should succeed + EXPECT_TRUE(scenario.SimulateProc(testEntry)) + << "SpellId " << _entry.SpellId << " first proc should succeed"; + + // Second proc immediately after should fail (on cooldown) + EXPECT_FALSE(scenario.SimulateProc(testEntry)) + << "SpellId " << _entry.SpellId << " should be blocked during " + << _entry.Cooldown << "ms cooldown"; + + // Wait for cooldown to expire + scenario.AdvanceTime(std::chrono::milliseconds(_entry.Cooldown + 1)); + + // Third proc after cooldown should succeed + EXPECT_TRUE(scenario.SimulateProc(testEntry)) + << "SpellId " << _entry.SpellId << " should proc after cooldown expires"; +} + +// ============================================================================= +// Level 60+ Reduction Tests - ALL entries with PROC_ATTR_REDUCE_PROC_60 +// Currently 0 of 869 entries use this attribute (data may need population). +// This attribute reduces proc chance by 3.333% per level above 60. +// ============================================================================= + +TEST_P(SpellProcFullCoverageTest, Level60Reduction_WhenAttributeSet) +{ + // SKIP REASON: This test validates the level 60+ proc chance reduction formula. + // Only entries with PROC_ATTR_REDUCE_PROC_60 attribute have their proc chance + // reduced at higher levels. Spells like old weapon procs (Fiery, Crusader) + // use this to prevent them from being overpowered at level 80. + // Entries without this attribute maintain constant proc chance at all levels. + if (!(_entry.AttributesMask & PROC_ATTR_REDUCE_PROC_60)) + GTEST_SKIP() << "SpellId " << _entry.SpellId << " doesn't have REDUCE_PROC_60"; + + // Use a meaningful base chance for testing + float baseChance = _entry.Chance > 0 ? _entry.Chance : 30.0f; + + // Level 60: No reduction + float chanceAt60 = ProcChanceTestHelper::ApplyLevel60Reduction(baseChance, 60); + EXPECT_NEAR(chanceAt60, baseChance, 0.01f) + << "SpellId " << _entry.SpellId << " should have no reduction at level 60"; + + // Level 70: 33.33% reduction + float chanceAt70 = ProcChanceTestHelper::ApplyLevel60Reduction(baseChance, 70); + float expectedAt70 = baseChance * (1.0f - 10.0f/30.0f); + EXPECT_NEAR(chanceAt70, expectedAt70, 0.5f) + << "SpellId " << _entry.SpellId << " should have 33% reduction at level 70"; + + // Level 80: 66.67% reduction + float chanceAt80 = ProcChanceTestHelper::ApplyLevel60Reduction(baseChance, 80); + float expectedAt80 = baseChance * (1.0f - 20.0f/30.0f); + EXPECT_NEAR(chanceAt80, expectedAt80, 0.5f) + << "SpellId " << _entry.SpellId << " should have 66% reduction at level 80"; + + // Verify reduction is correct + EXPECT_LT(chanceAt80, chanceAt70) + << "SpellId " << _entry.SpellId << " chance at 80 should be less than at 70"; + EXPECT_LT(chanceAt70, chanceAt60) + << "SpellId " << _entry.SpellId << " chance at 70 should be less than at 60"; +} + +// ============================================================================= +// Attribute Validation Tests - ALL entries +// ============================================================================= + +TEST_P(SpellProcFullCoverageTest, AttributeMask_ValidFlags) +{ + // Valid attribute flags + constexpr uint32 VALID_ATTRIBUTE_MASK = + PROC_ATTR_REQ_EXP_OR_HONOR | + PROC_ATTR_TRIGGERED_CAN_PROC | + PROC_ATTR_REQ_MANA_COST | + PROC_ATTR_REQ_SPELLMOD | + PROC_ATTR_USE_STACKS_FOR_CHARGES | + PROC_ATTR_REDUCE_PROC_60 | + PROC_ATTR_CANT_PROC_FROM_ITEM_CAST; + + // Check for invalid bits (skip 0x20 and 0x40 which are unused/reserved) + uint32 invalidBits = _entry.AttributesMask & ~VALID_ATTRIBUTE_MASK & ~0x60; + EXPECT_EQ(invalidBits, 0u) + << "SpellId " << _entry.SpellId << " has invalid attribute bits: 0x" + << std::hex << invalidBits; +} + +TEST_P(SpellProcFullCoverageTest, UseStacksForCharges_Behavior) +{ + // SKIP REASON: This test validates stack consumption instead of charge consumption. + // Currently 0 entries use PROC_ATTR_USE_STACKS_FOR_CHARGES (attribute data may + // need population). When set, this causes procs to decrement the aura's stack + // count rather than its charge count. + // Example: Druid's Eclipse - each proc reduces stacks until buff expires. + // Most proc auras use charges (consumed individually) not stacks. + if (!(_entry.AttributesMask & PROC_ATTR_USE_STACKS_FOR_CHARGES)) + GTEST_SKIP() << "SpellId " << _entry.SpellId << " doesn't use stacks for charges"; + + auto aura = AuraStubBuilder() + .WithId(std::abs(_entry.SpellId)) + .WithStackAmount(5) + .Build(); + + SpellProcEntry testEntry = _procEntry; + testEntry.Chance = 100.0f; + + // Consume should decrement stacks + bool removed = ProcChanceTestHelper::SimulateConsumeProcCharges(aura.get(), testEntry); + + EXPECT_EQ(aura->GetStackAmount(), 4) + << "SpellId " << _entry.SpellId << " should decrement stacks"; + EXPECT_FALSE(removed); +} + +TEST_P(SpellProcFullCoverageTest, TriggeredCanProc_FlagSet) +{ + // SKIP REASON: This test validates the PROC_ATTR_TRIGGERED_CAN_PROC attribute. + // Most proc auras (796 entries) do NOT allow triggered spells to trigger them, + // preventing infinite proc chains. Only 73 entries explicitly allow triggered + // spells to proc (e.g., some talent effects that should chain-react). + // Entries without this flag block triggered spell procs for safety. + if (!(_entry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC)) + GTEST_SKIP() << "SpellId " << _entry.SpellId << " doesn't have TRIGGERED_CAN_PROC"; + + // Just verify the flag is properly set in the entry + EXPECT_TRUE(_procEntry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC) + << "SpellId " << _entry.SpellId << " TRIGGERED_CAN_PROC should be set"; +} + +TEST_P(SpellProcFullCoverageTest, ReqManaCost_FlagSet) +{ + // SKIP REASON: This test validates the PROC_ATTR_REQ_MANA_COST attribute. + // Only 5 entries require the triggering spell to have a mana cost. + // This prevents free spells (instant casts with no cost) from triggering procs. + // Example: Illumination should only proc from actual heals, not free procs. + // 864 entries don't care about mana cost, so this test is skipped for them. + if (!(_entry.AttributesMask & PROC_ATTR_REQ_MANA_COST)) + GTEST_SKIP() << "SpellId " << _entry.SpellId << " doesn't have REQ_MANA_COST"; + + // Just verify the flag is properly set in the entry + EXPECT_TRUE(_procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST) + << "SpellId " << _entry.SpellId << " REQ_MANA_COST should be set"; +} + +// ============================================================================= +// Chance Calculation Tests - ALL entries with Chance > 0 +// ============================================================================= + +TEST_P(SpellProcFullCoverageTest, ChanceValue_InValidRange) +{ + // Chance should be in valid range (0-100 normally, but some can exceed) + // Just verify it's not negative + EXPECT_GE(_entry.Chance, 0.0f) + << "SpellId " << _entry.SpellId << " has negative chance"; + + // And not absurdly high (>500% would be suspicious) + EXPECT_LE(_entry.Chance, 500.0f) + << "SpellId " << _entry.SpellId << " has suspiciously high chance"; +} + +TEST_P(SpellProcFullCoverageTest, ChanceCalculation_WithEntry) +{ + // SKIP REASON: This test validates proc chance calculation with level reduction. + // Entries with Chance = 0 rely on DBC defaults or use PPM (procs per minute) instead. + // We can only test explicit chance calculation for entries that define a Chance value. + // PPM-based procs are tested separately in SpellProcPPMTest.cpp. + if (_entry.Chance <= 0.0f) + GTEST_SKIP() << "SpellId " << _entry.SpellId << " has no base chance"; + + // Calculate chance at level 80 (typical max level) + float calculatedChance = ProcChanceTestHelper::SimulateCalcProcChance( + _procEntry, 80, 2500, 0.0f, 0.0f, false); + + if (_entry.AttributesMask & PROC_ATTR_REDUCE_PROC_60) + { + // With level 60+ reduction at level 80 + float expectedReduced = _entry.Chance * (1.0f - 20.0f/30.0f); + EXPECT_NEAR(calculatedChance, expectedReduced, 0.5f) + << "SpellId " << _entry.SpellId << " reduced chance mismatch"; + } + else + { + // Without reduction + EXPECT_NEAR(calculatedChance, _entry.Chance, 0.01f) + << "SpellId " << _entry.SpellId << " base chance mismatch"; + } +} + +// ============================================================================= +// ProcFlags Validation Tests - ALL entries +// ============================================================================= + +TEST_P(SpellProcFullCoverageTest, ProcFlags_NotEmpty) +{ + // Most entries should have proc flags OR spell family filters + // Skip validation if both are zero (some entries use only SchoolMask) + if (_entry.ProcFlags == 0 && _entry.SpellFamilyName == 0 && _entry.SchoolMask == 0) + { + // This is a potential configuration issue, but not necessarily an error + // Some entries are passive effects that don't proc from events + } + + // Just verify ProcFlags is valid (no invalid bits) + // All valid proc flags are defined in SpellMgr.h + // This is a basic sanity check +} + +// ============================================================================= +// Cooldown Value Validation Tests - ALL entries with cooldown +// ============================================================================= + +TEST_P(SpellProcFullCoverageTest, CooldownValue_Reasonable) +{ + // SKIP REASON: This test validates cooldown values are within reasonable bounds. + // Entries without cooldowns (Cooldown = 0) can proc on every trigger with no + // internal cooldown. 623 entries have no ICD and this is intentional - they + // rely on proc chance alone to limit frequency. + // Only 246 entries with explicit cooldowns need range validation. + if (_entry.Cooldown == 0) + GTEST_SKIP() << "SpellId " << _entry.SpellId << " has no cooldown"; + + // Cooldowns should be reasonable (not too short, not too long) + // Shortest reasonable cooldown is ~1ms + // Longest reasonable cooldown is ~15 minutes (900000ms) - some trinkets have 10+ min ICDs + EXPECT_GE(_entry.Cooldown, 1u) + << "SpellId " << _entry.SpellId << " has suspiciously short cooldown"; + EXPECT_LE(_entry.Cooldown, 900000u) + << "SpellId " << _entry.SpellId << " has suspiciously long cooldown (" + << _entry.Cooldown << "ms = " << _entry.Cooldown/60000 << " minutes)"; +} + +// ============================================================================= +// SpellId Validation Tests - ALL entries +// ============================================================================= + +TEST_P(SpellProcFullCoverageTest, SpellId_NonZero) +{ + // SpellId should never be zero + EXPECT_NE(_entry.SpellId, 0) + << "Entry has zero SpellId which is invalid"; +} + +// ============================================================================= +// Test Instantiation - ALL 869 entries +// ============================================================================= + +INSTANTIATE_TEST_SUITE_P( + AllSpellProcEntries, + SpellProcFullCoverageTest, + ::testing::ValuesIn(GetAllSpellProcTestEntries()), + [](const ::testing::TestParamInfo& info) { + // Generate unique test name from spell ID + int32_t id = info.param.SpellId; + if (id < 0) + return "NegId_" + std::to_string(-id); + return "SpellId_" + std::to_string(id); + } +); + +// ============================================================================= +// Statistics Tests - Run once to summarize coverage +// ============================================================================= + +class SpellProcCoverageStatsTest : public ::testing::Test +{ +protected: + void SetUp() override + { + _allEntries = GetAllSpellProcTestEntries(); + } + + std::vector _allEntries; +}; + +TEST_F(SpellProcCoverageStatsTest, CountEntriesWithCooldown) +{ + size_t withCooldown = 0; + for (auto const& entry : _allEntries) + { + if (entry.Cooldown > 0) + ++withCooldown; + } + std::cout << "[ INFO ] Entries with cooldown: " << withCooldown + << " / " << _allEntries.size() << std::endl; + EXPECT_GT(withCooldown, 0u); +} + +TEST_F(SpellProcCoverageStatsTest, CountEntriesWithChance) +{ + size_t withChance = 0; + for (auto const& entry : _allEntries) + { + if (entry.Chance > 0.0f) + ++withChance; + } + std::cout << "[ INFO ] Entries with chance > 0: " << withChance + << " / " << _allEntries.size() << std::endl; +} + +TEST_F(SpellProcCoverageStatsTest, CountEntriesWithLevel60Reduction) +{ + size_t withReduction = 0; + for (auto const& entry : _allEntries) + { + if (entry.AttributesMask & PROC_ATTR_REDUCE_PROC_60) + ++withReduction; + } + std::cout << "[ INFO ] Entries with REDUCE_PROC_60: " << withReduction + << " / " << _allEntries.size() << std::endl; +} + +TEST_F(SpellProcCoverageStatsTest, CountEntriesWithUseStacks) +{ + size_t withUseStacks = 0; + for (auto const& entry : _allEntries) + { + if (entry.AttributesMask & PROC_ATTR_USE_STACKS_FOR_CHARGES) + ++withUseStacks; + } + std::cout << "[ INFO ] Entries with USE_STACKS_FOR_CHARGES: " << withUseStacks + << " / " << _allEntries.size() << std::endl; +} + +TEST_F(SpellProcCoverageStatsTest, CountEntriesWithTriggeredCanProc) +{ + size_t withTriggered = 0; + for (auto const& entry : _allEntries) + { + if (entry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC) + ++withTriggered; + } + std::cout << "[ INFO ] Entries with TRIGGERED_CAN_PROC: " << withTriggered + << " / " << _allEntries.size() << std::endl; +} + +TEST_F(SpellProcCoverageStatsTest, CountEntriesWithReqManaCost) +{ + size_t withReqManaCost = 0; + for (auto const& entry : _allEntries) + { + if (entry.AttributesMask & PROC_ATTR_REQ_MANA_COST) + ++withReqManaCost; + } + std::cout << "[ INFO ] Entries with REQ_MANA_COST: " << withReqManaCost + << " / " << _allEntries.size() << std::endl; +} + +TEST_F(SpellProcCoverageStatsTest, TotalEntryCount) +{ + std::cout << "[ INFO ] Total spell_proc entries tested: " << _allEntries.size() << std::endl; + EXPECT_EQ(_allEntries.size(), 869u) + << "Expected 869 entries but got " << _allEntries.size(); +} diff --git a/src/test/server/game/Spells/SpellProcIntegrationTest.cpp b/src/test/server/game/Spells/SpellProcIntegrationTest.cpp new file mode 100644 index 000000000..11aeeba67 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcIntegrationTest.cpp @@ -0,0 +1,565 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "AuraScriptTestFramework.h" +#include "SpellMgr.h" +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +using namespace testing; + +/** + * @brief Integration tests for the proc system + * + * These tests verify that the proc system correctly integrates: + * - SpellProcEntry configuration + * - CanSpellTriggerProcOnEvent logic + * - Proc flag combinations + * - Spell family matching + * - Hit mask filtering + */ +class SpellProcIntegrationTest : public AuraScriptProcTestFixture +{ +protected: + void SetUp() override + { + AuraScriptProcTestFixture::SetUp(); + } +}; + +// ============================================================================= +// Melee Attack Proc Tests +// ============================================================================= + +TEST_F(SpellProcIntegrationTest, MeleeAutoAttackProc_NormalHit) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL | PROC_HIT_CRITICAL) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnMeleeAutoAttack() + .WithNormalHit(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +TEST_F(SpellProcIntegrationTest, MeleeAutoAttackProc_CritOnly) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_CRITICAL) + .Build(); + + // Normal hit should NOT trigger crit-only proc + auto normalScenario = ProcScenarioBuilder() + .OnMeleeAutoAttack() + .WithNormalHit(); + EXPECT_PROC_DOES_NOT_TRIGGER(procEntry, normalScenario); + + // Critical hit should trigger + auto critScenario = ProcScenarioBuilder() + .OnMeleeAutoAttack() + .WithCrit(); + EXPECT_PROC_TRIGGERS(procEntry, critScenario); +} + +TEST_F(SpellProcIntegrationTest, MeleeAutoAttackProc_Miss) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_MISS) + .Build(); + + auto missScenario = ProcScenarioBuilder() + .OnMeleeAutoAttack() + .WithMiss(); + + EXPECT_PROC_TRIGGERS(procEntry, missScenario); +} + +// ============================================================================= +// Spell Damage Proc Tests +// ============================================================================= + +TEST_F(SpellProcIntegrationTest, SpellDamageProc_OnHit) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnSpellDamage() + .OnHit() + .WithNormalHit(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +TEST_F(SpellProcIntegrationTest, SpellDamageProc_OnCast) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_CAST) + .Build(); + + // Should trigger on cast phase + auto castScenario = ProcScenarioBuilder() + .OnSpellDamage() + .OnCast(); + EXPECT_PROC_TRIGGERS(procEntry, castScenario); + + // Should NOT trigger on hit phase when configured for cast only + auto hitScenario = ProcScenarioBuilder() + .OnSpellDamage() + .OnHit(); + EXPECT_PROC_DOES_NOT_TRIGGER(procEntry, hitScenario); +} + +// ============================================================================= +// Heal Proc Tests +// ============================================================================= + +// Heal proc tests - require SpellPhaseMask to be set +TEST_F(SpellProcIntegrationTest, HealProc_OnHeal) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellTypeMask(PROC_SPELL_TYPE_HEAL) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnHeal() + .OnHit(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +TEST_F(SpellProcIntegrationTest, HealProc_CritHeal) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellTypeMask(PROC_SPELL_TYPE_HEAL) + .WithHitMask(PROC_HIT_CRITICAL) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + // Normal heal should NOT trigger crit-only proc + auto normalScenario = ProcScenarioBuilder() + .OnHeal() + .WithNormalHit(); + EXPECT_PROC_DOES_NOT_TRIGGER(procEntry, normalScenario); + + // Crit heal should trigger + auto critScenario = ProcScenarioBuilder() + .OnHeal() + .WithCrit(); + EXPECT_PROC_TRIGGERS(procEntry, critScenario); +} + +// ============================================================================= +// Periodic Effect Proc Tests +// ============================================================================= + +// Periodic proc tests - spell procs that require SpellPhaseMask to be set +TEST_F(SpellProcIntegrationTest, PeriodicDamageProc) +{ + // Note: PROC_FLAG_DONE_PERIODIC is in REQ_SPELL_PHASE_PROC_FLAG_MASK, + // so SpellPhaseMask must be set (can't be 0) + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_PERIODIC) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnPeriodicDamage() + .WithNormalHit(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +TEST_F(SpellProcIntegrationTest, PeriodicHealProc) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_PERIODIC) + .WithSpellTypeMask(PROC_SPELL_TYPE_HEAL) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnPeriodicHeal() + .WithNormalHit(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +// ============================================================================= +// Kill/Death Proc Tests +// ============================================================================= + +TEST_F(SpellProcIntegrationTest, KillProc) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_KILL) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnKill(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +TEST_F(SpellProcIntegrationTest, DeathProc) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DEATH) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnDeath(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +// ============================================================================= +// Defensive Proc Tests (Dodge/Parry/Block) +// ============================================================================= + +TEST_F(SpellProcIntegrationTest, DodgeProc) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_DODGE) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnTakenMeleeAutoAttack() + .WithDodge(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +TEST_F(SpellProcIntegrationTest, ParryProc) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_PARRY) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnTakenMeleeAutoAttack() + .WithParry(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +TEST_F(SpellProcIntegrationTest, BlockProc) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_BLOCK) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnTakenMeleeAutoAttack() + .WithBlock(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +TEST_F(SpellProcIntegrationTest, FullBlockProc) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_FULL_BLOCK) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnTakenMeleeAutoAttack() + .WithFullBlock(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +// ============================================================================= +// Absorb Proc Tests +// ============================================================================= + +TEST_F(SpellProcIntegrationTest, AbsorbProc) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG) + .WithHitMask(PROC_HIT_ABSORB) + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnTakenSpellDamage() + .WithAbsorb(); + + EXPECT_PROC_TRIGGERS(procEntry, scenario); +} + +// Note: PROC_HIT_ABSORB covers both partial and full absorb +// There is no separate PROC_HIT_FULL_ABSORB flag in AzerothCore + +// ============================================================================= +// Spell Family Filtering Tests +// ============================================================================= + +TEST_F(SpellProcIntegrationTest, SpellFamilyMatch_SameFamily) +{ + // Create a Mage spell (family 3) + auto* triggerSpell = CreateSpellInfo(133, 3, 0x00000001); // Fireball + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellFamilyName(3) // SPELLFAMILY_MAGE + .WithSpellFamilyMask(flag96(0x00000001, 0, 0)) + .Build(); + + // Test family match logic + EXPECT_TRUE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, triggerSpell)); +} + +TEST_F(SpellProcIntegrationTest, SpellFamilyMatch_DifferentFamily) +{ + // Create a Warrior spell (family 4) + auto* triggerSpell = CreateSpellInfo(6343, 4, 0x00000001); // Thunder Clap + + auto procEntry = SpellProcEntryBuilder() + .WithSpellFamilyName(3) // SPELLFAMILY_MAGE - should NOT match + .WithSpellFamilyMask(flag96(0x00000001, 0, 0)) + .Build(); + + EXPECT_FALSE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, triggerSpell)); +} + +TEST_F(SpellProcIntegrationTest, SpellFamilyMatch_NoFamilyFilter) +{ + // Create any spell + auto* triggerSpell = CreateSpellInfo(133, 3, 0x00000001); + + // Proc with no family filter should match any spell + auto procEntry = SpellProcEntryBuilder() + .WithSpellFamilyName(0) // No family filter + .Build(); + + EXPECT_TRUE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, triggerSpell)); +} + +TEST_F(SpellProcIntegrationTest, SpellFamilyMatch_FlagMismatch) +{ + // Create a Mage spell with specific flags + auto* triggerSpell = CreateSpellInfo(133, 3, 0x00000001); // Fireball flag + + auto procEntry = SpellProcEntryBuilder() + .WithSpellFamilyName(3) // SPELLFAMILY_MAGE + .WithSpellFamilyMask(flag96(0x00000002, 0, 0)) // Different flag + .Build(); + + EXPECT_FALSE(TestSpellFamilyMatch(procEntry.SpellFamilyName, procEntry.SpellFamilyMask, triggerSpell)); +} + +// ============================================================================= +// Combined Flag Tests +// ============================================================================= + +TEST_F(SpellProcIntegrationTest, MultipleProcFlags_MeleeOrSpell) +{ + // Proc on melee OR spell damage + // Note: Spell procs require SpellPhaseMask to be set, otherwise the check + // (eventInfo.SpellPhaseMask & procEntry.SpellPhaseMask) fails when procEntry = 0 + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + // Melee test + auto meleeEventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, meleeEventInfo)); + + // Spell test - needs matching SpellPhaseMask AND SpellInfo + auto* spellInfo = CreateSpellInfo(100); + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + auto spellEventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithHitMask(PROC_HIT_NORMAL) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithDamageInfo(&damageInfo) + .Build(); + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, spellEventInfo)); +} + +TEST_F(SpellProcIntegrationTest, MultipleHitMasks_CritOrNormal) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL | PROC_HIT_CRITICAL) + .Build(); + + auto normalScenario = ProcScenarioBuilder() + .OnMeleeAutoAttack() + .WithNormalHit(); + EXPECT_PROC_TRIGGERS(procEntry, normalScenario); + + auto critScenario = ProcScenarioBuilder() + .OnMeleeAutoAttack() + .WithCrit(); + EXPECT_PROC_TRIGGERS(procEntry, critScenario); + + auto missScenario = ProcScenarioBuilder() + .OnMeleeAutoAttack() + .WithMiss(); + EXPECT_PROC_DOES_NOT_TRIGGER(procEntry, missScenario); +} + +// ============================================================================= +// School Mask Tests +// ============================================================================= + +TEST_F(SpellProcIntegrationTest, SchoolMaskFilter_FireOnly_FireDamage) +{ + // Proc entry requires fire school damage + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSchoolMask(SPELL_SCHOOL_MASK_FIRE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + // Create fire spell and fire damage info + auto* fireSpell = CreateSpellInfo(133, 3, 0); // Fireball + DamageInfo fireDamageInfo(nullptr, nullptr, 100, fireSpell, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithHitMask(PROC_HIT_NORMAL) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithDamageInfo(&fireDamageInfo) + .Build(); + + // Fire damage should trigger fire-only proc + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcIntegrationTest, SchoolMaskFilter_FireOnly_FrostDamage) +{ + // Proc entry requires fire school damage + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSchoolMask(SPELL_SCHOOL_MASK_FIRE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + // Create frost spell and frost damage info + auto* frostSpell = CreateSpellInfo(116, 3, 0); // Frostbolt + DamageInfo frostDamageInfo(nullptr, nullptr, 100, frostSpell, SPELL_SCHOOL_MASK_FROST, SPELL_DIRECT_DAMAGE); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithHitMask(PROC_HIT_NORMAL) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithDamageInfo(&frostDamageInfo) + .Build(); + + // Frost damage should NOT trigger fire-only proc + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcIntegrationTest, SchoolMaskFilter_NoSchoolMask_AnySchoolTriggers) +{ + // Proc entry with no school mask filter (accepts all schools) + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSchoolMask(0) // No filter + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + // Test with shadow damage + auto* shadowSpell = CreateSpellInfo(686, 5, 0); // Shadow Bolt + DamageInfo shadowDamageInfo(nullptr, nullptr, 100, shadowSpell, SPELL_SCHOOL_MASK_SHADOW, SPELL_DIRECT_DAMAGE); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithHitMask(PROC_HIT_NORMAL) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithDamageInfo(&shadowDamageInfo) + .Build(); + + // Any school should trigger when no school mask filter is set + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +// ============================================================================= +// Edge Case Tests +// ============================================================================= + +TEST_F(SpellProcIntegrationTest, EmptyProcFlags_NeverTriggers) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_NONE) // No flags set + .Build(); + + auto scenario = ProcScenarioBuilder() + .OnMeleeAutoAttack() + .WithNormalHit(); + + // Without PROC_FLAG_NONE special handling, this might still match + // The actual behavior depends on implementation + auto eventInfo = scenario.Build(); + + // Event has flags but proc entry has none - should not trigger + if (procEntry.ProcFlags == 0 && scenario.GetTypeMask() != 0) + { + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); + } +} + +TEST_F(SpellProcIntegrationTest, AllHitMasks_TriggersOnAny) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_MASK_ALL) + .Build(); + + // Should trigger on any hit type + std::vector hitTypes = { + PROC_HIT_NORMAL, PROC_HIT_CRITICAL, PROC_HIT_MISS, + PROC_HIT_DODGE, PROC_HIT_PARRY, PROC_HIT_BLOCK + }; + + for (uint32_t hitType : hitTypes) + { + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(hitType) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + << "Failed for hit type: " << hitType; + } +} diff --git a/src/test/server/game/Spells/SpellProcPPMModifierTest.cpp b/src/test/server/game/Spells/SpellProcPPMModifierTest.cpp new file mode 100644 index 000000000..88749ee25 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcPPMModifierTest.cpp @@ -0,0 +1,399 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcPPMModifierTest.cpp + * @brief Unit tests for SPELLMOD_PROC_PER_MINUTE modifier application + * + * Tests the logic from Unit.cpp:10378-10390: + * - Base PPM calculation without modifiers + * - Flat PPM modifier application + * - Percent PPM modifier application + * - GetSpellModOwner() null handling + * - SpellProto null handling + */ + +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "gtest/gtest.h" + +using namespace testing; + +class SpellProcPPMModifierTest : public ::testing::Test +{ +protected: + void SetUp() override {} + + // Standard weapon speeds for testing + static constexpr uint32 DAGGER_SPEED = 1400; // 1.4 sec + static constexpr uint32 SWORD_SPEED = 2500; // 2.5 sec + static constexpr uint32 TWO_HANDED_SPEED = 3300; // 3.3 sec +}; + +// ============================================================================= +// Base PPM Calculation (No Modifiers) +// ============================================================================= + +TEST_F(SpellProcPPMModifierTest, BasePPM_NoModifiers) +{ + ProcChanceTestHelper::PPMModifierConfig config; + // Default config: no modifiers, has spell mod owner and spell proto + + float basePPM = 6.0f; + + // With 2500ms weapon: (2500 * 6) / 600 = 25% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, basePPM, config); + + EXPECT_NEAR(chance, 25.0f, 0.01f) + << "Base PPM 6.0 with 2.5s weapon should give 25% chance"; +} + +TEST_F(SpellProcPPMModifierTest, BasePPM_DifferentWeaponSpeeds) +{ + ProcChanceTestHelper::PPMModifierConfig config; + float basePPM = 6.0f; + + // Fast dagger: (1400 * 6) / 600 = 14% + float daggerChance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + DAGGER_SPEED, basePPM, config); + EXPECT_NEAR(daggerChance, 14.0f, 0.01f); + + // Slow 2H: (3300 * 6) / 600 = 33% + float twoHandChance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + TWO_HANDED_SPEED, basePPM, config); + EXPECT_NEAR(twoHandChance, 33.0f, 0.01f); +} + +TEST_F(SpellProcPPMModifierTest, BasePPM_ZeroPPM) +{ + ProcChanceTestHelper::PPMModifierConfig config; + + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, 0.0f, config); + + EXPECT_EQ(chance, 0.0f) + << "Zero PPM should return 0% chance"; +} + +TEST_F(SpellProcPPMModifierTest, BasePPM_NegativePPM) +{ + ProcChanceTestHelper::PPMModifierConfig config; + + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, -5.0f, config); + + EXPECT_EQ(chance, 0.0f) + << "Negative PPM should return 0% chance"; +} + +// ============================================================================= +// Flat Modifier Tests - SPELLMOD_FLAT for SPELLMOD_PROC_PER_MINUTE +// ============================================================================= + +TEST_F(SpellProcPPMModifierTest, FlatModifier_IncreasesPPM) +{ + ProcChanceTestHelper::PPMModifierConfig config; + config.flatModifier = 2.0f; // +2 PPM + + float basePPM = 6.0f; + // Modified PPM: 6 + 2 = 8 + // Chance: (2500 * 8) / 600 = 33.33% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, basePPM, config); + + EXPECT_NEAR(chance, 33.33f, 0.1f) + << "Flat +2 PPM modifier should increase chance from 25% to 33.33%"; +} + +TEST_F(SpellProcPPMModifierTest, FlatModifier_DecreasesPPM) +{ + ProcChanceTestHelper::PPMModifierConfig config; + config.flatModifier = -3.0f; // -3 PPM + + float basePPM = 6.0f; + // Modified PPM: 6 - 3 = 3 + // Chance: (2500 * 3) / 600 = 12.5% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, basePPM, config); + + EXPECT_NEAR(chance, 12.5f, 0.1f) + << "Flat -3 PPM modifier should decrease chance from 25% to 12.5%"; +} + +TEST_F(SpellProcPPMModifierTest, FlatModifier_ReducesToZero) +{ + ProcChanceTestHelper::PPMModifierConfig config; + config.flatModifier = -10.0f; // Would reduce to -4 PPM + + float basePPM = 6.0f; + // Modified PPM: 6 - 10 = -4 (negative) + // Formula still applies: (2500 * -4) / 600 = negative + // But the check at start for PPM <= 0 happens before modifiers + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, basePPM, config); + + // Note: In the real code, negative results are possible after modifiers + // The helper doesn't clamp the final result + EXPECT_LT(chance, 0.0f) + << "Extreme negative modifier can produce negative chance"; +} + +// ============================================================================= +// Percent Modifier Tests - SPELLMOD_PCT for SPELLMOD_PROC_PER_MINUTE +// ============================================================================= + +TEST_F(SpellProcPPMModifierTest, PercentModifier_50PercentIncrease) +{ + ProcChanceTestHelper::PPMModifierConfig config; + config.pctModifier = 1.5f; // 150% = 50% increase + + float basePPM = 6.0f; + // Modified PPM: 6 * 1.5 = 9 + // Chance: (2500 * 9) / 600 = 37.5% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, basePPM, config); + + EXPECT_NEAR(chance, 37.5f, 0.1f) + << "50% PPM increase should raise chance from 25% to 37.5%"; +} + +TEST_F(SpellProcPPMModifierTest, PercentModifier_50PercentDecrease) +{ + ProcChanceTestHelper::PPMModifierConfig config; + config.pctModifier = 0.5f; // 50% = 50% decrease + + float basePPM = 6.0f; + // Modified PPM: 6 * 0.5 = 3 + // Chance: (2500 * 3) / 600 = 12.5% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, basePPM, config); + + EXPECT_NEAR(chance, 12.5f, 0.1f) + << "50% PPM decrease should lower chance from 25% to 12.5%"; +} + +TEST_F(SpellProcPPMModifierTest, PercentModifier_DoublesPPM) +{ + ProcChanceTestHelper::PPMModifierConfig config; + config.pctModifier = 2.0f; // 200% + + float basePPM = 6.0f; + // Modified PPM: 6 * 2 = 12 + // Chance: (2500 * 12) / 600 = 50% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, basePPM, config); + + EXPECT_NEAR(chance, 50.0f, 0.1f) + << "100% PPM increase should double chance to 50%"; +} + +// ============================================================================= +// Combined Modifiers Tests +// ============================================================================= + +TEST_F(SpellProcPPMModifierTest, CombinedModifiers_FlatThenPercent) +{ + ProcChanceTestHelper::PPMModifierConfig config; + config.flatModifier = 2.0f; // +2 PPM first + config.pctModifier = 1.5f; // Then 50% increase + + float basePPM = 6.0f; + // Flat first: 6 + 2 = 8 + // Percent: 8 * 1.5 = 12 + // Chance: (2500 * 12) / 600 = 50% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, basePPM, config); + + EXPECT_NEAR(chance, 50.0f, 0.1f) + << "Flat +2 then 50% increase should result in 50% chance"; +} + +TEST_F(SpellProcPPMModifierTest, CombinedModifiers_BothIncrease) +{ + ProcChanceTestHelper::PPMModifierConfig config; + config.flatModifier = 4.0f; // +4 PPM + config.pctModifier = 1.25f; // 25% increase + + float basePPM = 6.0f; + // Flat first: 6 + 4 = 10 + // Percent: 10 * 1.25 = 12.5 + // Chance: (2500 * 12.5) / 600 = 52.08% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, basePPM, config); + + EXPECT_NEAR(chance, 52.08f, 0.1f); +} + +// ============================================================================= +// No SpellModOwner Tests - GetSpellModOwner() returns null +// ============================================================================= + +TEST_F(SpellProcPPMModifierTest, NoSpellModOwner_ModifiersIgnored) +{ + ProcChanceTestHelper::PPMModifierConfig config; + config.hasSpellModOwner = false; // GetSpellModOwner() returns null + config.flatModifier = 10.0f; // Would significantly change result + config.pctModifier = 2.0f; + + float basePPM = 6.0f; + // Without spell mod owner, modifiers are NOT applied + // Chance: (2500 * 6) / 600 = 25% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, basePPM, config); + + EXPECT_NEAR(chance, 25.0f, 0.1f) + << "Without spell mod owner, modifiers should be ignored"; +} + +// ============================================================================= +// No SpellProto Tests - spellProto is null +// ============================================================================= + +TEST_F(SpellProcPPMModifierTest, NoSpellProto_ModifiersIgnored) +{ + ProcChanceTestHelper::PPMModifierConfig config; + config.hasSpellProto = false; // spellProto is null + config.flatModifier = 10.0f; + config.pctModifier = 2.0f; + + float basePPM = 6.0f; + // Without spell proto, modifiers are NOT applied + // Chance: (2500 * 6) / 600 = 25% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, basePPM, config); + + EXPECT_NEAR(chance, 25.0f, 0.1f) + << "Without spell proto, modifiers should be ignored"; +} + +// ============================================================================= +// Real Spell Scenarios +// ============================================================================= + +TEST_F(SpellProcPPMModifierTest, Scenario_OmenOfClarity_BasePPM) +{ + // Omen of Clarity: 6 PPM + ProcChanceTestHelper::PPMModifierConfig config; + + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, 6.0f, config); + + EXPECT_NEAR(chance, 25.0f, 0.1f) + << "Omen of Clarity base chance with 2.5s weapon"; +} + +TEST_F(SpellProcPPMModifierTest, Scenario_OmenOfClarity_WithTalent) +{ + // Hypothetical talent that increases Omen of Clarity PPM by 2 + ProcChanceTestHelper::PPMModifierConfig config; + config.flatModifier = 2.0f; + + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, 6.0f, config); + + EXPECT_NEAR(chance, 33.33f, 0.1f) + << "Omen of Clarity with +2 PPM talent"; +} + +TEST_F(SpellProcPPMModifierTest, Scenario_WindfuryWeapon_FastWeapon) +{ + // Windfury Weapon: 2 PPM with fast weapon + ProcChanceTestHelper::PPMModifierConfig config; + + // Fast 1.5s weapon: (1500 * 2) / 600 = 5% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + 1500, 2.0f, config); + + EXPECT_NEAR(chance, 5.0f, 0.1f) + << "Windfury with 1.5s weapon"; +} + +TEST_F(SpellProcPPMModifierTest, Scenario_WindfuryWeapon_SlowWeapon) +{ + // Windfury Weapon: 2 PPM with slow weapon + ProcChanceTestHelper::PPMModifierConfig config; + + // Slow 3.6s weapon: (3600 * 2) / 600 = 12% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + 3600, 2.0f, config); + + EXPECT_NEAR(chance, 12.0f, 0.1f) + << "Windfury with 3.6s weapon"; +} + +TEST_F(SpellProcPPMModifierTest, Scenario_JudgementOfLight_HighPPM) +{ + // Judgement of Light: 15 PPM (very high) + ProcChanceTestHelper::PPMModifierConfig config; + + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, 15.0f, config); + + // (2500 * 15) / 600 = 62.5% + EXPECT_NEAR(chance, 62.5f, 0.1f) + << "Judgement of Light with 2.5s weapon"; +} + +// ============================================================================= +// Edge Cases +// ============================================================================= + +TEST_F(SpellProcPPMModifierTest, EdgeCase_VeryFastWeapon) +{ + ProcChanceTestHelper::PPMModifierConfig config; + + // 1.0s weapon (very fast): (1000 * 6) / 600 = 10% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + 1000, 6.0f, config); + + EXPECT_NEAR(chance, 10.0f, 0.1f); +} + +TEST_F(SpellProcPPMModifierTest, EdgeCase_VerySlowWeapon) +{ + ProcChanceTestHelper::PPMModifierConfig config; + + // 4.0s weapon (very slow): (4000 * 6) / 600 = 40% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + 4000, 6.0f, config); + + EXPECT_NEAR(chance, 40.0f, 0.1f); +} + +TEST_F(SpellProcPPMModifierTest, EdgeCase_VeryHighPPM) +{ + ProcChanceTestHelper::PPMModifierConfig config; + + // 60 PPM: (2500 * 60) / 600 = 250% (over 100%, can happen) + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + SWORD_SPEED, 60.0f, config); + + EXPECT_NEAR(chance, 250.0f, 0.1f) + << "Very high PPM can exceed 100% chance"; +} + +TEST_F(SpellProcPPMModifierTest, EdgeCase_ZeroWeaponSpeed) +{ + ProcChanceTestHelper::PPMModifierConfig config; + + // Zero weapon speed should result in 0% + float chance = ProcChanceTestHelper::CalculatePPMChanceWithModifiers( + 0, 6.0f, config); + + EXPECT_EQ(chance, 0.0f); +} diff --git a/src/test/server/game/Spells/SpellProcPPMTest.cpp b/src/test/server/game/Spells/SpellProcPPMTest.cpp new file mode 100644 index 000000000..b58df9a0e --- /dev/null +++ b/src/test/server/game/Spells/SpellProcPPMTest.cpp @@ -0,0 +1,377 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcPPMTest.cpp + * @brief Unit tests for PPM (Procs Per Minute) calculation + * + * Tests the formula: chance = (WeaponSpeed * PPM) / 600.0f + */ + +#include "ProcChanceTestHelper.h" +#include "UnitStub.h" +#include "gtest/gtest.h" + +using namespace testing; + +// ============================================================================= +// PPM Formula Tests +// ============================================================================= + +class SpellProcPPMTest : public ::testing::Test +{ +protected: + void SetUp() override + { + _unit = std::make_unique(); + } + + std::unique_ptr _unit; +}; + +TEST_F(SpellProcPPMTest, PPMFormula_BasicCalculation) +{ + // Formula: (WeaponSpeed * PPM) / 600.0f + // 2500ms * 6 PPM / 600 = 25% + float result = ProcChanceTestHelper::CalculatePPMChance(2500, 6.0f); + EXPECT_NEAR(result, 25.0f, 0.01f); +} + +TEST_F(SpellProcPPMTest, PPMFormula_FastWeapon_HigherChancePerSwing) +{ + // Fast dagger (1.4 sec = 1400ms), 6 PPM + // 1400 * 6 / 600 = 14% + float result = ProcChanceTestHelper::CalculatePPMChance(1400, 6.0f); + EXPECT_NEAR(result, 14.0f, 0.01f); +} + +TEST_F(SpellProcPPMTest, PPMFormula_SlowWeapon_LowerChancePerSwing) +{ + // Slow 2H (3.3 sec = 3300ms), 6 PPM + // 3300 * 6 / 600 = 33% + float result = ProcChanceTestHelper::CalculatePPMChance(3300, 6.0f); + EXPECT_NEAR(result, 33.0f, 0.01f); +} + +TEST_F(SpellProcPPMTest, PPMFormula_VerySlowWeapon) +{ + // Very slow weapon (3.8 sec = 3800ms), 6 PPM + // 3800 * 6 / 600 = 38% + float result = ProcChanceTestHelper::CalculatePPMChance(3800, 6.0f); + EXPECT_NEAR(result, 38.0f, 0.01f); +} + +TEST_F(SpellProcPPMTest, PPMFormula_ZeroPPM_ReturnsZero) +{ + float result = ProcChanceTestHelper::CalculatePPMChance(2500, 0.0f); + EXPECT_FLOAT_EQ(result, 0.0f); +} + +TEST_F(SpellProcPPMTest, PPMFormula_NegativePPM_ReturnsZero) +{ + float result = ProcChanceTestHelper::CalculatePPMChance(2500, -1.0f); + EXPECT_FLOAT_EQ(result, 0.0f); +} + +TEST_F(SpellProcPPMTest, PPMFormula_WithPositiveModifier) +{ + // 2500ms, 6 PPM + 2 PPM modifier = 8 effective PPM + // 2500 * 8 / 600 = 33.33% + float result = ProcChanceTestHelper::CalculatePPMChance(2500, 6.0f, 2.0f); + EXPECT_NEAR(result, 33.33f, 0.01f); +} + +TEST_F(SpellProcPPMTest, PPMFormula_WithNegativeModifier) +{ + // 2500ms, 6 PPM - 2 PPM modifier = 4 effective PPM + // 2500 * 4 / 600 = 16.67% + float result = ProcChanceTestHelper::CalculatePPMChance(2500, 6.0f, -2.0f); + EXPECT_NEAR(result, 16.67f, 0.01f); +} + +// ============================================================================= +// UnitStub PPM Tests +// ============================================================================= + +TEST_F(SpellProcPPMTest, UnitStub_GetPPMProcChance_DefaultWeaponSpeed) +{ + // Default weapon speed is 2000ms + float result = _unit->GetPPMProcChance(2000, 6.0f); + EXPECT_NEAR(result, 20.0f, 0.01f); +} + +TEST_F(SpellProcPPMTest, UnitStub_GetPPMProcChance_CustomWeaponSpeed) +{ + _unit->SetAttackTime(0, 2500); // BASE_ATTACK + float result = _unit->GetPPMProcChance(_unit->GetAttackTime(0), 6.0f); + EXPECT_NEAR(result, 25.0f, 0.01f); +} + +TEST_F(SpellProcPPMTest, UnitStub_GetPPMProcChance_WithPPMModifier) +{ + _unit->SetPPMModifier(12345, 2.0f); // Spell ID 12345 has +2 PPM modifier + float result = _unit->GetPPMProcChance(2500, 6.0f, 12345); + // 2500 * (6 + 2) / 600 = 33.33% + EXPECT_NEAR(result, 33.33f, 0.01f); +} + +TEST_F(SpellProcPPMTest, UnitStub_GetPPMProcChance_ModifierNotAppliedWithoutSpellId) +{ + _unit->SetPPMModifier(12345, 2.0f); + // Without spell ID, modifier is not applied + float result = _unit->GetPPMProcChance(2500, 6.0f, 0); + EXPECT_NEAR(result, 25.0f, 0.01f); +} + +// ============================================================================= +// Real-World PPM Spell Examples +// ============================================================================= + +TEST_F(SpellProcPPMTest, OmenOfClarity_PPM6_VariousWeaponSpeeds) +{ + // Omen of Clarity: 6 PPM + constexpr float OOC_PPM = 6.0f; + + // Fast dagger + float daggerChance = ProcChanceTestHelper::CalculatePPMChance(1400, OOC_PPM); + EXPECT_NEAR(daggerChance, 14.0f, 0.01f); + + // Normal 1H sword + float swordChance = ProcChanceTestHelper::CalculatePPMChance(2500, OOC_PPM); + EXPECT_NEAR(swordChance, 25.0f, 0.01f); + + // Staff + float staffChance = ProcChanceTestHelper::CalculatePPMChance(3000, OOC_PPM); + EXPECT_NEAR(staffChance, 30.0f, 0.01f); +} + +TEST_F(SpellProcPPMTest, JudgementOfLight_PPM15_VariousWeaponSpeeds) +{ + // Judgement of Light: 15 PPM + constexpr float JOL_PPM = 15.0f; + + // Fast dagger + float daggerChance = ProcChanceTestHelper::CalculatePPMChance(1400, JOL_PPM); + EXPECT_NEAR(daggerChance, 35.0f, 0.01f); + + // Normal 1H sword + float swordChance = ProcChanceTestHelper::CalculatePPMChance(2500, JOL_PPM); + EXPECT_NEAR(swordChance, 62.5f, 0.01f); + + // Slow 2H weapon + float twoHanderChance = ProcChanceTestHelper::CalculatePPMChance(3300, JOL_PPM); + EXPECT_NEAR(twoHanderChance, 82.5f, 0.01f); +} + +TEST_F(SpellProcPPMTest, WindfuryWeapon_PPM2_VariousWeaponSpeeds) +{ + // Windfury Weapon: 2 PPM (low PPM for testing) + constexpr float WF_PPM = 2.0f; + + // Fast dagger + float daggerChance = ProcChanceTestHelper::CalculatePPMChance(1400, WF_PPM); + EXPECT_NEAR(daggerChance, 4.67f, 0.01f); + + // Slow 2H weapon + float twoHanderChance = ProcChanceTestHelper::CalculatePPMChance(3300, WF_PPM); + EXPECT_NEAR(twoHanderChance, 11.0f, 0.01f); +} + +// ============================================================================= +// Edge Cases +// ============================================================================= + +TEST_F(SpellProcPPMTest, EdgeCase_VeryFastWeapon) +{ + // Very fast (theoretical) weapon - 1.0 sec = 1000ms + float result = ProcChanceTestHelper::CalculatePPMChance(1000, 6.0f); + EXPECT_NEAR(result, 10.0f, 0.01f); +} + +TEST_F(SpellProcPPMTest, EdgeCase_ExtremelySlow) +{ + // Extremely slow weapon - 5.0 sec = 5000ms + float result = ProcChanceTestHelper::CalculatePPMChance(5000, 6.0f); + EXPECT_NEAR(result, 50.0f, 0.01f); +} + +TEST_F(SpellProcPPMTest, EdgeCase_HighPPM) +{ + // High PPM value (30) + float result = ProcChanceTestHelper::CalculatePPMChance(2500, 30.0f); + // 2500 * 30 / 600 = 125% (can exceed 100%) + EXPECT_NEAR(result, 125.0f, 0.01f); +} + +TEST_F(SpellProcPPMTest, EdgeCase_FractionalPPM) +{ + // Fractional PPM value (2.5) + float result = ProcChanceTestHelper::CalculatePPMChance(2400, 2.5f); + // 2400 * 2.5 / 600 = 10% + EXPECT_NEAR(result, 10.0f, 0.01f); +} + +// ============================================================================= +// Shapeshifter Enchant PPM Bug Tests +// +// Player::CastItemCombatSpell has two PPM paths: +// 1) Item spells (line ~7308): uses GetAttackTime(attType) - CORRECT +// 2) Enchantment procs (line ~7375): uses proto->Delay - BUG +// +// For non-shapeshifted players these return the same value, but for +// Feral Druids proto->Delay reflects the weapon (e.g. 3.6s staff) +// while GetAttackTime returns the form speed (1.0s Cat, 2.5s Bear). +// ============================================================================= + +TEST_F(SpellProcPPMTest, ShapeshiftBug_NonShifted_NoDiscrepancy) +{ + // A warrior with a 3.6s weapon: proto->Delay == GetAttackTime() + constexpr uint32 WEAPON_DELAY = ProcChanceTestHelper::WEAPON_SPEED_STAFF; + constexpr float MONGOOSE_PPM = 1.0f; + + _unit->SetAttackTime(0, WEAPON_DELAY); + + float chanceFromProtoDelay = ProcChanceTestHelper::CalculatePPMChance(WEAPON_DELAY, MONGOOSE_PPM); + float chanceFromGetAttackTime = ProcChanceTestHelper::CalculatePPMChance( + _unit->GetAttackTime(0), MONGOOSE_PPM); + + EXPECT_FLOAT_EQ(chanceFromProtoDelay, chanceFromGetAttackTime) + << "Non-shapeshifted: proto->Delay and GetAttackTime() should be identical"; +} + +TEST_F(SpellProcPPMTest, ShapeshiftBug_CatForm_ProtoDelayInflatesChance) +{ + // Druid in Cat Form with a 3.6s staff equipped + // proto->Delay = 3600ms (the staff), GetAttackTime = 1000ms (Cat Form) + constexpr uint32 STAFF_DELAY = ProcChanceTestHelper::WEAPON_SPEED_STAFF; + constexpr uint32 CAT_SPEED = ProcChanceTestHelper::FORM_SPEED_CAT; + constexpr float MONGOOSE_PPM = 1.0f; + + _unit->SetAttackTime(0, CAT_SPEED); + + float buggyChance = ProcChanceTestHelper::CalculatePPMChance(STAFF_DELAY, MONGOOSE_PPM); + float correctChance = ProcChanceTestHelper::CalculatePPMChance(CAT_SPEED, MONGOOSE_PPM); + + // proto->Delay gives 3600 * 1 / 600 = 6.0% per swing + EXPECT_NEAR(buggyChance, 6.0f, 0.01f); + // GetAttackTime gives 1000 * 1 / 600 = 1.67% per swing + EXPECT_NEAR(correctChance, 1.67f, 0.01f); + + // The bug inflates chance per swing by weapon_speed / form_speed + EXPECT_NEAR(buggyChance / correctChance, + static_cast(STAFF_DELAY) / static_cast(CAT_SPEED), 0.01f) + << "Bug inflates per-swing chance by ratio of weapon speed to form speed"; +} + +TEST_F(SpellProcPPMTest, ShapeshiftBug_CatForm_EffectivePPMIs3Point6x) +{ + // Cat Form attacks every 1.0s (60 swings/min) + // With the buggy 6.0% chance per swing: 60 * 0.06 = 3.6 procs/min + // With the correct 1.67% chance: 60 * 0.0167 = 1.0 procs/min + constexpr uint32 STAFF_DELAY = ProcChanceTestHelper::WEAPON_SPEED_STAFF; + constexpr uint32 CAT_SPEED = ProcChanceTestHelper::FORM_SPEED_CAT; + constexpr float MONGOOSE_PPM = 1.0f; + + float buggyChance = ProcChanceTestHelper::CalculatePPMChance(STAFF_DELAY, MONGOOSE_PPM); + float correctChance = ProcChanceTestHelper::CalculatePPMChance(CAT_SPEED, MONGOOSE_PPM); + + float buggyEffectivePPM = ProcChanceTestHelper::CalculateEffectivePPM(buggyChance, CAT_SPEED); + float correctEffectivePPM = ProcChanceTestHelper::CalculateEffectivePPM(correctChance, CAT_SPEED); + + // Buggy: effective PPM is 3.6 instead of 1.0 + EXPECT_NEAR(buggyEffectivePPM, 3.6f, 0.01f) + << "Bug: Cat Form Mongoose procs 3.6 times/min instead of 1.0"; + // Correct: effective PPM matches the intended value + EXPECT_NEAR(correctEffectivePPM, MONGOOSE_PPM, 0.01f) + << "Fix: Cat Form Mongoose should proc exactly 1.0 times/min"; +} + +TEST_F(SpellProcPPMTest, ShapeshiftBug_BearForm_ProtoDelayInflatesChance) +{ + // Bear Form with 3.6s staff: proto->Delay = 3600, GetAttackTime = 2500 + constexpr uint32 STAFF_DELAY = ProcChanceTestHelper::WEAPON_SPEED_STAFF; + constexpr uint32 BEAR_SPEED = ProcChanceTestHelper::FORM_SPEED_BEAR; + constexpr float MONGOOSE_PPM = 1.0f; + + _unit->SetAttackTime(0, BEAR_SPEED); + + float buggyChance = ProcChanceTestHelper::CalculatePPMChance(STAFF_DELAY, MONGOOSE_PPM); + float correctChance = ProcChanceTestHelper::CalculatePPMChance(BEAR_SPEED, MONGOOSE_PPM); + + float buggyEffectivePPM = ProcChanceTestHelper::CalculateEffectivePPM(buggyChance, BEAR_SPEED); + float correctEffectivePPM = ProcChanceTestHelper::CalculateEffectivePPM(correctChance, BEAR_SPEED); + + // Buggy: 1.44 PPM instead of 1.0 + EXPECT_NEAR(buggyEffectivePPM, 1.44f, 0.01f) + << "Bug: Bear Form Mongoose procs 1.44 times/min instead of 1.0"; + EXPECT_NEAR(correctEffectivePPM, MONGOOSE_PPM, 0.01f) + << "Fix: Bear Form Mongoose should proc exactly 1.0 times/min"; +} + +TEST_F(SpellProcPPMTest, ShapeshiftBug_CatForm_FieryWeapon6PPM) +{ + // Fiery Weapon (6 PPM) in Cat Form with 3.6s staff + constexpr uint32 STAFF_DELAY = ProcChanceTestHelper::WEAPON_SPEED_STAFF; + constexpr uint32 CAT_SPEED = ProcChanceTestHelper::FORM_SPEED_CAT; + constexpr float FIERY_PPM = 6.0f; + + float buggyChance = ProcChanceTestHelper::CalculatePPMChance(STAFF_DELAY, FIERY_PPM); + float correctChance = ProcChanceTestHelper::CalculatePPMChance(CAT_SPEED, FIERY_PPM); + + float buggyEffectivePPM = ProcChanceTestHelper::CalculateEffectivePPM(buggyChance, CAT_SPEED); + float correctEffectivePPM = ProcChanceTestHelper::CalculateEffectivePPM(correctChance, CAT_SPEED); + + // Buggy: 36% chance per swing → 21.6 procs/min instead of 6.0 + EXPECT_NEAR(buggyChance, 36.0f, 0.01f); + EXPECT_NEAR(correctChance, 10.0f, 0.01f); + EXPECT_NEAR(buggyEffectivePPM, 21.6f, 0.01f) + << "Bug: Cat Form Fiery Weapon procs 21.6 times/min instead of 6.0"; + EXPECT_NEAR(correctEffectivePPM, FIERY_PPM, 0.01f) + << "Fix: Cat Form Fiery Weapon should proc exactly 6.0 times/min"; +} + +TEST_F(SpellProcPPMTest, ShapeshiftBug_ItemSpellPath_AlreadyCorrect) +{ + // The item spell PPM path (line ~7308) already uses GetAttackTime. + // Verify that using GetAttackTime gives correct PPM for all forms. + constexpr float PPM = 1.0f; + + struct FormScenario + { + const char* name; + uint32 formSpeed; + }; + + FormScenario scenarios[] = { + {"Normal (3.6s weapon)", ProcChanceTestHelper::WEAPON_SPEED_STAFF}, + {"Cat Form", ProcChanceTestHelper::FORM_SPEED_CAT}, + {"Bear Form", ProcChanceTestHelper::FORM_SPEED_BEAR}, + }; + + for (auto const& scenario : scenarios) + { + _unit->SetAttackTime(0, scenario.formSpeed); + + float chance = ProcChanceTestHelper::CalculatePPMChance( + _unit->GetAttackTime(0), PPM); + float effectivePPM = ProcChanceTestHelper::CalculateEffectivePPM( + chance, scenario.formSpeed); + + EXPECT_NEAR(effectivePPM, PPM, 0.01f) + << scenario.name << ": GetAttackTime-based PPM should always match intended PPM"; + } +} diff --git a/src/test/server/game/Spells/SpellProcPipelineTest.cpp b/src/test/server/game/Spells/SpellProcPipelineTest.cpp new file mode 100644 index 000000000..3edc1cf98 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcPipelineTest.cpp @@ -0,0 +1,462 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcPipelineTest.cpp + * @brief End-to-end integration tests for the full proc pipeline + * + * Tests the complete proc execution flow: + * 1. Cooldown check (IsProcOnCooldown) + * 2. Chance calculation (CalcProcChance) + * 3. Roll check (rand_chance) + * 4. Cooldown application + * 5. Charge consumption (ConsumeProcCharges) + */ + +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "AuraStub.h" +#include "UnitStub.h" +#include "gtest/gtest.h" + +using namespace testing; +using namespace std::chrono_literals; + +class SpellProcPipelineTest : public ::testing::Test +{ +protected: + void SetUp() override + { + _scenario = std::make_unique(); + } + + std::unique_ptr _scenario; +}; + +// ============================================================================= +// Full Pipeline Flow Tests +// ============================================================================= + +TEST_F(SpellProcPipelineTest, FullFlow_BasicProc_100Percent) +{ + _scenario->WithAura(12345); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // 100% chance should always proc + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); +} + +TEST_F(SpellProcPipelineTest, FullFlow_BasicProc_0Percent) +{ + _scenario->WithAura(12345); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(0.0f) + .Build(); + + // 0% chance should never proc (when roll is > 0) + EXPECT_FALSE(_scenario->SimulateProc(procEntry, 50.0f)); +} + +TEST_F(SpellProcPipelineTest, FullFlow_WithCooldown) +{ + _scenario->WithAura(12345); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithCooldown(1000ms) + .Build(); + + // First proc succeeds + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + + // Second proc blocked by cooldown + EXPECT_FALSE(_scenario->SimulateProc(procEntry)); + + // Wait for cooldown + _scenario->AdvanceTime(1100ms); + + // Third proc succeeds + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); +} + +TEST_F(SpellProcPipelineTest, FullFlow_WithCharges) +{ + _scenario->WithAura(12345, 3); // 3 charges + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // First proc - 3 -> 2 charges + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_EQ(_scenario->GetAura()->GetCharges(), 2); + + // Second proc - 2 -> 1 charges + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_EQ(_scenario->GetAura()->GetCharges(), 1); + + // Third proc - 1 -> 0 charges, aura removed + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_EQ(_scenario->GetAura()->GetCharges(), 0); + EXPECT_TRUE(_scenario->GetAura()->IsRemoved()); +} + +TEST_F(SpellProcPipelineTest, FullFlow_WithStacks) +{ + _scenario->WithAura(12345, 0, 5); // 5 stacks, no charges + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_USE_STACKS_FOR_CHARGES) + .Build(); + + // Each proc consumes one stack + for (int i = 5; i > 0; --i) + { + EXPECT_EQ(_scenario->GetAura()->GetStackAmount(), i); + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + } + + EXPECT_EQ(_scenario->GetAura()->GetStackAmount(), 0); + EXPECT_TRUE(_scenario->GetAura()->IsRemoved()); +} + +// ============================================================================= +// Combined Feature Tests +// ============================================================================= + +TEST_F(SpellProcPipelineTest, Combined_ChargesAndCooldown) +{ + _scenario->WithAura(12345, 5); // 5 charges + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithCooldown(500ms) + .Build(); + + // First proc at t=0 + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_EQ(_scenario->GetAura()->GetCharges(), 4); + + // Blocked at t=0 (cooldown) + EXPECT_FALSE(_scenario->SimulateProc(procEntry)); + EXPECT_EQ(_scenario->GetAura()->GetCharges(), 4); + + // Wait and proc again at t=600ms + _scenario->AdvanceTime(600ms); + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_EQ(_scenario->GetAura()->GetCharges(), 3); + + // Blocked at t=600ms + EXPECT_FALSE(_scenario->SimulateProc(procEntry)); + EXPECT_EQ(_scenario->GetAura()->GetCharges(), 3); +} + +TEST_F(SpellProcPipelineTest, Combined_PPM_AndCooldown) +{ + _scenario->WithAura(12345); + _scenario->WithWeaponSpeed(0, 2500); // BASE_ATTACK = 2500ms + + auto procEntry = SpellProcEntryBuilder() + .WithProcsPerMinute(6.0f) // 25% with 2500ms weapon + .WithCooldown(1000ms) + .Build(); + + // First proc (roll 0 = always pass) + EXPECT_TRUE(_scenario->SimulateProc(procEntry, 0.0f)); + + // Blocked by cooldown even if roll would pass + EXPECT_FALSE(_scenario->SimulateProc(procEntry, 0.0f)); + + // Wait for cooldown + _scenario->AdvanceTime(1100ms); + + // Can proc again + EXPECT_TRUE(_scenario->SimulateProc(procEntry, 0.0f)); +} + +TEST_F(SpellProcPipelineTest, Combined_Level60Reduction_WithCooldown) +{ + _scenario->WithAura(12345); + _scenario->WithActorLevel(80); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .WithCooldown(1000ms) + .Build(); + + // Level 80: 30% * (1 - 20/30) = 10% effective chance + // Roll of 5 should pass + EXPECT_TRUE(_scenario->SimulateProc(procEntry, 5.0f)); + + // Blocked by cooldown + EXPECT_FALSE(_scenario->SimulateProc(procEntry, 5.0f)); + + // Wait and try again + _scenario->AdvanceTime(1100ms); + + // Roll of 15 should fail (10% chance) + EXPECT_FALSE(_scenario->SimulateProc(procEntry, 15.0f)); +} + +// ============================================================================= +// Real Spell Scenarios +// ============================================================================= + +TEST_F(SpellProcPipelineTest, Scenario_OmenOfClarity) +{ + // Omen of Clarity: 6 PPM, no cooldown, no charges + _scenario->WithAura(16864); // Omen of Clarity + _scenario->WithWeaponSpeed(0, 2500); // Staff + + auto procEntry = SpellProcEntryBuilder() + .WithProcsPerMinute(6.0f) // 25% with 2500ms + .Build(); + + // Simulate multiple hits + int procCount = 0; + for (int i = 0; i < 10; ++i) + { + // Roll values simulating ~25% success rate + float roll = (i % 4 == 0) ? 10.0f : 50.0f; + if (_scenario->SimulateProc(procEntry, roll)) + procCount++; + } + + // With deterministic rolls, should have 3 procs (indexes 0, 4, 8) + // But our test is roll > chance check, so roll 10 fails against 25% chance + // Actually roll 0 always passes, non-zero rolls check roll > chance +} + +TEST_F(SpellProcPipelineTest, Scenario_LeaderOfThePack) +{ + // Leader of the Pack: 6 second ICD + _scenario->WithAura(24932); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithCooldown(6000ms) + .Build(); + + // First crit - procs + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + + // Second crit at 1 second - blocked + _scenario->AdvanceTime(1000ms); + EXPECT_FALSE(_scenario->SimulateProc(procEntry)); + + // Third crit at 5 seconds - blocked + _scenario->AdvanceTime(4000ms); + EXPECT_FALSE(_scenario->SimulateProc(procEntry)); + + // Fourth crit at 6.1 seconds - allowed + _scenario->AdvanceTime(1100ms); + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); +} + +TEST_F(SpellProcPipelineTest, Scenario_ArtOfWar) +{ + // Art of War: 2 charges (typically) + _scenario->WithAura(53486, 2); // Art of War + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // First Exorcism - consumes charge + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_EQ(_scenario->GetAura()->GetCharges(), 1); + + // Second Exorcism - consumes last charge + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_EQ(_scenario->GetAura()->GetCharges(), 0); + EXPECT_TRUE(_scenario->GetAura()->IsRemoved()); +} + +TEST_F(SpellProcPipelineTest, Scenario_LightningShield) +{ + // Lightning Shield: 3 charges (orbs) + _scenario->WithAura(324, 3); // Lightning Shield Rank 1 + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // First hit - uses orb + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_EQ(_scenario->GetAura()->GetCharges(), 2); + + // Second hit - uses orb + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_EQ(_scenario->GetAura()->GetCharges(), 1); + + // Third hit - last orb, aura removed + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_TRUE(_scenario->GetAura()->IsRemoved()); +} + +TEST_F(SpellProcPipelineTest, Scenario_WanderingPlague) +{ + // Wandering Plague: 1 second ICD + _scenario->WithAura(49217); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithCooldown(1000ms) + .Build(); + + // First tick procs + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + + // Rapid ticks blocked + _scenario->AdvanceTime(200ms); + EXPECT_FALSE(_scenario->SimulateProc(procEntry)); + + _scenario->AdvanceTime(200ms); + EXPECT_FALSE(_scenario->SimulateProc(procEntry)); + + _scenario->AdvanceTime(200ms); + EXPECT_FALSE(_scenario->SimulateProc(procEntry)); + + // After 1 second total, can proc again + _scenario->AdvanceTime(600ms); + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); +} + +// ============================================================================= +// Edge Cases +// ============================================================================= + +TEST_F(SpellProcPipelineTest, EdgeCase_NoAura_NoProcPossible) +{ + // Don't set up aura + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + EXPECT_FALSE(_scenario->SimulateProc(procEntry)); +} + +TEST_F(SpellProcPipelineTest, EdgeCase_ZeroCooldown_AllowsRapidProcs) +{ + _scenario->WithAura(12345); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithCooldown(0ms) + .Build(); + + // Multiple rapid procs should all succeed + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); +} + +TEST_F(SpellProcPipelineTest, EdgeCase_VeryLongCooldown) +{ + _scenario->WithAura(12345); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .WithCooldown(300000ms) // 5 minute cooldown + .Build(); + + // First proc + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + + // Blocked even after 4 minutes + _scenario->AdvanceTime(240000ms); + EXPECT_FALSE(_scenario->SimulateProc(procEntry)); + + // Allowed after 5 minutes + _scenario->AdvanceTime(60001ms); + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); +} + +TEST_F(SpellProcPipelineTest, EdgeCase_ManyCharges) +{ + _scenario->WithAura(12345, 100); // 100 charges + + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // Consume all charges + for (int i = 100; i > 0; --i) + { + EXPECT_EQ(_scenario->GetAura()->GetCharges(), i); + EXPECT_TRUE(_scenario->SimulateProc(procEntry)); + } + + EXPECT_TRUE(_scenario->GetAura()->IsRemoved()); +} + +// ============================================================================= +// Actor Configuration Tests +// ============================================================================= + +TEST_F(SpellProcPipelineTest, ActorLevel_AffectsProcChance) +{ + _scenario->WithAura(12345); + _scenario->WithActorLevel(60); + + auto procEntry = SpellProcEntryBuilder() + .WithChance(30.0f) + .WithAttributesMask(PROC_ATTR_REDUCE_PROC_60) + .Build(); + + // At level 60, full 30% chance + // Roll of 25 should pass + EXPECT_TRUE(_scenario->SimulateProc(procEntry, 25.0f)); + + // Reset + _scenario->GetAura()->ResetProcCooldown(); + + // Change to level 80 + _scenario->WithActorLevel(80); + + // At level 80, only 10% chance + // Roll of 25 should fail + EXPECT_FALSE(_scenario->SimulateProc(procEntry, 25.0f)); +} + +TEST_F(SpellProcPipelineTest, WeaponSpeed_AffectsPPMChance) +{ + _scenario->WithAura(12345); + + auto procEntry = SpellProcEntryBuilder() + .WithProcsPerMinute(6.0f) + .Build(); + + // Fast dagger (1400ms): 14% chance + _scenario->WithWeaponSpeed(0, 1400); + // Roll of 10 should pass (< 14%) + EXPECT_TRUE(_scenario->SimulateProc(procEntry, 10.0f)); + + // Reset cooldown + _scenario->GetAura()->ResetProcCooldown(); + + // Slow 2H (3300ms): 33% chance + _scenario->WithWeaponSpeed(0, 3300); + // Roll of 30 should pass (< 33%) + EXPECT_TRUE(_scenario->SimulateProc(procEntry, 30.0f)); +} diff --git a/src/test/server/game/Spells/SpellProcSpellTypeMaskTest.cpp b/src/test/server/game/Spells/SpellProcSpellTypeMaskTest.cpp new file mode 100644 index 000000000..063075de0 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcSpellTypeMaskTest.cpp @@ -0,0 +1,226 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "AuraScriptTestFramework.h" +#include "SpellMgr.h" +#include "gtest/gtest.h" + +/** + * @brief Tests for SpellTypeMask calculation based on proc phase + * + * These tests verify that the proc system correctly calculates SpellTypeMask + * for different proc phases. This is critical because: + * - CAST phase: No damage/heal has occurred yet + * - HIT phase: Damage/heal info is available + * - FINISH phase: damageInfo may be null even for damage spells + * + * Regression test for: FINISH phase was incorrectly using NO_DMG_HEAL when + * damageInfo was null, breaking procs like Killing Machine (51124) that + * require SpellTypeMask=DAMAGE and SpellPhaseMask=FINISH. + */ +class SpellProcSpellTypeMaskTest : public AuraScriptProcTestFixture +{ +protected: + void SetUp() override + { + AuraScriptProcTestFixture::SetUp(); + } + + /** + * @brief Calculate spellTypeMask the same way ProcSkillsAndAuras does + * + * This mirrors the logic in Unit::ProcSkillsAndAuras to allow unit testing + * of the spellTypeMask calculation without needing full Unit objects. + */ + static uint32 CalculateSpellTypeMask(uint32 procPhase, DamageInfo* damageInfo, HealInfo* healInfo, bool hasSpellInfo) + { + uint32 spellTypeMask = 0; + if (procPhase == PROC_SPELL_PHASE_CAST || procPhase == PROC_SPELL_PHASE_FINISH) + { + // At CAST phase, no damage/heal has occurred yet - use MASK_ALL + // At FINISH phase, damageInfo may be null but spell did do damage - use MASK_ALL + spellTypeMask = PROC_SPELL_TYPE_MASK_ALL; + } + else if (healInfo && healInfo->GetHeal()) + spellTypeMask = PROC_SPELL_TYPE_HEAL; + else if (damageInfo && damageInfo->GetDamage()) + spellTypeMask = PROC_SPELL_TYPE_DAMAGE; + else if (hasSpellInfo) + spellTypeMask = PROC_SPELL_TYPE_NO_DMG_HEAL; + + return spellTypeMask; + } +}; + +// ============================================================================= +// SpellTypeMask Calculation Tests +// ============================================================================= + +TEST_F(SpellProcSpellTypeMaskTest, CastPhase_UsesMaskAll) +{ + // CAST phase should use MASK_ALL regardless of damage/heal info + uint32 result = CalculateSpellTypeMask(PROC_SPELL_PHASE_CAST, nullptr, nullptr, true); + EXPECT_EQ(result, PROC_SPELL_TYPE_MASK_ALL); +} + +TEST_F(SpellProcSpellTypeMaskTest, FinishPhase_UsesMaskAll_EvenWithNullDamageInfo) +{ + // FINISH phase should use MASK_ALL even when damageInfo is null + // This is the key regression test - previously returned NO_DMG_HEAL + uint32 result = CalculateSpellTypeMask(PROC_SPELL_PHASE_FINISH, nullptr, nullptr, true); + EXPECT_EQ(result, PROC_SPELL_TYPE_MASK_ALL); + + // Verify it includes DAMAGE type (required for procs like Killing Machine) + EXPECT_TRUE(result & PROC_SPELL_TYPE_DAMAGE); +} + +TEST_F(SpellProcSpellTypeMaskTest, HitPhase_WithDamage_UsesDamageType) +{ + auto* spellInfo = CreateSpellInfo(12345, 15, 0); + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_FROST, SPELL_DIRECT_DAMAGE); + + uint32 result = CalculateSpellTypeMask(PROC_SPELL_PHASE_HIT, &damageInfo, nullptr, true); + EXPECT_EQ(result, PROC_SPELL_TYPE_DAMAGE); +} + +TEST_F(SpellProcSpellTypeMaskTest, HitPhase_WithHeal_UsesHealType) +{ + auto* spellInfo = CreateSpellInfo(12345, 15, 0); + HealInfo healInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_HOLY); + + uint32 result = CalculateSpellTypeMask(PROC_SPELL_PHASE_HIT, nullptr, &healInfo, true); + EXPECT_EQ(result, PROC_SPELL_TYPE_HEAL); +} + +TEST_F(SpellProcSpellTypeMaskTest, HitPhase_NoDamageNoHeal_UsesNoDmgHeal) +{ + // HIT phase with no damage/heal info should use NO_DMG_HEAL + uint32 result = CalculateSpellTypeMask(PROC_SPELL_PHASE_HIT, nullptr, nullptr, true); + EXPECT_EQ(result, PROC_SPELL_TYPE_NO_DMG_HEAL); +} + +// ============================================================================= +// Killing Machine Regression Test +// ============================================================================= + +/** + * @brief Regression test for Killing Machine (51124) proc consumption + * + * Killing Machine has: + * - SpellTypeMask = 1 (PROC_SPELL_TYPE_DAMAGE) + * - SpellPhaseMask = 4 (PROC_SPELL_PHASE_FINISH) + * + * When Icy Touch is cast, the FINISH phase event must have a spellTypeMask + * that includes DAMAGE for the proc to fire and consume the buff. + * + * The bug was: FINISH phase calculated spellTypeMask as NO_DMG_HEAL (4) + * because damageInfo was null, causing the proc check to fail. + */ +TEST_F(SpellProcSpellTypeMaskTest, KillingMachine_FinishPhase_MatchesDamageTypeMask) +{ + // Killing Machine spell_proc entry + auto procEntry = SpellProcEntryBuilder() + .WithSpellFamilyName(15) // SPELLFAMILY_DEATHKNIGHT + .WithSpellFamilyMask(flag96(2, 6, 0)) // Icy Touch, Frost Strike, Howling Blast + .WithProcFlags(PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_FINISH) + .WithAttributesMask(PROC_ATTR_REQ_SPELLMOD) + .WithCharges(1) + .Build(); + + // Calculate what spellTypeMask FINISH phase would produce + // (simulating Spell.cpp calling ProcSkillsAndAuras with nullptr damageInfo) + uint32 finishPhaseSpellTypeMask = CalculateSpellTypeMask(PROC_SPELL_PHASE_FINISH, nullptr, nullptr, true); + + // Verify the calculated mask includes DAMAGE type + EXPECT_TRUE(finishPhaseSpellTypeMask & PROC_SPELL_TYPE_DAMAGE) + << "FINISH phase spellTypeMask must include PROC_SPELL_TYPE_DAMAGE for Killing Machine to work"; + + // Verify that the proc entry's SpellTypeMask requirement is satisfied + EXPECT_TRUE(finishPhaseSpellTypeMask & procEntry.SpellTypeMask) + << "FINISH phase spellTypeMask (" << finishPhaseSpellTypeMask + << ") must match Killing Machine's SpellTypeMask requirement (" << procEntry.SpellTypeMask << ")"; +} + +/** + * @brief Verify FINISH phase works with actual CanSpellTriggerProcOnEvent + * + * This test verifies the full integration: when we pass the correctly + * calculated spellTypeMask to CanSpellTriggerProcOnEvent, Killing Machine + * style procs should work. + */ +TEST_F(SpellProcSpellTypeMaskTest, KillingMachine_FullIntegration_ProcTriggers) +{ + // Killing Machine spell_proc entry + auto procEntry = SpellProcEntryBuilder() + .WithSpellFamilyName(15) // SPELLFAMILY_DEATHKNIGHT + .WithSpellFamilyMask(flag96(2, 0, 0)) // Icy Touch + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_FINISH) + .Build(); + + // Create Icy Touch spell info (SpellFamilyFlags = [2, 0, 0]) + auto* icyTouchSpell = CreateSpellInfo(49909, 15, 2); // DK family, mask0=2 + DamageInfo damageInfo(nullptr, nullptr, 100, icyTouchSpell, SPELL_SCHOOL_MASK_FROST, SPELL_DIRECT_DAMAGE); + + // Create event with FINISH phase and MASK_ALL (as the fix provides) + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithHitMask(PROC_HIT_NORMAL) + .WithSpellTypeMask(PROC_SPELL_TYPE_MASK_ALL) // Fixed behavior + .WithSpellPhaseMask(PROC_SPELL_PHASE_FINISH) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + << "Killing Machine style proc should trigger on FINISH phase with MASK_ALL spellTypeMask"; +} + +/** + * @brief Verify the bug scenario - FINISH phase with NO_DMG_HEAL fails + * + * This test documents the bug behavior: if FINISH phase incorrectly uses + * NO_DMG_HEAL spellTypeMask, Killing Machine style procs fail. + */ +TEST_F(SpellProcSpellTypeMaskTest, KillingMachine_BugScenario_NoDmgHealFails) +{ + auto procEntry = SpellProcEntryBuilder() + .WithSpellFamilyName(15) + .WithSpellFamilyMask(flag96(2, 0, 0)) + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) // Requires DAMAGE + .WithSpellPhaseMask(PROC_SPELL_PHASE_FINISH) + .Build(); + + auto* icyTouchSpell = CreateSpellInfo(49909, 15, 2); + DamageInfo damageInfo(nullptr, nullptr, 100, icyTouchSpell, SPELL_SCHOOL_MASK_FROST, SPELL_DIRECT_DAMAGE); + + // Simulate the bug: FINISH phase with NO_DMG_HEAL (the old broken behavior) + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithHitMask(PROC_HIT_NORMAL) + .WithSpellTypeMask(PROC_SPELL_TYPE_NO_DMG_HEAL) // Bug: wrong mask + .WithSpellPhaseMask(PROC_SPELL_PHASE_FINISH) + .WithDamageInfo(&damageInfo) + .Build(); + + // This should fail - documenting the bug behavior + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)) + << "With NO_DMG_HEAL spellTypeMask, DAMAGE-requiring procs should NOT trigger (this was the bug)"; +} diff --git a/src/test/server/game/Spells/SpellProcTest.cpp b/src/test/server/game/Spells/SpellProcTest.cpp new file mode 100644 index 000000000..7bf7fe869 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcTest.cpp @@ -0,0 +1,903 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ProcEventInfoHelper.h" +#include "SpellInfoTestHelper.h" +#include "SpellMgr.h" +#include "WorldMock.h" +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +using namespace testing; + +/** + * @brief Test fixture for SpellMgr proc tests + * + * Tests the CanSpellTriggerProcOnEvent function and related proc logic. + */ +class SpellProcTest : public ::testing::Test +{ +protected: + void SetUp() override + { + _originalWorld = sWorld.release(); + _worldMock = new NiceMock(); + sWorld.reset(_worldMock); + + static std::string emptyString; + ON_CALL(*_worldMock, GetDataPath()).WillByDefault(ReturnRef(emptyString)); + } + + void TearDown() override + { + IWorld* currentWorld = sWorld.release(); + delete currentWorld; + _worldMock = nullptr; + + sWorld.reset(_originalWorld); + _originalWorld = nullptr; + + // Clean up any SpellInfo objects we created + for (auto* spellInfo : _spellInfos) + delete spellInfo; + _spellInfos.clear(); + } + + // Helper to create and track SpellInfo objects for cleanup + SpellInfo* CreateSpellInfo(uint32 id = 1, uint32 familyName = 0, + uint32 familyFlag0 = 0, uint32 familyFlag1 = 0, uint32 familyFlag2 = 0) + { + auto* spellInfo = SpellInfoBuilder() + .WithId(id) + .WithSpellFamilyName(familyName) + .WithSpellFamilyFlags(familyFlag0, familyFlag1, familyFlag2) + .Build(); + _spellInfos.push_back(spellInfo); + return spellInfo; + } + + IWorld* _originalWorld = nullptr; + NiceMock* _worldMock = nullptr; + std::vector _spellInfos; +}; + +// ============================================================================= +// ProcFlags Tests - Basic proc flag matching +// ============================================================================= + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_ProcFlagsMatch) +{ + // Setup: Create a proc entry that triggers on melee auto attacks + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .Build(); + + // Create ProcEventInfo with matching type mask + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + // Should match + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_ProcFlagsNoMatch) +{ + // Setup: Create a proc entry that triggers on melee auto attacks + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .Build(); + + // Create ProcEventInfo with different type mask (ranged instead of melee) + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_RANGED_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + // Should not match + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_MultipleProcFlagsPartialMatch) +{ + // Setup: Create a proc entry that triggers on melee OR ranged + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_RANGED_AUTO_ATTACK) + .Build(); + + // Create ProcEventInfo with only melee + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + // Should match (partial match is OK - it's an OR relationship) + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +// ============================================================================= +// Kill/Death Event Tests - These always trigger regardless of other conditions +// ============================================================================= + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_KillEventAlwaysProcs) +{ + // Setup: Create a proc entry for kill events + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_KILL) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_KILL) + .Build(); + + // Kill events should always trigger + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_KilledEventAlwaysProcs) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_KILLED) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_KILLED) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_DeathEventAlwaysProcs) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DEATH) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DEATH) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +// ============================================================================= +// HitMask Tests - Test hit type filtering +// ============================================================================= + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_HitMaskCriticalMatch) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_CRITICAL) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_CRITICAL) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_HitMaskCriticalNoMatch) +{ + // Proc entry requires critical hit + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_CRITICAL) + .Build(); + + // Event is a normal hit + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_HitMaskDefaultForDone) +{ + // When HitMask is 0, default for DONE procs is NORMAL | CRITICAL | ABSORB + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(0) // Default + .Build(); + + // Normal hit should work with default mask + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_HitMaskDefaultForTaken) +{ + // When HitMask is 0, default for TAKEN procs is NORMAL | CRITICAL + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(0) // Default + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_CRITICAL) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_HitMaskMissNoMatch) +{ + // Miss should not trigger default hit mask + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(0) // Default allows NORMAL | CRITICAL | ABSORB + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_MISS) + .Build(); + + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_HitMaskDodge) +{ + // Explicitly require dodge + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_DODGE) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_DODGE) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_HitMaskParry) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_PARRY) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_PARRY) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_HitMaskBlock) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_BLOCK) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_BLOCK) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +// ============================================================================= +// SpellTypeMask Tests - Damage vs Heal vs Other +// ============================================================================= + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellTypeMaskDamage) +{ + auto* spellInfo = CreateSpellInfo(1); + + // Create DamageInfo for the test + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellTypeMaskHeal) +{ + auto* spellInfo = CreateSpellInfo(1); + + // Create HealInfo with the spell info so GetSpellInfo() works + HealInfo healInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_HOLY); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellTypeMask(PROC_SPELL_TYPE_HEAL) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellTypeMask(PROC_SPELL_TYPE_HEAL) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithHealInfo(&healInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellTypeMaskNoMatch) +{ + // Proc requires heal but event is damage + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellTypeMask(PROC_SPELL_TYPE_HEAL) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) // Mismatch + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +// ============================================================================= +// SpellPhaseMask Tests - Cast vs Hit vs Finish +// ============================================================================= + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellPhaseMaskCast) +{ + auto* spellInfo = CreateSpellInfo(1); + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_CAST) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_CAST) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellPhaseMaskHit) +{ + auto* spellInfo = CreateSpellInfo(1); + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellPhaseMaskNoMatch) +{ + auto* spellInfo = CreateSpellInfo(1); + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + + // Proc requires cast phase + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_CAST) + .Build(); + + // Event is hit phase + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_CastPhaseWithExplicitHitMaskCrit) +{ + // Nature's Grace scenario: CAST phase + explicit HitMask for crit + // Crit is pre-calculated for travel-time spells + auto* spellInfo = CreateSpellInfo(1); + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_NATURE, SPELL_DIRECT_DAMAGE); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_CAST) + .WithHitMask(PROC_HIT_CRITICAL) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_CAST) + .WithHitMask(PROC_HIT_CRITICAL) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_CastPhaseWithExplicitHitMaskNoCrit) +{ + // CAST phase + explicit HitMask requires crit, but spell didn't crit + auto* spellInfo = CreateSpellInfo(1); + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_NATURE, SPELL_DIRECT_DAMAGE); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_CAST) + .WithHitMask(PROC_HIT_CRITICAL) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_CAST) + .WithHitMask(PROC_HIT_NORMAL) // No crit + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_CastPhaseWithDefaultHitMask) +{ + // CAST phase + HitMask=0 should skip HitMask check (old behavior) + auto* spellInfo = CreateSpellInfo(1); + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_NATURE, SPELL_DIRECT_DAMAGE); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_CAST) + .WithHitMask(0) // Default - no explicit HitMask + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_CAST) + .WithHitMask(PROC_HIT_NORMAL) // Doesn't matter - HitMask check skipped + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +// ============================================================================= +// Combined Condition Tests +// ============================================================================= + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_AllConditionsMatch) +{ + auto* spellInfo = CreateSpellInfo(1); + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_CRITICAL) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_CRITICAL) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_OneConditionFails) +{ + auto* spellInfo = CreateSpellInfo(1); + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_CRITICAL) // Requires crit + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) // But we got normal hit + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +// ============================================================================= +// Edge Cases +// ============================================================================= + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_ZeroProcFlags) +{ + // Zero proc flags should never match anything + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(0) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_PeriodicDamage) +{ + auto* spellInfo = CreateSpellInfo(1); + DamageInfo damageInfo(nullptr, nullptr, 50, spellInfo, SPELL_SCHOOL_MASK_SHADOW, SPELL_DIRECT_DAMAGE); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_PERIODIC) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_PERIODIC) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_TakenDamage) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_TAKEN_DAMAGE) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_TAKEN_DAMAGE) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +// ============================================================================= +// SpellFamilyName/SpellFamilyFlags Tests - Class-specific proc matching +// ============================================================================= + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellFamilyNameMatch) +{ + // Create a Mage spell (SpellFamilyName = SPELLFAMILY_MAGE = 3) + auto* spellInfo = SpellInfoBuilder() + .WithId(133) // Fireball + .WithSpellFamilyName(SPELLFAMILY_MAGE) + .Build(); + _spellInfos.push_back(spellInfo); + + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + + // Proc entry requires Mage spells + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellFamilyName(SPELLFAMILY_MAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellFamilyNameNoMatch) +{ + // Create a Warlock spell but proc requires Mage + auto* spellInfo = SpellInfoBuilder() + .WithId(686) // Shadow Bolt + .WithSpellFamilyName(SPELLFAMILY_WARLOCK) + .Build(); + _spellInfos.push_back(spellInfo); + + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_SHADOW, SPELL_DIRECT_DAMAGE); + + // Proc entry requires Mage spells + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellFamilyName(SPELLFAMILY_MAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellFamilyFlagsMatch) +{ + // Create a Paladin Holy Light spell with specific family flags + auto* spellInfo = SpellInfoBuilder() + .WithId(635) // Holy Light + .WithSpellFamilyName(SPELLFAMILY_PALADIN) + .WithSpellFamilyFlags(0x80000000, 0, 0) // Example flag for Holy Light + .Build(); + _spellInfos.push_back(spellInfo); + + HealInfo healInfo(nullptr, nullptr, 500, spellInfo, SPELL_SCHOOL_MASK_HOLY); + + // Proc entry requires specific Paladin family flag + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellFamilyName(SPELLFAMILY_PALADIN) + .WithSpellFamilyMask(flag96(0x80000000, 0, 0)) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithHealInfo(&healInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellFamilyFlagsNoMatch) +{ + // Create a Paladin spell with different family flags + auto* spellInfo = SpellInfoBuilder() + .WithId(19750) // Flash of Light + .WithSpellFamilyName(SPELLFAMILY_PALADIN) + .WithSpellFamilyFlags(0x40000000, 0, 0) // Different flag + .Build(); + _spellInfos.push_back(spellInfo); + + HealInfo healInfo(nullptr, nullptr, 300, spellInfo, SPELL_SCHOOL_MASK_HOLY); + + // Proc entry requires different family flag + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellFamilyName(SPELLFAMILY_PALADIN) + .WithSpellFamilyMask(flag96(0x80000000, 0, 0)) // Wants Holy Light flag + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithHealInfo(&healInfo) + .Build(); + + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellFamilyNameZeroAcceptsAll) +{ + // When SpellFamilyName is 0, it should accept any spell family + auto* spellInfo = SpellInfoBuilder() + .WithId(100) + .WithSpellFamilyName(SPELLFAMILY_DRUID) + .Build(); + _spellInfos.push_back(spellInfo); + + DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_NATURE, SPELL_DIRECT_DAMAGE); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellFamilyName(0) // Accept any family + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SpellFamilyFlagsZeroAcceptsAll) +{ + // When SpellFamilyMask is 0, it should accept any flags within the family + auto* spellInfo = SpellInfoBuilder() + .WithId(100) + .WithSpellFamilyName(SPELLFAMILY_PRIEST) + .WithSpellFamilyFlags(0x12345678, 0xABCDEF01, 0x87654321) // Any flags + .Build(); + _spellInfos.push_back(spellInfo); + + HealInfo healInfo(nullptr, nullptr, 200, spellInfo, SPELL_SCHOOL_MASK_HOLY); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellFamilyName(SPELLFAMILY_PRIEST) + .WithSpellFamilyMask(flag96(0, 0, 0)) // Accept any flags + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithHealInfo(&healInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +// ============================================================================= +// Real-world Spell Proc Examples +// ============================================================================= + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_HotStreakScenario) +{ + // Hot Streak: Proc on critical damage spell from Mage + auto* fireballSpell = SpellInfoBuilder() + .WithId(133) + .WithSpellFamilyName(SPELLFAMILY_MAGE) + .WithSpellFamilyFlags(0x00000001, 0, 0) // Fireball flag + .Build(); + _spellInfos.push_back(fireballSpell); + + DamageInfo damageInfo(nullptr, nullptr, 1000, fireballSpell, SPELL_SCHOOL_MASK_FIRE, SPELL_DIRECT_DAMAGE); + + // Hot Streak proc entry - triggers on fire spell crits + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellFamilyName(SPELLFAMILY_MAGE) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_CRITICAL) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_CRITICAL) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_IlluminationScenario) +{ + // Illumination: Proc on critical heals from Paladin + auto* holyLightSpell = SpellInfoBuilder() + .WithId(635) + .WithSpellFamilyName(SPELLFAMILY_PALADIN) + .WithSpellFamilyFlags(0x80000000, 0, 0) + .Build(); + _spellInfos.push_back(holyLightSpell); + + HealInfo healInfo(nullptr, nullptr, 2000, holyLightSpell, SPELL_SCHOOL_MASK_HOLY); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellFamilyName(SPELLFAMILY_PALADIN) + .WithSpellTypeMask(PROC_SPELL_TYPE_HEAL) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_CRITICAL) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellTypeMask(PROC_SPELL_TYPE_HEAL) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_CRITICAL) + .WithHealInfo(&healInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SecondWindScenario) +{ + // Second Wind: Proc when stunned/immobilized (taken hit with dodge/parry) + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS) + .WithHitMask(PROC_HIT_DODGE | PROC_HIT_PARRY) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_DODGE) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} + +TEST_F(SpellProcTest, CanSpellTriggerProcOnEvent_SwordAndBoardScenario) +{ + // Sword and Board: Proc on Devastate/Revenge (block effects) + auto* devastateSpell = SpellInfoBuilder() + .WithId(20243) // Devastate + .WithSpellFamilyName(SPELLFAMILY_WARRIOR) + .WithSpellFamilyFlags(0x00000000, 0x00000000, 0x00000100) // Devastate flag + .Build(); + _spellInfos.push_back(devastateSpell); + + DamageInfo damageInfo(nullptr, nullptr, 500, devastateSpell, SPELL_SCHOOL_MASK_NORMAL, SPELL_DIRECT_DAMAGE); + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS) + .WithSpellFamilyName(SPELLFAMILY_WARRIOR) + .WithSpellFamilyMask(flag96(0, 0, 0x100)) // Devastate flag + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + auto eventInfo = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .WithDamageInfo(&damageInfo) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo)); +} diff --git a/src/test/server/game/Spells/SpellProcTestData.h b/src/test/server/game/Spells/SpellProcTestData.h new file mode 100644 index 000000000..c0915b2ae --- /dev/null +++ b/src/test/server/game/Spells/SpellProcTestData.h @@ -0,0 +1,1020 @@ +/* + * This file is part of the AzerothCore Project. + * AUTO-GENERATED - DO NOT EDIT + * Generated by generate_spell_proc_data.py + */ + +#ifndef AZEROTHCORE_SPELL_PROC_TEST_DATA_H +#define AZEROTHCORE_SPELL_PROC_TEST_DATA_H + +#include "SpellMgr.h" +#include +#include + +/** + * @brief Test data entry from spell_proc table with DBC comparison data + */ +struct SpellProcTestEntry +{ + // spell_proc table fields + int32_t SpellId; + uint32_t SchoolMask; + uint32_t SpellFamilyName; + uint32_t SpellFamilyMask0; + uint32_t SpellFamilyMask1; + uint32_t SpellFamilyMask2; + uint32_t ProcFlags; + uint32_t SpellTypeMask; + uint32_t SpellPhaseMask; + uint32_t HitMask; + uint32_t AttributesMask; + uint32_t Cooldown; + float Chance; + float ProcsPerMinute; + uint8_t Charges; + uint8_t DisableEffectsMask; + + // DBC fields for comparison (from Spell.dbc) + uint32_t DBC_ProcFlags; + uint32_t DBC_ProcChance; + uint32_t DBC_ProcCharges; + + /** + * @brief Convert to SpellProcEntry for testing + */ + SpellProcEntry ToSpellProcEntry() const + { + SpellProcEntry entry = {}; + entry.SchoolMask = SchoolMask; + entry.SpellFamilyName = SpellFamilyName; + entry.SpellFamilyMask[0] = SpellFamilyMask0; + entry.SpellFamilyMask[1] = SpellFamilyMask1; + entry.SpellFamilyMask[2] = SpellFamilyMask2; + entry.ProcFlags = ProcFlags; + entry.SpellTypeMask = SpellTypeMask; + entry.SpellPhaseMask = SpellPhaseMask; + entry.HitMask = HitMask; + entry.AttributesMask = AttributesMask; + entry.Cooldown = Milliseconds(Cooldown); + entry.Chance = Chance; + entry.ProcsPerMinute = ProcsPerMinute; + entry.Charges = Charges; + entry.DisableEffectsMask = DisableEffectsMask; + return entry; + } + + /** + * @brief Check if this entry adds value beyond DBC defaults + * + * Returns true if the spell_proc entry provides functionality + * not available in Spell.dbc alone. + */ + bool AddsValueBeyondDBC() const + { + // New fields not in DBC (always add value) + if (ProcsPerMinute > 0) return true; + if (Cooldown > 0) return true; + if (SpellTypeMask != 0) return true; + if (SpellPhaseMask != 0) return true; + if (HitMask != 0) return true; + if (DisableEffectsMask != 0) return true; + if (AttributesMask != 0) return true; + if (SchoolMask != 0) return true; + if (SpellFamilyMask0 != 0 || SpellFamilyMask1 != 0 || SpellFamilyMask2 != 0) return true; + + // Override fields (add value if different from DBC) + if (ProcFlags != 0 && ProcFlags != DBC_ProcFlags) return true; + if (Chance != 0 && static_cast(Chance) != DBC_ProcChance) return true; + if (Charges != 0 && Charges != DBC_ProcCharges) return true; + + return false; + } + + /** + * @brief Check if DBC values are available for this entry + */ + bool HasDBCData() const + { + return DBC_ProcFlags != 0 || DBC_ProcChance != 0 || DBC_ProcCharges != 0; + } +}; + +/** + * @brief All spell_proc entries from the database + * Total: 869 entries + */ +inline std::vector GetAllSpellProcTestEntries() +{ + return { + { -66799, 0, 15, 4194304, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -65661, 0, 15, 4194321, 537001988, 0, 16, 1, 2, 0, 0, 0, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -64127, 0, 6, 1, 1, 0, 0, 6, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -63730, 0, 6, 2048, 4, 0, 0, 0, 2, 0, 0, 100, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -63373, 0, 11, 2147483648, 0, 0, 65536, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -63156, 0, 5, 1, 192, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -62764, 0, 9, 0, 268435456, 0, 65536, 4, 2, 0, 0, 0, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -61846, 0, 0, 0, 0, 0, 64, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -61680, 0, 9, 0, 268435456, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -59887, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -59088, 0, 4, 0, 2, 0, 1024, 4, 4, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -58872, 0, 0, 0, 0, 0, 0, 1, 0, 8259, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -57878, 0, 0, 0, 0, 0, 0, 1, 0, 16, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -57470, 0, 6, 1, 0, 0, 0, 0, 2, 0, 0, 15000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -56636, 0, 4, 32, 0, 0, 0, 0, 2, 0, 0, 5800, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -56342, 0, 9, 24, 134217728, 147456, 0, 0, 4, 0, 2, 22000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -55666, 0, 15, 1, 134217728, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -54747, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -54639, 0, 15, 4194304, 65536, 0, 0, 0, 2, 0, 0, 100, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53709, 2, 10, 16384, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53695, 0, 10, 8388608, 0, 8, 16, 5, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53671, 0, 10, 8388608, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53583, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53569, 0, 10, 1075838976, 65536, 0, 0, 3, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53551, 0, 10, 4096, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53527, 1, 10, 0, 0, 4, 1024, 0, 2, 1, 0, 0, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53501, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53486, 0, 10, 8388608, 163840, 0, 0, 0, 2, 2, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53380, 0, 10, 8388608, 163840, 0, 0, 1, 2, 2, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53290, 0, 9, 2048, 1, 512, 0, 1, 2, 2, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53256, 0, 9, 2048, 8388609, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53234, 0, 9, 131072, 1, 1, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53228, 0, 9, 32, 16777216, 0, 0, 4, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53221, 0, 9, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53215, 0, 9, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -53178, 0, 9, 0, 268435456, 0, 65536, 4, 2, 0, 0, 0, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -52795, 0, 6, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -52127, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 3500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51940, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51692, 0, 8, 516, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51682, 0, 8, 0, 524288, 0, 0, 4, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51672, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51664, 0, 8, 131072, 8, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51634, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51627, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51625, 0, 8, 268476416, 0, 0, 0, 5, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51562, 0, 11, 256, 0, 16, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51556, 0, 11, 192, 0, 16, 0, 2, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51525, 0, 11, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51523, 0, 11, 0, 1, 0, 65536, 0, 2, 0, 0, 0, 50.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51521, 0, 11, 0, 16777216, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -51459, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -50880, 0, 15, 0, 67108864, 0, 0, 0, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49467, 0, 15, 16, 131072, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49223, 0, 15, 17, 134348800, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49219, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49217, 0, 15, 0, 0, 2, 0, 0, 2, 0, 0, 500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49208, 0, 15, 4194304, 65536, 0, 0, 0, 2, 0, 0, 100, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49200, 126, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49188, 0, 15, 0, 131072, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49182, 0, 15, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49149, 0, 15, 6, 131074, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49027, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 20000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49018, 0, 15, 20971520, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49015, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -49004, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -48988, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -48979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -48539, 0, 7, 16, 67108864, 0, 262144, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -48516, 0, 7, 5, 0, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -48506, 0, 7, 5, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -48496, 0, 7, 96, 33554434, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -48483, 0, 7, 34816, 1088, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -47580, 0, 6, 0, 0, 64, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -47569, 0, 6, 16384, 0, 0, 16384, 4, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -47516, 0, 6, 6144, 65536, 0, 0, 0, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -47509, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -47263, 32, 5, 0, 0, 0, 0, 0, 2, 2, 0, 20000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -47258, 0, 5, 0, 8388608, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -47245, 0, 5, 2, 0, 0, 262144, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -47230, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -47201, 0, 5, 16393, 262144, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -47195, 0, 5, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -46951, 0, 4, 1024, 64, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -46945, 0, 4, 0, 65536, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -46913, 0, 4, 64, 1028, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -46867, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -46854, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -45234, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -44557, 0, 3, 32, 0, 0, 0, 0, 2, 0, 0, 6000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -44546, 0, 3, 736, 4096, 0, 69632, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -44449, 0, 3, 551686775, 102472, 0, 0, 0, 2, 2, 0, 8, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -44445, 0, 3, 19, 69632, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -44442, 0, 3, 8388608, 64, 0, 0, 0, 2, 0, 0, 1000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -44404, 0, 3, 536870945, 36864, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -41635, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -35541, 0, 0, 0, 0, 0, 8388608, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -35100, 0, 9, 4096, 0, 1, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -34950, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -34935, 0, 0, 0, 0, 0, 0, 1, 0, 1027, 0, 8000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -34914, 0, 6, 8192, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -34753, 0, 6, 6144, 4, 4096, 0, 0, 2, 2, 2, 1, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -34500, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -34497, 0, 9, 395264, 8388609, 513, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -33881, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -33191, 0, 6, 32768, 1024, 64, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -33150, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 6000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -33142, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -33076, 0, 0, 0, 0, 0, 664232, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -32385, 0, 5, 1, 262144, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -31876, 0, 10, 8388608, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -31871, 0, 10, 16, 0, 0, 16384, 4, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -31833, 0, 10, 2147483648, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -31785, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -31656, 4, 3, 134217728, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -31641, 0, 0, 0, 0, 0, 680, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -31571, 0, 3, 0, 34, 0, 16384, 7, 4, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -31569, 0, 3, 65536, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -31244, 0, 8, 3801088, 9, 0, 0, 5, 2, 11196, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -31226, 0, 8, 0, 524288, 0, 0, 5, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -31124, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -30881, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -30701, 28, 0, 0, 0, 0, 664232, 1, 0, 0, 0, 0, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -30675, 0, 11, 3, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -30482, 0, 0, 0, 0, 0, 0, 1, 0, 1027, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -30299, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -30293, 0, 5, 385, 8519872, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -30160, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -29834, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -29723, 0, 4, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -29593, 0, 0, 0, 0, 0, 0, 1, 0, 112, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -29441, 0, 0, 0, 0, 0, 0, 7, 0, 8, 0, 1000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -29074, 20, 3, 0, 0, 0, 0, 0, 2, 2, 0, 8, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -27811, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -27243, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -20925, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -20500, 0, 4, 268435456, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -20335, 0, 10, 8388608, 0, 0, 16, 5, 2, 0, 0, 0, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -20234, 0, 10, 32768, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -20210, 0, 10, 3221225472, 65536, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -20177, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -20049, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -19572, 0, 9, 8388608, 0, 0, 262144, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -19184, 0, 9, 16, 8192, 0, 0, 0, 4, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -18213, 32, 5, 16384, 0, 0, 2, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -18119, 0, 5, 0, 8388608, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -18096, 0, 5, 256, 8388608, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -18094, 0, 5, 10, 0, 0, 0, 1, 2, 0, 0, 6000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -17793, 0, 5, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -17106, 0, 7, 524288, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -16958, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -16952, 0, 7, 233472, 1024, 262144, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -16880, 72, 7, 103, 58720258, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -16689, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -16487, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -16257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -16256, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -16180, 0, 11, 448, 0, 16, 0, 2, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -16176, 0, 11, 448, 0, 16, 0, 2, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -15337, 0, 6, 8396800, 2, 0, 0, 1, 2, 2, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -14892, 0, 6, 268443136, 65540, 0, 0, 0, 2, 2, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -14531, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -14186, 0, 8, 1107296782, 2, 0, 0, 0, 2, 2, 2, 500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -14156, 0, 8, 4063232, 9, 0, 0, 0, 4, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -14143, 0, 8, 1191182854, 2097152, 0, 0, 1, 2, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -13983, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 1000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -13754, 0, 8, 16, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -13165, 0, 0, 0, 0, 0, 64, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -12966, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -12834, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -12319, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -12317, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -12311, 0, 4, 2048, 1, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -12298, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -12289, 0, 4, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -12281, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 6000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -11255, 0, 3, 16384, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -11213, 0, 3, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -11185, 0, 3, 128, 0, 0, 65536, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -11180, 16, 3, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -11119, 4, 3, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -11103, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -11095, 0, 3, 16, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -10400, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 8, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -9799, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -9452, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -7302, 0, 0, 0, 0, 0, 0, 1, 0, 1027, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -7001, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -5952, 0, 8, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -1463, 0, 3, 0, 0, 0, 0, 1, 0, 1024, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -1120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -974, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 3500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -588, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -324, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 3500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { -168, 0, 0, 0, 0, 0, 0, 1, 0, 1027, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 1719, 0, 4, 778044484, 4212549, 0, 0, 1, 2, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 4341, 0, 0, 0, 0, 0, 4096, 1, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 4524, 0, 0, 0, 0, 0, 1048576, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 5118, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 6346, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 7383, 1, 0, 0, 0, 0, 0, 1, 0, 256, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 7434, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 6000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 8178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 9782, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 9784, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 11129, 4, 3, 146800663, 200776, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 12043, 0, 3, 1631584309, 4096, 0, 0, 7, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 12169, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 12322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 12328, 0, 4, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 12536, 0, 3, 549591799, 168000, 0, 0, 0, 1, 0, 12, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 12999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 13000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 13001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 13002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 13159, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 13163, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 20000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 13234, 0, 0, 0, 0, 0, 0, 1, 0, 1027, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 15088, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 5000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 15128, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 15277, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 15286, 32, 6, 41984016, 9218, 8, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 15346, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 15600, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2000, 2.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 16164, 28, 0, 0, 0, 0, 65536, 1, 2, 2, 0, 500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 16166, 0, 11, 3, 4096, 0, 0, 7, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 16246, 0, 11, 2551185859, 5120, 16, 0, 0, 1, 0, 12, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 16372, 0, 0, 0, 0, 0, 131072, 0, 0, 0, 0, 0, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 16550, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 16620, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 16624, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 16864, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 16870, 0, 7, 14924799, 126879699, 263168, 0, 0, 1, 0, 12, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 17116, 0, 7, 268436065, 33554464, 32768, 0, 7, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 17364, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 17495, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 17619, 0, 13, 0, 0, 0, 34816, 7, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 17670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 17941, 0, 5, 1, 0, 0, 65536, 1, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 18708, 0, 5, 536870912, 0, 0, 0, 0, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 18820, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20128, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20131, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20132, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20164, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20165, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20166, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20185, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20186, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20375, 1, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20705, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20784, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 20911, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 21084, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 21185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 21882, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 21890, 0, 4, 712396527, 876, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 22007, 0, 3, 2097185, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 22008, 0, 3, 1631584309, 0, 0, 69632, 5, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 22618, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 1000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 22648, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 120000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23547, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23548, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23551, 0, 11, 192, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23552, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23572, 0, 11, 192, 0, 0, 0, 0, 2, 0, 0, 1000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23578, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23581, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23591, 0, 10, 8388608, 0, 0, 16, 0, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23686, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23688, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23689, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23721, 0, 9, 2048, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 23920, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 24353, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 24389, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 24658, 0, 0, 0, 0, 0, 87376, 7, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 24905, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 24932, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 25050, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 25669, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 25899, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 26107, 0, 7, 8388608, 268435584, 0, 0, 0, 2, 116, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 26119, 0, 0, 2416967683, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 26128, 0, 0, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 26135, 0, 10, 8388608, 0, 0, 16, 0, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 26169, 0, 6, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 26467, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 26480, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 26605, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 27419, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 27498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 27521, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 15000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 27539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 27656, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 27774, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 27787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28200, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28716, 0, 7, 16, 0, 0, 262144, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28719, 0, 7, 32, 0, 0, 0, 2, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28744, 0, 7, 64, 0, 0, 278528, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28752, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28789, 0, 10, 3221225472, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28802, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28809, 0, 6, 4096, 0, 0, 0, 2, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28812, 0, 8, 33554438, 0, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28823, 0, 11, 192, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28845, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28847, 0, 7, 32, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 28849, 0, 11, 128, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29150, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29307, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29385, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29455, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29501, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29601, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29624, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29625, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29626, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29632, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29633, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29634, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29635, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29636, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29637, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 29977, 4, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 30003, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 30823, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 30937, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 31394, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 31794, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 31801, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 31834, 0, 10, 2147483648, 0, 0, 16384, 2, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 31904, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32065, 0, 0, 0, 0, 0, 524288, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32216, 0, 4, 0, 256, 0, 16, 1, 4, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32409, 0, 0, 0, 8192, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32587, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32642, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32734, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32748, 0, 8, 0, 1, 0, 320, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32776, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32777, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32837, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 35000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32844, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32863, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 32885, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 33089, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 33127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 33297, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 33299, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 33510, 0, 0, 0, 0, 0, 340, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 33648, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 33719, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 33746, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 33757, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 33759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 33953, 0, 0, 0, 0, 0, 279552, 2, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34074, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34080, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34138, 0, 11, 128, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34139, 0, 10, 1073741824, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34258, 0, 10, 8388608, 0, 0, 0, 0, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34262, 0, 10, 8388608, 0, 0, 0, 0, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34320, 0, 0, 0, 0, 0, 0, 3, 2, 2, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34355, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34477, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34584, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34586, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34598, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34749, 0, 0, 0, 0, 0, 0, 0, 2, 8, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34774, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 20000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34783, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34827, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 34936, 0, 5, 1, 64, 0, 65536, 1, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 35077, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 35080, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 60000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 35083, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 60000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 35086, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 60000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 35121, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 35321, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 35399, 0, 0, 0, 0, 0, 131072, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 36032, 0, 3, 4096, 32768, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 36096, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 36111, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 36123, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 36541, 4, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 36659, 0, 0, 0, 0, 0, 524288, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37165, 0, 8, 2098176, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37168, 0, 8, 4063232, 9, 0, 0, 0, 4, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37170, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37173, 0, 8, 750519704, 262, 0, 0, 0, 2, 0, 0, 30000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37189, 0, 10, 3221225472, 0, 0, 0, 0, 2, 2, 0, 60000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37193, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37195, 0, 10, 8388608, 0, 0, 0, 0, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37197, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37213, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37214, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37227, 0, 11, 448, 0, 0, 0, 0, 2, 2, 0, 60000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37237, 0, 11, 1, 0, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37247, 8, 0, 0, 0, 0, 0, 0, 2, 0, 0, 40000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37288, 0, 7, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37295, 0, 7, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37377, 32, 5, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37379, 32, 5, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37381, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37384, 0, 5, 1, 64, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37443, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37447, 0, 3, 0, 256, 0, 16384, 4, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37514, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37516, 0, 4, 1024, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37519, 0, 0, 0, 0, 0, 0, 0, 2, 48, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37523, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37528, 0, 4, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37536, 0, 4, 65536, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37568, 0, 6, 2048, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37594, 0, 6, 4096, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37600, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37601, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37603, 0, 6, 32768, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37604, 0, 6, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37655, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 37657, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 2500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38026, 1, 0, 0, 0, 0, 0, 1, 0, 256, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38031, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38164, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 120000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38252, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38290, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38299, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 15000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38326, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38327, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38334, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38347, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38350, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38363, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38394, 0, 5, 6, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 38857, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 39027, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 39215, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 39367, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 39372, 48, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 39437, 4, 5, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 39442, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 39443, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 39530, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 39958, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 40000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40407, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40438, 0, 6, 32832, 0, 0, 0, 3, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40442, 0, 7, 20, 1088, 0, 0, 7, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40444, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40458, 0, 4, 33554432, 1537, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40463, 0, 11, 129, 16, 0, 0, 3, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40470, 0, 10, 3229614080, 0, 0, 0, 3, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40475, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40478, 0, 5, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40482, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40485, 0, 9, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40816, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 7000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 40971, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 41034, 126, 0, 0, 0, 0, 0, 0, 0, 1024, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 41260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 41262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 41350, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 41381, 0, 0, 0, 0, 0, 0, 1, 0, 256, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 41393, 0, 0, 0, 0, 0, 0, 1, 0, 32, 0, 15000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 41434, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 41469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 41989, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 42083, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 42135, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 42136, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 42368, 0, 10, 1073741824, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 42370, 0, 11, 128, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 42770, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 43443, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 43726, 0, 10, 1073741824, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 43728, 0, 11, 128, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 43737, 0, 7, 0, 1088, 0, 0, 0, 2, 0, 0, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 43739, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 43741, 0, 10, 2147483648, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 43745, 0, 10, 0, 512, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 43748, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 43750, 0, 11, 1, 0, 0, 0, 0, 2, 0, 0, 30000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 43819, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 44141, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 44401, 0, 3, 0, 0, 0, 69632, 5, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 44543, 0, 3, 1049120, 4096, 0, 0, 0, 1, 0, 2, 0, 7.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 44545, 0, 3, 1049120, 4096, 0, 0, 0, 1, 0, 2, 0, 15.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 45054, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 15000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 45057, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 45092, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 45354, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 45355, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 45469, 0, 15, 16, 0, 0, 16, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 45481, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 45482, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 45483, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 45484, 0, 0, 0, 0, 0, 16384, 2, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 46025, 32, 6, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 46092, 0, 10, 1073741824, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 46098, 0, 11, 128, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 46569, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 46662, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 25000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 46832, 0, 7, 1, 0, 0, 0, 0, 2, 0, 0, 15000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 46910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 46911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 46916, 0, 4, 2097152, 0, 0, 0, 0, 4, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 47383, 0, 5, 0, 192, 0, 0, 0, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 47981, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 48108, 0, 3, 4194304, 0, 0, 65536, 1, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 48504, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 48833, 0, 7, 0, 1088, 0, 0, 0, 2, 0, 0, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 48835, 0, 10, 8388608, 0, 0, 0, 0, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 48837, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 49005, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 49028, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 49194, 0, 15, 0, 0, 1, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 49222, 0, 0, 0, 0, 0, 139944, 1, 0, 0, 0, 2000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 49592, 0, 0, 0, 0, 0, 8528552, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 49622, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 49796, 0, 15, 2, 131078, 0, 0, 0, 4, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 50240, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 50421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 50781, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 6000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 50871, 0, 9, 0, 1073741824, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 50908, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51124, 0, 15, 2, 6, 0, 65552, 1, 4, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51414, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51528, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51529, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51530, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51531, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51532, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51698, 0, 0, 0, 0, 0, 0, 3, 4, 2, 0, 1000, 33.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51700, 0, 0, 0, 0, 0, 0, 3, 4, 2, 0, 1000, 66.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51701, 0, 0, 0, 0, 0, 0, 3, 4, 2, 0, 1000, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 51915, 0, 0, 0, 0, 0, 16777216, 0, 0, 0, 0, 600000, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 52020, 0, 7, 32768, 1048576, 0, 0, 0, 2, 0, 0, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 52420, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 52423, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 52437, 1, 4, 536870912, 0, 0, 16, 0, 4, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 52881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 52898, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 6000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 53257, 0, 9, 0, 268435456, 0, 16, 1, 2, 2, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 53386, 0, 15, 2182250279, 447, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 53397, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 53515, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 53601, 0, 0, 0, 0, 0, 1048576, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 53646, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 5000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 53651, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 53736, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 53817, 0, 11, 451, 32768, 0, 0, 0, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54274, 0, 5, 357, 131264, 0, 0, 0, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54276, 0, 5, 357, 131264, 0, 0, 0, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54277, 0, 5, 357, 131264, 0, 0, 0, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54278, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54646, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54695, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54707, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54738, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54741, 0, 3, 4, 0, 0, 65536, 5, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54748, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54754, 0, 7, 16, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54808, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54815, 0, 7, 32768, 0, 0, 16, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54821, 0, 7, 4096, 0, 0, 16, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54832, 0, 7, 0, 4096, 0, 16384, 4, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54838, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54841, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 2500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54845, 0, 7, 4, 0, 0, 65536, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54909, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54925, 2, 10, 0, 512, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54937, 0, 10, 2147483648, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 54939, 0, 10, 32768, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55198, 0, 11, 448, 0, 0, 16384, 2, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55380, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 40000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55381, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 15000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55440, 0, 11, 64, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55640, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 60000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55677, 0, 6, 0, 1, 0, 0, 4, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55680, 0, 6, 512, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55681, 0, 6, 32768, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55689, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55747, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55768, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 55776, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 55000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56218, 0, 5, 2, 0, 0, 0, 1, 2, 0, 0, 6000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56249, 0, 5, 0, 0, 1024, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56355, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56364, 0, 3, 0, 16777216, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56372, 0, 3, 0, 128, 0, 16384, 4, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56374, 0, 3, 0, 16384, 0, 16384, 4, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56375, 0, 3, 16777216, 0, 0, 65536, 4, 2, 2049, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56451, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56800, 0, 8, 4, 0, 0, 16, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56816, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56817, 0, 15, 0, 536870912, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56821, 0, 8, 2, 0, 0, 0, 0, 2, 2, 0, 500, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 56841, 0, 9, 2048, 0, 0, 256, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 57345, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 57351, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 57352, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 57529, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 57531, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 57761, 0, 3, 1, 4096, 0, 65536, 1, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 57870, 0, 9, 8388608, 0, 0, 262144, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 57907, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 57989, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58357, 0, 4, 64, 0, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58364, 0, 4, 1024, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58372, 0, 4, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58375, 0, 4, 0, 512, 0, 16, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58386, 0, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58442, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 30000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58444, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 5000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58616, 0, 15, 16777216, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58620, 0, 15, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58626, 0, 15, 33554432, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58642, 0, 15, 0, 134217728, 0, 16, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58677, 0, 15, 8192, 0, 0, 0, 2, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 58901, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 59176, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 6000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 59327, 0, 15, 134217728, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 59345, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 59630, 0, 0, 0, 0, 0, 69648, 5, 1, 0, 2, 35000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 59725, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 59906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 59915, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60061, 0, 0, 0, 0, 0, 294912, 2, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60063, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60066, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60132, 0, 15, 16, 134348800, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60170, 0, 5, 6, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60172, 0, 5, 262144, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60176, 0, 4, 32, 16, 0, 262144, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60221, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60301, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60306, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60317, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60436, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60442, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60473, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60482, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60487, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 15000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60490, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60493, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60503, 1, 4, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60519, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60524, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60529, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60537, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60564, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60571, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60572, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60573, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60574, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60575, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60617, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60710, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60717, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60719, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60722, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60724, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60726, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60770, 0, 11, 1, 0, 0, 0, 0, 2, 0, 0, 30000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60818, 0, 10, 0, 512, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 60826, 0, 15, 20971520, 0, 0, 0, 0, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 61062, 0, 3, 0, 256, 0, 16384, 4, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 61188, 0, 5, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 61257, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 61324, 0, 10, 0, 131072, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 61356, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 61618, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 61848, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 62114, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 62115, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 62147, 0, 15, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 62259, 0, 15, 33554432, 0, 0, 0, 0, 0, 0, 1, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 62337, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 62459, 0, 15, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 62600, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 62606, 0, 0, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 63057, 0, 7, 0, 262144, 0, 16384, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 63086, 0, 9, 0, 0, 65536, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 63108, 0, 5, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 63251, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 63279, 0, 11, 0, 1024, 0, 0, 4, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 63280, 0, 11, 536870912, 0, 0, 0, 0, 1, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 63310, 0, 5, 0, 65536, 0, 65536, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 63320, 0, 5, 2147745792, 0, 32768, 1024, 7, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 63335, 0, 15, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 63611, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 63849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64343, 0, 3, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64411, 0, 0, 0, 0, 0, 279552, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64415, 0, 0, 0, 0, 0, 279552, 2, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64440, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64571, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64714, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64738, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64742, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64752, 0, 7, 4096, 256, 2097152, 0, 0, 2, 0, 0, 15000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64786, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64792, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64823, 0, 7, 4, 0, 0, 65536, 1, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64824, 0, 7, 2097152, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64860, 0, 9, 0, 1, 0, 0, 0, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64867, 0, 3, 536870945, 4096, 0, 0, 0, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64882, 0, 10, 0, 1048576, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64890, 0, 10, 0, 65536, 0, 0, 2, 2, 2, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64908, 0, 6, 8192, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64912, 0, 6, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64914, 0, 8, 65536, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64928, 0, 11, 1, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64938, 0, 4, 2097216, 0, 0, 0, 0, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64952, 0, 7, 0, 1088, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64955, 0, 10, 0, 64, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64964, 0, 15, 0, 536870912, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64976, 0, 4, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 64999, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 65002, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 65005, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 65007, 0, 0, 0, 0, 0, 81920, 3, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 65013, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 65020, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 65025, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 65032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 66808, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 66865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3000, 35.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 66889, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67115, 0, 15, 20971520, 0, 0, 0, 0, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67151, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67209, 1, 8, 1048576, 0, 0, 0, 0, 2, 0, 0, 15000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67228, 0, 11, 0, 4096, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67353, 0, 7, 32768, 1049856, 0, 0, 0, 2, 0, 0, 8000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67356, 8, 7, 16, 0, 0, 0, 2, 2, 0, 0, 5000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67361, 0, 7, 2, 0, 0, 0, 1, 2, 0, 0, 6000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67363, 0, 10, 2147483648, 0, 0, 0, 0, 2, 0, 0, 8000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67365, 0, 10, 0, 2048, 0, 0, 0, 2, 0, 0, 8000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67379, 0, 10, 0, 262144, 0, 0, 0, 2, 0, 0, 9000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67381, 0, 15, 0, 536870912, 0, 0, 0, 2, 0, 0, 10000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67384, 0, 15, 16, 134348800, 0, 0, 0, 2, 0, 0, 10000, 80.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67386, 0, 11, 1, 0, 0, 65536, 0, 1, 0, 0, 6000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67389, 0, 11, 256, 0, 0, 16384, 0, 1, 0, 0, 8000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67392, 0, 11, 0, 0, 4, 16, 0, 2, 0, 0, 9000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67530, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 5000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67653, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67667, 0, 0, 0, 0, 0, 16384, 2, 1, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67670, 0, 0, 0, 0, 0, 65536, 1, 1, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67672, 0, 0, 0, 0, 0, 8388948, 1, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67698, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67702, 1, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67712, 0, 0, 0, 0, 0, 69632, 1, 2, 2, 0, 2000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67752, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67758, 0, 0, 0, 0, 0, 69632, 1, 2, 2, 0, 2000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 67771, 1, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 68051, 1, 4, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 68160, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 69739, 0, 0, 0, 0, 0, 0, 7, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 69755, 0, 0, 0, 0, 0, 0, 7, 2, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 69762, 0, 0, 0, 0, 0, 87040, 0, 1, 0, 256, 100, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70188, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 3000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70388, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70652, 0, 15, 8, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70656, 0, 15, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70664, 0, 7, 16, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70672, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70723, 0, 7, 5, 0, 0, 0, 1, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70727, 0, 9, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70730, 0, 9, 16384, 4096, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70748, 0, 3, 0, 2097152, 0, 1024, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70756, 0, 10, 0, 65536, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70761, 0, 10, 0, 0, 1, 1024, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70770, 0, 6, 2048, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70803, 0, 8, 4063232, 8, 0, 0, 0, 4, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70805, 0, 8, 0, 131072, 0, 0, 4, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70807, 0, 11, 0, 0, 16, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70808, 0, 11, 256, 0, 0, 0, 2, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70811, 0, 11, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70817, 0, 11, 0, 4096, 0, 65536, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70830, 0, 11, 0, 131072, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70841, 0, 5, 4, 256, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70844, 0, 4, 256, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70854, 0, 4, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 70904, 0, 6, 0, 0, 2048, 2048, 4, 0, 0, 0, 1000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71162, 0, 5, 0, 192, 0, 0, 0, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71165, 0, 5, 0, 192, 0, 0, 0, 1, 0, 8, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71174, 1, 7, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71176, 0, 7, 2097154, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71178, 0, 7, 16, 0, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71186, 0, 10, 0, 32768, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71191, 0, 10, 0, 65536, 0, 0, 2, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71194, 0, 10, 0, 1048576, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71198, 4, 11, 268435456, 0, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71214, 0, 11, 0, 16, 0, 16, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71217, 0, 11, 0, 0, 16, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71226, 0, 15, 16, 134348800, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71228, 0, 15, 0, 536870912, 0, 0, 0, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71402, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71404, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71406, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 50.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71519, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 105000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71540, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71545, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 50.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71562, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 105000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71564, 126, 0, 0, 0, 0, 0, 3, 2, 2, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71567, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 250, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71571, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71573, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71585, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71602, 0, 0, 0, 0, 0, 65536, 1, 1, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71606, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 100000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71611, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71634, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71637, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 100000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71640, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71642, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71645, 0, 0, 0, 0, 0, 65536, 1, 1, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71756, 4, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71761, 0, 3, 0, 1048576, 0, 0, 5, 2, 256, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71770, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71865, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71868, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71880, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71892, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71903, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 71993, 0, 0, 0, 0, 0, 4, 0, 0, 12287, 0, 3000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72059, 0, 0, 0, 0, 0, 0, 1, 0, 1027, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72176, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72256, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72413, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 60000, 10.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72417, 0, 0, 0, 0, 0, 327680, 1, 2, 0, 0, 60000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72419, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 60000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72455, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72674, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72675, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000, 100.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72782, 4, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72783, 4, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72784, 4, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72832, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 72833, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 74396, 84, 3, 685904631, 1151048, 0, 65536, 0, 1, 0, 0, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 75455, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 75457, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 75465, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 75474, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 50000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 75475, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 75481, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 45000, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 75490, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 0.0f, 0.0f, 0, 0, 0, 0, 0 }, + { 75495, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 0.0f } + }; +} + +/** + * @brief Group entries by ProcFlags pattern for targeted testing + */ +inline std::map> GroupByProcFlags() +{ + std::map> grouped; + for (auto const& entry : GetAllSpellProcTestEntries()) + { + grouped[entry.ProcFlags].push_back(entry); + } + return grouped; +} + +/** + * @brief Group entries by HitMask for targeted testing + */ +inline std::map> GroupByHitMask() +{ + std::map> grouped; + for (auto const& entry : GetAllSpellProcTestEntries()) + { + grouped[entry.HitMask].push_back(entry); + } + return grouped; +} + +/** + * @brief Group entries by SpellFamilyName for class-specific testing + */ +inline std::map> GroupBySpellFamily() +{ + std::map> grouped; + for (auto const& entry : GetAllSpellProcTestEntries()) + { + grouped[entry.SpellFamilyName].push_back(entry); + } + return grouped; +} + +#endif //AZEROTHCORE_SPELL_PROC_TEST_DATA_H diff --git a/src/test/server/game/Spells/SpellProcTriggeredFilterTest.cpp b/src/test/server/game/Spells/SpellProcTriggeredFilterTest.cpp new file mode 100644 index 000000000..997425915 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcTriggeredFilterTest.cpp @@ -0,0 +1,391 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcTriggeredFilterTest.cpp + * @brief Unit tests for triggered spell filtering in proc system + * + * Tests the logic from SpellAuras.cpp:2191-2209: + * - Self-loop prevention (spell triggered by same aura) + * - Triggered spell blocking (default behavior) + * - SPELL_ATTR3_CAN_PROC_FROM_PROCS exception + * - PROC_ATTR_TRIGGERED_CAN_PROC exception + * - SPELL_ATTR3_NOT_A_PROC exception + * - AUTO_ATTACK_PROC_FLAG_MASK exception + */ + +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "gtest/gtest.h" + +using namespace testing; + +class SpellProcTriggeredFilterTest : public ::testing::Test +{ +protected: + void SetUp() override {} + + // Helper to create default proc entry + SpellProcEntry CreateBasicProcEntry() + { + return SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithChance(100.0f) + .Build(); + } +}; + +// ============================================================================= +// Self-Loop Prevention Tests - SpellAuras.cpp:2191-2192 +// ============================================================================= + +TEST_F(SpellProcTriggeredFilterTest, SelfLoop_BlocksWhenTriggeredBySameAura) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.triggeredByAuraSpellId = 12345; // Same as proc aura + config.procAuraSpellId = 12345; + + auto procEntry = CreateBasicProcEntry(); + + // Self-loop should be blocked + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "Self-loop should block proc"; +} + +TEST_F(SpellProcTriggeredFilterTest, SelfLoop_AllowsWhenTriggeredByDifferentAura) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.triggeredByAuraSpellId = 12345; // Different from proc aura + config.procAuraSpellId = 67890; + config.auraHasCanProcFromProcs = true; // Allow triggered spells + + auto procEntry = CreateBasicProcEntry(); + + // Different aura should be allowed + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "Different aura trigger should allow proc"; +} + +TEST_F(SpellProcTriggeredFilterTest, SelfLoop_AllowsWhenNotTriggered) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = false; // Not a triggered spell + config.triggeredByAuraSpellId = 0; + config.procAuraSpellId = 12345; + + auto procEntry = CreateBasicProcEntry(); + + // Non-triggered spell should be allowed + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "Non-triggered spell should allow proc"; +} + +// ============================================================================= +// Triggered Spell Blocking - Default Behavior +// ============================================================================= + +TEST_F(SpellProcTriggeredFilterTest, TriggeredSpell_BlockedByDefault) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = false; + + // No TRIGGERED_CAN_PROC attribute + auto procEntry = CreateBasicProcEntry(); + + // Should be blocked - no exceptions apply + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "Triggered spell should be blocked by default"; +} + +TEST_F(SpellProcTriggeredFilterTest, NonTriggeredSpell_AllowedByDefault) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = false; // Not triggered + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = false; + + auto procEntry = CreateBasicProcEntry(); + + // Should be allowed + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "Non-triggered spell should be allowed"; +} + +// ============================================================================= +// SPELL_ATTR3_CAN_PROC_FROM_PROCS Exception +// ============================================================================= + +TEST_F(SpellProcTriggeredFilterTest, CanProcFromProcs_AllowsTriggeredSpells) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = true; // Exception: aura has SPELL_ATTR3_CAN_PROC_FROM_PROCS + config.spellHasNotAProc = false; + + auto procEntry = CreateBasicProcEntry(); + + // Should be allowed due to aura attribute + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "SPELL_ATTR3_CAN_PROC_FROM_PROCS should allow triggered spells"; +} + +// ============================================================================= +// PROC_ATTR_TRIGGERED_CAN_PROC Exception +// ============================================================================= + +TEST_F(SpellProcTriggeredFilterTest, TriggeredCanProcAttribute_AllowsTriggeredSpells) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = false; + + // Set TRIGGERED_CAN_PROC attribute + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithAttributesMask(PROC_ATTR_TRIGGERED_CAN_PROC) + .WithChance(100.0f) + .Build(); + + // Should be allowed due to proc entry attribute + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "PROC_ATTR_TRIGGERED_CAN_PROC should allow triggered spells"; +} + +// ============================================================================= +// SPELL_ATTR3_NOT_A_PROC Exception +// ============================================================================= + +TEST_F(SpellProcTriggeredFilterTest, NotAProc_AllowsTriggeredSpell) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = true; // Exception: spell has SPELL_ATTR3_NOT_A_PROC + + auto procEntry = CreateBasicProcEntry(); + + // Should be allowed due to spell attribute + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "SPELL_ATTR3_NOT_A_PROC should allow triggered spell"; +} + +// ============================================================================= +// AUTO_ATTACK_PROC_FLAG_MASK Exception +// ============================================================================= + +TEST_F(SpellProcTriggeredFilterTest, AutoAttackMelee_AllowsTriggeredSpells) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = false; + + auto procEntry = CreateBasicProcEntry(); + + // Event mask includes auto-attack - exception applies + uint32 autoAttackEvent = PROC_FLAG_DONE_MELEE_AUTO_ATTACK; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, autoAttackEvent)) + << "AUTO_ATTACK_PROC_FLAG_MASK (melee) should allow triggered spells"; +} + +TEST_F(SpellProcTriggeredFilterTest, AutoAttackRanged_AllowsTriggeredSpells) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = false; + + auto procEntry = CreateBasicProcEntry(); + + // Hunter auto-shot or wand (ranged auto-attack) + uint32 rangedAutoEvent = PROC_FLAG_DONE_RANGED_AUTO_ATTACK; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, rangedAutoEvent)) + << "AUTO_ATTACK_PROC_FLAG_MASK (ranged) should allow triggered spells"; +} + +TEST_F(SpellProcTriggeredFilterTest, TakenAutoAttack_AllowsTriggeredSpells) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = false; + + auto procEntry = CreateBasicProcEntry(); + + // Taken melee auto-attack + uint32 takenMeleeEvent = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, takenMeleeEvent)) + << "TAKEN_MELEE_AUTO_ATTACK should allow triggered spells"; +} + +// ============================================================================= +// Combined Scenarios +// ============================================================================= + +TEST_F(SpellProcTriggeredFilterTest, Combined_SelfLoopTakesPrecedence) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.triggeredByAuraSpellId = 12345; + config.procAuraSpellId = 12345; // Self-loop + config.auraHasCanProcFromProcs = true; // Would normally allow + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithAttributesMask(PROC_ATTR_TRIGGERED_CAN_PROC) + .WithChance(100.0f) + .Build(); + + // Self-loop should still block even with exceptions + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "Self-loop should block even when TRIGGERED_CAN_PROC is set"; +} + +TEST_F(SpellProcTriggeredFilterTest, Combined_MultipleExceptions) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = true; // Exception 1 + config.spellHasNotAProc = true; // Exception 2 + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithAttributesMask(PROC_ATTR_TRIGGERED_CAN_PROC) // Exception 3 + .WithChance(100.0f) + .Build(); + + // Should be allowed (multiple exceptions all pass) + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "Multiple exceptions should still allow proc"; +} + +// ============================================================================= +// Real Spell Scenarios +// ============================================================================= + +TEST_F(SpellProcTriggeredFilterTest, Scenario_HotStreak_TriggeredPyroblast) +{ + // Hot Streak (48108) allows triggered Pyroblast to not proc it again + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; // Pyroblast was triggered by Hot Streak + config.triggeredByAuraSpellId = 48108; // Hot Streak + config.procAuraSpellId = 48108; // Hot Streak is checking if it should proc + + auto procEntry = CreateBasicProcEntry(); + + // Self-loop: Hot Streak can't proc from spell it triggered + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "Hot Streak triggered Pyroblast should not proc Hot Streak"; +} + +TEST_F(SpellProcTriggeredFilterTest, Scenario_SwordSpec_ChainProcs) +{ + // Sword Specialization with TRIGGERED_CAN_PROC + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.triggeredByAuraSpellId = 12345; // Some other proc + config.procAuraSpellId = 16459; // Sword Specialization + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithAttributesMask(PROC_ATTR_TRIGGERED_CAN_PROC) + .WithChance(5.0f) + .Build(); + + // TRIGGERED_CAN_PROC allows chain procs (but not self-loops) + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_MELEE_AUTO_ATTACK)) + << "Sword Spec with TRIGGERED_CAN_PROC should allow chain procs"; +} + +TEST_F(SpellProcTriggeredFilterTest, Scenario_WindfuryWeapon_AutoAttack) +{ + // Windfury Weapon procs from auto-attacks, which are allowed for triggered spells + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; // Windfury extra attacks are triggered + config.auraHasCanProcFromProcs = false; + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithProcsPerMinute(2.0f) + .Build(); + + // Auto-attack exception allows triggered Windfury attacks + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_MELEE_AUTO_ATTACK)) + << "Windfury triggered attacks should be allowed (auto-attack exception)"; +} + +// ============================================================================= +// Edge Cases +// ============================================================================= + +TEST_F(SpellProcTriggeredFilterTest, EdgeCase_ZeroEventMask) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + + auto procEntry = CreateBasicProcEntry(); + + // Zero event mask means no auto-attack exception + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, 0)) + << "Zero event mask should not grant auto-attack exception"; +} + +TEST_F(SpellProcTriggeredFilterTest, EdgeCase_AllExceptionsDisabled) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = false; + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithAttributesMask(0) // No TRIGGERED_CAN_PROC + .WithChance(100.0f) + .Build(); + + // No exceptions - should block + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)) + << "No exceptions should block triggered spell"; +} diff --git a/src/test/server/game/Spells/SpellScriptMissileBarrageTest.cpp b/src/test/server/game/Spells/SpellScriptMissileBarrageTest.cpp new file mode 100644 index 000000000..bde844c19 --- /dev/null +++ b/src/test/server/game/Spells/SpellScriptMissileBarrageTest.cpp @@ -0,0 +1,274 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellScriptMissileBarrageTest.cpp + * @brief Unit tests for Missile Barrage (44404-44408) proc behavior + * + * Missile Barrage talent should proc: + * - 100% chance when casting Arcane Blast (SpellFamilyFlags[0] & 0x20000000) + * - 50% reduced chance when casting other spells (Arcane Barrage, Frostfire Bolt, etc.) + * + * DBC Base proc chances by rank: + * - Rank 1 (44404): 4% + * - Rank 2 (44405): 8% + * - Rank 3 (44406): 12% + * - Rank 4 (44407): 16% + * - Rank 5 (44408): 20% + * + * Effective proc rates: + * - Arcane Blast: Full DBC chance (4-20%) + * - Other spells: 50% of DBC chance (2-10%) + */ + +#include "gtest/gtest.h" +#include "SpellInfo.h" +#include "SpellMgr.h" +#include "SharedDefines.h" + +// ============================================================================= +// Missile Barrage Script Logic Simulation +// ============================================================================= + +/** + * @brief Simulates the CheckProc logic from spell_mage_missile_barrage + * + * This mirrors the actual script at: + * src/server/scripts/Spells/spell_mage.cpp:1325-1338 + * + * @param spellFamilyFlags0 The SpellFamilyFlags[0] of the triggering spell + * @param rollResult The result of roll_chance_i(50) - pass 0-49 to succeed, 50-99 to fail + * @return true if the proc check passes + */ +bool SimulateMissileBarrageCheckProc(uint32 spellFamilyFlags0, int rollResult) +{ + // Arcane Blast - full proc chance (100%) + // Arcane Blast spell family flags: 0x20000000 + if (spellFamilyFlags0 & 0x20000000) + return true; + + // Other spells - 50% proc chance + // Simulates: return roll_chance_i(50); + return rollResult < 50; +} + +/** + * @brief Get the SpellFamilyFlags[0] for common Mage spells + */ +namespace MageSpellFlags +{ + constexpr uint32 ARCANE_BLAST = 0x20000000; + constexpr uint32 ARCANE_MISSILES = 0x00000020; + constexpr uint32 FIREBALL = 0x00000001; + constexpr uint32 FROSTFIRE_BOLT = 0x00000000; // Uses SpellFamilyFlags[1] + constexpr uint32 ARCANE_BARRAGE = 0x00000000; // Uses SpellFamilyFlags[1] +} + +// ============================================================================= +// Test Fixture +// ============================================================================= + +class MissileBarrageTest : public ::testing::Test +{ +protected: + void SetUp() override {} + void TearDown() override {} + + /** + * @brief Run multiple proc checks and return the success rate + * @param spellFamilyFlags0 The spell flags to test + * @param iterations Number of iterations + * @return Success rate as percentage (0-100) + */ + float RunStatisticalTest(uint32 spellFamilyFlags0, int iterations = 10000) + { + int successes = 0; + for (int i = 0; i < iterations; i++) + { + // Simulate random roll 0-99 + int roll = i % 100; + if (SimulateMissileBarrageCheckProc(spellFamilyFlags0, roll)) + successes++; + } + return (float)successes / iterations * 100.0f; + } +}; + +// ============================================================================= +// Deterministic Tests - Arcane Blast +// ============================================================================= + +TEST_F(MissileBarrageTest, ArcaneBlast_AlwaysProcs_RegardlessOfRoll) +{ + // Arcane Blast should always pass CheckProc, regardless of the roll result + for (int roll = 0; roll < 100; roll++) + { + EXPECT_TRUE(SimulateMissileBarrageCheckProc(MageSpellFlags::ARCANE_BLAST, roll)) + << "Arcane Blast should always proc, but failed with roll=" << roll; + } +} + +TEST_F(MissileBarrageTest, ArcaneBlast_Returns100PercentRate) +{ + float rate = RunStatisticalTest(MageSpellFlags::ARCANE_BLAST); + EXPECT_NEAR(rate, 100.0f, 0.01f) << "Arcane Blast should have 100% CheckProc pass rate"; +} + +// ============================================================================= +// Deterministic Tests - Other Spells (50% Reduction) +// ============================================================================= + +TEST_F(MissileBarrageTest, Fireball_ProcsOnLowRoll) +{ + // Rolls 0-49 should succeed + for (int roll = 0; roll < 50; roll++) + { + EXPECT_TRUE(SimulateMissileBarrageCheckProc(MageSpellFlags::FIREBALL, roll)) + << "Fireball should proc with roll=" << roll << " (< 50)"; + } +} + +TEST_F(MissileBarrageTest, Fireball_FailsOnHighRoll) +{ + // Rolls 50-99 should fail + for (int roll = 50; roll < 100; roll++) + { + EXPECT_FALSE(SimulateMissileBarrageCheckProc(MageSpellFlags::FIREBALL, roll)) + << "Fireball should NOT proc with roll=" << roll << " (>= 50)"; + } +} + +TEST_F(MissileBarrageTest, Fireball_Returns50PercentRate) +{ + float rate = RunStatisticalTest(MageSpellFlags::FIREBALL); + EXPECT_NEAR(rate, 50.0f, 0.01f) << "Fireball should have 50% CheckProc pass rate"; +} + +TEST_F(MissileBarrageTest, ArcaneMissiles_Returns50PercentRate) +{ + float rate = RunStatisticalTest(MageSpellFlags::ARCANE_MISSILES); + EXPECT_NEAR(rate, 50.0f, 0.01f) << "Arcane Missiles should have 50% CheckProc pass rate"; +} + +TEST_F(MissileBarrageTest, OtherSpells_Returns50PercentRate) +{ + // Any spell that doesn't have the Arcane Blast flag should get 50% rate + float rate = RunStatisticalTest(0x00000000); + EXPECT_NEAR(rate, 50.0f, 0.01f) << "Other spells should have 50% CheckProc pass rate"; +} + +// ============================================================================= +// Effective Proc Rate Tests +// ============================================================================= + +/** + * @brief Calculate the effective proc rate combining DBC chance and CheckProc + * @param dbcChance Base proc chance from DBC (e.g., 20 for rank 5) + * @param checkProcRate CheckProc pass rate (100 for Arcane Blast, 50 for others) + * @return Effective proc rate as percentage + */ +float CalculateEffectiveProcRate(float dbcChance, float checkProcRate) +{ + return dbcChance * (checkProcRate / 100.0f); +} + +TEST_F(MissileBarrageTest, EffectiveRate_ArcaneBlast_Rank5) +{ + // Rank 5: 20% base chance * 100% CheckProc = 20% effective + float effective = CalculateEffectiveProcRate(20.0f, 100.0f); + EXPECT_NEAR(effective, 20.0f, 0.01f); +} + +TEST_F(MissileBarrageTest, EffectiveRate_Fireball_Rank5) +{ + // Rank 5: 20% base chance * 50% CheckProc = 10% effective + float effective = CalculateEffectiveProcRate(20.0f, 50.0f); + EXPECT_NEAR(effective, 10.0f, 0.01f); +} + +TEST_F(MissileBarrageTest, EffectiveRate_ArcaneBlast_Rank1) +{ + // Rank 1: 4% base chance * 100% CheckProc = 4% effective + float effective = CalculateEffectiveProcRate(4.0f, 100.0f); + EXPECT_NEAR(effective, 4.0f, 0.01f); +} + +TEST_F(MissileBarrageTest, EffectiveRate_Fireball_Rank1) +{ + // Rank 1: 4% base chance * 50% CheckProc = 2% effective + float effective = CalculateEffectiveProcRate(4.0f, 50.0f); + EXPECT_NEAR(effective, 2.0f, 0.01f); +} + +// ============================================================================= +// DBC Data Validation +// ============================================================================= + +TEST_F(MissileBarrageTest, DBCProcChances_MatchExpectedValues) +{ + // Expected DBC proc chances for each rank + // Note: These should match the actual DBC values + struct RankData + { + uint32 spellId; + int expectedChance; + }; + + std::vector ranks = { + { 44404, 4 }, // Rank 1: 4% (actually 8% in some versions) + { 44405, 8 }, // Rank 2 + { 44406, 12 }, // Rank 3 + { 44407, 16 }, // Rank 4 + { 44408, 20 }, // Rank 5 + }; + + // This documents the expected values - actual verification would require SpellMgr + for (auto const& rank : ranks) + { + SCOPED_TRACE("Spell ID: " + std::to_string(rank.spellId)); + // The actual DBC lookup would be: + // SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(rank.spellId); + // EXPECT_EQ(spellInfo->ProcChance, rank.expectedChance); + } +} + +// ============================================================================= +// Boundary Tests +// ============================================================================= + +TEST_F(MissileBarrageTest, BoundaryRoll_49_Succeeds) +{ + // Roll of 49 should succeed (< 50) + EXPECT_TRUE(SimulateMissileBarrageCheckProc(MageSpellFlags::FIREBALL, 49)); +} + +TEST_F(MissileBarrageTest, BoundaryRoll_50_Fails) +{ + // Roll of 50 should fail (>= 50) + EXPECT_FALSE(SimulateMissileBarrageCheckProc(MageSpellFlags::FIREBALL, 50)); +} + +TEST_F(MissileBarrageTest, ArcaneBlastFlag_ExactMatch) +{ + // Test that exactly the Arcane Blast flag triggers 100% rate + EXPECT_TRUE(SimulateMissileBarrageCheckProc(0x20000000, 99)); + + // Combined flags should also work if Arcane Blast is present + EXPECT_TRUE(SimulateMissileBarrageCheckProc(0x20000001, 99)); + EXPECT_TRUE(SimulateMissileBarrageCheckProc(0x20000020, 99)); + EXPECT_TRUE(SimulateMissileBarrageCheckProc(0xFFFFFFFF, 99)); +} From bb5485b197efa52c6b03ff9d9619603ffd297d05 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 18 Feb 2026 11:32:59 +0000 Subject: [PATCH 153/335] chore(DB): import pending files Referenced commit(s): 4599f26ae9cda03394bd6dc5902b946266c65f3a --- .../rev_1766547838660651694.sql => db_world/2026_02_18_01.sql} | 1 + .../rev_1769292856469402686.sql => db_world/2026_02_18_02.sql} | 1 + .../rev_1769396722032747978.sql => db_world/2026_02_18_03.sql} | 1 + .../rev_1769728867586741519.sql => db_world/2026_02_18_04.sql} | 1 + .../rev_1769815350392767493.sql => db_world/2026_02_18_05.sql} | 1 + .../rev_1769974041727457907.sql => db_world/2026_02_18_06.sql} | 1 + .../rev_1769983684458633094.sql => db_world/2026_02_18_07.sql} | 1 + 7 files changed, 7 insertions(+) rename data/sql/updates/{pending_db_world/rev_1766547838660651694.sql => db_world/2026_02_18_01.sql} (99%) rename data/sql/updates/{pending_db_world/rev_1769292856469402686.sql => db_world/2026_02_18_02.sql} (99%) rename data/sql/updates/{pending_db_world/rev_1769396722032747978.sql => db_world/2026_02_18_03.sql} (94%) rename data/sql/updates/{pending_db_world/rev_1769728867586741519.sql => db_world/2026_02_18_04.sql} (96%) rename data/sql/updates/{pending_db_world/rev_1769815350392767493.sql => db_world/2026_02_18_05.sql} (82%) rename data/sql/updates/{pending_db_world/rev_1769974041727457907.sql => db_world/2026_02_18_06.sql} (79%) rename data/sql/updates/{pending_db_world/rev_1769983684458633094.sql => db_world/2026_02_18_07.sql} (90%) diff --git a/data/sql/updates/pending_db_world/rev_1766547838660651694.sql b/data/sql/updates/db_world/2026_02_18_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1766547838660651694.sql rename to data/sql/updates/db_world/2026_02_18_01.sql index 0fe6f5bbe..3e49c01a4 100644 --- a/data/sql/updates/pending_db_world/rev_1766547838660651694.sql +++ b/data/sql/updates/db_world/2026_02_18_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_18_00 -> 2026_02_18_01 -- QAston Proc System - Base spell_proc entries -- Port from TrinityCore QAston proc system commits diff --git a/data/sql/updates/pending_db_world/rev_1769292856469402686.sql b/data/sql/updates/db_world/2026_02_18_02.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1769292856469402686.sql rename to data/sql/updates/db_world/2026_02_18_02.sql index ad6cd3321..544f74628 100644 --- a/data/sql/updates/pending_db_world/rev_1769292856469402686.sql +++ b/data/sql/updates/db_world/2026_02_18_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_18_01 -> 2026_02_18_02 -- Lock and Load - Add spell_proc entry with correct SpellPhaseMask for periodic damage procs -- SpellPhaseMask changed from 4 (PROC_SPELL_PHASE_FINISH) to 2 (PROC_SPELL_PHASE_HIT) -- This allows Black Arrow, Explosive Trap, and Immolation Trap periodic damage to trigger Lock and Load diff --git a/data/sql/updates/pending_db_world/rev_1769396722032747978.sql b/data/sql/updates/db_world/2026_02_18_03.sql similarity index 94% rename from data/sql/updates/pending_db_world/rev_1769396722032747978.sql rename to data/sql/updates/db_world/2026_02_18_03.sql index 608335533..9c7706e13 100644 --- a/data/sql/updates/pending_db_world/rev_1769396722032747978.sql +++ b/data/sql/updates/db_world/2026_02_18_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_18_02 -> 2026_02_18_03 -- DELETE FROM `spell_script_names` WHERE `spell_id` IN (52179, 16246, 16191, -30881, 55278, 55328, 55329, 55330, 55332, 55333, 55335, 58589, 58590, 58591, 28820); INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES diff --git a/data/sql/updates/pending_db_world/rev_1769728867586741519.sql b/data/sql/updates/db_world/2026_02_18_04.sql similarity index 96% rename from data/sql/updates/pending_db_world/rev_1769728867586741519.sql rename to data/sql/updates/db_world/2026_02_18_04.sql index 5e420fa88..5ee1be53f 100644 --- a/data/sql/updates/pending_db_world/rev_1769728867586741519.sql +++ b/data/sql/updates/db_world/2026_02_18_04.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_18_03 -> 2026_02_18_04 -- Register Nether Protection spell script DELETE FROM `spell_script_names` WHERE `spell_id` = -30299; INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES diff --git a/data/sql/updates/pending_db_world/rev_1769815350392767493.sql b/data/sql/updates/db_world/2026_02_18_05.sql similarity index 82% rename from data/sql/updates/pending_db_world/rev_1769815350392767493.sql rename to data/sql/updates/db_world/2026_02_18_05.sql index 0674f3d60..f00a9d77b 100644 --- a/data/sql/updates/pending_db_world/rev_1769815350392767493.sql +++ b/data/sql/updates/db_world/2026_02_18_05.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_18_04 -> 2026_02_18_05 -- Hunter T9 4P Bonus - spell script registration DELETE FROM `spell_script_names` WHERE `spell_id` = 67151; INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES diff --git a/data/sql/updates/pending_db_world/rev_1769974041727457907.sql b/data/sql/updates/db_world/2026_02_18_06.sql similarity index 79% rename from data/sql/updates/pending_db_world/rev_1769974041727457907.sql rename to data/sql/updates/db_world/2026_02_18_06.sql index 830ecbf62..8875535db 100644 --- a/data/sql/updates/pending_db_world/rev_1769974041727457907.sql +++ b/data/sql/updates/db_world/2026_02_18_06.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_18_05 -> 2026_02_18_06 -- Omen of Clarity should only proc from damage and healing spells, not utility spells like Furor UPDATE `spell_proc` SET `SpellTypeMask` = 3 WHERE `SpellId` = 16864; diff --git a/data/sql/updates/pending_db_world/rev_1769983684458633094.sql b/data/sql/updates/db_world/2026_02_18_07.sql similarity index 90% rename from data/sql/updates/pending_db_world/rev_1769983684458633094.sql rename to data/sql/updates/db_world/2026_02_18_07.sql index 75c212cd0..32cbde817 100644 --- a/data/sql/updates/pending_db_world/rev_1769983684458633094.sql +++ b/data/sql/updates/db_world/2026_02_18_07.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_18_06 -> 2026_02_18_07 -- -- The Lightning Capacitor, Thunder Capacitor, Reign of the Dead/Unliving trinkets DELETE FROM `spell_script_names` WHERE `spell_id` IN (37657, 54841, 67712, 67758); From ab42ae45a7fdfdca59df1ba24b5ae00337f9a966 Mon Sep 17 00:00:00 2001 From: MkDev11 <94194147+MkDev11@users.noreply.github.com> Date: Wed, 18 Feb 2026 15:04:48 -0800 Subject: [PATCH 154/335] fix(DB/Quest): Slaves to Saronite RP scripting improvements (#24343) Co-authored-by: mkdev11 --- .../rev_slaves_to_saronite_rp.sql | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_slaves_to_saronite_rp.sql diff --git a/data/sql/updates/pending_db_world/rev_slaves_to_saronite_rp.sql b/data/sql/updates/pending_db_world/rev_slaves_to_saronite_rp.sql new file mode 100644 index 000000000..af30c27bb --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_slaves_to_saronite_rp.sql @@ -0,0 +1,102 @@ +-- Fix Slaves to Saronite RP scripting (Issue #24157) +-- https://github.com/azerothcore/azerothcore-wotlk/issues/24157 +-- +-- This PR was created with AI assistance (Windsurf/Cascade). +-- +-- Current behavior: +-- - Script 3139700: Slave runs to freedom (working correctly) +-- - Script 3139701: Slave yells and attacks (yelling is wrong per blizzlike) +-- +-- Blizzlike behavior per 2009 video evidence (https://www.youtube.com/watch?v=QeW_q-24Z28): +-- 1. Slave silently runs to freedom +-- 2. Slave emotes "goes into a frenzy!" and becomes hostile (NO yelling) +-- 3. Slave yells one of their quotes and runs to pit to jump (NEW) +-- +-- Changes: +-- 1. Gossip: cast 5429 on player; NpcFlags/EmoteState reset on respawn (template) +-- 2. Add third random outcome (pit-jumping with yell); three pit waypoints per sniffs +-- 3. Fix hostile behavior to use emote instead of yell +-- 4. Fix /say messages language from Orcish to Universal +-- 5. Add unknown voice whispers in Saronite Mines (spell_area 27769, area 4514) +-- 6. Freedom path and pit coordinates from in-game research (Gultask) +-- 7. Workaround (Gultask): run random script on gossip first, then cast 5429 on link; +-- pit outcome sets phase 1 and UPDATE (event 60) picks random pit (no actionlist overlap). + +-- ============================================================================ +-- 1. Gossip: Run random script first, then cast 5429 on link (fixes actionlist overlap). +-- MovementInform (event 34, pointId 1/2/3): jump then despawn 4000ms. +-- MovementInform pointId 4: freedom reached, despawn instant. +-- UPDATE phase 1: run random pit (3139703/4/5) so 1/3 chance without nested actionlist. +-- ============================================================================ +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 31397); +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 +(31397, 0, 0, 1, 62, 0, 100, 512, 10137, 0, 0, 0, 0, 0, 87, 3139700, 3139701, 3139702, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - On Gossip Option Selected - Run Random Script'), +(31397, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 5429, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - On Link - Cast 5429 on Player'), +(31397, 0, 2, 0, 0, 0, 100, 0, 1000, 1000, 14000, 14000, 0, 0, 11, 3148, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - IC - Cast Head Crack'), +(31397, 0, 3, 0, 1, 0, 15, 0, 10000, 30000, 50000, 70000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - OOC - Say text2'), +(31397, 0, 4, 5, 34, 0, 100, 0, 8, 1, 0, 0, 0, 0, 97, 15, 15, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6966.75, 2067.58, 482.553, 0, 'Saronite Mine Slave - On Reached Pit 1 - Jump To Pos'), +(31397, 0, 5, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 4000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - On Reached Pit 1 - Despawn In 4000 ms'), +(31397, 0, 6, 7, 34, 0, 100, 0, 8, 2, 0, 0, 0, 0, 97, 15, 15, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6904.17, 2026.23, 482.964, 0, 'Saronite Mine Slave - On Reached Pit 2 - Jump To Pos'), +(31397, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 4000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - On Reached Pit 2 - Despawn In 4000 ms'), +(31397, 0, 8, 9, 34, 0, 100, 0, 8, 3, 0, 0, 0, 0, 97, 15, 15, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6911.13, 1969.18, 488.24, 0, 'Saronite Mine Slave - On Reached Pit 3 - Jump To Pos'), +(31397, 0, 9, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 4000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - On Reached Pit 3 - Despawn In 4000 ms'), +(31397, 0, 10, 0, 60, 1, 100, 0, 1200, 1200, 0, 0, 0, 0, 87, 3139703, 3139704, 3139705, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - On Update Phase 1 - Run to Random Pit'), +(31397, 0, 11, 0, 34, 0, 100, 0, 8, 4, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - On Reached Freedom - Despawn Instant'); + +-- ============================================================================ +-- 2a. Freedom path: move to PointId 4 (7026.46, 1877.16, 533.62); MovementInform 4 despawns (31397 id 11). +-- ============================================================================ +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 3139700); +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 +(3139700, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - Actionlist - Close Gossip'), +(3139700, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - Actionlist - Remove Npc Flags Gossip'), +(3139700, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 33, 31866, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Saronite Mine Slave - Actionlist - Quest Credit Slaves to Saronite'), +(3139700, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 69, 4, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 7026.46, 1877.16, 533.627, 0, 'Saronite Mine Slave - Actionlist - Move To Freedom PointId 4'); + +-- ============================================================================ +-- 2b. Pit outcome: yell, set phase 1 (no quest credit; UPDATE event 60 on 31397 runs random pit). +-- ============================================================================ +DELETE FROM `smart_scripts` WHERE `entryorguid`=3139702 AND `source_type`=9; +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 +(3139702,9,0,0,0,0,100,0,0,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,'Saronite Mine Slave - On Script - Close Gossip'), +(3139702,9,1,0,0,0,100,0,0,0,0,0,0,0,83,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Saronite Mine Slave - On Script - Remove NPC Flag'), +(3139702,9,2,0,0,0,100,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Saronite Mine Slave - On Script - Yell (GroupID 0)'), +(3139702,9,3,0,0,0,100,0,0,0,0,0,0,0,59,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Saronite Mine Slave - On Script - Set Run On'), +(3139702,9,4,0,0,0,100,0,0,0,0,0,0,0,22,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Saronite Mine Slave - On Script - Set Event Phase 1'); + +-- Pit scripts: only Move to Pos with PointId; MovementInform on 31397 handles jump + despawn +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (3139703,3139704,3139705) AND `source_type`=9; +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 +(3139703,9,0,0,0,0,100,0,0,0,0,0,0,0,69,1,0,0,0,0,0,8,0,0,0,0,6966.371,2050.5237,519.42505,0,'Pit 1 - Move to pos PointId 1'), +(3139704,9,0,0,0,0,100,0,0,0,0,0,0,0,69,2,0,0,0,0,0,8,0,0,0,0,6915.9272,2025.5466,518.6113,0,'Pit 2 - Move to pos PointId 2'), +(3139705,9,0,0,0,0,100,0,0,0,0,0,0,0,69,3,0,0,0,0,0,8,0,0,0,0,6921.0854,1972.6857,523.33716,0,'Pit 3 - Move to pos PointId 3'); + +-- ============================================================================ +-- 3. Fix hostile behavior: emote "goes into a frenzy!" instead of yelling +-- ============================================================================ + +-- Add emote text (Type 16 = CHAT_MSG_MONSTER_EMOTE) +DELETE FROM `creature_text` WHERE `CreatureID`=31397 AND `GroupID`=2; +INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES +(31397,2,0,'%s goes into a frenzy!',16,0,100,0,0,0,36719,0,'Saronite Mine Slave - Frenzy Emote'); + +-- Update hostile script to use emote (GroupID 2) instead of yell (GroupID 0) +DELETE FROM `smart_scripts` WHERE `entryorguid`=3139701 AND `source_type`=9; +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 +(3139701,9,0,0,0,0,100,0,0,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,'Saronite Mine Slave - On Script - Close Gossip'), +(3139701,9,1,0,0,0,100,0,0,0,0,0,0,0,2,14,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Saronite Mine Slave - On Script - Set Faction Hostile'), +(3139701,9,2,0,0,0,100,0,0,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Saronite Mine Slave - On Script - Emote (GroupID 2 - frenzy)'), +(3139701,9,3,0,0,0,100,0,0,0,0,0,0,0,49,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,'Saronite Mine Slave - On Script - Attack'), +(3139701,9,4,0,0,0,100,0,0,0,0,0,0,0,11,8599,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Saronite Mine Slave - On Script - Cast Enrage'); + +-- ============================================================================ +-- 4. Fix /say messages language from Orcish (1) to Universal (0) +-- ============================================================================ +UPDATE `creature_text` SET `Language`=0 WHERE `CreatureID`=31397 AND `GroupID`=1; + +-- ============================================================================ +-- 5. Unknown voice whispers in Saronite Mines (same as Whisper Gulch) +-- ============================================================================ +DELETE FROM `spell_area` WHERE `spell` = 27769 AND `area` = 4514; +INSERT INTO `spell_area` (`spell`,`area`,`quest_start`,`quest_end`,`aura_spell`,`racemask`,`gender`,`autocast`,`quest_start_status`,`quest_end_status`) VALUES +(27769,4514,0,0,0,0,2,1,64,11); From f6f94db02b35646858be0edf4b3a25fce383ad2f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 18 Feb 2026 23:06:07 +0000 Subject: [PATCH 155/335] chore(DB): import pending files Referenced commit(s): ab42ae45a7fdfdca59df1ba24b5ae00337f9a966 --- .../rev_slaves_to_saronite_rp.sql => db_world/2026_02_18_08.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_slaves_to_saronite_rp.sql => db_world/2026_02_18_08.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_slaves_to_saronite_rp.sql b/data/sql/updates/db_world/2026_02_18_08.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_slaves_to_saronite_rp.sql rename to data/sql/updates/db_world/2026_02_18_08.sql index af30c27bb..6a5adf6a0 100644 --- a/data/sql/updates/pending_db_world/rev_slaves_to_saronite_rp.sql +++ b/data/sql/updates/db_world/2026_02_18_08.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_18_07 -> 2026_02_18_08 -- Fix Slaves to Saronite RP scripting (Issue #24157) -- https://github.com/azerothcore/azerothcore-wotlk/issues/24157 -- From 68b52001d3a11afeb2eb92ad341639501f0c2793 Mon Sep 17 00:00:00 2001 From: sudlud Date: Thu, 19 Feb 2026 02:04:32 +0100 Subject: [PATCH 156/335] fix(DB/Gameobject): Sniffed Values for 'InnTableTiny' spawns (#24744) --- .../rev_1771443569952388000.sql | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771443569952388000.sql diff --git a/data/sql/updates/pending_db_world/rev_1771443569952388000.sql b/data/sql/updates/pending_db_world/rev_1771443569952388000.sql new file mode 100644 index 000000000..33a5e5678 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771443569952388000.sql @@ -0,0 +1,40 @@ +-- Update gameobject 'InnTableTiny' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (180885)) AND (`guid` IN (240279, 240280, 240281, 240282, 240283, 240284)); +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 +(240279, 180885, 0, 0, 0, 1, 1, 1805.888916015625, 217.1336822509765625, 60.60018539428710937, 1.518436193466186523, 0, 0, 0.6883544921875, 0.725374460220336914, 120, 255, 1, "", 51943, NULL), +(240280, 180885, 1, 0, 0, 1, 1, 10050.326171875, 2118.060791015625, 1329.939697265625, 0.750490784645080566, 0, 0, 0.3665008544921875, 0.93041771650314331, 120, 255, 1, "", 51943, NULL), +(240281, 180885, 0, 0, 0, 1, 1, -5149.5244140625, -854.9305419921875, 508.43206787109375, 0.750490784645080566, 0, 0, 0.3665008544921875, 0.93041771650314331, 120, 255, 1, "", 51943, NULL), +(240282, 180885, 0, 0, 0, 1, 1, -9331.4423828125, 181.9913177490234375, 61.6300048828125, 0.750490784645080566, 0, 0, 0.3665008544921875, 0.93041771650314331, 120, 255, 1, "", 51943, NULL), +(240283, 180885, 1, 0, 0, 1, 1, 1176.8541259765625, -4464.08837890625, 21.34675025939941406, 0.750490784645080566, 0, 0, 0.3665008544921875, 0.93041771650314331, 120, 255, 1, "", 51943, NULL), +(240284, 180885, 1, 0, 0, 1, 1, -980.32989501953125, -71.845489501953125, 19.58780288696289062, 0.750490784645080566, 0, 0, 0.3665008544921875, 0.93041771650314331, 120, 255, 1, "", 46368, NULL); + +-- Day of the Dead +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (240279, 240280, 240281, 240282, 240283, 240284)); +INSERT INTO `game_event_gameobject` (`eventEntry`,`guid`) VALUES +(51, 240279), +(51, 240280), +(51, 240281), +(51, 240282), +(51, 240283), +(51, 240284); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (180885)) AND (`guid` IN (184, 185, 186, 187)); +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 +(184, 180885, 0, 0, 0, 1, 1, 1647.7454833984375, 233.8232421875, 62.59157180786132812, 2.321286916732788085, 0, 0, 0.917059898376464843, 0.398749500513076782, 120, 255, 1, "", 47612, NULL), +(185, 180885, 530, 0, 0, 1, 1, -4318.9775390625, -12442.326171875, 17.2803955078125, 0.750490784645080566, 0, 0, 0.3665008544921875, 0.93041771650314331, 120, 255, 1, "", 51943, NULL), +(186, 180885, 530, 0, 0, 1, 1, 9411.2724609375, -6838.46533203125, 16.24826431274414062, 1.518436193466186523, 0, 0, 0.6883544921875, 0.725374460220336914, 120, 255, 1, "", 51943, NULL), +(187, 180885, 571, 0, 0, 1, 1, 5848.79345703125, 767.888916015625, 640.4781494140625, 0.750490784645080566, 0, 0, 0.3665008544921875, 0.93041771650314331, 120, 255, 1, "", 46248, NULL); + +-- Lunar Festival +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 7) AND (`guid` IN (184)); +INSERT INTO `game_event_gameobject` (`eventEntry`,`guid`) VALUES +(7, 184); + +-- Day of the Dead +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (185, 186, 187)); +INSERT INTO `game_event_gameobject` (`eventEntry`,`guid`) VALUES +(51, 185), +(51, 186), +(51, 187); From 4cc6c3f1d29252ee36415b0546b9b8cb3d5c1083 Mon Sep 17 00:00:00 2001 From: sudlud Date: Thu, 19 Feb 2026 02:04:48 +0100 Subject: [PATCH 157/335] fix(DB/Gameobject): Sniffed Values for 'Candy Skulls' spawns (#24745) --- .../rev_1771445747231243200.sql | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771445747231243200.sql diff --git a/data/sql/updates/pending_db_world/rev_1771445747231243200.sql b/data/sql/updates/pending_db_world/rev_1771445747231243200.sql new file mode 100644 index 000000000..386572837 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771445747231243200.sql @@ -0,0 +1,43 @@ +-- Update gameobject 'Candy Skulls' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (195069)) AND (`guid` IN (240004, 240286, 240287, 240289, 240290, 240291, 240294, 240295, 240298, 240302, 240303, 240304, 240307, 240309, 240310, 240312, 240315, 240316)); +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 +(240004, 195069, 0, 0, 0, 1, 1, -9330.9794921875, 181.9184112548828125, 62.72217559814453125, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(240286, 195069, 0, 0, 0, 1, 1, -9331.4775390625, 181.4496612548828125, 62.7343292236328125, 5.393068790435791015, 0, 0, -0.43051052093505859, 0.902585566043853759, 120, 255, 1, "", 51943, NULL), +(240287, 195069, 0, 0, 0, 1, 1, -9332.0068359375, 182.0434112548828125, 62.68918991088867187, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 51943, NULL), +(240289, 195069, 0, 0, 0, 1, 1, -5149.046875, -855.00347900390625, 509.504302978515625, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(240290, 195069, 0, 0, 0, 1, 1, -5149.54541015625, -855.47222900390625, 509.469451904296875, 5.393068790435791015, 0, 0, -0.43051052093505859, 0.902585566043853759, 120, 255, 1, "", 51943, NULL), +(240291, 195069, 0, 0, 0, 1, 1, -5150.07470703125, -854.87847900390625, 509.49609375, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 51943, NULL), +(240294, 195069, 1, 0, 0, 1, 1, 10049.826171875, 2118.114501953125, 1331.0101318359375, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 51943, NULL), +(240295, 195069, 1, 0, 0, 1, 1, 10050.892578125, 2117.890625, 1331.0274658203125, 1.727874636650085449, 0, 0, 0.760405540466308593, 0.649448513984680175, 120, 255, 1, "", 51943, NULL), +(240298, 195069, 1, 0, 0, 1, 1, 10050.34765625, 2117.479248046875, 1330.9945068359375, 5.393068790435791015, 0, 0, -0.43051052093505859, 0.902585566043853759, 120, 255, 1, "", 51943, NULL), +(240302, 195069, 0, 0, 0, 1, 1, 1805.326416015625, 217.407989501953125, 61.5327301025390625, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 51943, NULL), +(240303, 195069, 0, 0, 0, 1, 1, 1805.85595703125, 216.814239501953125, 61.588623046875, 5.393068790435791015, 0, 0, -0.43051052093505859, 0.902585566043853759, 120, 255, 1, "", 51943, NULL), +(240304, 195069, 0, 0, 0, 1, 1, 1806.3541259765625, 217.282989501953125, 61.54374313354492187, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(240307, 195069, 1, 0, 0, 1, 1, 1176.2899169921875, -4464.03662109375, 22.45013999938964843, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 51943, NULL), +(240309, 195069, 1, 0, 0, 1, 1, 1177.3177490234375, -4464.16162109375, 22.46108245849609375, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(240310, 195069, 1, 0, 0, 1, 1, 1176.8194580078125, -4464.63037109375, 22.45066452026367187, 5.393068790435791015, 0, 0, -0.43051052093505859, 0.902585566043853759, 120, 255, 1, "", 51943, NULL), +(240312, 195069, 1, 0, 0, 1, 1, -979.8663330078125, -71.9184036254882812, 20.70171165466308593, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 46368, NULL), +(240315, 195069, 1, 0, 0, 1, 1, -980.89410400390625, -71.7934036254882812, 20.70992469787597656, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 46368, NULL), +(240316, 195069, 1, 0, 0, 1, 1, -980.36456298828125, -72.3871536254882812, 20.70847511291503906, 5.393068790435791015, 0, 0, -0.43051052093505859, 0.902585566043853759, 120, 255, 1, "", 46368, NULL); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (195069)) AND (`guid` IN (1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345)); +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 +(1333, 195069, 530, 0, 0, 1, 1, -1785.0538330078125, 4926.18408203125, -21.1391162872314453, 4.380776405334472656, 0, 0, -0.81411552429199218, 0.580702960491180419, 120, 255, 1, "", 51943, NULL), +(1334, 195069, 530, 0, 0, 1, 1, -1785.7864990234375, 4925.87353515625, -21.1390743255615234, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1335, 195069, 530, 0, 0, 1, 1, -1788.5833740234375, 4923.9052734375, -21.0877628326416015, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1336, 195069, 530, 0, 0, 1, 1, -1789.04345703125, 4923.306640625, -21.0878314971923828, 1.221729278564453125, 0, 0, 0.573575973510742187, 0.819152355194091796, 120, 255, 1, "", 51943, NULL), +(1337, 195069, 530, 0, 0, 1, 1, -4318.515625, -12442.3994140625, 18.40369224548339843, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(1338, 195069, 530, 0, 0, 1, 1, -4319.01416015625, -12442.8681640625, 18.41169166564941406, 5.393068790435791015, 0, 0, -0.43051052093505859, 0.902585566043853759, 120, 255, 1, "", 51943, NULL), +(1339, 195069, 530, 0, 0, 1, 1, -4319.54345703125, -12442.2744140625, 18.39897918701171875, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 51943, NULL), +(1340, 195069, 530, 0, 0, 1, 1, 9410.8037109375, -6838.18408203125, 17.31257820129394531, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 51943, NULL), +(1341, 195069, 530, 0, 0, 1, 1, 9411.3330078125, -6838.77783203125, 17.290008544921875, 5.393068790435791015, 0, 0, -0.43051052093505859, 0.902585566043853759, 120, 255, 1, "", 51943, NULL), +(1342, 195069, 530, 0, 0, 1, 1, 9411.83203125, -6838.30908203125, 17.33341217041015625, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(1343, 195069, 571, 0, 0, 1, 1, 5848.22900390625, 767.94097900390625, 641.64593505859375, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 46248, NULL), +(1344, 195069, 571, 0, 0, 1, 1, 5848.759765625, 767.34722900390625, 641.61102294921875, 5.393068790435791015, 0, 0, -0.43051052093505859, 0.902585566043853759, 120, 255, 1, "", 46248, NULL), +(1345, 195069, 571, 0, 0, 1, 1, 5849.25634765625, 767.81597900390625, 641.60101318359375, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 46248, NULL); + +-- enable all spawns for eventEntry 51 +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (SELECT `guid` FROM `gameobject` WHERE `id` IN (195069))); +INSERT INTO `game_event_gameobject` (SELECT 51, `guid` FROM `gameobject` WHERE `id` IN (195069)); From 1aba09f0bfc38140f55762e5e0804c3206660307 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 01:05:37 +0000 Subject: [PATCH 158/335] chore(DB): import pending files Referenced commit(s): 68b52001d3a11afeb2eb92ad341639501f0c2793 --- .../rev_1771443569952388000.sql => db_world/2026_02_19_00.sql} | 1 + .../rev_1771445747231243200.sql => db_world/2026_02_19_01.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1771443569952388000.sql => db_world/2026_02_19_00.sql} (98%) rename data/sql/updates/{pending_db_world/rev_1771445747231243200.sql => db_world/2026_02_19_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771443569952388000.sql b/data/sql/updates/db_world/2026_02_19_00.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1771443569952388000.sql rename to data/sql/updates/db_world/2026_02_19_00.sql index 33a5e5678..9115a6325 100644 --- a/data/sql/updates/pending_db_world/rev_1771443569952388000.sql +++ b/data/sql/updates/db_world/2026_02_19_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_18_08 -> 2026_02_19_00 -- Update gameobject 'InnTableTiny' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (180885)) AND (`guid` IN (240279, 240280, 240281, 240282, 240283, 240284)); diff --git a/data/sql/updates/pending_db_world/rev_1771445747231243200.sql b/data/sql/updates/db_world/2026_02_19_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771445747231243200.sql rename to data/sql/updates/db_world/2026_02_19_01.sql index 386572837..1202e8b4e 100644 --- a/data/sql/updates/pending_db_world/rev_1771445747231243200.sql +++ b/data/sql/updates/db_world/2026_02_19_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_19_00 -> 2026_02_19_01 -- Update gameobject 'Candy Skulls' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (195069)) AND (`guid` IN (240004, 240286, 240287, 240289, 240290, 240291, 240294, 240295, 240298, 240302, 240303, 240304, 240307, 240309, 240310, 240312, 240315, 240316)); From c1400db05d80f549044b70f5cdb500ef24228e6c Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Wed, 18 Feb 2026 22:53:38 -0600 Subject: [PATCH 159/335] fix(Core/Arena): persist personal rating when adding arena team member (#24743) Co-authored-by: blinkysc --- .../database/Database/Implementation/CharacterDatabase.cpp | 2 +- src/server/game/Battlegrounds/ArenaTeam.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 1b8650b49..43fa9cfbf 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -276,7 +276,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() // Arena teams PrepareStatement(CHAR_INS_ARENA_TEAM, "INSERT INTO arena_team (arenaTeamId, name, captainGuid, type, rating, backgroundColor, emblemStyle, emblemColor, borderStyle, borderColor) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_ARENA_TEAM_MEMBER, "INSERT INTO arena_team_member (arenaTeamId, guid) VALUES (?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_ARENA_TEAM_MEMBER, "INSERT INTO arena_team_member (arenaTeamId, guid, personalRating) VALUES (?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_ARENA_TEAM, "DELETE FROM arena_team WHERE arenaTeamId = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_ARENA_TEAM_MEMBERS, "DELETE FROM arena_team_member WHERE arenaTeamId = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_ARENA_TEAM_CAPTAIN, "UPDATE arena_team SET captainGuid = ? WHERE arenaTeamId = ?", CONNECTION_ASYNC); diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index dcd567d67..720270d92 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -180,6 +180,7 @@ bool ArenaTeam::AddMember(ObjectGuid playerGuid) stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ARENA_TEAM_MEMBER); stmt->SetData(0, TeamId); stmt->SetData(1, playerGuid.GetCounter()); + stmt->SetData(2, personalRating); CharacterDatabase.Execute(stmt); // Inform player if online From af83b62f7c9bc5c64868e890b899b27e970ad432 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 19 Feb 2026 07:04:42 -0600 Subject: [PATCH 160/335] fix(DB/Spell): Elemental Focus proc on hit instead of cast (#24753) Co-authored-by: blinkysc --- data/sql/updates/pending_db_world/rev_1771505895831244753.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771505895831244753.sql diff --git a/data/sql/updates/pending_db_world/rev_1771505895831244753.sql b/data/sql/updates/pending_db_world/rev_1771505895831244753.sql new file mode 100644 index 000000000..90b544310 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771505895831244753.sql @@ -0,0 +1,2 @@ +-- Elemental Focus (16164): change SpellPhaseMask from CAST (0x1) to HIT (0x2) +UPDATE `spell_proc` SET `SpellPhaseMask` = 2 WHERE `SpellId` = 16164; From 08cb2ab615af23baaebbd24bb9b294ac6588b776 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 13:05:50 +0000 Subject: [PATCH 161/335] chore(DB): import pending files Referenced commit(s): af83b62f7c9bc5c64868e890b899b27e970ad432 --- .../rev_1771505895831244753.sql => db_world/2026_02_19_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771505895831244753.sql => db_world/2026_02_19_02.sql} (77%) diff --git a/data/sql/updates/pending_db_world/rev_1771505895831244753.sql b/data/sql/updates/db_world/2026_02_19_02.sql similarity index 77% rename from data/sql/updates/pending_db_world/rev_1771505895831244753.sql rename to data/sql/updates/db_world/2026_02_19_02.sql index 90b544310..c4d0b2443 100644 --- a/data/sql/updates/pending_db_world/rev_1771505895831244753.sql +++ b/data/sql/updates/db_world/2026_02_19_02.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_19_01 -> 2026_02_19_02 -- Elemental Focus (16164): change SpellPhaseMask from CAST (0x1) to HIT (0x2) UPDATE `spell_proc` SET `SpellPhaseMask` = 2 WHERE `SpellId` = 16164; From 61e5cd7ac37e8bbf8d16416ed92cf542476ee897 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 19 Feb 2026 12:37:00 -0600 Subject: [PATCH 162/335] fix(Core/Spells): Combustion non-crit hits now add crit stacks (#24752) Co-authored-by: blinkysc --- .../pending_db_world/rev_1771505399132109970.sql | 4 ++++ src/server/scripts/Spells/spell_mage.cpp | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771505399132109970.sql diff --git a/data/sql/updates/pending_db_world/rev_1771505399132109970.sql b/data/sql/updates/pending_db_world/rev_1771505399132109970.sql new file mode 100644 index 000000000..6e6ca210b --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771505399132109970.sql @@ -0,0 +1,4 @@ +-- Enable charge tracking for Combustion (11129) +-- Charges were 0 (disabled), should be 3 to match DBC ProcCharges +-- Combustion should be removed after 3 critical strikes with Fire spells +UPDATE `spell_proc` SET `Charges` = 3 WHERE `SpellId` = 11129; diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index f8d5db149..3c6c7e42d 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -37,6 +37,7 @@ enum MageSpells SPELL_MAGE_BURNOUT_TRIGGER = 44450, SPELL_MAGE_IMPROVED_BLIZZARD_CHILLED = 12486, SPELL_MAGE_COMBUSTION = 11129, + SPELL_MAGE_COMBUSTION_PROC = 28682, SPELL_MAGE_COLD_SNAP = 11958, SPELL_MAGE_FOCUS_MAGIC_PROC = 54648, SPELL_MAGE_FROST_WARDING_R1 = 11189, @@ -997,10 +998,21 @@ class spell_mage_combustion : public AuraScript { PrepareAuraScript(spell_mage_combustion); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGE_COMBUSTION_PROC }); + } + bool CheckProc(ProcEventInfo& eventInfo) { - // Prevent charge consumption on non-crits - return eventInfo.GetHitMask() & PROC_EX_CRITICAL_HIT; + // Do not take charges, add a stack of crit buff + if (!(eventInfo.GetHitMask() & PROC_HIT_CRITICAL)) + { + eventInfo.GetActor()->CastSpell(static_cast(nullptr), SPELL_MAGE_COMBUSTION_PROC, true); + return false; + } + + return true; } void Register() override From 42ba48a9a9cfc80a04091b83de5c611971c13a50 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 18:40:21 +0000 Subject: [PATCH 163/335] chore(DB): import pending files Referenced commit(s): 61e5cd7ac37e8bbf8d16416ed92cf542476ee897 --- .../rev_1771505399132109970.sql => db_world/2026_02_19_03.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771505399132109970.sql => db_world/2026_02_19_03.sql} (85%) diff --git a/data/sql/updates/pending_db_world/rev_1771505399132109970.sql b/data/sql/updates/db_world/2026_02_19_03.sql similarity index 85% rename from data/sql/updates/pending_db_world/rev_1771505399132109970.sql rename to data/sql/updates/db_world/2026_02_19_03.sql index 6e6ca210b..0cfd1eae1 100644 --- a/data/sql/updates/pending_db_world/rev_1771505399132109970.sql +++ b/data/sql/updates/db_world/2026_02_19_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_19_02 -> 2026_02_19_03 -- Enable charge tracking for Combustion (11129) -- Charges were 0 (disabled), should be 3 to match DBC ProcCharges -- Combustion should be removed after 3 critical strikes with Fire spells From ab29745d6a2e361442acb0a105213453a0853cbc Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 19 Feb 2026 12:58:17 -0600 Subject: [PATCH 164/335] fix(Core/Spells): fix PPM proc chance calculation for healing spells (#24761) Co-authored-by: blinkysc --- .../rev_1771524241618710557.sql | 11 ++++++ src/server/game/Spells/Auras/SpellAuras.cpp | 5 ++- src/test/mocks/ProcChanceTestHelper.h | 8 ++-- .../game/Spells/SpellProcChanceTest.cpp | 37 +++++++++++++++++-- 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771524241618710557.sql diff --git a/data/sql/updates/pending_db_world/rev_1771524241618710557.sql b/data/sql/updates/pending_db_world/rev_1771524241618710557.sql new file mode 100644 index 000000000..fa345e0b4 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771524241618710557.sql @@ -0,0 +1,11 @@ +-- Soul Preserver (60510): add spell_proc entry to fix proc for non-Paladin healers +-- Auto-generated entry had SpellFamilyName=10 (Paladin) which blocked other classes +-- ProcFlags 0x4400: DONE_SPELL_MAGIC_DMG_CLASS_POS + DONE_SPELL_NONE_DMG_CLASS_POS (direct heals + HoTs) +-- SpellTypeMask 6: HEAL + NO_DMG_HEAL (HoT applications) +DELETE FROM `spell_proc` WHERE `SpellId` = 60510; +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) +VALUES (60510, 0, 0, 0, 0, 0, 0x4400, 6, 2, 0, 0, 0, 0, 0, 0, 0); + +-- Spark of Life (60519): add DONE_SPELL_NONE_DMG_CLASS_POS (0x400) and NO_DMG_HEAL to SpellTypeMask +-- Allows HoT casts to trigger the proc +UPDATE `spell_proc` SET `ProcFlags` = 0x14400, `SpellTypeMask` = 7 WHERE `SpellId` = 60519; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 63da507eb..0ea002cff 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2280,13 +2280,14 @@ float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& event if (Unit* caster = GetCaster()) { // If PPM exists calculate chance from PPM - if (eventInfo.GetDamageInfo() && procEntry.ProcsPerMinute != 0) + if ((eventInfo.GetDamageInfo() || eventInfo.GetHealInfo()) && procEntry.ProcsPerMinute != 0) { SpellInfo const* procSpell = eventInfo.GetSpellInfo(); uint32 attackSpeed = 0; if (!procSpell || procSpell->DmgClass == SPELL_DAMAGE_CLASS_MELEE || procSpell->IsRangedWeaponSpell()) { - attackSpeed = caster->GetAttackTime(eventInfo.GetDamageInfo()->GetAttackType()); + if (eventInfo.GetDamageInfo()) + attackSpeed = caster->GetAttackTime(eventInfo.GetDamageInfo()->GetAttackType()); } else // spells use their cast time for PPM calculations { diff --git a/src/test/mocks/ProcChanceTestHelper.h b/src/test/mocks/ProcChanceTestHelper.h index 58436973d..32a3dac98 100644 --- a/src/test/mocks/ProcChanceTestHelper.h +++ b/src/test/mocks/ProcChanceTestHelper.h @@ -79,6 +79,7 @@ public: * @param chanceModifier Talent/aura modifier to chance * @param ppmModifier Talent/aura modifier to PPM * @param hasDamageInfo Whether a DamageInfo is present (enables PPM) + * @param hasHealInfo Whether a HealInfo is present (also enables PPM) * @return Calculated proc chance */ static float SimulateCalcProcChance( @@ -87,12 +88,13 @@ public: uint32 weaponSpeed = 2500, float chanceModifier = 0.0f, float ppmModifier = 0.0f, - bool hasDamageInfo = true) + bool hasDamageInfo = true, + bool hasHealInfo = false) { float chance = procEntry.Chance; - // PPM calculation overrides base chance if PPM > 0 and we have DamageInfo - if (hasDamageInfo && procEntry.ProcsPerMinute > 0.0f) + // PPM calculation overrides base chance if PPM > 0 and we have DamageInfo or HealInfo + if ((hasDamageInfo || hasHealInfo) && procEntry.ProcsPerMinute > 0.0f) { chance = CalculatePPMChance(weaponSpeed, procEntry.ProcsPerMinute, ppmModifier); } diff --git a/src/test/server/game/Spells/SpellProcChanceTest.cpp b/src/test/server/game/Spells/SpellProcChanceTest.cpp index 7c7f6fbbf..189f36823 100644 --- a/src/test/server/game/Spells/SpellProcChanceTest.cpp +++ b/src/test/server/game/Spells/SpellProcChanceTest.cpp @@ -91,19 +91,50 @@ TEST_F(SpellProcChanceTest, PPM_OverridesBaseChance_WithDamageInfo) EXPECT_NEAR(result, 25.0f, 0.01f); } -TEST_F(SpellProcChanceTest, PPM_NotApplied_WithoutDamageInfo) +TEST_F(SpellProcChanceTest, PPM_NotApplied_WithoutDamageOrHealInfo) { auto procEntry = SpellProcEntryBuilder() .WithChance(50.0f) .WithProcsPerMinute(6.0f) .Build(); - // Without DamageInfo, base chance is used + // Without DamageInfo or HealInfo, base chance is used float result = ProcChanceTestHelper::SimulateCalcProcChance( - procEntry, 80, 2500, 0.0f, 0.0f, false); + procEntry, 80, 2500, 0.0f, 0.0f, false, false); EXPECT_NEAR(result, 50.0f, 0.01f); } +TEST_F(SpellProcChanceTest, PPM_Applied_WithHealInfo) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(0.0f) + .WithProcsPerMinute(3.5f) + .Build(); + + // With HealInfo (no DamageInfo), PPM should still calculate + // 3000ms cast time * 3.5 PPM / 600 = 17.5% + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 3000, 0.0f, 0.0f, false, true); + EXPECT_NEAR(result, 17.5f, 0.01f); +} + +TEST_F(SpellProcChanceTest, PPM_HealInfo_ZeroBaseChance_WouldBeZeroWithoutFix) +{ + // Reproduces the Omen of Clarity healing bug: + // PPM=3.5, Chance=0, and only HealInfo present (no DamageInfo) + // Without the fix, chance would be 0% because PPM branch was skipped + auto procEntry = SpellProcEntryBuilder() + .WithChance(0.0f) + .WithProcsPerMinute(3.5f) + .Build(); + + // Instant cast uses 1500ms minimum + float result = ProcChanceTestHelper::SimulateCalcProcChance( + procEntry, 80, 1500, 0.0f, 0.0f, false, true); + EXPECT_NEAR(result, 8.75f, 0.01f); + EXPECT_GT(result, 0.0f) << "PPM with HealInfo must produce non-zero chance"; +} + TEST_F(SpellProcChanceTest, PPM_WithWeaponSpeedVariation) { auto procEntry = SpellProcEntryBuilder() From 96b51b1dd407b94b938af6ab14d72ce8c6a94c1c Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 19 Feb 2026 12:58:32 -0600 Subject: [PATCH 165/335] fix(Core/Spells): fix DoEffectCalcAmount receiving amount without spell power (#24759) Co-authored-by: blinkysc Co-authored-by: ariel- --- .../game/Spells/Auras/SpellAuraEffects.cpp | 3 +- .../game/Spells/WildGrowthTickScalingTest.cpp | 214 ++++++++++++++++++ 2 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 src/test/server/game/Spells/WildGrowthTickScalingTest.cpp diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 7a3b2edf4..3651fae12 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -552,7 +552,6 @@ int32 AuraEffect::CalculateAmount(Unit* caster) // xinef: save base amount, before calculating sp etc. Used for Unit::CastDelayedSpellWithPeriodicAmount SetOldAmount(amount * GetBase()->GetStackAmount()); - GetBase()->CallScriptEffectCalcAmountHandlers(this, amount, m_canBeRecalculated); // Xinef: Periodic auras if (caster) @@ -576,6 +575,8 @@ int32 AuraEffect::CalculateAmount(Unit* caster) break; } + GetBase()->CallScriptEffectCalcAmountHandlers(this, amount, m_canBeRecalculated); + amount *= GetBase()->GetStackAmount(); return amount; } diff --git a/src/test/server/game/Spells/WildGrowthTickScalingTest.cpp b/src/test/server/game/Spells/WildGrowthTickScalingTest.cpp new file mode 100644 index 000000000..cd0d33472 --- /dev/null +++ b/src/test/server/game/Spells/WildGrowthTickScalingTest.cpp @@ -0,0 +1,214 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file WildGrowthTickScalingTest.cpp + * @brief Tests for Wild Growth tick scaling formula + * + * Wild Growth heals with a front-loaded pattern: first tick heals most, + * each subsequent tick heals less. The formula (from spell_dru_wild_growth_aura): + * + * bonus = 6.0 - baseReduction * (tickNumber - 1) + * amount = baseTick + baseTick * bonus / 100 + * + * Where baseTick MUST include caster spell power bonuses (set via + * DoEffectCalcAmount, which runs after SpellHealingBonusDone in + * CalculateAmount). See TrinityCore issue #21281. + * + * baseReduction defaults to 2.0, reduced by T10 Restoration 2P Bonus. + * Wild Growth has 7 ticks (7s duration, 1s amplitude). + */ + +#include "gtest/gtest.h" + +#include +#include +#include +#include + +namespace +{ + constexpr int32_t TOTAL_TICKS = 7; + constexpr float DEFAULT_REDUCTION = 2.0f; + + /// Mirrors CalculatePct from Define.h: base * pct / 100 + template + T CalcPct(T base, float pct) + { + return static_cast(base * pct / 100.0f); + } + + /// Mirrors spell_dru_wild_growth_aura::HandleTickUpdate + int32_t CalcWildGrowthTickAmount(int32_t baseTick, uint32_t tickNumber, float baseReduction) + { + float reduction = baseReduction * static_cast(tickNumber - 1); + float bonus = 6.0f - reduction; + return static_cast(baseTick + CalcPct(baseTick, bonus)); + } + + /// Calculate all tick amounts for a Wild Growth cast + std::vector CalcAllTicks(int32_t baseTick, float baseReduction = DEFAULT_REDUCTION) + { + std::vector ticks; + ticks.reserve(TOTAL_TICKS); + for (uint32_t i = 1; i <= TOTAL_TICKS; ++i) + ticks.push_back(CalcWildGrowthTickAmount(baseTick, i, baseReduction)); + return ticks; + } +} + +class WildGrowthTickScalingTest : public ::testing::Test {}; + +// ============================================================================= +// Formula correctness with spell power included in baseTick +// ============================================================================= + +TEST_F(WildGrowthTickScalingTest, FirstTickIsHighest) +{ + // baseTick=600 simulates a spell-power-inclusive value + auto ticks = CalcAllTicks(600); + + for (int i = 1; i < TOTAL_TICKS; ++i) + EXPECT_GT(ticks[0], ticks[i]) << "Tick 1 should be highest, but tick " << (i + 1) << " is higher"; +} + +TEST_F(WildGrowthTickScalingTest, LastTickIsLowest) +{ + auto ticks = CalcAllTicks(600); + + for (int i = 0; i < TOTAL_TICKS - 1; ++i) + EXPECT_LT(ticks[TOTAL_TICKS - 1], ticks[i]) << "Tick 7 should be lowest, but tick " << (i + 1) << " is lower"; +} + +TEST_F(WildGrowthTickScalingTest, TicksAreMonotonicallyDecreasing) +{ + auto ticks = CalcAllTicks(600); + + for (int i = 1; i < TOTAL_TICKS; ++i) + EXPECT_LE(ticks[i], ticks[i - 1]) << "Tick " << (i + 1) << " should be <= tick " << i; +} + +TEST_F(WildGrowthTickScalingTest, TotalHealingPreserved) +{ + // Sum of all ticks should equal 7 * baseTick (scaling is symmetric) + int32_t const baseTick = 600; + auto ticks = CalcAllTicks(baseTick); + + int32_t totalHealing = std::accumulate(ticks.begin(), ticks.end(), 0); + int32_t expectedTotal = baseTick * TOTAL_TICKS; + + // Allow +-1 per tick for integer truncation + EXPECT_NEAR(totalHealing, expectedTotal, TOTAL_TICKS); +} + +TEST_F(WildGrowthTickScalingTest, MiddleTickEqualsBase) +{ + // Tick 4 (middle) has 0% bonus, so it equals baseTick exactly + int32_t const baseTick = 600; + int32_t tick4 = CalcWildGrowthTickAmount(baseTick, 4, DEFAULT_REDUCTION); + + EXPECT_EQ(tick4, baseTick); +} + +// ============================================================================= +// Specific tick values with spell power +// ============================================================================= + +TEST_F(WildGrowthTickScalingTest, TickValues_WithSpellPower) +{ + // baseTick = 600 (raw base ~206 + spell power ~394) + int32_t const baseTick = 600; + auto ticks = CalcAllTicks(baseTick); + + // Tick 1: 600 + 6% = 636 + EXPECT_EQ(ticks[0], 636); + // Tick 2: 600 + 4% = 624 + EXPECT_EQ(ticks[1], 624); + // Tick 3: 600 + 2% = 612 + EXPECT_EQ(ticks[2], 612); + // Tick 4: 600 + 0% = 600 + EXPECT_EQ(ticks[3], 600); + // Tick 5: 600 - 2% = 588 + EXPECT_EQ(ticks[4], 588); + // Tick 6: 600 - 4% = 576 + EXPECT_EQ(ticks[5], 576); + // Tick 7: 600 - 6% = 564 + EXPECT_EQ(ticks[6], 564); +} + +TEST_F(WildGrowthTickScalingTest, TickValues_RawBaseOnly_WouldBeBroken) +{ + // If baseTick were only the raw base (206) without spell power, + // ticks would be far too low. This documents the bug from + // TrinityCore #21281 / AC's CallScriptEffectCalcAmountHandlers + // ordering issue. + int32_t const rawBase = 206; + auto ticks = CalcAllTicks(rawBase); + + // Tick 1 without spell power: 206 + 6% = 218 + EXPECT_EQ(ticks[0], 218); + // This is ~1/3 of the correct value (636), matching the player report + EXPECT_LT(ticks[0], 636 / 2) << "Raw base ticks are less than half the SP-inclusive value"; +} + +// ============================================================================= +// T10 Restoration 2P Bonus (reduces tick drop-off rate) +// ============================================================================= + +TEST_F(WildGrowthTickScalingTest, T10_2P_ReducesReduction) +{ + // T10 2P reduces the drop rate. If bonus amount is 30%, + // baseReduction = 2.0 - 2.0 * 30/100 = 1.4 + float baseReduction = DEFAULT_REDUCTION; + float t10BonusAmount = 30.0f; + baseReduction -= baseReduction * t10BonusAmount / 100.0f; + EXPECT_FLOAT_EQ(baseReduction, 1.4f); + + auto ticks = CalcAllTicks(600, baseReduction); + + // With reduced drop-off, ticks are more uniform + // First tick: 600 + 6% = 636 (unchanged, bonus starts at 6%) + EXPECT_EQ(ticks[0], 636); + // Last tick: 600 + (6 - 1.4*6)% = 600 + (-2.4)% = 600 - 14.4 -> 586 + EXPECT_EQ(ticks[TOTAL_TICKS - 1], 586); + + // Range is smaller with T10 2P + int32_t rangeWithT10 = ticks[0] - ticks[TOTAL_TICKS - 1]; + auto normalTicks = CalcAllTicks(600); + int32_t rangeNormal = normalTicks[0] - normalTicks[TOTAL_TICKS - 1]; + + EXPECT_LT(rangeWithT10, rangeNormal) << "T10 2P should reduce tick-to-tick variance"; +} + +TEST_F(WildGrowthTickScalingTest, T10_2P_TotalHealingPreserved) +{ + float baseReduction = DEFAULT_REDUCTION; + baseReduction -= baseReduction * 30.0f / 100.0f; + + int32_t const baseTick = 600; + auto ticks = CalcAllTicks(baseTick, baseReduction); + + int32_t totalHealing = std::accumulate(ticks.begin(), ticks.end(), 0); + int32_t expectedTotal = baseTick * TOTAL_TICKS; + + // With T10 2P the scaling is asymmetric (bonus starts at +6% but + // only drops by 1.4% per tick instead of 2%), so total healing is + // slightly higher than 7 * baseTick. This is expected and matches TC. + EXPECT_GT(totalHealing, expectedTotal); + // Should not exceed ~2% above baseline + EXPECT_LT(totalHealing, expectedTotal * 102 / 100); +} From 47568e42c5c2a733bc6a9780a62fba06f9eb9c24 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 19 Feb 2026 12:58:46 -0600 Subject: [PATCH 166/335] fix(Core/Spells): fix FINISH phase proc targeting for triggered spells (#24757) Co-authored-by: blinkysc Co-authored-by: Mykhailo Redko Co-authored-by: Claude Opus 4.6 --- .../game/Spells/Auras/SpellAuraEffects.cpp | 8 +- src/server/game/Spells/Auras/SpellAuras.cpp | 1 + src/server/game/Spells/Spell.cpp | 2 +- .../Spells/SpellProcTargetResolutionTest.cpp | 204 ++++++++++++++++++ 4 files changed, 211 insertions(+), 4 deletions(-) create mode 100644 src/test/server/game/Spells/SpellProcTargetResolutionTest.cpp diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 3651fae12..43f9b3adc 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -7217,7 +7217,7 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) { Unit* triggerCaster = aurApp->GetTarget(); - Unit* triggerTarget = eventInfo.GetProcTarget(); + Unit* triggerTarget = triggerCaster == eventInfo.GetActor() ? eventInfo.GetActionTarget() : eventInfo.GetActor(); uint32 triggerSpellId = GetSpellInfo()->Effects[GetEffIndex()].TriggerSpell; if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId)) @@ -7234,7 +7234,7 @@ void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEve void AuraEffect::HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) { Unit* triggerCaster = aurApp->GetTarget(); - Unit* triggerTarget = eventInfo.GetProcTarget(); + Unit* triggerTarget = triggerCaster == eventInfo.GetActor() ? eventInfo.GetActionTarget() : eventInfo.GetActor(); uint32 triggerSpellId = GetSpellInfo()->Effects[m_effIndex].TriggerSpell; if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId)) @@ -7255,7 +7255,9 @@ void AuraEffect::HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp void AuraEffect::HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) { Unit* target = aurApp->GetTarget(); - Unit* triggerTarget = eventInfo.GetProcTarget(); + Unit* triggerTarget = target == eventInfo.GetActor() ? eventInfo.GetActionTarget() : eventInfo.GetActor(); + if (!triggerTarget) + return; if (triggerTarget->HasUnitState(UNIT_STATE_ISOLATED) || triggerTarget->IsImmunedToDamageOrSchool(GetSpellInfo())) { SendTickImmune(triggerTarget, target); diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 0ea002cff..bdab990fa 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2266,6 +2266,7 @@ uint8 Aura::GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo, } float procChance = CalcProcChance(*procEntry, eventInfo); + if (roll_chance_f(procChance)) return procEffectMask; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 02cea67fd..768b00405 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4269,7 +4269,7 @@ void Spell::_handle_finish_phase() break; } - Unit::ProcSkillsAndAuras(m_originalCaster, m_originalCaster, procAttacker, PROC_FLAG_NONE, hitMask, 1, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell.spellInfo, + Unit::ProcSkillsAndAuras(m_originalCaster, nullptr, procAttacker, PROC_FLAG_NONE, hitMask, 1, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell.spellInfo, m_triggeredByAuraSpell.effectIndex, this, nullptr, nullptr, PROC_SPELL_PHASE_FINISH); } } diff --git a/src/test/server/game/Spells/SpellProcTargetResolutionTest.cpp b/src/test/server/game/Spells/SpellProcTargetResolutionTest.cpp new file mode 100644 index 000000000..602f690f9 --- /dev/null +++ b/src/test/server/game/Spells/SpellProcTargetResolutionTest.cpp @@ -0,0 +1,204 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file SpellProcTargetResolutionTest.cpp + * @brief Tests for smart proc trigger target resolution + * + * Verifies the targeting expression used in HandleProcTriggerSpellAuraProc + * and HandleProcTriggerSpellWithValueAuraProc: + * + * triggerTarget = (triggerCaster == actor) ? actionTarget : actor + * + * This expression correctly resolves targets for all proc scenarios: + * - Actor-side HIT phase: triggerCaster==actor, returns enemy (actionTarget) + * - Actor-side FINISH phase: triggerCaster==actor, returns nullptr (actionTarget + * is nullptr because FINISH phase passes no victim) + * - Victim-side HIT phase: triggerCaster!=actor, returns attacker (actor) + */ + +#include "ProcEventInfoHelper.h" +#include "Unit.h" +#include "gtest/gtest.h" + +// Use fake Unit* pointers for testing. The smart targeting expression only +// performs pointer comparison (==), never dereferences, so these are safe. +namespace +{ + Unit* const FAKE_ROGUE = reinterpret_cast(uintptr_t(0x1000)); + Unit* const FAKE_ENEMY = reinterpret_cast(uintptr_t(0x2000)); +} + +/** + * @brief Applies the smart targeting expression from SpellAuraEffects.cpp + * + * This mirrors the logic in HandleProcTriggerSpellAuraProc: + * Unit* triggerCaster = aurApp->GetTarget(); // the aura owner + * Unit* triggerTarget = triggerCaster == eventInfo.GetActor() + * ? eventInfo.GetActionTarget() + * : eventInfo.GetActor(); + */ +static Unit* ResolveProcTriggerTarget(Unit* triggerCaster, ProcEventInfo& eventInfo) +{ + return triggerCaster == eventInfo.GetActor() + ? eventInfo.GetActionTarget() + : eventInfo.GetActor(); +} + +class SpellProcTargetResolutionTest : public ::testing::Test {}; + +// ============================================================================= +// Actor-side proc scenarios (aura owner == event actor) +// ============================================================================= + +TEST_F(SpellProcTargetResolutionTest, ActorSide_HitPhase_TargetsEnemy) +{ + // Scenario: Rogue has Ruthlessness aura, casts Eviscerate on enemy. + // HIT phase: actor=Rogue, actionTarget=Enemy + // triggerCaster is the aura owner (Rogue), which == actor + // Result: returns actionTarget (Enemy) + auto eventInfo = ProcEventInfoBuilder() + .WithActor(FAKE_ROGUE) + .WithActionTarget(FAKE_ENEMY) + .WithTypeMask(PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + Unit* triggerCaster = FAKE_ROGUE; // aura owner + Unit* result = ResolveProcTriggerTarget(triggerCaster, eventInfo); + + EXPECT_EQ(result, FAKE_ENEMY); +} + +TEST_F(SpellProcTargetResolutionTest, ActorSide_FinishPhase_ReturnsNullptr) +{ + // Scenario: Rogue has Ruthlessness aura, finishes Eviscerate. + // FINISH phase: actor=Rogue, actionTarget=nullptr (no victim passed) + // triggerCaster is the aura owner (Rogue), which == actor + // Result: returns nullptr (CastSpell handles this via implicit targeting) + auto eventInfo = ProcEventInfoBuilder() + .WithActor(FAKE_ROGUE) + .WithActionTarget(nullptr) + .WithTypeMask(PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS) + .WithSpellPhaseMask(PROC_SPELL_PHASE_FINISH) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + Unit* triggerCaster = FAKE_ROGUE; // aura owner + Unit* result = ResolveProcTriggerTarget(triggerCaster, eventInfo); + + EXPECT_EQ(result, nullptr); +} + +TEST_F(SpellProcTargetResolutionTest, ActorSide_CastPhase_TargetsEnemy) +{ + // Scenario: Actor-side CAST phase proc (e.g., Nature's Grace). + // actor=Rogue, actionTarget=Enemy + // triggerCaster == actor, returns actionTarget + auto eventInfo = ProcEventInfoBuilder() + .WithActor(FAKE_ROGUE) + .WithActionTarget(FAKE_ENEMY) + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + .WithSpellPhaseMask(PROC_SPELL_PHASE_CAST) + .Build(); + + Unit* triggerCaster = FAKE_ROGUE; + Unit* result = ResolveProcTriggerTarget(triggerCaster, eventInfo); + + EXPECT_EQ(result, FAKE_ENEMY); +} + +// ============================================================================= +// Victim-side proc scenarios (aura owner != event actor) +// ============================================================================= + +TEST_F(SpellProcTargetResolutionTest, VictimSide_HitPhase_TargetsAttacker) +{ + // Scenario: Enemy has a "when hit" proc aura. Rogue hits Enemy. + // HIT phase: actor=Rogue (attacker), actionTarget=Enemy (victim) + // triggerCaster is the aura owner (Enemy), which != actor (Rogue) + // Result: returns actor (Rogue) — the attacker + auto eventInfo = ProcEventInfoBuilder() + .WithActor(FAKE_ROGUE) + .WithActionTarget(FAKE_ENEMY) + .WithTypeMask(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + Unit* triggerCaster = FAKE_ENEMY; // aura owner (victim) + Unit* result = ResolveProcTriggerTarget(triggerCaster, eventInfo); + + EXPECT_EQ(result, FAKE_ROGUE); +} + +// ============================================================================= +// Edge cases +// ============================================================================= + +TEST_F(SpellProcTargetResolutionTest, ActorSide_NullActionTarget_ReturnsNullptr) +{ + // Generic test: when actor-side proc has nullptr actionTarget, + // result is nullptr regardless of phase + auto eventInfo = ProcEventInfoBuilder() + .WithActor(FAKE_ROGUE) + .WithActionTarget(nullptr) + .WithTypeMask(PROC_FLAG_DONE_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + Unit* triggerCaster = FAKE_ROGUE; + Unit* result = ResolveProcTriggerTarget(triggerCaster, eventInfo); + + EXPECT_EQ(result, nullptr); +} + +TEST_F(SpellProcTargetResolutionTest, VictimSide_NullActionTarget_StillReturnsActor) +{ + // When victim-side proc has nullptr actionTarget, the expression + // still returns actor (the attacker) since triggerCaster != actor + auto eventInfo = ProcEventInfoBuilder() + .WithActor(FAKE_ROGUE) + .WithActionTarget(nullptr) + .WithTypeMask(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + Unit* triggerCaster = FAKE_ENEMY; // aura owner (victim), != actor + Unit* result = ResolveProcTriggerTarget(triggerCaster, eventInfo); + + EXPECT_EQ(result, FAKE_ROGUE); +} + +TEST_F(SpellProcTargetResolutionTest, SelfProc_ActorIsActionTarget) +{ + // Edge case: actor == actionTarget (self-damage/self-heal) + // triggerCaster == actor, returns actionTarget (which is also actor) + auto eventInfo = ProcEventInfoBuilder() + .WithActor(FAKE_ROGUE) + .WithActionTarget(FAKE_ROGUE) + .WithTypeMask(PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithHitMask(PROC_HIT_NORMAL) + .Build(); + + Unit* triggerCaster = FAKE_ROGUE; + Unit* result = ResolveProcTriggerTarget(triggerCaster, eventInfo); + + EXPECT_EQ(result, FAKE_ROGUE); +} From 0f4bd870dce1885fedf671dfc0ddff2e446b8a4c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 18:59:23 +0000 Subject: [PATCH 167/335] chore(DB): import pending files Referenced commit(s): ab29745d6a2e361442acb0a105213453a0853cbc --- .../rev_1771524241618710557.sql => db_world/2026_02_19_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771524241618710557.sql => db_world/2026_02_19_04.sql} (95%) diff --git a/data/sql/updates/pending_db_world/rev_1771524241618710557.sql b/data/sql/updates/db_world/2026_02_19_04.sql similarity index 95% rename from data/sql/updates/pending_db_world/rev_1771524241618710557.sql rename to data/sql/updates/db_world/2026_02_19_04.sql index fa345e0b4..571a43bef 100644 --- a/data/sql/updates/pending_db_world/rev_1771524241618710557.sql +++ b/data/sql/updates/db_world/2026_02_19_04.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_19_03 -> 2026_02_19_04 -- Soul Preserver (60510): add spell_proc entry to fix proc for non-Paladin healers -- Auto-generated entry had SpellFamilyName=10 (Paladin) which blocked other classes -- ProcFlags 0x4400: DONE_SPELL_MAGIC_DMG_CLASS_POS + DONE_SPELL_NONE_DMG_CLASS_POS (direct heals + HoTs) From e54e280e60986291c1ea3b7581aef99c4ed27f0b Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 19 Feb 2026 14:25:06 -0600 Subject: [PATCH 168/335] fix(Core/Spells): fix Lock and Load not proccing from Frost Trap (#24762) Co-authored-by: blinkysc --- .../updates/pending_db_world/rev_1771530276818524334.sql | 2 ++ src/server/game/Spells/Spell.cpp | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771530276818524334.sql diff --git a/data/sql/updates/pending_db_world/rev_1771530276818524334.sql b/data/sql/updates/pending_db_world/rev_1771530276818524334.sql new file mode 100644 index 000000000..92d6a5e9e --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771530276818524334.sql @@ -0,0 +1,2 @@ +-- Lock and Load (-56342): fix SpellPhaseMask from HIT (2) to FINISH (4) +UPDATE `spell_proc` SET `SpellPhaseMask` = 4 WHERE `SpellId` = -56342; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 768b00405..856eafe78 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2242,9 +2242,13 @@ void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/) if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc - m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap + m_spellInfo->SpellFamilyFlags[2] & 0x00024000)) // Explosive and Immolation Trap { m_procAttacker |= PROC_FLAG_DONE_TRAP_ACTIVATION; + + // also fill up other flags (TargetInfo::DoDamageAndTriggers only fills up flag if both are not set) + m_procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG; + m_procVictim |= PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG; } /* Effects which are result of aura proc from triggered spell cannot proc From 082147fc47c21ab4c4632bd8254c396ddcc3e3f6 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 19 Feb 2026 14:25:35 -0600 Subject: [PATCH 169/335] refactor(Core/Spells): remove defensive DamageInfo guard in PPM calc (#24763) Co-authored-by: blinkysc --- src/server/game/Spells/Auras/SpellAuras.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index bdab990fa..a6fa20e6c 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2287,8 +2287,7 @@ float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& event uint32 attackSpeed = 0; if (!procSpell || procSpell->DmgClass == SPELL_DAMAGE_CLASS_MELEE || procSpell->IsRangedWeaponSpell()) { - if (eventInfo.GetDamageInfo()) - attackSpeed = caster->GetAttackTime(eventInfo.GetDamageInfo()->GetAttackType()); + attackSpeed = caster->GetAttackTime(eventInfo.GetDamageInfo()->GetAttackType()); } else // spells use their cast time for PPM calculations { From e135e83183d26da86825ee74171afe6a2cd7d481 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 19 Feb 2026 14:29:08 -0600 Subject: [PATCH 170/335] fix(Scripts/Spells): fix Blood Presence not healing for damage dealt (#24765) Co-authored-by: blinkysc Co-authored-by: mik1893 --- .../rev_1771531781265186556.sql | 2 ++ src/server/scripts/Spells/spell_dk.cpp | 29 +++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771531781265186556.sql diff --git a/data/sql/updates/pending_db_world/rev_1771531781265186556.sql b/data/sql/updates/pending_db_world/rev_1771531781265186556.sql new file mode 100644 index 000000000..35eaa2c31 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771531781265186556.sql @@ -0,0 +1,2 @@ +-- Blood Presence (63611): rename script to match new class name +UPDATE `spell_script_names` SET `ScriptName` = 'spell_dk_improved_blood_presence_triggered' WHERE `spell_id` = 63611; diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 7b164e32d..06afadf85 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -60,6 +60,7 @@ enum DeathKnightSpells SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1 = 50365, SPELL_DK_IMPROVED_FROST_PRESENCE_R1 = 50384, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_R1 = 50391, + SPELL_DK_IMPROVED_BLOOD_PRESENCE_HEAL = 50475, SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED = 63611, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622, SPELL_DK_ITEM_SIGIL_VENGEFUL_HEART = 64962, @@ -492,19 +493,35 @@ class spell_dk_summon_gargoyle : public SpellScript } }; -// 63611 - Improved Blood Presence -class spell_dk_improved_blood_presence_proc : public AuraScript +// 63611 - Improved Blood Presence Triggered +class spell_dk_improved_blood_presence_triggered : public AuraScript { - PrepareAuraScript(spell_dk_improved_blood_presence_proc); + PrepareAuraScript(spell_dk_improved_blood_presence_triggered); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DK_IMPROVED_BLOOD_PRESENCE_HEAL }); + } bool CheckProc(ProcEventInfo& eventInfo) { - return eventInfo.GetDamageInfo() && eventInfo.GetDamageInfo()->GetDamage(); + return eventInfo.GetActor()->IsPlayer(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (DamageInfo* dmgInfo = eventInfo.GetDamageInfo()) + { + int32 bp0 = CalculatePct(static_cast(dmgInfo->GetDamage()), aurEff->GetAmount()); + eventInfo.GetActor()->CastCustomSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_HEAL, SPELLVALUE_BASE_POINT0, bp0, eventInfo.GetActor(), true, nullptr, aurEff); + } } void Register() override { - DoCheckProc += AuraCheckProcFn(spell_dk_improved_blood_presence_proc::CheckProc); + DoCheckProc += AuraCheckProcFn(spell_dk_improved_blood_presence_triggered::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_improved_blood_presence_triggered::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -2995,7 +3012,7 @@ void AddSC_deathknight_spell_scripts() RegisterSpellAndAuraScriptPair(spell_dk_chains_of_ice, spell_dk_chains_of_ice_aura); RegisterSpellScript(spell_dk_bloodworms); RegisterSpellScript(spell_dk_summon_gargoyle); - RegisterSpellScript(spell_dk_improved_blood_presence_proc); + RegisterSpellScript(spell_dk_improved_blood_presence_triggered); RegisterSpellScript(spell_dk_wandering_plague_aura); RegisterSpellScript(spell_dk_rune_of_the_fallen_crusader); RegisterSpellScript(spell_dk_bone_shield); From cafb5eae4b4bb97749b3b2501037b479500b7462 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 20:48:07 +0000 Subject: [PATCH 171/335] chore(DB): import pending files Referenced commit(s): e54e280e60986291c1ea3b7581aef99c4ed27f0b --- .../rev_1771530276818524334.sql => db_world/2026_02_19_05.sql} | 1 + .../rev_1771531781265186556.sql => db_world/2026_02_19_06.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1771530276818524334.sql => db_world/2026_02_19_05.sql} (76%) rename data/sql/updates/{pending_db_world/rev_1771531781265186556.sql => db_world/2026_02_19_06.sql} (80%) diff --git a/data/sql/updates/pending_db_world/rev_1771530276818524334.sql b/data/sql/updates/db_world/2026_02_19_05.sql similarity index 76% rename from data/sql/updates/pending_db_world/rev_1771530276818524334.sql rename to data/sql/updates/db_world/2026_02_19_05.sql index 92d6a5e9e..7eeaffe45 100644 --- a/data/sql/updates/pending_db_world/rev_1771530276818524334.sql +++ b/data/sql/updates/db_world/2026_02_19_05.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_19_04 -> 2026_02_19_05 -- Lock and Load (-56342): fix SpellPhaseMask from HIT (2) to FINISH (4) UPDATE `spell_proc` SET `SpellPhaseMask` = 4 WHERE `SpellId` = -56342; diff --git a/data/sql/updates/pending_db_world/rev_1771531781265186556.sql b/data/sql/updates/db_world/2026_02_19_06.sql similarity index 80% rename from data/sql/updates/pending_db_world/rev_1771531781265186556.sql rename to data/sql/updates/db_world/2026_02_19_06.sql index 35eaa2c31..9560ff972 100644 --- a/data/sql/updates/pending_db_world/rev_1771531781265186556.sql +++ b/data/sql/updates/db_world/2026_02_19_06.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_19_05 -> 2026_02_19_06 -- Blood Presence (63611): rename script to match new class name UPDATE `spell_script_names` SET `ScriptName` = 'spell_dk_improved_blood_presence_triggered' WHERE `spell_id` = 63611; From 94a72339277016feaae8eb9b7fb7fbbe0ed454f7 Mon Sep 17 00:00:00 2001 From: sudlud Date: Thu, 19 Feb 2026 23:24:32 +0100 Subject: [PATCH 172/335] fix(DB/Gameobject): Sniffed Values for 'Ghostly Cooking Fire' spawns (#24764) --- .../rev_1771531668170920000.sql | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771531668170920000.sql diff --git a/data/sql/updates/pending_db_world/rev_1771531668170920000.sql b/data/sql/updates/pending_db_world/rev_1771531668170920000.sql new file mode 100644 index 000000000..6876bd99e --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771531668170920000.sql @@ -0,0 +1,18 @@ +-- Update gameobject 'Ghostly Cooking Fire' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (195087)) AND (`guid` IN (240012, 240013, 240017, 240018, 240019, 240020, 240021, 240022, 240023, 240024)); +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 +(240012, 195087, 0, 0, 0, 1, 1, -9329.9287109375, 180.2777862548828125, 61.687744140625, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(240013, 195087, 1, 0, 0, 1, 1, 1181.967041015625, -4466.10595703125, 21.32663726806640625, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(240017, 195087, 571, 0, 0, 1, 1, 5851.900390625, 765.91668701171875, 641.065185546875, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 46248, NULL), +(240018, 195087, 0, 0, 0, 1, 1, 1803.685791015625, 217.23785400390625, 60.58968734741210937, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(240019, 195087, 530, 0, 0, 1, 1, 9410.9521484375, -6840.46728515625, 16.09267234802246093, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(240020, 195087, 1, 0, 0, 1, 1, 10051.26953125, 2122.4306640625, 1329.9278564453125, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(240021, 195087, 1, 0, 0, 1, 1, -979.109375, -77.9027786254882812, 19.64342498779296875, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 46368, NULL), +(240022, 195087, 530, 0, 0, 1, 1, -4323.8974609375, -12446.646484375, 17.00409698486328125, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL), +(240023, 195087, 530, 0, 0, 1, 1, -1790.765625, 4923.8974609375, -21.7850627899169921, 0.942476630210876464, 0, 0, 0.453989982604980468, 0.891006767749786376, 120, 255, 1, "", 51943, NULL), +(240024, 195087, 0, 0, 0, 1, 1, -5147.767578125, -856.9913330078125, 508.491546630859375, 2.548179388046264648, 0, 0, 0.956304550170898437, 0.292372345924377441, 120, 255, 1, "", 51943, NULL); + +-- enable all spawns for eventEntry 51 +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (SELECT `guid` FROM `gameobject` WHERE `id` IN (195087))); +INSERT INTO `game_event_gameobject` (SELECT 51, `guid` FROM `gameobject` WHERE `id` IN (195087)); From 41dad1710ccb4c6a152c0e9bc397b664eeb216c8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 22:25:50 +0000 Subject: [PATCH 173/335] chore(DB): import pending files Referenced commit(s): 94a72339277016feaae8eb9b7fb7fbbe0ed454f7 --- .../rev_1771531668170920000.sql => db_world/2026_02_19_07.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771531668170920000.sql => db_world/2026_02_19_07.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1771531668170920000.sql b/data/sql/updates/db_world/2026_02_19_07.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1771531668170920000.sql rename to data/sql/updates/db_world/2026_02_19_07.sql index 6876bd99e..9f4d95bad 100644 --- a/data/sql/updates/pending_db_world/rev_1771531668170920000.sql +++ b/data/sql/updates/db_world/2026_02_19_07.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_19_06 -> 2026_02_19_07 -- Update gameobject 'Ghostly Cooking Fire' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (195087)) AND (`guid` IN (240012, 240013, 240017, 240018, 240019, 240020, 240021, 240022, 240023, 240024)); From 0cd5403d1220ac2b0e44cfce8c43a5c04e2d1268 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 19 Feb 2026 16:33:48 -0600 Subject: [PATCH 174/335] fix(Core/Spells): add per-aura SpellTypeMask for auto-generated procs (#24766) Co-authored-by: blinkysc Co-authored-by: ariel- --- src/server/game/Spells/SpellMgr.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index a2006ba45..c18449ec4 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1773,6 +1773,7 @@ void SpellMgr::LoadSpellGroupStackRules() static bool InitTriggerAuraData(); static bool isTriggerAura[TOTAL_AURAS]; static bool isAlwaysTriggeredAura[TOTAL_AURAS]; +static uint32 spellTypeMask[TOTAL_AURAS]; static bool procPrepared = InitTriggerAuraData(); // List of auras that CAN trigger but may not exist in spell_proc @@ -1785,6 +1786,7 @@ bool InitTriggerAuraData() { isTriggerAura[i] = false; isAlwaysTriggeredAura[i] = false; + spellTypeMask[i] = PROC_SPELL_TYPE_MASK_ALL; } isTriggerAura[SPELL_AURA_DUMMY] = true; // Most dummy auras should require scripting isTriggerAura[SPELL_AURA_MOD_CONFUSE] = true; // "Any direct damaging attack will revive targets" @@ -1828,6 +1830,13 @@ bool InitTriggerAuraData() isAlwaysTriggeredAura[SPELL_AURA_SCHOOL_ABSORB] = true; isAlwaysTriggeredAura[SPELL_AURA_MOD_STEALTH] = true; + spellTypeMask[SPELL_AURA_MOD_STEALTH] = PROC_SPELL_TYPE_DAMAGE | PROC_SPELL_TYPE_NO_DMG_HEAL; + spellTypeMask[SPELL_AURA_MOD_CONFUSE] = PROC_SPELL_TYPE_DAMAGE; + spellTypeMask[SPELL_AURA_MOD_FEAR] = PROC_SPELL_TYPE_DAMAGE; + spellTypeMask[SPELL_AURA_MOD_ROOT] = PROC_SPELL_TYPE_DAMAGE; + spellTypeMask[SPELL_AURA_MOD_STUN] = PROC_SPELL_TYPE_DAMAGE; + spellTypeMask[SPELL_AURA_TRANSFORM] = PROC_SPELL_TYPE_DAMAGE; + return true; } @@ -2000,6 +2009,7 @@ void SpellMgr::LoadSpellProcs() // Check if spell has any trigger aura effects bool found = false, addTriggerFlag = false; + uint32 procSpellTypeMask = PROC_SPELL_TYPE_NONE; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (!spellInfo->Effects[i].IsEffect()) @@ -2013,10 +2023,10 @@ void SpellMgr::LoadSpellProcs() continue; found = true; + procSpellTypeMask |= spellTypeMask[auraName]; if (!addTriggerFlag && isAlwaysTriggeredAura[auraName]) addTriggerFlag = true; - break; } if (!found) @@ -2038,7 +2048,7 @@ void SpellMgr::LoadSpellProcs() procEntry.SpellFamilyMask |= spellInfo->Effects[i].SpellClassMask; procEntry.ProcFlags = spellInfo->ProcFlags; - procEntry.SpellTypeMask = PROC_SPELL_TYPE_MASK_ALL; + procEntry.SpellTypeMask = procSpellTypeMask; procEntry.SpellPhaseMask = PROC_SPELL_PHASE_HIT; procEntry.HitMask = PROC_HIT_NONE; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent From 1665c4c36977f91027925e29476101912949381e Mon Sep 17 00:00:00 2001 From: sudlud Date: Fri, 20 Feb 2026 01:13:26 +0100 Subject: [PATCH 175/335] fix(DB/Gameobject): Sniffed Values for 'Orange Marigolds' spawns (#24767) --- .../rev_1771535608017994700.sql | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771535608017994700.sql diff --git a/data/sql/updates/pending_db_world/rev_1771535608017994700.sql b/data/sql/updates/pending_db_world/rev_1771535608017994700.sql new file mode 100644 index 000000000..fdc103a8c --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771535608017994700.sql @@ -0,0 +1,96 @@ +-- Update gameobject 'Orange Marigolds' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (195307, 195063)) AND (`guid` IN (240006, 240008, 240009, 240010, 240011, 240195, 240196, 240197, 240198, 240199, 240200, 240201, 240202, 240203, 240204, 240231, 240232, 240233, 240234, 240235, 240236, 240237, 240238, 240239, 240240, 240241, 240242, 240243, 240244, 240245, 240246, 240247, 240248, 240249, 240250, 240251, 240252, 240253, 240254, 240255, 240256, 240257, 240258, 240259, 240260, 240261, 240262)); +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 +(240006, 195307, 0, 0, 0, 1, 1, 1780.49658203125, 269.079864501953125, 59.82373046875, 3.001946926116943359, 0, 0, 0.997563362121582031, 0.069766148924827575, 120, 255, 1, "", 51943, NULL), +(240008, 195307, 1, 0, 0, 1, 1, 10054.2431640625, 2129.032958984375, 1329.6583251953125, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(240009, 195307, 0, 0, 0, 1, 1, 1792.5086669921875, 241.7743072509765625, 60.58672332763671875, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(240010, 195307, 1, 0, 0, 1, 1, 10053.81640625, 2127.782958984375, 1329.666259765625, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(240011, 195307, 1, 0, 0, 1, 1, 10049.7158203125, 2113.114501953125, 1329.6754150390625, 3.490667104721069335, 0, 0, -0.98480701446533203, 0.173652306199073791, 120, 255, 1, "", 51943, NULL), +(240195, 195307, 1, 0, 0, 1, 1, 10054.6357421875, 2131.958251953125, 1329.6578369140625, 3.52557229995727539, 0, 0, -0.98162651062011718, 0.190812408924102783, 120, 255, 1, "", 51943, NULL), +(240196, 195307, 1, 0, 0, 1, 1, 10062.8076171875, 2129.416748046875, 1329.6578369140625, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(240197, 195307, 0, 0, 0, 1, 1, -5159.658203125, -869.70831298828125, 507.315155029296875, 3.001946926116943359, 0, 0, 0.997563362121582031, 0.069766148924827575, 120, 255, 1, "", 51943, NULL), +(240198, 195307, 0, 0, 0, 1, 1, -5160.8037109375, -869.68402099609375, 507.250640869140625, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(240199, 195307, 0, 0, 0, 1, 1, -9328.341796875, 171.94097900390625, 62.83431625366210937, 3.001946926116943359, 0, 0, 0.997563362121582031, 0.069766148924827575, 120, 255, 1, "", 51943, NULL), +(240200, 195307, 0, 0, 0, 1, 1, -9351.12890625, 177.2621612548828125, 62.71487045288085937, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(240201, 195307, 1, 0, 0, 1, 1, 1171.9427490234375, -4462.66162109375, 21.31712722778320312, 3.001946926116943359, 0, 0, 0.997563362121582031, 0.069766148924827575, 120, 255, 1, "", 51943, NULL), +(240202, 195307, 1, 0, 0, 1, 1, 1177.21875, -4464.49658203125, 22.4542236328125, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(240203, 195307, 1, 0, 0, 1, 1, -984.53472900390625, -75.828125, 20.86415672302246093, 3.001946926116943359, 0, 0, 0.997563362121582031, 0.069766148924827575, 120, 255, 1, "", 46368, NULL), +(240204, 195307, 1, 0, 0, 1, 1, -979.9774169921875, -71.3420181274414062, 20.71724510192871093, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 46368, NULL), +(240231, 195063, 1, 0, 0, 1, 1, 1191.095458984375, -4465.376953125, 21.489013671875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240232, 195063, 1, 0, 0, 1, 1, 1176.060791015625, -4456.29541015625, 21.5271453857421875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240233, 195063, 1, 0, 0, 1, 1, 1185.154541015625, -4469.57275390625, 21.33182907104492187, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240234, 195063, 0, 0, 0, 1, 1, 1776.75, 250.7430572509765625, 59.88243484497070312, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240235, 195063, 0, 0, 0, 1, 1, 1782.6007080078125, 260.548614501953125, 59.42001724243164062, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240236, 195063, 0, 0, 0, 1, 1, 1776.3489990234375, 223.173614501953125, 59.50775146484375, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240237, 195063, 0, 0, 0, 1, 1, 1781.5989990234375, 252.3177032470703125, 59.52621841430664062, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240238, 195063, 0, 0, 0, 1, 1, 1779.51220703125, 268.923614501953125, 59.89298629760742187, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240239, 195063, 1, 0, 0, 1, 1, 10066.3837890625, 2120.482666015625, 1329.6578369140625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240240, 195063, 1, 0, 0, 1, 1, 10046.6630859375, 2110.079833984375, 1329.6492919921875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240241, 195063, 1, 0, 0, 1, 1, 10050.3095703125, 2118.569580078125, 1331.0484619140625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240242, 195063, 1, 0, 0, 1, 1, 10063.59765625, 2112.157958984375, 1329.65625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240243, 195063, 1, 0, 0, 1, 1, 10055.0166015625, 2111.276123046875, 1329.647705078125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240244, 195063, 0, 0, 0, 1, 1, -5158.9443359375, -869.95489501953125, 507.357269287109375, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240245, 195063, 0, 0, 0, 1, 1, -5160.0537109375, -871.75347900390625, 507.314666748046875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240246, 195063, 0, 0, 0, 1, 1, -5161.0400390625, -868.96875, 507.233306884765625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240247, 195063, 0, 0, 0, 1, 1, -5149.85791015625, -882.234375, 508.225311279296875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240248, 195063, 0, 0, 0, 1, 1, -5162.09912109375, -870.6007080078125, 507.185394287109375, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240249, 195063, 0, 0, 0, 1, 1, -5149.59033203125, -854.4288330078125, 509.498870849609375, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240250, 195063, 0, 0, 0, 1, 1, -9323.8876953125, 179.86285400390625, 64.642120361328125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240251, 195063, 0, 0, 0, 1, 1, -9330.9326171875, 172.33160400390625, 61.64415359497070312, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240252, 195063, 0, 0, 0, 1, 1, -9331.5224609375, 182.4930572509765625, 61.60004425048828125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240253, 195063, 0, 0, 0, 1, 1, -9334.95703125, 176.013885498046875, 63.38739013671875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240254, 195063, 0, 0, 0, 1, 1, -9340.6630859375, 187.5243072509765625, 61.55168914794921875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240255, 195063, 1, 0, 0, 1, 1, 1176.7742919921875, -4463.5869140625, 22.47352409362792968, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240256, 195063, 1, 0, 0, 1, 1, 1177.625, -4467.955078125, 21.30695915222167968, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240257, 195063, 1, 0, 0, 1, 1, 1174.7222900390625, -4455.4912109375, 21.53682327270507812, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240258, 195063, 1, 0, 0, 1, 1, -980.40972900390625, -71.34375, 20.71851539611816406, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL), +(240259, 195063, 1, 0, 0, 1, 1, -983.4930419921875, -72.6302108764648437, 20.66981315612792968, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL), +(240260, 195063, 1, 0, 0, 1, 1, -982.13018798828125, -68.0763931274414062, 20.8835906982421875, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL), +(240261, 195063, 1, 0, 0, 1, 1, -984.1492919921875, -77.3333358764648437, 20.75267982482910156, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL), +(240262, 195063, 1, 0, 0, 1, 1, -980.2117919921875, -80.2552108764648437, 20.06755256652832031, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (195063, 195307)) AND (`guid` IN (2690, 2691, 2692, 2693, 2694, 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712, 2713, 2714, 2715, 2716, 2717, 2718, 2719, 2720, 2721, 2722, 2723, 2724, 2725, 2726)); +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 +(2690, 195063, 0, 0, 0, 1, 1, -9327.30078125, 164.15625, 62.84149169921875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2691, 195063, 530, 0, 0, 1, 1, -1783.1336669921875, 4926.90966796875, -21.1390628814697265, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2692, 195063, 530, 0, 0, 1, 1, -1790.3194580078125, 4921.7265625, -21.0877933502197265, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2693, 195063, 530, 0, 0, 1, 1, -1791.41845703125, 4919.37255859375, -21.0256156921386718, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2694, 195063, 530, 0, 0, 1, 1, -1791.9566650390625, 4916.51904296875, -21.0255775451660156, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2695, 195063, 530, 0, 0, 1, 1, -1815.7413330078125, 4911.44970703125, -21.2438621520996093, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2696, 195063, 530, 0, 0, 1, 1, -1836.826416015625, 4923.66259765625, -21.1737899780273437, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2697, 195063, 530, 0, 0, 1, 1, -4310.8837890625, -12445.173828125, 17.40244865417480468, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2698, 195063, 530, 0, 0, 1, 1, -4315.609375, -12442.861328125, 17.24088859558105468, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2699, 195063, 530, 0, 0, 1, 1, -4318.97216796875, -12441.6318359375, 18.41204261779785156, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2700, 195063, 530, 0, 0, 1, 1, -4323.720703125, -12439.263671875, 17.49479103088378906, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2701, 195063, 530, 0, 0, 1, 1, -4325.501953125, -12449.763671875, 16.71574592590332031, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2702, 195063, 530, 0, 0, 1, 1, 9414.4443359375, -6857.546875, 14.74676513671875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2703, 195063, 530, 0, 0, 1, 1, 9415.4892578125, -6857.064453125, 14.79820919036865234, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2704, 195063, 530, 0, 0, 1, 1, 9416.951171875, -6845.9287109375, 15.41892528533935546, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2705, 195063, 530, 0, 0, 1, 1, 9418.0244140625, -6846.97216796875, 15.29443645477294921, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2706, 195063, 530, 0, 0, 1, 1, 9419.1689453125, -6852.986328125, 14.97407245635986328, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2707, 195063, 571, 0, 0, 1, 1, 5848.71435546875, 768.390625, 641.6309814453125, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL), +(2708, 195063, 571, 0, 0, 1, 1, 5849.20166015625, 772.20660400390625, 640.47674560546875, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL), +(2709, 195063, 571, 0, 0, 1, 1, 5850.00537109375, 771.921875, 640.58428955078125, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL), +(2710, 195063, 571, 0, 0, 1, 1, 5852.234375, 767.95489501953125, 641.10302734375, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL), +(2711, 195063, 571, 0, 0, 1, 1, 5856.7666015625, 766.2274169921875, 641.3299560546875, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL), +(2712, 195063, 571, 0, 0, 1, 1, 5857.072265625, 765.01214599609375, 641.21575927734375, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL), +(2713, 195307, 530, 0, 0, 1, 1, -1784.595458984375, 4926.28662109375, -21.1390972137451171, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(2714, 195307, 530, 0, 0, 1, 1, -1789.3541259765625, 4922.8515625, -21.0877628326416015, 1.291541695594787597, 0, 0, 0.60181427001953125, 0.798636078834533691, 120, 255, 1, "", 51943, NULL), +(2715, 195307, 530, 0, 0, 1, 1, -1830.345458984375, 4920.56884765625, -21.528116226196289, 0.436331570148468017, 0, 0, 0.216439247131347656, 0.976296067237854003, 120, 255, 1, "", 51943, NULL), +(2716, 195307, 530, 0, 0, 1, 1, -4310.455078125, -12444.986328125, 17.43355751037597656, 3.106652259826660156, 0, 0, 0.999847412109375, 0.017469281330704689, 120, 255, 1, "", 51943, NULL), +(2717, 195307, 530, 0, 0, 1, 1, -4319.09375, -12442, 18.40237808227539062, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(2718, 195307, 530, 0, 0, 1, 1, -4319.51904296875, -12455.021484375, 17.36684608459472656, 3.001946926116943359, 0, 0, 0.997563362121582031, 0.069766148924827575, 120, 255, 1, "", 51943, NULL), +(2719, 195307, 530, 0, 0, 1, 1, -4320.1962890625, -12452.8134765625, 17.29529380798339843, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(2720, 195307, 530, 0, 0, 1, 1, -4322.37841796875, -12439.0595703125, 17.53725242614746093, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(2721, 195307, 530, 0, 0, 1, 1, -4324.6181640625, -12440.138671875, 17.45537567138671875, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(2722, 195307, 530, 0, 0, 1, 1, -4324.97216796875, -12449.4482421875, 16.71002388000488281, 0.453785061836242675, 0, 0, 0.224950790405273437, 0.974370121955871582, 120, 255, 1, "", 51943, NULL), +(2723, 195307, 530, 0, 0, 1, 1, 9416.861328125, -6847.47900390625, 15.28504467010498046, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 51943, NULL), +(2724, 195307, 530, 0, 0, 1, 1, 9418.82421875, -6851.0537109375, 15.01081657409667968, 3.001946926116943359, 0, 0, 0.997563362121582031, 0.069766148924827575, 120, 255, 1, "", 51943, NULL), +(2725, 195307, 571, 0, 0, 1, 1, 5849.15869140625, 767.48089599609375, 641.58538818359375, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 120, 255, 1, "", 46248, NULL), +(2726, 195307, 571, 0, 0, 1, 1, 5852.81884765625, 768.201416015625, 642.14239501953125, 3.001946926116943359, 0, 0, 0.997563362121582031, 0.069766148924827575, 120, 255, 1, "", 46248, NULL); + +-- enable all spawns for eventEntry 51 +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (SELECT `guid` FROM `gameobject` WHERE `id` IN (195063, 195307))); +INSERT INTO `game_event_gameobject` (SELECT 51, `guid` FROM `gameobject` WHERE `id` IN (195063, 195307)); From 2203e4b0a93f8b68ea5ecd0d03dae322d114a142 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 20 Feb 2026 00:14:35 +0000 Subject: [PATCH 176/335] chore(DB): import pending files Referenced commit(s): 1665c4c36977f91027925e29476101912949381e --- .../rev_1771535608017994700.sql => db_world/2026_02_20_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771535608017994700.sql => db_world/2026_02_20_00.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771535608017994700.sql b/data/sql/updates/db_world/2026_02_20_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771535608017994700.sql rename to data/sql/updates/db_world/2026_02_20_00.sql index fdc103a8c..035488bdf 100644 --- a/data/sql/updates/pending_db_world/rev_1771535608017994700.sql +++ b/data/sql/updates/db_world/2026_02_20_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_19_07 -> 2026_02_20_00 -- Update gameobject 'Orange Marigolds' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (195307, 195063)) AND (`guid` IN (240006, 240008, 240009, 240010, 240011, 240195, 240196, 240197, 240198, 240199, 240200, 240201, 240202, 240203, 240204, 240231, 240232, 240233, 240234, 240235, 240236, 240237, 240238, 240239, 240240, 240241, 240242, 240243, 240244, 240245, 240246, 240247, 240248, 240249, 240250, 240251, 240252, 240253, 240254, 240255, 240256, 240257, 240258, 240259, 240260, 240261, 240262)); From ac7446fe1c2c047ee13b46b74c6e4a312967a33c Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 19 Feb 2026 21:03:50 -0600 Subject: [PATCH 177/335] fix(Core/Scripts): fix Pet Healing set bonus using heal info instead of damage info (#24768) Co-authored-by: blinkysc Co-authored-by: ariel- --- src/server/scripts/Spells/spell_item.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index e6dd1fcad..f2d237eda 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -5655,13 +5655,12 @@ class spell_item_pet_healing : public AuraScript void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - HealInfo* healInfo = eventInfo.GetHealInfo(); - if (!healInfo || !healInfo->GetHeal()) + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) return; - Unit* caster = eventInfo.GetActor(); - int32 bp0 = CalculatePct(static_cast(healInfo->GetHeal()), aurEff->GetAmount()); - caster->CastCustomSpell(SPELL_HEALTH_LINK, SPELLVALUE_BASE_POINT0, bp0, nullptr, true, nullptr, aurEff); + int32 bp0 = CalculatePct(static_cast(damageInfo->GetDamage()), aurEff->GetAmount()); + eventInfo.GetActor()->CastCustomSpell(SPELL_HEALTH_LINK, SPELLVALUE_BASE_POINT0, bp0, nullptr, true, nullptr, aurEff); } void Register() override From 188976dbea9c0ac5fd46c3b17897c1ec64318911 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 19 Feb 2026 23:29:23 -0600 Subject: [PATCH 178/335] fix(Core/Spells): Fingers of Frost proc and consumption with Blizzard (#24770) Co-authored-by: blinkysc --- .../rev_1771551013532224914.sql | 1 + src/server/scripts/Spells/spell_mage.cpp | 35 ++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771551013532224914.sql diff --git a/data/sql/updates/pending_db_world/rev_1771551013532224914.sql b/data/sql/updates/pending_db_world/rev_1771551013532224914.sql new file mode 100644 index 000000000..6dda33ef4 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771551013532224914.sql @@ -0,0 +1 @@ +UPDATE `spell_proc` SET `SpellPhaseMask` = 3, `AttributesMask` = 2 WHERE `SpellId` = 74396; diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index 3c6c7e42d..11b2f4bbf 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -930,8 +930,6 @@ class spell_mage_summon_water_elemental : public SpellScript }; // 74396 - Fingers of Frost -// Charge consumption is handled by the default proc system in PrepareProcToTrigger -// This script only handles removing the aura state aura (44544) when the buff expires class spell_mage_fingers_of_frost : public AuraScript { PrepareAuraScript(spell_mage_fingers_of_frost); @@ -941,6 +939,27 @@ class spell_mage_fingers_of_frost : public AuraScript return ValidateSpellInfo({ SPELL_MAGE_FINGERS_OF_FROST_AURASTATE_AURA }); } + void PrepareProc(ProcEventInfo& eventInfo) + { + if (Spell const* spell = eventInfo.GetProcSpell()) + { + bool isTriggered = spell->IsTriggered(); + bool isCastPhase = (eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST) != 0; + bool isChanneled = spell->GetSpellInfo()->IsChanneled(); + bool prevent = false; + + if (isTriggered) + prevent = false; + else if (isChanneled) + prevent = true; + else if (!isCastPhase) + prevent = true; + + if (prevent) + PreventDefaultAction(); + } + } + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { GetTarget()->RemoveAurasDueToSpell(SPELL_MAGE_FINGERS_OF_FROST_AURASTATE_AURA); @@ -948,6 +967,7 @@ class spell_mage_fingers_of_frost : public AuraScript void Register() override { + DoPrepareProc += AuraProcFn(spell_mage_fingers_of_frost::PrepareProc); AfterEffectRemove += AuraEffectRemoveFn(spell_mage_fingers_of_frost::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } }; @@ -1245,7 +1265,8 @@ class spell_mage_imp_blizzard : public AuraScript { SPELL_MAGE_CHILLED_R1, SPELL_MAGE_CHILLED_R2, - SPELL_MAGE_CHILLED_R3 + SPELL_MAGE_CHILLED_R3, + SPELL_MAGE_FINGERS_OF_FROST_AURASTATE_AURA }); } @@ -1262,8 +1283,14 @@ class spell_mage_imp_blizzard : public AuraScript default: return; } + Unit* caster = GetTarget(); if (Unit* target = eventInfo.GetProcTarget()) - GetTarget()->CastSpell(target, spellId, true, nullptr, aurEff); + caster->CastSpell(target, spellId, true, nullptr, aurEff); + + // Fingers of Frost: Blizzard chill effects can trigger FoF + if (AuraEffect const* fofTalent = caster->GetAuraEffectOfRankedSpell(SPELL_MAGE_FINGERS_OF_FROST, EFFECT_0)) + if (roll_chance_i(fofTalent->GetAmount())) + caster->CastSpell(caster, SPELL_MAGE_FINGERS_OF_FROST_AURASTATE_AURA, true); } void Register() override From 7102298d907a07e2eaf94304744166371fe90c9a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 20 Feb 2026 05:30:31 +0000 Subject: [PATCH 179/335] chore(DB): import pending files Referenced commit(s): 188976dbea9c0ac5fd46c3b17897c1ec64318911 --- .../rev_1771551013532224914.sql => db_world/2026_02_20_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771551013532224914.sql => db_world/2026_02_20_01.sql} (67%) diff --git a/data/sql/updates/pending_db_world/rev_1771551013532224914.sql b/data/sql/updates/db_world/2026_02_20_01.sql similarity index 67% rename from data/sql/updates/pending_db_world/rev_1771551013532224914.sql rename to data/sql/updates/db_world/2026_02_20_01.sql index 6dda33ef4..5c6017c61 100644 --- a/data/sql/updates/pending_db_world/rev_1771551013532224914.sql +++ b/data/sql/updates/db_world/2026_02_20_01.sql @@ -1 +1,2 @@ +-- DB update 2026_02_20_00 -> 2026_02_20_01 UPDATE `spell_proc` SET `SpellPhaseMask` = 3, `AttributesMask` = 2 WHERE `SpellId` = 74396; From 4b4fb0f90734bc849a526a55afe5552eb41b9608 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 20 Feb 2026 12:25:34 -0300 Subject: [PATCH 180/335] fix(DB/Loot): Loot Normalization Part 1 (#24398) --- .../updates/pending_db_world/lockboxes.sql | 287 + .../updates/pending_db_world/vanillaTBC.sql | 18284 ++++++++++++++++ data/sql/updates/pending_db_world/wotlk.sql | 4510 ++++ 3 files changed, 23081 insertions(+) create mode 100644 data/sql/updates/pending_db_world/lockboxes.sql create mode 100644 data/sql/updates/pending_db_world/vanillaTBC.sql create mode 100644 data/sql/updates/pending_db_world/wotlk.sql diff --git a/data/sql/updates/pending_db_world/lockboxes.sql b/data/sql/updates/pending_db_world/lockboxes.sql new file mode 100644 index 000000000..0656674ca --- /dev/null +++ b/data/sql/updates/pending_db_world/lockboxes.sql @@ -0,0 +1,287 @@ +-- Ornate Bronze Lockbox +DELETE FROM `item_loot_template` WHERE (`Entry` = 4632); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4632, 1, 4632, 100, 0, 1, 0, 1, 1, 'Ornate Bronze Lockbox - Guaranteed Loot'), +(4632, 2, 4632, 25, 0, 1, 0, 1, 1, 'Ornate Bronze Lockbox - Bonus Loot 1'), +(4632, 3, 4632, 5, 0, 1, 0, 1, 1, 'Ornate Bronze Lockbox - Bonus Loot 2'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 4632); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4632, 1206, 0, 3, 0, 1, 1, 1, 1, 'Moss Agate'), +(4632, 1210, 0, 1, 0, 1, 1, 1, 1, 'Shadowgem'), +(4632, 1705, 0, 1, 0, 1, 1, 1, 1, 'Lesser Moonstone'), +(4632, 1 , 1011822, 2, 0, 1, 1, 1, 1, 'Vanilla Whites 18-22 Level Range'), +(4632, 2 , 1011923, 2, 0, 1, 1, 1, 1, 'Vanilla Whites 19-23 Level Range'), +(4632, 3 , 1012024, 2, 0, 1, 1, 1, 1, 'Vanilla Whites 20-24 Level Range'), +(4632, 4 , 1012125, 2, 0, 1, 1, 1, 1, 'Vanilla Whites 21-25 Level Range'), +(4632, 5 , 1021620, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 16-20 Level Range'), +(4632, 6 , 1021721, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 17-21 Level Range'), +(4632, 7 , 1021822, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 18-22 Level Range'), +(4632, 8 , 1021923, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 19-23 Level Range'), +(4632, 9 , 1022024, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 20-24 Level Range'), +(4632, 10, 1022125, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 21-25 Level Range'), +(4632, 11, 1022226, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 22-26 Level Range'), +(4632, 12, 1022327, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 23-27 Level Range'), +(4632, 13, 1022428, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 24-28 Level Range'), +(4632, 14, 1032023, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 20-23 Level Range'), +(4632, 15, 1032124, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 21-24 Level Range'), +(4632, 16, 1032225, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 22-25 Level Range'), +(4632, 17, 1032326, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 23-26 Level Range'), +(4632, 18, 1032427, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 24-27 Level Range'), +(4632, 19, 1081225, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 12-25 Level Range'), +(4632, 20, 1081630, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 16-30 Level Range'), +(4632, 21, 1082035, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 20-35 Level Range'), +(4632, 22, 1092130, 5, 0, 1, 1, 1, 1, 'Vanilla Bags 10-Slot'); + +-- Heavy Bronze Lockbox +DELETE FROM `item_loot_template` WHERE (`Entry` = 4633); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4633, 1, 4633, 100, 0, 1, 0, 1, 1, 'Heavy Bronze Lockbox - Guaranteed Loot'), +(4633, 2, 4633, 25, 0, 1, 0, 1, 1, 'Heavy Bronze Lockbox - Bonus Loot 1'), +(4633, 3, 4633, 5, 0, 1, 0, 1, 1, 'Heavy Bronze Lockbox - Bonus Loot 2'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 4633); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4633, 1206, 0, 1, 0, 1, 1, 1, 1, 'Moss Agate'), +(4633, 1529, 0, 1, 0, 1, 1, 1, 1, 'Jade'), +(4633, 1705, 0, 3, 0, 1, 1, 1, 1, 'Lesser Moonstone'), +(4633, 1 , 1022226, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 22-26 Level Range'), +(4633, 2 , 1022327, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 23-27 Level Range'), +(4633, 3 , 1022428, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 24-28 Level Range'), +(4633, 4 , 1022529, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 25-29 Level Range'), +(4633, 5 , 1022630, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 26-30 Level Range'), +(4633, 6 , 1022731, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 27-31 Level Range'), +(4633, 7 , 1032528, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 25-28 Level Range'), +(4633, 8 , 1032629, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 26-29 Level Range'), +(4633, 9 , 1032730, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 27-30 Level Range'), +(4633, 10, 1032831, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 28-31 Level Range'), +(4633, 11, 1032932, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 29-32 Level Range'), +(4633, 12, 1081630, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 16-30 Level Range'), +(4633, 13, 1082035, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 20-35 Level Range'), +(4633, 14, 1082640, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 26-40 Level Range'), +(4633, 15, 1092130, 5, 0, 1, 1, 1, 1, 'Vanilla Bags 10-Slot'); + +-- Iron Lockbox +DELETE FROM `item_loot_template` WHERE (`Entry` = 4634); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4634, 1, 4634, 100, 0, 1, 0, 1, 1, 'Iron Lockbox - Guaranteed Loot'), +(4634, 2, 4634, 25, 0, 1, 0, 1, 1, 'Iron Lockbox - Bonus Loot 1'), +(4634, 3, 4634, 5, 0, 1, 0, 1, 1, 'Iron Lockbox - Bonus Loot 2'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 4634); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4634, 1529, 0, 1, 0, 1, 1, 1, 1, 'Jade'), +(4634, 1705, 0, 1, 0, 1, 1, 1, 1, 'Lesser Moonstone'), +(4634, 1725, 0, 5, 0, 1, 1, 1, 1, 'Large Knapsack'), +(4634, 3864, 0, 3, 0, 1, 1, 1, 1, 'Citrine'), +(4634, 4354, 0, 0.1, 0, 1, 1, 1, 1, 'Pattern: Rich Purple Silk Shirt'), +(4634, 1 , 1022832, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 28-32 Level Range'), +(4634, 2 , 1022933, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 29-33 Level Range'), +(4634, 3 , 1023034, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 30-34 Level Range'), +(4634, 4 , 1023135, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 31-35 Level Range'), +(4634, 5 , 1023236, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 32-36 Level Range'), +(4634, 6 , 1023337, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 33-37 Level Range'), +(4634, 7 , 1033134, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 31-34 Level Range'), +(4634, 8 , 1033235, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 32-35 Level Range'), +(4634, 9 , 1033336, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 33-36 Level Range'), +(4634, 10, 1033437, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 34-37 Level Range'), +(4634, 11, 1081630, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 16-30 Level Range'), +(4634, 12, 1082640, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 26-40 Level Range'), +(4634, 13, 1083045, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 30-45 Level Range'); + +-- Strong Iron Lockbox +DELETE FROM `item_loot_template` WHERE (`Entry` = 4636); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4636, 1, 4636, 100, 0, 1, 0, 1, 1, 'Strong Iron Lockbox - Guaranteed Loot'), +(4636, 2, 4636, 25, 0, 1, 0, 1, 1, 'Strong Iron Lockbox - Bonus Loot 1'), +(4636, 3, 4636, 5, 0, 1, 0, 1, 1, 'Strong Iron Lockbox - Bonus Loot 2'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 4636); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4636, 1529, 0, 1, 0, 1, 1, 1, 1, 'Jade'), +(4636, 1725, 0, 5, 0, 1, 1, 1, 1, 'Large Knapsack'), +(4636, 3864, 0, 3, 0, 1, 1, 1, 1, 'Citrine'), +(4636, 4354, 0, 0.1, 0, 1, 1, 1, 1, 'Pattern: Rich Purple Silk Shirt'), +(4636, 7909, 0, 1, 0, 1, 1, 1, 1, 'Aquamarine'), +(4636, 1 , 1023236, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 32-36 Level Range'), +(4636, 2 , 1023337, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 33-37 Level Range'), +(4636, 3 , 1023438, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 34-38 Level Range'), +(4636, 4 , 1023539, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 35-39 Level Range'), +(4636, 5 , 1023640, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 36-40 Level Range'), +(4636, 6 , 1023741, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 37-41 Level Range'), +(4636, 7 , 1023842, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 38-42 Level Range'), +(4636, 8 , 1023943, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 39-43 Level Range'), +(4636, 9 , 1033538, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 35-38 Level Range'), +(4636, 10, 1033639, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 36-39 Level Range'), +(4636, 11, 1033740, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 37-40 Level Range'), +(4636, 12, 1033841, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 38-41 Level Range'), +(4636, 13, 1033942, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 39-42 Level Range'), +(4636, 14, 1082640, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 26-40 Level Range'), +(4636, 15, 1083045, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 30-45 Level Range'), +(4636, 16, 1083650, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 36-50 Level Range'); + +-- Steel Lockbox +DELETE FROM `item_loot_template` WHERE (`Entry` = 4637); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4637, 1, 4637, 100, 0, 1, 0, 1, 1, 'Steel Lockbox - Guaranteed Loot'), +(4637, 2, 4637, 25, 0, 1, 0, 1, 1, 'Steel Lockbox - Bonus Loot 1'), +(4637, 3, 4637, 5, 0, 1, 0, 1, 1, 'Steel Lockbox - Bonus Loot 2'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 4637); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4637, 3864, 0, 1, 0, 1, 1, 1, 1, 'Citrine'), +(4637, 7909, 0, 3, 0, 1, 1, 1, 1, 'Aquamarine'), +(4637, 7910, 0, 1, 0, 1, 1, 1, 1, 'Star Ruby'), +(4637, 1 , 1023741, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 37-41 Level Range'), +(4637, 2 , 1023842, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 38-42 Level Range'), +(4637, 3 , 1023943, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 39-43 Level Range'), +(4637, 4 , 1024044, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 40-44 Level Range'), +(4637, 5 , 1024145, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 41-45 Level Range'), +(4637, 6 , 1024246, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 42-46 Level Range'), +(4637, 7 , 1034043, 1, 0, 1, 1, 1, 1, 'Vanilla Blues 40-43 Level Range'), +(4637, 8 , 1034144, 1, 0, 1, 1, 1, 1, 'Vanilla Blues 41-44 Level Range'), +(4637, 9 , 1034245, 1, 0, 1, 1, 1, 1, 'Vanilla Blues 42-45 Level Range'), +(4637, 10, 1083045, 3.33, 0, 1, 0, 1, 1, 'Vanilla Patterns 30-45 Level Range'), +(4637, 11, 1083650, 3.33, 0, 1, 0, 1, 1, 'Vanilla Patterns 36-50 Level Range'), +(4637, 12, 1084055, 3.33, 0, 1, 0, 1, 1, 'Vanilla Patterns 40-55 Level Range'), +(4637, 13, 1094150, 5, 0, 1, 1, 1, 1, 'Vanilla Bags 14-Slot'); + +-- Reinforced Steel Lockbox +DELETE FROM `item_loot_template` WHERE (`Entry` = 4638); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4638, 1, 4638, 100, 0, 1, 0, 1, 1, 'Reinforced Steel Lockbox - Guaranteed Loot'), +(4638, 2, 4638, 25, 0, 1, 0, 1, 1, 'Reinforced Steel Lockbox - Bonus Loot 1'), +(4638, 3, 4638, 5, 0, 1, 0, 1, 1, 'Reinforced Steel Lockbox - Bonus Loot 2'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 4638); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(4638, 7909, 0, 2.5, 0, 1, 1, 1, 1, 'Aquamarine'), +(4638, 7910, 0, 2.5, 0, 1, 1, 1, 1, 'Star Ruby'), +(4638, 1 , 1024347, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 43-47 Level Range'), +(4638, 2 , 1024448, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 44-48 Level Range'), +(4638, 3 , 1024549, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 45-49 Level Range'), +(4638, 4 , 1024650, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 46-50 Level Range'), +(4638, 5 , 1024751, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 47-51 Level Range'), +(4638, 6 , 1024852, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 48-52 Level Range'), +(4638, 7 , 1034548, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 45-48 Level Range'), +(4638, 8 , 1034649, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 46-49 Level Range'), +(4638, 9 , 1034750, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 47-50 Level Range'), +(4638, 10, 1034851, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 48-51 Level Range'), +(4638, 11, 1034952, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 49-52 Level Range'), +(4638, 12, 1083650, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 36-50 Level Range'), +(4638, 13, 1084055, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 40-55 Level Range'), +(4638, 14, 1084660, 3.33, 0, 1, 1, 1, 1, 'Vanilla Patterns 46-60 Level Range'), +(4638, 15, 1094150, 5, 0, 1, 1, 1, 1, 'Vanilla Bags 14-Slot'); + +-- Mithril Lockbox +DELETE FROM `item_loot_template` WHERE (`Entry` = 5758); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(5758, 1, 5758, 100, 0, 1, 0, 1, 1, 'Mithril Lockbox - Guaranteed Loot'), +(5758, 2, 5758, 25, 0, 1, 0, 1, 1, 'Mithril Lockbox - Bonus Loot 1'), +(5758, 3, 5758, 5, 0, 1, 0, 1, 1, 'Mithril Lockbox - Bonus Loot 2'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 5758); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(5758, 7909, 0, 2.5, 0, 1, 1, 1, 1, 'Aquamarine'), +(5758, 7910, 0, 2.5, 0, 1, 1, 1, 1, 'Star Ruby'), +(5758, 1 , 1024650, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 46-50 Level Range'), +(5758, 2 , 1024751, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 47-51 Level Range'), +(5758, 3 , 1024852, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 48-52 Level Range'), +(5758, 4 , 1024953, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 49-53 Level Range'), +(5758, 5 , 1025054, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 50-54 Level Range'), +(5758, 6 , 1025155, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 51-55 Level Range'), +(5758, 7 , 1025256, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 52-56 Level Range'), +(5758, 8 , 1025357, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 53-57 Level Range'), +(5758, 9 , 1035053, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 50-53 Level Range'), +(5758, 10, 1035154, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 51-54 Level Range'), +(5758, 11, 1035255, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 52-55 Level Range'), +(5758, 12, 1035356, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 53-56 Level Range'), +(5758, 13, 1035457, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 54-57 Level Range'), +(5758, 14, 1084055, 2.5, 0, 1, 1, 1, 1, 'Vanilla Patterns 40-55 Level Range'), +(5758, 15, 1084660, 2.5, 0, 1, 1, 1, 1, 'Vanilla Patterns 46-60 Level Range'), +(5758, 16, 1085063, 2.5, 0, 1, 1, 1, 1, 'Vanilla Patterns 50-63 Level Range'), +(5758, 17, 1085663, 2.5, 0, 1, 1, 1, 1, 'Vanilla Patterns 56-63 Level Range'), +(5758, 18, 1095162, 5, 0, 1, 1, 1, 1, 'Vanilla Bags 14 and 16 Slots'); + +-- Thorium Lockbox +DELETE FROM `item_loot_template` WHERE (`Entry` = 5759); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(5759, 1, 5759, 100, 0, 1, 0, 1, 1, 'Thorium Lockbox - Guaranteed Loot'), +(5759, 2, 5759, 25, 0, 1, 0, 1, 1, 'Thorium Lockbox - Bonus Loot 1'), +(5759, 3, 5759, 5, 0, 1, 0, 1, 1, 'Thorium Lockbox - Bonus Loot 2'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 5759); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(5759, 7909, 0, 2.5, 0, 1, 1, 1, 1, 'Aquamarine'), +(5759, 7910, 0, 2.5, 0, 1, 1, 1, 1, 'Star Ruby'), +(5759, 1 , 1025256, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 52-56 Level Range'), +(5759, 2 , 1025357, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 53-57 Level Range'), +(5759, 3 , 1025458, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 54-58 Level Range'), +(5759, 4 , 1025559, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 55-59 Level Range'), +(5759, 5 , 1025660, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 56-60 Level Range'), +(5759, 6 , 1025761, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 57-61 Level Range'), +(5759, 7 , 1035558, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 55-58 Level Range'), +(5759, 8 , 1035659, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 56-59 Level Range'), +(5759, 9 , 1035760, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 57-60 Level Range'), +(5759, 10, 1035861, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 58-61 Level Range'), +(5759, 11, 1035963, 0.5, 0, 1, 1, 1, 1, 'Vanilla Blues 59+ Level Range'), +(5759, 12, 1084055, 2.5, 0, 1, 1, 1, 1, 'Vanilla Patterns 40-55 Level Range'), +(5759, 13, 1084660, 2.5, 0, 1, 1, 1, 1, 'Vanilla Patterns 46-60 Level Range'), +(5759, 14, 1085063, 2.5, 0, 1, 1, 1, 1, 'Vanilla Patterns 50-63 Level Range'), +(5759, 15, 1085663, 2.5, 0, 1, 1, 1, 1, 'Vanilla Patterns 55-63 Level Range'), +(5759, 16, 1095162, 5, 0, 1, 1, 1, 1, 'Vanilla Bags 14 and 16 Slots'); + +-- Eternium Lockbox +DELETE FROM `item_loot_template` WHERE (`Entry` = 5760); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(5760, 1, 5760, 100, 0, 1, 0, 1, 1, 'Eternium Lockbox - Guaranteed Loot'), +(5760, 2, 5760, 25, 0, 1, 0, 1, 1, 'Eternium Lockbox - Bonus Loot 1'), +(5760, 3, 5760, 5, 0, 1, 0, 1, 1, 'Eternium Lockbox - Bonus Loot 2'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 5760); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(5760, 7909, 0, 2.5, 0, 1, 1, 1, 1, 'Aquamarine'), +(5760, 7910, 0, 2.5, 0, 1, 1, 1, 1, 'Star Ruby'), +(5760, 1 , 1025862, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 58-62 Level Range'), +(5760, 2 , 1025963, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 59-63 Level Range'), +(5760, 3 , 1026063, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 60-63 Level Range'), +(5760, 4 , 1026163, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 61-63 Level Range'), +(5760, 5 , 1026263, 0, 0, 1, 1, 1, 1, 'Vanilla Greens 62-63 Level Range'), +(5760, 6 , 1035760, 1, 0, 1, 1, 1, 1, 'Vanilla Blues 57-60 Level Range'), +(5760, 7 , 1035861, 1, 0, 1, 1, 1, 1, 'Vanilla Blues 58-61 Level Range'), +(5760, 8 , 1035963, 1, 0, 1, 1, 1, 1, 'Vanilla Blues 59+ Level Range'), +(5760, 9 , 1085063, 5, 0, 1, 1, 1, 1, 'Vanilla Patterns 50-63 Level Range'), +(5760, 10, 1085663, 5, 0, 1, 1, 1, 1, 'Vanilla Patterns 55-63 Level Range'), +(5760, 11, 1095162, 5, 0, 1, 1, 1, 1, 'Vanilla Bags 14 and 16 Slots'); + +-- Khorium Lockbox +DELETE FROM `item_loot_template` WHERE (`Entry` = 31952); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(31952, 1, 31952, 100, 0, 1, 0, 1, 1, 'Khorium Lockbox - Guaranteed Loot'), +(31952, 2, 31952, 25, 0, 1, 0, 1, 1, 'Khorium Lockbox - Bonus Loot 1'), +(31952, 3, 31952, 5, 0, 1, 0, 1, 1, 'Khorium Lockbox - Bonus Loot 2'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 31952); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(31952, 1, 1126668, 0, 0, 1, 1, 1, 1, 'TBC Greens 66-68 Level Range'), +(31952, 2, 1126769, 0, 0, 1, 1, 1, 1, 'TBC Greens 67-69 Level Range'), +(31952, 3, 1126870, 0, 0, 1, 1, 1, 1, 'TBC Greens 68-70 Level Range'), +(31952, 4, 1136568, 1, 0, 1, 1, 1, 1, 'TBC Blues 65-68 Level Range'), +(31952, 5, 1136669, 1, 0, 1, 1, 1, 1, 'TBC Blues 66-69 Level Range'), +(31952, 6, 1136770, 1, 0, 1, 1, 1, 1, 'TBC Blues 67-70 Level Range'); + +-- Froststeel Lockbox +DELETE FROM `item_loot_template` WHERE (`Entry` = 43622); +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(43622, 1, 43622, 100, 0, 1, 0, 1, 1, 'Froststeel Lockbox - Guaranteed Loot'), +(43622, 2, 43622, 25, 0, 1, 0, 1, 1, 'Froststeel Lockbox - Bonus Loot 1'), +(43622, 3, 43622, 5, 0, 1, 0, 1, 1, 'Froststeel Lockbox - Bonus Loot 2'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 43622); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(43622, 1, 1227173, 0, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(43622, 2, 1227274, 0, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(43622, 3, 1227375, 0, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(43622, 4, 1237173, 1, 0, 1, 1, 1, 1, 'WotLK Blues 71-73 Level Range'), +(43622, 5, 1237274, 1, 0, 1, 1, 1, 1, 'WotLK Blues 72-74 Level Range'), +(43622, 6, 1237375, 1, 0, 1, 1, 1, 1, 'WotLK Blues 73-75 Level Range'); diff --git a/data/sql/updates/pending_db_world/vanillaTBC.sql b/data/sql/updates/pending_db_world/vanillaTBC.sql new file mode 100644 index 000000000..ab28a55cd --- /dev/null +++ b/data/sql/updates/pending_db_world/vanillaTBC.sql @@ -0,0 +1,18284 @@ +-- Remove Old System References +DELETE FROM `reference_loot_template` WHERE `Entry` IN (1002125, 1012425, 1022425, 1032425, 1052130, 1062029, 1071930, 1080003, 1080016, 1000610, 1010506, 1050110, 1070518, 1080001, 1080013, 1001115, 1011112, 1021112, 1051120, 1061019, 1080002, 1080014, 1010607, 1020608, 1010809, 1020809, 1010910, 1020910, 1012122, 1022122, 1032122, 1010808, 1011111, 1021111, 1011010, 1021010, 1003140, 1023940, 1033940, 1043840, 1053140, 1064049, 1073545, 1080004, 1080020, 1001620, 1011718, 1021718, 1080015, 1011212, 1021212, 1011415, 1021415, 1011011, 1021011, 1011616, 1021616, 1011414, 1021414, 1011516, 1021516, 1011920, 1021920, 1031820, 1011213, 1021213, 1011819, 1021819, 1011617, 1021617, 1012324, 1022324, 1032324, 1012223, 1022223, 1032223, 1002630, 1022829, 1032829, 1080018, 1023030, 1033030, 1063039, 1022627, 1032627, 1080017, 1022930, 1032930, 1012323, 1022323, 1032323, 1023232, 1033232, 1080019, 1010909, 1020909, 1012424, 1022424, 1032424, 1010707, 1012020, 1022020, 1022626, 1032626, 1012525, 1022526, 1032526, 1010708, 1012021, 1022021, 1032021, 1022929, 1032929, 1011515, 1021515, 1023131, 1033131, 1011818, 1021818, 1011919, 1021919, 1022728, 1032728, 1023434, 1033434, 1022727, 1032727, 1023334, 1033334, 1023435, 1033435, 1011314, 1021314, 1023637, 1033637, 1023737, 1033737, 1004150, 1024142, 1034142, 1044142, 1054162, 1080005, 1080021, 1024444, 1034444, 1044444, 1024041, 1034041, 1044041, 1024242, 1034242, 1044242, 1024344, 1034344, 1044344, 1024545, 1034545, 1044545, 1023031, 1033031, 1023233, 1033233, 1023738, 1033738, 1023536, 1033536, 1023132, 1033132, 1024040, 1034040, 1024343, 1034343, 1044343, 1024141, 1034141, 1044141, 1024243, 1034243, 1044243, 1023939, 1033939, 1023839, 1033839, 1023838, 1033838, 1005163, 1025051, 1035051, 1045051, 1065054, 1075062, 1080007, 1080022, 1025050, 1035050, 1045050, 1025353, 1035353, 1045353, 1023636, 1033636, 1024747, 1034747, 1044747, 1080006, 1011717, 1021717, 1012222, 1022222, 1032222, 1012121, 1022121, 1032121, 1011313, 1021313, 1025152, 1035152, 1045152, 1025455, 1035455, 1045455, 1065562, 1025657, 1035657, 1045657, 1025556, 1035556, 1045556, 1025151, 1035151, 1045151, 1025757, 1035757, 1045757, 1025354, 1035354, 1045354, 1025253, 1035253, 1045253, 1026060, 1036060, 1046060, 1025858, 1035858, 1045858, 1025959, 1035959, 1045959, 1025252, 1035252, 1045252, 1025656, 1035656, 1045656, 1026262, 1036262, 1046262, 1025555, 1035555, 1045555, 1025859, 1035859, 1045859, 1023535, 1033535, 1023333, 1033333, 1022525, 1032525, 1024445, 1034445, 1044445, 1024646, 1034646, 1044646, 1024546, 1034546, 1044546, 1024647, 1034647, 1044647, 1024748, 1034748, 1044748, 1024849, 1034849, 1044849, 1024950, 1034950, 1044950, 1010606, 1022828, 1032828, 1025758, 1035758, 1045758, 1024848, 1034848, 1044848, 1024949, 1034949, 1044949, 1025454, 1035454, 1045454, 1025960, 1035960, 1045960, 1026161, 1036161, 1046161, 1026061, 1036061, 1046061); + +-- Create new Reference Bases +DELETE FROM `reference_loot_template` WHERE `Entry` IN (1085663,1180002,1180003,1180004,1000105,1000610,1001115,1001620,1002125,1002630,1003140,1004150,1005163,1010708,1010809,1010910,1011011,1011112,1011213,1011314,1011415,1011822,1011923,1012024,1012125,1020812,1021014,1021115,1021216,1021317,1021418,1021519,1021620,1021721,1021822,1021923,1022024,1022125,1022226,1022327,1022428,1022529,1022630,1022731,1022832,1022933,1023034,1023135,1023236,1023337,1023438,1023539,1023640,1023741,1023842,1023943,1024044,1024145,1024246,1024347,1024448,1024549,1024650,1024751,1024852,1024953,1025054,1025155,1025256,1025357,1025458,1025559,1025660,1025761,1025862,1025963,1026063,1026163,1026263,1031922,1032023,1032124,1032225,1032326,1032427,1032528,1032629,1032730,1032831,1032932,1033033,1033134,1033235,1033336,1033437,1033538,1033639,1033740,1033841,1033942,1034043,1034144,1034245,1034346,1034447,1034548,1034649,1034750,1034851,1034952,1035053,1035154,1035255,1035356,1035457,1035558,1035659,1035760,1035861,1035963,1044046,1044248,1044450,1044652,1044854,1045056,1045258,1045460,1045662,1045863,1046063,1050614,1051525,1052635,1053650,1055163,1060610,1061120,1062130,1063140,1064150,1065155,1065663,1070610,1071114,1071519,1072025,1072627,1072830,1073135,1073640,1074145,1074650,1075061,1075063,1075155,1075660,1076163,1080620,1081225,1081630,1082035,1082640,1083045,1083650,1084055,1084660,1085063,1086163,1090110,1091120,1092130,1093140,1094150,1095162,1100105,1105865,1106672,1125860,1125961,1126062,1126163,1126264,1126365,1126466,1126567,1126668,1126769,1126870,1126971,1127072,1127173,1135861,1135962,1136063,1136164,1136265,1136366,1136467,1136568,1136669,1136770,1136873,1146773,1155873,1165864,1166573,1176571,1176573,1186165,1186673); +INSERT INTO `reference_loot_template` (`Entry`, `Chance`, `GroupId`, `Item`, `Comment`) VALUES +-- Greys +-- 1-5 +(1000105, 0, 1, 1366, 'Ragged Leather Pants'), +(1000105, 0, 1, 1378, 'Frayed Pants'), +(1000105, 0, 1, 2210, 'Battered Buckler'), +(1000105, 0, 1, 2649, 'Flimsy Chain Belt'), +(1000105, 0, 1, 2654, 'Flimsy Chain Pants'), +(1000105, 0, 1, 1367, 'Ragged Leather Boots'), +(1000105, 0, 1, 1372, 'Ragged Cloak'), +(1000105, 0, 1, 1377, 'Frayed Gloves'), +(1000105, 0, 1, 2650, 'Flimsy Chain Boots'), +(1000105, 0, 1, 3363, 'Frayed Belt'), +(1000105, 0, 1, 1368, 'Ragged Leather Gloves'), +(1000105, 0, 1, 1370, 'Ragged Leather Bracers'), +(1000105, 0, 1, 1374, 'Frayed Shoes'), +(1000105, 0, 1, 1380, 'Frayed Robe'), +(1000105, 0, 1, 2211, 'Bent Large Shield'), +(1000105, 0, 1, 2651, 'Flimsy Chain Bracers'), +(1000105, 0, 1, 2653, 'Flimsy Chain Gloves'), +(1000105, 0, 1, 1364, 'Ragged Leather Vest'), +(1000105, 0, 1, 1369, 'Ragged Leather Belt'), +(1000105, 0, 1, 1376, 'Frayed Cloak'), +(1000105, 0, 1, 2652, 'Flimsy Chain Cloak'), +(1000105, 0, 1, 2656, 'Flimsy Chain Vest'), +(1000105, 0, 1, 3365, 'Frayed Bracers'), +-- 6-10 +(1000610, 0, 1, 1422, 'Worn Leather Gloves'), +(1000610, 0, 1, 1429, 'Patchwork Cloak'), +(1000610, 0, 1, 2212, 'Cracked Buckler'), +(1000610, 0, 1, 2644, 'Loose Chain Cloak'), +(1000610, 0, 1, 1412, 'Crude Bastard Sword'), +(1000610, 0, 1, 1418, 'Worn Leather Belt'), +(1000610, 0, 1, 1423, 'Worn Leather Pants'), +(1000610, 0, 1, 1430, 'Patchwork Gloves'), +(1000610, 0, 1, 1433, 'Patchwork Armor'), +(1000610, 0, 1, 2138, 'Sharpened Letter Opener'), +(1000610, 0, 1, 2213, 'Worn Large Shield'), +(1000610, 0, 1, 2645, 'Loose Chain Gloves'), +(1000610, 0, 1, 2774, 'Rust-covered Blunderbuss'), +(1000610, 0, 1, 1411, 'Withered Staff'), +(1000610, 0, 1, 1413, 'Feeble Sword'), +(1000610, 0, 1, 1417, 'Beaten Battle Axe'), +(1000610, 0, 1, 1419, 'Worn Leather Boots'), +(1000610, 0, 1, 1431, 'Patchwork Pants'), +(1000610, 0, 1, 2635, 'Loose Chain Belt'), +(1000610, 0, 1, 2646, 'Loose Chain Pants'), +(1000610, 0, 1, 2773, 'Cracked Shortbow'), +(1000610, 0, 1, 3370, 'Patchwork Belt'), +(1000610, 0, 1, 1414, 'Cracked Sledge'), +(1000610, 0, 1, 1415, 'Carpenter\'s Mallet'), +(1000610, 0, 1, 1416, 'Rusty Hatchet'), +(1000610, 0, 1, 1420, 'Worn Leather Bracers'), +(1000610, 0, 1, 1425, 'Worn Leather Vest'), +(1000610, 0, 1, 2642, 'Loose Chain Boots'), +(1000610, 0, 1, 3373, 'Patchwork Bracers'), +(1000610, 0, 1, 1421, 'Worn Hide Cloak'), +(1000610, 0, 1, 1427, 'Patchwork Shoes'), +(1000610, 0, 1, 2643, 'Loose Chain Bracers'), +(1000610, 0, 1, 2648, 'Loose Chain Vest'), +-- 11-15 +(1001115, 0, 1, 1499, 'Calico Pants'), +(1001115, 0, 1, 1504, 'Warped Leather Bracers'), +(1001115, 0, 1, 1509, 'Warped Leather Vest'), +(1001115, 0, 1, 1734, 'Worn Mail Gloves'), +(1001115, 0, 1, 2215, 'Wooden Shield'), +(1001115, 0, 1, 1505, 'Warped Cloak'), +(1001115, 0, 1, 1510, 'Heavy Hammer'), +(1001115, 0, 1, 1512, 'Crude Battle Axe'), +(1001115, 0, 1, 1515, 'Rough Wooden Staff'), +(1001115, 0, 1, 1730, 'Worn Mail Belt'), +(1001115, 0, 1, 1735, 'Worn Mail Pants'), +(1001115, 0, 1, 3375, 'Calico Bracers'), +(1001115, 0, 1, 1495, 'Calico Shoes'), +(1001115, 0, 1, 1501, 'Calico Tunic'), +(1001115, 0, 1, 1506, 'Warped Leather Gloves'), +(1001115, 0, 1, 1511, 'Commoner\'s Sword'), +(1001115, 0, 1, 1731, 'Worn Mail Boots'), +(1001115, 0, 1, 2777, 'Feeble Shortbow'), +(1001115, 0, 1, 2778, 'Cheap Blunderbuss'), +(1001115, 0, 1, 1497, 'Calico Cloak'), +(1001115, 0, 1, 1502, 'Warped Leather Belt'), +(1001115, 0, 1, 1507, 'Warped Leather Pants'), +(1001115, 0, 1, 1513, 'Old Greatsword'), +(1001115, 0, 1, 1514, 'Rusty Warhammer'), +(1001115, 0, 1, 1516, 'Worn Hatchet'), +(1001115, 0, 1, 1732, 'Worn Mail Bracers'), +(1001115, 0, 1, 1737, 'Worn Mail Vest'), +(1001115, 0, 1, 2763, 'Fisherman Knife'), +(1001115, 0, 1, 3374, 'Calico Belt'), +(1001115, 0, 1, 1498, 'Calico Gloves'), +(1001115, 0, 1, 1503, 'Warped Leather Boots'), +(1001115, 0, 1, 1733, 'Worn Cloak'), +(1001115, 0, 1, 2214, 'Wooden Buckler'), +-- 16-20 +(1001620, 0, 1, 1740, 'Laced Mail Bracers'), +(1001620, 0, 1, 1745, 'Laced Mail Vest'), +(1001620, 0, 1, 1790, 'Patched Cloak'), +(1001620, 0, 1, 2216, 'Simple Buckler'), +(1001620, 0, 1, 1741, 'Laced Cloak'), +(1001620, 0, 1, 1764, 'Canvas Shoes'), +(1001620, 0, 1, 1770, 'Canvas Vest'), +(1001620, 0, 1, 1791, 'Patched Leather Gloves'), +(1001620, 0, 1, 1811, 'Blunt Claymore'), +(1001620, 0, 1, 1812, 'Short-handled Battle Axe'), +(1001620, 0, 1, 1815, 'Ornamental Mace'), +(1001620, 0, 1, 2217, 'Rectangular Shield'), +(1001620, 0, 1, 1742, 'Laced Mail Gloves'), +(1001620, 0, 1, 1766, 'Canvas Cloak'), +(1001620, 0, 1, 1787, 'Patched Leather Belt'), +(1001620, 0, 1, 1792, 'Patched Leather Pants'), +(1001620, 0, 1, 1813, 'Chipped Quarterstaff'), +(1001620, 0, 1, 2764, 'Small Dagger'), +(1001620, 0, 1, 2781, 'Dirty Blunderbuss'), +(1001620, 0, 1, 3376, 'Canvas Belt'), +(1001620, 0, 1, 1738, 'Laced Mail Belt'), +(1001620, 0, 1, 1743, 'Laced Mail Pants'), +(1001620, 0, 1, 1767, 'Canvas Gloves'), +(1001620, 0, 1, 1788, 'Patched Leather Boots'), +(1001620, 0, 1, 1814, 'Battered Mallet'), +(1001620, 0, 1, 1816, 'Unbalanced Axe'), +(1001620, 0, 1, 1817, 'Stock Shortsword'), +(1001620, 0, 1, 2780, 'Light Hunting Bow'), +(1001620, 0, 1, 3377, 'Canvas Bracers'), +(1001620, 0, 1, 1739, 'Laced Mail Boots'), +(1001620, 0, 1, 1744, 'Laced Mail Shoulderpads'), +(1001620, 0, 1, 1768, 'Canvas Pants'), +(1001620, 0, 1, 1769, 'Canvas Shoulderpads'), +(1001620, 0, 1, 1789, 'Patched Leather Bracers'), +(1001620, 0, 1, 1793, 'Patched Leather Shoulderpads'), +(1001620, 0, 1, 1794, 'Patched Leather Jerkin'), +-- 21-25 +(1002125, 0, 1, 1747, 'Linked Chain Boots'), +(1002125, 0, 1, 1752, 'Linked Chain Shoulderpads'), +(1002125, 0, 1, 1776, 'Brocade Pants'), +(1002125, 0, 1, 1797, 'Rawhide Bracers'), +(1002125, 0, 1, 1802, 'Rawhide Tunic'), +(1002125, 0, 1, 3378, 'Brocade Belt'), +(1002125, 0, 1, 1748, 'Linked Chain Bracers'), +(1002125, 0, 1, 1753, 'Linked Chain Vest'), +(1002125, 0, 1, 1777, 'Brocade Shoulderpads'), +(1002125, 0, 1, 1798, 'Rawhide Cloak'), +(1002125, 0, 1, 1819, 'Gouging Pick'), +(1002125, 0, 1, 1820, 'Wooden Maul'), +(1002125, 0, 1, 1823, 'Bludgeoning Cudgel'), +(1002125, 0, 1, 2219, 'Small Round Shield'), +(1002125, 0, 1, 2783, 'Shoddy Blunderbuss'), +(1002125, 0, 1, 3379, 'Brocade Bracers'), +(1002125, 0, 1, 1749, 'Linked Chain Cloak'), +(1002125, 0, 1, 1772, 'Brocade Shoes'), +(1002125, 0, 1, 1778, 'Brocade Vest'), +(1002125, 0, 1, 1799, 'Rawhide Gloves'), +(1002125, 0, 1, 1822, 'Cedar Walking Stick'), +(1002125, 0, 1, 1824, 'Shiny War Axe'), +(1002125, 0, 1, 2220, 'Box Shield'), +(1002125, 0, 1, 2765, 'Hunting Knife'), +(1002125, 0, 1, 1750, 'Linked Chain Gloves'), +(1002125, 0, 1, 1774, 'Brocade Cloak'), +(1002125, 0, 1, 1795, 'Rawhide Belt'), +(1002125, 0, 1, 1800, 'Rawhide Pants'), +(1002125, 0, 1, 1818, 'Standard Claymore'), +(1002125, 0, 1, 1821, 'Warped Blade'), +(1002125, 0, 1, 2782, 'Mishandled Recurve Bow'), +(1002125, 0, 1, 1746, 'Linked Chain Belt'), +(1002125, 0, 1, 1751, 'Linked Chain Pants'), +(1002125, 0, 1, 1775, 'Brocade Gloves'), +(1002125, 0, 1, 1796, 'Rawhide Boots'), +(1002125, 0, 1, 1801, 'Rawhide Shoulderpads'), +-- 26-30 +(1002630, 0, 1, 1754, 'Reinforced Chain Belt'), +(1002630, 0, 1, 1759, 'Reinforced Chain Pants'), +(1002630, 0, 1, 1783, 'Cross-stitched Gloves'), +(1002630, 0, 1, 1804, 'Tough Leather Boots'), +(1002630, 0, 1, 1809, 'Tough Leather Shoulderpads'), +(1002630, 0, 1, 1755, 'Reinforced Chain Boots'), +(1002630, 0, 1, 1760, 'Reinforced Chain Shoulderpads'), +(1002630, 0, 1, 1784, 'Cross-stitched Pants'), +(1002630, 0, 1, 1805, 'Tough Leather Bracers'), +(1002630, 0, 1, 1810, 'Tough Leather Armor'), +(1002630, 0, 1, 1826, 'Rock Maul'), +(1002630, 0, 1, 1827, 'Meat Cleaver'), +(1002630, 0, 1, 1828, 'Stone War Axe'), +(1002630, 0, 1, 1756, 'Reinforced Chain Bracers'), +(1002630, 0, 1, 1761, 'Reinforced Chain Vest'), +(1002630, 0, 1, 1785, 'Cross-stitched Shoulderpads'), +(1002630, 0, 1, 1806, 'Tough Cloak'), +(1002630, 0, 1, 1825, 'Bulky Bludgeon'), +(1002630, 0, 1, 1830, 'Long Bastard Sword'), +(1002630, 0, 1, 1831, 'Oaken War Staff'), +(1002630, 0, 1, 2221, 'Targe Shield'), +(1002630, 0, 1, 2785, 'Stiff Recurve Bow'), +(1002630, 0, 1, 3381, 'Cross-stitched Bracers'), +(1002630, 0, 1, 1757, 'Reinforced Chain Cloak'), +(1002630, 0, 1, 1780, 'Cross-stitched Sandals'), +(1002630, 0, 1, 1786, 'Cross-stitched Vest'), +(1002630, 0, 1, 1807, 'Tough Leather Gloves'), +(1002630, 0, 1, 1829, 'Short Cutlass'), +(1002630, 0, 1, 2222, 'Tower Shield'), +(1002630, 0, 1, 2766, 'Deft Stiletto'), +(1002630, 0, 1, 2786, 'Oiled Blunderbuss'), +(1002630, 0, 1, 1758, 'Reinforced Chain Gloves'), +(1002630, 0, 1, 1782, 'Cross-stitched Cloak'), +(1002630, 0, 1, 1803, 'Tough Leather Belt'), +(1002630, 0, 1, 1808, 'Tough Leather Pants'), +(1002630, 0, 1, 3380, 'Cross-stitched Belt'), +-- 31-40 +(1003140, 0, 1, 8748, 'Double Mail Coif'), +(1003140, 0, 1, 3778, 'Taut Compound Bow'), +(1003140, 0, 1, 3779, 'Hefty War Axe'), +(1003140, 0, 1, 3793, 'Interlaced Boots'), +(1003140, 0, 1, 3805, 'Hardened Leather Pants'), +(1003140, 0, 1, 3809, 'Double Mail Boots'), +(1003140, 0, 1, 3780, 'Long-barreled Musket'), +(1003140, 0, 1, 3796, 'Interlaced Gloves'), +(1003140, 0, 1, 3807, 'Hardened Leather Tunic'), +(1003140, 0, 1, 3815, 'Double Mail Vest'), +(1003140, 0, 1, 3817, 'Reinforced Buckler'), +(1003140, 0, 1, 8746, 'Interlaced Cowl'), +(1003140, 0, 1, 3781, 'Broad Claymore'), +(1003140, 0, 1, 3792, 'Interlaced Belt'), +(1003140, 0, 1, 3802, 'Hardened Leather Bracers'), +(1003140, 0, 1, 3808, 'Double Mail Belt'), +(1003140, 0, 1, 3782, 'Large War Club'), +(1003140, 0, 1, 3798, 'Interlaced Shoulderpads'), +(1003140, 0, 1, 3801, 'Hardened Leather Boots'), +(1003140, 0, 1, 3813, 'Double Mail Pants'), +(1003140, 0, 1, 8747, 'Hardened Leather Helm'), +(1003140, 0, 1, 3783, 'Light Scimitar'), +(1003140, 0, 1, 3795, 'Interlaced Cloak'), +(1003140, 0, 1, 3804, 'Hardened Leather Gloves'), +(1003140, 0, 1, 3812, 'Double Mail Gloves'), +(1003140, 0, 1, 3816, 'Reflective Heater'), +(1003140, 0, 1, 3784, 'Metal Stave'), +(1003140, 0, 1, 3799, 'Interlaced Vest'), +(1003140, 0, 1, 3806, 'Hardened Leather Shoulderpads'), +(1003140, 0, 1, 3811, 'Double-stitched Cloak'), +(1003140, 0, 1, 3785, 'Keen Axe'), +(1003140, 0, 1, 3794, 'Interlaced Bracers'), +(1003140, 0, 1, 3803, 'Hardened Cloak'), +(1003140, 0, 1, 3810, 'Double Mail Bracers'), +(1003140, 0, 1, 3786, 'Shiny Dirk'), +(1003140, 0, 1, 3797, 'Interlaced Pants'), +(1003140, 0, 1, 3800, 'Hardened Leather Belt'), +(1003140, 0, 1, 3814, 'Double Mail Shoulderpads'), +(1003140, 0, 1, 3787, 'Stone Club'), +-- 41-50 +(1004150, 0, 1, 3936, 'Crochet Belt'), +(1004150, 0, 1, 3966, 'Thick Leather Pants'), +(1004150, 0, 1, 3989, 'Blocking Targe'), +(1004150, 0, 1, 4006, 'Overlinked Chain Shoulderpads'), +(1004150, 0, 1, 4018, 'Whetted Claymore'), +(1004150, 0, 1, 8750, 'Thick Leather Hat'), +(1004150, 0, 1, 3943, 'Crochet Vest'), +(1004150, 0, 1, 3963, 'Thick Leather Bracers'), +(1004150, 0, 1, 4005, 'Overlinked Chain Pants'), +(1004150, 0, 1, 4026, 'Sentinel Musket'), +(1004150, 0, 1, 8749, 'Crochet Hat'), +(1004150, 0, 1, 3938, 'Crochet Bracers'), +(1004150, 0, 1, 3961, 'Thick Leather Belt'), +(1004150, 0, 1, 4000, 'Overlinked Chain Belt'), +(1004150, 0, 1, 4023, 'Fine Pointed Dagger'), +(1004150, 0, 1, 8751, 'Overlinked Coif'), +(1004150, 0, 1, 3941, 'Crochet Pants'), +(1004150, 0, 1, 3968, 'Thick Leather Tunic'), +(1004150, 0, 1, 4007, 'Overlinked Chain Armor'), +(1004150, 0, 1, 4025, 'Balanced Long Bow'), +(1004150, 0, 1, 3937, 'Crochet Boots'), +(1004150, 0, 1, 3964, 'Thick Cloak'), +(1004150, 0, 1, 4001, 'Overlinked Chain Boots'), +(1004150, 0, 1, 4017, 'Sharp Shortsword'), +(1004150, 0, 1, 4021, 'Blunting Mace'), +(1004150, 0, 1, 3939, 'Crochet Cloak'), +(1004150, 0, 1, 3967, 'Thick Leather Shoulderpads'), +(1004150, 0, 1, 4004, 'Overlinked Chain Gloves'), +(1004150, 0, 1, 4024, 'Heavy War Staff'), +(1004150, 0, 1, 3940, 'Crochet Gloves'), +(1004150, 0, 1, 3962, 'Thick Leather Boots'), +(1004150, 0, 1, 3986, 'Protective Pavise'), +(1004150, 0, 1, 4002, 'Overlinked Chain Bracers'), +(1004150, 0, 1, 4019, 'Heavy Flint Axe'), +(1004150, 0, 1, 3942, 'Crochet Shoulderpads'), +(1004150, 0, 1, 3965, 'Thick Leather Gloves'), +(1004150, 0, 1, 4003, 'Overlinked Chain Cloak'), +(1004150, 0, 1, 4020, 'Splintering Battle Axe'), +(1004150, 0, 1, 4022, 'Crushing Maul'), +-- 51+ +(1005163, 0, 1, 13823, 'Stout War Staff'), +(1005163, 0, 1, 3947, 'Twill Cloak'), +(1005163, 0, 1, 3975, 'Smooth Leather Shoulderpads'), +(1005163, 0, 1, 3992, 'Laminated Scale Belt'), +(1005163, 0, 1, 8082, 'Light Plate Boots'), +(1005163, 0, 1, 13816, 'Fine Longsword'), +(1005163, 0, 1, 3944, 'Twill Belt'), +(1005163, 0, 1, 3974, 'Smooth Leather Pants'), +(1005163, 0, 1, 3987, 'Deflecting Tower'), +(1005163, 0, 1, 3993, 'Laminated Scale Boots'), +(1005163, 0, 1, 8083, 'Light Plate Bracers'), +(1005163, 0, 1, 13822, 'Spiked Dagger'), +(1005163, 0, 1, 3946, 'Twill Bracers'), +(1005163, 0, 1, 3970, 'Smooth Leather Boots'), +(1005163, 0, 1, 3999, 'Laminated Scale Armor'), +(1005163, 0, 1, 8086, 'Light Plate Shoulderpads'), +(1005163, 0, 1, 8752, 'Laminated Scale Circlet'), +(1005163, 0, 1, 13820, 'Clout Mace'), +(1005163, 0, 1, 3945, 'Twill Boots'), +(1005163, 0, 1, 3969, 'Smooth Leather Belt'), +(1005163, 0, 1, 3998, 'Laminated Scale Shoulderpads'), +(1005163, 0, 1, 8085, 'Light Plate Pants'), +(1005163, 0, 1, 8755, 'Light Plate Helmet'), +(1005163, 0, 1, 13824, 'Recurve Long Bow'), +(1005163, 0, 1, 3950, 'Twill Shoulderpads'), +(1005163, 0, 1, 3972, 'Smooth Cloak'), +(1005163, 0, 1, 3990, 'Crested Buckler'), +(1005163, 0, 1, 3997, 'Laminated Scale Pants'), +(1005163, 0, 1, 8084, 'Light Plate Gloves'), +(1005163, 0, 1, 8754, 'Twill Cover'), +(1005163, 0, 1, 13818, 'Jagged Axe'), +(1005163, 0, 1, 3951, 'Twill Vest'), +(1005163, 0, 1, 3976, 'Smooth Leather Armor'), +(1005163, 0, 1, 3995, 'Laminated Scale Cloak'), +(1005163, 0, 1, 8081, 'Light Plate Belt'), +(1005163, 0, 1, 8753, 'Smooth Leather Helmet'), +(1005163, 0, 1, 13821, 'Bulky Maul'), +(1005163, 0, 1, 13825, 'Primed Musket'), +(1005163, 0, 1, 3948, 'Twill Gloves'), +(1005163, 0, 1, 3973, 'Smooth Leather Gloves'), +(1005163, 0, 1, 3994, 'Laminated Scale Bracers'), +(1005163, 0, 1, 8080, 'Light Plate Chestpiece'), +(1005163, 0, 1, 13817, 'Tapered Greatsword'), +(1005163, 0, 1, 3949, 'Twill Pants'), +(1005163, 0, 1, 3971, 'Smooth Leather Bracers'), +(1005163, 0, 1, 3996, 'Laminated Scale Gloves'), +(1005163, 0, 1, 13819, 'Balanced War Axe'), +-- TBC 58-65 +(1105865, 0, 1, 24576, 'Loosely Threaded Belt'), +(1105865, 0, 1, 24577, 'Loosely Threaded Boots'), +(1105865, 0, 1, 24578, 'Loosely Threaded Bracers'), +(1105865, 0, 1, 24580, 'Loosely Threaded Hat'), +(1105865, 0, 1, 24782, 'Loosely Threaded Gloves'), +(1105865, 0, 1, 25338, 'Loosely Threaded Pants'), +(1105865, 0, 1, 25339, 'Loosely Threaded Shoulderpads'), +(1105865, 0, 1, 25340, 'Loosely Threaded Vest'), +(1105865, 0, 1, 25349, 'Moldy Leather Armor'), +(1105865, 0, 1, 25350, 'Moldy Leather Belt'), +(1105865, 0, 1, 25351, 'Moldy Leather Boots'), +(1105865, 0, 1, 25352, 'Moldy Leather Bracers'), +(1105865, 0, 1, 25353, 'Moldy Leather Gloves'), +(1105865, 0, 1, 25354, 'Moldy Leather Helmet'), +(1105865, 0, 1, 25355, 'Moldy Leather Pants'), +(1105865, 0, 1, 25356, 'Moldy Leather Shoulderpads'), +(1105865, 0, 1, 25365, 'Eroded Mail Armor'), +(1105865, 0, 1, 25366, 'Eroded Mail Belt'), +(1105865, 0, 1, 25367, 'Eroded Mail Boots'), +(1105865, 0, 1, 25368, 'Eroded Mail Bracers'), +(1105865, 0, 1, 25369, 'Eroded Mail Circlet'), +(1105865, 0, 1, 25370, 'Eroded Mail Gloves'), +(1105865, 0, 1, 25371, 'Eroded Mail Pants'), +(1105865, 0, 1, 25372, 'Eroded Mail Shoulderpads'), +(1105865, 0, 1, 25381, 'Tarnished Plate Belt'), +(1105865, 0, 1, 25382, 'Tarnished Plate Boots'), +(1105865, 0, 1, 25383, 'Tarnished Plate Bracers'), +(1105865, 0, 1, 25384, 'Tarnished Plate Chestpiece'), +(1105865, 0, 1, 25385, 'Tarnished Plate Gloves'), +(1105865, 0, 1, 25386, 'Tarnished Plate Helmet'), +(1105865, 0, 1, 25387, 'Tarnished Plate Pants'), +(1105865, 0, 1, 25388, 'Tarnished Plate Shoulderpads'), +-- TBC 66+ +(1106672, 0, 1, 25397, 'Eroded Axe'), +(1106672, 0, 1, 25398, 'Stone Reaper'), +(1106672, 0, 1, 25399, 'Deteriorating Blade'), +(1106672, 0, 1, 25400, 'Tarnished Claymore'), +(1106672, 0, 1, 25401, 'Corroded Mace'), +(1106672, 0, 1, 25402, 'The Stoppable Force'), +(1106672, 0, 1, 25403, 'Sharpened Stilleto'), +(1106672, 0, 1, 25404, 'Dense War Staff'), +(1106672, 0, 1, 25405, 'Rusted Musket'), +(1106672, 0, 1, 25406, 'Broken Longbow'), +(1106672, 0, 1, 25341, 'Dilapidated Cloth Belt'), +(1106672, 0, 1, 25342, 'Dilapidated Cloth Boots'), +(1106672, 0, 1, 25343, 'Dilapidated Cloth Bracers'), +(1106672, 0, 1, 25344, 'Dilapidated Cloth Gloves'), +(1106672, 0, 1, 25345, 'Dilapidated Cloth Hat'), +(1106672, 0, 1, 25346, 'Dilapidated Cloth Pants'), +(1106672, 0, 1, 25347, 'Dilapidated Cloth Shoulderpads'), +(1106672, 0, 1, 25348, 'Dilapidated Cloth Vest'), +(1106672, 0, 1, 25357, 'Decaying Leather Armor'), +(1106672, 0, 1, 25358, 'Decaying Leather Belt'), +(1106672, 0, 1, 25359, 'Decaying Leather Boots'), +(1106672, 0, 1, 25360, 'Decaying Leather Bracers'), +(1106672, 0, 1, 25361, 'Decaying Leather Gloves'), +(1106672, 0, 1, 25362, 'Decaying Leather Helmet'), +(1106672, 0, 1, 25363, 'Decaying Leather Pants'), +(1106672, 0, 1, 25364, 'Decaying Leather Shoulderpads'), +(1106672, 0, 1, 25373, 'Corroded Mail Armor'), +(1106672, 0, 1, 25374, 'Corroded Mail Belt'), +(1106672, 0, 1, 25375, 'Corroded Mail Boots'), +(1106672, 0, 1, 25376, 'Corroded Mail Bracers'), +(1106672, 0, 1, 25377, 'Corroded Mail Circlet'), +(1106672, 0, 1, 25378, 'Corroded Mail Gloves'), +(1106672, 0, 1, 25379, 'Corroded Mail Pants'), +(1106672, 0, 1, 25380, 'Corroded Mail Shoulderpads'), +(1106672, 0, 1, 25389, 'Deteriorating Plate Belt'), +(1106672, 0, 1, 25390, 'Deteriorating Plate Boots'), +(1106672, 0, 1, 25391, 'Deteriorating Plate Bracers'), +(1106672, 0, 1, 25392, 'Deteriorating Plate Chestpiece'), +(1106672, 0, 1, 25393, 'Deteriorating Plate Gloves'), +(1106672, 0, 1, 25394, 'Deteriorating Plate Helmet'), +(1106672, 0, 1, 25395, 'Deteriorating Plate Pants'), +(1106672, 0, 1, 25396, 'Deteriorating Plate Shoulderpads'), +-- Eversong Woods (1-5) +-- (1100105, 0, 1, 21006, 'Unkempt Pants'), +-- (1100105, 0, 1, 21013, 'Scraggy Leather Pants'), +-- (1100105, 0, 1, 21015, 'Shoddy Chain Belt'), +-- (1100105, 0, 1, 21017, 'Shoddy Chain Pants'), +-- (1100105, 0, 1, 21022, 'Weather Beaten Buckler'), +-- (1100105, 0, 1, 21002, 'Unkempt Belt'), +-- (1100105, 0, 1, 21005, 'Unkempt Gloves'), +-- (1100105, 0, 1, 21010, 'Scraggy Leather Boots'), +-- (1100105, 0, 1, 21020, 'Shoddy Chain Boots'), +-- (1100105, 0, 1, 21007, 'Unkempt Robe'), +-- (1100105, 0, 1, 21008, 'Unkempt Shoes'), +-- (1100105, 0, 1, 21011, 'Scraggy Leather Bracers'), +-- (1100105, 0, 1, 21012, 'Scraggy Leather Gloves'), +-- (1100105, 0, 1, 21018, 'Shoddy Chain Gloves'), +-- (1100105, 0, 1, 21019, 'Shoddy Chain Bracers'), +-- (1100105, 0, 1, 21021, 'Battered Shield'), +-- (1100105, 0, 1, 21003, 'Unkempt Bracers'), +-- (1100105, 0, 1, 21004, 'Unkempt Cloak'), +-- (1100105, 0, 1, 21009, 'Scraggy Leather Belt'), +-- (1100105, 0, 1, 21014, 'Scraggy Leather Vest'), +-- (1100105, 0, 1, 21016, 'Shoddy Chain Vest'), +-- Whites +-- 7-8 +(1010708, 0, 1, 4560, 'Fine Scimitar'), +(1010708, 0, 1, 4565, 'Simple Dagger'), +(1010708, 0, 1, 8179, 'Cadet\'s Bow'), +(1010708, 0, 1, 766, 'Flanged Mace'), +(1010708, 0, 1, 8177, 'Practice Sword'), +(1010708, 0, 1, 8182, 'Pellet Rifle'), +-- 8-9 +(1010809, 0, 1, 767, 'Long Bo Staff'), +(1010809, 0, 1, 3189, 'Wood Chopper'), +(1010809, 0, 1, 3190, 'Beatstick'), +(1010809, 0, 1, 3200, 'Burnt Leather Bracers'), +(1010809, 0, 1, 3641, 'Journeyman\'s Bracers'), +(1010809, 0, 1, 4658, 'Warrior\'s Cloak'), +(1010809, 0, 1, 4659, 'Warrior\'s Girdle'), +(1010809, 0, 1, 4662, 'Journeyman\'s Cloak'), +(1010809, 0, 1, 4665, 'Burnt Cloak'), +(1010809, 0, 1, 14087, 'Beaded Cuffs'), +(1010809, 0, 1, 14088, 'Beaded Cloak'), +(1010809, 0, 1, 15003, 'Primal Belt'), +(1010809, 0, 1, 15007, 'Primal Cape'), +(1010809, 0, 1, 15474, 'Charger\'s Bindings'), +(1010809, 0, 1, 15475, 'Charger\'s Cloak'), +(1010809, 0, 1, 15478, 'Charger\'s Shield'), +(1010809, 0, 1, 15895, 'Burnt Buckler'), +-- 9-10 +(1010910, 0, 1, 768, 'Lumberjack Axe'), +(1010910, 0, 1, 2112, 'Lumberjack Jerkin'), +(1010910, 0, 1, 1438, 'Warrior\'s Shield'), +(1010910, 0, 1, 2959, 'Journeyman\'s Boots'), +(1010910, 0, 1, 2960, 'Journeyman\'s Gloves'), +(1010910, 0, 1, 2963, 'Burnt Leather Boots'), +(1010910, 0, 1, 2968, 'Warrior\'s Gloves'), +(1010910, 0, 1, 3214, 'Warrior\'s Bracers'), +(1010910, 0, 1, 3280, 'Battle Chain Bracers'), +(1010910, 0, 1, 3642, 'Ancestral Bracers'), +(1010910, 0, 1, 3650, 'Battle Shield'), +(1010910, 0, 1, 4563, 'Billy Club'), +(1010910, 0, 1, 4663, 'Journeyman\'s Belt'), +(1010910, 0, 1, 4666, 'Burnt Leather Belt'), +(1010910, 0, 1, 4668, 'Battle Chain Cloak'), +(1010910, 0, 1, 4671, 'Ancestral Cloak'), +(1010910, 0, 1, 4674, 'Tribal Cloak'), +(1010910, 0, 1, 6508, 'Infantry Cloak'), +(1010910, 0, 1, 6520, 'Pioneer Cloak'), +(1010910, 0, 1, 7109, 'Pioneer Buckler'), +(1010910, 0, 1, 14093, 'Beaded Cord'), +(1010910, 0, 1, 15004, 'Primal Boots'), +(1010910, 0, 1, 15005, 'Primal Bands'), +(1010910, 0, 1, 15006, 'Primal Buckler'), +(1010910, 0, 1, 15472, 'Charger\'s Belt'), +-- 10-11 +(1011011, 0, 1, 2964, 'Burnt Leather Gloves'), +(1011011, 0, 1, 2967, 'Warrior\'s Boots'), +(1011011, 0, 1, 3285, 'Tribal Bracers'), +(1011011, 0, 1, 4669, 'Battle Chain Girdle'), +(1011011, 0, 1, 4672, 'Ancestral Belt'), +(1011011, 0, 1, 4675, 'Tribal Belt'), +(1011011, 0, 1, 6507, 'Infantry Bracers'), +(1011011, 0, 1, 6509, 'Infantry Belt'), +(1011011, 0, 1, 6513, 'Disciple\'s Sash'), +(1011011, 0, 1, 6514, 'Disciple\'s Cloak'), +(1011011, 0, 1, 6517, 'Pioneer Belt'), +(1011011, 0, 1, 6519, 'Pioneer Bracers'), +(1011011, 0, 1, 7350, 'Disciple\'s Bracers'), +(1011011, 0, 1, 14086, 'Beaded Sandals'), +(1011011, 0, 1, 14089, 'Beaded Gloves'), +(1011011, 0, 1, 14098, 'Native Cloak'), +(1011011, 0, 1, 15008, 'Primal Mitts'), +(1011011, 0, 1, 15299, 'Grizzly Cape'), +(1011011, 0, 1, 15473, 'Charger\'s Boots'), +(1011011, 0, 1, 15476, 'Charger\'s Handwraps'), +(1011011, 0, 1, 15483, 'War Torn Cape'), +-- 11-12 +(1011112, 0, 1, 3281, 'Battle Chain Gloves'), +(1011112, 0, 1, 3289, 'Ancestral Boots'), +(1011112, 0, 1, 3649, 'Tribal Buckler'), +(1011112, 0, 1, 6506, 'Infantry Boots'), +(1011112, 0, 1, 6510, 'Infantry Gauntlets'), +(1011112, 0, 1, 6515, 'Disciple\'s Gloves'), +(1011112, 0, 1, 6518, 'Pioneer Boots'), +(1011112, 0, 1, 6521, 'Pioneer Gloves'), +(1011112, 0, 1, 7351, 'Disciple\'s Boots'), +(1011112, 0, 1, 9745, 'Simple Cape'), +(1011112, 0, 1, 9754, 'Gypsy Cloak'), +(1011112, 0, 1, 9761, 'Cadet Cloak'), +(1011112, 0, 1, 14095, 'Native Bands'), +(1011112, 0, 1, 15297, 'Grizzly Bracers'), +(1011112, 0, 1, 15302, 'Grizzly Belt'), +(1011112, 0, 1, 15482, 'War Torn Bands'), +-- 12-13 +(1011213, 0, 1, 3279, 'Battle Chain Boots'), +(1011213, 0, 1, 3284, 'Tribal Boots'), +(1011213, 0, 1, 3286, 'Tribal Gloves'), +(1011213, 0, 1, 3290, 'Ancestral Gloves'), +(1011213, 0, 1, 3303, 'Brackwater Bracers'), +(1011213, 0, 1, 3331, 'Melrache\'s Cape'), +(1011213, 0, 1, 3644, 'Barbaric Cloth Bracers'), +(1011213, 0, 1, 4677, 'Veteran Cloak'), +(1011213, 0, 1, 4686, 'Barbaric Cloth Cloak'), +(1011213, 0, 1, 4692, 'Ceremonial Cloak'), +(1011213, 0, 1, 9742, 'Simple Cord'), +(1011213, 0, 1, 9743, 'Simple Shoes'), +(1011213, 0, 1, 9744, 'Simple Bands'), +(1011213, 0, 1, 9750, 'Gypsy Sash'), +(1011213, 0, 1, 9751, 'Gypsy Sandals'), +(1011213, 0, 1, 9752, 'Gypsy Bands'), +(1011213, 0, 1, 9758, 'Cadet Belt'), +(1011213, 0, 1, 9760, 'Cadet Bracers'), +(1011213, 0, 1, 14099, 'Native Sash'), +(1011213, 0, 1, 15484, 'War Torn Handgrips'), +-- 13-14 +(1011314, 0, 1, 3213, 'Veteran Bracers'), +(1011314, 0, 1, 3312, 'Ceremonial Leather Bracers'), +(1011314, 0, 1, 4680, 'Brackwater Cloak'), +(1011314, 0, 1, 4683, 'Spellbinder Cloak'), +(1011314, 0, 1, 4684, 'Spellbinder Belt'), +(1011314, 0, 1, 4689, 'Hunting Cloak'), +(1011314, 0, 1, 4690, 'Hunting Belt'), +(1011314, 0, 1, 9746, 'Simple Gloves'), +(1011314, 0, 1, 9755, 'Gypsy Gloves'), +(1011314, 0, 1, 9759, 'Cadet Boots'), +(1011314, 0, 1, 9762, 'Cadet Gauntlets'), +(1011314, 0, 1, 14102, 'Native Handwraps'), +(1011314, 0, 1, 14110, 'Native Sandals'), +(1011314, 0, 1, 15015, 'Lupine Cloak'), +(1011314, 0, 1, 15301, 'Grizzly Slippers'), +(1011314, 0, 1, 15480, 'War Torn Girdle'), +(1011314, 0, 1, 15481, 'War Torn Greaves'), +-- 14-15 +(1011415, 0, 1, 2971, 'Spellbinder Boots'), +(1011415, 0, 1, 2972, 'Spellbinder Gloves'), +(1011415, 0, 1, 2975, 'Hunting Boots'), +(1011415, 0, 1, 2979, 'Veteran Boots'), +(1011415, 0, 1, 3207, 'Hunting Bracers'), +(1011415, 0, 1, 3304, 'Brackwater Gauntlets'), +(1011415, 0, 1, 3643, 'Spellbinder Bracers'), +(1011415, 0, 1, 4678, 'Veteran Girdle'), +(1011415, 0, 1, 4681, 'Brackwater Girdle'), +(1011415, 0, 1, 4687, 'Barbaric Cloth Belt'), +(1011415, 0, 1, 4693, 'Ceremonial Leather Belt'), +(1011415, 0, 1, 6549, 'Soldier\'s Cloak'), +(1011415, 0, 1, 6555, 'Bard\'s Cloak'), +(1011415, 0, 1, 14115, 'Aboriginal Bands'), +(1011415, 0, 1, 14116, 'Aboriginal Cape'), +(1011415, 0, 1, 15013, 'Lupine Cuffs'), +(1011415, 0, 1, 15300, 'Grizzly Gloves'), +(1011415, 0, 1, 15490, 'Bloodspattered Cloak'), +-- 18-22 +(1011822, 0, 1, 4698, 'Seer\'s Mantle'), +(1011822, 0, 1, 4700, 'Inscribed Leather Spaulders'), +(1011822, 0, 1, 5093, 'Razormane Backstabber'), +(1011822, 0, 1, 10407, 'Raider\'s Shoulderpads'), +(1011822, 0, 1, 14169, 'Aboriginal Shoulder Pads'), +(1011822, 0, 1, 15019, 'Lupine Mantle'), +(1011822, 0, 1, 15496, 'Bloodspattered Shoulder Pads'), +-- 19-23 +(1011923, 0, 1, 4694, 'Burnished Pauldrons'), +(1011923, 0, 1, 10405, 'Bandit Shoulders'), +(1011923, 0, 1, 14170, 'Buccaneer\'s Mantle'), +(1011923, 0, 1, 14368, 'Mystic\'s Shoulder Pads'), +(1011923, 0, 1, 14728, 'War Paint Shoulder Pads'), +-- 20-24 +(1012024, 0, 1, 6588, 'Scouting Spaulders'), +(1012024, 0, 1, 14126, 'Ritual Amice'), +(1012024, 0, 1, 15505, 'Outrunner\'s Pauldrons'), +-- 21-25 +(1012125, 0, 1, 6566, 'Shimmering Amice'), +(1012125, 0, 1, 6579, 'Defender Spaulders'), +(1012125, 0, 1, 14157, 'Pagan Mantle'), +(1012125, 0, 1, 15313, 'Feral Shoulder Pads'), +-- Greens +-- 8-12 +(1020812, 0, 1, 15969, 'Beaded Orb'), +(1020812, 0, 1, 2962, 'Burnt Leather Breeches'), +(1020812, 0, 1, 2958, 'Journeyman\'s Pants'), +(1020812, 0, 1, 15925, 'Journeyman\'s Stave'), +(1020812, 0, 1, 727, 'Notched Shortsword'), +(1020812, 0, 1, 4562, 'Severing Axe'), +(1020812, 0, 1, 8178, 'Training Sword'), +(1020812, 0, 1, 2966, 'Warrior\'s Pants'), +(1020812, 0, 1, 14090, 'Beaded Britches'), +(1020812, 0, 1, 14091, 'Beaded Robe'), +(1020812, 0, 1, 14094, 'Beaded Wraps'), +(1020812, 0, 1, 2961, 'Burnt Leather Vest'), +(1020812, 0, 1, 2140, 'Carving Knife'), +(1020812, 0, 1, 15479, 'Charger\'s Armor'), +(1020812, 0, 1, 15477, 'Charger\'s Pants'), +(1020812, 0, 1, 8180, 'Hunting Bow'), +(1020812, 0, 1, 7108, 'Infantry Shield'), +(1020812, 0, 1, 6511, 'Journeyman\'s Robe'), +(1020812, 0, 1, 2957, 'Journeyman\'s Vest'), +(1020812, 0, 1, 15009, 'Primal Leggings'), +(1020812, 0, 1, 15010, 'Primal Wraps'), +(1020812, 0, 1, 4561, 'Scalping Tomahawk'), +(1020812, 0, 1, 2965, 'Warrior\'s Tunic'), +(1020812, 0, 1, 15944, 'Ancestral Orb'), +(1020812, 0, 1, 3282, 'Battle Chain Pants'), +(1020812, 0, 1, 6267, 'Disciple\'s Pants'), +(1020812, 0, 1, 15932, 'Disciple\'s Stein'), +(1020812, 0, 1, 5069, 'Fire Wand'), +(1020812, 0, 1, 9753, 'Gypsy Buckler'), +(1020812, 0, 1, 6337, 'Infantry Leggings'), +(1020812, 0, 1, 6269, 'Pioneer Trousers'), +(1020812, 0, 1, 2075, 'Priest\'s Mace'), +(1020812, 0, 1, 3192, 'Short Bastard Sword'), +(1020812, 0, 1, 3287, 'Tribal Pants'), +(1020812, 0, 1, 15486, 'War Torn Shield'), +-- 10-14 +(1021014, 0, 1, 6527, 'Ancestral Robe'), +(1021014, 0, 1, 3292, 'Ancestral Tunic'), +(1021014, 0, 1, 3291, 'Ancestral Woollies'), +(1021014, 0, 1, 3283, 'Battle Chain Tunic'), +(1021014, 0, 1, 9764, 'Cadet Shield'), +(1021014, 0, 1, 4577, 'Compact Shotgun'), +(1021014, 0, 1, 6512, 'Disciple\'s Robe'), +(1021014, 0, 1, 6266, 'Disciple\'s Vest'), +(1021014, 0, 1, 15298, 'Grizzly Buckler'), +(1021014, 0, 1, 6336, 'Infantry Tunic'), +(1021014, 0, 1, 6268, 'Pioneer Tunic'), +(1021014, 0, 1, 4564, 'Spiked Club'), +(1021014, 0, 1, 4566, 'Sturdy Quarterstaff'), +(1021014, 0, 1, 3288, 'Tribal Vest'), +-- 11-15 +(1021115, 0, 1, 3654, 'Brackwater Shield'), +(1021115, 0, 1, 9763, 'Cadet Leggings'), +(1021115, 0, 1, 2632, 'Curved Dagger'), +(1021115, 0, 1, 15303, 'Grizzly Pants'), +(1021115, 0, 1, 9756, 'Gypsy Trousers'), +(1021115, 0, 1, 3652, 'Hunting Buckler'), +(1021115, 0, 1, 14097, 'Native Pants'), +(1021115, 0, 1, 5071, 'Shadow Wand'), +(1021115, 0, 1, 9747, 'Simple Britches'), +(1021115, 0, 1, 4569, 'Staunch Hammer'), +(1021115, 0, 1, 15485, 'War Torn Pants'), +-- 12-16 +(1021216, 0, 1, 14113, 'Aboriginal Sash'), +(1021216, 0, 1, 3307, 'Barbaric Cloth Boots'), +(1021216, 0, 1, 3308, 'Barbaric Cloth Gloves'), +(1021216, 0, 1, 6558, 'Bard\'s Belt'), +(1021216, 0, 1, 6556, 'Bard\'s Bracers'), +(1021216, 0, 1, 4570, 'Birchwood Maul'), +(1021216, 0, 1, 15491, 'Bloodspattered Gloves'), +(1021216, 0, 1, 15492, 'Bloodspattered Sash'), +(1021216, 0, 1, 15495, 'Bloodspattered Wristbands'), +(1021216, 0, 1, 3302, 'Brackwater Boots'), +(1021216, 0, 1, 9765, 'Cadet Vest'), +(1021216, 0, 1, 3653, 'Ceremonial Buckler'), +(1021216, 0, 1, 3314, 'Ceremonial Leather Gloves'), +(1021216, 0, 1, 2073, 'Dwarven Hatchet'), +(1021216, 0, 1, 15309, 'Feral Cloak'), +(1021216, 0, 1, 9757, 'Gypsy Tunic'), +(1021216, 0, 1, 3036, 'Heavy Shortbow'), +(1021216, 0, 1, 2976, 'Hunting Gloves'), +(1021216, 0, 1, 15011, 'Lupine Cord'), +(1021216, 0, 1, 14365, 'Mystic\'s Cape'), +(1021216, 0, 1, 15970, 'Native Branch'), +(1021216, 0, 1, 9749, 'Simple Blouse'), +(1021216, 0, 1, 15933, 'Simple Branch'), +(1021216, 0, 1, 9748, 'Simple Robe'), +(1021216, 0, 1, 6550, 'Soldier\'s Wristguards'), +(1021216, 0, 1, 2980, 'Veteran Gloves'), +(1021216, 0, 1, 2978, 'Veteran Leggings'), +(1021216, 0, 1, 3651, 'Veteran Shield'), +(1021216, 0, 1, 6537, 'Willow Boots'), +(1021216, 0, 1, 6543, 'Willow Bracers'), +(1021216, 0, 1, 6542, 'Willow Cape'), +-- 13-17 +(1021317, 0, 1, 14114, 'Aboriginal Footwraps'), +(1021317, 0, 1, 14117, 'Aboriginal Gloves'), +(1021317, 0, 1, 3309, 'Barbaric Loincloth'), +(1021317, 0, 1, 6557, 'Bard\'s Boots'), +(1021317, 0, 1, 6559, 'Bard\'s Buckler'), +(1021317, 0, 1, 15489, 'Bloodspattered Sabatons'), +(1021317, 0, 1, 3305, 'Brackwater Leggings'), +(1021317, 0, 1, 15306, 'Feral Bindings'), +(1021317, 0, 1, 15304, 'Grizzly Jerkin'), +(1021317, 0, 1, 2974, 'Hunting Pants'), +(1021317, 0, 1, 4701, 'Inscribed Cloak'), +(1021317, 0, 1, 15016, 'Lupine Handwraps'), +(1021317, 0, 1, 15012, 'Lupine Slippers'), +(1021317, 0, 1, 4567, 'Merc Sword'), +(1021317, 0, 1, 14109, 'Native Robe'), +(1021317, 0, 1, 14096, 'Native Vest'), +(1021317, 0, 1, 15210, 'Raider Shortsword'), +(1021317, 0, 1, 9786, 'Raider\'s Cloak'), +(1021317, 0, 1, 6548, 'Soldier\'s Girdle'), +(1021317, 0, 1, 2970, 'Spellbinder Pants'), +(1021317, 0, 1, 15268, 'Twin-bladed Axe'), +(1021317, 0, 1, 2977, 'Veteran Armor'), +(1021317, 0, 1, 14724, 'War Paint Cloak'), +(1021317, 0, 1, 15487, 'War Torn Tunic'), +(1021317, 0, 1, 6539, 'Willow Belt'), +(1021317, 0, 1, 6541, 'Willow Gloves'), +-- 14-18 +(1021418, 0, 1, 14119, 'Aboriginal Loincloth'), +(1021418, 0, 1, 6554, 'Bard\'s Gloves'), +(1021418, 0, 1, 5212, 'Blazing Wand'), +(1021418, 0, 1, 3315, 'Ceremonial Leather Loincloth'), +(1021418, 0, 1, 15308, 'Feral Cord'), +(1021418, 0, 1, 2973, 'Hunting Tunic'), +(1021418, 0, 1, 6379, 'Inscribed Leather Belt'), +(1021418, 0, 1, 3205, 'Inscribed Leather Bracers'), +(1021418, 0, 1, 15014, 'Lupine Buckler'), +(1021418, 0, 1, 14025, 'Mystic\'s Belt'), +(1021418, 0, 1, 14366, 'Mystic\'s Bracelets'), +(1021418, 0, 1, 15501, 'Outrunner\'s Cloak'), +(1021418, 0, 1, 14563, 'Prospector\'s Cloak'), +(1021418, 0, 1, 14561, 'Prospector\'s Cuffs'), +(1021418, 0, 1, 9785, 'Raider\'s Bracers'), +(1021418, 0, 1, 14123, 'Ritual Cape'), +(1021418, 0, 1, 2983, 'Seer\'s Boots'), +(1021418, 0, 1, 6378, 'Seer\'s Cape'), +(1021418, 0, 1, 3645, 'Seer\'s Cuffs'), +(1021418, 0, 1, 2079, 'Sergeant\'s Warhammer'), +(1021418, 0, 1, 6551, 'Soldier\'s Boots'), +(1021418, 0, 1, 6547, 'Soldier\'s Gauntlets'), +(1021418, 0, 1, 6546, 'Soldier\'s Leggings'), +(1021418, 0, 1, 6560, 'Soldier\'s Shield'), +(1021418, 0, 1, 15926, 'Spellbinder Orb'), +(1021418, 0, 1, 6528, 'Spellbinder Robe'), +(1021418, 0, 1, 2969, 'Spellbinder Vest'), +(1021418, 0, 1, 4571, 'War Knife'), +(1021418, 0, 1, 14722, 'War Paint Anklewraps'), +(1021418, 0, 1, 14723, 'War Paint Bindings'), +(1021418, 0, 1, 14725, 'War Paint Waistband'), +-- 15-19 +(1021519, 0, 1, 9779, 'Bandit Cloak'), +(1021519, 0, 1, 3195, 'Barbaric Battle Axe'), +(1021519, 0, 1, 6531, 'Barbaric Cloth Robe'), +(1021519, 0, 1, 3310, 'Barbaric Cloth Vest'), +(1021519, 0, 1, 6553, 'Bard\'s Trousers'), +(1021519, 0, 1, 15493, 'Bloodspattered Loincloth'), +(1021519, 0, 1, 15494, 'Bloodspattered Shield'), +(1021519, 0, 1, 3306, 'Brackwater Vest'), +(1021519, 0, 1, 4695, 'Burnished Cloak'), +(1021519, 0, 1, 3313, 'Ceremonial Leather Harness'), +(1021519, 0, 1, 3196, 'Edged Bastard Sword'), +(1021519, 0, 1, 15310, 'Feral Gloves'), +(1021519, 0, 1, 15305, 'Feral Shoes'), +(1021519, 0, 1, 6380, 'Inscribed Buckler'), +(1021519, 0, 1, 2987, 'Inscribed Leather Boots'), +(1021519, 0, 1, 14364, 'Mystic\'s Slippers'), +(1021519, 0, 1, 2078, 'Northern Shortsword'), +(1021519, 0, 1, 15499, 'Outrunner\'s Cuffs'), +(1021519, 0, 1, 14161, 'Pagan Cape'), +(1021519, 0, 1, 14559, 'Prospector\'s Sash'), +(1021519, 0, 1, 9788, 'Raider\'s Belt'), +(1021519, 0, 1, 14122, 'Ritual Bands'), +(1021519, 0, 1, 15945, 'Runic Stave'), +(1021519, 0, 1, 4699, 'Seer\'s Belt'), +(1021519, 0, 1, 2984, 'Seer\'s Gloves'), +(1021519, 0, 1, 6545, 'Soldier\'s Armor'), +(1021519, 0, 1, 14726, 'War Paint Gloves'), +(1021519, 0, 1, 6540, 'Willow Pants'), +-- 16-20 +(1021620, 0, 1, 9777, 'Bandit Bracers'), +(1021620, 0, 1, 9775, 'Bandit Cinch'), +(1021620, 0, 1, 15222, 'Barbed Club'), +(1021620, 0, 1, 6552, 'Bard\'s Tunic'), +(1021620, 0, 1, 14174, 'Buccaneer\'s Boots'), +(1021620, 0, 1, 14166, 'Buccaneer\'s Bracers'), +(1021620, 0, 1, 14167, 'Buccaneer\'s Cape'), +(1021620, 0, 1, 3211, 'Burnished Bracers'), +(1021620, 0, 1, 15307, 'Feral Buckler'), +(1021620, 0, 1, 15507, 'Grunt\'s Bracers'), +(1021620, 0, 1, 15508, 'Grunt\'s Cape'), +(1021620, 0, 1, 3040, 'Hunter\'s Muzzle Loader'), +(1021620, 0, 1, 2988, 'Inscribed Leather Gloves'), +(1021620, 0, 1, 15017, 'Lupine Leggings'), +(1021620, 0, 1, 4575, 'Medicine Staff'), +(1021620, 0, 1, 14367, 'Mystic\'s Gloves'), +(1021620, 0, 1, 14370, 'Mystic\'s Woolies'), +(1021620, 0, 1, 15497, 'Outrunner\'s Cord'), +(1021620, 0, 1, 14160, 'Pagan Bands'), +(1021620, 0, 1, 14560, 'Prospector\'s Boots'), +(1021620, 0, 1, 14564, 'Prospector\'s Mitts'), +(1021620, 0, 1, 9784, 'Raider\'s Boots'), +(1021620, 0, 1, 9787, 'Raider\'s Gauntlets'), +(1021620, 0, 1, 9789, 'Raider\'s Legguards'), +(1021620, 0, 1, 9790, 'Raider\'s Shield'), +(1021620, 0, 1, 15114, 'Rigid Cape'), +(1021620, 0, 1, 14131, 'Ritual Belt'), +(1021620, 0, 1, 14727, 'War Paint Legguards'), +(1021620, 0, 1, 7554, 'Willow Branch'), +(1021620, 0, 1, 6538, 'Willow Robe'), +(1021620, 0, 1, 6536, 'Willow Vest'), +-- 17-21 +(1021721, 0, 1, 14120, 'Aboriginal Robe'), +(1021721, 0, 1, 15971, 'Aboriginal Rod'), +(1021721, 0, 1, 14121, 'Aboriginal Vest'), +(1021721, 0, 1, 9776, 'Bandit Boots'), +(1021721, 0, 1, 9778, 'Bandit Buckler'), +(1021721, 0, 1, 9780, 'Bandit Gloves'), +(1021721, 0, 1, 14173, 'Buccaneer\'s Cord'), +(1021721, 0, 1, 14168, 'Buccaneer\'s Gloves'), +(1021721, 0, 1, 4697, 'Burnished Girdle'), +(1021721, 0, 1, 2992, 'Burnished Gloves'), +(1021721, 0, 1, 6575, 'Defender Cloak'), +(1021721, 0, 1, 15312, 'Feral Leggings'), +(1021721, 0, 1, 15248, 'Gleaming Claymore'), +(1021721, 0, 1, 9770, 'Greenweave Cloak'), +(1021721, 0, 1, 15510, 'Grunt\'s Belt'), +(1021721, 0, 1, 3184, 'Hook Dagger'), +(1021721, 0, 1, 14745, 'Hulking Cloak'), +(1021721, 0, 1, 2986, 'Inscribed Leather Pants'), +(1021721, 0, 1, 11981, 'Lead Band'), +(1021721, 0, 1, 15018, 'Lupine Vest'), +(1021721, 0, 1, 5207, 'Opaque Wand'), +(1021721, 0, 1, 15502, 'Outrunner\'s Gloves'), +(1021721, 0, 1, 15498, 'Outrunner\'s Slippers'), +(1021721, 0, 1, 11965, 'Quartz Ring'), +(1021721, 0, 1, 9783, 'Raider\'s Chestpiece'), +(1021721, 0, 1, 15110, 'Rigid Belt'), +(1021721, 0, 1, 15112, 'Rigid Bracelets'), +(1021721, 0, 1, 14124, 'Ritual Gloves'), +(1021721, 0, 1, 14129, 'Ritual Sandals'), +(1021721, 0, 1, 6585, 'Scouting Cloak'), +(1021721, 0, 1, 2982, 'Seer\'s Pants'), +(1021721, 0, 1, 6563, 'Shimmering Bracers'), +(1021721, 0, 1, 14729, 'War Paint Shield'), +-- 18-22 +(1021822, 0, 1, 15488, 'Bloodspattered Surcoat'), +(1021822, 0, 1, 14571, 'Bristlebark Cape'), +(1021822, 0, 1, 2991, 'Burnished Boots'), +(1021822, 0, 1, 2990, 'Burnished Leggings'), +(1021822, 0, 1, 3655, 'Burnished Shield'), +(1021822, 0, 1, 2989, 'Burnished Tunic'), +(1021822, 0, 1, 9768, 'Greenweave Bracers'), +(1021822, 0, 1, 4568, 'Grunt Axe'), +(1021822, 0, 1, 15506, 'Grunt\'s AnkleWraps'), +(1021822, 0, 1, 15509, 'Grunt\'s Handwraps'), +(1021822, 0, 1, 2985, 'Inscribed Leather Breastplate'), +(1021822, 0, 1, 4576, 'Light Bow'), +(1021822, 0, 1, 3193, 'Oak Mallet'), +(1021822, 0, 1, 14164, 'Pagan Belt'), +(1021822, 0, 1, 15893, 'Prospector\'s Buckler'), +(1021822, 0, 1, 14565, 'Prospector\'s Woolies'), +(1021822, 0, 1, 15111, 'Rigid Moccasins'), +(1021822, 0, 1, 12052, 'Ring of the Moon'), +(1021822, 0, 1, 14125, 'Ritual Leggings'), +(1021822, 0, 1, 6581, 'Scouting Belt'), +(1021822, 0, 1, 6583, 'Scouting Bracers'), +(1021822, 0, 1, 7608, 'Seer\'s Fine Stein'), +(1021822, 0, 1, 6561, 'Seer\'s Padded Armor'), +(1021822, 0, 1, 2981, 'Seer\'s Robe'), +(1021822, 0, 1, 6562, 'Shimmering Boots'), +(1021822, 0, 1, 6564, 'Shimmering Cloak'), +(1021822, 0, 1, 12053, 'Volcanic Rock Ring'), +-- 19-23 +(1021923, 0, 1, 9781, 'Bandit Pants'), +(1021923, 0, 1, 3199, 'Battle Slayer'), +(1021923, 0, 1, 14569, 'Bristlebark Bindings'), +(1021923, 0, 1, 14171, 'Buccaneer\'s Pants'), +(1021923, 0, 1, 11993, 'Clay Ring'), +(1021923, 0, 1, 6574, 'Defender Bracers'), +(1021923, 0, 1, 6576, 'Defender Girdle'), +(1021923, 0, 1, 15311, 'Feral Harness'), +(1021923, 0, 1, 4710, 'Forest Cloak'), +(1021923, 0, 1, 9812, 'Fortified Cloak'), +(1021923, 0, 1, 9766, 'Greenweave Sash'), +(1021923, 0, 1, 14743, 'Hulking Bands'), +(1021923, 0, 1, 14746, 'Hulking Belt'), +(1021923, 0, 1, 12006, 'Meadow Ring'), +(1021923, 0, 1, 15211, 'Militant Shortsword'), +(1021923, 0, 1, 15503, 'Outrunner\'s Legguards'), +(1021923, 0, 1, 15504, 'Outrunner\'s Shield'), +(1021923, 0, 1, 14159, 'Pagan Shoes'), +(1021923, 0, 1, 15115, 'Rigid Gloves'), +(1021923, 0, 1, 14376, 'Sanguine Cape'), +(1021923, 0, 1, 6582, 'Scouting Boots'), +(1021923, 0, 1, 6571, 'Scouting Buckler'), +(1021923, 0, 1, 6565, 'Shimmering Gloves'), +(1021923, 0, 1, 6570, 'Shimmering Sash'), +(1021923, 0, 1, 789, 'Stout Battlehammer'), +(1021923, 0, 1, 15333, 'Wrangler\'s Cloak'), +-- 20-24 +(1022024, 0, 1, 9782, 'Bandit Jerkin'), +(1022024, 0, 1, 3198, 'Battering Hammer'), +(1022024, 0, 1, 3065, 'Bright Boots'), +(1022024, 0, 1, 3647, 'Bright Bracers'), +(1022024, 0, 1, 6381, 'Bright Cloak'), +(1022024, 0, 1, 14567, 'Bristlebark Belt'), +(1022024, 0, 1, 14568, 'Bristlebark Boots'), +(1022024, 0, 1, 15912, 'Buccaneer\'s Orb'), +(1022024, 0, 1, 14172, 'Buccaneer\'s Robes'), +(1022024, 0, 1, 14175, 'Buccaneer\'s Vest'), +(1022024, 0, 1, 6573, 'Defender Boots'), +(1022024, 0, 1, 6577, 'Defender Gauntlets'), +(1022024, 0, 1, 6578, 'Defender Leggings'), +(1022024, 0, 1, 6572, 'Defender Shield'), +(1022024, 0, 1, 6580, 'Defender Tunic'), +(1022024, 0, 1, 6382, 'Forest Leather Belt'), +(1022024, 0, 1, 790, 'Forester\'s Axe'), +(1022024, 0, 1, 9767, 'Greenweave Sandals'), +(1022024, 0, 1, 14747, 'Hulking Gauntlets'), +(1022024, 0, 1, 14371, 'Mystic\'s Robe'), +(1022024, 0, 1, 15946, 'Mystic\'s Sphere'), +(1022024, 0, 1, 14369, 'Mystic\'s Wrap'), +(1022024, 0, 1, 14162, 'Pagan Mitts'), +(1022024, 0, 1, 14562, 'Prospector\'s Chestpiece'), +(1022024, 0, 1, 15113, 'Rigid Buckler'), +(1022024, 0, 1, 6586, 'Scouting Gloves'), +(1022024, 0, 1, 3039, 'Short Ash Bow'), +(1022024, 0, 1, 15519, 'Spiked Chain Cloak'), +(1022024, 0, 1, 11982, 'Viridian Band'), +(1022024, 0, 1, 14730, 'War Paint Chestpiece'), +(1022024, 0, 1, 15331, 'Wrangler\'s Wristbands'), +(1022024, 0, 1, 11967, 'Zircon Band'), +-- 21-25 +(1022125, 0, 1, 4998, 'Blood Ring'), +(1022125, 0, 1, 4708, 'Bright Belt'), +(1022125, 0, 1, 3066, 'Bright Gloves'), +(1022125, 0, 1, 14572, 'Bristlebark Gloves'), +(1022125, 0, 1, 3740, 'Decapitating Sword'), +(1022125, 0, 1, 12054, 'Demon Band'), +(1022125, 0, 1, 6383, 'Forest Buckler'), +(1022125, 0, 1, 3057, 'Forest Leather Boots'), +(1022125, 0, 1, 3202, 'Forest Leather Bracers'), +(1022125, 0, 1, 9814, 'Fortified Belt'), +(1022125, 0, 1, 9811, 'Fortified Bracers'), +(1022125, 0, 1, 15511, 'Grunt\'s Legguards'), +(1022125, 0, 1, 15512, 'Grunt\'s Shield'), +(1022125, 0, 1, 14742, 'Hulking Boots'), +(1022125, 0, 1, 15223, 'Jagged Star'), +(1022125, 0, 1, 4706, 'Lambent Scale Cloak'), +(1022125, 0, 1, 15269, 'Massive Battle Axe'), +(1022125, 0, 1, 15500, 'Outrunner\'s Chestguard'), +(1022125, 0, 1, 15117, 'Rigid Leggings'), +(1022125, 0, 1, 14127, 'Ritual Shroud'), +(1022125, 0, 1, 15972, 'Ritual Stein'), +(1022125, 0, 1, 14133, 'Ritual Tunic'), +(1022125, 0, 1, 14374, 'Sanguine Sandals'), +(1022125, 0, 1, 6587, 'Scouting Trousers'), +(1022125, 0, 1, 15526, 'Sentry\'s Cape'), +(1022125, 0, 1, 6568, 'Shimmering Trousers'), +(1022125, 0, 1, 9805, 'Superior Cloak'), +(1022125, 0, 1, 14179, 'Watcher\'s Cape'), +(1022125, 0, 1, 15329, 'Wrangler\'s Belt'), +-- 22-26 +(1022226, 0, 1, 15224, 'Battlesmasher'), +(1022226, 0, 1, 15894, 'Bristlebark Buckler'), +(1022226, 0, 1, 11994, 'Coral Band'), +(1022226, 0, 1, 3058, 'Forest Leather Gloves'), +(1022226, 0, 1, 4709, 'Forest Leather Mantle'), +(1022226, 0, 1, 9810, 'Fortified Boots'), +(1022226, 0, 1, 9818, 'Fortified Chain'), +(1022226, 0, 1, 9813, 'Fortified Gauntlets'), +(1022226, 0, 1, 9815, 'Fortified Leggings'), +(1022226, 0, 1, 9816, 'Fortified Shield'), +(1022226, 0, 1, 9771, 'Greenweave Gloves'), +(1022226, 0, 1, 15513, 'Grunt\'s Pauldrons'), +(1022226, 0, 1, 15259, 'Hefty Battlehammer'), +(1022226, 0, 1, 14748, 'Hulking Leggings'), +(1022226, 0, 1, 9792, 'Ivycloth Boots'), +(1022226, 0, 1, 9793, 'Ivycloth Bracelets'), +(1022226, 0, 1, 9794, 'Ivycloth Cloak'), +(1022226, 0, 1, 14165, 'Pagan Britches'), +(1022226, 0, 1, 12007, 'Prairie Ring'), +(1022226, 0, 1, 14566, 'Prospector\'s Pads'), +(1022226, 0, 1, 15230, 'Ridge Cleaver'), +(1022226, 0, 1, 15122, 'Robust Bracers'), +(1022226, 0, 1, 15124, 'Robust Cloak'), +(1022226, 0, 1, 14373, 'Sanguine Belt'), +(1022226, 0, 1, 14375, 'Sanguine Cuffs'), +(1022226, 0, 1, 6584, 'Scouting Tunic'), +(1022226, 0, 1, 6567, 'Shimmering Armor'), +(1022226, 0, 1, 6569, 'Shimmering Robe'), +(1022226, 0, 1, 7558, 'Shimmering Stave'), +(1022226, 0, 1, 15515, 'Spiked Chain Belt'), +(1022226, 0, 1, 15517, 'Spiked Chain Wristbands'), +(1022226, 0, 1, 9801, 'Superior Belt'), +(1022226, 0, 1, 15330, 'Wrangler\'s Boots'), +-- 23-27 +(1022327, 0, 1, 11968, 'Amber Hoop'), +(1022327, 0, 1, 15241, 'Battle Knife'), +(1022327, 0, 1, 6593, 'Battleforge Cloak'), +(1022327, 0, 1, 4661, 'Bright Mantle'), +(1022327, 0, 1, 3067, 'Bright Pants'), +(1022327, 0, 1, 14574, 'Bristlebark Britches'), +(1022327, 0, 1, 11983, 'Chrome Ring'), +(1022327, 0, 1, 6604, 'Dervish Cape'), +(1022327, 0, 1, 8186, 'Dire Wand'), +(1022327, 0, 1, 3055, 'Forest Leather Chestpiece'), +(1022327, 0, 1, 3056, 'Forest Leather Pants'), +(1022327, 0, 1, 9817, 'Fortified Spaulders'), +(1022327, 0, 1, 10287, 'Greenweave Mantle'), +(1022327, 0, 1, 15514, 'Grunt\'s Chestpiece'), +(1022327, 0, 1, 15891, 'Hulking Shield'), +(1022327, 0, 1, 14749, 'Hulking Spaulders'), +(1022327, 0, 1, 9795, 'Ivycloth Gloves'), +(1022327, 0, 1, 9799, 'Ivycloth Sash'), +(1022327, 0, 1, 3212, 'Lambent Scale Bracers'), +(1022327, 0, 1, 4707, 'Lambent Scale Girdle'), +(1022327, 0, 1, 3048, 'Lambent Scale Legguards'), +(1022327, 0, 1, 15974, 'Pagan Rod'), +(1022327, 0, 1, 14158, 'Pagan Vest'), +(1022327, 0, 1, 14163, 'Pagan Wraps'), +(1022327, 0, 1, 15348, 'Pathfinder Bracers'), +(1022327, 0, 1, 15249, 'Polished Zweihander'), +(1022327, 0, 1, 15116, 'Rigid Shoulders'), +(1022327, 0, 1, 15118, 'Rigid Tunic'), +(1022327, 0, 1, 15120, 'Robust Girdle'), +(1022327, 0, 1, 14377, 'Sanguine Handwraps'), +(1022327, 0, 1, 15532, 'Sentry\'s Armsplints'), +(1022327, 0, 1, 15528, 'Sentry\'s Sash'), +(1022327, 0, 1, 4713, 'Silver-thread Cloak'), +(1022327, 0, 1, 15520, 'Spiked Chain Gauntlets'), +(1022327, 0, 1, 9802, 'Superior Boots'), +(1022327, 0, 1, 9803, 'Superior Bracers'), +(1022327, 0, 1, 9804, 'Superior Buckler'), +(1022327, 0, 1, 14176, 'Watcher\'s Boots'), +(1022327, 0, 1, 14177, 'Watcher\'s Cuffs'), +-- 24-28 +(1022428, 0, 1, 4999, 'Azora\'s Will'), +(1022428, 0, 1, 6591, 'Battleforge Wristguards'), +(1022428, 0, 1, 6608, 'Bright Armor'), +(1022428, 0, 1, 3069, 'Bright Robe'), +(1022428, 0, 1, 15927, 'Bright Sphere'), +(1022428, 0, 1, 14573, 'Bristlebark Amice'), +(1022428, 0, 1, 6600, 'Dervish Belt'), +(1022428, 0, 1, 6602, 'Dervish Bracers'), +(1022428, 0, 1, 14580, 'Dokebi Bracers'), +(1022428, 0, 1, 2072, 'Dwarven Magestaff'), +(1022428, 0, 1, 4715, 'Emblazoned Cloak'), +(1022428, 0, 1, 15212, 'Fighter Broadsword'), +(1022428, 0, 1, 9769, 'Greenweave Branch'), +(1022428, 0, 1, 9772, 'Greenweave Leggings'), +(1022428, 0, 1, 9773, 'Greenweave Robe'), +(1022428, 0, 1, 9774, 'Greenweave Vest'), +(1022428, 0, 1, 5001, 'Heart Ring'), +(1022428, 0, 1, 9796, 'Ivycloth Mantle'), +(1022428, 0, 1, 3045, 'Lambent Scale Boots'), +(1022428, 0, 1, 3049, 'Lambent Scale Breastplate'), +(1022428, 0, 1, 3047, 'Lambent Scale Gloves'), +(1022428, 0, 1, 4705, 'Lambent Scale Pauldrons'), +(1022428, 0, 1, 3656, 'Lambent Scale Shield'), +(1022428, 0, 1, 15340, 'Pathfinder Cloak'), +(1022428, 0, 1, 8183, 'Precision Bow'), +(1022428, 0, 1, 14188, 'Raincaller Cloak'), +(1022428, 0, 1, 14378, 'Sanguine Mantle'), +(1022428, 0, 1, 15527, 'Sentry\'s Gloves'), +(1022428, 0, 1, 6394, 'Silver-thread Boots'), +(1022428, 0, 1, 4036, 'Silver-thread Cuffs'), +(1022428, 0, 1, 4714, 'Silver-thread Sash'), +(1022428, 0, 1, 14752, 'Slayer\'s Cape'), +(1022428, 0, 1, 15521, 'Spiked Chain Leggings'), +(1022428, 0, 1, 15523, 'Spiked Chain Shoulder Pads'), +(1022428, 0, 1, 15516, 'Spiked Chain Slippers'), +(1022428, 0, 1, 9806, 'Superior Gloves'), +(1022428, 0, 1, 9807, 'Superior Shoulders'), +(1022428, 0, 1, 14185, 'Watcher\'s Cinch'), +(1022428, 0, 1, 15332, 'Wrangler\'s Buckler'), +(1022428, 0, 1, 15334, 'Wrangler\'s Gloves'), +(1022428, 0, 1, 15336, 'Wrangler\'s Leggings'), +-- 25-29 +(1022529, 0, 1, 3201, 'Barbarian War Axe'), +(1022529, 0, 1, 6595, 'Battleforge Gauntlets'), +(1022529, 0, 1, 6594, 'Battleforge Girdle'), +(1022529, 0, 1, 6596, 'Battleforge Legguards'), +(1022529, 0, 1, 6597, 'Battleforge Shoulderguards'), +(1022529, 0, 1, 14570, 'Bristlebark Blouse'), +(1022529, 0, 1, 3206, 'Cavalier Two-hander'), +(1022529, 0, 1, 2819, 'Cross Dagger'), +(1022529, 0, 1, 6601, 'Dervish Boots'), +(1022529, 0, 1, 6598, 'Dervish Buckler'), +(1022529, 0, 1, 6605, 'Dervish Gloves'), +(1022529, 0, 1, 14582, 'Dokebi Cape'), +(1022529, 0, 1, 4049, 'Emblazoned Bracers'), +(1022529, 0, 1, 4711, 'Glimmering Cloak'), +(1022529, 0, 1, 14744, 'Hulking Chestguard'), +(1022529, 0, 1, 11995, 'Ivory Band'), +(1022529, 0, 1, 9797, 'Ivycloth Pants'), +(1022529, 0, 1, 15347, 'Pathfinder Belt'), +(1022529, 0, 1, 14194, 'Raincaller Cord'), +(1022529, 0, 1, 14187, 'Raincaller Cuffs'), +(1022529, 0, 1, 15121, 'Robust Boots'), +(1022529, 0, 1, 15123, 'Robust Buckler'), +(1022529, 0, 1, 6612, 'Sage\'s Boots'), +(1022529, 0, 1, 6613, 'Sage\'s Bracers'), +(1022529, 0, 1, 6614, 'Sage\'s Cloak'), +(1022529, 0, 1, 14372, 'Sanguine Armor'), +(1022529, 0, 1, 14380, 'Sanguine Robe'), +(1022529, 0, 1, 15947, 'Sanguine Star'), +(1022529, 0, 1, 12008, 'Savannah Ring'), +(1022529, 0, 1, 15525, 'Sentry\'s Slippers'), +(1022529, 0, 1, 6393, 'Silver-thread Gloves'), +(1022529, 0, 1, 14750, 'Slayer\'s Cuffs'), +(1022529, 0, 1, 14755, 'Slayer\'s Sash'), +(1022529, 0, 1, 9808, 'Superior Leggings'), +(1022529, 0, 1, 9809, 'Superior Tunic'), +(1022529, 0, 1, 14181, 'Watcher\'s Handwraps'), +(1022529, 0, 1, 14182, 'Watcher\'s Mantle'), +(1022529, 0, 1, 15537, 'Wicked Chain Cloak'), +(1022529, 0, 1, 15338, 'Wrangler\'s Mantle'), +-- 26-30 +(1022630, 0, 1, 9838, 'Banded Cloak'), +(1022630, 0, 1, 6592, 'Battleforge Armor'), +(1022630, 0, 1, 6590, 'Battleforge Boots'), +(1022630, 0, 1, 6599, 'Battleforge Shield'), +(1022630, 0, 1, 11984, 'Cobalt Ring'), +(1022630, 0, 1, 15132, 'Cutthroat\'s Armguards'), +(1022630, 0, 1, 7415, 'Dervish Spaulders'), +(1022630, 0, 1, 14578, 'Dokebi Cord'), +(1022630, 0, 1, 9822, 'Durable Cape'), +(1022630, 0, 1, 6398, 'Emblazoned Belt'), +(1022630, 0, 1, 6397, 'Emblazoned Gloves'), +(1022630, 0, 1, 8184, 'Firestarter'), +(1022630, 0, 1, 6387, 'Glimmering Mail Bracers'), +(1022630, 0, 1, 4712, 'Glimmering Mail Girdle'), +(1022630, 0, 1, 9800, 'Ivy Orb'), +(1022630, 0, 1, 9798, 'Ivycloth Robe'), +(1022630, 0, 1, 9791, 'Ivycloth Tunic'), +(1022630, 0, 1, 11969, 'Jacinth Circle'), +(1022630, 0, 1, 15284, 'Long Battle Bow'), +(1022630, 0, 1, 2077, 'Magician Staff'), +(1022630, 0, 1, 14195, 'Raincaller Boots'), +(1022630, 0, 1, 14186, 'Raincaller Mantle'), +(1022630, 0, 1, 14402, 'Resilient Bands'), +(1022630, 0, 1, 14400, 'Resilient Cape'), +(1022630, 0, 1, 15125, 'Robust Gloves'), +(1022630, 0, 1, 15126, 'Robust Leggings'), +(1022630, 0, 1, 6615, 'Sage\'s Gloves'), +(1022630, 0, 1, 6611, 'Sage\'s Sash'), +(1022630, 0, 1, 14379, 'Sanguine Trousers'), +(1022630, 0, 1, 9831, 'Scaled Cloak'), +(1022630, 0, 1, 9829, 'Scaled Leather Bracers'), +(1022630, 0, 1, 15529, 'Sentry\'s Leggings'), +(1022630, 0, 1, 6395, 'Silver-thread Amice'), +(1022630, 0, 1, 14754, 'Slayer\'s Gloves'), +(1022630, 0, 1, 14756, 'Slayer\'s Slippers'), +(1022630, 0, 1, 15522, 'Spiked Chain Shield'), +(1022630, 0, 1, 15547, 'Thick Scale Cloak'), +(1022630, 0, 1, 15535, 'Wicked Chain Bracers'), +(1022630, 0, 1, 15337, 'Wrangler\'s Wraps'), +-- 27-31), +(1022731, 0, 1, 9837, 'Banded Bracers'), +(1022731, 0, 1, 3210, 'Brutal War Axe'), +(1022731, 0, 1, 15135, 'Cutthroat\'s Cape'), +(1022731, 0, 1, 6607, 'Dervish Leggings'), +(1022731, 0, 1, 6603, 'Dervish Tunic'), +(1022731, 0, 1, 10404, 'Durable Belt'), +(1022731, 0, 1, 9821, 'Durable Bracers'), +(1022731, 0, 1, 7356, 'Elder\'s Cloak'), +(1022731, 0, 1, 4051, 'Emblazoned Boots'), +(1022731, 0, 1, 4064, 'Emblazoned Buckler'), +(1022731, 0, 1, 6399, 'Emblazoned Shoulders'), +(1022731, 0, 1, 4072, 'Glimmering Mail Gauntlets'), +(1022731, 0, 1, 6386, 'Glimmering Mail Legguards'), +(1022731, 0, 1, 6388, 'Glimmering Mail Pauldrons'), +(1022731, 0, 1, 5002, 'Glowing Green Talisman'), +(1022731, 0, 1, 15351, 'Headhunter\'s Bands'), +(1022731, 0, 1, 15242, 'Honed Stiletto'), +(1022731, 0, 1, 15341, 'Pathfinder Footpads'), +(1022731, 0, 1, 15343, 'Pathfinder Gloves'), +(1022731, 0, 1, 15342, 'Pathfinder Guard'), +(1022731, 0, 1, 7419, 'Phalanx Cloak'), +(1022731, 0, 1, 14191, 'Raincaller Mitts'), +(1022731, 0, 1, 14406, 'Resilient Cord'), +(1022731, 0, 1, 15127, 'Robust Shoulders'), +(1022731, 0, 1, 6617, 'Sage\'s Mantle'), +(1022731, 0, 1, 9827, 'Scaled Leather Belt'), +(1022731, 0, 1, 15531, 'Sentry\'s Shoulderguards'), +(1022731, 0, 1, 4037, 'Silver-thread Pants'), +(1022731, 0, 1, 12047, 'Spectral Necklace'), +(1022731, 0, 1, 15518, 'Spiked Chain Breastplate'), +(1022731, 0, 1, 15545, 'Thick Scale Bracelets'), +(1022731, 0, 1, 14197, 'Thistlefur Bands'), +(1022731, 0, 1, 3186, 'Viking Sword'), +(1022731, 0, 1, 14180, 'Watcher\'s Jerkin'), +(1022731, 0, 1, 14183, 'Watcher\'s Leggings'), +(1022731, 0, 1, 14184, 'Watcher\'s Robes'), +(1022731, 0, 1, 15973, 'Watcher\'s Star'), +(1022731, 0, 1, 15538, 'Wicked Chain Gauntlets'), +(1022731, 0, 1, 15539, 'Wicked Chain Waistband'), +-- 28-32 +(1022832, 0, 1, 3041, '"Mage-Eye" Blunderbuss'), +(1022832, 0, 1, 5007, 'Band of Thorns'), +(1022832, 0, 1, 9839, 'Banded Gauntlets'), +(1022832, 0, 1, 9840, 'Banded Girdle'), +(1022832, 0, 1, 5003, 'Crystal Starfire Medallion'), +(1022832, 0, 1, 15136, 'Cutthroat\'s Belt'), +(1022832, 0, 1, 14579, 'Dokebi Boots'), +(1022832, 0, 1, 14608, 'Dokebi Buckler'), +(1022832, 0, 1, 9820, 'Durable Boots'), +(1022832, 0, 1, 9823, 'Durable Gloves'), +(1022832, 0, 1, 7355, 'Elder\'s Bracers'), +(1022832, 0, 1, 7370, 'Elder\'s Sash'), +(1022832, 0, 1, 4048, 'Emblazoned Hat'), +(1022832, 0, 1, 4050, 'Emblazoned Leggings'), +(1022832, 0, 1, 4071, 'Glimmering Mail Breastplate'), +(1022832, 0, 1, 6389, 'Glimmering Mail Coif'), +(1022832, 0, 1, 4073, 'Glimmering Mail Greaves'), +(1022832, 0, 1, 6400, 'Glimmering Shield'), +(1022832, 0, 1, 7410, 'Infiltrator Bracers'), +(1022832, 0, 1, 7411, 'Infiltrator Cloak'), +(1022832, 0, 1, 865, 'Leaden Mace'), +(1022832, 0, 1, 15344, 'Pathfinder Pants'), +(1022832, 0, 1, 15345, 'Pathfinder Shoulder Pads'), +(1022832, 0, 1, 7416, 'Phalanx Bracers'), +(1022832, 0, 1, 15559, 'Pillager\'s Cloak'), +(1022832, 0, 1, 14193, 'Raincaller Pants'), +(1022832, 0, 1, 14192, 'Raincaller Robes'), +(1022832, 0, 1, 15975, 'Raincaller Scepter'), +(1022832, 0, 1, 14190, 'Raincaller Vest'), +(1022832, 0, 1, 14399, 'Resilient Boots'), +(1022832, 0, 1, 14403, 'Resilient Handgrips'), +(1022832, 0, 1, 15129, 'Robust Helm'), +(1022832, 0, 1, 15128, 'Robust Tunic'), +(1022832, 0, 1, 10288, 'Sage\'s Circlet'), +(1022832, 0, 1, 9828, 'Scaled Leather Boots'), +(1022832, 0, 1, 9832, 'Scaled Leather Gloves'), +(1022832, 0, 1, 15533, 'Sentry\'s Headdress'), +(1022832, 0, 1, 15530, 'Sentry\'s Shield'), +(1022832, 0, 1, 15524, 'Sentry\'s Surcoat'), +(1022832, 0, 1, 7110, 'Silver-thread Armor'), +(1022832, 0, 1, 4035, 'Silver-thread Robe'), +(1022832, 0, 1, 15928, 'Silver-thread Rod'), +(1022832, 0, 1, 14758, 'Slayer\'s Shoulderguards'), +(1022832, 0, 1, 15231, 'Splitting Hatchet'), +(1022832, 0, 1, 15549, 'Thick Scale Belt'), +(1022832, 0, 1, 14198, 'Thistlefur Cloak'), +(1022832, 0, 1, 14178, 'Watcher\'s Cap'), +(1022832, 0, 1, 15534, 'Wicked Chain Boots'), +-- 29-33), +(1022933, 0, 1, 15285, 'Archer\'s Longbow'), +(1022933, 0, 1, 10409, 'Banded Boots'), +(1022933, 0, 1, 10408, 'Banded Helm'), +(1022933, 0, 1, 9841, 'Banded Leggings'), +(1022933, 0, 1, 9842, 'Banded Pauldrons'), +(1022933, 0, 1, 12028, 'Basalt Necklace'), +(1022933, 0, 1, 12019, 'Cerulean Talisman'), +(1022933, 0, 1, 4716, 'Combat Cloak'), +(1022933, 0, 1, 15131, 'Cutthroat\'s Boots'), +(1022933, 0, 1, 14583, 'Dokebi Gloves'), +(1022933, 0, 1, 14585, 'Dokebi Leggings'), +(1022933, 0, 1, 14587, 'Dokebi Mantle'), +(1022933, 0, 1, 10289, 'Durable Hat'), +(1022933, 0, 1, 9824, 'Durable Shoulders'), +(1022933, 0, 1, 7366, 'Elder\'s Gloves'), +(1022933, 0, 1, 6396, 'Emblazoned Chestpiece'), +(1022933, 0, 1, 14763, 'Enduring Cape'), +(1022933, 0, 1, 15250, 'Glimmering Flamberge'), +(1022933, 0, 1, 15354, 'Headhunter\'s Cloak'), +(1022933, 0, 1, 7406, 'Infiltrator Cord'), +(1022933, 0, 1, 7412, 'Infiltrator Gloves'), +(1022933, 0, 1, 4722, 'Insignia Cloak'), +(1022933, 0, 1, 4719, 'Nightsky Cloak'), +(1022933, 0, 1, 15346, 'Pathfinder Vest'), +(1022933, 0, 1, 7422, 'Phalanx Girdle'), +(1022933, 0, 1, 15556, 'Pillager\'s Bracers'), +(1022933, 0, 1, 14189, 'Raincaller Cap'), +(1022933, 0, 1, 14397, 'Resilient Mantle'), +(1022933, 0, 1, 6609, 'Sage\'s Cloth'), +(1022933, 0, 1, 6616, 'Sage\'s Pants'), +(1022933, 0, 1, 6610, 'Sage\'s Robe'), +(1022933, 0, 1, 15934, 'Sage\'s Stave'), +(1022933, 0, 1, 10406, 'Scaled Leather Headband'), +(1022933, 0, 1, 9834, 'Scaled Leather Shoulders'), +(1022933, 0, 1, 9830, 'Scaled Shield'), +(1022933, 0, 1, 14757, 'Slayer\'s Pants'), +(1022933, 0, 1, 15892, 'Slayer\'s Shield'), +(1022933, 0, 1, 15548, 'Thick Scale Gauntlets'), +(1022933, 0, 1, 15544, 'Thick Scale Sabatons'), +(1022933, 0, 1, 14205, 'Thistlefur Belt'), +(1022933, 0, 1, 14196, 'Thistlefur Sandals'), +(1022933, 0, 1, 14206, 'Vital Bracelets'), +(1022933, 0, 1, 14210, 'Vital Cape'), +(1022933, 0, 1, 5214, 'Wand of Eventide'), +(1022933, 0, 1, 15542, 'Wicked Chain Shoulder Pads'), +-- 30-34 +(1023034, 0, 1, 9836, 'Banded Armor'), +(1023034, 0, 1, 9843, 'Banded Shield'), +(1023034, 0, 1, 3042, 'BKP "Sparrow" Smallbore'), +(1023034, 0, 1, 9847, 'Conjurer\'s Cloak'), +(1023034, 0, 1, 15133, 'Cutthroat\'s Buckler'), +(1023034, 0, 1, 15137, 'Cutthroat\'s Mitts'), +(1023034, 0, 1, 15139, 'Cutthroat\'s Pants'), +(1023034, 0, 1, 14581, 'Dokebi Chestguard'), +(1023034, 0, 1, 9825, 'Durable Pants'), +(1023034, 0, 1, 7354, 'Elder\'s Boots'), +(1023034, 0, 1, 7367, 'Elder\'s Mantle'), +(1023034, 0, 1, 15143, 'Ghostwalker Bindings'), +(1023034, 0, 1, 15147, 'Ghostwalker Cloak'), +(1023034, 0, 1, 15232, 'Hacking Cleaver'), +(1023034, 0, 1, 15349, 'Headhunter\'s Belt'), +(1023034, 0, 1, 7409, 'Infiltrator Boots'), +(1023034, 0, 1, 7330, 'Infiltrator Buckler'), +(1023034, 0, 1, 7413, 'Infiltrator Cap'), +(1023034, 0, 1, 7408, 'Infiltrator Shoulders'), +(1023034, 0, 1, 6410, 'Insignia Bracers'), +(1023034, 0, 1, 6403, 'Mail Combat Armguards'), +(1023034, 0, 1, 15568, 'Marauder\'s Cloak'), +(1023034, 0, 1, 4720, 'Nightsky Sash'), +(1023034, 0, 1, 6407, 'Nightsky Wristbands'), +(1023034, 0, 1, 7421, 'Phalanx Gauntlets'), +(1023034, 0, 1, 7420, 'Phalanx Headguard'), +(1023034, 0, 1, 7424, 'Phalanx Spaulders'), +(1023034, 0, 1, 15555, 'Pillager\'s Boots'), +(1023034, 0, 1, 15554, 'Pillager\'s Girdle'), +(1023034, 0, 1, 9867, 'Renegade Cloak'), +(1023034, 0, 1, 14401, 'Resilient Cap'), +(1023034, 0, 1, 14404, 'Resilient Leggings'), +(1023034, 0, 1, 14405, 'Resilient Robe'), +(1023034, 0, 1, 14398, 'Resilient Tunic'), +(1023034, 0, 1, 15962, 'Satyr\'s Rod'), +(1023034, 0, 1, 9833, 'Scaled Leather Leggings'), +(1023034, 0, 1, 9835, 'Scaled Leather Tunic'), +(1023034, 0, 1, 15225, 'Sequoia Hammer'), +(1023034, 0, 1, 14753, 'Slayer\'s Skullcap'), +(1023034, 0, 1, 14751, 'Slayer\'s Surcoat'), +(1023034, 0, 1, 14409, 'Stonecloth Cape'), +(1023034, 0, 1, 14199, 'Thistlefur Gloves'), +(1023034, 0, 1, 12039, 'Tundra Necklace'), +(1023034, 0, 1, 12009, 'Tundra Ring'), +(1023034, 0, 1, 14209, 'Vital Sash'), +(1023034, 0, 1, 15541, 'Wicked Chain Legguards'), +-- 31-35 +(1023135, 0, 1, 3185, 'Acrobatic Staff'), +(1023135, 0, 1, 9857, 'Archer\'s Bracers'), +(1023135, 0, 1, 9860, 'Archer\'s Cloak'), +(1023135, 0, 1, 11996, 'Basalt Ring'), +(1023135, 0, 1, 9853, 'Conjurer\'s Cinch'), +(1023135, 0, 1, 15140, 'Cutthroat\'s Mantle'), +(1023135, 0, 1, 15130, 'Cutthroat\'s Vest'), +(1023135, 0, 1, 9826, 'Durable Robe'), +(1023135, 0, 1, 15935, 'Durable Rod'), +(1023135, 0, 1, 9819, 'Durable Tunic'), +(1023135, 0, 1, 7357, 'Elder\'s Hat'), +(1023135, 0, 1, 7368, 'Elder\'s Pants'), +(1023135, 0, 1, 14761, 'Enduring Belt'), +(1023135, 0, 1, 14759, 'Enduring Bracers'), +(1023135, 0, 1, 14219, 'Geomancer\'s Cloak'), +(1023135, 0, 1, 15148, 'Ghostwalker Belt'), +(1023135, 0, 1, 15352, 'Headhunter\'s Buckler'), +(1023135, 0, 1, 15355, 'Headhunter\'s Mitts'), +(1023135, 0, 1, 15350, 'Headhunter\'s Slippers'), +(1023135, 0, 1, 2080, 'Hillborne Axe'), +(1023135, 0, 1, 7414, 'Infiltrator Pants'), +(1023135, 0, 1, 6409, 'Insignia Belt'), +(1023135, 0, 1, 4055, 'Insignia Boots'), +(1023135, 0, 1, 6408, 'Insignia Gloves'), +(1023135, 0, 1, 7460, 'Knight\'s Cloak'), +(1023135, 0, 1, 4717, 'Mail Combat Belt'), +(1023135, 0, 1, 4075, 'Mail Combat Gauntlets'), +(1023135, 0, 1, 6406, 'Nightsky Boots'), +(1023135, 0, 1, 4040, 'Nightsky Gloves'), +(1023135, 0, 1, 15339, 'Pathfinder Hat'), +(1023135, 0, 1, 7417, 'Phalanx Boots'), +(1023135, 0, 1, 7423, 'Phalanx Leggings'), +(1023135, 0, 1, 7331, 'Phalanx Shield'), +(1023135, 0, 1, 15560, 'Pillager\'s Gloves'), +(1023135, 0, 1, 9865, 'Renegade Bracers'), +(1023135, 0, 1, 11970, 'Spinel Ring'), +(1023135, 0, 1, 14414, 'Stonecloth Belt'), +(1023135, 0, 1, 14416, 'Stonecloth Bindings'), +(1023135, 0, 1, 15553, 'Thick Scale Shoulder Pads'), +(1023135, 0, 1, 14201, 'Thistlefur Mantle'), +(1023135, 0, 1, 14214, 'Vital Boots'), +(1023135, 0, 1, 14211, 'Vital Handwraps'), +(1023135, 0, 1, 3037, 'Whipwood Recurve Bow'), +(1023135, 0, 1, 15536, 'Wicked Chain Chestpiece'), +(1023135, 0, 1, 15540, 'Wicked Chain Helmet'), +(1023135, 0, 1, 15543, 'Wicked Chain Shield'), +-- 32-36 +(1023236, 0, 1, 9855, 'Archer\'s Belt'), +(1023236, 0, 1, 9861, 'Archer\'s Gloves'), +(1023236, 0, 1, 11985, 'Cerulean Ring'), +(1023236, 0, 1, 9846, 'Conjurer\'s Bracers'), +(1023236, 0, 1, 9845, 'Conjurer\'s Shoes'), +(1023236, 0, 1, 14584, 'Dokebi Hat'), +(1023236, 0, 1, 7609, 'Elder\'s Amber Stave'), +(1023236, 0, 1, 7353, 'Elder\'s Padded Armor'), +(1023236, 0, 1, 7369, 'Elder\'s Robe'), +(1023236, 0, 1, 14764, 'Enduring Gauntlets'), +(1023236, 0, 1, 14221, 'Geomancer\'s Bracers'), +(1023236, 0, 1, 15142, 'Ghostwalker Boots'), +(1023236, 0, 1, 12029, 'Greenstone Talisman'), +(1023236, 0, 1, 14590, 'Hawkeye\'s Bracers'), +(1023236, 0, 1, 14593, 'Hawkeye\'s Cloak'), +(1023236, 0, 1, 15357, 'Headhunter\'s Spaulders'), +(1023236, 0, 1, 15358, 'Headhunter\'s Woolies'), +(1023236, 0, 1, 7407, 'Infiltrator Armor'), +(1023236, 0, 1, 4066, 'Insignia Buckler'), +(1023236, 0, 1, 4052, 'Insignia Cap'), +(1023236, 0, 1, 4054, 'Insignia Leggings'), +(1023236, 0, 1, 4721, 'Insignia Mantle'), +(1023236, 0, 1, 15286, 'Long Redwood Bow'), +(1023236, 0, 1, 4076, 'Mail Combat Boots'), +(1023236, 0, 1, 4077, 'Mail Combat Headguard'), +(1023236, 0, 1, 6404, 'Mail Combat Spaulders'), +(1023236, 0, 1, 15571, 'Marauder\'s Belt'), +(1023236, 0, 1, 15566, 'Marauder\'s Bracers'), +(1023236, 0, 1, 4039, 'Nightsky Cowl'), +(1023236, 0, 1, 4718, 'Nightsky Mantle'), +(1023236, 0, 1, 7418, 'Phalanx Breastplate'), +(1023236, 0, 1, 9869, 'Renegade Belt'), +(1023236, 0, 1, 9868, 'Renegade Gauntlets'), +(1023236, 0, 1, 5213, 'Scorching Wand'), +(1023236, 0, 1, 15579, 'Sparkleshell Cloak'), +(1023236, 0, 1, 14408, 'Stonecloth Boots'), +(1023236, 0, 1, 14411, 'Stonecloth Gloves'), +(1023236, 0, 1, 3197, 'Stonecutter Claymore'), +(1023236, 0, 1, 15550, 'Thick Scale Crown'), +(1023236, 0, 1, 15551, 'Thick Scale Legguards'), +(1023236, 0, 1, 14200, 'Thistlefur Cap'), +(1023236, 0, 1, 14203, 'Thistlefur Pants'), +(1023236, 0, 1, 7436, 'Twilight Cape'), +(1023236, 0, 1, 14212, 'Vital Shoulders'), +-- 33-37 +(1023337, 0, 1, 9856, 'Archer\'s Boots'), +(1023337, 0, 1, 9858, 'Archer\'s Buckler'), +(1023337, 0, 1, 9859, 'Archer\'s Cap'), +(1023337, 0, 1, 1990, 'Ballast Maul'), +(1023337, 0, 1, 4726, 'Chief Brigadier Cloak'), +(1023337, 0, 1, 4065, 'Combat Shield'), +(1023337, 0, 1, 9848, 'Conjurer\'s Gloves'), +(1023337, 0, 1, 9849, 'Conjurer\'s Hood'), +(1023337, 0, 1, 9850, 'Conjurer\'s Mantle'), +(1023337, 0, 1, 15243, 'Deadly Kris'), +(1023337, 0, 1, 14229, 'Embersilk Cloak'), +(1023337, 0, 1, 14217, 'Geomancer\'s Cord'), +(1023337, 0, 1, 15145, 'Ghostwalker Buckler'), +(1023337, 0, 1, 15149, 'Ghostwalker Gloves'), +(1023337, 0, 1, 15151, 'Ghostwalker Legguards'), +(1023337, 0, 1, 15150, 'Ghostwalker Pads'), +(1023337, 0, 1, 14588, 'Hawkeye\'s Cord'), +(1023337, 0, 1, 15356, 'Headhunter\'s Armor'), +(1023337, 0, 1, 4057, 'Insignia Chestguard'), +(1023337, 0, 1, 7461, 'Knight\'s Bracers'), +(1023337, 0, 1, 4074, 'Mail Combat Armor'), +(1023337, 0, 1, 6402, 'Mail Combat Leggings'), +(1023337, 0, 1, 15570, 'Marauder\'s Gauntlets'), +(1023337, 0, 1, 15213, 'Mercenary Blade'), +(1023337, 0, 1, 5009, 'Mindbender Loop'), +(1023337, 0, 1, 6405, 'Nightsky Trousers'), +(1023337, 0, 1, 15561, 'Pillager\'s Leggings'), +(1023337, 0, 1, 15562, 'Pillager\'s Pauldrons'), +(1023337, 0, 1, 9864, 'Renegade Boots'), +(1023337, 0, 1, 9870, 'Renegade Circlet'), +(1023337, 0, 1, 7447, 'Sentinel Bracers'), +(1023337, 0, 1, 7446, 'Sentinel Cloak'), +(1023337, 0, 1, 7448, 'Sentinel Girdle'), +(1023337, 0, 1, 15575, 'Sparkleshell Belt'), +(1023337, 0, 1, 15577, 'Sparkleshell Bracers'), +(1023337, 0, 1, 14412, 'Stonecloth Epaulets'), +(1023337, 0, 1, 12020, 'Thallium Choker'), +(1023337, 0, 1, 15546, 'Thick Scale Breastplate'), +(1023337, 0, 1, 15552, 'Thick Scale Shield'), +(1023337, 0, 1, 15976, 'Thistlefur Branch'), +(1023337, 0, 1, 14202, 'Thistlefur Jerkin'), +(1023337, 0, 1, 14204, 'Thistlefur Robe'), +(1023337, 0, 1, 15364, 'Trickster\'s Cloak'), +(1023337, 0, 1, 7438, 'Twilight Belt'), +(1023337, 0, 1, 7437, 'Twilight Cuffs'), +(1023337, 0, 1, 14208, 'Vital Headband'), +(1023337, 0, 1, 14207, 'Vital Leggings'), +-- 34-38 +(1023438, 0, 1, 11971, 'Amethyst Band'), +(1023438, 0, 1, 9863, 'Archer\'s Shoulderpads'), +(1023438, 0, 1, 9862, 'Archer\'s Trousers'), +(1023438, 0, 1, 6417, 'Aurora Cloak'), +(1023438, 0, 1, 6418, 'Aurora Sash'), +(1023438, 0, 1, 6413, 'Chief Brigadier Bracers'), +(1023438, 0, 1, 9851, 'Conjurer\'s Breeches'), +(1023438, 0, 1, 15134, 'Cutthroat\'s Hat'), +(1023438, 0, 1, 14226, 'Embersilk Bracelets'), +(1023438, 0, 1, 14235, 'Embersilk Cord'), +(1023438, 0, 1, 14762, 'Enduring Boots'), +(1023438, 0, 1, 14766, 'Enduring Breeches'), +(1023438, 0, 1, 8188, 'Explosive Shotgun'), +(1023438, 0, 1, 12010, 'Fen Ring'), +(1023438, 0, 1, 14218, 'Geomancer\'s Boots'), +(1023438, 0, 1, 14222, 'Geomancer\'s Gloves'), +(1023438, 0, 1, 15144, 'Ghostwalker Rags'), +(1023438, 0, 1, 15226, 'Giant Club'), +(1023438, 0, 1, 863, 'Gloom Reaper'), +(1023438, 0, 1, 4059, 'Glyphed Bracers'), +(1023438, 0, 1, 4732, 'Glyphed Cloak'), +(1023438, 0, 1, 14607, 'Hawkeye\'s Buckler'), +(1023438, 0, 1, 14594, 'Hawkeye\'s Gloves'), +(1023438, 0, 1, 14589, 'Hawkeye\'s Shoes'), +(1023438, 0, 1, 7458, 'Knight\'s Boots'), +(1023438, 0, 1, 7457, 'Knight\'s Gauntlets'), +(1023438, 0, 1, 7462, 'Knight\'s Girdle'), +(1023438, 0, 1, 7111, 'Nightsky Armor'), +(1023438, 0, 1, 15929, 'Nightsky Orb'), +(1023438, 0, 1, 4038, 'Nightsky Robe'), +(1023438, 0, 1, 15153, 'Nocturnal Cloak'), +(1023438, 0, 1, 15557, 'Pillager\'s Chestguard'), +(1023438, 0, 1, 15558, 'Pillager\'s Crown'), +(1023438, 0, 1, 15563, 'Pillager\'s Shield'), +(1023438, 0, 1, 9871, 'Renegade Leggings'), +(1023438, 0, 1, 9872, 'Renegade Pauldrons'), +(1023438, 0, 1, 9873, 'Renegade Shield'), +(1023438, 0, 1, 7444, 'Sentinel Boots'), +(1023438, 0, 1, 7443, 'Sentinel Gloves'), +(1023438, 0, 1, 15590, 'Steadfast Bracelets'), +(1023438, 0, 1, 15594, 'Steadfast Cloak'), +(1023438, 0, 1, 14415, 'Stonecloth Britches'), +(1023438, 0, 1, 15361, 'Trickster\'s Sash'), +(1023438, 0, 1, 7434, 'Twilight Boots'), +(1023438, 0, 1, 7433, 'Twilight Gloves'), +(1023438, 0, 1, 15977, 'Vital Orb'), +(1023438, 0, 1, 14213, 'Vital Raiment'), +(1023438, 0, 1, 14215, 'Vital Tunic'), +-- 35-39 +(1023539, 0, 1, 9854, 'Archer\'s Jerkin'), +(1023539, 0, 1, 6416, 'Aurora Boots'), +(1023539, 0, 1, 4043, 'Aurora Bracers'), +(1023539, 0, 1, 1988, 'Chief Brigadier Gauntlets'), +(1023539, 0, 1, 4727, 'Chief Brigadier Girdle'), +(1023539, 0, 1, 9852, 'Conjurer\'s Robe'), +(1023539, 0, 1, 15918, 'Conjurer\'s Sphere'), +(1023539, 0, 1, 9844, 'Conjurer\'s Vest'), +(1023539, 0, 1, 14236, 'Embersilk Boots'), +(1023539, 0, 1, 14231, 'Embersilk Mitts'), +(1023539, 0, 1, 14765, 'Enduring Circlet'), +(1023539, 0, 1, 14767, 'Enduring Pauldrons'), +(1023539, 0, 1, 12040, 'Forest Pendant'), +(1023539, 0, 1, 14223, 'Geomancer\'s Spaulders'), +(1023539, 0, 1, 6421, 'Glyphed Belt'), +(1023539, 0, 1, 6419, 'Glyphed Mitts'), +(1023539, 0, 1, 11997, 'Greenstone Circle'), +(1023539, 0, 1, 14595, 'Hawkeye\'s Breeches'), +(1023539, 0, 1, 14596, 'Hawkeye\'s Epaulets'), +(1023539, 0, 1, 15353, 'Headhunter\'s Headdress'), +(1023539, 0, 1, 9890, 'Huntsman\'s Cape'), +(1023539, 0, 1, 9898, 'Jazeraint Cloak'), +(1023539, 0, 1, 7456, 'Knight\'s Headguard'), +(1023539, 0, 1, 7459, 'Knight\'s Pauldrons'), +(1023539, 0, 1, 864, 'Knightly Longsword'), +(1023539, 0, 1, 15565, 'Marauder\'s Boots'), +(1023539, 0, 1, 15573, 'Marauder\'s Leggings'), +(1023539, 0, 1, 15154, 'Nocturnal Sash'), +(1023539, 0, 1, 9866, 'Renegade Chestguard'), +(1023539, 0, 1, 7463, 'Sentinel Buckler'), +(1023539, 0, 1, 7441, 'Sentinel Cap'), +(1023539, 0, 1, 7445, 'Sentinel Shoulders'), +(1023539, 0, 1, 14419, 'Silksand Bracers'), +(1023539, 0, 1, 14420, 'Silksand Cape'), +(1023539, 0, 1, 9877, 'Sorcerer Cloak'), +(1023539, 0, 1, 15581, 'Sparkleshell Gauntlets'), +(1023539, 0, 1, 15598, 'Steadfast Girdle'), +(1023539, 0, 1, 15260, 'Stone Hammer'), +(1023539, 0, 1, 14410, 'Stonecloth Circlet'), +(1023539, 0, 1, 1465, 'Tigerbane'), +(1023539, 0, 1, 15360, 'Trickster\'s Bindings'), +(1023539, 0, 1, 15365, 'Trickster\'s Handwraps'), +(1023539, 0, 1, 7432, 'Twilight Cowl'), +(1023539, 0, 1, 7435, 'Twilight Mantle'), +-- 36-40 +(1023640, 0, 1, 4041, 'Aurora Cowl'), +(1023640, 0, 1, 4042, 'Aurora Gloves'), +(1023640, 0, 1, 4729, 'Aurora Mantle'), +(1023640, 0, 1, 7492, 'Captain\'s Cloak'), +(1023640, 0, 1, 6412, 'Chief Brigadier Boots'), +(1023640, 0, 1, 4078, 'Chief Brigadier Coif'), +(1023640, 0, 1, 14239, 'Darkmist Cape'), +(1023640, 0, 1, 14232, 'Embersilk Mantle'), +(1023640, 0, 1, 14760, 'Enduring Breastplate'), +(1023640, 0, 1, 15990, 'Enduring Shield'), +(1023640, 0, 1, 14224, 'Geomancer\'s Trousers'), +(1023640, 0, 1, 15146, 'Ghostwalker Crown'), +(1023640, 0, 1, 6420, 'Glyphed Boots'), +(1023640, 0, 1, 4067, 'Glyphed Buckler'), +(1023640, 0, 1, 4731, 'Glyphed Epaulets'), +(1023640, 0, 1, 6422, 'Glyphed Helm'), +(1023640, 0, 1, 9886, 'Huntsman\'s Bands'), +(1023640, 0, 1, 9891, 'Huntsman\'s Belt'), +(1023640, 0, 1, 9896, 'Jazeraint Bracers'), +(1023640, 0, 1, 12030, 'Jet Chain'), +(1023640, 0, 1, 7454, 'Knight\'s Breastplate'), +(1023640, 0, 1, 7465, 'Knight\'s Crest'), +(1023640, 0, 1, 7455, 'Knight\'s Legguards'), +(1023640, 0, 1, 15572, 'Marauder\'s Circlet'), +(1023640, 0, 1, 1207, 'Murphstar'), +(1023640, 0, 1, 15155, 'Nocturnal Gloves'), +(1023640, 0, 1, 15160, 'Nocturnal Wristbands'), +(1023640, 0, 1, 14771, 'Ravager\'s Cloak'), +(1023640, 0, 1, 14773, 'Ravager\'s Cord'), +(1023640, 0, 1, 15233, 'Savage Axe'), +(1023640, 0, 1, 7440, 'Sentinel Trousers'), +(1023640, 0, 1, 14418, 'Silksand Boots'), +(1023640, 0, 1, 14426, 'Silksand Girdle'), +(1023640, 0, 1, 15322, 'Smoothbore Gun'), +(1023640, 0, 1, 9879, 'Sorcerer Bracelets'), +(1023640, 0, 1, 9875, 'Sorcerer Sash'), +(1023640, 0, 1, 15576, 'Sparkleshell Sabatons'), +(1023640, 0, 1, 15595, 'Steadfast Gloves'), +(1023640, 0, 1, 15963, 'Stonecloth Branch'), +(1023640, 0, 1, 14413, 'Stonecloth Robe'), +(1023640, 0, 1, 14407, 'Stonecloth Vest'), +(1023640, 0, 1, 11986, 'Thallium Hoop'), +(1023640, 0, 1, 15362, 'Trickster\'s Boots'), +(1023640, 0, 1, 15368, 'Trickster\'s Pauldrons'), +(1023640, 0, 1, 15367, 'Trickster\'s Protector'), +(1023640, 0, 1, 7431, 'Twilight Pants'), +(1023640, 0, 1, 14602, 'Warden\'s Cloak'), +-- 37-41 +(1023741, 0, 1, 4044, 'Aurora Pants'), +(1023741, 0, 1, 7493, 'Captain\'s Bracers'), +(1023741, 0, 1, 11972, 'Carnelian Loop'), +(1023741, 0, 1, 4079, 'Chief Brigadier Leggings'), +(1023741, 0, 1, 4725, 'Chief Brigadier Pauldrons'), +(1023741, 0, 1, 4068, 'Chief Brigadier Shield'), +(1023741, 0, 1, 14240, 'Darkmist Bands'), +(1023741, 0, 1, 14233, 'Embersilk Leggings'), +(1023741, 0, 1, 14220, 'Geomancer\'s Cap'), +(1023741, 0, 1, 4060, 'Glyphed Leggings'), +(1023741, 0, 1, 15234, 'Greater Scythe'), +(1023741, 0, 1, 14591, 'Hawkeye\'s Helm'), +(1023741, 0, 1, 14592, 'Hawkeye\'s Tunic'), +(1023741, 0, 1, 9885, 'Huntsman\'s Boots'), +(1023741, 0, 1, 9889, 'Huntsman\'s Cap'), +(1023741, 0, 1, 9892, 'Huntsman\'s Gloves'), +(1023741, 0, 1, 9901, 'Jazeraint Belt'), +(1023741, 0, 1, 9895, 'Jazeraint Boots'), +(1023741, 0, 1, 9900, 'Jazeraint Gauntlets'), +(1023741, 0, 1, 14251, 'Lunar Cloak'), +(1023741, 0, 1, 15569, 'Marauder\'s Crest'), +(1023741, 0, 1, 15574, 'Marauder\'s Shoulder Pads'), +(1023741, 0, 1, 15567, 'Marauder\'s Tunic'), +(1023741, 0, 1, 15214, 'Nobles Brand'), +(1023741, 0, 1, 15158, 'Nocturnal Shoulder Pads'), +(1023741, 0, 1, 7483, 'Ranger Cloak'), +(1023741, 0, 1, 14770, 'Ravager\'s Armguards'), +(1023741, 0, 1, 14772, 'Ravager\'s Handwraps'), +(1023741, 0, 1, 7474, 'Regal Cloak'), +(1023741, 0, 1, 7476, 'Regal Sash'), +(1023741, 0, 1, 7439, 'Sentinel Breastplate'), +(1023741, 0, 1, 15261, 'Sequoia Branch'), +(1023741, 0, 1, 14422, 'Silksand Gloves'), +(1023741, 0, 1, 14423, 'Silksand Shoulder Pads'), +(1023741, 0, 1, 9880, 'Sorcerer Gloves'), +(1023741, 0, 1, 9876, 'Sorcerer Slippers'), +(1023741, 0, 1, 15580, 'Sparkleshell Headwrap'), +(1023741, 0, 1, 15582, 'Sparkleshell Legguards'), +(1023741, 0, 1, 15366, 'Trickster\'s Leggings'), +(1023741, 0, 1, 7429, 'Twilight Armor'), +(1023741, 0, 1, 7556, 'Twilight Orb'), +(1023741, 0, 1, 7430, 'Twilight Robe'), +(1023741, 0, 1, 14598, 'Warden\'s Waistband'), +(1023741, 0, 1, 14600, 'Warden\'s Wristbands'), +(1023741, 0, 1, 5011, 'Welken Ring'), +(1023741, 0, 1, 8158, 'Jouster\'s Gauntlets'), +(1023741, 0, 1, 8159, 'Jouster\'s Girdle'), +(1023741, 0, 1, 8160, 'Jouster\'s Greaves'), +(1023741, 0, 1, 8161, 'Jouster\'s Visor'), +(1023741, 0, 1, 8156, 'Jouster\'s Wristguards'), +(1023741, 0, 1, 14903, 'Saltstone Armsplints'), +(1023741, 0, 1, 14897, 'Saltstone Gauntlets'), +(1023741, 0, 1, 14898, 'Saltstone Girdle'), +(1023741, 0, 1, 14900, 'Saltstone Legplates'), +(1023741, 0, 1, 14896, 'Saltstone Sabatons'), +-- 38-42 +(1023842, 0, 1, 15606, 'Ancient Belt'), +(1023842, 0, 1, 15603, 'Ancient Cloak'), +(1023842, 0, 1, 7112, 'Aurora Armor'), +(1023842, 0, 1, 6415, 'Aurora Robe'), +(1023842, 0, 1, 7610, 'Aurora Sphere'), +(1023842, 0, 1, 9929, 'Brigade Cloak'), +(1023842, 0, 1, 7489, 'Captain\'s Gauntlets'), +(1023842, 0, 1, 7494, 'Captain\'s Waistguard'), +(1023842, 0, 1, 6411, 'Chief Brigadier Armor'), +(1023842, 0, 1, 14238, 'Darkmist Boots'), +(1023842, 0, 1, 14245, 'Darkmist Girdle'), +(1023842, 0, 1, 14241, 'Darkmist Handguards'), +(1023842, 0, 1, 5215, 'Ember Wand'), +(1023842, 0, 1, 14228, 'Embersilk Coronet'), +(1023842, 0, 1, 1625, 'Exquisite Flamberge'), +(1023842, 0, 1, 12011, 'Forest Hoop'), +(1023842, 0, 1, 14216, 'Geomancer\'s Jerkin'), +(1023842, 0, 1, 15978, 'Geomancer\'s Rod'), +(1023842, 0, 1, 14225, 'Geomancer\'s Wraps'), +(1023842, 0, 1, 4058, 'Glyphed Breastplate'), +(1023842, 0, 1, 9894, 'Huntsman\'s Shoulders'), +(1023842, 0, 1, 6432, 'Imperial Cloak'), +(1023842, 0, 1, 12022, 'Iridium Chain'), +(1023842, 0, 1, 9902, 'Jazeraint Helm'), +(1023842, 0, 1, 9904, 'Jazeraint Pauldrons'), +(1023842, 0, 1, 4070, 'Jouster\'s Crest'), +(1023842, 0, 1, 14248, 'Lunar Bindings'), +(1023842, 0, 1, 4735, 'Mistscape Cloak'), +(1023842, 0, 1, 15157, 'Nocturnal Leggings'), +(1023842, 0, 1, 15152, 'Nocturnal Shoes'), +(1023842, 0, 1, 7485, 'Ranger Cord'), +(1023842, 0, 1, 7480, 'Ranger Gloves'), +(1023842, 0, 1, 7484, 'Ranger Wristguards'), +(1023842, 0, 1, 7472, 'Regal Boots'), +(1023842, 0, 1, 7475, 'Regal Cuffs'), +(1023842, 0, 1, 14902, 'Saltstone Shield'), +(1023842, 0, 1, 9878, 'Sorcerer Hat'), +(1023842, 0, 1, 9881, 'Sorcerer Mantle'), +(1023842, 0, 1, 15578, 'Sparkleshell Breastplate'), +(1023842, 0, 1, 15584, 'Sparkleshell Shield'), +(1023842, 0, 1, 15583, 'Sparkleshell Shoulder Pads'), +(1023842, 0, 1, 15596, 'Steadfast Legplates'), +(1023842, 0, 1, 15589, 'Steadfast Stompers'), +(1023842, 0, 1, 15359, 'Trickster\'s Vest'), +(1023842, 0, 1, 4087, 'Trueshot Bow'), +(1023842, 0, 1, 14606, 'Warden\'s Gloves'), +(1023842, 0, 1, 14603, 'Warden\'s Mantle'), +(1023842, 0, 1, 15371, 'Wolf Rider\'s Cloak'), +(1023842, 0, 1, 9289, 'Field Plate Boots'), +(1023842, 0, 1, 9287, 'Field Plate Gauntlets'), +(1023842, 0, 1, 9288, 'Field Plate Girdle'), +(1023842, 0, 1, 9285, 'Field Plate Vambraces'), +(1023842, 0, 1, 8162, 'Jouster\'s Legplates'), +(1023842, 0, 1, 8163, 'Jouster\'s Pauldrons'), +(1023842, 0, 1, 14899, 'Saltstone Helm'), +(1023842, 0, 1, 14901, 'Saltstone Shoulder Pads'), +(1023842, 0, 1, 14895, 'Saltstone Surcoat'), +(1023842, 0, 1, 14827, 'Symbolic Belt'), +(1023842, 0, 1, 14826, 'Symbolic Gauntlets'), +(1023842, 0, 1, 14832, 'Symbolic Vambraces'), +-- 39-43 +(1023943, 0, 1, 14255, 'Lunar Belt'), +(1023943, 0, 1, 15605, 'Ancient Gauntlets'), +(1023943, 0, 1, 15600, 'Ancient Vambraces'), +(1023943, 0, 1, 6424, 'Blackforge Cape'), +(1023943, 0, 1, 15613, 'Bonelink Belt'), +(1023943, 0, 1, 9927, 'Brigade Bracers'), +(1023943, 0, 1, 7490, 'Captain\'s Boots'), +(1023943, 0, 1, 7488, 'Captain\'s Circlet'), +(1023943, 0, 1, 14234, 'Embersilk Robes'), +(1023943, 0, 1, 15979, 'Embersilk Stave'), +(1023943, 0, 1, 14230, 'Embersilk Tunic'), +(1023943, 0, 1, 9893, 'Huntsman\'s Leggings'), +(1023943, 0, 1, 4738, 'Imperial Leather Belt'), +(1023943, 0, 1, 4061, 'Imperial Leather Bracers'), +(1023943, 0, 1, 15165, 'Imposing Cape'), +(1023943, 0, 1, 9897, 'Jazeraint Chestguard'), +(1023943, 0, 1, 9903, 'Jazeraint Leggings'), +(1023943, 0, 1, 9899, 'Jazeraint Shield'), +(1023943, 0, 1, 11998, 'Jet Loop'), +(1023943, 0, 1, 14250, 'Lunar Slippers'), +(1023943, 0, 1, 12042, 'Marsh Chain'), +(1023943, 0, 1, 4045, 'Mistscape Bracers'), +(1023943, 0, 1, 4736, 'Mistscape Sash'), +(1023943, 0, 1, 866, 'Monk\'s Staff'), +(1023943, 0, 1, 1640, 'Monstrous War Axe'), +(1023943, 0, 1, 15159, 'Nocturnal Tunic'), +(1023943, 0, 1, 7481, 'Ranger Boots'), +(1023943, 0, 1, 7479, 'Ranger Helm'), +(1023943, 0, 1, 7482, 'Ranger Shoulders'), +(1023943, 0, 1, 14769, 'Ravager\'s Sandals'), +(1023943, 0, 1, 15244, 'Razor Blade'), +(1023943, 0, 1, 7471, 'Regal Gloves'), +(1023943, 0, 1, 7473, 'Regal Mantle'), +(1023943, 0, 1, 7470, 'Regal Wizard Hat'), +(1023943, 0, 1, 14421, 'Silksand Circlet'), +(1023943, 0, 1, 14424, 'Silksand Legwraps'), +(1023943, 0, 1, 9883, 'Sorcerer Pants'), +(1023943, 0, 1, 15593, 'Steadfast Coronet'), +(1023943, 0, 1, 15597, 'Steadfast Shoulders'), +(1023943, 0, 1, 15363, 'Trickster\'s Headdress'), +(1023943, 0, 1, 14599, 'Warden\'s Footpads'), +(1023943, 0, 1, 14430, 'Windchaser Cloak'), +(1023943, 0, 1, 15369, 'Wolf Rider\'s Belt'), +(1023943, 0, 1, 15377, 'Wolf Rider\'s Wristbands'), +(1023943, 0, 1, 9973, 'Embossed Plate Boots'), +(1023943, 0, 1, 9972, 'Embossed Plate Bracers'), +(1023943, 0, 1, 9968, 'Embossed Plate Girdle'), +(1023943, 0, 1, 9290, 'Field Plate Helmet'), +(1023943, 0, 1, 9292, 'Field Plate Pauldrons'), +(1023943, 0, 1, 8157, 'Jouster\'s Chestplate'), +(1023943, 0, 1, 14828, 'Symbolic Greaves'), +(1023943, 0, 1, 14829, 'Symbolic Legplates'), +(1023943, 0, 1, 14830, 'Symbolic Pauldrons'), +(1023943, 0, 1, 14941, 'Warbringer\'s Armsplints'), +(1023943, 0, 1, 14943, 'Warbringer\'s Belt'), +(1023943, 0, 1, 14942, 'Warbringer\'s Gauntlets'), +-- 40-44 +(1024044, 0, 1, 6426, 'Blackforge Bracers'), +(1024044, 0, 1, 14261, 'Bloodwoven Cloak'), +(1024044, 0, 1, 15610, 'Bonelink Bracers'), +(1024044, 0, 1, 15611, 'Bonelink Cape'), +(1024044, 0, 1, 9926, 'Brigade Boots'), +(1024044, 0, 1, 9930, 'Brigade Gauntlets'), +(1024044, 0, 1, 9931, 'Brigade Girdle'), +(1024044, 0, 1, 7487, 'Captain\'s Leggings'), +(1024044, 0, 1, 7491, 'Captain\'s Shoulderguards'), +(1024044, 0, 1, 14243, 'Darkmist Mantle'), +(1024044, 0, 1, 14242, 'Darkmist Pants'), +(1024044, 0, 1, 8196, 'Ebon Scimitar'), +(1024044, 0, 1, 7496, 'Field Plate Shield'), +(1024044, 0, 1, 8194, 'Goblin Nutcracker'), +(1024044, 0, 1, 15251, 'Headstriker Sword'), +(1024044, 0, 1, 11973, 'Hematite Link'), +(1024044, 0, 1, 9887, 'Huntsman\'s Armor'), +(1024044, 0, 1, 6431, 'Imperial Leather Boots'), +(1024044, 0, 1, 4063, 'Imperial Leather Gloves'), +(1024044, 0, 1, 6433, 'Imperial Leather Helm'), +(1024044, 0, 1, 15161, 'Imposing Belt'), +(1024044, 0, 1, 15163, 'Imposing Bracers'), +(1024044, 0, 1, 11987, 'Iridium Circle'), +(1024044, 0, 1, 14253, 'Lunar Handwraps'), +(1024044, 0, 1, 4047, 'Mistscape Boots'), +(1024044, 0, 1, 6428, 'Mistscape Gloves'), +(1024044, 0, 1, 4734, 'Mistscape Mantle'), +(1024044, 0, 1, 15156, 'Nocturnal Cap'), +(1024044, 0, 1, 7478, 'Ranger Leggings'), +(1024044, 0, 1, 14774, 'Ravager\'s Crown'), +(1024044, 0, 1, 14776, 'Ravager\'s Mantle'), +(1024044, 0, 1, 14775, 'Ravager\'s Woolies'), +(1024044, 0, 1, 9909, 'Royal Bands'), +(1024044, 0, 1, 9908, 'Royal Cape'), +(1024044, 0, 1, 9874, 'Sorcerer Drape'), +(1024044, 0, 1, 9884, 'Sorcerer Robe'), +(1024044, 0, 1, 9882, 'Sorcerer Sphere'), +(1024044, 0, 1, 15591, 'Steadfast Breastplate'), +(1024044, 0, 1, 15592, 'Steadfast Buckler'), +(1024044, 0, 1, 14825, 'Symbolic Crest'), +(1024044, 0, 1, 9919, 'Tracker\'s Cloak'), +(1024044, 0, 1, 14605, 'Warden\'s Woolies'), +(1024044, 0, 1, 14435, 'Windchaser Cinch'), +(1024044, 0, 1, 14429, 'Windchaser Cuffs'), +(1024044, 0, 1, 15372, 'Wolf Rider\'s Gloves'), +(1024044, 0, 1, 15375, 'Wolf Rider\'s Shoulder Pads'), +(1024044, 0, 1, 8137, 'Chromite Bracers'), +(1024044, 0, 1, 8140, 'Chromite Girdle'), +(1024044, 0, 1, 9967, 'Embossed Plate Gauntlets'), +(1024044, 0, 1, 9969, 'Embossed Plate Helmet'), +(1024044, 0, 1, 9971, 'Embossed Plate Pauldrons'), +(1024044, 0, 1, 9291, 'Field Plate Leggings'), +(1024044, 0, 1, 14821, 'Symbolic Breastplate'), +(1024044, 0, 1, 14831, 'Symbolic Crown'), +(1024044, 0, 1, 14834, 'Tyrant\'s Armguards'), +(1024044, 0, 1, 14838, 'Tyrant\'s Belt'), +(1024044, 0, 1, 14940, 'Warbringer\'s Sabatons '), +(1024044, 0, 1, 14946, 'Warbringer\'s Spaulders'), +-- 41-45 +(1024145, 0, 1, 15599, 'Ancient Greaves'), +(1024145, 0, 1, 15607, 'Ancient Legguards'), +(1024145, 0, 1, 15608, 'Ancient Pauldrons'), +(1024145, 0, 1, 4083, 'Blackforge Gauntlets'), +(1024145, 0, 1, 6425, 'Blackforge Girdle'), +(1024145, 0, 1, 14260, 'Bloodwoven Bracers'), +(1024145, 0, 1, 15612, 'Bonelink Gauntlets'), +(1024145, 0, 1, 9932, 'Brigade Circlet'), +(1024145, 0, 1, 9934, 'Brigade Pauldrons'), +(1024145, 0, 1, 7533, 'Cabalist Cloak'), +(1024145, 0, 1, 7486, 'Captain\'s Breastplate'), +(1024145, 0, 1, 7495, 'Captain\'s Buckler'), +(1024145, 0, 1, 7544, 'Champion\'s Cape'), +(1024145, 0, 1, 14246, 'Darkmist Wizard Hat'), +(1024145, 0, 1, 7552, 'Falcon\'s Hook'), +(1024145, 0, 1, 7524, 'Gossamer Cape'), +(1024145, 0, 1, 4737, 'Imperial Leather Spaulders'), +(1024145, 0, 1, 15169, 'Imposing Shoulders'), +(1024145, 0, 1, 14781, 'Khan\'s Cloak'), +(1024145, 0, 1, 12031, 'Lodestone Necklace'), +(1024145, 0, 1, 14247, 'Lunar Mantle'), +(1024145, 0, 1, 6429, 'Mistscape Wizard Hat'), +(1024145, 0, 1, 14768, 'Ravager\'s Armor'), +(1024145, 0, 1, 14777, 'Ravager\'s Shield'), +(1024145, 0, 1, 7469, 'Regal Leggings'), +(1024145, 0, 1, 9907, 'Royal Boots'), +(1024145, 0, 1, 9910, 'Royal Gloves'), +(1024145, 0, 1, 9906, 'Royal Sash'), +(1024145, 0, 1, 3187, 'Sacrificial Kris'), +(1024145, 0, 1, 14656, 'Scorpashi Cape'), +(1024145, 0, 1, 14654, 'Scorpashi Wristbands'), +(1024145, 0, 1, 15964, 'Silksand Star'), +(1024145, 0, 1, 14417, 'Silksand Tunic'), +(1024145, 0, 1, 14425, 'Silksand Wraps'), +(1024145, 0, 1, 3430, 'Sniper Rifle'), +(1024145, 0, 1, 1613, 'Spiritchaser Staff'), +(1024145, 0, 1, 9916, 'Tracker\'s Belt'), +(1024145, 0, 1, 9917, 'Tracker\'s Boots'), +(1024145, 0, 1, 9920, 'Tracker\'s Gloves'), +(1024145, 0, 1, 9925, 'Tracker\'s Wristguards'), +(1024145, 0, 1, 14601, 'Warden\'s Wraps'), +(1024145, 0, 1, 14428, 'Windchaser Footpads'), +(1024145, 0, 1, 14431, 'Windchaser Handguards'), +(1024145, 0, 1, 15370, 'Wolf Rider\'s Boots'), +(1024145, 0, 1, 15374, 'Wolf Rider\'s Leggings'), +(1024145, 0, 1, 14910, 'Brutish Armguards'), +(1024145, 0, 1, 14906, 'Brutish Belt'), +(1024145, 0, 1, 8142, 'Chromite Barbute'), +(1024145, 0, 1, 8139, 'Chromite Gauntlets'), +(1024145, 0, 1, 8141, 'Chromite Greaves'), +(1024145, 0, 1, 9970, 'Embossed Plate Leggings'), +(1024145, 0, 1, 9286, 'Field Plate Armor'), +(1024145, 0, 1, 14841, 'Tyrant\'s Epaulets'), +(1024145, 0, 1, 14833, 'Tyrant\'s Gauntlets'), +(1024145, 0, 1, 14839, 'Tyrant\'s Greaves'), +-- 42-46 +(1024246, 0, 1, 15602, 'Ancient Crown'), +(1024246, 0, 1, 4080, 'Blackforge Cowl'), +(1024246, 0, 1, 6423, 'Blackforge Greaves'), +(1024246, 0, 1, 14956, 'Bloodforged Bindings'), +(1024246, 0, 1, 14258, 'Bloodwoven Cord'), +(1024246, 0, 1, 14262, 'Bloodwoven Mitts'), +(1024246, 0, 1, 15617, 'Bonelink Epaulets'), +(1024246, 0, 1, 15614, 'Bonelink Sabatons'), +(1024246, 0, 1, 9928, 'Brigade Breastplate'), +(1024246, 0, 1, 9918, 'Brigade Defender'), +(1024246, 0, 1, 9933, 'Brigade Leggings'), +(1024246, 0, 1, 14905, 'Brutish Gauntlets'), +(1024246, 0, 1, 14909, 'Brutish Shoulders'), +(1024246, 0, 1, 7534, 'Cabalist Bracers'), +(1024246, 0, 1, 7545, 'Champion\'s Bracers'), +(1024246, 0, 1, 8144, 'Chromite Pauldrons'), +(1024246, 0, 1, 15287, 'Crusader Bow'), +(1024246, 0, 1, 9966, 'Embossed Plate Armor'), +(1024246, 0, 1, 9935, 'Embossed Plate Shield'), +(1024246, 0, 1, 15215, 'Furious Falchion'), +(1024246, 0, 1, 14270, 'Gaea\'s Cloak'), +(1024246, 0, 1, 7522, 'Gossamer Boots'), +(1024246, 0, 1, 7525, 'Gossamer Bracers'), +(1024246, 0, 1, 10088, 'Gothic Plate Girdle'), +(1024246, 0, 1, 10094, 'Gothic Plate Vambraces'), +(1024246, 0, 1, 10089, 'Gothic Sabatons'), +(1024246, 0, 1, 15624, 'Gryphon Cloak'), +(1024246, 0, 1, 8120, 'Heraldic Cloak'), +(1024246, 0, 1, 4062, 'Imperial Leather Pants'), +(1024246, 0, 1, 15162, 'Imposing Boots'), +(1024246, 0, 1, 15166, 'Imposing Gloves'), +(1024246, 0, 1, 15168, 'Imposing Pants'), +(1024246, 0, 1, 14778, 'Khan\'s Bindings'), +(1024246, 0, 1, 14782, 'Khan\'s Gloves'), +(1024246, 0, 1, 14252, 'Lunar Coronet'), +(1024246, 0, 1, 14257, 'Lunar Leggings'), +(1024246, 0, 1, 12012, 'Marsh Ring'), +(1024246, 0, 1, 4046, 'Mistscape Pants'), +(1024246, 0, 1, 15382, 'Rageclaw Cloak'), +(1024246, 0, 1, 7477, 'Ranger Tunic'), +(1024246, 0, 1, 7332, 'Regal Armor'), +(1024246, 0, 1, 7468, 'Regal Robe'), +(1024246, 0, 1, 7555, 'Regal Star'), +(1024246, 0, 1, 9912, 'Royal Amice'), +(1024246, 0, 1, 9915, 'Royal Headband'), +(1024246, 0, 1, 14652, 'Scorpashi Sash'), +(1024246, 0, 1, 12023, 'Tellurium Necklace'), +(1024246, 0, 1, 9921, 'Tracker\'s Headband'), +(1024246, 0, 1, 9923, 'Tracker\'s Shoulderpads'), +(1024246, 0, 1, 5216, 'Umbral Wand'), +(1024246, 0, 1, 14944, 'Warbringer\'s Crown'), +(1024246, 0, 1, 14945, 'Warbringer\'s Legguards'), +(1024246, 0, 1, 14604, 'Warden\'s Wizard Hat'), +(1024246, 0, 1, 9959, 'Warmonger\'s Cloak'), +(1024246, 0, 1, 14432, 'Windchaser Amice'), +-- 43-47 +(1024347, 0, 1, 15601, 'Ancient Chestpiece'), +(1024347, 0, 1, 15604, 'Ancient Defender'), +(1024347, 0, 1, 11974, 'Aquamarine Ring'), +(1024347, 0, 1, 4084, 'Blackforge Leggings'), +(1024347, 0, 1, 4733, 'Blackforge Pauldrons'), +(1024347, 0, 1, 14950, 'Bloodforged Belt'), +(1024347, 0, 1, 14259, 'Bloodwoven Boots'), +(1024347, 0, 1, 15615, 'Bonelink Helmet'), +(1024347, 0, 1, 15616, 'Bonelink Legplates'), +(1024347, 0, 1, 14911, 'Brutish Boots'), +(1024347, 0, 1, 7535, 'Cabalist Belt'), +(1024347, 0, 1, 7531, 'Cabalist Boots'), +(1024347, 0, 1, 7530, 'Cabalist Gloves'), +(1024347, 0, 1, 7541, 'Champion\'s Gauntlets'), +(1024347, 0, 1, 7546, 'Champion\'s Girdle'), +(1024347, 0, 1, 7542, 'Champion\'s Greaves'), +(1024347, 0, 1, 8143, 'Chromite Legplates'), +(1024347, 0, 1, 8135, 'Chromite Shield'), +(1024347, 0, 1, 14237, 'Darkmist Armor'), +(1024347, 0, 1, 15980, 'Darkmist Orb'), +(1024347, 0, 1, 14244, 'Darkmist Wraps'), +(1024347, 0, 1, 1994, 'Ebonclaw Reaver'), +(1024347, 0, 1, 15632, 'Formidable Cape'), +(1024347, 0, 1, 14268, 'Gaea\'s Cuffs'), +(1024347, 0, 1, 15270, 'Gigantic War Axe'), +(1024347, 0, 1, 7526, 'Gossamer Belt'), +(1024347, 0, 1, 7521, 'Gossamer Gloves'), +(1024347, 0, 1, 7523, 'Gossamer Shoulderpads'), +(1024347, 0, 1, 10087, 'Gothic Plate Gauntlets'), +(1024347, 0, 1, 10090, 'Gothic Plate Helmet'), +(1024347, 0, 1, 15262, 'Greater Maul'), +(1024347, 0, 1, 8118, 'Heraldic Bracers'), +(1024347, 0, 1, 8109, 'Hibernal Cloak'), +(1024347, 0, 1, 6430, 'Imperial Leather Breastplate'), +(1024347, 0, 1, 14914, 'Jade Bracers'), +(1024347, 0, 1, 14783, 'Khan\'s Belt'), +(1024347, 0, 1, 14784, 'Khan\'s Greaves'), +(1024347, 0, 1, 11999, 'Lodestone Hoop'), +(1024347, 0, 1, 7113, 'Mistscape Armor'), +(1024347, 0, 1, 6427, 'Mistscape Robe'), +(1024347, 0, 1, 7611, 'Mistscape Stave'), +(1024347, 0, 1, 15173, 'Potent Cape'), +(1024347, 0, 1, 15378, 'Rageclaw Belt'), +(1024347, 0, 1, 15380, 'Rageclaw Bracers'), +(1024347, 0, 1, 9911, 'Royal Trousers'), +(1024347, 0, 1, 14657, 'Scorpashi Gloves'), +(1024347, 0, 1, 14653, 'Scorpashi Slippers'), +(1024347, 0, 1, 9922, 'Tracker\'s Leggings'), +(1024347, 0, 1, 14843, 'Tyrant\'s Helm'), +(1024347, 0, 1, 8277, 'Valorous Girdle'), +(1024347, 0, 1, 8273, 'Valorous Wristguards'), +(1024347, 0, 1, 14440, 'Venomshroud Cape'), +(1024347, 0, 1, 14939, 'Warbringer\'s Chestguard'), +(1024347, 0, 1, 14947, 'Warbringer\'s Shield'), +(1024347, 0, 1, 9956, 'Warmonger\'s Bracers'), +(1024347, 0, 1, 14436, 'Windchaser Coronet'), +(1024347, 0, 1, 14433, 'Windchaser Woolies'), +(1024347, 0, 1, 15376, 'Wolf Rider\'s Padded Armor'), +-- 44-48 +(1024448, 0, 1, 8199, 'Battlefield Destroyer'), +(1024448, 0, 1, 4082, 'Blackforge Breastplate'), +(1024448, 0, 1, 4069, 'Blackforge Buckler'), +(1024448, 0, 1, 14949, 'Bloodforged Gauntlets'), +(1024448, 0, 1, 14951, 'Bloodforged Sabatons'), +(1024448, 0, 1, 14955, 'Bloodforged Shoulder Pads'), +(1024448, 0, 1, 14266, 'Bloodwoven Pads'), +(1024448, 0, 1, 15609, 'Bonelink Armor'), +(1024448, 0, 1, 15618, 'Bonelink Wall Shield'), +(1024448, 0, 1, 7529, 'Cabalist Helm'), +(1024448, 0, 1, 7532, 'Cabalist Spaulders'), +(1024448, 0, 1, 7540, 'Champion\'s Helmet'), +(1024448, 0, 1, 7543, 'Champion\'s Pauldrons'), +(1024448, 0, 1, 9951, 'Chieftain\'s Cloak'), +(1024448, 0, 1, 8138, 'Chromite Chestplate'), +(1024448, 0, 1, 12043, 'Desert Choker'), +(1024448, 0, 1, 4088, 'Dreadblade'), +(1024448, 0, 1, 14276, 'Gaea\'s Belt'), +(1024448, 0, 1, 14272, 'Gaea\'s Handwraps'), +(1024448, 0, 1, 14269, 'Gaea\'s Slippers'), +(1024448, 0, 1, 7520, 'Gossamer Headpiece'), +(1024448, 0, 1, 7519, 'Gossamer Pants'), +(1024448, 0, 1, 10091, 'Gothic Plate Leggings'), +(1024448, 0, 1, 10092, 'Gothic Plate Spaulders'), +(1024448, 0, 1, 15620, 'Gryphon Mail Bracelets'), +(1024448, 0, 1, 15625, 'Gryphon Mail Gauntlets'), +(1024448, 0, 1, 15626, 'Gryphon Mail Greaves'), +(1024448, 0, 1, 8116, 'Heraldic Belt'), +(1024448, 0, 1, 8117, 'Heraldic Boots'), +(1024448, 0, 1, 8121, 'Heraldic Gloves'), +(1024448, 0, 1, 8107, 'Hibernal Boots'), +(1024448, 0, 1, 8108, 'Hibernal Bracers'), +(1024448, 0, 1, 8110, 'Hibernal Gloves'), +(1024448, 0, 1, 8114, 'Hibernal Sash'), +(1024448, 0, 1, 15164, 'Imposing Vest'), +(1024448, 0, 1, 14918, 'Jade Belt'), +(1024448, 0, 1, 14786, 'Khan\'s Legguards'), +(1024448, 0, 1, 14787, 'Khan\'s Mantle'), +(1024448, 0, 1, 14254, 'Lunar Raiment'), +(1024448, 0, 1, 15981, 'Lunar Sphere'), +(1024448, 0, 1, 14249, 'Lunar Vest'), +(1024448, 0, 1, 8127, 'Myrmidon\'s Cape'), +(1024448, 0, 1, 15172, 'Potent Bands'), +(1024448, 0, 1, 15178, 'Potent Belt'), +(1024448, 0, 1, 14659, 'Scorpashi Leggings'), +(1024448, 0, 1, 14660, 'Scorpashi Shoulder Pads'), +(1024448, 0, 1, 1608, 'Skullcrusher Mace'), +(1024448, 0, 1, 11988, 'Tellurium Band'), +(1024448, 0, 1, 14840, 'Tyrant\'s Legplates'), +(1024448, 0, 1, 8276, 'Valorous Gauntlets'), +(1024448, 0, 1, 8278, 'Valorous Greaves'), +(1024448, 0, 1, 14439, 'Venomshroud Armguards'), +(1024448, 0, 1, 9961, 'Warmonger\'s Belt'), +(1024448, 0, 1, 9960, 'Warmonger\'s Gauntlets'), +(1024448, 0, 1, 15373, 'Wolf Rider\'s Headgear'), +-- 45-49 +(1024549, 0, 1, 9937, 'Abjurer\'s Bands'), +(1024549, 0, 1, 9938, 'Abjurer\'s Cloak'), +(1024549, 0, 1, 9945, 'Abjurer\'s Sash'), +(1024549, 0, 1, 7553, 'Band of the Unicorn'), +(1024549, 0, 1, 14263, 'Bloodwoven Mask'), +(1024549, 0, 1, 14264, 'Bloodwoven Pants'), +(1024549, 0, 1, 14907, 'Brutish Helmet'), +(1024549, 0, 1, 14908, 'Brutish Legguards'), +(1024549, 0, 1, 7528, 'Cabalist Leggings'), +(1024549, 0, 1, 7538, 'Champion\'s Armor'), +(1024549, 0, 1, 7539, 'Champion\'s Leggings'), +(1024549, 0, 1, 7536, 'Champion\'s Wall Shield'), +(1024549, 0, 1, 9947, 'Chieftain\'s Belt'), +(1024549, 0, 1, 9949, 'Chieftain\'s Bracers'), +(1024549, 0, 1, 3208, 'Conk Hammer'), +(1024549, 0, 1, 15235, 'Crescent Edge'), +(1024549, 0, 1, 15629, 'Formidable Bracers'), +(1024549, 0, 1, 15635, 'Formidable Gauntlets'), +(1024549, 0, 1, 14273, 'Gaea\'s Amice'), +(1024549, 0, 1, 15619, 'Gryphon Mail Belt'), +(1024549, 0, 1, 15628, 'Gryphon Mail Pauldrons'), +(1024549, 0, 1, 8122, 'Heraldic Headpiece'), +(1024549, 0, 1, 8124, 'Heraldic Spaulders'), +(1024549, 0, 1, 8115, 'Hibernal Cowl'), +(1024549, 0, 1, 8111, 'Hibernal Mantle'), +(1024549, 0, 1, 15167, 'Imposing Bandana'), +(1024549, 0, 1, 14917, 'Jade Gauntlets'), +(1024549, 0, 1, 14663, 'Keeper\'s Bindings'), +(1024549, 0, 1, 14665, 'Keeper\'s Cloak'), +(1024549, 0, 1, 14785, 'Khan\'s Helmet'), +(1024549, 0, 1, 10079, 'Lord\'s Cape'), +(1024549, 0, 1, 8125, 'Myrmidon\'s Bracers'), +(1024549, 0, 1, 12032, 'Onyx Choker'), +(1024549, 0, 1, 14280, 'Opulent Cape'), +(1024549, 0, 1, 10206, 'Overlord\'s Girdle'), +(1024549, 0, 1, 10201, 'Overlord\'s Greaves'), +(1024549, 0, 1, 10202, 'Overlord\'s Vambraces'), +(1024549, 0, 1, 14791, 'Protector Cape'), +(1024549, 0, 1, 15379, 'Rageclaw Boots'), +(1024549, 0, 1, 15383, 'Rageclaw Gloves'), +(1024549, 0, 1, 15386, 'Rageclaw Shoulder Pads'), +(1024549, 0, 1, 4089, 'Ricochet Blunderbuss'), +(1024549, 0, 1, 9905, 'Royal Blouse'), +(1024549, 0, 1, 9913, 'Royal Gown'), +(1024549, 0, 1, 9914, 'Royal Scepter'), +(1024549, 0, 1, 14853, 'Sunscale Wristguards'), +(1024549, 0, 1, 9924, 'Tracker\'s Tunic'), +(1024549, 0, 1, 14835, 'Tyrant\'s Chestpiece'), +(1024549, 0, 1, 14842, 'Tyrant\'s Shield'), +(1024549, 0, 1, 8279, 'Valorous Helm'), +(1024549, 0, 1, 8281, 'Valorous Pauldrons'), +(1024549, 0, 1, 14446, 'Venomshroud Belt'), +(1024549, 0, 1, 14438, 'Venomshroud Boots'), +(1024549, 0, 1, 9963, 'Warmonger\'s Circlet'), +(1024549, 0, 1, 9962, 'Warmonger\'s Greaves'), +-- 46-50 +(1024650, 0, 1, 9936, 'Abjurer\'s Boots'), +(1024650, 0, 1, 9939, 'Abjurer\'s Gloves'), +(1024650, 0, 1, 9941, 'Abjurer\'s Mantle'), +(1024650, 0, 1, 14292, 'Arachnidian Cape'), +(1024650, 0, 1, 14953, 'Bloodforged Legplates'), +(1024650, 0, 1, 9948, 'Chieftain\'s Boots'), +(1024650, 0, 1, 9952, 'Chieftain\'s Gloves'), +(1024650, 0, 1, 12013, 'Desert Ring'), +(1024650, 0, 1, 15227, 'Diamond-Tip Bludgeon'), +(1024650, 0, 1, 10060, 'Duskwoven Cape'), +(1024650, 0, 1, 10066, 'Duskwoven Sash'), +(1024650, 0, 1, 15636, 'Formidable Belt'), +(1024650, 0, 1, 15630, 'Formidable Sabatons'), +(1024650, 0, 1, 15638, 'Formidable Shoulder Pads'), +(1024650, 0, 1, 14271, 'Gaea\'s Circlet'), +(1024650, 0, 1, 10086, 'Gothic Plate Armor'), +(1024650, 0, 1, 7537, 'Gothic Shield'), +(1024650, 0, 1, 1639, 'Grinning Axe'), +(1024650, 0, 1, 8123, 'Heraldic Leggings'), +(1024650, 0, 1, 8112, 'Hibernal Pants'), +(1024650, 0, 1, 14965, 'High Chief\'s Bindings'), +(1024650, 0, 1, 15643, 'Ironhide Cloak'), +(1024650, 0, 1, 14921, 'Jade Epaulets'), +(1024650, 0, 1, 14913, 'Jade Greaves'), +(1024650, 0, 1, 15392, 'Jadefire Cloak'), +(1024650, 0, 1, 14661, 'Keeper\'s Cord'), +(1024650, 0, 1, 14780, 'Khan\'s Buckler'), +(1024650, 0, 1, 14779, 'Khan\'s Chestpiece'), +(1024650, 0, 1, 10076, 'Lord\'s Armguards'), +(1024650, 0, 1, 8128, 'Myrmidon\'s Gauntlets'), +(1024650, 0, 1, 8129, 'Myrmidon\'s Girdle'), +(1024650, 0, 1, 8130, 'Myrmidon\'s Greaves'), +(1024650, 0, 1, 14279, 'Opulent Bracers'), +(1024650, 0, 1, 10207, 'Overlord\'s Crown'), +(1024650, 0, 1, 10205, 'Overlord\'s Gauntlets'), +(1024650, 0, 1, 15177, 'Potent Shoulders'), +(1024650, 0, 1, 14788, 'Protector Armguards'), +(1024650, 0, 1, 15385, 'Rageclaw Leggings'), +(1024650, 0, 1, 10127, 'Revenant Bracers'), +(1024650, 0, 1, 10069, 'Righteous Bracers'), +(1024650, 0, 1, 10071, 'Righteous Cloak'), +(1024650, 0, 1, 10067, 'Righteous Waistguard'), +(1024650, 0, 1, 14655, 'Scorpashi Breastplate'), +(1024650, 0, 1, 14658, 'Scorpashi Skullcap'), +(1024650, 0, 1, 14847, 'Sunscale Belt'), +(1024650, 0, 1, 11975, 'Topaz Ring'), +(1024650, 0, 1, 15252, 'Tusker Sword'), +(1024650, 0, 1, 8280, 'Valorous Legguards'), +(1024650, 0, 1, 14443, 'Venomshroud Mantle'), +(1024650, 0, 1, 14442, 'Venomshroud Mitts'), +(1024650, 0, 1, 9964, 'Warmonger\'s Leggings'), +(1024650, 0, 1, 9965, 'Warmonger\'s Pauldrons'), +(1024650, 0, 1, 15965, 'Windchaser Orb'), +(1024650, 0, 1, 14434, 'Windchaser Robes'), +(1024650, 0, 1, 14427, 'Windchaser Wraps'), +-- 47-51 +(1024751, 0, 1, 9940, 'Abjurer\'s Hood'), +(1024751, 0, 1, 9942, 'Abjurer\'s Pants'), +(1024751, 0, 1, 14291, 'Arachnidian Bracelets'), +(1024751, 0, 1, 14952, 'Bloodforged Helmet'), +(1024751, 0, 1, 14904, 'Brutish Breastplate'), +(1024751, 0, 1, 14912, 'Brutish Shield'), +(1024751, 0, 1, 7527, 'Cabalist Chestpiece'), +(1024751, 0, 1, 9953, 'Chieftain\'s Headdress'), +(1024751, 0, 1, 9955, 'Chieftain\'s Shoulders'), +(1024751, 0, 1, 10194, 'Crusader\'s Cloak'), +(1024751, 0, 1, 10059, 'Duskwoven Bracers'), +(1024751, 0, 1, 10058, 'Duskwoven Sandals'), +(1024751, 0, 1, 7518, 'Gossamer Robe'), +(1024751, 0, 1, 7557, 'Gossamer Rod'), +(1024751, 0, 1, 7517, 'Gossamer Tunic'), +(1024751, 0, 1, 15623, 'Gryphon Mail Crown'), +(1024751, 0, 1, 15627, 'Gryphon Mail Legguards'), +(1024751, 0, 1, 8248, 'Imperial Red Cloak'), +(1024751, 0, 1, 15639, 'Ironhide Bracers'), +(1024751, 0, 1, 15387, 'Jadefire Bracelets'), +(1024751, 0, 1, 14923, 'Lofty Armguards'), +(1024751, 0, 1, 10080, 'Lord\'s Gauntlets'), +(1024751, 0, 1, 10081, 'Lord\'s Girdle'), +(1024751, 0, 1, 8131, 'Myrmidon\'s Helm'), +(1024751, 0, 1, 8133, 'Myrmidon\'s Pauldrons'), +(1024751, 0, 1, 12001, 'Onyx Ring'), +(1024751, 0, 1, 14286, 'Opulent Belt'), +(1024751, 0, 1, 14285, 'Opulent Boots'), +(1024751, 0, 1, 14282, 'Opulent Gloves'), +(1024751, 0, 1, 14278, 'Opulent Mantle'), +(1024751, 0, 1, 10208, 'Overlord\'s Legplates'), +(1024751, 0, 1, 10209, 'Overlord\'s Spaulders'), +(1024751, 0, 1, 15323, 'Percussion Shotgun'), +(1024751, 0, 1, 15171, 'Potent Boots'), +(1024751, 0, 1, 15174, 'Potent Gloves'), +(1024751, 0, 1, 15176, 'Potent Pants'), +(1024751, 0, 1, 15183, 'Praetorian Cloak'), +(1024751, 0, 1, 14794, 'Protector Ankleguards'), +(1024751, 0, 1, 14792, 'Protector Gauntlets'), +(1024751, 0, 1, 14793, 'Protector Waistband'), +(1024751, 0, 1, 15384, 'Rageclaw Helm'), +(1024751, 0, 1, 10131, 'Revenant Boots'), +(1024751, 0, 1, 10129, 'Revenant Gauntlets'), +(1024751, 0, 1, 10130, 'Revenant Girdle'), +(1024751, 0, 1, 15263, 'Royal Mallet'), +(1024751, 0, 1, 8257, 'Serpentskin Bracers'), +(1024751, 0, 1, 8259, 'Serpentskin Cloak'), +(1024751, 0, 1, 8255, 'Serpentskin Girdle'), +(1024751, 0, 1, 14846, 'Sunscale Gauntlets'), +(1024751, 0, 1, 14848, 'Sunscale Sabatons'), +(1024751, 0, 1, 12024, 'Vanadium Talisman'), +(1024751, 0, 1, 14441, 'Venomshroud Mask'), +(1024751, 0, 1, 15245, 'Vorpal Dagger'), +(1024751, 0, 1, 9958, 'Warmonger\'s Buckler'), +(1024751, 0, 1, 9957, 'Warmonger\'s Chestpiece'), +-- 48-52 +(1024852, 0, 1, 8106, 'Hibernal Armor'), +(1024852, 0, 1, 14290, 'Arachnidian Footpads'), +(1024852, 0, 1, 14289, 'Arachnidian Girdle'), +(1024852, 0, 1, 14294, 'Arachnidian Gloves'), +(1024852, 0, 1, 12044, 'Arctic Pendant'), +(1024852, 0, 1, 14948, 'Bloodforged Chestpiece'), +(1024852, 0, 1, 14954, 'Bloodforged Shield'), +(1024852, 0, 1, 14267, 'Bloodwoven Jerkin'), +(1024852, 0, 1, 15982, 'Bloodwoven Rod'), +(1024852, 0, 1, 14265, 'Bloodwoven Wraps'), +(1024852, 0, 1, 9954, 'Chieftain\'s Leggings'), +(1024852, 0, 1, 10191, 'Crusader\'s Armguards'), +(1024852, 0, 1, 10063, 'Duskwoven Amice'), +(1024852, 0, 1, 10062, 'Duskwoven Gloves'), +(1024852, 0, 1, 10061, 'Duskwoven Turban'), +(1024852, 0, 1, 8266, 'Ebonhold Cloak'), +(1024852, 0, 1, 15637, 'Formidable Legguards'), +(1024852, 0, 1, 14274, 'Gaea\'s Leggings'), +(1024852, 0, 1, 15622, 'Gryphon Mail Breastplate'), +(1024852, 0, 1, 15621, 'Gryphon Mail Buckler'), +(1024852, 0, 1, 15291, 'Harpy Needler'), +(1024852, 0, 1, 10243, 'Heavy Lamellar Girdle'), +(1024852, 0, 1, 10239, 'Heavy Lamellar Vambraces'), +(1024852, 0, 1, 8119, 'Heraldic Breastplate'), +(1024852, 0, 1, 8113, 'Hibernal Robe'), +(1024852, 0, 1, 15937, 'Hibernal Sphere'), +(1024852, 0, 1, 14960, 'High Chief\'s Belt'), +(1024852, 0, 1, 14957, 'High Chief\'s Sabatons'), +(1024852, 0, 1, 14450, 'Highborne Cloak'), +(1024852, 0, 1, 8247, 'Imperial Red Bracers'), +(1024852, 0, 1, 8253, 'Imperial Red Sash'), +(1024852, 0, 1, 15641, 'Ironhide Belt'), +(1024852, 0, 1, 15279, 'Ivory Wand'), +(1024852, 0, 1, 14920, 'Jade Legplates'), +(1024852, 0, 1, 14666, 'Keeper\'s Gloves'), +(1024852, 0, 1, 14662, 'Keeper\'s Hooves'), +(1024852, 0, 1, 14669, 'Keeper\'s Mantle'), +(1024852, 0, 1, 10082, 'Lord\'s Boots'), +(1024852, 0, 1, 10083, 'Lord\'s Crown'), +(1024852, 0, 1, 15649, 'Merciless Bracers'), +(1024852, 0, 1, 15652, 'Merciless Cloak'), +(1024852, 0, 1, 8126, 'Myrmidon\'s Breastplate'), +(1024852, 0, 1, 8134, 'Myrmidon\'s Defender'), +(1024852, 0, 1, 8132, 'Myrmidon\'s Leggings'), +(1024852, 0, 1, 15175, 'Potent Helmet'), +(1024852, 0, 1, 15182, 'Praetorian Wristbands'), +(1024852, 0, 1, 14797, 'Protector Pads'), +(1024852, 0, 1, 15381, 'Rageclaw Chestguard'), +(1024852, 0, 1, 10132, 'Revenant Helmet'), +(1024852, 0, 1, 10134, 'Revenant Shoulders'), +(1024852, 0, 1, 10068, 'Righteous Boots'), +(1024852, 0, 1, 10072, 'Righteous Gloves'), +(1024852, 0, 1, 10075, 'Righteous Spaulders'), +(1024852, 0, 1, 15216, 'Rune Sword'), +(1024852, 0, 1, 14851, 'Sunscale Spaulders'), +(1024852, 0, 1, 10185, 'Swashbuckler\'s Cape'), +(1024852, 0, 1, 8274, 'Valorous Chestguard'), +(1024852, 0, 1, 8282, 'Valorous Shield'), +(1024852, 0, 1, 11989, 'Vanadium Loop'), +-- 49-53 +(1024953, 0, 1, 8315, 'Alabaster Plate Girdle'), +(1024953, 0, 1, 14296, 'Arachnidian Pauldrons'), +(1024953, 0, 1, 15253, 'Beheading Blade'), +(1024953, 0, 1, 14801, 'Bloodlust Cape'), +(1024953, 0, 1, 14300, 'Bonecaster\'s Cape'), +(1024953, 0, 1, 10197, 'Crusader\'s Belt'), +(1024953, 0, 1, 10196, 'Crusader\'s Gauntlets'), +(1024953, 0, 1, 15274, 'Diviner Long Staff'), +(1024953, 0, 1, 8264, 'Ebonhold Wristguards'), +(1024953, 0, 1, 15631, 'Formidable Chestpiece'), +(1024953, 0, 1, 15634, 'Formidable Circlet'), +(1024953, 0, 1, 15633, 'Formidable Crest'), +(1024953, 0, 1, 14275, 'Gaea\'s Raiment'), +(1024953, 0, 1, 15983, 'Gaea\'s Scepter'), +(1024953, 0, 1, 14277, 'Gaea\'s Tunic'), +(1024953, 0, 1, 10238, 'Heavy Lamellar Boots'), +(1024953, 0, 1, 10242, 'Heavy Lamellar Gauntlets'), +(1024953, 0, 1, 14959, 'High Chief\'s Gauntlets'), +(1024953, 0, 1, 14448, 'Highborne Bracelets'), +(1024953, 0, 1, 8246, 'Imperial Red Boots'), +(1024953, 0, 1, 8249, 'Imperial Red Gloves'), +(1024953, 0, 1, 8250, 'Imperial Red Mantle'), +(1024953, 0, 1, 15644, 'Ironhide Gauntlets'), +(1024953, 0, 1, 15642, 'Ironhide Greaves'), +(1024953, 0, 1, 14919, 'Jade Circlet'), +(1024953, 0, 1, 15388, 'Jadefire Belt'), +(1024953, 0, 1, 15393, 'Jadefire Gloves'), +(1024953, 0, 1, 14668, 'Keeper\'s Woolies'), +(1024953, 0, 1, 14927, 'Lofty Belt'), +(1024953, 0, 1, 10084, 'Lord\'s Legguards'), +(1024953, 0, 1, 10085, 'Lord\'s Pauldrons'), +(1024953, 0, 1, 15236, 'Moon Cleaver'), +(1024953, 0, 1, 10180, 'Mystical Belt'), +(1024953, 0, 1, 10174, 'Mystical Cape'), +(1024953, 0, 1, 10203, 'Overlord\'s Chestplate'), +(1024953, 0, 1, 9974, 'Overlord\'s Shield'), +(1024953, 0, 1, 15170, 'Potent Armor'), +(1024953, 0, 1, 14673, 'Pridelord Cape'), +(1024953, 0, 1, 10133, 'Revenant Leggings'), +(1024953, 0, 1, 10073, 'Righteous Helmet'), +(1024953, 0, 1, 11976, 'Sardonyx Knuckle'), +(1024953, 0, 1, 8256, 'Serpentskin Boots'), +(1024953, 0, 1, 8260, 'Serpentskin Gloves'), +(1024953, 0, 1, 12055, 'Stardust Band'), +(1024953, 0, 1, 14850, 'Sunscale Legplates'), +(1024953, 0, 1, 10190, 'Swashbuckler\'s Belt'), +(1024953, 0, 1, 10184, 'Swashbuckler\'s Bracers'), +(1024953, 0, 1, 14861, 'Vanguard Vambraces'), +(1024953, 0, 1, 14444, 'Venomshroud Leggings'), +-- 50-54 +(1025054, 0, 1, 9944, 'Abjurer\'s Crystal'), +(1025054, 0, 1, 9943, 'Abjurer\'s Robe'), +(1025054, 0, 1, 9946, 'Abjurer\'s Tunic'), +(1025054, 0, 1, 8314, 'Alabaster Plate Gauntlets'), +(1025054, 0, 1, 8316, 'Alabaster Plate Greaves'), +(1025054, 0, 1, 8311, 'Alabaster Plate Vambraces'), +(1025054, 0, 1, 12014, 'Arctic Ring'), +(1025054, 0, 1, 14807, 'Bloodlust Bracelets'), +(1025054, 0, 1, 14301, 'Bonecaster\'s Bindings'), +(1025054, 0, 1, 9950, 'Chieftain\'s Breastplate'), +(1025054, 0, 1, 10098, 'Councillor\'s Cloak'), +(1025054, 0, 1, 10192, 'Crusader\'s Boots'), +(1025054, 0, 1, 10198, 'Crusader\'s Helm'), +(1025054, 0, 1, 10200, 'Crusader\'s Pauldrons'), +(1025054, 0, 1, 10064, 'Duskwoven Pants'), +(1025054, 0, 1, 10241, 'Heavy Lamellar Helm'), +(1025054, 0, 1, 10245, 'Heavy Lamellar Pauldrons'), +(1025054, 0, 1, 14963, 'High Chief\'s Pauldrons'), +(1025054, 0, 1, 14454, 'Highborne Cord'), +(1025054, 0, 1, 14447, 'Highborne Footpads'), +(1025054, 0, 1, 14451, 'Highborne Gloves'), +(1025054, 0, 1, 8254, 'Imperial Red Circlet'), +(1025054, 0, 1, 15647, 'Ironhide Pauldrons'), +(1025054, 0, 1, 14915, 'Jade Breastplate'), +(1025054, 0, 1, 14916, 'Jade Deflector'), +(1025054, 0, 1, 15395, 'Jadefire Epaulets'), +(1025054, 0, 1, 15389, 'Jadefire Sabatons'), +(1025054, 0, 1, 14667, 'Keeper\'s Wreath'), +(1025054, 0, 1, 14926, 'Lofty Gauntlets'), +(1025054, 0, 1, 14922, 'Lofty Sabatons'), +(1025054, 0, 1, 10077, 'Lord\'s Breastplate'), +(1025054, 0, 1, 10078, 'Lord\'s Crest'), +(1025054, 0, 1, 12034, 'Marble Necklace'), +(1025054, 0, 1, 15653, 'Merciless Gauntlets'), +(1025054, 0, 1, 10173, 'Mystical Bracers'), +(1025054, 0, 1, 14281, 'Opulent Crown'), +(1025054, 0, 1, 10120, 'Ornate Cloak'), +(1025054, 0, 1, 15180, 'Praetorian Girdle'), +(1025054, 0, 1, 14672, 'Pridelord Bands'), +(1025054, 0, 1, 14795, 'Protector Helm'), +(1025054, 0, 1, 14796, 'Protector Legguards'), +(1025054, 0, 1, 10074, 'Righteous Leggings'), +(1025054, 0, 1, 8263, 'Serpentskin Spaulders'), +(1025054, 0, 1, 15294, 'Siege Bow'), +(1025054, 0, 1, 15228, 'Smashing Star'), +(1025054, 0, 1, 14849, 'Sunscale Helmet'), +(1025054, 0, 1, 10186, 'Swashbuckler\'s Gloves'), +(1025054, 0, 1, 10108, 'Wanderer\'s Cloak'), +(1025054, 0, 1, 15280, 'Wizard\'s Hand'), +-- 51-55 +(1025155, 0, 1, 8317, 'Alabaster Plate Helmet'), +(1025155, 0, 1, 14299, 'Bonecaster\'s Boots'), +(1025155, 0, 1, 14313, 'Celestial Cape'), +(1025155, 0, 1, 10096, 'Councillor\'s Cuffs'), +(1025155, 0, 1, 10103, 'Councillor\'s Sash'), +(1025155, 0, 1, 10199, 'Crusader\'s Leggings'), +(1025155, 0, 1, 15254, 'Dark Espadon'), +(1025155, 0, 1, 8267, 'Ebonhold Gauntlets'), +(1025155, 0, 1, 8268, 'Ebonhold Girdle'), +(1025155, 0, 1, 8272, 'Ebonhold Shoulderpads'), +(1025155, 0, 1, 10244, 'Heavy Lamellar Leggings'), +(1025155, 0, 1, 14962, 'High Chief\'s Legguards'), +(1025155, 0, 1, 14452, 'Highborne Pauldrons'), +(1025155, 0, 1, 15661, 'Impenetrable Cloak'), +(1025155, 0, 1, 8251, 'Imperial Red Pants'), +(1025155, 0, 1, 15394, 'Jadefire Pants'), +(1025155, 0, 1, 14664, 'Keeper\'s Armor'), +(1025155, 0, 1, 14929, 'Lofty Shoulder Pads'), +(1025155, 0, 1, 12002, 'Marble Circle'), +(1025155, 0, 1, 15654, 'Merciless Belt'), +(1025155, 0, 1, 15656, 'Merciless Epaulets'), +(1025155, 0, 1, 15694, 'Merciless Greaves'), +(1025155, 0, 1, 10179, 'Mystical Boots'), +(1025155, 0, 1, 10176, 'Mystical Gloves'), +(1025155, 0, 1, 14283, 'Opulent Leggings'), +(1025155, 0, 1, 10126, 'Ornate Bracers'), +(1025155, 0, 1, 15427, 'Peerless Cloak'), +(1025155, 0, 1, 15184, 'Praetorian Gloves'), +(1025155, 0, 1, 15187, 'Praetorian Pauldrons'), +(1025155, 0, 1, 14789, 'Protector Breastplate'), +(1025155, 0, 1, 14790, 'Protector Buckler'), +(1025155, 0, 1, 10128, 'Revenant Chestplate'), +(1025155, 0, 1, 10093, 'Revenant Deflector'), +(1025155, 0, 1, 12025, 'Selenium Chain'), +(1025155, 0, 1, 8261, 'Serpentskin Helm'), +(1025155, 0, 1, 8262, 'Serpentskin Leggings'), +(1025155, 0, 1, 14844, 'Sunscale Chestguard'), +(1025155, 0, 1, 14852, 'Sunscale Shield'), +(1025155, 0, 1, 10183, 'Swashbuckler\'s Boots'), +(1025155, 0, 1, 10171, 'Templar Bracers'), +(1025155, 0, 1, 10166, 'Templar Girdle'), +(1025155, 0, 1, 15275, 'Thaumaturgist Staff'), +(1025155, 0, 1, 14856, 'Vanguard Girdle'), +(1025155, 0, 1, 14857, 'Vanguard Sabatons'), +(1025155, 0, 1, 15966, 'Venomshroud Orb'), +(1025155, 0, 1, 14445, 'Venomshroud Silk Robes'), +(1025155, 0, 1, 14437, 'Venomshroud Vest'), +(1025155, 0, 1, 10109, 'Wanderer\'s Belt'), +(1025155, 0, 1, 10107, 'Wanderer\'s Bracers'), +(1025155, 0, 1, 15217, 'Widow Blade'), +-- 52-56 +(1025256, 0, 1, 8319, 'Alabaster Plate Pauldrons'), +(1025256, 0, 1, 14293, 'Arachnidian Circlet'), +(1025256, 0, 1, 14295, 'Arachnidian Legguards'), +(1025256, 0, 1, 8286, 'Arcane Cloak'), +(1025256, 0, 1, 15229, 'Blesswind Hammer'), +(1025256, 0, 1, 14803, 'Bloodlust Belt'), +(1025256, 0, 1, 14802, 'Bloodlust Gauntlets'), +(1025256, 0, 1, 14304, 'Bonecaster\'s Belt'), +(1025256, 0, 1, 14311, 'Celestial Bindings'), +(1025256, 0, 1, 15237, 'Corpse Harvester'), +(1025256, 0, 1, 10099, 'Councillor\'s Gloves'), +(1025256, 0, 1, 10193, 'Crusader\'s Armor'), +(1025256, 0, 1, 10195, 'Crusader\'s Shield'), +(1025256, 0, 1, 15936, 'Duskwoven Branch'), +(1025256, 0, 1, 10065, 'Duskwoven Robe'), +(1025256, 0, 1, 10057, 'Duskwoven Tunic'), +(1025256, 0, 1, 8269, 'Ebonhold Boots'), +(1025256, 0, 1, 8270, 'Ebonhold Helmet'), +(1025256, 0, 1, 10278, 'Emerald Girdle'), +(1025256, 0, 1, 10231, 'Engraved Cape'), +(1025256, 0, 1, 14968, 'Glorious Belt'), +(1025256, 0, 1, 14974, 'Glorious Bindings'), +(1025256, 0, 1, 15190, 'Grand Cloak'), +(1025256, 0, 1, 10240, 'Heavy Lamellar Chestpiece'), +(1025256, 0, 1, 10204, 'Heavy Lamellar Shield'), +(1025256, 0, 1, 14961, 'High Chief\'s Crown'), +(1025256, 0, 1, 15659, 'Impenetrable Bindings'), +(1025256, 0, 1, 15645, 'Ironhide Helmet'), +(1025256, 0, 1, 15646, 'Ironhide Legguards'), +(1025256, 0, 1, 14928, 'Lofty Legguards'), +(1025256, 0, 1, 10175, 'Mystical Headwrap'), +(1025256, 0, 1, 10172, 'Mystical Mantle'), +(1025256, 0, 1, 10122, 'Ornate Girdle'), +(1025256, 0, 1, 15425, 'Peerless Bracers'), +(1025256, 0, 1, 15181, 'Praetorian Boots'), +(1025256, 0, 1, 15186, 'Praetorian Leggings'), +(1025256, 0, 1, 14674, 'Pridelord Girdle'), +(1025256, 0, 1, 15295, 'Quillfire Bow'), +(1025256, 0, 1, 14321, 'Resplendent Cloak'), +(1025256, 0, 1, 10070, 'Righteous Armor'), +(1025256, 0, 1, 11990, 'Selenium Loop'), +(1025256, 0, 1, 11977, 'Serpentine Loop'), +(1025256, 0, 1, 10187, 'Swashbuckler\'s Eyepatch'), +(1025256, 0, 1, 10189, 'Swashbuckler\'s Shoulderpads'), +(1025256, 0, 1, 10167, 'Templar Boots'), +(1025256, 0, 1, 10165, 'Templar Gauntlets'), +(1025256, 0, 1, 8297, 'Traveler\'s Cloak'), +(1025256, 0, 1, 14855, 'Vanguard Gauntlets'), +(1025256, 0, 1, 10110, 'Wanderer\'s Gloves'), +-- 53-57 +(1025357, 0, 1, 8318, 'Alabaster Plate Leggings'), +(1025357, 0, 1, 8285, 'Arcane Bands'), +(1025357, 0, 1, 8291, 'Arcane Sash'), +(1025357, 0, 1, 15264, 'Backbreaker'), +(1025357, 0, 1, 14302, 'Bonecaster\'s Gloves'), +(1025357, 0, 1, 14298, 'Bonecaster\'s Spaulders'), +(1025357, 0, 1, 15324, 'Burnside Rifle'), +(1025357, 0, 1, 14309, 'Celestial Belt'), +(1025357, 0, 1, 15271, 'Colossal Great Axe'), +(1025357, 0, 1, 10095, 'Councillor\'s Boots'), +(1025357, 0, 1, 8265, 'Ebonhold Armor'), +(1025357, 0, 1, 8275, 'Ebonhold Buckler'), +(1025357, 0, 1, 8271, 'Ebonhold Leggings'), +(1025357, 0, 1, 10276, 'Emerald Sabatons'), +(1025357, 0, 1, 10282, 'Emerald Vambraces'), +(1025357, 0, 1, 10229, 'Engraved Bracers'), +(1025357, 0, 1, 14967, 'Glorious Gauntlets'), +(1025357, 0, 1, 14972, 'Glorious Sabatons'), +(1025357, 0, 1, 14938, 'Heroic Bracers'), +(1025357, 0, 1, 14958, 'High Chief\'s Armor'), +(1025357, 0, 1, 14964, 'High Chief\'s Shield'), +(1025357, 0, 1, 15119, 'Highborne Pants'), +(1025357, 0, 1, 15663, 'Impenetrable Belt'), +(1025357, 0, 1, 8252, 'Imperial Red Robe'), +(1025357, 0, 1, 15930, 'Imperial Red Scepter'), +(1025357, 0, 1, 8245, 'Imperial Red Tunic'), +(1025357, 0, 1, 15640, 'Ironhide Breastplate'), +(1025357, 0, 1, 15648, 'Ironhide Shield'), +(1025357, 0, 1, 15391, 'Jadefire Cap'), +(1025357, 0, 1, 15390, 'Jadefire Chestguard'), +(1025357, 0, 1, 15671, 'Magnificent Cloak'), +(1025357, 0, 1, 15651, 'Merciless Crown'), +(1025357, 0, 1, 15655, 'Merciless Legguards'), +(1025357, 0, 1, 10177, 'Mystical Leggings'), +(1025357, 0, 1, 14284, 'Opulent Robes'), +(1025357, 0, 1, 15984, 'Opulent Scepter'), +(1025357, 0, 1, 14287, 'Opulent Tunic'), +(1025357, 0, 1, 10121, 'Ornate Gauntlets'), +(1025357, 0, 1, 10125, 'Ornate Pauldrons'), +(1025357, 0, 1, 15428, 'Peerless Belt'), +(1025357, 0, 1, 14671, 'Pridelord Boots'), +(1025357, 0, 1, 14675, 'Pridelord Gloves'), +(1025357, 0, 1, 12056, 'Ring of the Heavens'), +(1025357, 0, 1, 8258, 'Serpentskin Armor'), +(1025357, 0, 1, 12045, 'Swamp Pendant'), +(1025357, 0, 1, 10188, 'Swashbuckler\'s Leggings'), +(1025357, 0, 1, 10168, 'Templar Crown'), +(1025357, 0, 1, 10170, 'Templar Pauldrons'), +(1025357, 0, 1, 8293, 'Traveler\'s Belt'), +(1025357, 0, 1, 8295, 'Traveler\'s Bracers'), +(1025357, 0, 1, 14860, 'Vanguard Pauldrons'), +(1025357, 0, 1, 10106, 'Wanderer\'s Boots'), +-- 54-58), +(1025458, 0, 1, 8312, 'Alabaster Breastplate'), +(1025458, 0, 1, 8320, 'Alabaster Shield'), +(1025458, 0, 1, 14288, 'Arachnidian Armor'), +(1025458, 0, 1, 15985, 'Arachnidian Branch'), +(1025458, 0, 1, 14297, 'Arachnidian Robes'), +(1025458, 0, 1, 8284, 'Arcane Boots'), +(1025458, 0, 1, 8287, 'Arcane Gloves'), +(1025458, 0, 1, 14805, 'Bloodlust Britches'), +(1025458, 0, 1, 14806, 'Bloodlust Epaulets'), +(1025458, 0, 1, 14305, 'Bonecaster\'s Sarong'), +(1025458, 0, 1, 10097, 'Councillor\'s Circlet'), +(1025458, 0, 1, 10100, 'Councillor\'s Shoulders'), +(1025458, 0, 1, 15218, 'Crystal Sword'), +(1025458, 0, 1, 10212, 'Elegant Cloak'), +(1025458, 0, 1, 14459, 'Elunarian Cloak'), +(1025458, 0, 1, 10277, 'Emerald Gauntlets'), +(1025458, 0, 1, 10233, 'Engraved Girdle'), +(1025458, 0, 1, 15255, 'Gallant Flamberge'), +(1025458, 0, 1, 14971, 'Glorious Shoulder Pads'), +(1025458, 0, 1, 15281, 'Glowstar Rod'), +(1025458, 0, 1, 15188, 'Grand Armguards'), +(1025458, 0, 1, 15191, 'Grand Belt'), +(1025458, 0, 1, 8304, 'Hero\'s Cape'), +(1025458, 0, 1, 14934, 'Heroic Girdle'), +(1025458, 0, 1, 14449, 'Highborne Crown'), +(1025458, 0, 1, 10370, 'Imbued Plate Girdle'), +(1025458, 0, 1, 10375, 'Imbued Plate Vambraces'), +(1025458, 0, 1, 15662, 'Impenetrable Gauntlets'), +(1025458, 0, 1, 14924, 'Lofty Breastplate'), +(1025458, 0, 1, 14925, 'Lofty Helm'), +(1025458, 0, 1, 14930, 'Lofty Shield'), +(1025458, 0, 1, 15657, 'Merciless Shield'), +(1025458, 0, 1, 15650, 'Merciless Surcoat'), +(1025458, 0, 1, 10224, 'Nightshade Cloak'), +(1025458, 0, 1, 12035, 'Obsidian Pendant'), +(1025458, 0, 1, 10123, 'Ornate Circlet'), +(1025458, 0, 1, 10119, 'Ornate Greaves'), +(1025458, 0, 1, 10124, 'Ornate Legguards'), +(1025458, 0, 1, 15185, 'Praetorian Coif'), +(1025458, 0, 1, 15179, 'Praetorian Padded Armor'), +(1025458, 0, 1, 14678, 'Pridelord Pauldrons'), +(1025458, 0, 1, 14320, 'Resplendent Bracelets'), +(1025458, 0, 1, 12015, 'Swamp Ring'), +(1025458, 0, 1, 10169, 'Templar Legplates'), +(1025458, 0, 1, 8294, 'Traveler\'s Boots'), +(1025458, 0, 1, 8298, 'Traveler\'s Gloves'), +(1025458, 0, 1, 14859, 'Vanguard Legplates'), +(1025458, 0, 1, 10111, 'Wanderer\'s Hat'), +(1025458, 0, 1, 10113, 'Wanderer\'s Shoulders'), +(1025458, 0, 1, 14813, 'Warstrike Cape'), +-- 55-59 +(1025559, 0, 1, 8292, 'Arcane Cover'), +(1025559, 0, 1, 14799, 'Bloodlust Boots'), +(1025559, 0, 1, 14804, 'Bloodlust Helm'), +(1025559, 0, 1, 14314, 'Celestial Handwraps'), +(1025559, 0, 1, 14310, 'Celestial Slippers'), +(1025559, 0, 1, 10101, 'Councillor\'s Pants'), +(1025559, 0, 1, 10216, 'Elegant Belt'), +(1025559, 0, 1, 10213, 'Elegant Bracers'), +(1025559, 0, 1, 14457, 'Elunarian Cuffs'), +(1025559, 0, 1, 10279, 'Emerald Helm'), +(1025559, 0, 1, 10281, 'Emerald Pauldrons'), +(1025559, 0, 1, 10234, 'Engraved Boots'), +(1025559, 0, 1, 10232, 'Engraved Gauntlets'), +(1025559, 0, 1, 10237, 'Engraved Pauldrons'), +(1025559, 0, 1, 14331, 'Eternal Cloak'), +(1025559, 0, 1, 14970, 'Glorious Legplates'), +(1025559, 0, 1, 8302, 'Hero\'s Bracers'), +(1025559, 0, 1, 14933, 'Heroic Gauntlets'), +(1025559, 0, 1, 14932, 'Heroic Greaves'), +(1025559, 0, 1, 10369, 'Imbued Plate Gauntlets'), +(1025559, 0, 1, 10371, 'Imbued Plate Greaves'), +(1025559, 0, 1, 11978, 'Jasper Link'), +(1025559, 0, 1, 15673, 'Magnificent Belt'), +(1025559, 0, 1, 15668, 'Magnificent Bracers'), +(1025559, 0, 1, 15276, 'Magus Long Staff'), +(1025559, 0, 1, 10148, 'Mighty Cloak'), +(1025559, 0, 1, 10181, 'Mystical Armor'), +(1025559, 0, 1, 15938, 'Mystical Orb'), +(1025559, 0, 1, 10178, 'Mystical Robe'), +(1025559, 0, 1, 10223, 'Nightshade Armguards'), +(1025559, 0, 1, 10221, 'Nightshade Girdle'), +(1025559, 0, 1, 12004, 'Obsidian Band'), +(1025559, 0, 1, 10118, 'Ornate Breastplate'), +(1025559, 0, 1, 10362, 'Ornate Shield'), +(1025559, 0, 1, 15265, 'Painbringer'), +(1025559, 0, 1, 15426, 'Peerless Boots'), +(1025559, 0, 1, 15429, 'Peerless Gloves'), +(1025559, 0, 1, 15432, 'Peerless Shoulders'), +(1025559, 0, 1, 14676, 'Pridelord Halo'), +(1025559, 0, 1, 14677, 'Pridelord Pants'), +(1025559, 0, 1, 14327, 'Resplendent Belt'), +(1025559, 0, 1, 10182, 'Swashbuckler\'s Breastplate'), +(1025559, 0, 1, 10164, 'Templar Chestplate'), +(1025559, 0, 1, 10364, 'Templar Shield'), +(1025559, 0, 1, 15681, 'Triumphant Cloak'), +(1025559, 0, 1, 14858, 'Vanguard Headdress'), +(1025559, 0, 1, 10112, 'Wanderer\'s Leggings'), +(1025559, 0, 1, 14869, 'Warleader\'s Bracers'), +(1025559, 0, 1, 15238, 'Warlord\'s Axe'), +-- 56-60 +(1025660, 0, 1, 8288, 'Arcane Pads'), +(1025660, 0, 1, 14798, 'Bloodlust Breastplate'), +(1025660, 0, 1, 14800, 'Bloodlust Buckler'), +(1025660, 0, 1, 14307, 'Bonecaster\'s Crown'), +(1025660, 0, 1, 14315, 'Celestial Kilt'), +(1025660, 0, 1, 14316, 'Celestial Pauldrons'), +(1025660, 0, 1, 10381, 'Commander\'s Girdle'), +(1025660, 0, 1, 10377, 'Commander\'s Vambraces'), +(1025660, 0, 1, 10102, 'Councillor\'s Robes'), +(1025660, 0, 1, 15939, 'Councillor\'s Scepter'), +(1025660, 0, 1, 10104, 'Councillor\'s Tunic'), +(1025660, 0, 1, 15219, 'Dimensional Blade'), +(1025660, 0, 1, 10211, 'Elegant Boots'), +(1025660, 0, 1, 10214, 'Elegant Gloves'), +(1025660, 0, 1, 10280, 'Emerald Legplates'), +(1025660, 0, 1, 10365, 'Emerald Shield'), +(1025660, 0, 1, 10235, 'Engraved Helm'), +(1025660, 0, 1, 10236, 'Engraved Leggings'), +(1025660, 0, 1, 14983, 'Exalted Armsplints'), +(1025660, 0, 1, 14969, 'Glorious Headdress'), +(1025660, 0, 1, 15693, 'Grand Shoulders'), +(1025660, 0, 1, 8306, 'Hero\'s Belt'), +(1025660, 0, 1, 8305, 'Hero\'s Gauntlets'), +(1025660, 0, 1, 14937, 'Heroic Pauldrons'), +(1025660, 0, 1, 10138, 'High Councillor\'s Cloak'), +(1025660, 0, 1, 14455, 'Highborne Padded Armor'), +(1025660, 0, 1, 14453, 'Highborne Robes'), +(1025660, 0, 1, 15967, 'Highborne Star'), +(1025660, 0, 1, 10372, 'Imbued Plate Helmet'), +(1025660, 0, 1, 10374, 'Imbued Plate Pauldrons'), +(1025660, 0, 1, 15666, 'Impenetrable Pauldrons'), +(1025660, 0, 1, 15658, 'Impenetrable Sabatons'), +(1025660, 0, 1, 14682, 'Indomitable Armguards'), +(1025660, 0, 1, 14683, 'Indomitable Cloak'), +(1025660, 0, 1, 15256, 'Massacre Sword'), +(1025660, 0, 1, 10159, 'Mercurial Cloak'), +(1025660, 0, 1, 10145, 'Mighty Girdle'), +(1025660, 0, 1, 10222, 'Nightshade Boots'), +(1025660, 0, 1, 10225, 'Nightshade Gloves'), +(1025660, 0, 1, 15431, 'Peerless Leggings'), +(1025660, 0, 1, 14670, 'Pridelord Armor'), +(1025660, 0, 1, 12026, 'Quicksilver Pendant'), +(1025660, 0, 1, 11991, 'Quicksilver Ring'), +(1025660, 0, 1, 15272, 'Razor Axe'), +(1025660, 0, 1, 14319, 'Resplendent Boots'), +(1025660, 0, 1, 8299, 'Traveler\'s Helm'), +(1025660, 0, 1, 8301, 'Traveler\'s Spaulders'), +(1025660, 0, 1, 14854, 'Vanguard Breastplate'), +(1025660, 0, 1, 15890, 'Vanguard Shield'), +(1025660, 0, 1, 14864, 'Warleader\'s Belt'), +(1025660, 0, 1, 14810, 'Warstrike Armsplints'), +(1025660, 0, 1, 14808, 'Warstrike Belt'), +-- 57-61 +(1025761, 0, 1, 10258, 'Adventurer\'s Cape'), +(1025761, 0, 1, 8289, 'Arcane Leggings'), +(1025761, 0, 1, 14303, 'Bonecaster\'s Shroud'), +(1025761, 0, 1, 15986, 'Bonecaster\'s Star'), +(1025761, 0, 1, 14306, 'Bonecaster\'s Vest'), +(1025761, 0, 1, 10376, 'Commander\'s Boots'), +(1025761, 0, 1, 10380, 'Commander\'s Gauntlets'), +(1025761, 0, 1, 15282, 'Dragon Finger'), +(1025761, 0, 1, 12057, 'Dragonscale Band'), +(1025761, 0, 1, 10219, 'Elegant Circlet'), +(1025761, 0, 1, 10210, 'Elegant Mantle'), +(1025761, 0, 1, 14465, 'Elunarian Belt'), +(1025761, 0, 1, 14458, 'Elunarian Boots'), +(1025761, 0, 1, 10275, 'Emerald Breastplate'), +(1025761, 0, 1, 10230, 'Engraved Breastplate'), +(1025761, 0, 1, 10363, 'Engraved Wall'), +(1025761, 0, 1, 14977, 'Exalted Girdle'), +(1025761, 0, 1, 14973, 'Glorious Shield'), +(1025761, 0, 1, 15189, 'Grand Boots'), +(1025761, 0, 1, 15192, 'Grand Gauntlets'), +(1025761, 0, 1, 8308, 'Hero\'s Band'), +(1025761, 0, 1, 8307, 'Hero\'s Boots'), +(1025761, 0, 1, 8310, 'Hero\'s Pauldrons'), +(1025761, 0, 1, 14935, 'Heroic Skullcap'), +(1025761, 0, 1, 10136, 'High Councillor\'s Bracers'), +(1025761, 0, 1, 10144, 'High Councillor\'s Sash'), +(1025761, 0, 1, 10391, 'Hyperion Vambraces'), +(1025761, 0, 1, 15664, 'Impenetrable Helmet'), +(1025761, 0, 1, 15665, 'Impenetrable Legguards'), +(1025761, 0, 1, 14684, 'Indomitable Belt'), +(1025761, 0, 1, 12046, 'Jungle Necklace'), +(1025761, 0, 1, 15672, 'Magnificent Gauntlets'), +(1025761, 0, 1, 15674, 'Magnificent Greaves'), +(1025761, 0, 1, 10156, 'Mercurial Bracers'), +(1025761, 0, 1, 10147, 'Mighty Armsplints'), +(1025761, 0, 1, 10228, 'Nightshade Spaulders'), +(1025761, 0, 1, 15430, 'Peerless Headband'), +(1025761, 0, 1, 14323, 'Resplendent Gauntlets'), +(1025761, 0, 1, 14324, 'Resplendent Sarong'), +(1025761, 0, 1, 15325, 'Sharpshooter Harquebus'), +(1025761, 0, 1, 15278, 'Solstice Staff'), +(1025761, 0, 1, 15436, 'Supreme Bracers'), +(1025761, 0, 1, 8300, 'Traveler\'s Leggings'), +(1025761, 0, 1, 15683, 'Triumphant Girdle'), +(1025761, 0, 1, 10105, 'Wanderer\'s Armor'), +(1025761, 0, 1, 14863, 'Warleader\'s Gauntlets'), +(1025761, 0, 1, 14865, 'Warleader\'s Greaves'), +-- 58-62 +(1025862, 0, 1, 10256, 'Adventurer\'s Bracers'), +(1025862, 0, 1, 8283, 'Arcane Armor'), +(1025862, 0, 1, 8290, 'Arcane Robe'), +(1025862, 0, 1, 15931, 'Arcane Star'), +(1025862, 0, 1, 15987, 'Astral Orb'), +(1025862, 0, 1, 15288, 'Blasthorn Bow'), +(1025862, 0, 1, 14312, 'Celestial Crown'), +(1025862, 0, 1, 14317, 'Celestial Silk Robes'), +(1025862, 0, 1, 14308, 'Celestial Tunic'), +(1025862, 0, 1, 10379, 'Commander\'s Helm'), +(1025862, 0, 1, 10383, 'Commander\'s Pauldrons'), +(1025862, 0, 1, 10217, 'Elegant Leggings'), +(1025862, 0, 1, 14330, 'Eternal Bindings'), +(1025862, 0, 1, 14337, 'Eternal Cord'), +(1025862, 0, 1, 14976, 'Exalted Gauntlets'), +(1025862, 0, 1, 15239, 'Felstone Reaver'), +(1025862, 0, 1, 15266, 'Fierce Mauler'), +(1025862, 0, 1, 14966, 'Glorious Breastplate'), +(1025862, 0, 1, 15194, 'Grand Legguards'), +(1025862, 0, 1, 8309, 'Hero\'s Leggings'), +(1025862, 0, 1, 14936, 'Heroic Legplates'), +(1025862, 0, 1, 10137, 'High Councillor\'s Boots'), +(1025862, 0, 1, 10140, 'High Councillor\'s Gloves'), +(1025862, 0, 1, 10387, 'Hyperion Girdle'), +(1025862, 0, 1, 10373, 'Imbued Plate Leggings'), +(1025862, 0, 1, 15943, 'Imbued Shield'), +(1025862, 0, 1, 15660, 'Impenetrable Breastplate'), +(1025862, 0, 1, 15667, 'Impenetrable Wall'), +(1025862, 0, 1, 14688, 'Indomitable Epaulets'), +(1025862, 0, 1, 12016, 'Jungle Ring'), +(1025862, 0, 1, 15670, 'Magnificent Helmet'), +(1025862, 0, 1, 15676, 'Magnificent Leggings'), +(1025862, 0, 1, 15677, 'Magnificent Shoulders'), +(1025862, 0, 1, 10249, 'Master\'s Cloak'), +(1025862, 0, 1, 10267, 'Masterwork Cape'), +(1025862, 0, 1, 10161, 'Mercurial Gauntlets'), +(1025862, 0, 1, 10154, 'Mercurial Girdle'), +(1025862, 0, 1, 10155, 'Mercurial Greaves'), +(1025862, 0, 1, 10146, 'Mighty Boots'), +(1025862, 0, 1, 10149, 'Mighty Gauntlets'), +(1025862, 0, 1, 10226, 'Nightshade Helmet'), +(1025862, 0, 1, 15433, 'Peerless Armor'), +(1025862, 0, 1, 11979, 'Peridot Circle'), +(1025862, 0, 1, 14325, 'Resplendent Epaulets'), +(1025862, 0, 1, 15437, 'Supreme Cape'), +(1025862, 0, 1, 15434, 'Supreme Sash'), +(1025862, 0, 1, 8296, 'Traveler\'s Jerkin'), +(1025862, 0, 1, 15679, 'Triumphant Bracers'), +(1025862, 0, 1, 14868, 'Warleader\'s Shoulders'), +-- 59-63 +(1025963, 0, 1, 10259, 'Adventurer\'s Belt'), +(1025963, 0, 1, 10257, 'Adventurer\'s Boots'), +(1025963, 0, 1, 15220, 'Battlefell Sabre'), +(1025963, 0, 1, 10382, 'Commander\'s Leggings'), +(1025963, 0, 1, 15246, 'Demon Blade'), +(1025963, 0, 1, 10215, 'Elegant Robes'), +(1025963, 0, 1, 15940, 'Elegant Scepter'), +(1025963, 0, 1, 10218, 'Elegant Tunic'), +(1025963, 0, 1, 14461, 'Elunarian Handgrips'), +(1025963, 0, 1, 14462, 'Elunarian Sarong'), +(1025963, 0, 1, 14463, 'Elunarian Spaulders'), +(1025963, 0, 1, 14329, 'Eternal Boots'), +(1025963, 0, 1, 14981, 'Exalted Epaulets'), +(1025963, 0, 1, 15195, 'Grand Breastplate'), +(1025963, 0, 1, 15193, 'Grand Crown'), +(1025963, 0, 1, 12036, 'Granite Necklace'), +(1025963, 0, 1, 12005, 'Granite Ring'), +(1025963, 0, 1, 8303, 'Hero\'s Breastplate'), +(1025963, 0, 1, 8313, 'Hero\'s Buckler'), +(1025963, 0, 1, 14931, 'Heroic Armor'), +(1025963, 0, 1, 15887, 'Heroic Guard'), +(1025963, 0, 1, 10139, 'High Councillor\'s Circlet'), +(1025963, 0, 1, 10142, 'High Councillor\'s Mantle'), +(1025963, 0, 1, 10386, 'Hyperion Gauntlets'), +(1025963, 0, 1, 10385, 'Hyperion Greaves'), +(1025963, 0, 1, 10368, 'Imbued Plate Armor'), +(1025963, 0, 1, 14681, 'Indomitable Boots'), +(1025963, 0, 1, 14685, 'Indomitable Gauntlets'), +(1025963, 0, 1, 14687, 'Indomitable Leggings'), +(1025963, 0, 1, 15669, 'Magnificent Breastplate'), +(1025963, 0, 1, 15675, 'Magnificent Guard'), +(1025963, 0, 1, 10255, 'Master\'s Belt'), +(1025963, 0, 1, 10248, 'Master\'s Bracers'), +(1025963, 0, 1, 10265, 'Masterwork Bracers'), +(1025963, 0, 1, 10269, 'Masterwork Girdle'), +(1025963, 0, 1, 10160, 'Mercurial Circlet'), +(1025963, 0, 1, 10163, 'Mercurial Pauldrons'), +(1025963, 0, 1, 10150, 'Mighty Helmet'), +(1025963, 0, 1, 10153, 'Mighty Spaulders'), +(1025963, 0, 1, 10227, 'Nightshade Leggings'), +(1025963, 0, 1, 14322, 'Resplendent Circlet'), +(1025963, 0, 1, 15257, 'Shin Blade'), +(1025963, 0, 1, 14866, 'Warleader\'s Crown'), +(1025963, 0, 1, 14867, 'Warleader\'s Leggings'), +(1025963, 0, 1, 14815, 'Warstrike Gauntlets'), +(1025963, 0, 1, 14816, 'Warstrike Legguards'), +(1025963, 0, 1, 14809, 'Warstrike Sabatons'), +(1025963, 0, 1, 14817, 'Warstrike Shoulder Pads'), +-- 60-64 +(1026063, 0, 1, 10261, 'Adventurer\'s Bandana'), +(1026063, 0, 1, 10260, 'Adventurer\'s Gloves'), +(1026063, 0, 1, 10263, 'Adventurer\'s Shoulders'), +(1026063, 0, 1, 15267, 'Brutehammer'), +(1026063, 0, 1, 10378, 'Commander\'s Armor'), +(1026063, 0, 1, 15273, 'Death Striker'), +(1026063, 0, 1, 10366, 'Demon Guard'), +(1026063, 0, 1, 14460, 'Elunarian Diadem'), +(1026063, 0, 1, 14333, 'Eternal Gloves'), +(1026063, 0, 1, 14334, 'Eternal Sarong'), +(1026063, 0, 1, 14335, 'Eternal Spaulders'), +(1026063, 0, 1, 14980, 'Exalted Legplates'), +(1026063, 0, 1, 14978, 'Exalted Sabatons'), +(1026063, 0, 1, 15296, 'Hawkeye Bow'), +(1026063, 0, 1, 10141, 'High Councillor\'s Pants'), +(1026063, 0, 1, 10388, 'Hyperion Helm'), +(1026063, 0, 1, 10390, 'Hyperion Pauldrons'), +(1026063, 0, 1, 14686, 'Indomitable Headdress'), +(1026063, 0, 1, 10247, 'Master\'s Boots'), +(1026063, 0, 1, 10251, 'Master\'s Gloves'), +(1026063, 0, 1, 10250, 'Master\'s Hat'), +(1026063, 0, 1, 10253, 'Master\'s Mantle'), +(1026063, 0, 1, 10270, 'Masterwork Boots'), +(1026063, 0, 1, 10272, 'Masterwork Circlet'), +(1026063, 0, 1, 10268, 'Masterwork Gauntlets'), +(1026063, 0, 1, 10274, 'Masterwork Pauldrons'), +(1026063, 0, 1, 10162, 'Mercurial Legguards'), +(1026063, 0, 1, 10152, 'Mighty Leggings'), +(1026063, 0, 1, 10220, 'Nightshade Tunic'), +(1026063, 0, 1, 15988, 'Resplendent Orb'), +(1026063, 0, 1, 14326, 'Resplendent Robes'), +(1026063, 0, 1, 14318, 'Resplendent Tunic'), +(1026063, 0, 1, 15438, 'Supreme Gloves'), +(1026063, 0, 1, 15440, 'Supreme Leggings'), +(1026063, 0, 1, 15435, 'Supreme Shoes'), +(1026063, 0, 1, 15441, 'Supreme Shoulders'), +(1026063, 0, 1, 15682, 'Triumphant Gauntlets'), +(1026063, 0, 1, 15685, 'Triumphant Legplates'), +(1026063, 0, 1, 15678, 'Triumphant Sabatons'), +(1026063, 0, 1, 15686, 'Triumphant Shoulder Pads'), +(1026063, 0, 1, 11992, 'Vermilion Band'), +(1026063, 0, 1, 12027, 'Vermilion Necklace'), +(1026063, 0, 1, 14862, 'Warleader\'s Breastplate'), +(1026063, 0, 1, 15991, 'Warleader\'s Shield'), +(1026063, 0, 1, 14814, 'Warstrike Helmet'), +-- 61+ +(1026163, 0, 1, 10262, 'Adventurer\'s Legguards'), +(1026163, 0, 1, 15247, 'Bloodstrike Dagger'), +(1026163, 0, 1, 15240, 'Demon\'s Claw'), +(1026163, 0, 1, 12058, 'Demonic Bone Ring'), +(1026163, 0, 1, 14464, 'Elunarian Silk Robes'), +(1026163, 0, 1, 15968, 'Elunarian Sphere'), +(1026163, 0, 1, 14456, 'Elunarian Vest'), +(1026163, 0, 1, 14332, 'Eternal Crown'), +(1026163, 0, 1, 14979, 'Exalted Helmet'), +(1026163, 0, 1, 10143, 'High Councillor\'s Robe'), +(1026163, 0, 1, 15941, 'High Councillor\'s Scepter'), +(1026163, 0, 1, 10135, 'High Councillor\'s Tunic'), +(1026163, 0, 1, 10389, 'Hyperion Legplates'), +(1026163, 0, 1, 14680, 'Indomitable Vest'), +(1026163, 0, 1, 15283, 'Lunar Wand'), +(1026163, 0, 1, 10252, 'Master\'s Leggings'), +(1026163, 0, 1, 10273, 'Masterwork Legplates'), +(1026163, 0, 1, 10157, 'Mercurial Breastplate'), +(1026163, 0, 1, 10158, 'Mercurial Guard'), +(1026163, 0, 1, 10151, 'Mighty Tunic'), +(1026163, 0, 1, 11980, 'Opal Ring'), +(1026163, 0, 1, 15439, 'Supreme Crown'), +(1026163, 0, 1, 15684, 'Triumphant Skullcap'), +(1026163, 0, 1, 14812, 'Warstrike Buckler'), +(1026163, 0, 1, 14811, 'Warstrike Chestguard'), +-- 62+ +(1026263, 0, 1, 10264, 'Adventurer\'s Tunic'), +(1026263, 0, 1, 15289, 'Archstrike Bow'), +(1026263, 0, 1, 15258, 'Divine Warblade'), +(1026263, 0, 1, 14328, 'Eternal Chestguard'), +(1026263, 0, 1, 15989, 'Eternal Rod'), +(1026263, 0, 1, 14336, 'Eternal Wraps'), +(1026263, 0, 1, 14975, 'Exalted Harness'), +(1026263, 0, 1, 14982, 'Exalted Shield'), +(1026263, 0, 1, 15221, 'Holy War Sword'), +(1026263, 0, 1, 10384, 'Hyperion Armor'), +(1026263, 0, 1, 10367, 'Hyperion Shield'), +(1026263, 0, 1, 10254, 'Master\'s Robe'), +(1026263, 0, 1, 15942, 'Master\'s Rod'), +(1026263, 0, 1, 10246, 'Master\'s Vest'), +(1026263, 0, 1, 10266, 'Masterwork Breastplate'), +(1026263, 0, 1, 10271, 'Masterwork Shield'), +(1026263, 0, 1, 12017, 'Prismatic Band'), +(1026263, 0, 1, 12048, 'Prismatic Pendant'), +(1026263, 0, 1, 15442, 'Supreme Breastplate'), +(1026263, 0, 1, 15680, 'Triumphant Chestpiece'), +(1026263, 0, 1, 15687, 'Triumphant Shield'), +-- TBC Greens +-- 58-60 +(1125860, 0, 1, 25296, 'Absorption Dagger'), +(1125860, 0, 1, 25324, 'Angerstaff'), +(1125860, 0, 1, 25058, 'Anglesite Choker'), +(1125860, 0, 1, 25240, 'Azerothian Longbow'), +(1125860, 0, 1, 28531, 'Barbed Shrike'), +(1125860, 0, 1, 24700, 'Bonechewer Bands'), +(1125860, 0, 1, 24695, 'Bonechewer Chestpiece'), +(1125860, 0, 1, 24693, 'Bonechewer Pelt-Girdle'), +(1125860, 0, 1, 24698, 'Bonechewer Ripleggings'), +(1125860, 0, 1, 24699, 'Bonechewer Shoulderguards'), +(1125860, 0, 1, 24694, 'Bonechewer Shredboots'), +(1125860, 0, 1, 24697, 'Bonechewer Skincloak'), +(1125860, 0, 1, 24696, 'Bonechewer Spikegloves'), +(1125860, 0, 1, 25114, 'Doomsayer\'s Mace'), +(1125860, 0, 1, 25086, 'Dreamseeker Dandelion'), +(1125860, 0, 1, 24920, 'Grimscale Armor'), +(1125860, 0, 1, 24918, 'Grimscale Belt'), +(1125860, 0, 1, 24921, 'Grimscale Gauntlets'), +(1125860, 0, 1, 24922, 'Grimscale Helm'), +(1125860, 0, 1, 24923, 'Grimscale Legguards'), +(1125860, 0, 1, 24924, 'Grimscale Pauldrons'), +(1125860, 0, 1, 24919, 'Grimscale Sabatons'), +(1125860, 0, 1, 24925, 'Grimscale Vambraces'), +(1125860, 0, 1, 25198, 'Karaborian Battle Axe'), +(1125860, 0, 1, 25268, 'Lead-Slug Shotgun'), +(1125860, 0, 1, 25100, 'Liege Blade'), +(1125860, 0, 1, 25212, 'Lucky Strike Axe'), +(1125860, 0, 1, 25282, 'Mahogany Wand'), +(1125860, 0, 1, 25310, 'Naaru Lightmace'), +(1125860, 0, 1, 25072, 'Northman\'s Shield'), +(1125860, 0, 1, 24582, 'Outlander\'s Boots'), +(1125860, 0, 1, 24588, 'Outlander\'s Bracers'), +(1125860, 0, 1, 24585, 'Outlander\'s Facewrap'), +(1125860, 0, 1, 24575, 'Outlander\'s Girdle'), +(1125860, 0, 1, 24584, 'Outlander\'s Gloves'), +(1125860, 0, 1, 24586, 'Outlander\'s Leggings'), +(1125860, 0, 1, 24587, 'Outlander\'s Pauldrons'), +(1125860, 0, 1, 24583, 'Outlander\'s Tunic'), +(1125860, 0, 1, 25170, 'Rattan Bo Staff'), +(1125860, 0, 1, 25184, 'Ravager Claws'), +(1125860, 0, 1, 25156, 'Royal Crusader Sword'), +(1125860, 0, 1, 25044, 'Rubellite Ring'), +(1125860, 0, 1, 25128, 'Shining Mace'), +(1125860, 0, 1, 25030, 'Silky Velvet Cloak'), +(1125860, 0, 1, 25142, 'Telaari Longblade'), +(1125860, 0, 1, 25254, 'Tower Crossbow'), +(1125860, 0, 1, 24813, 'Unyielding Bindings'), +(1125860, 0, 1, 24808, 'Unyielding Chain Vest'), +(1125860, 0, 1, 24809, 'Unyielding Fists'), +(1125860, 0, 1, 24807, 'Unyielding Footwraps'), +(1125860, 0, 1, 24810, 'Unyielding Helm'), +(1125860, 0, 1, 24811, 'Unyielding Leggings'), +(1125860, 0, 1, 24812, 'Unyielding Spaulders'), +(1125860, 0, 1, 24806, 'Unyielding Waistband'), +(1125860, 0, 1, 25226, 'War Scythe'), +-- 59-61 +(1125961, 0, 1, 24926, 'Ango\'rosh Belt'), +(1125961, 0, 1, 24928, 'Ango\'rosh Breastplate'), +(1125961, 0, 1, 24929, 'Ango\'rosh Gauntlets'), +(1125961, 0, 1, 24930, 'Ango\'rosh Helm'), +(1125961, 0, 1, 24931, 'Ango\'rosh Legguards'), +(1125961, 0, 1, 24932, 'Ango\'rosh Pauldrons'), +(1125961, 0, 1, 24927, 'Ango\'rosh Sabatons'), +(1125961, 0, 1, 24933, 'Ango\'rosh Vambraces'), +(1125961, 0, 1, 25241, 'Ashenvale Longbow'), +(1125961, 0, 1, 25045, 'Azurite Ring'), +(1125961, 0, 1, 25087, 'Bleeding Eye'), +(1125961, 0, 1, 25325, 'Brutal Scar-Limb'), +(1125961, 0, 1, 25101, 'Cross Pommel Dagger'), +(1125961, 0, 1, 25283, 'Crystallized Ebony Wand'), +(1125961, 0, 1, 25073, 'Emperor Shield'), +(1125961, 0, 1, 25213, 'Fel-Touched Axe'), +(1125961, 0, 1, 24821, 'Felstone Bindings'), +(1125961, 0, 1, 24816, 'Felstone Chain Vest'), +(1125961, 0, 1, 24817, 'Felstone Gauntlets'), +(1125961, 0, 1, 24815, 'Felstone Greaves'), +(1125961, 0, 1, 24818, 'Felstone Helm'), +(1125961, 0, 1, 24819, 'Felstone Leggings'), +(1125961, 0, 1, 24820, 'Felstone Spaulders'), +(1125961, 0, 1, 24814, 'Felstone Waistband'), +(1125961, 0, 1, 25059, 'Fire Opal Collar'), +(1125961, 0, 1, 24590, 'Fireheart Boots'), +(1125961, 0, 1, 24596, 'Fireheart Bracers'), +(1125961, 0, 1, 24591, 'Fireheart Chestpiece'), +(1125961, 0, 1, 24589, 'Fireheart Girdle'), +(1125961, 0, 1, 24592, 'Fireheart Gloves'), +(1125961, 0, 1, 24594, 'Fireheart Leggings'), +(1125961, 0, 1, 24595, 'Fireheart Shoulderpads'), +(1125961, 0, 1, 24593, 'Fireheart Skullcap'), +(1125961, 0, 1, 25129, 'Giant\'s Leg Bone'), +(1125961, 0, 1, 24708, 'Haal\'eshi Bindings'), +(1125961, 0, 1, 24702, 'Haal\'eshi Boots'), +(1125961, 0, 1, 24701, 'Haal\'eshi Cord'), +(1125961, 0, 1, 24704, 'Haal\'eshi Gloves'), +(1125961, 0, 1, 24705, 'Haal\'eshi Hat'), +(1125961, 0, 1, 24703, 'Haal\'eshi Jerkin'), +(1125961, 0, 1, 24706, 'Haal\'eshi Leggings'), +(1125961, 0, 1, 24707, 'Haal\'eshi Pauldrons'), +(1125961, 0, 1, 25199, 'Knight\'s War Axe'), +(1125961, 0, 1, 25269, 'Longbeard Rifle'), +(1125961, 0, 1, 25255, 'Ram\'s Head Crossbow'), +(1125961, 0, 1, 25311, 'Revitalizing Hammer'), +(1125961, 0, 1, 25115, 'Riversong Mace'), +(1125961, 0, 1, 25157, 'Serpentlord Claymore'), +(1125961, 0, 1, 25227, 'Sha\'tari Longspear'), +(1125961, 0, 1, 25143, 'Silver Hand Blade'), +(1125961, 0, 1, 28532, 'Silver Throwing Knives'), +(1125961, 0, 1, 25031, 'Silvermoon Royal Cloak'), +(1125961, 0, 1, 25171, 'Straight Hardwood Staff'), +(1125961, 0, 1, 25185, 'Thrasher Blades'), +(1125961, 0, 1, 25297, 'Tuning Knife'), +-- 60-62 +(1126062, 0, 1, 25298, 'Combustion Dagger'), +(1126062, 0, 1, 24934, 'Darkcrest Belt'), +(1126062, 0, 1, 24941, 'Darkcrest Bracers'), +(1126062, 0, 1, 24936, 'Darkcrest Breastplate'), +(1126062, 0, 1, 24937, 'Darkcrest Gauntlets'), +(1126062, 0, 1, 24938, 'Darkcrest Helm'), +(1126062, 0, 1, 24939, 'Darkcrest Legguards'), +(1126062, 0, 1, 24940, 'Darkcrest Pauldrons'), +(1126062, 0, 1, 24935, 'Darkcrest Sabatons'), +(1126062, 0, 1, 25312, 'Glorious Scepter'), +(1126062, 0, 1, 25270, 'Gnomish Assault Rifle'), +(1126062, 0, 1, 25130, 'Gronn-Bone Club'), +(1126062, 0, 1, 25228, 'Halberd Polearm'), +(1126062, 0, 1, 25032, 'Hellfire Cloak'), +(1126062, 0, 1, 25102, 'Jaedenis Dagger'), +(1126062, 0, 1, 25200, 'Jagged Broadaxe'), +(1126062, 0, 1, 25172, 'Jinbali Warp-Staff'), +(1126062, 0, 1, 25088, 'Laughing Skull Orb'), +(1126062, 0, 1, 25214, 'Mok\'Nathal Battleaxe'), +(1126062, 0, 1, 24824, 'Netherstalker Armor'), +(1126062, 0, 1, 24822, 'Netherstalker Belt'), +(1126062, 0, 1, 24829, 'Netherstalker Bracer'), +(1126062, 0, 1, 24825, 'Netherstalker Gloves'), +(1126062, 0, 1, 24823, 'Netherstalker Greaves'), +(1126062, 0, 1, 24826, 'Netherstalker Helmet'), +(1126062, 0, 1, 24827, 'Netherstalker Legguards'), +(1126062, 0, 1, 24828, 'Netherstalker Mantle'), +(1126062, 0, 1, 25116, 'Pneumatic War Hammer'), +(1126062, 0, 1, 25326, 'Primal Lore-Staff'), +(1126062, 0, 1, 25284, 'Purpleheart Wand'), +(1126062, 0, 1, 25158, 'Skeletal Broadsword'), +(1126062, 0, 1, 25144, 'Skettis Curved Blade'), +(1126062, 0, 1, 25046, 'Spined Ring'), +(1126062, 0, 1, 24601, 'Starfire Circlet'), +(1126062, 0, 1, 24600, 'Starfire Gloves'), +(1126062, 0, 1, 24603, 'Starfire Mantle'), +(1126062, 0, 1, 24598, 'Starfire Sandals'), +(1126062, 0, 1, 24597, 'Starfire Sash'), +(1126062, 0, 1, 24602, 'Starfire Trousers'), +(1126062, 0, 1, 24599, 'Starfire Vest'), +(1126062, 0, 1, 24604, 'Starfire Wristwraps'), +(1126062, 0, 1, 25256, 'Stronghold Crossbow'), +(1126062, 0, 1, 25060, 'Sunstone Necklace'), +(1126062, 0, 1, 25242, 'Telaari Longbow'), +(1126062, 0, 1, 25074, 'Telaari Shield'), +(1126062, 0, 1, 25186, 'Vampiric Handscythes'), +(1126062, 0, 1, 24716, 'Vengeance Bands'), +(1126062, 0, 1, 24709, 'Vengeance Belt'), +(1126062, 0, 1, 24710, 'Vengeance Boots'), +(1126062, 0, 1, 24711, 'Vengeance Chestpiece'), +(1126062, 0, 1, 24712, 'Vengeance Gloves'), +(1126062, 0, 1, 24713, 'Vengeance Helm'), +(1126062, 0, 1, 24714, 'Vengeance Legguards'), +(1126062, 0, 1, 24715, 'Vengeance Pauldrons'), +(1126062, 0, 1, 28533, 'Wooden Boomerang'), +-- 61-63 +(1126163, 0, 1, 24942, 'Bloodscale Belt'), +(1126163, 0, 1, 24949, 'Bloodscale Bracers'), +(1126163, 0, 1, 24944, 'Bloodscale Breastplate'), +(1126163, 0, 1, 24945, 'Bloodscale Gauntlets'), +(1126163, 0, 1, 24946, 'Bloodscale Helm'), +(1126163, 0, 1, 24947, 'Bloodscale Legguards'), +(1126163, 0, 1, 24948, 'Bloodscale Pauldrons'), +(1126163, 0, 1, 24943, 'Bloodscale Sabatons'), +(1126163, 0, 1, 25257, 'Citadel Crossbow'), +(1126163, 0, 1, 25313, 'Cold-Iron Scepter'), +(1126163, 0, 1, 25271, 'Croc-Hunter\'s Rifle'), +(1126163, 0, 1, 24724, 'Dreghood Bands'), +(1126163, 0, 1, 24717, 'Dreghood Belt'), +(1126163, 0, 1, 24718, 'Dreghood Boots'), +(1126163, 0, 1, 24719, 'Dreghood Chestpiece'), +(1126163, 0, 1, 24721, 'Dreghood Cowl'), +(1126163, 0, 1, 24720, 'Dreghood Gloves'), +(1126163, 0, 1, 24723, 'Dreghood Pauldrons'), +(1126163, 0, 1, 24722, 'Dreghood Trousers'), +(1126163, 0, 1, 28534, 'Fel Tipped Dart'), +(1126163, 0, 1, 25117, 'Flanged Battle Mace'), +(1126163, 0, 1, 25327, 'Frenzied Staff'), +(1126163, 0, 1, 25075, 'Hardened Steel Shield'), +(1126163, 0, 1, 25131, 'Hateful Bludgeon'), +(1126163, 0, 1, 25061, 'Hiddenite Necklace'), +(1126163, 0, 1, 24606, 'Laughing Skull Boot'), +(1126163, 0, 1, 24612, 'Laughing Skull Bracelets'), +(1126163, 0, 1, 24609, 'Laughing Skull Cap'), +(1126163, 0, 1, 24608, 'Laughing Skull Gloves'), +(1126163, 0, 1, 24610, 'Laughing Skull Pants'), +(1126163, 0, 1, 24611, 'Laughing Skull Shoulderpads'), +(1126163, 0, 1, 24607, 'Laughing Skull Tunic'), +(1126163, 0, 1, 24605, 'Laughing Skull Waistguard'), +(1126163, 0, 1, 24830, 'Nexus-Strider Belt'), +(1126163, 0, 1, 24837, 'Nexus-Strider Bracer'), +(1126163, 0, 1, 24832, 'Nexus-Strider Breastplate'), +(1126163, 0, 1, 24833, 'Nexus-Strider Gloves'), +(1126163, 0, 1, 24831, 'Nexus-Strider Greaves'), +(1126163, 0, 1, 24834, 'Nexus-Strider Helmet'), +(1126163, 0, 1, 24835, 'Nexus-Strider Legwraps'), +(1126163, 0, 1, 24836, 'Nexus-Strider Mantle'), +(1126163, 0, 1, 25103, 'Nightstalker Dagger'), +(1126163, 0, 1, 25229, 'Partisan Polearm'), +(1126163, 0, 1, 25201, 'Reaver\'s Sickle'), +(1126163, 0, 1, 25033, 'Scavenger\'s Cloak'), +(1126163, 0, 1, 25187, 'Shekketh Talons'), +(1126163, 0, 1, 25299, 'Siphoning Dagger'), +(1126163, 0, 1, 25215, 'Spiked Battle Axe'), +(1126163, 0, 1, 25089, 'Supplicant\'s Rod'), +(1126163, 0, 1, 25047, 'Tourmaline Loop'), +(1126163, 0, 1, 25243, 'Windtalker Bow'), +-- 62-64 +(1126264, 0, 1, 28535, 'Amani Throwing Axe'), +(1126264, 0, 1, 25104, 'Anzac Dagger'), +(1126264, 0, 1, 25118, 'Battle Star'), +(1126264, 0, 1, 24950, 'Bogslayer Belt'), +(1126264, 0, 1, 24957, 'Bogslayer Bracers'), +(1126264, 0, 1, 24952, 'Bogslayer Breastplate'), +(1126264, 0, 1, 24953, 'Bogslayer Gauntlets'), +(1126264, 0, 1, 24954, 'Bogslayer Helm'), +(1126264, 0, 1, 24955, 'Bogslayer Legplates'), +(1126264, 0, 1, 24956, 'Bogslayer Pauldrons'), +(1126264, 0, 1, 24951, 'Bogslayer Sabatons'), +(1126264, 0, 1, 25314, 'Ceremonial Hammer'), +(1126264, 0, 1, 24732, 'Dementia Armguards'), +(1126264, 0, 1, 24726, 'Dementia Boots'), +(1126264, 0, 1, 24725, 'Dementia Cord'), +(1126264, 0, 1, 24728, 'Dementia Gloves'), +(1126264, 0, 1, 24729, 'Dementia Hood'), +(1126264, 0, 1, 24731, 'Dementia Shoulderguards'), +(1126264, 0, 1, 24730, 'Dementia Trousers'), +(1126264, 0, 1, 24727, 'Dementia Vest'), +(1126264, 0, 1, 25034, 'Elementalist Cloak'), +(1126264, 0, 1, 25328, 'Faerie-Kind Staff'), +(1126264, 0, 1, 25174, 'Hanbo Staff'), +(1126264, 0, 1, 25202, 'Kingly Axe'), +(1126264, 0, 1, 25146, 'Light-Etched Longsword'), +(1126264, 0, 1, 25300, 'Lightning Dagger'), +(1126264, 0, 1, 25216, 'Ogre Splitting Axe'), +(1126264, 0, 1, 25272, 'PC-54 Shotgun'), +(1126264, 0, 1, 25258, 'Repeater Crossbow'), +(1126264, 0, 1, 25076, 'Screaming Shield'), +(1126264, 0, 1, 25090, 'Slavehandler Rod'), +(1126264, 0, 1, 25048, 'Smoky Quartz Ring'), +(1126264, 0, 1, 25188, 'Spleenripper Claws'), +(1126264, 0, 1, 25132, 'Thrallmar War Hammer'), +(1126264, 0, 1, 25160, 'Vengeance Blade'), +(1126264, 0, 1, 24613, 'Vindicator Belt'), +(1126264, 0, 1, 24614, 'Vindicator Boots'), +(1126264, 0, 1, 24620, 'Vindicator Bracers'), +(1126264, 0, 1, 24617, 'Vindicator Cap'), +(1126264, 0, 1, 24616, 'Vindicator Gloves'), +(1126264, 0, 1, 24618, 'Vindicator Pants'), +(1126264, 0, 1, 24619, 'Vindicator Shoulderpads'), +(1126264, 0, 1, 24615, 'Vindicator Tunic'), +(1126264, 0, 1, 25244, 'Viper Bow'), +(1126264, 0, 1, 25230, 'Voulge Blade'), +(1126264, 0, 1, 24840, 'Wrathfin Armor'), +(1126264, 0, 1, 24845, 'Wrathfin Bindings'), +(1126264, 0, 1, 24841, 'Wrathfin Gloves'), +(1126264, 0, 1, 24839, 'Wrathfin Greaves'), +(1126264, 0, 1, 24842, 'Wrathfin Helmet'), +(1126264, 0, 1, 24843, 'Wrathfin Legguards'), +(1126264, 0, 1, 24844, 'Wrathfin Mantle'), +(1126264, 0, 1, 24838, 'Wrathfin Waistband'), +(1126264, 0, 1, 25286, 'Yew Wand'), +(1126264, 0, 1, 25062, 'Zircon Amulet'), +-- 63-65 +(1126365, 0, 1, 25105, 'Arachnid Dagger'), +(1126365, 0, 1, 25203, 'Chipped Woodchopper'), +(1126365, 0, 1, 25259, 'Collapsible Crossbow'), +(1126365, 0, 1, 25175, 'Demoniac Longstaff'), +(1126365, 0, 1, 25161, 'Dragon Wing Blade'), +(1126365, 0, 1, 25231, 'Fel-Wrought Halberd'), +(1126365, 0, 1, 24848, 'Fenclaw Armor'), +(1126365, 0, 1, 24853, 'Fenclaw Bindings'), +(1126365, 0, 1, 24849, 'Fenclaw Fists'), +(1126365, 0, 1, 24847, 'Fenclaw Footwraps'), +(1126365, 0, 1, 24850, 'Fenclaw Helm'), +(1126365, 0, 1, 24851, 'Fenclaw Legguards'), +(1126365, 0, 1, 24852, 'Fenclaw Mantle'), +(1126365, 0, 1, 24846, 'Fenclaw Waistband'), +(1126365, 0, 1, 25189, 'Ironspine Point'), +(1126365, 0, 1, 28536, 'Jagged Guillotine'), +(1126365, 0, 1, 24965, 'Khan\'aish Bracers'), +(1126365, 0, 1, 24960, 'Khan\'aish Breastplate'), +(1126365, 0, 1, 24964, 'Khan\'aish Epaulets'), +(1126365, 0, 1, 24958, 'Khan\'aish Girdle'), +(1126365, 0, 1, 24961, 'Khan\'aish Gloves'), +(1126365, 0, 1, 24959, 'Khan\'aish Greaves'), +(1126365, 0, 1, 24962, 'Khan\'aish Helmet'), +(1126365, 0, 1, 24963, 'Khan\'aish Legplates'), +(1126365, 0, 1, 25287, 'Magician\'s Wand'), +(1126365, 0, 1, 25091, 'Mistyreed Torch'), +(1126365, 0, 1, 25077, 'Modani War-Shield'), +(1126365, 0, 1, 25063, 'Multi-Colored Beads'), +(1126365, 0, 1, 25245, 'Razorsong Bow'), +(1126365, 0, 1, 25315, 'Restorative Mace'), +(1126365, 0, 1, 25273, 'Sawed-Off Shotgun'), +(1126365, 0, 1, 25049, 'Scheelite Ring'), +(1126365, 0, 1, 25301, 'Shattering Dagger'), +(1126365, 0, 1, 25035, 'Silver-Lined Cloak'), +(1126365, 0, 1, 25119, 'Silvermoon War-Mace'), +(1126365, 0, 1, 25147, 'Skystrider Katana'), +(1126365, 0, 1, 24627, 'Slavehandler Amice'), +(1126365, 0, 1, 24621, 'Slavehandler Belt'), +(1126365, 0, 1, 24625, 'Slavehandler Cap'), +(1126365, 0, 1, 24622, 'Slavehandler Footpads'), +(1126365, 0, 1, 24624, 'Slavehandler Handwraps'), +(1126365, 0, 1, 24623, 'Slavehandler Jerkin'), +(1126365, 0, 1, 24626, 'Slavehandler Pants'), +(1126365, 0, 1, 24628, 'Slavehandler Wristguards'), +(1126365, 0, 1, 25133, 'Stormwind Maul'), +(1126365, 0, 1, 25217, 'Sundering Axe'), +(1126365, 0, 1, 24740, 'Sunroc Armguards'), +(1126365, 0, 1, 24734, 'Sunroc Boots'), +(1126365, 0, 1, 24735, 'Sunroc Chestpiece'), +(1126365, 0, 1, 24736, 'Sunroc Gloves'), +(1126365, 0, 1, 24737, 'Sunroc Mask'), +(1126365, 0, 1, 24738, 'Sunroc Pants'), +(1126365, 0, 1, 24739, 'Sunroc Shoulderguards'), +(1126365, 0, 1, 24733, 'Sunroc Waistband'), +(1126365, 0, 1, 25329, 'Tranquility Staff'), +-- 64-66 +(1126466, 0, 1, 25064, 'Amethyst Pendant'), +(1126466, 0, 1, 25260, 'Archer\'s Crossbow'), +(1126466, 0, 1, 25148, 'Bone Collector Sword'), +(1126466, 0, 1, 25036, 'Boulderfist Cloak'), +(1126466, 0, 1, 25274, 'Cliffjumper Shotgun'), +(1126466, 0, 1, 25106, 'Cobra Shortblade'), +(1126466, 0, 1, 25204, 'Colossal War Axe'), +(1126466, 0, 1, 25288, 'Conjurer\'s Wand'), +(1126466, 0, 1, 25092, 'Consortium Crystal'), +(1126466, 0, 1, 25162, 'Darkened Broadsword'), +(1126466, 0, 1, 24635, 'Feralfen Amice'), +(1126466, 0, 1, 24636, 'Feralfen Cuffs'), +(1126466, 0, 1, 24632, 'Feralfen Hand'), +(1126466, 0, 1, 24633, 'Feralfen Hood'), +(1126466, 0, 1, 24631, 'Feralfen Jerkin'), +(1126466, 0, 1, 24634, 'Feralfen Pants'), +(1126466, 0, 1, 24630, 'Feralfen Sandals'), +(1126466, 0, 1, 24629, 'Feralfen Sash'), +(1126466, 0, 1, 25134, 'Highmountain Hammer'), +(1126466, 0, 1, 24854, 'Marshcreeper Belt'), +(1126466, 0, 1, 24861, 'Marshcreeper Bracelets'), +(1126466, 0, 1, 24856, 'Marshcreeper Fen-Vest'), +(1126466, 0, 1, 24857, 'Marshcreeper Gloves'), +(1126466, 0, 1, 24858, 'Marshcreeper Helm'), +(1126466, 0, 1, 24859, 'Marshcreeper Leggings'), +(1126466, 0, 1, 24860, 'Marshcreeper Mantle'), +(1126466, 0, 1, 24855, 'Marshcreeper Sludgeboots'), +(1126466, 0, 1, 25050, 'Moldavite Ring'), +(1126466, 0, 1, 24748, 'Ranger Armguards'), +(1126466, 0, 1, 24741, 'Ranger Belt'), +(1126466, 0, 1, 24742, 'Ranger Boots'), +(1126466, 0, 1, 24744, 'Ranger Gloves'), +(1126466, 0, 1, 24745, 'Ranger Hat'), +(1126466, 0, 1, 24743, 'Ranger Jerkin'), +(1126466, 0, 1, 24746, 'Ranger Pants'), +(1126466, 0, 1, 24747, 'Ranger Pauldrons'), +(1126466, 0, 1, 25120, 'Rockshard Club'), +(1126466, 0, 1, 25218, 'Silver-Edged Axe'), +(1126466, 0, 1, 25302, 'Soul-Drain Dagger'), +(1126466, 0, 1, 25316, 'Spirit-Clad Mace'), +(1126466, 0, 1, 25330, 'Starshine Staff'), +(1126466, 0, 1, 25176, 'Taiji Quarterstaff'), +(1126466, 0, 1, 24968, 'Talonguard Armor'), +(1126466, 0, 1, 24973, 'Talonguard Bracers'), +(1126466, 0, 1, 24972, 'Talonguard Epaulets'), +(1126466, 0, 1, 24966, 'Talonguard Girdle'), +(1126466, 0, 1, 24969, 'Talonguard Gloves'), +(1126466, 0, 1, 24967, 'Talonguard Greaves'), +(1126466, 0, 1, 24970, 'Talonguard Helmet'), +(1126466, 0, 1, 24971, 'Talonguard Legplates'), +(1126466, 0, 1, 25246, 'Thalassian Compound Bow'), +(1126466, 0, 1, 25232, 'War Glaive'), +(1126466, 0, 1, 25190, 'Wight\'s Claws'), +(1126466, 0, 1, 28537, 'Wildhammer Throwing Axe'), +(1126466, 0, 1, 25078, 'Zangari Shield'), +-- 65-67 +(1126567, 0, 1, 25303, 'Amplifying Blade'), +(1126567, 0, 1, 25149, 'Baron\'s Broadsword'), +(1126567, 0, 1, 25233, 'Battle Scythe'), +(1126567, 0, 1, 24863, 'Blood Knight Boots'), +(1126567, 0, 1, 24869, 'Blood Knight Bracers'), +(1126567, 0, 1, 24864, 'Blood Knight Breastplate'), +(1126567, 0, 1, 24865, 'Blood Knight Gauntlets'), +(1126567, 0, 1, 24862, 'Blood Knight Girdle'), +(1126567, 0, 1, 24867, 'Blood Knight Greaves'), +(1126567, 0, 1, 24866, 'Blood Knight Helm'), +(1126567, 0, 1, 24868, 'Blood Knight Pauldrons'), +(1126567, 0, 1, 25051, 'Blue Topaz Band'), +(1126567, 0, 1, 25135, 'Clefthoof Mace'), +(1126567, 0, 1, 24751, 'Daggerfen Battlevest'), +(1126567, 0, 1, 24749, 'Daggerfen Belt'), +(1126567, 0, 1, 24756, 'Daggerfen Bindings'), +(1126567, 0, 1, 24750, 'Daggerfen Boots'), +(1126567, 0, 1, 24753, 'Daggerfen Cowl'), +(1126567, 0, 1, 24752, 'Daggerfen Gloves'), +(1126567, 0, 1, 24755, 'Daggerfen Pauldrons'), +(1126567, 0, 1, 24754, 'Daggerfen Stitchpants'), +(1126567, 0, 1, 25107, 'Draconic Dagger'), +(1126567, 0, 1, 25275, 'Dragonbreath Musket'), +(1126567, 0, 1, 25191, 'Dread Fangs'), +(1126567, 0, 1, 25121, 'Dreaded Mace'), +(1126567, 0, 1, 25163, 'Elexorien Blade'), +(1126567, 0, 1, 25247, 'Expert\'s Bow'), +(1126567, 0, 1, 28538, 'Forked Shuriken'), +(1126567, 0, 1, 25317, 'Lesser Sledgemace'), +(1126567, 0, 1, 25289, 'Majestic Wand'), +(1126567, 0, 1, 25261, 'Mighty Crossbow'), +(1126567, 0, 1, 24637, 'Mistyreed Belt'), +(1126567, 0, 1, 24638, 'Mistyreed Boots'), +(1126567, 0, 1, 24644, 'Mistyreed Bracers'), +(1126567, 0, 1, 24640, 'Mistyreed Gloves'), +(1126567, 0, 1, 24641, 'Mistyreed Hood'), +(1126567, 0, 1, 24642, 'Mistyreed Pants'), +(1126567, 0, 1, 24643, 'Mistyreed Shoulderpads'), +(1126567, 0, 1, 24639, 'Mistyreed Tunic'), +(1126567, 0, 1, 25079, 'Outland Shield'), +(1126567, 0, 1, 25037, 'Patched Cape'), +(1126567, 0, 1, 24976, 'Reaver Armor'), +(1126567, 0, 1, 24981, 'Reaver Bracers'), +(1126567, 0, 1, 24980, 'Reaver Epaulets'), +(1126567, 0, 1, 24974, 'Reaver Girdle'), +(1126567, 0, 1, 24977, 'Reaver Gloves'), +(1126567, 0, 1, 24975, 'Reaver Greaves'), +(1126567, 0, 1, 24978, 'Reaver Helmet'), +(1126567, 0, 1, 24979, 'Reaver Legplates'), +(1126567, 0, 1, 25219, 'Rending Claw'), +(1126567, 0, 1, 25093, 'Shadow Council Orb'), +(1126567, 0, 1, 25205, 'Silvermoon Crescent Axe'), +(1126567, 0, 1, 25177, 'Tanjo Staff'), +(1126567, 0, 1, 25065, 'Turquoise Brooch'), +(1126567, 0, 1, 25331, 'Vengeance Staff'), +-- 66-68 +(1126668, 0, 1, 25318, 'Ancestral Hammer'), +(1126668, 0, 1, 24645, 'Astralaan Belt'), +(1126668, 0, 1, 24646, 'Astralaan Boots'), +(1126668, 0, 1, 24652, 'Astralaan Bracer'), +(1126668, 0, 1, 24648, 'Astralaan Gloves'), +(1126668, 0, 1, 24649, 'Astralaan Headdress'), +(1126668, 0, 1, 24650, 'Astralaan Pants'), +(1126668, 0, 1, 24647, 'Astralaan Robe'), +(1126668, 0, 1, 24651, 'Astralaan Shoulderpads'), +(1126668, 0, 1, 25178, 'Bata Staff'), +(1126668, 0, 1, 25262, 'Battle Damaged Crossbow'), +(1126668, 0, 1, 25206, 'Berserker Axe'), +(1126668, 0, 1, 25136, 'Blood Stained Hammer'), +(1126668, 0, 1, 24984, 'Boulderfist Armor'), +(1126668, 0, 1, 24982, 'Boulderfist Belt'), +(1126668, 0, 1, 24989, 'Boulderfist Bracers'), +(1126668, 0, 1, 24988, 'Boulderfist Epaulets'), +(1126668, 0, 1, 24985, 'Boulderfist Gloves'), +(1126668, 0, 1, 24983, 'Boulderfist Greaves'), +(1126668, 0, 1, 24986, 'Boulderfist Helm'), +(1126668, 0, 1, 24987, 'Boulderfist Legplates'), +(1126668, 0, 1, 25164, 'Crude Umbrafen Blade'), +(1126668, 0, 1, 25304, 'Destructo-Blade'), +(1126668, 0, 1, 25094, 'Eldr\'naan Scepter'), +(1126668, 0, 1, 25038, 'Forest Shroud'), +(1126668, 0, 1, 25220, 'Glorious War-Axe'), +(1126668, 0, 1, 25108, 'Grave Keeper Knife'), +(1126668, 0, 1, 25192, 'Gutrippers'), +(1126668, 0, 1, 25052, 'Hauyne Ring'), +(1126668, 0, 1, 25150, 'Honor Hold Saber'), +(1126668, 0, 1, 24870, 'Ironspine Belt'), +(1126668, 0, 1, 24877, 'Ironspine Bracelets'), +(1126668, 0, 1, 24872, 'Ironspine Chain Vest'), +(1126668, 0, 1, 24873, 'Ironspine Gloves'), +(1126668, 0, 1, 24871, 'Ironspine Greaves'), +(1126668, 0, 1, 24874, 'Ironspine Helm'), +(1126668, 0, 1, 24875, 'Ironspine Legguards'), +(1126668, 0, 1, 24876, 'Ironspine Shoulderguards'), +(1126668, 0, 1, 25122, 'Khorium Plated Bludgeon'), +(1126668, 0, 1, 25066, 'Pink Sapphire Necklace'), +(1126668, 0, 1, 28539, 'Razor-Edged Boomerang'), +(1126668, 0, 1, 25332, 'Reflective Staff'), +(1126668, 0, 1, 25290, 'Solitaire Wand'), +(1126668, 0, 1, 25080, 'Spell-Breaker Shield'), +(1126668, 0, 1, 25248, 'Talbuk Hunting Bow'), +(1126668, 0, 1, 25276, 'Tauren Runed Musket'), +(1126668, 0, 1, 25234, 'Telaari Polearm'), +(1126668, 0, 1, 24764, 'Umbrafen Bindings'), +(1126668, 0, 1, 24758, 'Umbrafen Boots'), +(1126668, 0, 1, 24762, 'Umbrafen Britches'), +(1126668, 0, 1, 24761, 'Umbrafen Cap'), +(1126668, 0, 1, 24760, 'Umbrafen Gloves'), +(1126668, 0, 1, 24763, 'Umbrafen Shoulderguards'), +(1126668, 0, 1, 24759, 'Umbrafen Tunic'), +(1126668, 0, 1, 24757, 'Umbrafen Waistband'), +-- 67-69 +(1126769, 0, 1, 28540, 'Arakkoa Talon-Axe'), +(1126769, 0, 1, 25095, 'Archmage Orb'), +(1126769, 0, 1, 25151, 'Assassins\' Short Blade'), +(1126769, 0, 1, 25263, 'Assassins\' Silent Crossbow'), +(1126769, 0, 1, 25081, 'Bayeaux Shield'), +(1126769, 0, 1, 25123, 'Boneshredder Mace'), +(1126769, 0, 1, 25165, 'Boulderfist Claymore'), +(1126769, 0, 1, 24765, 'Clefthoof Belt'), +(1126769, 0, 1, 24772, 'Clefthoof Bracers'), +(1126769, 0, 1, 24770, 'Clefthoof Britches'), +(1126769, 0, 1, 24769, 'Clefthoof Cover'), +(1126769, 0, 1, 24768, 'Clefthoof Gloves'), +(1126769, 0, 1, 24767, 'Clefthoof Hidemantle'), +(1126769, 0, 1, 24771, 'Clefthoof Shoulderguards'), +(1126769, 0, 1, 24766, 'Clefthoof Wanderboots'), +(1126769, 0, 1, 24654, 'Consortium Boot'), +(1126769, 0, 1, 24660, 'Consortium Bracer'), +(1126769, 0, 1, 24656, 'Consortium Gloves'), +(1126769, 0, 1, 24657, 'Consortium Hood'), +(1126769, 0, 1, 24659, 'Consortium Mantle'), +(1126769, 0, 1, 24658, 'Consortium Pants'), +(1126769, 0, 1, 24655, 'Consortium Robe'), +(1126769, 0, 1, 24653, 'Consortium Sash'), +(1126769, 0, 1, 25193, 'Deathclaw Talons'), +(1126769, 0, 1, 24878, 'Der\'izu Belt'), +(1126769, 0, 1, 24885, 'Der\'izu Bracer'), +(1126769, 0, 1, 24880, 'Der\'izu Chestpiece'), +(1126769, 0, 1, 24881, 'Der\'izu Fists'), +(1126769, 0, 1, 24879, 'Der\'izu Greaves'), +(1126769, 0, 1, 24882, 'Der\'izu Helm'), +(1126769, 0, 1, 24883, 'Der\'izu Legguards'), +(1126769, 0, 1, 24884, 'Der\'izu Spaulders'), +(1126769, 0, 1, 25067, 'Diopside Beads'), +(1126769, 0, 1, 25137, 'Draenethyst Mallet'), +(1126769, 0, 1, 25305, 'Elemental Dagger'), +(1126769, 0, 1, 25235, 'Ethereal-Etched Glaive'), +(1126769, 0, 1, 25039, 'Farseer Cloak'), +(1126769, 0, 1, 25221, 'Ghostly Battle Axe'), +(1126769, 0, 1, 25053, 'Lazuli Ring'), +(1126769, 0, 1, 25109, 'Moon Blade'), +(1126769, 0, 1, 25179, 'Nguni Stick'), +(1126769, 0, 1, 25291, 'Nobility Torch'), +(1126769, 0, 1, 25333, 'Purification Staff'), +(1126769, 0, 1, 25249, 'Ranger\'s Recurved Bow'), +(1126769, 0, 1, 25207, 'Shadowmoon Cleaver'), +(1126769, 0, 1, 25277, 'Sporting Rifle'), +(1126769, 0, 1, 25319, 'Tranquility Mace'), +(1126769, 0, 1, 24990, 'Warmaul Belt'), +(1126769, 0, 1, 24992, 'Warmaul Breastplate'), +(1126769, 0, 1, 24996, 'Warmaul Epaulets'), +(1126769, 0, 1, 24993, 'Warmaul Gloves'), +(1126769, 0, 1, 24991, 'Warmaul Greaves'), +(1126769, 0, 1, 24994, 'Warmaul Helmet'), +(1126769, 0, 1, 24995, 'Warmaul Legplates'), +(1126769, 0, 1, 24997, 'Warmaul Vambraces'), +-- 68-70 +(1126870, 0, 1, 25208, 'Bladespire Broadaxe'), +(1126870, 0, 1, 25138, 'Blood Knight Maul'), +(1126870, 0, 1, 25000, 'Bloodfist Breastplate'), +(1126870, 0, 1, 25004, 'Bloodfist Epaulets'), +(1126870, 0, 1, 24998, 'Bloodfist Girdle'), +(1126870, 0, 1, 25001, 'Bloodfist Gloves'), +(1126870, 0, 1, 24999, 'Bloodfist Greaves'), +(1126870, 0, 1, 25002, 'Bloodfist Helmet'), +(1126870, 0, 1, 25003, 'Bloodfist Legplates'), +(1126870, 0, 1, 25005, 'Bloodfist Vambraces'), +(1126870, 0, 1, 24773, 'Boneshredder Belt'), +(1126870, 0, 1, 24774, 'Boneshredder Boots'), +(1126870, 0, 1, 24778, 'Boneshredder Britches'), +(1126870, 0, 1, 24776, 'Boneshredder Gloves'), +(1126870, 0, 1, 24775, 'Boneshredder Jerkin'), +(1126870, 0, 1, 24779, 'Boneshredder Shoulderguards'), +(1126870, 0, 1, 24777, 'Boneshredder Skullcap'), +(1126870, 0, 1, 24780, 'Boneshredder Wristguards'), +(1126870, 0, 1, 25180, 'Calenda Fighting Stick'), +(1126870, 0, 1, 25222, 'Ceremonial Slayer\'s Axe'), +(1126870, 0, 1, 25096, 'Elementalist Star'), +(1126870, 0, 1, 25082, 'Fel-Iron Shield'), +(1126870, 0, 1, 25124, 'Footman Mace'), +(1126870, 0, 1, 25236, 'Grim Scythe'), +(1126870, 0, 1, 25152, 'Howling Sword'), +(1126870, 0, 1, 25334, 'Intimidating Greatstaff'), +(1126870, 0, 1, 25068, 'Kunzite Necklace'), +(1126870, 0, 1, 25292, 'Mechano-Wand'), +(1126870, 0, 1, 25166, 'Mok\'Nathal Warblade'), +(1126870, 0, 1, 25040, 'Murkblood Cape'), +(1126870, 0, 1, 25278, 'Nesingwary Longrifle'), +(1126870, 0, 1, 25306, 'Permafrost Dagger'), +(1126870, 0, 1, 25264, 'Pocket Ballista'), +(1126870, 0, 1, 25320, 'Queen\'s Insignia'), +(1126870, 0, 1, 25250, 'Rocslayer Longbow'), +(1126870, 0, 1, 28541, 'Sawshrike'), +(1126870, 0, 1, 25194, 'Serpent\'s Fangs'), +(1126870, 0, 1, 24662, 'Shadow Council Boots'), +(1126870, 0, 1, 24668, 'Shadow Council Bracer'), +(1126870, 0, 1, 24661, 'Shadow Council Chain'), +(1126870, 0, 1, 24665, 'Shadow Council Cowl'), +(1126870, 0, 1, 24664, 'Shadow Council Gloves'), +(1126870, 0, 1, 24667, 'Shadow Council Mantle'), +(1126870, 0, 1, 24666, 'Shadow Council Pants'), +(1126870, 0, 1, 24663, 'Shadow Council Tunic'), +(1126870, 0, 1, 25110, 'Sharp Bowie Knife'), +(1126870, 0, 1, 24886, 'Skettis Belt'), +(1126870, 0, 1, 24893, 'Skettis Bracer'), +(1126870, 0, 1, 24888, 'Skettis Chestpiece'), +(1126870, 0, 1, 24887, 'Skettis Footwraps'), +(1126870, 0, 1, 24889, 'Skettis Gauntlets'), +(1126870, 0, 1, 24890, 'Skettis Helmet'), +(1126870, 0, 1, 24891, 'Skettis Legguards'), +(1126870, 0, 1, 24892, 'Skettis Spaulders'), +(1126870, 0, 1, 25054, 'Sodalite Band'), +-- 69-71 +(1126971, 0, 1, 25055, 'Alexandrite Ring'), +(1126971, 0, 1, 25139, 'Algaz Battle Hammer'), +(1126971, 0, 1, 25209, 'Amani Tomahawk'), +(1126971, 0, 1, 25041, 'Ambusher\'s Cloak'), +(1126971, 0, 1, 25097, 'Astralaan Orb'), +(1126971, 0, 1, 25265, 'Barreled Crossbow'), +(1126971, 0, 1, 25008, 'Conqueror\'s Breastplate'), +(1126971, 0, 1, 25012, 'Conqueror\'s Epaulets'), +(1126971, 0, 1, 25009, 'Conqueror\'s Gauntlets'), +(1126971, 0, 1, 25006, 'Conqueror\'s Girdle'), +(1126971, 0, 1, 25007, 'Conqueror\'s Greaves'), +(1126971, 0, 1, 25010, 'Conqueror\'s Helmet'), +(1126971, 0, 1, 25011, 'Conqueror\'s Legplates'), +(1126971, 0, 1, 25013, 'Conqueror\'s Vambraces'), +(1126971, 0, 1, 25195, 'Diamond Tipped Claws'), +(1126971, 0, 1, 25321, 'Divine Hammer'), +(1126971, 0, 1, 25293, 'Draenethyst Wand'), +(1126971, 0, 1, 24669, 'Eldr\'naan Belt'), +(1126971, 0, 1, 24670, 'Eldr\'naan Boots'), +(1126971, 0, 1, 24676, 'Eldr\'naan Bracelets'), +(1126971, 0, 1, 24672, 'Eldr\'naan Gloves'), +(1126971, 0, 1, 24673, 'Eldr\'naan Hood'), +(1126971, 0, 1, 24671, 'Eldr\'naan Jerkin'), +(1126971, 0, 1, 24674, 'Eldr\'naan Pants'), +(1126971, 0, 1, 24675, 'Eldr\'naan Shoulderpads'), +(1126971, 0, 1, 25069, 'Epidote Stone Necklace'), +(1126971, 0, 1, 25335, 'Feral Warp-Staff'), +(1126971, 0, 1, 25153, 'Gladiator Greatblade'), +(1126971, 0, 1, 28542, 'Heartseeker Knives'), +(1126971, 0, 1, 25111, 'Lionhead Dagger'), +(1126971, 0, 1, 24781, 'Murkblood Belt'), +(1126971, 0, 1, 24783, 'Murkblood Boots'), +(1126971, 0, 1, 24789, 'Murkblood Bracers'), +(1126971, 0, 1, 24784, 'Murkblood Chestpiece'), +(1126971, 0, 1, 24786, 'Murkblood Cover'), +(1126971, 0, 1, 24785, 'Murkblood Gloves'), +(1126971, 0, 1, 24787, 'Murkblood Pants'), +(1126971, 0, 1, 24788, 'Murkblood Shoulderguards'), +(1126971, 0, 1, 25237, 'Nether Trident'), +(1126971, 0, 1, 25167, 'Nethersteel Claymore'), +(1126971, 0, 1, 25251, 'Orc Flatbow'), +(1126971, 0, 1, 25125, 'Retro-Spike Club'), +(1126971, 0, 1, 25279, 'Sen\'jin Longrifle'), +(1126971, 0, 1, 25307, 'Shadow Dagger'), +(1126971, 0, 1, 25083, 'Smouldering Shield'), +(1126971, 0, 1, 24896, 'Sundered Chestpiece'), +(1126971, 0, 1, 24895, 'Sundered Footwraps'), +(1126971, 0, 1, 24897, 'Sundered Gauntlets'), +(1126971, 0, 1, 24898, 'Sundered Helmet'), +(1126971, 0, 1, 24899, 'Sundered Legguards'), +(1126971, 0, 1, 24900, 'Sundered Spaulders'), +(1126971, 0, 1, 24894, 'Sundered Waistband'), +(1126971, 0, 1, 25181, 'Tapered Staff'), +(1126971, 0, 1, 24901, 'Tortured Bracer'), +(1126971, 0, 1, 25223, 'Windcaller Hatchet'), +-- 70-72 +(1127072, 0, 1, 25056, 'Almandine Ring'), +(1127072, 0, 1, 25126, 'Anvilmar Hammer'), +(1127072, 0, 1, 24677, 'Archmage Belt'), +(1127072, 0, 1, 24684, 'Archmage Bracelets'), +(1127072, 0, 1, 24680, 'Archmage Gloves'), +(1127072, 0, 1, 24681, 'Archmage Headpiece'), +(1127072, 0, 1, 24683, 'Archmage Mantle'), +(1127072, 0, 1, 24682, 'Archmage Pants'), +(1127072, 0, 1, 24679, 'Archmage Robe'), +(1127072, 0, 1, 24678, 'Archmage Slippers'), +(1127072, 0, 1, 25154, 'Blood Groove Blade'), +(1127072, 0, 1, 25196, 'Boneshredder Claws'), +(1127072, 0, 1, 25140, 'Commanding Mallet'), +(1127072, 0, 1, 25070, 'Coral Beads'), +(1127072, 0, 1, 25182, 'Crystal-Etched Warstaff'), +(1127072, 0, 1, 25210, 'Double-Bladed Axe'), +(1127072, 0, 1, 25294, 'Dragonscale Wand'), +(1127072, 0, 1, 25252, 'Dream Catcher Bow'), +(1127072, 0, 1, 28543, 'Dreghood Throwing Axe'), +(1127072, 0, 1, 24791, 'Expedition Boots'), +(1127072, 0, 1, 24797, 'Expedition Bracers'), +(1127072, 0, 1, 24790, 'Expedition Girdle'), +(1127072, 0, 1, 24793, 'Expedition Gloves'), +(1127072, 0, 1, 24794, 'Expedition Hood'), +(1127072, 0, 1, 24795, 'Expedition Pants'), +(1127072, 0, 1, 24796, 'Expedition Shoulderguards'), +(1127072, 0, 1, 24792, 'Expedition Tunic'), +(1127072, 0, 1, 25112, 'Fel Ripper'), +(1127072, 0, 1, 25280, 'Game Hunter Musket'), +(1127072, 0, 1, 25238, 'Hellfire War Spear'), +(1127072, 0, 1, 25322, 'Lordly Scepter'), +(1127072, 0, 1, 25042, 'Nether Cloak'), +(1127072, 0, 1, 25168, 'Sha\'tari Longsword'), +(1127072, 0, 1, 25014, 'Shattered Hand Belt'), +(1127072, 0, 1, 25016, 'Shattered Hand Breastplate'), +(1127072, 0, 1, 25020, 'Shattered Hand Epaulets'), +(1127072, 0, 1, 25017, 'Shattered Hand Gauntlets'), +(1127072, 0, 1, 25018, 'Shattered Hand Helmet'), +(1127072, 0, 1, 25019, 'Shattered Hand Legplates'), +(1127072, 0, 1, 25015, 'Shattered Hand Sabatons'), +(1127072, 0, 1, 25021, 'Shattered Hand Vambraces'), +(1127072, 0, 1, 25224, 'Slavemaster Axe'), +(1127072, 0, 1, 25336, 'Splintering Greatstaff'), +(1127072, 0, 1, 24904, 'Talhide Chestpiece'), +(1127072, 0, 1, 24906, 'Talhide Helmet'), +(1127072, 0, 1, 24903, 'Talhide Lined-Boots'), +(1127072, 0, 1, 24909, 'Talhide Lined-Bracers'), +(1127072, 0, 1, 24905, 'Talhide Lined-Gloves'), +(1127072, 0, 1, 24907, 'Talhide Lined-Leggings'), +(1127072, 0, 1, 24908, 'Talhide Shoulderguards'), +(1127072, 0, 1, 24902, 'Talhide Stitched-Belt'), +(1127072, 0, 1, 25308, 'Thunder Spike'), +(1127072, 0, 1, 25098, 'Tuurik Torch'), +(1127072, 0, 1, 25266, 'Well-Balanced Crossbow'), +(1127072, 0, 1, 25084, 'Zeth\'Gor Shield'), +-- 71+ +(1127173, 0, 1, 25057, 'Amber Band'), +(1127173, 0, 1, 25043, 'Amber Cape'), +(1127173, 0, 1, 25323, 'Ascendant\'s Scepter'), +(1127173, 0, 1, 28544, 'Assassin\'s Shuriken'), +(1127173, 0, 1, 25281, 'Big-Boar Battle Rifle'), +(1127173, 0, 1, 25225, 'Deepforge Broadaxe'), +(1127173, 0, 1, 25099, 'Draenei Crystal Rod'), +(1127173, 0, 1, 24805, 'Dragonhawk Bands'), +(1127173, 0, 1, 24798, 'Dragonhawk Belt'), +(1127173, 0, 1, 24799, 'Dragonhawk Boots'), +(1127173, 0, 1, 24801, 'Dragonhawk Gloves'), +(1127173, 0, 1, 24802, 'Dragonhawk Hat'), +(1127173, 0, 1, 24803, 'Dragonhawk Pants'), +(1127173, 0, 1, 24804, 'Dragonhawk Shoulderguards'), +(1127173, 0, 1, 24800, 'Dragonhawk Tunic'), +(1127173, 0, 1, 25085, 'Dragonscale Shield'), +(1127173, 0, 1, 24685, 'Elementalist Belt'), +(1127173, 0, 1, 24686, 'Elementalist Boots'), +(1127173, 0, 1, 24692, 'Elementalist Bracelets'), +(1127173, 0, 1, 24688, 'Elementalist Gloves'), +(1127173, 0, 1, 24690, 'Elementalist Leggings'), +(1127173, 0, 1, 24691, 'Elementalist Mantle'), +(1127173, 0, 1, 24689, 'Elementalist Skullcap'), +(1127173, 0, 1, 24687, 'Elementalist Tunic'), +(1127173, 0, 1, 25169, 'Fel Orc Brute Sword'), +(1127173, 0, 1, 25295, 'Flawless Wand'), +(1127173, 0, 1, 25141, 'Halaani Hammer'), +(1127173, 0, 1, 25155, 'Iron Skull Sword'), +(1127173, 0, 1, 25127, 'Knight\'s War Hammer'), +(1127173, 0, 1, 25239, 'Legend\'s Glaive'), +(1127173, 0, 1, 24910, 'Netherstorm Belt'), +(1127173, 0, 1, 24917, 'Netherstorm Bracer'), +(1127173, 0, 1, 24912, 'Netherstorm Chestpiece'), +(1127173, 0, 1, 24913, 'Netherstorm Gauntlets'), +(1127173, 0, 1, 24911, 'Netherstorm Greaves'), +(1127173, 0, 1, 24914, 'Netherstorm Helm'), +(1127173, 0, 1, 24915, 'Netherstorm Legguards'), +(1127173, 0, 1, 24916, 'Netherstorm Shoulderguards'), +(1127173, 0, 1, 25113, 'Phantom Dagger'), +(1127173, 0, 1, 25267, 'Rampant Crossbow'), +(1127173, 0, 1, 25197, 'Razor Scythes'), +(1127173, 0, 1, 25211, 'Rockbiter Cutter'), +(1127173, 0, 1, 25337, 'Swarming Sting-Staff'), +(1127173, 0, 1, 25071, 'Tanzanite Pendant'), +(1127173, 0, 1, 25183, 'Voodoo Hex-Staff'), +(1127173, 0, 1, 25024, 'Warlord\'s Iron-Breastplate'), +(1127173, 0, 1, 25028, 'Warlord\'s Iron-Epaulets'), +(1127173, 0, 1, 25025, 'Warlord\'s Iron-Gauntlets'), +(1127173, 0, 1, 25022, 'Warlord\'s Iron-Girdle'), +(1127173, 0, 1, 25026, 'Warlord\'s Iron-Helm'), +(1127173, 0, 1, 25027, 'Warlord\'s Iron-Legplates'), +(1127173, 0, 1, 25029, 'Warlord\'s Iron-Vambraces'), +(1127173, 0, 1, 25023, 'Warlord\'s Sabatons'), +(1127173, 0, 1, 25309, 'Warpdagger'), +(1127173, 0, 1, 25253, 'Windspear Longbow'), +-- Blues +-- 19-22 +(1031922, 0, 1, 12976, 'Ironpatch Blade'), +(1031922, 0, 1, 12977, 'Magefist Gloves'), +(1031922, 0, 1, 935, 'Night Watch Shortsword'), +(1031922, 0, 1, 12975, 'Prospector Axe'), +(1031922, 0, 1, 12978, 'Stormbringer Belt'), +-- 20-23 +(1032023, 0, 1, 12979, 'Firebane Cloak'), +(1032023, 0, 1, 13136, 'Lil Timmy\'s Peashooter'), +(1032023, 0, 1, 12983, 'Rakzur Club'), +(1032023, 0, 1, 12982, 'Silver-linked Footguards'), +(1032023, 0, 1, 12984, 'Skycaller'), +-- 21-24 +(1032124, 0, 1, 2879, 'Antipodean Rod'), +(1032124, 0, 1, 12987, 'Darkweave Breeches'), +(1032124, 0, 1, 12985, 'Ring of Defense'), +(1032124, 0, 1, 12988, 'Starsight Tunic'), +(1032124, 0, 1, 12989, 'Gargoyle\'s Bite'), +-- 22-25 +(1032225, 0, 1, 12996, 'Band of Purification'), +(1032225, 0, 1, 2911, 'Keller\'s Girdle'), +(1032225, 0, 1, 12990, 'Razor\'s Edge'), +(1032225, 0, 1, 12992, 'Searing Blade'), +(1032225, 0, 1, 12994, 'Thorbia\'s Gauntlets'), +-- 23-26 +(1032326, 0, 1, 1121, 'Feet of the Lynx'), +(1032326, 0, 1, 12997, 'Redbeard Crest'), +(1032326, 0, 1, 2059, 'Sentry Cloak'), +(1032326, 0, 1, 2256, 'Skeletal Club'), +(1032326, 0, 1, 890, 'Twisted Chanter\'s Staff'), +-- 24-27 +(1032427, 0, 1, 2236, 'Blackfang'), +(1032427, 0, 1, 2194, 'Diamond Hammer'), +(1032427, 0, 1, 12999, 'Drakewing Bands'), +(1032427, 0, 1, 12998, 'Magician\'s Mantle'), +(1032427, 0, 1, 3021, 'Ranger Bow'), +-- 25-28 +(1032528, 0, 1, 2800, 'Black Velvet Robes'), +(1032528, 0, 1, 13010, 'Dreamsinger Legguards'), +(1032528, 0, 1, 13041, 'Guardian Blade'), +(1032528, 0, 1, 13016, 'Killmaim'), +(1032528, 0, 1, 2011, 'Twisted Sabre'), +-- 26-29 +(1032629, 0, 1, 2098, 'Double-barreled Shotgun'), +(1032629, 0, 1, 13011, 'Silver-lined Belt'), +(1032629, 0, 1, 13032, 'Sword of Corruption'), +(1032629, 0, 1, 13062, 'Thunderwood'), +(1032629, 0, 1, 13012, 'Yorgen Bracers'), +-- 27-30 +(1032730, 0, 1, 13005, 'Amy\'s Blanket'), +(1032730, 0, 1, 13057, 'Bloodpike'), +(1032730, 0, 1, 720, 'Brawler Gloves'), +(1032730, 0, 1, 3203, 'Dense Triangle Mace'), +(1032730, 0, 1, 13031, 'Orb of Mistmantle'), +-- 28-31 +(1032831, 0, 1, 13024, 'Beazel\'s Basher'), +(1032831, 0, 1, 13099, 'Moccasins of the White Hare'), +(1032831, 0, 1, 13131, 'Sparkleshell Mantle'), +(1032831, 0, 1, 13097, 'Thunderbrow Ring'), +(1032831, 0, 1, 13049, 'Deanship Claymore'), +-- 29-32 +(1032932, 0, 1, 2878, 'Bearded Boneaxe'), +(1032932, 0, 1, 1717, 'Double Link Tunic'), +(1032932, 0, 1, 13079, 'Shield of Thorsen'), +(1032932, 0, 1, 13094, 'The Queen\'s Jewel'), +(1032932, 0, 1, 13114, 'Troll\'s Bane Leggings'), +-- 30-33 +(1033033, 0, 1, 2278, 'Forest Tracker Epaulets'), +(1033033, 0, 1, 13106, 'Glowing Magical Bracelets'), +(1033033, 0, 1, 791, 'Gnarled Ash Staff'), +(1033033, 0, 1, 13048, 'Looming Gavel'), +(1033033, 0, 1, 12974, 'The Black Knight'), +-- 31-34 +(1033134, 0, 1, 2912, 'Claw of the Shadowmancer'), +(1033134, 0, 1, 13037, 'Crystalpine Stinger'), +(1033134, 0, 1, 13127, 'Frostreaver Crown'), +(1033134, 0, 1, 13019, 'Harpyclaw Short Bow'), +(1033134, 0, 1, 2721, 'Holy Shroud'), +-- 32-35 +(1033235, 0, 1, 2299, 'Burning War Axe'), +(1033235, 0, 1, 2877, 'Combatant Claymore'), +(1033235, 0, 1, 3020, 'Enduring Cap'), +(1033235, 0, 1, 9405, 'Girdle of Golem Strength'), +(1033235, 0, 1, 13087, 'River Pride Choker'), +-- 33-36 +(1033336, 0, 1, 9395, 'Gloves of Old'), +(1033336, 0, 1, 13137, 'Ironweaver'), +(1033336, 0, 1, 13063, 'Starfaller'), +(1033336, 0, 1, 13108, 'Tigerstrike Mantle'), +(1033336, 0, 1, 13033, 'Zealot Blade'), +-- 34-37 +(1033437, 0, 1, 13084, 'Kaleidoscope Chain'), +(1033437, 0, 1, 2277, 'Necromancer Leggings'), +(1033437, 0, 1, 13124, 'Ravasaur Scale Boots'), +(1033437, 0, 1, 2565, 'Rod of Molten Fire'), +(1033437, 0, 1, 13045, 'Viscous Hammer'), +-- 35-38 +(1033538, 0, 1, 9385, 'Archaic Defender'), +(1033538, 0, 1, 1726, 'Poison-tipped Bone Spear'), +(1033538, 0, 1, 9435, 'Reticulated Bone Gauntlets'), +(1033538, 0, 1, 2951, 'Ring of the Underwood'), +(1033538, 0, 1, 13110, 'Wolffear Harness'), +-- 36-39 +(1033639, 0, 1, 13093, 'Blush Ember Ring'), +(1033639, 0, 1, 13025, 'Deadwood Sledge'), +(1033639, 0, 1, 934, 'Stalvan\'s Reaper'), +(1033639, 0, 1, 13105, 'Sutarn\'s Ring'), +(1033639, 0, 1, 2276, 'Swampwalker Boots'), +-- 37-40 +(1033740, 0, 1, 937, 'Black Duskwood Staff'), +(1033740, 0, 1, 936, 'Midnight Mace'), +(1033740, 0, 1, 13103, 'Pads of the Venom Spider'), +(1033740, 0, 1, 13081, 'Skullance Shield'), +(1033740, 0, 1, 13121, 'Wing of the Whelpling'), +-- 38-41 +(1033841, 0, 1, 13119, 'Enchanted Kodo Bracers'), +(1033841, 0, 1, 13129, 'Firemane Leggings'), +(1033841, 0, 1, 1265, 'Scorpion Sting'), +(1033841, 0, 1, 13020, 'Skystriker Bow'), +(1033841, 0, 1, 8006, 'The Ziggler'), +-- 39-42 +(1033942, 0, 1, 13054, 'Grim Reaper'), +(1033942, 0, 1, 13017, 'Hellslayer Battle Axe'), +(1033942, 0, 1, 1716, 'Robe of the Magi'), +(1033942, 0, 1, 13038, 'Swiftwind'), +(1033942, 0, 1, 13145, 'Enormous Ogre Belt'), +-- 40-43 +(1034043, 0, 1, 13199, 'Crushridge Bindings'), +(1034043, 0, 1, 9434, 'Elemental Raiment'), +(1034043, 0, 1, 13088, 'Gazlowe\'s Charm'), +(1034043, 0, 1, 13034, 'Speedsteel Rapier'), +(1034043, 0, 1, 13042, 'Sword of the Magistrate'), +-- 41-44 +(1034144, 0, 1, 13064, 'Jaina\'s Firestarter'), +(1034144, 0, 1, 13117, 'Ogron\'s Sash'), +(1034144, 0, 1, 13138, 'The Silencer'), +(1034144, 0, 1, 1722, 'Thornstone Sledgehammer'), +(1034144, 0, 1, 13068, 'Obsidian Greaves'), +-- 42-45 +(1034245, 0, 1, 1718, 'Basilisk Hide Pants'), +(1034245, 0, 1, 2802, 'Blazing Emblem'), +(1034245, 0, 1, 1714, 'Necklace of Calisea'), +(1034245, 0, 1, 13132, 'Skeletal Shoulders'), +(1034245, 0, 1, 13029, 'Umbral Crystal'), +-- 43-46 +(1034346, 0, 1, 13095, 'Assault Band'), +(1034346, 0, 1, 13100, 'Furen\'s Boots'), +(1034346, 0, 1, 13058, 'Khoo\'s Point'), +(1034346, 0, 1, 1715, 'Polished Jazeraint Armor'), +(1034346, 0, 1, 13051, 'Witchfury'), +-- 44-47 +(1034447, 0, 1, 1713, 'Ankh of Life'), +(1034447, 0, 1, 2815, 'Curve-bladed Ripper'), +(1034447, 0, 1, 13026, 'Heaven\'s Light'), +(1034447, 0, 1, 13071, 'Plated Fist of Hakoo'), +(1034447, 0, 1, 13115, 'Sheepshear Mantle'), +(1034447, 0, 1, 9359, 'Wirt\'s Third Leg'), +-- 45-48 +(1034548, 0, 1, 9433, 'Forgotten Wraps'), +(1034548, 0, 1, 13074, 'Golem Shard Leggings'), +(1034548, 0, 1, 13082, 'Mountainside Buckler'), +(1034548, 0, 1, 4090, 'Mug O\' Hurt'), +(1034548, 0, 1, 1720, 'Tanglewood Staff'), +-- 46-49 +(1034649, 0, 1, 13102, 'Cassandra\'s Grace'), +(1034649, 0, 1, 13128, 'High Bergg Helm'), +(1034649, 0, 1, 13021, 'Needle Threader'), +(1034649, 0, 1, 754, 'Shortsword of Vengeance'), +(1034649, 0, 1, 4091, 'Widowmaker'), +-- 47-50 +(1034750, 0, 1, 13055, 'Bonechewer'), +(1034750, 0, 1, 13018, 'Executioner\'s Cleaver'), +(1034750, 0, 1, 13076, 'Giantslayer Bracers'), +(1034750, 0, 1, 13039, 'Skull Splitting Crossbow'), +(1034750, 0, 1, 13112, 'Winged Helm'), +-- 48-51 +(1034851, 0, 1, 13134, 'Belt of the Gladiator'), +(1034851, 0, 1, 13109, 'Blackflame Cape'), +(1034851, 0, 1, 13043, 'Blade of the Titans'), +(1034851, 0, 1, 13035, 'Serpent Slicer'), +(1034851, 0, 1, 13089, 'Skibi\'s Pendant'), +-- 49-52 +(1034952, 0, 1, 13046, 'Blanchard\'s Stout'), +(1034952, 0, 1, 13125, 'Elven Chain Boots'), +(1034952, 0, 1, 2564, 'Elven Spirit Claws'), +(1034952, 0, 1, 13139, 'Guttbuster'), +(1034952, 0, 1, 13065, 'Wand of Allistarj'), +-- 50-53 +(1035053, 0, 1, 13030, 'Basilisk Bone'), +(1035053, 0, 1, 13009, 'Cow King\'s Hide'), +(1035053, 0, 1, 13085, 'Horizon Choker'), +(1035053, 0, 1, 7734, 'Six Demon Bag'), +(1035053, 0, 1, 13066, 'Wyrmslayer Spaulders'), +-- 51-54 +(1035154, 0, 1, 13008, 'Dalewind Trousers'), +(1035154, 0, 1, 13073, 'Mugthol\'s Helm'), +(1035154, 0, 1, 13059, 'Stoneraven'), +(1035154, 0, 1, 11302, 'Uther\'s Strength'), +(1035154, 0, 1, 13052, 'Warmonger'), +-- 52-55 +(1035255, 0, 1, 13014, 'Axe of Rin\'ji'), +(1035255, 0, 1, 13126, 'Battlecaller Gauntlets'), +(1035255, 0, 1, 13027, 'Bonesnapper'), +(1035255, 0, 1, 5266, 'Eye of Adaegus'), +(1035255, 0, 1, 13144, 'Serenity Belt'), +-- 53-56 +(1035356, 0, 1, 1203, 'Aegis of Stormwind'), +(1035356, 0, 1, 13067, 'Hydralick Armor'), +(1035356, 0, 1, 13111, 'Sandals of the Insurgent'), +(1035356, 0, 1, 1607, 'Soulkeeper'), +(1035356, 0, 1, 1721, 'Viking Warhammer'), +-- 54-57 +(1035457, 0, 1, 13122, 'Dark Phantom Cape'), +(1035457, 0, 1, 13120, 'Deepfury Bracers'), +(1035457, 0, 1, 13022, 'Gryphonwing Long Bow'), +(1035457, 0, 1, 8190, 'Hanzo Sword'), +(1035457, 0, 1, 6660, 'Julie\'s Dagger'), +-- 55-58 +(1035558, 0, 1, 13013, 'Elder Wizard\'s Mantle'), +(1035558, 0, 1, 13056, 'Frenzied Striker'), +(1035558, 0, 1, 13040, 'Heartseeking Crossbow'), +(1035558, 0, 1, 13003, 'Lord Alexander\'s Battle Axe'), +(1035558, 0, 1, 13130, 'Windrunner Legguards'), +-- 56-59 +(1035659, 0, 1, 13036, 'Assassination Blade'), +(1035659, 0, 1, 13044, 'Demonslayer'), +(1035659, 0, 1, 13077, 'Girdle of Uther'), +(1035659, 0, 1, 13091, 'Medallion of Grand Marshal Morris'), +(1035659, 0, 1, 13118, 'Serpentine Sash'), +(1035659, 0, 1, 24222, 'The Shadowfoot Stabber'), +-- 57-60 +(1035760, 0, 1, 13007, 'Mageflame Cloak'), +(1035760, 0, 1, 13070, 'Sapphiron\'s Scale Boots'), +(1035760, 0, 1, 13146, 'Shell Launcher Shotgun'), +(1035760, 0, 1, 13004, 'Torch of Austen'), +(1035760, 0, 1, 13047, 'Twig of the World Tree'), +-- 58-61 +(1035861, 0, 1, 13002, 'Lady Alizabeth\'s Pendant'), +(1035861, 0, 1, 4696, 'Lapidis Tankard of Tidesippe'), +(1035861, 0, 1, 13135, 'Lordly Armguards'), +(1035861, 0, 1, 1973, 'Orb of Deception'), +(1035861, 0, 1, 13101, 'Wolfrunner Shoes'), +-- 59+ +(1035963, 0, 1, 13096, 'Band of the Hierophant'), +(1035963, 0, 1, 13053, 'Doombringer'), +(1035963, 0, 1, 9402, 'Earthborn Kilt'), +(1035963, 0, 1, 13072, 'Stonegrip Gauntlets'), +(1035963, 0, 1, 13060, 'The Needler'), +(1035963, 0, 1, 13001, 'Maiden\'s Circle'), +(1035963, 0, 1, 13028, 'Bludstone Hammer'), +(1035963, 0, 1, 13133, 'Drakesfire Epaulets'), +(1035963, 0, 1, 13015, 'Serathil'), +(1035963, 0, 1, 13116, 'Spaulders of the Unseen'), +(1035963, 0, 1, 13123, 'Dreamwalker Armor'), +(1035963, 0, 1, 13083, 'Garrett Family Crest'), +(1035963, 0, 1, 13107, 'Magiskull Cuffs'), +(1035963, 0, 1, 13006, 'Mass of McGowan'), +(1035963, 0, 1, 13000, 'Staff of Hale Magefire'), +(1035963, 0, 1, 13075, 'Direwing Legguards'), +(1035963, 0, 1, 13023, 'Eaglehorn Long Bow'), +(1035963, 0, 1, 13113, 'Feathermoon Headdress'), +(1035963, 0, 1, 5267, 'Scarlet Kris'), +(1035963, 0, 1, 6622, 'Sword of Zeal'), +(1035963, 0, 1, 23197, 'Idol of the Moon'), +(1035963, 0, 1, 23203, 'Libram of Fervor'), +(1035963, 0, 1, 23199, 'Totem of the Storm'), +-- TBC Blues +-- 58-61 +(1135861, 0, 1, 31134, 'Blade of Misfortune'), +(1135861, 0, 1, 31125, 'Boots of the Decimator'), +(1135861, 0, 1, 31126, 'Gloves of Ferocity'), +(1135861, 0, 1, 31127, 'Hauberk of Totemic Rage'), +(1135861, 0, 1, 31133, 'Leggings of Concentrated Darkness'), +(1135861, 0, 1, 31131, 'Sash of Silent Blades'), +-- 59-62 +(1135962, 0, 1, 31142, 'Blade of Trapped Knowledge'), +(1135962, 0, 1, 31136, 'Breastplate of Blade Turning'), +(1135962, 0, 1, 31140, 'Cloak of Entropy'), +(1135962, 0, 1, 31139, 'Fist of Reckoning'), +(1135962, 0, 1, 31137, 'Gauntlets of Purification'), +(1135962, 0, 1, 31138, 'Storm Lord\'s Girdle'), +-- 60-63 +(1136063, 0, 1, 31148, 'Demon Hide Spaulders'), +(1136063, 0, 1, 31149, 'Gloves of Pandemonium'), +(1136063, 0, 1, 31150, 'Gloves of Piety'), +(1136063, 0, 1, 31145, 'Headdress of the Sleeper'), +(1136063, 0, 1, 31147, 'Pendant of Cunning'), +(1136063, 0, 1, 31143, 'Shroud of Frenzy'), +-- 61-64 +(1136164, 0, 1, 31178, 'Amulet of Unstable Power'), +(1136164, 0, 1, 31153, 'Axe of the Legion'), +(1136164, 0, 1, 31175, 'Blade Dancer\'s Wristguards'), +(1136164, 0, 1, 31173, 'Boots of Savagery'), +(1136164, 0, 1, 31152, 'Chestguard of Illumination'), +(1136164, 0, 1, 31151, 'Girdle of Siege'), +-- 62-65 +(1136265, 0, 1, 31196, 'Amulet of Sanctification'), +(1136265, 0, 1, 31193, 'Blade of Unquenched Thirst'), +(1136265, 0, 1, 31187, 'Boots of the Pathfinder'), +(1136265, 0, 1, 31186, 'Braxxis\' Staff of Slumber'), +(1136265, 0, 1, 31180, 'Gauntlets of the Skullsplitter'), +(1136265, 0, 1, 31190, 'The Dreamer\'s Shoulderpads'), +-- 63-66 +(1136366, 0, 1, 31230, 'Abyss Walker\'s Boots'), +(1136366, 0, 1, 31202, 'Girdle of Divine Blessing'), +(1136366, 0, 1, 31222, 'Headdress of Inner Rage'), +(1136366, 0, 1, 31226, 'Leggings of the Sly'), +(1136366, 0, 1, 31200, 'Shield of the Wayward Footman'), +(1136366, 0, 1, 31204, 'The Gunblade'), +-- 64-67 +(1136467, 0, 1, 31258, 'Band of Sorrow'), +(1136467, 0, 1, 31255, 'Cloak of the Craft'), +(1136467, 0, 1, 31272, 'Crown of Endless Knowledge'), +(1136467, 0, 1, 31234, 'Crystalblade of the Draenei'), +(1136467, 0, 1, 31237, 'Elekk Hide Leggings'), +(1136467, 0, 1, 31240, 'Scales of the Beast'), +-- 65-68 +(1136568, 0, 1, 31276, 'Boots of Zealotry'), +(1136568, 0, 1, 31281, 'Mask of Veiled Death'), +(1136568, 0, 1, 31275, 'Necklace of Trophies'), +(1136568, 0, 1, 31277, 'Pathfinder\'s Band'), +(1136568, 0, 1, 31283, 'Sash of Sealed Fate'), +(1136568, 0, 1, 31282, 'Shroud of Spiritual Purity'), +(1136568, 0, 1, 31280, 'Thundercaller\'s Gauntlets'), +-- 66-69 +(1136669, 0, 1, 31284, 'Bracers of Recklessness'), +(1136669, 0, 1, 31286, 'Breastplate of Rapid Striking'), +(1136669, 0, 1, 31285, 'Chestguard of the Talon'), +(1136669, 0, 1, 31287, 'Draenei Honor Guard Shield'), +(1136669, 0, 1, 31289, 'Staff of Divine Infusion'), +(1136669, 0, 1, 31288, 'The Master\'s Treads'), +(1136669, 0, 1, 31290, 'Band of Dominion'), +-- 67-70 +(1136770, 0, 1, 31295, 'Chestguard of the Dark Stalker'), +(1136770, 0, 1, 31292, 'Crystal Pulse Shield'), +(1136770, 0, 1, 31291, 'Crystalforged War Axe'), +(1136770, 0, 1, 31293, 'Girdle of Gale Force'), +(1136770, 0, 1, 31294, 'Pauldrons of Surging Mana'), +(1136770, 0, 1, 31297, 'Robe of the Crimson Order'), +-- 68+ +(1136873, 0, 1, 31299, 'The Oathkeeper'), +(1136873, 0, 1, 31305, 'Ced\'s Carver'), +(1136873, 0, 1, 31940, 'Ethereum Torque'), +(1136873, 0, 1, 31306, 'Leggings of the Sacred Crest'), +(1136873, 0, 1, 31298, 'Legguards of the Shattered Hand'), +(1136873, 0, 1, 31308, 'The Bringer of Death'), +(1136873, 0, 1, 31304, 'The Essence Focuser'), +(1136873, 0, 1, 31303, 'Valanos\' Longbow'), +-- Purples +-- 40-46 +(1044046, 0, 1, 870, 'Fiery War Axe'), +(1044046, 0, 1, 873, 'Staff of Jordan'), +(1044046, 0, 1, 869, 'Dazzling Longsword'), +(1044046, 0, 1, 1204, 'The Green Tower'), +(1044046, 0, 1, 2825, 'Bow of Searing Arrows'), +(1044046, 0, 1, 867, 'Gloves of Holy Might'), +(1044046, 0, 1, 868, 'Ardent Custodian'), +(1044046, 0, 1, 1980, 'Underworld Band'), +(1044046, 0, 1, 1981, 'Icemail Jerkin'), +(1044046, 0, 1, 1982, 'Nightblade'), +-- 42-48 +(1044248, 0, 1, 14549, 'Boots of Avoidance'), +(1044248, 0, 1, 2164, 'Gut Ripper'), +(1044248, 0, 1, 1169, 'Blackskull Shield'), +(1044248, 0, 1, 1447, 'Ring of Saviors'), +-- 44-50 +(1044450, 0, 1, 871, 'Flurry Axe'), +(1044450, 0, 1, 940, 'Robes of Insight'), +(1044450, 0, 1, 2100, 'Precisely Calibrated Boomstick'), +(1044450, 0, 1, 943, 'Warden Staff'), +(1044450, 0, 1, 14551, 'Edgemaster\'s Handguards'), +-- 46-52 +(1044652, 0, 1, 2291, 'Kang the Decapitator'), +(1044652, 0, 1, 809, 'Bloodrazor'), +(1044652, 0, 1, 1979, 'Wall of the Dead'), +-- 48-54 +(1044854, 0, 1, 1315, 'Lei of Lilies'), +(1044854, 0, 1, 17007, 'Stonerender Gauntlets'), +(1044854, 0, 1, 942, 'Freezing Band'), +(1044854, 0, 1, 2915, 'Taran Icebreaker'), +-- 50-56 +(1045056, 0, 1, 2824, 'Hurricane'), +(1045056, 0, 1, 2163, 'Shadowblade'), +(1045056, 0, 1, 812, 'Glowing Brightwood Staff'), +(1045056, 0, 1, 810, 'Hammer of the Northern Wind'), +-- 52-58 +(1045258, 0, 1, 3075, 'Eye of Flame'), +(1045258, 0, 1, 14552, 'Stockade Pauldrons'), +(1045258, 0, 1, 2244, 'Krol Blade'), +(1045258, 0, 1, 833, 'Lifestone'), +-- 54-60 +(1045460, 0, 1, 811, 'Axe of the Deep Woods'), +(1045460, 0, 1, 647, 'Destiny'), +-- 56-62 +(1045662, 0, 1, 2099, 'Dwarven Hand Cannon'), +(1045662, 0, 1, 2246, 'Myrmidon\'s Signet'), +(1045662, 0, 1, 2245, 'Helm of Narv'), +(1045662, 0, 1, 1168, 'Skullflame Shield'), +(1045662, 0, 1, 1263, 'Brain Hacker'), +(1045662, 0, 1, 1443, 'Jeweled Amulet of Cainwyn'), +-- 58-63 +(1045863, 0, 1, 944, 'Elemental Mage Staff'), +(1045863, 0, 1, 14553, 'Sash of Mercy'), +(1045863, 0, 1, 14554, 'Cloudkeeper Legplates'), +(1045863, 0, 1, 2243, 'Hand of Edward the Odd'), +-- 60-63 +(1046063, 0, 1, 14555, 'Alcor\'s Sunrazor'), +(1046063, 0, 1, 14557, 'The Lion Horn of Stormwind'), +(1046063, 0, 1, 2801, 'Blade of Hanna'), +(1046063, 0, 1, 14558, 'Lady Maye\'s Pendant'), +(1046063, 10, 1, 1728, 'Teebu\'s Blazing Longsword'), +(1046063, 10, 1, 3475, 'Cloak of Flames'), +-- TBC Purples +-- 67+ +(1146773, 0, 1, 31319, 'Band of Impenetrable Defenses'), +(1146773, 0, 1, 31336, 'Blade of Wizardry'), +(1146773, 0, 1, 31332, 'Blinkstrike'), +(1146773, 0, 1, 31338, 'Charlotte\'s Ivy'), +(1146773, 0, 1, 31320, 'Chestguard of Exile'), +(1146773, 0, 1, 31321, 'Choker of Repentance'), +(1146773, 0, 1, 31323, 'Don Santos\' Famous Hunting Rifle'), +(1146773, 0, 1, 31343, 'Kamaei\'s Cerulean Skirt'), +(1146773, 0, 1, 31328, 'Leggings of Beast Mastery'), +(1146773, 0, 1, 31329, 'Lifegiving Cloak'), +(1146773, 0, 1, 31330, 'Lightning Crown'), +(1146773, 0, 1, 31339, 'Lola\'s Eve'), +(1146773, 0, 1, 31335, 'Pants of Living Growth'), +(1146773, 0, 1, 31318, 'Singing Crystal Axe'), +(1146773, 0, 1, 31334, 'Staff of Natural Fury'), +(1146773, 0, 1, 31342, 'The Ancient Scepter of Sue-Min'), +(1146773, 0, 1, 31322, 'The Hammer of Destiny'), +(1146773, 0, 1, 31331, 'The Night Blade'), +(1146773, 0, 1, 31333, 'The Night Watchman'), +(1146773, 0, 1, 31326, 'Truestrike Ring'), +(1146773, 0, 1, 31340, 'Will of Edward the Odd'), + +-- Scrolls +(1050614, 0, 1, 1181, 'Scroll of Spirit'), +(1050614, 0, 1, 3013, 'Scroll of Protection'), +-- 15-25 +(1051525, 0, 1, 954, 'Scroll of Strength'), +(1051525, 0, 1, 955, 'Scroll of Intellect'), +(1051525, 0, 1, 1180, 'Scroll of Stamina'), +(1051525, 0, 1, 1181, 'Scroll of Spirit'), +(1051525, 0, 1, 3012, 'Scroll of Agility'), +(1051525, 0, 1, 3013, 'Scroll of Protection'), +-- 26-35 +(1052635, 0, 1, 1711, 'Scroll of Stamina II'), +(1052635, 0, 1, 1477, 'Scroll of Agility II'), +(1052635, 0, 1, 1478, 'Scroll of Protection II'), +(1052635, 0, 1, 1712, 'Scroll of Spirit II'), +(1052635, 0, 1, 2289, 'Scroll of Strength II'), +(1052635, 0, 1, 2290, 'Scroll of Intellect II'), +-- 36-50 +(1053650, 0, 1, 4419, 'Scroll of Intellect III'), +(1053650, 0, 1, 4421, 'Scroll of Protection III'), +(1053650, 0, 1, 4422, 'Scroll of Stamina III'), +(1053650, 0, 1, 4424, 'Scroll of Spirit III'), +(1053650, 0, 1, 4425, 'Scroll of Agility III'), +(1053650, 0, 1, 4426, 'Scroll of Strength III'), +-- 50+ +(1055163, 0, 1, 10305, 'Scroll of Protection IV'), +(1055163, 0, 1, 10306, 'Scroll of Spirit IV'), +(1055163, 0, 1, 10307, 'Scroll of Stamina IV'), +(1055163, 0, 1, 10308, 'Scroll of Intellect IV'), +(1055163, 0, 1, 10309, 'Scroll of Agility IV'), +(1055163, 0, 1, 10310, 'Scroll of Strength IV'), +-- TBC 58-73 +(1155873, 11.1, 1, 27498, 'Scroll of Agility V'), +(1155873, 11.1, 1, 27499, 'Scroll of Intellect V'), +(1155873, 11.1, 1, 27500, 'Scroll of Protection V'), +(1155873, 11.1, 1, 27501, 'Scroll of Spirit V'), +(1155873, 11.1, 1, 27502, 'Scroll of Stamina V'), +(1155873, 11.1, 1, 27503, 'Scroll of Strength V'), +-- TBC 58-73 Half Chance +(1155873, 0, 1, 33457, 'Scroll of Agility VI'), +(1155873, 0, 1, 33458, 'Scroll of Intellect VI'), +(1155873, 0, 1, 33459, 'Scroll of Protection VI'), +(1155873, 0, 1, 33460, 'Scroll of Spirit VI'), +(1155873, 0, 1, 33461, 'Scroll of Stamina VI'), +(1155873, 0, 1, 33462, 'Scroll of Strength VI'), +-- Potions +-- 6-10 +(1060610, 0, 1, 118, 'Minor Healing Potion'), +-- 11-20 +(1061120, 67, 1, 858, 'Lesser Healing Potion'), +(1061120, 0, 1, 2455, 'Minor Mana Potion'), +-- 21-30 +(1062130, 67, 1, 929, 'Healing Potion'), +(1062130, 0, 1, 3385, 'Lesser Mana Potion'), +-- 31-40 +(1063140, 67, 1, 1710, 'Greater Healing Potion'), +(1063140, 0, 1, 3827, 'Mana Potion'), +-- 41-50 +(1064150, 67, 1, 3928, 'Superior Healing Potion'), +(1064150, 0, 1, 6149, 'Greater Mana Potion'), +-- 51-55 +(1065155, 0, 1, 13443, 'Superior Mana Potion'), +(1065155, 67, 1, 13446, 'Major Healing Potion'), +-- 56-63 +(1065663, 0, 1, 13444, 'Major Mana Potion'), +(1065663, 67, 1, 13446, 'Major Healing Potion'), +-- TBC +(1165864, 0, 1, 13444, 'Major Mana Potion'), +(1165864, 67, 1, 13446, 'Major Healing Potion'), +(1166573, 0, 1, 22832, 'Super Mana Potion'), +(1166573, 67, 1, 22829, 'Super Healing Potion'), +-- Gems and Lockboxes (100%) +-- 6-10 +(1070610, 1, 1, 774, 'Malachite'), +(1070610, 0.5, 1, 818, 'Tigerseye'), +-- 11-14 +(1071114, 0.5, 1, 774, 'Malachite'), +(1071114, 0.5, 1, 818, 'Tigerseye'), +(1071114, 0.5, 1, 1210, 'Shadowgem'), +-- 15-19 +(1071519, 0.5, 1, 818, 'Tigerseye'), +(1071519, 0.5, 1, 1210, 'Shadowgem'), +(1071519, 0.5, 1, 1206, 'Moss Agate'), +-- 20-25 +(1072025, 0.5, 1, 1210, 'Shadowgem'), +(1072025, 0.5, 1, 1206, 'Moss Agate'), +(1072025, 0.5, 1, 1705, 'Lesser Moonstone'), +(1072025, 0.5, 2, 4632, 'Ornate Bronze Lockbox'), +-- 26-27 +(1072627, 0.5, 1, 1206, 'Moss Agate'), +(1072627, 0.5, 1, 1705, 'Lesser Moonstone'), +(1072627, 0.5, 1, 1529, 'Jade'), +(1072627, 0.5, 2, 4633, 'Heavy Bronze Lockbox'), +-- 28-30 +(1072830, 0.75, 1, 1705, 'Lesser Moonstone'), +(1072830, 0.75, 1, 1529, 'Jade'), +(1072830, 0.5, 2, 4633, 'Heavy Bronze Lockbox'), +-- 31-35 +(1073135, 0.5, 1, 1705, 'Lesser Moonstone'), +(1073135, 0.5, 1, 1529, 'Jade'), +(1073135, 0.5, 1, 3864, 'Citrine'), +(1073135, 0.5, 2, 4634, 'Iron Lockbox'), +-- 36-40 +(1073640, 0.75, 1, 1529, 'Jade'), +(1073640, 0.75, 1, 3864, 'Citrine'), +(1073640, 0.5, 2, 4636, 'Strong Iron Lockbox'), +-- 41-45 +(1074145, 0.75, 1, 3864, 'Citrine'), +(1074145, 0.75, 1, 7909, 'Aquamarine'), +(1074145, 0.5, 2, 4637, 'Steel Lockbox'), +-- 46-50 +(1074650, 0.75, 1, 7909, 'Aquamarine'), +(1074650, 0.75, 1, 7910, 'Star Ruby'), +(1074650, 0.5, 2, 4638, 'Reinforced Steel Lockbox'), +-- 51-55 +(1075155, 0.75, 1, 7909, 'Aquamarine'), +(1075155, 0.75, 1, 7910, 'Star Ruby'), +(1075155, 0.5, 2, 5758, 'Mithril Lockbox'), +-- 56-60 +(1075660, 0.75, 1, 7909, 'Aquamarine'), +(1075660, 0.75, 1, 7910, 'Star Ruby'), +(1075660, 0.5, 2, 5759, 'Thorium Lockbox'), +-- 61-63 +(1076163, 0.75, 1, 7909, 'Aquamarine'), +(1076163, 0.75, 1, 7910, 'Star Ruby'), +(1076163, 0.5, 2, 5760, 'Eternium Lockbox'), +-- Cards and Librams (100%) +-- 50+ +-- Normal +(1075061, 0.05, 3, 19230, 'Two of Beasts'), +(1075061, 0.05, 3, 19231, 'Three of Beasts'), +(1075061, 0.05, 3, 19232, 'Four of Beasts'), +(1075061, 0.05, 3, 19259, 'Two of Warlords'), +(1075061, 0.05, 3, 19260, 'Three of Warlords'), +(1075061, 0.05, 3, 19261, 'Four of Warlords'), +(1075061, 0.05, 3, 19269, 'Two of Elementals'), +(1075061, 0.05, 3, 19270, 'Three of Elementals'), +(1075061, 0.05, 3, 19271, 'Four of Elementals'), +(1075061, 0.05, 3, 19278, 'Two of Portals'), +(1075061, 0.05, 3, 19279, 'Three of Portals'), +(1075061, 0.05, 3, 19280, 'Four of Portals'), +(1075061, 0.05, 4, 11732, 'Libram of Rumination'), +(1075061, 0.05, 4, 11733, 'Libram of Constitution'), +(1075061, 0.05, 4, 11734, 'Libram of Tenacity'), +(1075061, 0.05, 4, 11736, 'Libram of Resilience'), +(1075061, 0.05, 4, 11737, 'Libram of Voracity'), +-- Elite +(1075063, 0.05, 3, 19233, 'Five of Beasts'), +(1075063, 0.05, 3, 19234, 'Six of Beasts'), +(1075063, 0.05, 3, 19235, 'Seven of Beasts'), +(1075063, 0.05, 3, 19236, 'Eight of Beasts'), +(1075063, 0.05, 3, 19262, 'Five of Warlords'), +(1075063, 0.05, 3, 19263, 'Six of Warlords'), +(1075063, 0.05, 3, 19264, 'Seven of Warlords'), +(1075063, 0.05, 3, 19265, 'Eight of Warlords'), +(1075063, 0.05, 3, 19272, 'Five of Elementals'), +(1075063, 0.05, 3, 19273, 'Six of Elementals'), +(1075063, 0.05, 3, 19274, 'Seven of Elementals'), +(1075063, 0.05, 3, 19275, 'Eight of Elementals'), +(1075063, 0.05, 3, 19281, 'Five of Portals'), +(1075063, 0.05, 3, 19282, 'Six of Portals'), +(1075063, 0.05, 3, 19283, 'Seven of Portals'), +(1075063, 0.05, 3, 19284, 'Eight of Portals'), +(1075063, 0.05, 4, 11732, 'Libram of Rumination'), +(1075063, 0.05, 4, 11733, 'Libram of Constitution'), +(1075063, 0.05, 4, 11734, 'Libram of Tenacity'), +(1075063, 0.05, 4, 11736, 'Libram of Resilience'), +(1075063, 0.05, 4, 11737, 'Libram of Voracity'), +(1075063, 0.05, 5, 22393, 'Codex: Prayer of Shadow Protection'), +(1075063, 0.05, 5, 22891, 'Grimoire of Shadow Ward IV'), +(1075063, 0.05, 5, 17682, 'Book: Gift of the Wild'), +(1075063, 0.05, 5, 17683, 'Book: Gift of the Wild II'), +(1075063, 0.05, 5, 17413, 'Codex: Prayer of Fortitude'), +(1075063, 0.05, 5, 17414, 'Codex: Prayer of Fortitude II'), +(1075063, 0.05, 5, 18600, 'Tome of Arcane Brilliance'), +(1075063, 0.05, 5, 22890, 'Tome of Frost Ward V'), +-- TBC +-- 65+ +-- Normal +(1176571, 0.05, 3, 31889, 'Two of Blessings'), +(1176571, 0.05, 3, 31888, 'Three of Blessings'), +(1176571, 0.05, 3, 31885, 'Four of Blessings'), +(1176571, 0.05, 3, 31900, 'Two of Storms'), +(1176571, 0.05, 3, 31899, 'Three of Storms'), +(1176571, 0.05, 3, 31895, 'Four of Storms'), +(1176571, 0.05, 3, 31909, 'Two of Furies'), +(1176571, 0.05, 3, 31908, 'Three of Furies'), +(1176571, 0.05, 3, 31904, 'Four of Furies'), +(1176571, 0.05, 3, 31918, 'Two of Lunacy'), +(1176571, 0.05, 3, 31917, 'Three of Lunacy'), +(1176571, 0.05, 3, 31913, 'Four of Lunacy'), +-- Elite +(1176573, 0.05, 3, 31884, 'Five of Blessings'), +(1176573, 0.05, 3, 31887, 'Six of Blessings'), +(1176573, 0.05, 3, 31886, 'Seven of Blessings'), +(1176573, 0.05, 3, 31883, 'Eight of Blessings'), +(1176573, 0.05, 3, 31894, 'Five of Storms'), +(1176573, 0.05, 3, 31898, 'Six of Storms'), +(1176573, 0.05, 3, 31896, 'Seven of Storms'), +(1176573, 0.05, 3, 31893, 'Eight of Storms'), +(1176573, 0.05, 3, 31903, 'Five of Furies'), +(1176573, 0.05, 3, 31906, 'Six of Furies'), +(1176573, 0.05, 3, 31905, 'Seven of Furies'), +(1176573, 0.05, 3, 31902, 'Eight of Furies'), +(1176573, 0.05, 3, 31912, 'Five of Lunacy'), +(1176573, 0.05, 3, 31916, 'Six of Lunacy'), +(1176573, 0.05, 3, 31915, 'Seven of Lunacy'), +(1176573, 0.05, 3, 31911, 'Eight of Lunacy'), +-- Patterns & Recipes & Formulas & Plans +-- 6-20 +(1080620, 0, 1, 2598, 'Pattern: Red Linen Robe'), +(1080620, 0, 1, 3609, 'Plans: Copper Chain Vest'), +(1080620, 0, 1, 7288, 'Pattern: Rugged Leather Pants'), +(1080620, 0, 1, 6342, 'Formula: Enchant Chest - Minor Mana'), +(1080620, 0, 1, 6271, 'Pattern: Red Linen Vest'), +(1080620, 0, 1, 2553, 'Recipe: Elixir of Minor Agility'), +(1080620, 0, 1, 2407, 'Pattern: White Leather Jerkin'), +(1080620, 0, 1, 2406, 'Pattern: Fine Leather Boots'), +(1080620, 0, 1, 2408, 'Pattern: Fine Leather Gloves'), +(1080620, 0, 1, 3610, 'Plans: Gemmed Copper Gauntlets'), +(1080620, 0, 1, 2555, 'Recipe: Swiftness Potion'), +(1080620, 0, 1, 4408, 'Schematic: Mechanical Squirrel Box'), +-- 12-25 +(1081225, 0, 1, 6344, 'Formula: Enchant Bracer - Minor Spirit'), +(1081225, 0, 1, 2881, 'Plans: Runed Copper Breastplate'), +(1081225, 0, 1, 6663, 'Recipe: Elixir of Giant Growth'), +(1081225, 0, 1, 6347, 'Formula: Enchant Bracer - Minor Strength'), +(1081225, 0, 1, 4292, 'Pattern: Green Woolen Bag'), +(1081225, 0, 1, 4345, 'Pattern: Red Woolen Boots'), +(1081225, 0, 1, 6348, 'Formula: Enchant Weapon - Minor Beastslayer'), +(1081225, 0, 1, 2409, 'Pattern: Dark Leather Tunic'), +(1081225, 0, 1, 4346, 'Pattern: Heavy Woolen Cloak'), +(1081225, 0, 1, 4293, 'Pattern: Hillman\'s Leather Vest'), +(1081225, 0, 1, 6716, 'Schematic: EZ-Thro Dynamite'), +(1081225, 0, 1, 4409, 'Schematic: Small Seaforium Charge'), +-- 16-30 +(1081630, 0, 1, 5972, 'Pattern: Fine Leather Pants'), +(1081630, 0, 1, 2601, 'Pattern: Gray Woolen Robe'), +(1081630, 0, 1, 11038, 'Formula: Enchant 2H Weapon - Lesser Spirit'), +(1081630, 0, 1, 11039, 'Formula: Enchant Cloak - Minor Agility'), +(1081630, 0, 1, 11081, 'Formula: Enchant Shield - Lesser Protection'), +(1081630, 0, 1, 6375, 'Formula: Enchant Bracer - Lesser Spirit'), +(1081630, 0, 1, 10316, 'Pattern: Colorful Kilt'), +(1081630, 0, 1, 4294, 'Pattern: Hillman\'s Belt'), +(1081630, 0, 1, 4347, 'Pattern: Reinforced Woolen Shoulders'), +(1081630, 0, 1, 6390, 'Pattern: Stylish Blue Shirt'), +(1081630, 0, 1, 6391, 'Pattern: Stylish Green Shirt'), +(1081630, 0, 1, 4410, 'Schematic: Shadow Goggles'), +(1081630, 0, 1, 7360, 'Pattern: Dark Leather Gloves'), +(1081630, 0, 1, 4348, 'Pattern: Phoenix Gloves'), +(1081630, 0, 1, 4349, 'Pattern: Phoenix Pants'), +(1081630, 0, 1, 2883, 'Plans: Deadly Bronze Poniard'), +(1081630, 0, 1, 2882, 'Plans: Silvered Bronze Shoulders'), +-- 20-35 +(1082035, 0, 1, 6454, 'Manual: Strong Anti-Venom'), +(1082035, 0, 1, 5578, 'Plans: Silvered Bronze Breastplate'), +(1082035, 0, 1, 11098, 'Formula: Enchant Cloak - Lesser Shadow Resistance'), +(1082035, 0, 1, 4296, 'Pattern: Dark Leather Shoulders'), +(1082035, 0, 1, 7363, 'Pattern: Pilferer\'s Gloves'), +(1082035, 0, 1, 4350, 'Pattern: Spider Silk Slippers'), +(1082035, 0, 1, 5543, 'Plans: Iridescent Hammer'), +(1082035, 0, 1, 3396, 'Recipe: Elixir of Lesser Agility'), +(1082035, 0, 1, 7092, 'Pattern: Hands of Darkness'), +(1082035, 0, 1, 7364, 'Pattern: Heavy Earthen Gloves'), +(1082035, 0, 1, 3611, 'Plans: Green Iron Boots'), +(1082035, 0, 1, 3608, 'Plans: Mighty Iron Hammer'), +(1082035, 0, 1, 4412, 'Schematic: Moonsight Rifle'), +(1082035, 0, 1, 4297, 'Pattern: Barbaric Gloves'), +(1082035, 0, 1, 7091, 'Pattern: Truefaith Gloves'), +(1082035, 0, 1, 3612, 'Plans: Green Iron Gauntlets'), +(1082035, 0, 1, 6044, 'Plans: Iron Shield Spike'), +(1082035, 0, 1, 10424, 'Plans: Silvered Bronze Leggings'), +-- 26-40 +(1082640, 0, 1, 3870, 'Plans: Green Iron Shoulders'), +(1082640, 0, 1, 7449, 'Pattern: Dusky Leather Leggings'), +(1082640, 0, 1, 7090, 'Pattern: Green Silk Armor'), +(1082640, 0, 1, 6045, 'Plans: Iron Counterweight'), +(1082640, 0, 1, 4414, 'Schematic: Portable Bronze Mortar'), +(1082640, 0, 1, 4351, 'Pattern: Shadow Hood'), +(1082640, 0, 1, 3867, 'Plans: Golden Iron Destroyer'), +(1082640, 0, 1, 3871, 'Plans: Golden Scale Shoulders'), +(1082640, 0, 1, 3872, 'Plans: Golden Scale Leggings'), +(1082640, 0, 1, 11164, 'Formula: Enchant Weapon - Lesser Beastslayer'), +(1082640, 0, 1, 11165, 'Formula: Enchant Weapon - Lesser Elemental Slayer'), +(1082640, 0, 1, 4352, 'Pattern: Boots of the Enchanter'), +(1082640, 0, 1, 5774, 'Pattern: Green Silk Pack'), +(1082640, 0, 1, 7450, 'Pattern: Green Whelp Armor'), +(1082640, 0, 1, 4298, 'Pattern: Guardian Belt'), +(1082640, 0, 1, 4299, 'Pattern: Guardian Armor'), +(1082640, 0, 1, 3866, 'Plans: Jade Serpentblade'), +(1082640, 0, 1, 10601, 'Schematic: Bright-Eye Goggles'), +-- 30-45 +(1083045, 0, 1, 20974, 'Design: Jade Pendant of Blasting'), +(1083045, 0, 1, 4353, 'Pattern: Spider Belt'), +(1083045, 0, 1, 3831, 'Recipe: Major Troll\'s Blood Elixir'), +(1083045, 0, 1, 5974, 'Pattern: Guardian Cloak'), +(1083045, 0, 1, 3874, 'Plans: Polished Steel Boots'), +(1083045, 0, 1, 11167, 'Formula: Enchant Boots - Lesser Spirit'), +(1083045, 0, 1, 7085, 'Pattern: Azure Shoulders'), +(1083045, 0, 1, 7084, 'Pattern: Crimson Silk Shoulders'), +(1083045, 0, 1, 12261, 'Plans: Searing Golden Blade'), +(1083045, 0, 1, 6046, 'Plans: Steel Weapon Chain'), +(1083045, 0, 1, 20976, 'Design: Citrine Pendant of Golden Healing'), +(1083045, 0, 1, 11168, 'Formula: Enchant Shield - Lesser Block'), +(1083045, 0, 1, 7086, 'Pattern: Earthen Silk Belt'), +(1083045, 0, 1, 4300, 'Pattern: Guardian Leather Bracers'), +(1083045, 0, 1, 3873, 'Plans: Golden Scale Cuirass'), +(1083045, 0, 1, 3832, 'Recipe: Elixir of Detect Lesser Invisibility'), +(1083045, 0, 1, 4416, 'Schematic: Goblin Land Mine'), +(1083045, 0, 1, 21940, 'Design: Golden Hare'), +(1083045, 0, 1, 4356, 'Pattern: Star Belt'), +(1083045, 0, 1, 7453, 'Pattern: Swift Boots'), +(1083045, 0, 1, 3868, 'Plans: Frost Tiger Blade'), +(1083045, 0, 1, 3869, 'Plans: Shadow Crescent Axe'), +(1083045, 0, 1, 3875, 'Plans: Golden Scale Boots'), +(1083045, 0, 1, 4417, 'Schematic: Large Seaforium Charge'), +(1083045, 0, 1, 4415, 'Schematic: Craftsman\'s Monocle'), +(1083045, 0, 1, 7452, 'Pattern: Dusky Boots'), +(1083045, 0, 1, 4301, 'Pattern: Barbaric Belt'), +(1083045, 0, 1, 8384, 'Pattern: Comfortable Leather Hat'), +-- 36-50 +(1083650, 0, 1, 11202, 'Formula: Enchant Shield - Stamina'), +(1083650, 0, 1, 7975, 'Plans: Heavy Mithril Pants'), +(1083650, 0, 1, 9293, 'Recipe: Magic Resistance Potion'), +(1083650, 0, 1, 8386, 'Pattern: Big Voodoo Robe'), +(1083650, 0, 1, 10302, 'Pattern: Red Mageweave Pants'), +(1083650, 0, 1, 10300, 'Pattern: Red Mageweave Vest'), +(1083650, 0, 1, 10301, 'Pattern: White Bandit Mask'), +(1083650, 0, 1, 11204, 'Formula: Enchant Bracer - Greater Spirit'), +(1083650, 0, 1, 8385, 'Pattern: Turtle Scale Gloves'), +(1083650, 0, 1, 8387, 'Pattern: Big Voodoo Mask'), +(1083650, 0, 1, 7992, 'Plans: Blue Glittering Axe'), +(1083650, 0, 1, 10603, 'Schematic: Catseye Ultra Goggles'), +(1083650, 0, 1, 10604, 'Schematic: Mithril Heavy-bore Rifle'), +(1083650, 0, 1, 10312, 'Pattern: Red Mageweave Gloves'), +(1083650, 0, 1, 7976, 'Plans: Mithril Shield Spike'), +(1083650, 0, 1, 8029, 'Plans: Wicked Mithril Blade'), +(1083650, 0, 1, 10606, 'Schematic: Parachute Cloak'), +-- 40-55 +(1084055, 0, 1, 11208, 'Formula: Enchant Weapon - Demonslaying'), +(1084055, 0, 1, 21944, 'Design: Truesilver Boar'), +(1084055, 0, 1, 11224, 'Formula: Enchant Shield - Frost Resistance'), +(1084055, 0, 1, 10315, 'Pattern: Red Mageweave Shoulders'), +(1084055, 0, 1, 7989, 'Plans: Mithril Spurs'), +(1084055, 0, 1, 9295, 'Recipe: Invisibility Potion'), +(1084055, 0, 1, 8390, 'Pattern: Big Voodoo Cloak'), +(1084055, 0, 1, 8389, 'Pattern: Big Voodoo Pants'), +(1084055, 0, 1, 10320, 'Pattern: Red Mageweave Headband'), +(1084055, 0, 1, 7993, 'Plans: Dazzling Mithril Rapier'), +(1084055, 0, 1, 9297, 'Recipe: Elixir of Dream Vision'), +(1084055, 0, 1, 21945, 'Design: The Aquamarine Ward'), +(1084055, 0, 1, 11225, 'Formula: Enchant Bracer - Greater Stamina'), +(1084055, 0, 1, 7990, 'Plans: Heavy Mithril Helm'), +(1084055, 0, 1, 9298, 'Recipe: Elixir of Giants'), +(1084055, 0, 1, 21947, 'Design: Gem Studded Band'), +(1084055, 0, 1, 11226, 'Formula: Enchant Gloves - Riding Skill'), +(1084055, 0, 1, 12682, 'Plans: Thorium Armor'), +(1084055, 0, 1, 12683, 'Plans: Thorium Belt'), +(1084055, 0, 1, 3395, 'Recipe: Limited Invulnerability Potion'), +(1084055, 0, 1, 10608, 'Schematic: Sniper Scope'), +-- 46-60 +(1084660, 0, 1, 12684, 'Plans: Thorium Bracers'), +(1084660, 0, 1, 14467, 'Pattern: Frostweave Robe'), +(1084660, 0, 1, 14466, 'Pattern: Frostweave Tunic'), +(1084660, 0, 1, 12685, 'Plans: Radiant Belt'), +(1084660, 0, 1, 14470, 'Pattern: Runecloth Tunic'), +(1084660, 0, 1, 16043, 'Schematic: Thorium Rifle'), +(1084660, 0, 1, 16215, 'Formula: Enchant Boots - Greater Stamina'), +(1084660, 0, 1, 21949, 'Design: Ruby Serpent'), +(1084660, 0, 1, 16044, 'Schematic: Lifelike Mechanical Toad'), +(1084660, 0, 1, 14474, 'Pattern: Frostweave Gloves'), +(1084660, 0, 1, 8028, 'Plans: Runed Mithril Hammer'), +(1084660, 0, 1, 12689, 'Plans: Radiant Breastplate'), +(1084660, 0, 1, 12691, 'Plans: Wildthorn Mail'), +(1084660, 0, 1, 16218, 'Formula: Enchant Bracer - Superior Spirit'), +(1084660, 0, 1, 15731, 'Pattern: Runic Leather Gauntlets'), +(1084660, 0, 1, 14478, 'Pattern: Brightcloth Robe'), +(1084660, 0, 1, 14479, 'Pattern: Brightcloth Gloves'), +(1084660, 0, 1, 15737, 'Pattern: Chimeric Boots'), +(1084660, 0, 1, 14484, 'Pattern: Brightcloth Cloak'), +(1084660, 0, 1, 16220, 'Formula: Enchant Boots - Spirit'), +-- 50-63 +(1085063, 0, 1, 12692, 'Plans: Thorium Shield Spike'), +(1085063, 0, 1, 13486, 'Recipe: Transmute Undeath to Water'), +(1085063, 0, 1, 13488, 'Recipe: Transmute Life to Earth'), +(1085063, 0, 1, 13489, 'Recipe: Transmute Earth to Life'), +(1085063, 0, 1, 13487, 'Recipe: Transmute Water to Undeath'), +(1085063, 0, 1, 12693, 'Plans: Thorium Boots'), +(1085063, 0, 1, 12694, 'Plans: Thorium Helm'), +(1085063, 0, 1, 15746, 'Pattern: Chimeric Leggings'), +(1085063, 0, 1, 15745, 'Pattern: Runic Leather Belt'), +(1085063, 0, 1, 15743, 'Pattern: Heavy Scorpid Belt'), +(1085063, 0, 1, 13490, 'Recipe: Greater Stoneshield Potion'), +(1085063, 0, 1, 14489, 'Pattern: Frostweave Pants'), +(1085063, 0, 1, 12695, 'Plans: Radiant Gloves'), +(1085063, 0, 1, 14492, 'Pattern: Felcloth Boots'), +(1085063, 0, 1, 16051, 'Schematic: Thorium Shells'), +(1085063, 0, 1, 13492, 'Recipe: Purification Potion'), +(1085063, 0, 1, 13493, 'Recipe: Greater Arcane Elixir'), +(1085063, 0, 1, 14491, 'Pattern: Runecloth Pants'), +(1085063, 0, 1, 12697, 'Plans: Radiant Boots'), +(1085063, 0, 1, 15755, 'Pattern: Chimeric Vest'), +(1085063, 0, 1, 14494, 'Pattern: Brightcloth Pants'), +(1085063, 0, 1, 15757, 'Pattern: Wicked Leather Pants'), +(1085063, 0, 1, 14498, 'Pattern: Runecloth Headband'), +(1085063, 0, 1, 12702, 'Plans: Radiant Circlet'), +(1085063, 0, 1, 16245, 'Formula: Enchant Boots - Greater Agility'), +(1085063, 0, 1, 21953, 'Design: Emerald Owl'), +-- 56-63 +-- Uncommon Patterns +(1080002, 0, 2, 13518, 'Recipe: Potion of Petrification'), +(1080002, 0, 2, 15765, 'Pattern: Runic Leather Pants'), +(1080002, 0, 2, 12704, 'Plans: Thorium Leggings'), +(1080002, 0, 2, 16055, 'Schematic: Arcane Bomb'), +(1080002, 0, 2, 14499, 'Pattern: Mooncloth Bag'), +(1080002, 0, 2, 16251, 'Formula: Enchant Bracer - Superior Stamina'), +(1080002, 0, 2, 12713, 'Plans: Radiant Leggings'), +(1080002, 0, 2, 14504, 'Pattern: Runecloth Shoulders'), +(1080002, 0, 2, 14506, 'Pattern: Felcloth Robe'), +(1080002, 0, 2, 14508, 'Pattern: Felcloth Shoulders'), +(1080002, 0, 2, 16253, 'Formula: Enchant Chest - Greater Stats'), +-- Rare Patterns +(1080003, 0, 3, 15742, 'Pattern: Warbear Harness'), +(1080003, 0, 3, 12698, 'Plans: Dawnbringer Shoulders'), +(1080003, 0, 3, 12703, 'Plans: Storm Gauntlets'), +(1080003, 0, 3, 12711, 'Plans: Whitesoul Helm'), +(1080003, 0, 3, 14497, 'Pattern: Mooncloth Leggings'), +(1080003, 0, 3, 14501, 'Pattern: Mooncloth Vest'), +(1080003, 0, 3, 14507, 'Pattern: Mooncloth Shoulders'), +(1080003, 0, 3, 12716, 'Plans: Helm of the Great Chief'), +(1080003, 0, 3, 14509, 'Pattern: Mooncloth Circlet'), +(1080003, 0, 3, 14510, 'Pattern: Bottomless Bag'), +-- Epic Patterns +(1080004, 0, 4, 12717, 'Plans: Lionheart Helm'), +(1080004, 0, 4, 22388, 'Plans: Titanic Leggings'), +(1080004, 0, 4, 14511, 'Pattern: Gloves of Spell Mastery'), +(1080004, 0, 4, 12720, 'Plans: Stronghold Gauntlets'), +(1080004, 0, 4, 12728, 'Plans: Invulnerable Mail'), +(1080004, 0, 4, 22390, 'Plans: Persuader'), +(1080004, 0, 4, 22389, 'Plans: Sageblade'); + +INSERT INTO `reference_loot_template` (`Entry`, `Chance`, `Reference`, `GroupId`, `Item`, `Comment`) VALUES +(1085663, 75, 1080002, 1, 2, 'Uncommon Patterns'), +(1085663, 20, 1080003, 1, 3, 'Rare Patterns'), +(1085663, 5, 1080004, 1, 4, 'Epic Patterns'), + +-- TBC +-- 61+ Extremely Rare Outside Raids and Heroics +-- Normals: 25% +-- Elite: 100% +-- 61-65 +(1186165, 1.5, 0, 1, 5760, 'Eternium Lockbox'), +(1186165, 0.6, 1180002, 2, 1, 'Uncommon Patterns'), +(1186165, 0.3, 1180003, 2, 2, 'Rare Patterns'), +(1186165, 0.1, 1180004, 2, 3, 'Epic Patterns'), +-- 66-67 +(1186673, 1.5, 0, 1, 31952, 'Khorium Lockbox'), +(1186673, 0.6, 1180002, 2, 1, 'Uncommon Patterns'), +(1186673, 0.3, 1180003, 2, 2, 'Rare Patterns'), +(1186673, 0.1, 1180004, 2, 3, 'Epic Patterns'); + +INSERT INTO `reference_loot_template` (`Entry`, `Chance`, `GroupId`, `Item`, `Comment`) VALUES +-- Uncommon Patterns +(1180002, 0, 2, 22542, 'Formula: Enchant Boots - Vitality'), +(1180002, 0, 2, 16253, 'Formula: Enchant Chest - Greater Stats'), +(1180002, 0, 2, 23154, 'Design: Stormy Azure Moonstone'), +(1180002, 0, 2, 33186, 'Plans: Adamantite Weapon Chain'), +(1180002, 0, 2, 22903, 'Recipe: Insane Strength Potion'), +(1180002, 0, 2, 22904, 'Recipe: Elixir of the Searching Eye'), +(1180002, 0, 2, 23810, 'Schematic: Crashin\' Thrashin\' Robot'), +(1180002, 0, 2, 22548, 'Formula: Enchant Cloak - Major Resistance'), +(1180002, 0, 2, 22532, 'Formula: Enchant Bracer - Restore Mana Prime'), +(1180002, 0, 2, 25887, 'Schematic: Purple Smoke Flare'), +(1180002, 0, 2, 22540, 'Formula: Enchant Shield - Shield Block'), +(1180002, 0, 2, 28270, 'Formula: Enchant Chest - Major Resilience'), +(1180002, 0, 2, 22553, 'Formula: Enchant Weapon - Potency'), +(1180002, 0, 2, 22912, 'Recipe: Heroic Potion'), +(1180002, 0, 2, 22913, 'Recipe: Haste Potion'), +(1180002, 0, 2, 22914, 'Recipe: Destruction Potion'), +(1180002, 0, 2, 29714, 'Pattern: Drums of Restoration'), +(1180002, 0, 2, 22919, 'Recipe: Elixir of Major Mageblood'), +(1180002, 0, 2, 22541, 'Formula: Enchant Shield - Resistance'), +(1180002, 0, 2, 22557, 'Formula: Enchant Weapon - Battlemaster'), +(1180002, 0, 2, 22558, 'Formula: Enchant Weapon - Spellsurge'), +(1180002, 0, 2, 22926, 'Recipe: Elixir of Empowerment'), +-- Rare Patterns +(1180003, 0, 3, 23883, 'Schematic: Healing Potion Injector'), +(1180003, 0, 3, 23804, 'Schematic: Power Amplification Goggles'), +(1180003, 0, 3, 23884, 'Schematic: Mana Potion Injector'), +(1180003, 0, 3, 24163, 'Design: Heavy Felsteel Ring'), +(1180003, 0, 3, 22146, 'Book: Gift of the Wild III'), +(1180003, 0, 3, 22153, 'Tome of Arcane Brilliance 2'), +(1180003, 0, 3, 24192, 'Design: Bright Living Ruby'), +(1180003, 0, 3, 24193, 'Design: Bold Living Ruby'), +(1180003, 0, 3, 24194, 'Design: Delicate Living Ruby'), +(1180003, 0, 3, 24195, 'Design: Teardrop Living Ruby'), +(1180003, 0, 3, 24196, 'Design: Runed Living Ruby'), +(1180003, 0, 3, 24197, 'Design: Subtle Living Ruby'), +(1180003, 0, 3, 24198, 'Design: Flashing Living Ruby'), +(1180003, 0, 3, 24199, 'Design: Solid Star of Elune'), +(1180003, 0, 3, 24200, 'Design: Sparkling Star of Elune'), +(1180003, 0, 3, 24201, 'Design: Lustrous Star of Elune'), +(1180003, 0, 3, 24202, 'Design: Stormy Star of Elune'), +(1180003, 0, 3, 24203, 'Design: Brilliant Dawnstone'), +(1180003, 0, 3, 24204, 'Design: Smooth Dawnstone'), +(1180003, 0, 3, 24205, 'Design: Rigid Dawnstone'), +(1180003, 0, 3, 24206, 'Design: Gleaming Dawnstone'), +(1180003, 0, 3, 24207, 'Design: Thick Dawnstone'), +(1180003, 0, 3, 24209, 'Design: Sovereign Nightseye'), +(1180003, 0, 3, 24210, 'Design: Shifting Nightseye'), +(1180003, 0, 3, 24211, 'Design: Glowing Nightseye'), +(1180003, 0, 3, 24212, 'Design: Royal Nightseye'), +(1180003, 0, 3, 24213, 'Design: Inscribed Noble Topaz'), +(1180003, 0, 3, 24214, 'Design: Potent Noble Topaz'), +(1180003, 0, 3, 24215, 'Design: Luminous Noble Topaz'), +(1180003, 0, 3, 24216, 'Design: Glinting Noble Topaz'), +(1180003, 0, 3, 24217, 'Design: Enduring Talasite'), +(1180003, 0, 3, 24218, 'Design: Radiant Talasite'), +(1180003, 0, 3, 24219, 'Design: Dazzling Talasite'), +(1180003, 0, 3, 24220, 'Design: Jagged Talasite'), +(1180003, 0, 3, 24296, 'Pattern: Unyielding Bracers'), +(1180003, 0, 3, 24297, 'Pattern: Bracers of Havok'), +(1180003, 0, 3, 24298, 'Pattern: Blackstrike Bracers'), +(1180003, 0, 3, 24299, 'Pattern: Cloak of the Black Void'), +(1180003, 0, 3, 24300, 'Pattern: Cloak of Eternity'), +(1180003, 0, 3, 24301, 'Pattern: White Remedy Cape'), +(1180003, 0, 3, 29549, 'Codex: Prayer of Fortitude III'), +(1180003, 0, 3, 29550, 'Tome of Conjure Water IX'), +(1180003, 0, 3, 31501, 'Tome of Conjure Food VIII'), +(1180003, 0, 3, 31837, 'Codex: Prayer of Shadow Protection II'), +(1180003, 0, 3, 31875, 'Design: Great Dawnstone'), +(1180003, 0, 3, 31876, 'Design: Balanced Nightseye'), +(1180003, 0, 3, 31877, 'Design: Infused Nightseye'), +(1180003, 0, 3, 31878, 'Design: Veiled Noble Topaz'), +(1180003, 0, 3, 31879, 'Design: Wicked Noble Topaz'), +(1180003, 0, 3, 24164, 'Design: Delicate Eternium Ring'), +(1180003, 0, 3, 24166, 'Design: Thick Felsteel Necklace'), +(1180003, 0, 3, 24167, 'Design: Living Ruby Pendant'), +(1180003, 0, 3, 24168, 'Design: Braided Eternium Chain'), +(1180003, 0, 3, 24169, 'Design: Eye of the Night'), +(1180003, 0, 3, 28279, 'Formula: Enchant Boots - Cat\'s Swiftness'), +(1180003, 0, 3, 28280, 'Formula: Enchant Boots - Boar\'s Speed'), +(1180003, 0, 3, 24165, 'Design: Blazing Eternium Band'), +(1180003, 0, 3, 24170, 'Design: Embrace of the Dawn'), +(1180003, 0, 3, 24171, 'Design: Chain of the Twilight Owl'), +(1180003, 0, 3, 25905, 'Design: Tenacious Earthstorm Diamond'), +(1180003, 0, 3, 25906, 'Design: Brutal Earthstorm Diamond'), +(1180003, 0, 3, 25907, 'Design: Destructive Skyfire Diamond'), +(1180003, 0, 3, 25909, 'Design: Mystical Skyfire Diamond'), +(1180003, 0, 3, 32411, 'Design: Thundering Skyfire Diamond'), +(1180003, 0, 3, 23802, 'Schematic: Ornate Khorium Rifle'), +-- Epic Patterns +(1180004, 0, 4, 23620, 'Plans: Felfury Gauntlets'), +(1180004, 0, 4, 23621, 'Plans: Gauntlets of the Iron Tower'), +(1180004, 0, 4, 23622, 'Plans: Steelgrip Gauntlets'), +(1180004, 0, 4, 23623, 'Plans: Storm Helm'), +(1180004, 0, 4, 23624, 'Plans: Helm of the Stalwart Defender'), +(1180004, 0, 4, 23625, 'Plans: Oathkeeper\'s Helm'), +(1180004, 0, 4, 23626, 'Plans: Black Felsteel Bracers'), +(1180004, 0, 4, 23627, 'Plans: Bracers of the Green Fortress'), +(1180004, 0, 4, 23628, 'Plans: Blessed Bracers'), +(1180004, 0, 4, 23629, 'Plans: Felsteel Longblade'), +(1180004, 0, 4, 23630, 'Plans: Khorium Champion'), +(1180004, 0, 4, 23631, 'Plans: Fel Edged Battleaxe'), +(1180004, 0, 4, 23632, 'Plans: Felsteel Reaper'), +(1180004, 0, 4, 23633, 'Plans: Runic Hammer'), +(1180004, 0, 4, 23634, 'Plans: Fel Hardened Maul'), +(1180004, 0, 4, 23635, 'Plans: Eternium Runed Blade'), +(1180004, 0, 4, 23636, 'Plans: Dirge'), +(1180004, 0, 4, 23637, 'Plans: Hand of Eternity'), +(1180004, 0, 4, 24302, 'Pattern: Unyielding Girdle'), +(1180004, 0, 4, 24303, 'Pattern: Girdle of Ruination'), +(1180004, 0, 4, 24304, 'Pattern: Black Belt of Knowledge'), +(1180004, 0, 4, 24305, 'Pattern: Resolute Cape'), +(1180004, 0, 4, 24306, 'Pattern: Vengeance Wrap'), +(1180004, 0, 4, 24307, 'Pattern: Manaweave Cloak'), +(1180004, 0, 4, 29723, 'Pattern: Cobrascale Hood'), +(1180004, 0, 4, 29724, 'Pattern: Cobrascale Gloves'), +(1180004, 0, 4, 29725, 'Pattern: Windscale Hood'), +(1180004, 0, 4, 29726, 'Pattern: Hood of Primal Life'), +(1180004, 0, 4, 29727, 'Pattern: Gloves of the Living Touch'), +(1180004, 0, 4, 29728, 'Pattern: Windslayer Wraps'), +(1180004, 0, 4, 29729, 'Pattern: Living Dragonscale Helm'), +(1180004, 0, 4, 29730, 'Pattern: Earthen Netherscale Boots'), +(1180004, 0, 4, 29731, 'Pattern: Windstrike Gloves'), +(1180004, 0, 4, 29732, 'Pattern: Netherdrake Helm'), +(1180004, 0, 4, 29733, 'Pattern: Netherdrake Gloves'), +(1180004, 0, 4, 29734, 'Pattern: Thick Netherscale Breastplate'), +(1180004, 0, 4, 33954, 'Plans: Hammer of Righteous Might'); + +INSERT INTO `reference_loot_template` (`Entry`, `Chance`, `GroupId`, `Item`, `Comment`) VALUES +-- Bags +-- 1-10 +(1090110, 0, 1, 805, 'Small Red Pouch'), +(1090110, 0, 1, 828, 'Small Blue Pouch'), +(1090110, 0, 1, 4496, 'Small Brown Pouch'), +(1090110, 0, 1, 5571, 'Small Black Pouch'), +(1090110, 0, 1, 5572, 'Small Green Pouch'), +-- 11-20 +(1091120, 0, 1, 856, 'Blue Leather Bag'), +(1091120, 0, 1, 2657, 'Red Leather Bag'), +(1091120, 0, 1, 5573, 'Green Leather Bag'), +(1091120, 0, 1, 5574, 'White Leather Bag'), +-- 21-30 +(1092130, 0, 1, 804, 'Large Blue Sack'), +(1092130, 0, 1, 857, 'Large Red Sack'), +(1092130, 0, 1, 5575, 'Large Green Sack'), +(1092130, 0, 1, 5576, 'Large Brown Sack'), +-- 31-40 +(1093140, 0, 1, 1725, 'Large Knapsack'), +-- 41-50 +(1094150, 20, 1, 1685, 'Troll-hide Bag'), +(1094150, 80, 1, 3914, 'Journeyman\'s Backpack'), +-- 51+ +(1095162, 0, 1, 3914, 'Journeyman\'s Backpack'), +(1095162, 0, 1, 4500, 'Traveler\'s Backpack'); + +-- Master Reference Tables +-- Beasts do not drop: Potions, Scrolls +-- Beasts do drop: Patterns, Bags, Gems, Lockboxes +DELETE FROM `reference_loot_template` WHERE `Entry` BETWEEN 1000001 AND 1000062; +DELETE FROM `reference_loot_template` WHERE `Entry` BETWEEN 1100058 AND 1100072; +DELETE FROM `reference_loot_template` WHERE `Entry` BETWEEN 1000106 AND 1000162; +DELETE FROM `reference_loot_template` WHERE `Entry` BETWEEN 1100158 AND 1100172; +DELETE FROM `reference_loot_template` WHERE `Entry` BETWEEN 1000201 AND 1000263; +DELETE FROM `reference_loot_template` WHERE `Entry` BETWEEN 1100258 AND 1100272; +DELETE FROM `reference_loot_template` WHERE `Entry` BETWEEN 1000306 AND 1000363; +DELETE FROM `reference_loot_template` WHERE `Entry` BETWEEN 1100358 AND 1100372; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +-- I will not be messing with Level Ranges 1-4 as these have been heavily researched and sniffed by contributors +-- (1000001, 1, 1000105, 20, 0, 'Vanilla Greys 1-5 Level Range'), +-- (1000001, 2, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +-- (1000002, 1, 1000105, 20, 0, 'Vanilla Greys 1-5 Level Range'), +-- (1000002, 2, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +-- (1000003, 1, 1000105, 20, 0, 'Vanilla Greys 1-5 Level Range'), +-- (1000003, 2, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +-- (1000004, 1, 1000105, 20, 0, 'Vanilla Greys 1-5 Level Range'), +-- (1000004, 2, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +(1000005, 1, 1000105, 20, 0, 'Vanilla Greys 1-5 Level Range'), +(1000005, 2, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +-- Beasts +(1000006, 1, 1000610, 10, 0, 'Vanilla Greys 6-10 Level Range'), +(1000006, 4, 1070610, 100, 0, 'Vanilla Miscellaneous 6-10 Level Range'), +(1000006, 5, 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000006, 6, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +(1000007, 1, 1000610, 6, 0, 'Vanilla Greys 6-10 Level Range'), +(1000007, 2, 1010708, 5, 2, 'Vanilla Whites 7-8 Level Range'), +(1000007, 5, 1070610, 100, 0, 'Vanilla Miscellaneous 6-10 Level Range'), +(1000007, 6, 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000007, 7, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +(1000008, 1, 1000610, 6, 0, 'Vanilla Greys 6-10 Level Range'), +(1000008, 2, 1010708, 2.5, 2, 'Vanilla Whites 7-8 Level Range'), +(1000008, 3, 1010809, 2.5, 2, 'Vanilla Whites 8-9 Level Range'), +(1000008, 4, 1020812, 0.75, 3, 'Vanilla Greens 8-12 Level Range'), +(1000008, 7, 1070610, 100, 0, 'Vanilla Miscellaneous 6-10 Level Range'), +(1000008, 8, 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000008, 9, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +(1000009, 1, 1000610, 6, 0, 'Vanilla Greys 6-10 Level Range'), +(1000009, 2, 1010910, 2.5, 2, 'Vanilla Whites 9-10 Level Range'), +(1000009, 3, 1010809, 2.5, 2, 'Vanilla Whites 8-9 Level Range'), +(1000009, 4, 1020812, 1, 3, 'Vanilla Greens 8-12 Level Range'), +(1000009, 7, 1070610, 100, 0, 'Vanilla Miscellaneous 6-10 Level Range'), +(1000009, 8, 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000009, 9, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +(1000010, 1, 1000610, 6, 0, 'Vanilla Greys 6-10 Level Range'), +(1000010, 2, 1010910, 2.5, 2, 'Vanilla Whites 9-10 Level Range'), +(1000010, 3, 1011011, 2.5, 2, 'Vanilla Whites 10-11 Level Range'), +(1000010, 4, 1021014, 1, 3, 'Vanilla Greens 10-14 Level Range'), +(1000010, 5, 1020812, 1, 3, 'Vanilla Greens 8-12 Level Range'), +(1000010, 8, 1070610, 100, 0, 'Vanilla Miscellaneous 6-10 Level Range'), +(1000010, 9, 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000010, 10, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +(1000011, 1, 1001115, 6, 0, 'Vanilla Greys 11-15 Level Range'), +(1000011, 2, 1011112, 2.5, 2, 'Vanilla Whites 11-12 Level Range'), +(1000011, 3, 1011011, 2.5, 2, 'Vanilla Whites 10-11 Level Range'), +(1000011, 4, 1021115, 0.67, 3, 'Vanilla Greens 11-15 Level Range'), +(1000011, 5, 1021014, 0.67, 3, 'Vanilla Greens 10-14 Level Range'), +(1000011, 6, 1020812, 0.67, 3, 'Vanilla Greens 8-12 Level Range'), +(1000011, 9, 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000011, 10, 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000011, 11, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000012, 1, 1001115, 6, 0, 'Vanilla Greys 11-15 Level Range'), +(1000012, 2, 1011112, 2.5, 2, 'Vanilla Whites 11-12 Level Range'), +(1000012, 3, 1011213, 2.5, 2, 'Vanilla Whites 12-13 Level Range'), +(1000012, 4, 1021115, 0.5, 3, 'Vanilla Greens 11-15 Level Range'), +(1000012, 5, 1021014, 0.5, 3, 'Vanilla Greens 10-14 Level Range'), +(1000012, 6, 1021216, 0.5, 3, 'Vanilla Greens 12-16 Level Range'), +(1000012, 7, 1020812, 0.5, 3, 'Vanilla Greens 8-12 Level Range'), +(1000012, 10, 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000012, 11, 1080620, 0.15, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000012, 12, 1081225, 0.15, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000012, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000013, 1, 1001115, 6, 0, 'Vanilla Greys 11-15 Level Range'), +(1000013, 2, 1011314, 2.5, 2, 'Vanilla Whites 13-14 Level Range'), +(1000013, 3, 1011213, 2.5, 2, 'Vanilla Whites 12-13 Level Range'), +(1000013, 4, 1021317, 0.5, 3, 'Vanilla Greens 13-17 Level Range'), +(1000013, 5, 1021115, 0.5, 3, 'Vanilla Greens 11-15 Level Range'), +(1000013, 6, 1021014, 0.5, 3, 'Vanilla Greens 10-14 Level Range'), +(1000013, 7, 1021216, 0.5, 3, 'Vanilla Greens 12-16 Level Range'), +(1000013, 10, 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000013, 11, 1080620, 0.15, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000013, 12, 1081225, 0.15, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000013, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000014, 1, 1001115, 6, 0, 'Vanilla Greys 11-15 Level Range'), +(1000014, 2, 1011314, 2.5, 2, 'Vanilla Whites 13-14 Level Range'), +(1000014, 3, 1011415, 2.5, 2, 'Vanilla Whites 14-15 Level Range'), +(1000014, 4, 1021317, 0.4, 3, 'Vanilla Greens 13-17 Level Range'), +(1000014, 5, 1021115, 0.4, 3, 'Vanilla Greens 11-15 Level Range'), +(1000014, 6, 1021014, 0.4, 3, 'Vanilla Greens 10-14 Level Range'), +(1000014, 7, 1021216, 0.4, 3, 'Vanilla Greens 12-16 Level Range'), +(1000014, 8, 1021418, 0.4, 3, 'Vanilla Greens 14-18 Level Range'), +(1000014, 11, 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000014, 12, 1080620, 0.15, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000014, 13, 1081225, 0.15, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000014, 14, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000015, 1, 1001115, 6, 0, 'Vanilla Greys 11-15 Level Range'), +(1000015, 2, 1011415, 5, 2, 'Vanilla Whites 14-15 Level Range'), +(1000015, 3, 1021317, 0.4, 3, 'Vanilla Greens 13-17 Level Range'), +(1000015, 4, 1021115, 0.4, 3, 'Vanilla Greens 11-15 Level Range'), +(1000015, 5, 1021216, 0.4, 3, 'Vanilla Greens 12-16 Level Range'), +(1000015, 6, 1021418, 0.4, 3, 'Vanilla Greens 14-18 Level Range'), +(1000015, 7, 1021519, 0.4, 3, 'Vanilla Greens 15-19 Level Range'), +(1000015, 10, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000015, 11, 1080620, 0.15, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000015, 12, 1081225, 0.15, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000015, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000016, 1, 1001620, 6, 0, 'Vanilla Greys 16-20 Level Range'), +(1000016, 2, 1021317, 0.4, 3, 'Vanilla Greens 13-17 Level Range'), +(1000016, 3, 1021216, 0.4, 3, 'Vanilla Greens 12-16 Level Range'), +(1000016, 4, 1021418, 0.4, 3, 'Vanilla Greens 14-18 Level Range'), +(1000016, 5, 1021519, 0.4, 3, 'Vanilla Greens 15-19 Level Range'), +(1000016, 6, 1021620, 0.4, 3, 'Vanilla Greens 16-20 Level Range'), +(1000016, 9, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000016, 10, 1080620, 0.1, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000016, 11, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000016, 12, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000016, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000017, 1, 1001620, 6, 0, 'Vanilla Greys 16-20 Level Range'), +(1000017, 2, 1021317, 0.4, 3, 'Vanilla Greens 13-17 Level Range'), +(1000017, 3, 1021418, 0.4, 3, 'Vanilla Greens 14-18 Level Range'), +(1000017, 4, 1021519, 0.4, 3, 'Vanilla Greens 15-19 Level Range'), +(1000017, 5, 1021620, 0.4, 3, 'Vanilla Greens 16-20 Level Range'), +(1000017, 6, 1021721, 0.4, 3, 'Vanilla Greens 17-21 Level Range'), +(1000017, 9, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000017, 10, 1080620, 0.1, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000017, 11, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000017, 12, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000017, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000018, 1, 1001620, 6, 0, 'Vanilla Greys 16-20 Level Range'), +(1000018, 2, 1011822, 1, 2, 'Vanilla Whites 18-22 Level Range'), +(1000018, 3, 1021418, 0.4, 3, 'Vanilla Greens 14-18 Level Range'), +(1000018, 4, 1021519, 0.4, 3, 'Vanilla Greens 15-19 Level Range'), +(1000018, 5, 1021620, 0.4, 3, 'Vanilla Greens 16-20 Level Range'), +(1000018, 6, 1021721, 0.4, 3, 'Vanilla Greens 17-21 Level Range'), +(1000018, 7, 1021822, 0.4, 3, 'Vanilla Greens 18-22 Level Range'), +(1000018, 10, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000018, 11, 1080620, 0.1, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000018, 12, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000018, 13, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000018, 14, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000019, 1, 1001620, 6, 0, 'Vanilla Greys 16-20 Level Range'), +(1000019, 2, 1011822, 0.5, 2, 'Vanilla Whites 18-22 Level Range'), +(1000019, 3, 1011923, 0.5, 2, 'Vanilla Whites 19-23 Level Range'), +(1000019, 4, 1021519, 0.4, 3, 'Vanilla Greens 15-19 Level Range'), +(1000019, 5, 1021620, 0.4, 3, 'Vanilla Greens 16-20 Level Range'), +(1000019, 6, 1021721, 0.4, 3, 'Vanilla Greens 17-21 Level Range'), +(1000019, 7, 1021822, 0.4, 3, 'Vanilla Greens 18-22 Level Range'), +(1000019, 8, 1021923, 0.4, 3, 'Vanilla Greens 19-23 Level Range'), +(1000019, 9, 1031922, 0.1, 4, 'Vanilla Blues 19-22 Level Range'), +(1000019, 12, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000019, 13, 1080620, 0.1, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000019, 14, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000019, 15, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000019, 16, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000020, 1, 1001620, 6, 0, 'Vanilla Greys 16-20 Level Range'), +(1000020, 2, 1012024, 0.3333, 2, 'Vanilla Whites 20-24 Level Range'), +(1000020, 3, 1011822, 0.3333, 2, 'Vanilla Whites 18-22 Level Range'), +(1000020, 4, 1011923, 0.3333, 2, 'Vanilla Whites 19-23 Level Range'), +(1000020, 5, 1022024, 0.4, 3, 'Vanilla Greens 20-24 Level Range'), +(1000020, 6, 1021620, 0.4, 3, 'Vanilla Greens 16-20 Level Range'), +(1000020, 7, 1021721, 0.4, 3, 'Vanilla Greens 17-21 Level Range'), +(1000020, 8, 1021822, 0.4, 3, 'Vanilla Greens 18-22 Level Range'), +(1000020, 9, 1021923, 0.4, 3, 'Vanilla Greens 19-23 Level Range'), +(1000020, 10, 1032023, 0.05, 4, 'Vanilla Blues 20-23 Level Range'), +(1000020, 11, 1031922, 0.05, 4, 'Vanilla Blues 19-22 Level Range'), +(1000020, 14, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000020, 15, 1080620, 0.075, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000020, 16, 1081225, 0.075, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000020, 17, 1082035, 0.075, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000020, 18, 1081630, 0.075, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000020, 19, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000021, 1, 1002125, 6, 0, 'Vanilla Greys 21-25 Level Range'), +(1000021, 2, 1012024, 0.25, 2, 'Vanilla Whites 20-24 Level Range'), +(1000021, 3, 1012125, 0.25, 2, 'Vanilla Whites 21-25 Level Range'), +(1000021, 4, 1011822, 0.25, 2, 'Vanilla Whites 18-22 Level Range'), +(1000021, 5, 1011923, 0.25, 2, 'Vanilla Whites 19-23 Level Range'), +(1000021, 6, 1022125, 0.4, 3, 'Vanilla Greens 21-25 Level Range'), +(1000021, 7, 1022024, 0.4, 3, 'Vanilla Greens 20-24 Level Range'), +(1000021, 8, 1021721, 0.4, 3, 'Vanilla Greens 17-21 Level Range'), +(1000021, 9, 1021822, 0.4, 3, 'Vanilla Greens 18-22 Level Range'), +(1000021, 10, 1021923, 0.4, 3, 'Vanilla Greens 19-23 Level Range'), +(1000021, 11, 1032124, 0.0333, 4, 'Vanilla Blues 21-24 Level Range'), +(1000021, 12, 1032023, 0.0333, 4, 'Vanilla Blues 20-23 Level Range'), +(1000021, 13, 1031922, 0.0333, 4, 'Vanilla Blues 19-22 Level Range'), +(1000021, 16, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000021, 17, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000021, 18, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000021, 19, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000021, 20, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000022, 1, 1002125, 6, 0, 'Vanilla Greys 21-25 Level Range'), +(1000022, 2, 1012024, 0.25, 2, 'Vanilla Whites 20-24 Level Range'), +(1000022, 3, 1012125, 0.25, 2, 'Vanilla Whites 21-25 Level Range'), +(1000022, 4, 1011822, 0.25, 2, 'Vanilla Whites 18-22 Level Range'), +(1000022, 5, 1011923, 0.25, 2, 'Vanilla Whites 19-23 Level Range'), +(1000022, 6, 1022125, 0.4, 3, 'Vanilla Greens 21-25 Level Range'), +(1000022, 7, 1022024, 0.4, 3, 'Vanilla Greens 20-24 Level Range'), +(1000022, 8, 1022226, 0.4, 3, 'Vanilla Greens 22-26 Level Range'), +(1000022, 9, 1021822, 0.4, 3, 'Vanilla Greens 18-22 Level Range'), +(1000022, 10, 1021923, 0.4, 3, 'Vanilla Greens 19-23 Level Range'), +(1000022, 11, 1032124, 0.025, 4, 'Vanilla Blues 21-24 Level Range'), +(1000022, 12, 1032023, 0.025, 4, 'Vanilla Blues 20-23 Level Range'), +(1000022, 13, 1032225, 0.025, 4, 'Vanilla Blues 22-25 Level Range'), +(1000022, 14, 1031922, 0.025, 4, 'Vanilla Blues 19-22 Level Range'), +(1000022, 17, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000022, 18, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000022, 19, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000022, 20, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000022, 21, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000023, 1, 1002125, 6, 0, 'Vanilla Greys 21-25 Level Range'), +(1000023, 2, 1012024, 0.3333, 2, 'Vanilla Whites 20-24 Level Range'), +(1000023, 3, 1012125, 0.3333, 2, 'Vanilla Whites 21-25 Level Range'), +(1000023, 4, 1011923, 0.3333, 2, 'Vanilla Whites 19-23 Level Range'), +(1000023, 5, 1022327, 0.4, 3, 'Vanilla Greens 23-27 Level Range'), +(1000023, 6, 1022125, 0.4, 3, 'Vanilla Greens 21-25 Level Range'), +(1000023, 7, 1022024, 0.4, 3, 'Vanilla Greens 20-24 Level Range'), +(1000023, 8, 1022226, 0.4, 3, 'Vanilla Greens 22-26 Level Range'), +(1000023, 9, 1021923, 0.4, 3, 'Vanilla Greens 19-23 Level Range'), +(1000023, 10, 1032124, 0.025, 4, 'Vanilla Blues 21-24 Level Range'), +(1000023, 11, 1032023, 0.025, 4, 'Vanilla Blues 20-23 Level Range'), +(1000023, 12, 1032225, 0.025, 4, 'Vanilla Blues 22-25 Level Range'), +(1000023, 13, 1032326, 0.025, 4, 'Vanilla Blues 23-26 Level Range'), +(1000023, 16, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000023, 17, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000023, 18, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000023, 19, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000023, 20, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000024, 1, 1002125, 6, 0, 'Vanilla Greys 21-25 Level Range'), +(1000024, 2, 1012024, 0.5, 2, 'Vanilla Whites 20-24 Level Range'), +(1000024, 3, 1012125, 0.5, 2, 'Vanilla Whites 21-25 Level Range'), +(1000024, 4, 1022327, 0.4, 3, 'Vanilla Greens 23-27 Level Range'), +(1000024, 5, 1022428, 0.4, 3, 'Vanilla Greens 24-28 Level Range'), +(1000024, 6, 1022125, 0.4, 3, 'Vanilla Greens 21-25 Level Range'), +(1000024, 7, 1022024, 0.4, 3, 'Vanilla Greens 20-24 Level Range'), +(1000024, 8, 1022226, 0.4, 3, 'Vanilla Greens 22-26 Level Range'), +(1000024, 9, 1032427, 0.025, 4, 'Vanilla Blues 24-27 Level Range'), +(1000024, 10, 1032124, 0.025, 4, 'Vanilla Blues 21-24 Level Range'), +(1000024, 11, 1032225, 0.025, 4, 'Vanilla Blues 22-25 Level Range'), +(1000024, 12, 1032326, 0.025, 4, 'Vanilla Blues 23-26 Level Range'), +(1000024, 15, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000024, 16, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000024, 17, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000024, 18, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000024, 19, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000025, 1, 1002125, 6, 0, 'Vanilla Greys 21-25 Level Range'), +(1000025, 2, 1012125, 1, 2, 'Vanilla Whites 21-25 Level Range'), +(1000025, 3, 1022327, 0.4, 3, 'Vanilla Greens 23-27 Level Range'), +(1000025, 4, 1022428, 0.4, 3, 'Vanilla Greens 24-28 Level Range'), +(1000025, 5, 1022125, 0.4, 3, 'Vanilla Greens 21-25 Level Range'), +(1000025, 6, 1022226, 0.4, 3, 'Vanilla Greens 22-26 Level Range'), +(1000025, 7, 1022529, 0.4, 3, 'Vanilla Greens 25-29 Level Range'), +(1000025, 8, 1032427, 0.025, 4, 'Vanilla Blues 24-27 Level Range'), +(1000025, 9, 1032528, 0.025, 4, 'Vanilla Blues 25-28 Level Range'), +(1000025, 10, 1032225, 0.025, 4, 'Vanilla Blues 22-25 Level Range'), +(1000025, 11, 1032326, 0.025, 4, 'Vanilla Blues 23-26 Level Range'), +(1000025, 14, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000025, 15, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000025, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000025, 17, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000025, 18, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000026, 1, 1002630, 6, 0, 'Vanilla Greys 26-30 Level Range'), +(1000026, 2, 1022327, 0.4, 3, 'Vanilla Greens 23-27 Level Range'), +(1000026, 3, 1022428, 0.4, 3, 'Vanilla Greens 24-28 Level Range'), +(1000026, 4, 1022630, 0.4, 3, 'Vanilla Greens 26-30 Level Range'), +(1000026, 5, 1022226, 0.4, 3, 'Vanilla Greens 22-26 Level Range'), +(1000026, 6, 1022529, 0.4, 3, 'Vanilla Greens 25-29 Level Range'), +(1000026, 7, 1032427, 0.025, 4, 'Vanilla Blues 24-27 Level Range'), +(1000026, 8, 1032528, 0.025, 4, 'Vanilla Blues 25-28 Level Range'), +(1000026, 9, 1032629, 0.025, 4, 'Vanilla Blues 26-29 Level Range'), +(1000026, 10, 1032326, 0.025, 4, 'Vanilla Blues 23-26 Level Range'), +(1000026, 13, 1072627, 100, 0, 'Vanilla Miscellaneous 26-27 Level Range'), +(1000026, 14, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000026, 15, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000026, 16, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000026, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000027, 1, 1002630, 6, 0, 'Vanilla Greys 26-30 Level Range'), +(1000027, 2, 1022731, 0.4, 3, 'Vanilla Greens 27-31 Level Range'), +(1000027, 3, 1022327, 0.4, 3, 'Vanilla Greens 23-27 Level Range'), +(1000027, 4, 1022428, 0.4, 3, 'Vanilla Greens 24-28 Level Range'), +(1000027, 5, 1022630, 0.4, 3, 'Vanilla Greens 26-30 Level Range'), +(1000027, 6, 1022529, 0.4, 3, 'Vanilla Greens 25-29 Level Range'), +(1000027, 7, 1032427, 0.025, 4, 'Vanilla Blues 24-27 Level Range'), +(1000027, 8, 1032528, 0.025, 4, 'Vanilla Blues 25-28 Level Range'), +(1000027, 9, 1032629, 0.025, 4, 'Vanilla Blues 26-29 Level Range'), +(1000027, 10, 1032730, 0.025, 4, 'Vanilla Blues 27-30 Level Range'), +(1000027, 13, 1072627, 100, 0, 'Vanilla Miscellaneous 26-27 Level Range'), +(1000027, 14, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000027, 15, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000027, 16, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000027, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000028, 1, 1002630, 6, 0, 'Vanilla Greys 26-30 Level Range'), +(1000028, 2, 1022731, 0.4, 3, 'Vanilla Greens 27-31 Level Range'), +(1000028, 3, 1022832, 0.4, 3, 'Vanilla Greens 28-32 Level Range'), +(1000028, 4, 1022428, 0.4, 3, 'Vanilla Greens 24-28 Level Range'), +(1000028, 5, 1022630, 0.4, 3, 'Vanilla Greens 26-30 Level Range'), +(1000028, 6, 1022529, 0.4, 3, 'Vanilla Greens 25-29 Level Range'), +(1000028, 7, 1032528, 0.025, 4, 'Vanilla Blues 25-28 Level Range'), +(1000028, 8, 1032831, 0.025, 4, 'Vanilla Blues 28-31 Level Range'), +(1000028, 9, 1032629, 0.025, 4, 'Vanilla Blues 26-29 Level Range'), +(1000028, 10, 1032730, 0.025, 4, 'Vanilla Blues 27-30 Level Range'), +(1000028, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +(1000028, 14, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000028, 15, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000028, 16, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000028, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000029, 1, 1002630, 6, 0, 'Vanilla Greys 26-30 Level Range'), +(1000029, 2, 1022731, 0.4, 3, 'Vanilla Greens 27-31 Level Range'), +(1000029, 3, 1022832, 0.4, 3, 'Vanilla Greens 28-32 Level Range'), +(1000029, 4, 1022933, 0.4, 3, 'Vanilla Greens 29-33 Level Range'), +(1000029, 5, 1022630, 0.4, 3, 'Vanilla Greens 26-30 Level Range'), +(1000029, 6, 1022529, 0.4, 3, 'Vanilla Greens 25-29 Level Range'), +(1000029, 7, 1032932, 0.025, 4, 'Vanilla Blues 29-32 Level Range'), +(1000029, 8, 1032831, 0.025, 4, 'Vanilla Blues 28-31 Level Range'), +(1000029, 9, 1032629, 0.025, 4, 'Vanilla Blues 26-29 Level Range'), +(1000029, 10, 1032730, 0.025, 4, 'Vanilla Blues 27-30 Level Range'), +(1000029, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +(1000029, 14, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000029, 15, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000029, 16, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000029, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000030, 1, 1002630, 6, 0, 'Vanilla Greys 26-30 Level Range'), +(1000030, 2, 1023034, 0.4, 3, 'Vanilla Greens 30-34 Level Range'), +(1000030, 3, 1022731, 0.4, 3, 'Vanilla Greens 27-31 Level Range'), +(1000030, 4, 1022832, 0.4, 3, 'Vanilla Greens 28-32 Level Range'), +(1000030, 5, 1022933, 0.4, 3, 'Vanilla Greens 29-33 Level Range'), +(1000030, 6, 1022630, 0.4, 3, 'Vanilla Greens 26-30 Level Range'), +(1000030, 7, 1032932, 0.025, 4, 'Vanilla Blues 29-32 Level Range'), +(1000030, 8, 1032831, 0.025, 4, 'Vanilla Blues 28-31 Level Range'), +(1000030, 9, 1033033, 0.025, 4, 'Vanilla Blues 30-33 Level Range'), +(1000030, 10, 1032730, 0.025, 4, 'Vanilla Blues 27-30 Level Range'), +(1000030, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +(1000030, 14, 1083045, 0.075, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000030, 15, 1082640, 0.075, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000030, 16, 1082035, 0.075, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000030, 17, 1081630, 0.075, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000030, 18, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000031, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000031, 2, 1023034, 0.4, 3, 'Vanilla Greens 30-34 Level Range'), +(1000031, 3, 1023135, 0.4, 3, 'Vanilla Greens 31-35 Level Range'), +(1000031, 4, 1022731, 0.4, 3, 'Vanilla Greens 27-31 Level Range'), +(1000031, 5, 1022832, 0.4, 3, 'Vanilla Greens 28-32 Level Range'), +(1000031, 6, 1022933, 0.4, 3, 'Vanilla Greens 29-33 Level Range'), +(1000031, 7, 1033134, 0.025, 4, 'Vanilla Blues 31-34 Level Range'), +(1000031, 8, 1032932, 0.025, 4, 'Vanilla Blues 29-32 Level Range'), +(1000031, 9, 1032831, 0.025, 4, 'Vanilla Blues 28-31 Level Range'), +(1000031, 10, 1033033, 0.025, 4, 'Vanilla Blues 30-33 Level Range'), +(1000031, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000031, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000031, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000031, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000031, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000032, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000032, 2, 1023034, 0.4, 3, 'Vanilla Greens 30-34 Level Range'), +(1000032, 3, 1023135, 0.4, 3, 'Vanilla Greens 31-35 Level Range'), +(1000032, 4, 1022832, 0.4, 3, 'Vanilla Greens 28-32 Level Range'), +(1000032, 5, 1022933, 0.4, 3, 'Vanilla Greens 29-33 Level Range'), +(1000032, 6, 1023236, 0.4, 3, 'Vanilla Greens 32-36 Level Range'), +(1000032, 7, 1033134, 0.025, 4, 'Vanilla Blues 31-34 Level Range'), +(1000032, 8, 1032932, 0.025, 4, 'Vanilla Blues 29-32 Level Range'), +(1000032, 9, 1033235, 0.025, 4, 'Vanilla Blues 32-35 Level Range'), +(1000032, 10, 1033033, 0.025, 4, 'Vanilla Blues 30-33 Level Range'), +(1000032, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000032, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000032, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000032, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000032, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000033, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000033, 2, 1023034, 0.4, 3, 'Vanilla Greens 30-34 Level Range'), +(1000033, 3, 1023135, 0.4, 3, 'Vanilla Greens 31-35 Level Range'), +(1000033, 4, 1022933, 0.4, 3, 'Vanilla Greens 29-33 Level Range'), +(1000033, 5, 1023337, 0.4, 3, 'Vanilla Greens 33-37 Level Range'), +(1000033, 6, 1023236, 0.4, 3, 'Vanilla Greens 32-36 Level Range'), +(1000033, 7, 1033134, 0.025, 4, 'Vanilla Blues 31-34 Level Range'), +(1000033, 8, 1033336, 0.025, 4, 'Vanilla Blues 33-36 Level Range'), +(1000033, 9, 1033235, 0.025, 4, 'Vanilla Blues 32-35 Level Range'), +(1000033, 10, 1033033, 0.025, 4, 'Vanilla Blues 30-33 Level Range'), +(1000033, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000033, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000033, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000033, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000033, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000034, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000034, 2, 1023034, 0.4, 3, 'Vanilla Greens 30-34 Level Range'), +(1000034, 3, 1023438, 0.4, 3, 'Vanilla Greens 34-38 Level Range'), +(1000034, 4, 1023135, 0.4, 3, 'Vanilla Greens 31-35 Level Range'), +(1000034, 5, 1023337, 0.4, 3, 'Vanilla Greens 33-37 Level Range'), +(1000034, 6, 1023236, 0.4, 3, 'Vanilla Greens 32-36 Level Range'), +(1000034, 7, 1033134, 0.025, 4, 'Vanilla Blues 31-34 Level Range'), +(1000034, 8, 1033336, 0.025, 4, 'Vanilla Blues 33-36 Level Range'), +(1000034, 9, 1033437, 0.025, 4, 'Vanilla Blues 34-37 Level Range'), +(1000034, 10, 1033235, 0.025, 4, 'Vanilla Blues 32-35 Level Range'), +(1000034, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000034, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000034, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000034, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000034, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000035, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000035, 2, 1023438, 0.4, 3, 'Vanilla Greens 34-38 Level Range'), +(1000035, 3, 1023135, 0.4, 3, 'Vanilla Greens 31-35 Level Range'), +(1000035, 4, 1023337, 0.4, 3, 'Vanilla Greens 33-37 Level Range'), +(1000035, 5, 1023539, 0.4, 3, 'Vanilla Greens 35-39 Level Range'), +(1000035, 6, 1023236, 0.4, 3, 'Vanilla Greens 32-36 Level Range'), +(1000035, 7, 1033336, 0.025, 4, 'Vanilla Blues 33-36 Level Range'), +(1000035, 8, 1033437, 0.025, 4, 'Vanilla Blues 34-37 Level Range'), +(1000035, 9, 1033235, 0.025, 4, 'Vanilla Blues 32-35 Level Range'), +(1000035, 10, 1033538, 0.025, 4, 'Vanilla Blues 35-38 Level Range'), +(1000035, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000035, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000035, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000035, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000035, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000036, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000036, 2, 1023438, 0.4, 3, 'Vanilla Greens 34-38 Level Range'), +(1000036, 3, 1023640, 0.4, 3, 'Vanilla Greens 36-40 Level Range'), +(1000036, 4, 1023337, 0.4, 3, 'Vanilla Greens 33-37 Level Range'), +(1000036, 5, 1023539, 0.4, 3, 'Vanilla Greens 35-39 Level Range'), +(1000036, 6, 1023236, 0.4, 3, 'Vanilla Greens 32-36 Level Range'), +(1000036, 7, 1033639, 0.025, 4, 'Vanilla Blues 36-39 Level Range'), +(1000036, 8, 1033336, 0.025, 4, 'Vanilla Blues 33-36 Level Range'), +(1000036, 9, 1033437, 0.025, 4, 'Vanilla Blues 34-37 Level Range'), +(1000036, 10, 1033538, 0.025, 4, 'Vanilla Blues 35-38 Level Range'), +(1000036, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000036, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000036, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000036, 16, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000036, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000037, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000037, 2, 1023438, 0.4, 3, 'Vanilla Greens 34-38 Level Range'), +(1000037, 3, 1023640, 0.4, 3, 'Vanilla Greens 36-40 Level Range'), +(1000037, 4, 1023741, 0.4, 3, 'Vanilla Greens 37-41 Level Range'), +(1000037, 5, 1023337, 0.4, 3, 'Vanilla Greens 33-37 Level Range'), +(1000037, 6, 1023539, 0.4, 3, 'Vanilla Greens 35-39 Level Range'), +(1000037, 7, 1033639, 0.025, 4, 'Vanilla Blues 36-39 Level Range'), +(1000037, 8, 1033740, 0.025, 4, 'Vanilla Blues 37-40 Level Range'), +(1000037, 9, 1033437, 0.025, 4, 'Vanilla Blues 34-37 Level Range'), +(1000037, 10, 1033538, 0.025, 4, 'Vanilla Blues 35-38 Level Range'), +(1000037, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000037, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000037, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000037, 16, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000037, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000038, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000038, 2, 1023438, 0.4, 3, 'Vanilla Greens 34-38 Level Range'), +(1000038, 3, 1023640, 0.4, 3, 'Vanilla Greens 36-40 Level Range'), +(1000038, 4, 1023741, 0.4, 3, 'Vanilla Greens 37-41 Level Range'), +(1000038, 5, 1023842, 0.4, 3, 'Vanilla Greens 38-42 Level Range'), +(1000038, 6, 1023539, 0.4, 3, 'Vanilla Greens 35-39 Level Range'), +(1000038, 7, 1033841, 0.025, 4, 'Vanilla Blues 38-41 Level Range'), +(1000038, 8, 1033639, 0.025, 4, 'Vanilla Blues 36-39 Level Range'), +(1000038, 9, 1033740, 0.025, 4, 'Vanilla Blues 37-40 Level Range'), +(1000038, 10, 1033538, 0.025, 4, 'Vanilla Blues 35-38 Level Range'), +(1000038, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000038, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000038, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000038, 16, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000038, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000039, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000039, 2, 1023640, 0.4, 3, 'Vanilla Greens 36-40 Level Range'), +(1000039, 3, 1023741, 0.4, 3, 'Vanilla Greens 37-41 Level Range'), +(1000039, 4, 1023842, 0.4, 3, 'Vanilla Greens 38-42 Level Range'), +(1000039, 5, 1023943, 0.4, 3, 'Vanilla Greens 39-43 Level Range'), +(1000039, 6, 1023539, 0.4, 3, 'Vanilla Greens 35-39 Level Range'), +(1000039, 7, 1033841, 0.025, 4, 'Vanilla Blues 38-41 Level Range'), +(1000039, 8, 1033639, 0.025, 4, 'Vanilla Blues 36-39 Level Range'), +(1000039, 9, 1033740, 0.025, 4, 'Vanilla Blues 37-40 Level Range'), +(1000039, 10, 1033942, 0.025, 4, 'Vanilla Blues 39-42 Level Range'), +(1000039, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000039, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000039, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000039, 16, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000039, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000040, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000040, 2, 1023640, 0.4, 3, 'Vanilla Greens 36-40 Level Range'), +(1000040, 3, 1023741, 0.4, 3, 'Vanilla Greens 37-41 Level Range'), +(1000040, 4, 1023842, 0.4, 3, 'Vanilla Greens 38-42 Level Range'), +(1000040, 5, 1023943, 0.4, 3, 'Vanilla Greens 39-43 Level Range'), +(1000040, 6, 1024044, 0.4, 3, 'Vanilla Greens 40-44 Level Range'), +(1000040, 7, 1033841, 0.025, 4, 'Vanilla Blues 38-41 Level Range'), +(1000040, 8, 1033740, 0.025, 4, 'Vanilla Blues 37-40 Level Range'), +(1000040, 9, 1034043, 0.025, 4, 'Vanilla Blues 40-43 Level Range'), +(1000040, 10, 1033942, 0.025, 4, 'Vanilla Blues 39-42 Level Range'), +(1000040, 11, 1044046, 0.05, 5, 'Vanilla Purples 40-46 Level Range'), +(1000040, 14, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000040, 15, 1083045, 0.075, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000040, 16, 1082640, 0.075, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000040, 17, 1083650, 0.075, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000040, 18, 1084055, 0.075, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000040, 19, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000041, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000041, 2, 1024145, 0.4, 3, 'Vanilla Greens 41-45 Level Range'), +(1000041, 3, 1023741, 0.4, 3, 'Vanilla Greens 37-41 Level Range'), +(1000041, 4, 1023842, 0.4, 3, 'Vanilla Greens 38-42 Level Range'), +(1000041, 5, 1023943, 0.4, 3, 'Vanilla Greens 39-43 Level Range'), +(1000041, 6, 1024044, 0.4, 3, 'Vanilla Greens 40-44 Level Range'), +(1000041, 7, 1033841, 0.025, 4, 'Vanilla Blues 38-41 Level Range'), +(1000041, 8, 1034043, 0.025, 4, 'Vanilla Blues 40-43 Level Range'), +(1000041, 9, 1033942, 0.025, 4, 'Vanilla Blues 39-42 Level Range'), +(1000041, 10, 1034144, 0.025, 4, 'Vanilla Blues 41-44 Level Range'), +(1000041, 11, 1044046, 0.05, 5, 'Vanilla Purples 40-46 Level Range'), +(1000041, 14, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000041, 15, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000041, 16, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000041, 17, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000041, 18, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000042, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000042, 2, 1024145, 0.4, 3, 'Vanilla Greens 41-45 Level Range'), +(1000042, 3, 1024246, 0.4, 3, 'Vanilla Greens 42-46 Level Range'), +(1000042, 4, 1023842, 0.4, 3, 'Vanilla Greens 38-42 Level Range'), +(1000042, 5, 1023943, 0.4, 3, 'Vanilla Greens 39-43 Level Range'), +(1000042, 6, 1024044, 0.4, 3, 'Vanilla Greens 40-44 Level Range'), +(1000042, 7, 1034245, 0.025, 4, 'Vanilla Blues 42-45 Level Range'), +(1000042, 8, 1034043, 0.025, 4, 'Vanilla Blues 40-43 Level Range'), +(1000042, 9, 1033942, 0.025, 4, 'Vanilla Blues 39-42 Level Range'), +(1000042, 10, 1034144, 0.025, 4, 'Vanilla Blues 41-44 Level Range'), +(1000042, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +(1000042, 12, 1044046, 0.025, 5, 'Vanilla Purples 40-46 Level Range'), +(1000042, 15, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000042, 16, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000042, 17, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000042, 18, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000042, 19, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000043, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000043, 2, 1024145, 0.4, 3, 'Vanilla Greens 41-45 Level Range'), +(1000043, 3, 1024347, 0.4, 3, 'Vanilla Greens 43-47 Level Range'), +(1000043, 4, 1024246, 0.4, 3, 'Vanilla Greens 42-46 Level Range'), +(1000043, 5, 1023943, 0.4, 3, 'Vanilla Greens 39-43 Level Range'), +(1000043, 6, 1024044, 0.4, 3, 'Vanilla Greens 40-44 Level Range'), +(1000043, 7, 1034245, 0.025, 4, 'Vanilla Blues 42-45 Level Range'), +(1000043, 8, 1034346, 0.025, 4, 'Vanilla Blues 43-46 Level Range'), +(1000043, 9, 1034043, 0.025, 4, 'Vanilla Blues 40-43 Level Range'), +(1000043, 10, 1034144, 0.025, 4, 'Vanilla Blues 41-44 Level Range'), +(1000043, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +(1000043, 12, 1044046, 0.025, 5, 'Vanilla Purples 40-46 Level Range'), +(1000043, 15, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000043, 16, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000043, 17, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000043, 18, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000043, 19, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000044, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000044, 2, 1024145, 0.4, 3, 'Vanilla Greens 41-45 Level Range'), +(1000044, 3, 1024347, 0.4, 3, 'Vanilla Greens 43-47 Level Range'), +(1000044, 4, 1024448, 0.4, 3, 'Vanilla Greens 44-48 Level Range'), +(1000044, 5, 1024246, 0.4, 3, 'Vanilla Greens 42-46 Level Range'), +(1000044, 6, 1024044, 0.4, 3, 'Vanilla Greens 40-44 Level Range'), +(1000044, 7, 1034245, 0.025, 4, 'Vanilla Blues 42-45 Level Range'), +(1000044, 8, 1034447, 0.025, 4, 'Vanilla Blues 44-47 Level Range'), +(1000044, 9, 1034346, 0.025, 4, 'Vanilla Blues 43-46 Level Range'), +(1000044, 10, 1034144, 0.025, 4, 'Vanilla Blues 41-44 Level Range'), +(1000044, 11, 1044248, 0.0167, 5, 'Vanilla Purples 42-48 Level Range'), +(1000044, 12, 1044046, 0.0167, 5, 'Vanilla Purples 40-46 Level Range'), +(1000044, 13, 1044450, 0.0167, 5, 'Vanilla Purples 44-50 Level Range'), +(1000044, 16, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000044, 17, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000044, 18, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000044, 19, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000044, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000045, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000045, 2, 1024145, 0.4, 3, 'Vanilla Greens 41-45 Level Range'), +(1000045, 3, 1024347, 0.4, 3, 'Vanilla Greens 43-47 Level Range'), +(1000045, 4, 1024448, 0.4, 3, 'Vanilla Greens 44-48 Level Range'), +(1000045, 5, 1024549, 0.4, 3, 'Vanilla Greens 45-49 Level Range'), +(1000045, 6, 1024246, 0.4, 3, 'Vanilla Greens 42-46 Level Range'), +(1000045, 7, 1034245, 0.025, 4, 'Vanilla Blues 42-45 Level Range'), +(1000045, 8, 1034447, 0.025, 4, 'Vanilla Blues 44-47 Level Range'), +(1000045, 9, 1034346, 0.025, 4, 'Vanilla Blues 43-46 Level Range'), +(1000045, 10, 1034548, 0.025, 4, 'Vanilla Blues 45-48 Level Range'), +(1000045, 11, 1044248, 0.0167, 5, 'Vanilla Purples 42-48 Level Range'), +(1000045, 12, 1044046, 0.0167, 5, 'Vanilla Purples 40-46 Level Range'), +(1000045, 13, 1044450, 0.0167, 5, 'Vanilla Purples 44-50 Level Range'), +(1000045, 16, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000045, 17, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000045, 18, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000045, 19, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000045, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000046, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000046, 2, 1024347, 0.4, 3, 'Vanilla Greens 43-47 Level Range'), +(1000046, 3, 1024448, 0.4, 3, 'Vanilla Greens 44-48 Level Range'), +(1000046, 4, 1024549, 0.4, 3, 'Vanilla Greens 45-49 Level Range'), +(1000046, 5, 1024246, 0.4, 3, 'Vanilla Greens 42-46 Level Range'), +(1000046, 6, 1024650, 0.4, 3, 'Vanilla Greens 46-50 Level Range'), +(1000046, 7, 1034447, 0.025, 4, 'Vanilla Blues 44-47 Level Range'), +(1000046, 8, 1034346, 0.025, 4, 'Vanilla Blues 43-46 Level Range'), +(1000046, 9, 1034649, 0.025, 4, 'Vanilla Blues 46-49 Level Range'), +(1000046, 10, 1034548, 0.025, 4, 'Vanilla Blues 45-48 Level Range'), +(1000046, 11, 1044248, 0.0125, 5, 'Vanilla Purples 42-48 Level Range'), +(1000046, 12, 1044046, 0.0125, 5, 'Vanilla Purples 40-46 Level Range'), +(1000046, 13, 1044450, 0.0125, 5, 'Vanilla Purples 44-50 Level Range'), +(1000046, 14, 1044652, 0.0125, 5, 'Vanilla Purples 46-52 Level Range'), +(1000046, 17, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000046, 18, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000046, 19, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000046, 20, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000046, 21, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000047, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000047, 2, 1024347, 0.4, 3, 'Vanilla Greens 43-47 Level Range'), +(1000047, 3, 1024448, 0.4, 3, 'Vanilla Greens 44-48 Level Range'), +(1000047, 4, 1024549, 0.4, 3, 'Vanilla Greens 45-49 Level Range'), +(1000047, 5, 1024751, 0.4, 3, 'Vanilla Greens 47-51 Level Range'), +(1000047, 6, 1024650, 0.4, 3, 'Vanilla Greens 46-50 Level Range'), +(1000047, 7, 1034447, 0.025, 4, 'Vanilla Blues 44-47 Level Range'), +(1000047, 8, 1034649, 0.025, 4, 'Vanilla Blues 46-49 Level Range'), +(1000047, 9, 1034548, 0.025, 4, 'Vanilla Blues 45-48 Level Range'), +(1000047, 10, 1034750, 0.025, 4, 'Vanilla Blues 47-50 Level Range'), +(1000047, 11, 1044248, 0.0167, 5, 'Vanilla Purples 42-48 Level Range'), +(1000047, 12, 1044450, 0.0167, 5, 'Vanilla Purples 44-50 Level Range'), +(1000047, 13, 1044652, 0.0167, 5, 'Vanilla Purples 46-52 Level Range'), +(1000047, 16, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000047, 17, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000047, 18, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000047, 19, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000047, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000048, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000048, 2, 1024448, 0.4, 3, 'Vanilla Greens 44-48 Level Range'), +(1000048, 3, 1024549, 0.4, 3, 'Vanilla Greens 45-49 Level Range'), +(1000048, 4, 1024751, 0.4, 3, 'Vanilla Greens 47-51 Level Range'), +(1000048, 5, 1024852, 0.4, 3, 'Vanilla Greens 48-52 Level Range'), +(1000048, 6, 1024650, 0.4, 3, 'Vanilla Greens 46-50 Level Range'), +(1000048, 7, 1034649, 0.025, 4, 'Vanilla Blues 46-49 Level Range'), +(1000048, 8, 1034548, 0.025, 4, 'Vanilla Blues 45-48 Level Range'), +(1000048, 9, 1034851, 0.025, 4, 'Vanilla Blues 48-51 Level Range'), +(1000048, 10, 1034750, 0.025, 4, 'Vanilla Blues 47-50 Level Range'), +(1000048, 11, 1044248, 0.0125, 5, 'Vanilla Purples 42-48 Level Range'), +(1000048, 12, 1044854, 0.0125, 5, 'Vanilla Purples 48-54 Level Range'), +(1000048, 13, 1044450, 0.0125, 5, 'Vanilla Purples 44-50 Level Range'), +(1000048, 14, 1044652, 0.0125, 5, 'Vanilla Purples 46-52 Level Range'), +(1000048, 17, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000048, 18, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000048, 19, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000048, 20, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000048, 21, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000049, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000049, 2, 1024549, 0.4, 3, 'Vanilla Greens 45-49 Level Range'), +(1000049, 3, 1024751, 0.4, 3, 'Vanilla Greens 47-51 Level Range'), +(1000049, 4, 1024852, 0.4, 3, 'Vanilla Greens 48-52 Level Range'), +(1000049, 5, 1024953, 0.4, 3, 'Vanilla Greens 49-53 Level Range'), +(1000049, 6, 1024650, 0.4, 3, 'Vanilla Greens 46-50 Level Range'), +(1000049, 7, 1034649, 0.025, 4, 'Vanilla Blues 46-49 Level Range'), +(1000049, 8, 1034952, 0.025, 4, 'Vanilla Blues 49-52 Level Range'), +(1000049, 9, 1034851, 0.025, 4, 'Vanilla Blues 48-51 Level Range'), +(1000049, 10, 1034750, 0.025, 4, 'Vanilla Blues 47-50 Level Range'), +(1000049, 11, 1044854, 0.0167, 5, 'Vanilla Purples 48-54 Level Range'), +(1000049, 12, 1044450, 0.0167, 5, 'Vanilla Purples 44-50 Level Range'), +(1000049, 13, 1044652, 0.0167, 5, 'Vanilla Purples 46-52 Level Range'), +(1000049, 16, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000049, 17, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000049, 18, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000049, 19, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000049, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000050, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000050, 2, 1024751, 0.4, 3, 'Vanilla Greens 47-51 Level Range'), +(1000050, 3, 1025054, 0.4, 3, 'Vanilla Greens 50-54 Level Range'), +(1000050, 4, 1024852, 0.4, 3, 'Vanilla Greens 48-52 Level Range'), +(1000050, 5, 1024953, 0.4, 3, 'Vanilla Greens 49-53 Level Range'), +(1000050, 6, 1024650, 0.4, 3, 'Vanilla Greens 46-50 Level Range'), +(1000050, 7, 1034952, 0.025, 4, 'Vanilla Blues 49-52 Level Range'), +(1000050, 8, 1034851, 0.025, 4, 'Vanilla Blues 48-51 Level Range'), +(1000050, 9, 1035053, 0.025, 4, 'Vanilla Blues 50-53 Level Range'), +(1000050, 10, 1034750, 0.025, 4, 'Vanilla Blues 47-50 Level Range'), +(1000050, 11, 1044854, 0.0125, 5, 'Vanilla Purples 48-54 Level Range'), +(1000050, 12, 1044450, 0.0125, 5, 'Vanilla Purples 44-50 Level Range'), +(1000050, 13, 1044652, 0.0125, 5, 'Vanilla Purples 46-52 Level Range'), +(1000050, 14, 1045056, 0.0125, 5, 'Vanilla Purples 50-56 Level Range'), +(1000050, 18, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000050, 19, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000050, 20, 1084660, 0.075, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000050, 21, 1083650, 0.075, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000050, 22, 1084055, 0.075, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000050, 23, 1085063, 0.075, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000050, 24, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000051, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000051, 2, 1025155, 0.4, 3, 'Vanilla Greens 51-55 Level Range'), +(1000051, 3, 1024751, 0.4, 3, 'Vanilla Greens 47-51 Level Range'), +(1000051, 4, 1025054, 0.4, 3, 'Vanilla Greens 50-54 Level Range'), +(1000051, 5, 1024852, 0.4, 3, 'Vanilla Greens 48-52 Level Range'), +(1000051, 6, 1024953, 0.4, 3, 'Vanilla Greens 49-53 Level Range'), +(1000051, 7, 1034952, 0.025, 4, 'Vanilla Blues 49-52 Level Range'), +(1000051, 8, 1034851, 0.025, 4, 'Vanilla Blues 48-51 Level Range'), +(1000051, 9, 1035154, 0.025, 4, 'Vanilla Blues 51-54 Level Range'), +(1000051, 10, 1035053, 0.025, 4, 'Vanilla Blues 50-53 Level Range'), +(1000051, 11, 1044854, 0.0167, 5, 'Vanilla Purples 48-54 Level Range'), +(1000051, 12, 1044652, 0.0167, 5, 'Vanilla Purples 46-52 Level Range'), +(1000051, 13, 1045056, 0.0167, 5, 'Vanilla Purples 50-56 Level Range'), +(1000051, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000051, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000051, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000051, 20, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000051, 21, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000051, 22, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000052, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000052, 2, 1025155, 0.4, 3, 'Vanilla Greens 51-55 Level Range'), +(1000052, 3, 1025256, 0.4, 3, 'Vanilla Greens 52-56 Level Range'), +(1000052, 4, 1025054, 0.4, 3, 'Vanilla Greens 50-54 Level Range'), +(1000052, 5, 1024852, 0.4, 3, 'Vanilla Greens 48-52 Level Range'), +(1000052, 6, 1024953, 0.4, 3, 'Vanilla Greens 49-53 Level Range'), +(1000052, 7, 1035255, 0.025, 4, 'Vanilla Blues 52-55 Level Range'), +(1000052, 8, 1034952, 0.025, 4, 'Vanilla Blues 49-52 Level Range'), +(1000052, 9, 1035154, 0.025, 4, 'Vanilla Blues 51-54 Level Range'), +(1000052, 10, 1035053, 0.025, 4, 'Vanilla Blues 50-53 Level Range'), +(1000052, 11, 1044854, 0.0125, 5, 'Vanilla Purples 48-54 Level Range'), +(1000052, 12, 1044652, 0.0125, 5, 'Vanilla Purples 46-52 Level Range'), +(1000052, 13, 1045258, 0.0125, 5, 'Vanilla Purples 52-58 Level Range'), +(1000052, 14, 1045056, 0.0125, 5, 'Vanilla Purples 50-56 Level Range'), +(1000052, 17, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000052, 19, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000052, 20, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000052, 21, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000052, 22, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000052, 23, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000053, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000053, 2, 1025155, 0.4, 3, 'Vanilla Greens 51-55 Level Range'), +(1000053, 3, 1025357, 0.4, 3, 'Vanilla Greens 53-57 Level Range'), +(1000053, 4, 1025256, 0.4, 3, 'Vanilla Greens 52-56 Level Range'), +(1000053, 5, 1025054, 0.4, 3, 'Vanilla Greens 50-54 Level Range'), +(1000053, 6, 1024953, 0.4, 3, 'Vanilla Greens 49-53 Level Range'), +(1000053, 7, 1035255, 0.025, 4, 'Vanilla Blues 52-55 Level Range'), +(1000053, 8, 1035154, 0.025, 4, 'Vanilla Blues 51-54 Level Range'), +(1000053, 9, 1035356, 0.025, 4, 'Vanilla Blues 53-56 Level Range'), +(1000053, 10, 1035053, 0.025, 4, 'Vanilla Blues 50-53 Level Range'), +(1000053, 11, 1044854, 0.0167, 5, 'Vanilla Purples 48-54 Level Range'), +(1000053, 12, 1045258, 0.0167, 5, 'Vanilla Purples 52-58 Level Range'), +(1000053, 13, 1045056, 0.0167, 5, 'Vanilla Purples 50-56 Level Range'), +(1000053, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000053, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000053, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000053, 20, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000053, 21, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000053, 22, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000054, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000054, 2, 1025458, 0.4, 3, 'Vanilla Greens 54-58 Level Range'), +(1000054, 3, 1025155, 0.4, 3, 'Vanilla Greens 51-55 Level Range'), +(1000054, 4, 1025357, 0.4, 3, 'Vanilla Greens 53-57 Level Range'), +(1000054, 5, 1025256, 0.4, 3, 'Vanilla Greens 52-56 Level Range'), +(1000054, 6, 1025054, 0.4, 3, 'Vanilla Greens 50-54 Level Range'), +(1000054, 7, 1035255, 0.025, 4, 'Vanilla Blues 52-55 Level Range'), +(1000054, 8, 1035457, 0.025, 4, 'Vanilla Blues 54-57 Level Range'), +(1000054, 9, 1035154, 0.025, 4, 'Vanilla Blues 51-54 Level Range'), +(1000054, 10, 1035356, 0.025, 4, 'Vanilla Blues 53-56 Level Range'), +(1000054, 11, 1044854, 0.0125, 5, 'Vanilla Purples 48-54 Level Range'), +(1000054, 12, 1045258, 0.0125, 5, 'Vanilla Purples 52-58 Level Range'), +(1000054, 13, 1045056, 0.0125, 5, 'Vanilla Purples 50-56 Level Range'), +(1000054, 14, 1045460, 0.0125, 5, 'Vanilla Purples 54-60 Level Range'), +(1000054, 17, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000054, 19, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000054, 20, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000054, 21, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000054, 22, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000054, 23, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000055, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000055, 2, 1025458, 0.4, 3, 'Vanilla Greens 54-58 Level Range'), +(1000055, 3, 1025559, 0.4, 3, 'Vanilla Greens 55-59 Level Range'), +(1000055, 4, 1025155, 0.4, 3, 'Vanilla Greens 51-55 Level Range'), +(1000055, 5, 1025357, 0.4, 3, 'Vanilla Greens 53-57 Level Range'), +(1000055, 6, 1025256, 0.4, 3, 'Vanilla Greens 52-56 Level Range'), +(1000055, 7, 1035255, 0.025, 4, 'Vanilla Blues 52-55 Level Range'), +(1000055, 8, 1035558, 0.025, 4, 'Vanilla Blues 55-58 Level Range'), +(1000055, 9, 1035457, 0.025, 4, 'Vanilla Blues 54-57 Level Range'), +(1000055, 10, 1035356, 0.025, 4, 'Vanilla Blues 53-56 Level Range'), +(1000055, 11, 1045258, 0.0167, 5, 'Vanilla Purples 52-58 Level Range'), +(1000055, 12, 1045056, 0.0167, 5, 'Vanilla Purples 50-56 Level Range'), +(1000055, 13, 1045460, 0.0167, 5, 'Vanilla Purples 54-60 Level Range'), +(1000055, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000055, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000055, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000055, 20, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000055, 21, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000055, 22, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000056, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000056, 2, 1025660, 0.4, 3, 'Vanilla Greens 56-60 Level Range'), +(1000056, 3, 1025458, 0.4, 3, 'Vanilla Greens 54-58 Level Range'), +(1000056, 4, 1025559, 0.4, 3, 'Vanilla Greens 55-59 Level Range'), +(1000056, 5, 1025357, 0.4, 3, 'Vanilla Greens 53-57 Level Range'), +(1000056, 6, 1025256, 0.4, 3, 'Vanilla Greens 52-56 Level Range'), +(1000056, 7, 1035558, 0.025, 4, 'Vanilla Blues 55-58 Level Range'), +(1000056, 8, 1035457, 0.025, 4, 'Vanilla Blues 54-57 Level Range'), +(1000056, 9, 1035356, 0.025, 4, 'Vanilla Blues 53-56 Level Range'), +(1000056, 10, 1035659, 0.025, 4, 'Vanilla Blues 56-59 Level Range'), +(1000056, 11, 1045662, 0.0125, 5, 'Vanilla Purples 56-62 Level Range'), +(1000056, 12, 1045258, 0.0125, 5, 'Vanilla Purples 52-58 Level Range'), +(1000056, 13, 1045056, 0.0125, 5, 'Vanilla Purples 50-56 Level Range'), +(1000056, 14, 1045460, 0.0125, 5, 'Vanilla Purples 54-60 Level Range'), +(1000056, 17, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000056, 19, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000056, 20, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000056, 21, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000056, 22, 1085663, 0.1, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000056, 23, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000057, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000057, 2, 1025660, 0.4, 3, 'Vanilla Greens 56-60 Level Range'), +(1000057, 3, 1025458, 0.4, 3, 'Vanilla Greens 54-58 Level Range'), +(1000057, 4, 1025559, 0.4, 3, 'Vanilla Greens 55-59 Level Range'), +(1000057, 5, 1025357, 0.4, 3, 'Vanilla Greens 53-57 Level Range'), +(1000057, 6, 1025761, 0.4, 3, 'Vanilla Greens 57-61 Level Range'), +(1000057, 7, 1035558, 0.025, 4, 'Vanilla Blues 55-58 Level Range'), +(1000057, 8, 1035457, 0.025, 4, 'Vanilla Blues 54-57 Level Range'), +(1000057, 9, 1035760, 0.025, 4, 'Vanilla Blues 57-60 Level Range'), +(1000057, 10, 1035659, 0.025, 4, 'Vanilla Blues 56-59 Level Range'), +(1000057, 11, 1045662, 0.0167, 5, 'Vanilla Purples 56-62 Level Range'), +(1000057, 12, 1045258, 0.0167, 5, 'Vanilla Purples 52-58 Level Range'), +(1000057, 13, 1045460, 0.0167, 5, 'Vanilla Purples 54-60 Level Range'), +(1000057, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000057, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000057, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000057, 20, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000057, 21, 1085663, 0.1, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000057, 22, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000058, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000058, 2, 1025660, 0.4, 3, 'Vanilla Greens 56-60 Level Range'), +(1000058, 3, 1025862, 0.4, 3, 'Vanilla Greens 58-62 Level Range'), +(1000058, 4, 1025458, 0.4, 3, 'Vanilla Greens 54-58 Level Range'), +(1000058, 5, 1025559, 0.4, 3, 'Vanilla Greens 55-59 Level Range'), +(1000058, 6, 1025761, 0.4, 3, 'Vanilla Greens 57-61 Level Range'), +(1000058, 7, 1035861, 0.025, 4, 'Vanilla Blues 58-61 Level Range'), +(1000058, 8, 1035558, 0.025, 4, 'Vanilla Blues 55-58 Level Range'), +(1000058, 9, 1035760, 0.025, 4, 'Vanilla Blues 57-60 Level Range'), +(1000058, 10, 1035659, 0.025, 4, 'Vanilla Blues 56-59 Level Range'), +(1000058, 11, 1045662, 0.0125, 5, 'Vanilla Purples 56-62 Level Range'), +(1000058, 12, 1045258, 0.0125, 5, 'Vanilla Purples 52-58 Level Range'), +(1000058, 13, 1045460, 0.0125, 5, 'Vanilla Purples 54-60 Level Range'), +(1000058, 14, 1045863, 0.0125, 5, 'Vanilla Purples 58-63 Level Range'), +(1000058, 17, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000058, 19, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000058, 20, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000058, 21, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000058, 22, 1085663, 0.1, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000058, 23, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000059, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000059, 2, 1025660, 0.4, 3, 'Vanilla Greens 56-60 Level Range'), +(1000059, 3, 1025862, 0.4, 3, 'Vanilla Greens 58-62 Level Range'), +(1000059, 4, 1025559, 0.4, 3, 'Vanilla Greens 55-59 Level Range'), +(1000059, 5, 1025963, 0.4, 3, 'Vanilla Greens 59-63 Level Range'), +(1000059, 6, 1025761, 0.4, 3, 'Vanilla Greens 57-61 Level Range'), +(1000059, 7, 1035861, 0.025, 4, 'Vanilla Blues 58-61 Level Range'), +(1000059, 8, 1035963, 0.025, 4, 'Vanilla Blues 59-63 Level Range'), +(1000059, 9, 1035760, 0.025, 4, 'Vanilla Blues 57-60 Level Range'), +(1000059, 10, 1035659, 0.025, 4, 'Vanilla Blues 56-59 Level Range'), +(1000059, 11, 1045662, 0.0167, 5, 'Vanilla Purples 56-62 Level Range'), +(1000059, 12, 1045460, 0.0167, 5, 'Vanilla Purples 54-60 Level Range'), +(1000059, 13, 1045863, 0.0167, 5, 'Vanilla Purples 58-63 Level Range'), +(1000059, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000059, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000059, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000059, 20, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000059, 21, 1085663, 0.1, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000059, 22, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000060, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000060, 2, 1025660, 0.4, 3, 'Vanilla Greens 56-60 Level Range'), +(1000060, 3, 1025862, 0.4, 3, 'Vanilla Greens 58-62 Level Range'), +(1000060, 4, 1026063, 0.4, 3, 'Vanilla Greens 60-63 Level Range'), +(1000060, 5, 1025963, 0.4, 3, 'Vanilla Greens 59-63 Level Range'), +(1000060, 6, 1025761, 0.4, 3, 'Vanilla Greens 57-61 Level Range'), +(1000060, 7, 1035861, 0.0333, 4, 'Vanilla Blues 58-61 Level Range'), +(1000060, 8, 1035963, 0.0333, 4, 'Vanilla Blues 59-63 Level Range'), +(1000060, 9, 1035760, 0.0333, 4, 'Vanilla Blues 57-60 Level Range'), +(1000060, 10, 1045662, 0.0125, 5, 'Vanilla Purples 56-62 Level Range'), +(1000060, 11, 1046063, 0.0125, 5, 'Vanilla Purples 60-63 Level Range'), +(1000060, 12, 1045460, 0.0125, 5, 'Vanilla Purples 54-60 Level Range'), +(1000060, 13, 1045863, 0.0125, 5, 'Vanilla Purples 58-63 Level Range'), +(1000060, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000060, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000060, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000060, 20, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000060, 21, 1085663, 0.1, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000060, 22, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000061, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000061, 2, 1025862, 0.4, 3, 'Vanilla Greens 58-62 Level Range'), +(1000061, 3, 1026163, 0.4, 3, 'Vanilla Greens 61-63 Level Range'), +(1000061, 4, 1026063, 0.4, 3, 'Vanilla Greens 60-63 Level Range'), +(1000061, 5, 1025963, 0.4, 3, 'Vanilla Greens 59-63 Level Range'), +(1000061, 6, 1025761, 0.4, 3, 'Vanilla Greens 57-61 Level Range'), +(1000061, 7, 1035861, 0.05, 4, 'Vanilla Blues 58-61 Level Range'), +(1000061, 8, 1035963, 0.05, 4, 'Vanilla Blues 59-63 Level Range'), +(1000061, 9, 1045662, 0.0167, 5, 'Vanilla Purples 56-62 Level Range'), +(1000061, 10, 1046063, 0.0167, 5, 'Vanilla Purples 60-63 Level Range'), +(1000061, 11, 1045863, 0.0167, 5, 'Vanilla Purples 58-63 Level Range'), +(1000061, 14, 1076163, 100, 0, 'Vanilla Miscellaneous 61-63 Level Range'), +(1000061, 16, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000061, 17, 1085063, 0.15, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000061, 18, 1085663, 0.15, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000061, 19, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +-- (1000062, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +-- (1000062, 2, 1025862, 0.4, 3, 'Vanilla Greens 58-62 Level Range'), +-- (1000062, 3, 1026263, 0.4, 3, 'Vanilla Greens 62-63 Level Range'), +-- (1000062, 4, 1026163, 0.4, 3, 'Vanilla Greens 61-63 Level Range'), +-- (1000062, 5, 1026063, 0.4, 3, 'Vanilla Greens 60-63 Level Range'), +-- (1000062, 6, 1025963, 0.4, 3, 'Vanilla Greens 59-63 Level Range'), +-- (1000062, 7, 1035963, 0.1, 4, 'Vanilla Blues 59-63 Level Range'), +-- (1000062, 8, 1045662, 0.0167, 5, 'Vanilla Purples 56-62 Level Range'), +-- (1000062, 9, 1046063, 0.0167, 5, 'Vanilla Purples 60-63 Level Range'), +-- (1000062, 10, 1045863, 0.0167, 5, 'Vanilla Purples 58-63 Level Range'), +-- (1000062, 13, 1076163, 100, 0, 'Vanilla Miscellaneous 61-63 Level Range'), +-- (1000062, 14, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +-- (1000062, 16, 1084660, 0.3, 6, 'Vanilla Patterns 46-60 Level Range'), +-- (1000062, 17, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1100058, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100058, 2, 1125860, 2, 3, 'TBC Greens 58-60 Level Range'), +(1100058, 3, 1135861, 0.1, 4, 'TBC Blues 58-61 Level Range'), +(1100059, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100059, 2, 1125961, 1, 3, 'TBC Greens 59-61 Level Range'), +(1100059, 3, 1125860, 1, 3, 'TBC Greens 58-60 Level Range'), +(1100059, 4, 1135861, 0.05, 4, 'TBC Blues 58-61 Level Range'), +(1100059, 5, 1135962, 0.05, 4, 'TBC Blues 59-62 Level Range'), +(1100060, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100060, 2, 1126062, 0.67, 3, 'TBC Greens 60-62 Level Range'), +(1100060, 3, 1125961, 0.67, 3, 'TBC Greens 59-61 Level Range'), +(1100060, 4, 1125860, 0.67, 3, 'TBC Greens 58-60 Level Range'), +(1100060, 5, 1135861, 0.0333, 4, 'TBC Blues 58-61 Level Range'), +(1100060, 6, 1135962, 0.0333, 4, 'TBC Blues 59-62 Level Range'), +(1100060, 7, 1136063, 0.0333, 4, 'TBC Blues 60-63 Level Range'), +(1100061, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100061, 2, 1126062, 0.67, 3, 'TBC Greens 60-62 Level Range'), +(1100061, 3, 1125961, 0.67, 3, 'TBC Greens 59-61 Level Range'), +(1100061, 4, 1126163, 0.67, 3, 'TBC Greens 61-63 Level Range'), +(1100061, 5, 1136164, 0.025, 4, 'TBC Blues 61-64 Level Range'), +(1100061, 6, 1135861, 0.025, 4, 'TBC Blues 58-61 Level Range'), +(1100061, 7, 1135962, 0.025, 4, 'TBC Blues 59-62 Level Range'), +(1100061, 8, 1136063, 0.025, 4, 'TBC Blues 60-63 Level Range'), +(1100061, 11, 1186165, 25, 0, 'TBC Patterns 61-65 Level Range'), +(1100062, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100062, 2, 1126062, 0.67, 3, 'TBC Greens 60-62 Level Range'), +(1100062, 3, 1126163, 0.67, 3, 'TBC Greens 61-63 Level Range'), +(1100062, 4, 1126264, 0.67, 3, 'TBC Greens 62-64 Level Range'), +(1100062, 5, 1136265, 0.025, 4, 'TBC Blues 62-65 Level Range'), +(1100062, 6, 1136164, 0.025, 4, 'TBC Blues 61-64 Level Range'), +(1100062, 7, 1135962, 0.025, 4, 'TBC Blues 59-62 Level Range'), +(1100062, 8, 1136063, 0.025, 4, 'TBC Blues 60-63 Level Range'), +(1100062, 11, 1186165, 25, 0, 'TBC Patterns 61-65 Level Range'), +(1100063, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100063, 2, 1126365, 0.67, 3, 'TBC Greens 63-65 Level Range'), +(1100063, 3, 1126163, 0.67, 3, 'TBC Greens 61-63 Level Range'), +(1100063, 4, 1126264, 0.67, 3, 'TBC Greens 62-64 Level Range'), +(1100063, 5, 1136265, 0.025, 4, 'TBC Blues 62-65 Level Range'), +(1100063, 6, 1136164, 0.025, 4, 'TBC Blues 61-64 Level Range'), +(1100063, 7, 1136366, 0.025, 4, 'TBC Blues 63-66 Level Range'), +(1100063, 8, 1136063, 0.025, 4, 'TBC Blues 60-63 Level Range'), +(1100063, 11, 1186165, 25, 0, 'TBC Patterns 61-65 Level Range'), +(1100064, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100064, 2, 1126466, 0.67, 3, 'TBC Greens 64-66 Level Range'), +(1100064, 3, 1126365, 0.67, 3, 'TBC Greens 63-65 Level Range'), +(1100064, 4, 1126264, 0.67, 3, 'TBC Greens 62-64 Level Range'), +(1100064, 5, 1136265, 0.025, 4, 'TBC Blues 62-65 Level Range'), +(1100064, 6, 1136164, 0.025, 4, 'TBC Blues 61-64 Level Range'), +(1100064, 7, 1136467, 0.025, 4, 'TBC Blues 64-67 Level Range'), +(1100064, 8, 1136366, 0.025, 4, 'TBC Blues 63-66 Level Range'), +(1100064, 11, 1186165, 25, 0, 'TBC Patterns 61-65 Level Range'), +(1100065, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100065, 2, 1126567, 0.67, 3, 'TBC Greens 65-67 Level Range'), +(1100065, 3, 1126466, 0.67, 3, 'TBC Greens 64-66 Level Range'), +(1100065, 4, 1126365, 0.67, 3, 'TBC Greens 63-65 Level Range'), +(1100065, 5, 1136265, 0.025, 4, 'TBC Blues 62-65 Level Range'), +(1100065, 6, 1136467, 0.025, 4, 'TBC Blues 64-67 Level Range'), +(1100065, 7, 1136568, 0.025, 4, 'TBC Blues 65-68 Level Range'), +(1100065, 8, 1136366, 0.025, 4, 'TBC Blues 63-66 Level Range'), +(1100065, 12, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100065, 13, 1186165, 25, 0, 'TBC Patterns 61-65 Level Range'), +(1100066, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100066, 2, 1126567, 0.67, 3, 'TBC Greens 65-67 Level Range'), +(1100066, 3, 1126668, 0.67, 3, 'TBC Greens 66-68 Level Range'), +(1100066, 4, 1126466, 0.67, 3, 'TBC Greens 64-66 Level Range'), +(1100066, 5, 1136467, 0.025, 4, 'TBC Blues 64-67 Level Range'), +(1100066, 6, 1136568, 0.025, 4, 'TBC Blues 65-68 Level Range'), +(1100066, 7, 1136669, 0.025, 4, 'TBC Blues 66-69 Level Range'), +(1100066, 8, 1136366, 0.025, 4, 'TBC Blues 63-66 Level Range'), +(1100066, 12, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100066, 13, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100067, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100067, 2, 1126567, 0.67, 3, 'TBC Greens 65-67 Level Range'), +(1100067, 3, 1126668, 0.67, 3, 'TBC Greens 66-68 Level Range'), +(1100067, 4, 1126769, 0.67, 3, 'TBC Greens 67-69 Level Range'), +(1100067, 5, 1136467, 0.025, 4, 'TBC Blues 64-67 Level Range'), +(1100067, 6, 1136568, 0.025, 4, 'TBC Blues 65-68 Level Range'), +(1100067, 7, 1136669, 0.025, 4, 'TBC Blues 66-69 Level Range'), +(1100067, 8, 1136770, 0.025, 4, 'TBC Blues 67-70 Level Range'), +(1100067, 9, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100067, 13, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100067, 14, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100068, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100068, 2, 1126668, 0.67, 3, 'TBC Greens 66-68 Level Range'), +(1100068, 3, 1126769, 0.67, 3, 'TBC Greens 67-69 Level Range'), +(1100068, 4, 1126870, 0.67, 3, 'TBC Greens 68-70 Level Range'), +(1100068, 5, 1136568, 0.025, 4, 'TBC Blues 65-68 Level Range'), +(1100068, 6, 1136669, 0.025, 4, 'TBC Blues 66-69 Level Range'), +(1100068, 7, 1136873, 0.025, 4, 'TBC Blues 68-73 Level Range'), +(1100068, 8, 1136770, 0.025, 4, 'TBC Blues 67-70 Level Range'), +(1100068, 9, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100068, 13, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100068, 14, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100069, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100069, 2, 1126971, 0.67, 3, 'TBC Greens 69-71 Level Range'), +(1100069, 3, 1126769, 0.67, 3, 'TBC Greens 67-69 Level Range'), +(1100069, 4, 1126870, 0.67, 3, 'TBC Greens 68-70 Level Range'), +(1100069, 5, 1136669, 0.0333, 4, 'TBC Blues 66-69 Level Range'), +(1100069, 6, 1136873, 0.0333, 4, 'TBC Blues 68-73 Level Range'), +(1100069, 7, 1136770, 0.0333, 4, 'TBC Blues 67-70 Level Range'), +(1100069, 8, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100069, 12, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100069, 13, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100070, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100070, 2, 1126971, 0.67, 3, 'TBC Greens 69-71 Level Range'), +(1100070, 3, 1127072, 0.67, 3, 'TBC Greens 70-72 Level Range'), +(1100070, 4, 1126870, 0.67, 3, 'TBC Greens 68-70 Level Range'), +(1100070, 5, 1136873, 0.05, 4, 'TBC Blues 68-73 Level Range'), +(1100070, 6, 1136770, 0.05, 4, 'TBC Blues 67-70 Level Range'), +(1100070, 7, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100070, 11, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100070, 12, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100071, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100071, 2, 1126971, 0.67, 3, 'TBC Greens 69-71 Level Range'), +(1100071, 3, 1127072, 0.67, 3, 'TBC Greens 70-72 Level Range'), +(1100071, 4, 1127173, 0.67, 3, 'TBC Greens 71-73 Level Range'), +(1100071, 5, 1136873, 0.1, 4, 'TBC Blues 68-73 Level Range'), +(1100071, 6, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100071, 10, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100071, 11, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100072, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100072, 2, 1127072, 1, 3, 'TBC Greens 70-72 Level Range'), +(1100072, 3, 1127173, 1, 3, 'TBC Greens 71-73 Level Range'), +(1100072, 4, 1136873, 0.1, 4, 'TBC Blues 68-73 Level Range'), +(1100072, 5, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100072, 9, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100072, 10, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +-- Others +(1000106, 1, 1000610, 10, 0, 'Vanilla Greys 6-10 Level Range'), +(1000106, 2, 1050614, 3, 0, 'Vanilla Scrolls 6-14 Level Range'), +(1000106, 3, 1060610, 3, 0, 'Vanilla Potions 6-10 Level Range'), +(1000106, 4, 1070610, 100, 0, 'Vanilla Miscellaneous 6-10 Level Range'), +(1000106, 5, 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000106, 6, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +(1000107, 1, 1000610, 6, 0, 'Vanilla Greys 6-10 Level Range'), +(1000107, 2, 1010708, 5, 2, 'Vanilla Whites 7-8 Level Range'), +(1000107, 3, 1050614, 3, 0, 'Vanilla Scrolls 6-14 Level Range'), +(1000107, 4, 1060610, 3, 0, 'Vanilla Potions 6-10 Level Range'), +(1000107, 5, 1070610, 100, 0, 'Vanilla Miscellaneous 6-10 Level Range'), +(1000107, 6, 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000107, 7, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +(1000108, 1, 1000610, 6, 0, 'Vanilla Greys 6-10 Level Range'), +(1000108, 2, 1010708, 2.5, 2, 'Vanilla Whites 7-8 Level Range'), +(1000108, 3, 1010809, 2.5, 2, 'Vanilla Whites 8-9 Level Range'), +(1000108, 4, 1020812, 0.75, 3, 'Vanilla Greens 8-12 Level Range'), +(1000108, 5, 1050614, 3, 0, 'Vanilla Scrolls 6-14 Level Range'), +(1000108, 6, 1060610, 3, 0, 'Vanilla Potions 6-10 Level Range'), +(1000108, 7, 1070610, 100, 0, 'Vanilla Miscellaneous 6-10 Level Range'), +(1000108, 8, 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000108, 9, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +(1000109, 1, 1000610, 6, 0, 'Vanilla Greys 6-10 Level Range'), +(1000109, 2, 1010910, 2.5, 2, 'Vanilla Whites 9-10 Level Range'), +(1000109, 3, 1010809, 2.5, 2, 'Vanilla Whites 8-9 Level Range'), +(1000109, 4, 1020812, 1, 3, 'Vanilla Greens 8-12 Level Range'), +(1000109, 5, 1050614, 3, 0, 'Vanilla Scrolls 6-14 Level Range'), +(1000109, 6, 1060610, 3, 0, 'Vanilla Potions 6-10 Level Range'), +(1000109, 7, 1070610, 100, 0, 'Vanilla Miscellaneous 6-10 Level Range'), +(1000109, 8, 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000109, 9, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +(1000110, 1 , 1000610, 6, 0, 'Vanilla Greys 6-10 Level Range'), +(1000110, 2 , 1010910, 2.5, 2, 'Vanilla Whites 9-10 Level Range'), +(1000110, 3 , 1011011, 2.5, 2, 'Vanilla Whites 10-11 Level Range'), +(1000110, 4 , 1021014, 1, 3, 'Vanilla Greens 10-14 Level Range'), +(1000110, 5 , 1020812, 1, 3, 'Vanilla Greens 8-12 Level Range'), +(1000110, 6 , 1050614, 3, 0, 'Vanilla Scrolls 6-14 Level Range'), +(1000110, 7 , 1060610, 3, 0, 'Vanilla Potions 6-10 Level Range'), +(1000110, 8 , 1070610, 100, 0, 'Vanilla Miscellaneous 6-10 Level Range'), +(1000110, 9 , 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000110, 10, 1090110, 1, 0, 'Vanilla Bags 1-10 Level Range'), +(1000111, 1 , 1001115, 6, 0, 'Vanilla Greys 11-15 Level Range'), +(1000111, 2 , 1011112, 2.5, 2, 'Vanilla Whites 11-12 Level Range'), +(1000111, 3 , 1011011, 2.5, 2, 'Vanilla Whites 10-11 Level Range'), +(1000111, 4 , 1021115, 0.67, 3, 'Vanilla Greens 11-15 Level Range'), +(1000111, 5 , 1021014, 0.67, 3, 'Vanilla Greens 10-14 Level Range'), +(1000111, 6 , 1020812, 0.67, 3, 'Vanilla Greens 8-12 Level Range'), +(1000111, 7 , 1050614, 3, 0, 'Vanilla Scrolls 6-14 Level Range'), +(1000111, 8 , 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000111, 9 , 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000111, 10, 1080620, 0.3, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000111, 11, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000112, 1 , 1001115, 6, 0, 'Vanilla Greys 11-15 Level Range'), +(1000112, 2 , 1011112, 2.5, 2, 'Vanilla Whites 11-12 Level Range'), +(1000112, 3 , 1011213, 2.5, 2, 'Vanilla Whites 12-13 Level Range'), +(1000112, 4 , 1021115, 0.5, 3, 'Vanilla Greens 11-15 Level Range'), +(1000112, 5 , 1021014, 0.5, 3, 'Vanilla Greens 10-14 Level Range'), +(1000112, 6 , 1021216, 0.5, 3, 'Vanilla Greens 12-16 Level Range'), +(1000112, 7 , 1020812, 0.5, 3, 'Vanilla Greens 8-12 Level Range'), +(1000112, 8 , 1050614, 3, 0, 'Vanilla Scrolls 6-14 Level Range'), +(1000112, 9 , 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000112, 10, 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000112, 11, 1080620, 0.15, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000112, 12, 1081225, 0.15, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000112, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000113, 1 , 1001115, 6, 0, 'Vanilla Greys 11-15 Level Range'), +(1000113, 2 , 1011314, 2.5, 2, 'Vanilla Whites 13-14 Level Range'), +(1000113, 3 , 1011213, 2.5, 2, 'Vanilla Whites 12-13 Level Range'), +(1000113, 4 , 1021317, 0.5, 3, 'Vanilla Greens 13-17 Level Range'), +(1000113, 5 , 1021115, 0.5, 3, 'Vanilla Greens 11-15 Level Range'), +(1000113, 6 , 1021014, 0.5, 3, 'Vanilla Greens 10-14 Level Range'), +(1000113, 7 , 1021216, 0.5, 3, 'Vanilla Greens 12-16 Level Range'), +(1000113, 8 , 1050614, 3, 0, 'Vanilla Scrolls 6-14 Level Range'), +(1000113, 9 , 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000113, 10, 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000113, 11, 1080620, 0.15, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000113, 12, 1081225, 0.15, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000113, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000114, 1 , 1001115, 6, 0, 'Vanilla Greys 11-15 Level Range'), +(1000114, 2 , 1011314, 2.5, 2, 'Vanilla Whites 13-14 Level Range'), +(1000114, 3 , 1011415, 2.5, 2, 'Vanilla Whites 14-15 Level Range'), +(1000114, 4 , 1021317, 0.4, 3, 'Vanilla Greens 13-17 Level Range'), +(1000114, 5 , 1021115, 0.4, 3, 'Vanilla Greens 11-15 Level Range'), +(1000114, 6 , 1021014, 0.4, 3, 'Vanilla Greens 10-14 Level Range'), +(1000114, 7 , 1021216, 0.4, 3, 'Vanilla Greens 12-16 Level Range'), +(1000114, 8 , 1021418, 0.4, 3, 'Vanilla Greens 14-18 Level Range'), +(1000114, 9 , 1050614, 3, 0, 'Vanilla Scrolls 6-14 Level Range'), +(1000114, 10, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000114, 11, 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000114, 12, 1080620, 0.15, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000114, 13, 1081225, 0.15, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000114, 14, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000115, 1, 1001115, 6, 0, 'Vanilla Greys 11-15 Level Range'), +(1000115, 2, 1011415, 5, 2, 'Vanilla Whites 14-15 Level Range'), +(1000115, 3, 1021317, 0.4, 3, 'Vanilla Greens 13-17 Level Range'), +(1000115, 4, 1021115, 0.4, 3, 'Vanilla Greens 11-15 Level Range'), +(1000115, 5, 1021216, 0.4, 3, 'Vanilla Greens 12-16 Level Range'), +(1000115, 6, 1021418, 0.4, 3, 'Vanilla Greens 14-18 Level Range'), +(1000115, 7, 1021519, 0.4, 3, 'Vanilla Greens 15-19 Level Range'), +(1000115, 8, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000115, 9, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000115, 10, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000115, 11, 1080620, 0.15, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000115, 12, 1081225, 0.15, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000115, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000116, 1, 1001620, 6, 0, 'Vanilla Greys 16-20 Level Range'), +(1000116, 2, 1021317, 0.4, 3, 'Vanilla Greens 13-17 Level Range'), +(1000116, 3, 1021216, 0.4, 3, 'Vanilla Greens 12-16 Level Range'), +(1000116, 4, 1021418, 0.4, 3, 'Vanilla Greens 14-18 Level Range'), +(1000116, 5, 1021519, 0.4, 3, 'Vanilla Greens 15-19 Level Range'), +(1000116, 6, 1021620, 0.4, 3, 'Vanilla Greens 16-20 Level Range'), +(1000116, 7, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000116, 8, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000116, 9, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000116, 10, 1080620, 0.1, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000116, 11, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000116, 12, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000116, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000117, 1, 1001620, 6, 0, 'Vanilla Greys 16-20 Level Range'), +(1000117, 2, 1021317, 0.4, 3, 'Vanilla Greens 13-17 Level Range'), +(1000117, 3, 1021418, 0.4, 3, 'Vanilla Greens 14-18 Level Range'), +(1000117, 4, 1021519, 0.4, 3, 'Vanilla Greens 15-19 Level Range'), +(1000117, 5, 1021620, 0.4, 3, 'Vanilla Greens 16-20 Level Range'), +(1000117, 6, 1021721, 0.4, 3, 'Vanilla Greens 17-21 Level Range'), +(1000117, 7, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000117, 8, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000117, 9, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000117, 10, 1080620, 0.1, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000117, 11, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000117, 12, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000117, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000118, 1, 1001620, 6, 0, 'Vanilla Greys 16-20 Level Range'), +(1000118, 2, 1011822, 1, 2, 'Vanilla Whites 18-22 Level Range'), +(1000118, 3, 1021418, 0.4, 3, 'Vanilla Greens 14-18 Level Range'), +(1000118, 4, 1021519, 0.4, 3, 'Vanilla Greens 15-19 Level Range'), +(1000118, 5, 1021620, 0.4, 3, 'Vanilla Greens 16-20 Level Range'), +(1000118, 6, 1021721, 0.4, 3, 'Vanilla Greens 17-21 Level Range'), +(1000118, 7, 1021822, 0.4, 3, 'Vanilla Greens 18-22 Level Range'), +(1000118, 8, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000118, 9, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000118, 10, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000118, 11, 1080620, 0.1, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000118, 12, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000118, 13, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000118, 14, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000119, 1, 1001620, 6, 0, 'Vanilla Greys 16-20 Level Range'), +(1000119, 2, 1011822, 0.5, 2, 'Vanilla Whites 18-22 Level Range'), +(1000119, 3, 1011923, 0.5, 2, 'Vanilla Whites 19-23 Level Range'), +(1000119, 4, 1021519, 0.4, 3, 'Vanilla Greens 15-19 Level Range'), +(1000119, 5, 1021620, 0.4, 3, 'Vanilla Greens 16-20 Level Range'), +(1000119, 6, 1021721, 0.4, 3, 'Vanilla Greens 17-21 Level Range'), +(1000119, 7, 1021822, 0.4, 3, 'Vanilla Greens 18-22 Level Range'), +(1000119, 8, 1021923, 0.4, 3, 'Vanilla Greens 19-23 Level Range'), +(1000119, 9, 1031922, 0.1, 4, 'Vanilla Blues 19-22 Level Range'), +(1000119, 10, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000119, 11, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000119, 12, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000119, 13, 1080620, 0.1, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000119, 14, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000119, 15, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000119, 16, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000120, 1, 1001620, 6, 0, 'Vanilla Greys 16-20 Level Range'), +(1000120, 2, 1012024, 0.3333, 2, 'Vanilla Whites 20-24 Level Range'), +(1000120, 3, 1011822, 0.3333, 2, 'Vanilla Whites 18-22 Level Range'), +(1000120, 4, 1011923, 0.3333, 2, 'Vanilla Whites 19-23 Level Range'), +(1000120, 5, 1022024, 0.4, 3, 'Vanilla Greens 20-24 Level Range'), +(1000120, 6, 1021620, 0.4, 3, 'Vanilla Greens 16-20 Level Range'), +(1000120, 7, 1021721, 0.4, 3, 'Vanilla Greens 17-21 Level Range'), +(1000120, 8, 1021822, 0.4, 3, 'Vanilla Greens 18-22 Level Range'), +(1000120, 9, 1021923, 0.4, 3, 'Vanilla Greens 19-23 Level Range'), +(1000120, 10, 1032023, 0.05, 4, 'Vanilla Blues 20-23 Level Range'), +(1000120, 11, 1031922, 0.05, 4, 'Vanilla Blues 19-22 Level Range'), +(1000120, 12, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000120, 13, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000120, 14, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000120, 15, 1080620, 0.075, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000120, 16, 1081225, 0.075, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000120, 17, 1082035, 0.075, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000120, 18, 1081630, 0.075, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000120, 19, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000121, 1, 1002125, 6, 0, 'Vanilla Greys 21-25 Level Range'), +(1000121, 2, 1012024, 0.25, 2, 'Vanilla Whites 20-24 Level Range'), +(1000121, 3, 1012125, 0.25, 2, 'Vanilla Whites 21-25 Level Range'), +(1000121, 4, 1011822, 0.25, 2, 'Vanilla Whites 18-22 Level Range'), +(1000121, 5, 1011923, 0.25, 2, 'Vanilla Whites 19-23 Level Range'), +(1000121, 6, 1022125, 0.4, 3, 'Vanilla Greens 21-25 Level Range'), +(1000121, 7, 1022024, 0.4, 3, 'Vanilla Greens 20-24 Level Range'), +(1000121, 8, 1021721, 0.4, 3, 'Vanilla Greens 17-21 Level Range'), +(1000121, 9, 1021822, 0.4, 3, 'Vanilla Greens 18-22 Level Range'), +(1000121, 10, 1021923, 0.4, 3, 'Vanilla Greens 19-23 Level Range'), +(1000121, 11, 1032124, 0.0333, 4, 'Vanilla Blues 21-24 Level Range'), +(1000121, 12, 1032023, 0.0333, 4, 'Vanilla Blues 20-23 Level Range'), +(1000121, 13, 1031922, 0.0333, 4, 'Vanilla Blues 19-22 Level Range'), +(1000121, 14, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000121, 15, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000121, 16, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000121, 17, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000121, 18, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000121, 19, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000121, 20, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000122, 1, 1002125, 6, 0, 'Vanilla Greys 21-25 Level Range'), +(1000122, 2, 1012024, 0.25, 2, 'Vanilla Whites 20-24 Level Range'), +(1000122, 3, 1012125, 0.25, 2, 'Vanilla Whites 21-25 Level Range'), +(1000122, 4, 1011822, 0.25, 2, 'Vanilla Whites 18-22 Level Range'), +(1000122, 5, 1011923, 0.25, 2, 'Vanilla Whites 19-23 Level Range'), +(1000122, 6, 1022125, 0.4, 3, 'Vanilla Greens 21-25 Level Range'), +(1000122, 7, 1022024, 0.4, 3, 'Vanilla Greens 20-24 Level Range'), +(1000122, 8, 1022226, 0.4, 3, 'Vanilla Greens 22-26 Level Range'), +(1000122, 9, 1021822, 0.4, 3, 'Vanilla Greens 18-22 Level Range'), +(1000122, 10, 1021923, 0.4, 3, 'Vanilla Greens 19-23 Level Range'), +(1000122, 11, 1032124, 0.025, 4, 'Vanilla Blues 21-24 Level Range'), +(1000122, 12, 1032023, 0.025, 4, 'Vanilla Blues 20-23 Level Range'), +(1000122, 13, 1032225, 0.025, 4, 'Vanilla Blues 22-25 Level Range'), +(1000122, 14, 1031922, 0.025, 4, 'Vanilla Blues 19-22 Level Range'), +(1000122, 15, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000122, 16, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000122, 17, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000122, 18, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000122, 19, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000122, 20, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000122, 21, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000123, 1, 1002125, 6, 0, 'Vanilla Greys 21-25 Level Range'), +(1000123, 2, 1012024, 0.3333, 2, 'Vanilla Whites 20-24 Level Range'), +(1000123, 3, 1012125, 0.3333, 2, 'Vanilla Whites 21-25 Level Range'), +(1000123, 4, 1011923, 0.3333, 2, 'Vanilla Whites 19-23 Level Range'), +(1000123, 5, 1022327, 0.4, 3, 'Vanilla Greens 23-27 Level Range'), +(1000123, 6, 1022125, 0.4, 3, 'Vanilla Greens 21-25 Level Range'), +(1000123, 7, 1022024, 0.4, 3, 'Vanilla Greens 20-24 Level Range'), +(1000123, 8, 1022226, 0.4, 3, 'Vanilla Greens 22-26 Level Range'), +(1000123, 9, 1021923, 0.4, 3, 'Vanilla Greens 19-23 Level Range'), +(1000123, 10, 1032124, 0.025, 4, 'Vanilla Blues 21-24 Level Range'), +(1000123, 11, 1032023, 0.025, 4, 'Vanilla Blues 20-23 Level Range'), +(1000123, 12, 1032225, 0.025, 4, 'Vanilla Blues 22-25 Level Range'), +(1000123, 13, 1032326, 0.025, 4, 'Vanilla Blues 23-26 Level Range'), +(1000123, 14, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000123, 15, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000123, 16, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000123, 17, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000123, 18, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000123, 19, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000123, 20, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000124, 1, 1002125, 6, 0, 'Vanilla Greys 21-25 Level Range'), +(1000124, 2, 1012024, 0.5, 2, 'Vanilla Whites 20-24 Level Range'), +(1000124, 3, 1012125, 0.5, 2, 'Vanilla Whites 21-25 Level Range'), +(1000124, 4, 1022327, 0.4, 3, 'Vanilla Greens 23-27 Level Range'), +(1000124, 5, 1022428, 0.4, 3, 'Vanilla Greens 24-28 Level Range'), +(1000124, 6, 1022125, 0.4, 3, 'Vanilla Greens 21-25 Level Range'), +(1000124, 7, 1022024, 0.4, 3, 'Vanilla Greens 20-24 Level Range'), +(1000124, 8, 1022226, 0.4, 3, 'Vanilla Greens 22-26 Level Range'), +(1000124, 9, 1032427, 0.025, 4, 'Vanilla Blues 24-27 Level Range'), +(1000124, 10, 1032124, 0.025, 4, 'Vanilla Blues 21-24 Level Range'), +(1000124, 11, 1032225, 0.025, 4, 'Vanilla Blues 22-25 Level Range'), +(1000124, 12, 1032326, 0.025, 4, 'Vanilla Blues 23-26 Level Range'), +(1000124, 13, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000124, 14, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000124, 15, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000124, 16, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000124, 17, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000124, 18, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000124, 19, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000125, 1, 1002125, 6, 0, 'Vanilla Greys 21-25 Level Range'), +(1000125, 2, 1012125, 1, 2, 'Vanilla Whites 21-25 Level Range'), +(1000125, 3, 1022327, 0.4, 3, 'Vanilla Greens 23-27 Level Range'), +(1000125, 4, 1022428, 0.4, 3, 'Vanilla Greens 24-28 Level Range'), +(1000125, 5, 1022125, 0.4, 3, 'Vanilla Greens 21-25 Level Range'), +(1000125, 6, 1022226, 0.4, 3, 'Vanilla Greens 22-26 Level Range'), +(1000125, 7, 1022529, 0.4, 3, 'Vanilla Greens 25-29 Level Range'), +(1000125, 8, 1032427, 0.025, 4, 'Vanilla Blues 24-27 Level Range'), +(1000125, 9, 1032528, 0.025, 4, 'Vanilla Blues 25-28 Level Range'), +(1000125, 10, 1032225, 0.025, 4, 'Vanilla Blues 22-25 Level Range'), +(1000125, 11, 1032326, 0.025, 4, 'Vanilla Blues 23-26 Level Range'), +(1000125, 12, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000125, 13, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000125, 14, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000125, 15, 1081225, 0.1, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000125, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000125, 17, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000125, 18, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000126, 1, 1002630, 6, 0, 'Vanilla Greys 26-30 Level Range'), +(1000126, 2, 1022327, 0.4, 3, 'Vanilla Greens 23-27 Level Range'), +(1000126, 3, 1022428, 0.4, 3, 'Vanilla Greens 24-28 Level Range'), +(1000126, 4, 1022630, 0.4, 3, 'Vanilla Greens 26-30 Level Range'), +(1000126, 5, 1022226, 0.4, 3, 'Vanilla Greens 22-26 Level Range'), +(1000126, 6, 1022529, 0.4, 3, 'Vanilla Greens 25-29 Level Range'), +(1000126, 7, 1032427, 0.025, 4, 'Vanilla Blues 24-27 Level Range'), +(1000126, 8, 1032528, 0.025, 4, 'Vanilla Blues 25-28 Level Range'), +(1000126, 9, 1032629, 0.025, 4, 'Vanilla Blues 26-29 Level Range'), +(1000126, 10, 1032326, 0.025, 4, 'Vanilla Blues 23-26 Level Range'), +(1000126, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000126, 12, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000126, 13, 1072627, 100, 0, 'Vanilla Miscellaneous 26-27 Level Range'), +(1000126, 14, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000126, 15, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000126, 16, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000126, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000127, 1, 1002630, 6, 0, 'Vanilla Greys 26-30 Level Range'), +(1000127, 2, 1022731, 0.4, 3, 'Vanilla Greens 27-31 Level Range'), +(1000127, 3, 1022327, 0.4, 3, 'Vanilla Greens 23-27 Level Range'), +(1000127, 4, 1022428, 0.4, 3, 'Vanilla Greens 24-28 Level Range'), +(1000127, 5, 1022630, 0.4, 3, 'Vanilla Greens 26-30 Level Range'), +(1000127, 6, 1022529, 0.4, 3, 'Vanilla Greens 25-29 Level Range'), +(1000127, 7, 1032427, 0.025, 4, 'Vanilla Blues 24-27 Level Range'), +(1000127, 8, 1032528, 0.025, 4, 'Vanilla Blues 25-28 Level Range'), +(1000127, 9, 1032629, 0.025, 4, 'Vanilla Blues 26-29 Level Range'), +(1000127, 10, 1032730, 0.025, 4, 'Vanilla Blues 27-30 Level Range'), +(1000127, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000127, 12, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000127, 13, 1072627, 100, 0, 'Vanilla Miscellaneous 26-27 Level Range'), +(1000127, 14, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000127, 15, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000127, 16, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000127, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000128, 1, 1002630, 6, 0, 'Vanilla Greys 26-30 Level Range'), +(1000128, 2, 1022731, 0.4, 3, 'Vanilla Greens 27-31 Level Range'), +(1000128, 3, 1022832, 0.4, 3, 'Vanilla Greens 28-32 Level Range'), +(1000128, 4, 1022428, 0.4, 3, 'Vanilla Greens 24-28 Level Range'), +(1000128, 5, 1022630, 0.4, 3, 'Vanilla Greens 26-30 Level Range'), +(1000128, 6, 1022529, 0.4, 3, 'Vanilla Greens 25-29 Level Range'), +(1000128, 7, 1032528, 0.025, 4, 'Vanilla Blues 25-28 Level Range'), +(1000128, 8, 1032831, 0.025, 4, 'Vanilla Blues 28-31 Level Range'), +(1000128, 9, 1032629, 0.025, 4, 'Vanilla Blues 26-29 Level Range'), +(1000128, 10, 1032730, 0.025, 4, 'Vanilla Blues 27-30 Level Range'), +(1000128, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000128, 12, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000128, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +(1000128, 14, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000128, 15, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000128, 16, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000128, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000129, 1, 1002630, 6, 0, 'Vanilla Greys 26-30 Level Range'), +(1000129, 2, 1022731, 0.4, 3, 'Vanilla Greens 27-31 Level Range'), +(1000129, 3, 1022832, 0.4, 3, 'Vanilla Greens 28-32 Level Range'), +(1000129, 4, 1022933, 0.4, 3, 'Vanilla Greens 29-33 Level Range'), +(1000129, 5, 1022630, 0.4, 3, 'Vanilla Greens 26-30 Level Range'), +(1000129, 6, 1022529, 0.4, 3, 'Vanilla Greens 25-29 Level Range'), +(1000129, 7, 1032932, 0.025, 4, 'Vanilla Blues 29-32 Level Range'), +(1000129, 8, 1032831, 0.025, 4, 'Vanilla Blues 28-31 Level Range'), +(1000129, 9, 1032629, 0.025, 4, 'Vanilla Blues 26-29 Level Range'), +(1000129, 10, 1032730, 0.025, 4, 'Vanilla Blues 27-30 Level Range'), +(1000129, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000129, 12, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000129, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +(1000129, 14, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000129, 15, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000129, 16, 1081630, 0.1, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000129, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000130, 1, 1002630, 6, 0, 'Vanilla Greys 26-30 Level Range'), +(1000130, 2, 1023034, 0.4, 3, 'Vanilla Greens 30-34 Level Range'), +(1000130, 3, 1022731, 0.4, 3, 'Vanilla Greens 27-31 Level Range'), +(1000130, 4, 1022832, 0.4, 3, 'Vanilla Greens 28-32 Level Range'), +(1000130, 5, 1022933, 0.4, 3, 'Vanilla Greens 29-33 Level Range'), +(1000130, 6, 1022630, 0.4, 3, 'Vanilla Greens 26-30 Level Range'), +(1000130, 7, 1032932, 0.025, 4, 'Vanilla Blues 29-32 Level Range'), +(1000130, 8, 1032831, 0.025, 4, 'Vanilla Blues 28-31 Level Range'), +(1000130, 9, 1033033, 0.025, 4, 'Vanilla Blues 30-33 Level Range'), +(1000130, 10, 1032730, 0.025, 4, 'Vanilla Blues 27-30 Level Range'), +(1000130, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000130, 12, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000130, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +(1000130, 14, 1083045, 0.075, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000130, 15, 1082640, 0.075, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000130, 16, 1082035, 0.075, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000130, 17, 1081630, 0.075, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000130, 18, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000131, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000131, 2, 1023034, 0.4, 3, 'Vanilla Greens 30-34 Level Range'), +(1000131, 3, 1023135, 0.4, 3, 'Vanilla Greens 31-35 Level Range'), +(1000131, 4, 1022731, 0.4, 3, 'Vanilla Greens 27-31 Level Range'), +(1000131, 5, 1022832, 0.4, 3, 'Vanilla Greens 28-32 Level Range'), +(1000131, 6, 1022933, 0.4, 3, 'Vanilla Greens 29-33 Level Range'), +(1000131, 7, 1033134, 0.025, 4, 'Vanilla Blues 31-34 Level Range'), +(1000131, 8, 1032932, 0.025, 4, 'Vanilla Blues 29-32 Level Range'), +(1000131, 9, 1032831, 0.025, 4, 'Vanilla Blues 28-31 Level Range'), +(1000131, 10, 1033033, 0.025, 4, 'Vanilla Blues 30-33 Level Range'), +(1000131, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000131, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000131, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000131, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000131, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000131, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000131, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000132, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000132, 2, 1023034, 0.4, 3, 'Vanilla Greens 30-34 Level Range'), +(1000132, 3, 1023135, 0.4, 3, 'Vanilla Greens 31-35 Level Range'), +(1000132, 4, 1022832, 0.4, 3, 'Vanilla Greens 28-32 Level Range'), +(1000132, 5, 1022933, 0.4, 3, 'Vanilla Greens 29-33 Level Range'), +(1000132, 6, 1023236, 0.4, 3, 'Vanilla Greens 32-36 Level Range'), +(1000132, 7, 1033134, 0.025, 4, 'Vanilla Blues 31-34 Level Range'), +(1000132, 8, 1032932, 0.025, 4, 'Vanilla Blues 29-32 Level Range'), +(1000132, 9, 1033235, 0.025, 4, 'Vanilla Blues 32-35 Level Range'), +(1000132, 10, 1033033, 0.025, 4, 'Vanilla Blues 30-33 Level Range'), +(1000132, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000132, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000132, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000132, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000132, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000132, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000132, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000133, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000133, 2, 1023034, 0.4, 3, 'Vanilla Greens 30-34 Level Range'), +(1000133, 3, 1023135, 0.4, 3, 'Vanilla Greens 31-35 Level Range'), +(1000133, 4, 1022933, 0.4, 3, 'Vanilla Greens 29-33 Level Range'), +(1000133, 5, 1023337, 0.4, 3, 'Vanilla Greens 33-37 Level Range'), +(1000133, 6, 1023236, 0.4, 3, 'Vanilla Greens 32-36 Level Range'), +(1000133, 7, 1033134, 0.025, 4, 'Vanilla Blues 31-34 Level Range'), +(1000133, 8, 1033336, 0.025, 4, 'Vanilla Blues 33-36 Level Range'), +(1000133, 9, 1033235, 0.025, 4, 'Vanilla Blues 32-35 Level Range'), +(1000133, 10, 1033033, 0.025, 4, 'Vanilla Blues 30-33 Level Range'), +(1000133, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000133, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000133, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000133, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000133, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000133, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000133, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000134, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000134, 2, 1023034, 0.4, 3, 'Vanilla Greens 30-34 Level Range'), +(1000134, 3, 1023438, 0.4, 3, 'Vanilla Greens 34-38 Level Range'), +(1000134, 4, 1023135, 0.4, 3, 'Vanilla Greens 31-35 Level Range'), +(1000134, 5, 1023337, 0.4, 3, 'Vanilla Greens 33-37 Level Range'), +(1000134, 6, 1023236, 0.4, 3, 'Vanilla Greens 32-36 Level Range'), +(1000134, 7, 1033134, 0.025, 4, 'Vanilla Blues 31-34 Level Range'), +(1000134, 8, 1033336, 0.025, 4, 'Vanilla Blues 33-36 Level Range'), +(1000134, 9, 1033437, 0.025, 4, 'Vanilla Blues 34-37 Level Range'), +(1000134, 10, 1033235, 0.025, 4, 'Vanilla Blues 32-35 Level Range'), +(1000134, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000134, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000134, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000134, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000134, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000134, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000134, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000135, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000135, 2, 1023438, 0.4, 3, 'Vanilla Greens 34-38 Level Range'), +(1000135, 3, 1023135, 0.4, 3, 'Vanilla Greens 31-35 Level Range'), +(1000135, 4, 1023337, 0.4, 3, 'Vanilla Greens 33-37 Level Range'), +(1000135, 5, 1023539, 0.4, 3, 'Vanilla Greens 35-39 Level Range'), +(1000135, 6, 1023236, 0.4, 3, 'Vanilla Greens 32-36 Level Range'), +(1000135, 7, 1033336, 0.025, 4, 'Vanilla Blues 33-36 Level Range'), +(1000135, 8, 1033437, 0.025, 4, 'Vanilla Blues 34-37 Level Range'), +(1000135, 9, 1033235, 0.025, 4, 'Vanilla Blues 32-35 Level Range'), +(1000135, 10, 1033538, 0.025, 4, 'Vanilla Blues 35-38 Level Range'), +(1000135, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000135, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000135, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000135, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000135, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000135, 16, 1082035, 0.1, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000135, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000136, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000136, 2, 1023438, 0.4, 3, 'Vanilla Greens 34-38 Level Range'), +(1000136, 3, 1023640, 0.4, 3, 'Vanilla Greens 36-40 Level Range'), +(1000136, 4, 1023337, 0.4, 3, 'Vanilla Greens 33-37 Level Range'), +(1000136, 5, 1023539, 0.4, 3, 'Vanilla Greens 35-39 Level Range'), +(1000136, 6, 1023236, 0.4, 3, 'Vanilla Greens 32-36 Level Range'), +(1000136, 7, 1033639, 0.025, 4, 'Vanilla Blues 36-39 Level Range'), +(1000136, 8, 1033336, 0.025, 4, 'Vanilla Blues 33-36 Level Range'), +(1000136, 9, 1033437, 0.025, 4, 'Vanilla Blues 34-37 Level Range'), +(1000136, 10, 1033538, 0.025, 4, 'Vanilla Blues 35-38 Level Range'), +(1000136, 11, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000136, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000136, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000136, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000136, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000136, 16, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000136, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000137, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000137, 2, 1023438, 0.4, 3, 'Vanilla Greens 34-38 Level Range'), +(1000137, 3, 1023640, 0.4, 3, 'Vanilla Greens 36-40 Level Range'), +(1000137, 4, 1023741, 0.4, 3, 'Vanilla Greens 37-41 Level Range'), +(1000137, 5, 1023337, 0.4, 3, 'Vanilla Greens 33-37 Level Range'), +(1000137, 6, 1023539, 0.4, 3, 'Vanilla Greens 35-39 Level Range'), +(1000137, 7, 1033639, 0.025, 4, 'Vanilla Blues 36-39 Level Range'), +(1000137, 8, 1033740, 0.025, 4, 'Vanilla Blues 37-40 Level Range'), +(1000137, 9, 1033437, 0.025, 4, 'Vanilla Blues 34-37 Level Range'), +(1000137, 10, 1033538, 0.025, 4, 'Vanilla Blues 35-38 Level Range'), +(1000137, 11, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000137, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000137, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000137, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000137, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000137, 16, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000137, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000138, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000138, 2, 1023438, 0.4, 3, 'Vanilla Greens 34-38 Level Range'), +(1000138, 3, 1023640, 0.4, 3, 'Vanilla Greens 36-40 Level Range'), +(1000138, 4, 1023741, 0.4, 3, 'Vanilla Greens 37-41 Level Range'), +(1000138, 5, 1023842, 0.4, 3, 'Vanilla Greens 38-42 Level Range'), +(1000138, 6, 1023539, 0.4, 3, 'Vanilla Greens 35-39 Level Range'), +(1000138, 7, 1033841, 0.025, 4, 'Vanilla Blues 38-41 Level Range'), +(1000138, 8, 1033639, 0.025, 4, 'Vanilla Blues 36-39 Level Range'), +(1000138, 9, 1033740, 0.025, 4, 'Vanilla Blues 37-40 Level Range'), +(1000138, 10, 1033538, 0.025, 4, 'Vanilla Blues 35-38 Level Range'), +(1000138, 11, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000138, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000138, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000138, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000138, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000138, 16, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000138, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000139, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000139, 2, 1023640, 0.4, 3, 'Vanilla Greens 36-40 Level Range'), +(1000139, 3, 1023741, 0.4, 3, 'Vanilla Greens 37-41 Level Range'), +(1000139, 4, 1023842, 0.4, 3, 'Vanilla Greens 38-42 Level Range'), +(1000139, 5, 1023943, 0.4, 3, 'Vanilla Greens 39-43 Level Range'), +(1000139, 6, 1023539, 0.4, 3, 'Vanilla Greens 35-39 Level Range'), +(1000139, 7, 1033841, 0.025, 4, 'Vanilla Blues 38-41 Level Range'), +(1000139, 8, 1033639, 0.025, 4, 'Vanilla Blues 36-39 Level Range'), +(1000139, 9, 1033740, 0.025, 4, 'Vanilla Blues 37-40 Level Range'), +(1000139, 10, 1033942, 0.025, 4, 'Vanilla Blues 39-42 Level Range'), +(1000139, 11, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000139, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000139, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000139, 14, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000139, 15, 1082640, 0.1, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000139, 16, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000139, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000140, 1, 1003140, 6, 0, 'Vanilla Greys 31-40 Level Range'), +(1000140, 2, 1023640, 0.4, 3, 'Vanilla Greens 36-40 Level Range'), +(1000140, 3, 1023741, 0.4, 3, 'Vanilla Greens 37-41 Level Range'), +(1000140, 4, 1023842, 0.4, 3, 'Vanilla Greens 38-42 Level Range'), +(1000140, 5, 1023943, 0.4, 3, 'Vanilla Greens 39-43 Level Range'), +(1000140, 6, 1024044, 0.4, 3, 'Vanilla Greens 40-44 Level Range'), +(1000140, 7, 1033841, 0.025, 4, 'Vanilla Blues 38-41 Level Range'), +(1000140, 8, 1033740, 0.025, 4, 'Vanilla Blues 37-40 Level Range'), +(1000140, 9, 1034043, 0.025, 4, 'Vanilla Blues 40-43 Level Range'), +(1000140, 10, 1033942, 0.025, 4, 'Vanilla Blues 39-42 Level Range'), +(1000140, 11, 1044046, 0.05, 5, 'Vanilla Purples 40-46 Level Range'), +(1000140, 12, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000140, 13, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000140, 14, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000140, 15, 1083045, 0.075, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000140, 16, 1082640, 0.075, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000140, 17, 1083650, 0.075, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000140, 18, 1084055, 0.075, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000140, 19, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000141, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000141, 2, 1024145, 0.4, 3, 'Vanilla Greens 41-45 Level Range'), +(1000141, 3, 1023741, 0.4, 3, 'Vanilla Greens 37-41 Level Range'), +(1000141, 4, 1023842, 0.4, 3, 'Vanilla Greens 38-42 Level Range'), +(1000141, 5, 1023943, 0.4, 3, 'Vanilla Greens 39-43 Level Range'), +(1000141, 6, 1024044, 0.4, 3, 'Vanilla Greens 40-44 Level Range'), +(1000141, 7, 1033841, 0.025, 4, 'Vanilla Blues 38-41 Level Range'), +(1000141, 8, 1034043, 0.025, 4, 'Vanilla Blues 40-43 Level Range'), +(1000141, 9, 1033942, 0.025, 4, 'Vanilla Blues 39-42 Level Range'), +(1000141, 10, 1034144, 0.025, 4, 'Vanilla Blues 41-44 Level Range'), +(1000141, 11, 1044046, 0.05, 5, 'Vanilla Purples 40-46 Level Range'), +(1000141, 12, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000141, 13, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000141, 14, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000141, 15, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000141, 16, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000141, 17, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000141, 18, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000142, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000142, 2, 1024145, 0.4, 3, 'Vanilla Greens 41-45 Level Range'), +(1000142, 3, 1024246, 0.4, 3, 'Vanilla Greens 42-46 Level Range'), +(1000142, 4, 1023842, 0.4, 3, 'Vanilla Greens 38-42 Level Range'), +(1000142, 5, 1023943, 0.4, 3, 'Vanilla Greens 39-43 Level Range'), +(1000142, 6, 1024044, 0.4, 3, 'Vanilla Greens 40-44 Level Range'), +(1000142, 7, 1034245, 0.025, 4, 'Vanilla Blues 42-45 Level Range'), +(1000142, 8, 1034043, 0.025, 4, 'Vanilla Blues 40-43 Level Range'), +(1000142, 9, 1033942, 0.025, 4, 'Vanilla Blues 39-42 Level Range'), +(1000142, 10, 1034144, 0.025, 4, 'Vanilla Blues 41-44 Level Range'), +(1000142, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +(1000142, 12, 1044046, 0.025, 5, 'Vanilla Purples 40-46 Level Range'), +(1000142, 13, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000142, 14, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000142, 15, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000142, 16, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000142, 17, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000142, 18, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000142, 19, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000143, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000143, 2, 1024145, 0.4, 3, 'Vanilla Greens 41-45 Level Range'), +(1000143, 3, 1024347, 0.4, 3, 'Vanilla Greens 43-47 Level Range'), +(1000143, 4, 1024246, 0.4, 3, 'Vanilla Greens 42-46 Level Range'), +(1000143, 5, 1023943, 0.4, 3, 'Vanilla Greens 39-43 Level Range'), +(1000143, 6, 1024044, 0.4, 3, 'Vanilla Greens 40-44 Level Range'), +(1000143, 7, 1034245, 0.025, 4, 'Vanilla Blues 42-45 Level Range'), +(1000143, 8, 1034346, 0.025, 4, 'Vanilla Blues 43-46 Level Range'), +(1000143, 9, 1034043, 0.025, 4, 'Vanilla Blues 40-43 Level Range'), +(1000143, 10, 1034144, 0.025, 4, 'Vanilla Blues 41-44 Level Range'), +(1000143, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +(1000143, 12, 1044046, 0.025, 5, 'Vanilla Purples 40-46 Level Range'), +(1000143, 13, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000143, 14, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000143, 15, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000143, 16, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000143, 17, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000143, 18, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000143, 19, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000144, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000144, 2, 1024145, 0.4, 3, 'Vanilla Greens 41-45 Level Range'), +(1000144, 3, 1024347, 0.4, 3, 'Vanilla Greens 43-47 Level Range'), +(1000144, 4, 1024448, 0.4, 3, 'Vanilla Greens 44-48 Level Range'), +(1000144, 5, 1024246, 0.4, 3, 'Vanilla Greens 42-46 Level Range'), +(1000144, 6, 1024044, 0.4, 3, 'Vanilla Greens 40-44 Level Range'), +(1000144, 7, 1034245, 0.025, 4, 'Vanilla Blues 42-45 Level Range'), +(1000144, 8, 1034447, 0.025, 4, 'Vanilla Blues 44-47 Level Range'), +(1000144, 9, 1034346, 0.025, 4, 'Vanilla Blues 43-46 Level Range'), +(1000144, 10, 1034144, 0.025, 4, 'Vanilla Blues 41-44 Level Range'), +(1000144, 11, 1044248, 0.0167, 5, 'Vanilla Purples 42-48 Level Range'), +(1000144, 12, 1044046, 0.0167, 5, 'Vanilla Purples 40-46 Level Range'), +(1000144, 13, 1044450, 0.0167, 5, 'Vanilla Purples 44-50 Level Range'), +(1000144, 14, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000144, 15, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000144, 16, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000144, 17, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000144, 18, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000144, 19, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000144, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000145, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000145, 2, 1024145, 0.4, 3, 'Vanilla Greens 41-45 Level Range'), +(1000145, 3, 1024347, 0.4, 3, 'Vanilla Greens 43-47 Level Range'), +(1000145, 4, 1024448, 0.4, 3, 'Vanilla Greens 44-48 Level Range'), +(1000145, 5, 1024549, 0.4, 3, 'Vanilla Greens 45-49 Level Range'), +(1000145, 6, 1024246, 0.4, 3, 'Vanilla Greens 42-46 Level Range'), +(1000145, 7, 1034245, 0.025, 4, 'Vanilla Blues 42-45 Level Range'), +(1000145, 8, 1034447, 0.025, 4, 'Vanilla Blues 44-47 Level Range'), +(1000145, 9, 1034346, 0.025, 4, 'Vanilla Blues 43-46 Level Range'), +(1000145, 10, 1034548, 0.025, 4, 'Vanilla Blues 45-48 Level Range'), +(1000145, 11, 1044248, 0.0167, 5, 'Vanilla Purples 42-48 Level Range'), +(1000145, 12, 1044046, 0.0167, 5, 'Vanilla Purples 40-46 Level Range'), +(1000145, 13, 1044450, 0.0167, 5, 'Vanilla Purples 44-50 Level Range'), +(1000145, 14, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000145, 15, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000145, 16, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000145, 17, 1083045, 0.1, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000145, 18, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000145, 19, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000145, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000146, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000146, 2, 1024347, 0.4, 3, 'Vanilla Greens 43-47 Level Range'), +(1000146, 3, 1024448, 0.4, 3, 'Vanilla Greens 44-48 Level Range'), +(1000146, 4, 1024549, 0.4, 3, 'Vanilla Greens 45-49 Level Range'), +(1000146, 5, 1024246, 0.4, 3, 'Vanilla Greens 42-46 Level Range'), +(1000146, 6, 1024650, 0.4, 3, 'Vanilla Greens 46-50 Level Range'), +(1000146, 7, 1034447, 0.025, 4, 'Vanilla Blues 44-47 Level Range'), +(1000146, 8, 1034346, 0.025, 4, 'Vanilla Blues 43-46 Level Range'), +(1000146, 9, 1034649, 0.025, 4, 'Vanilla Blues 46-49 Level Range'), +(1000146, 10, 1034548, 0.025, 4, 'Vanilla Blues 45-48 Level Range'), +(1000146, 11, 1044248, 0.0125, 5, 'Vanilla Purples 42-48 Level Range'), +(1000146, 12, 1044046, 0.0125, 5, 'Vanilla Purples 40-46 Level Range'), +(1000146, 13, 1044450, 0.0125, 5, 'Vanilla Purples 44-50 Level Range'), +(1000146, 14, 1044652, 0.0125, 5, 'Vanilla Purples 46-52 Level Range'), +(1000146, 15, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000146, 16, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000146, 17, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000146, 18, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000146, 19, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000146, 20, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000146, 21, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000147, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000147, 2, 1024347, 0.4, 3, 'Vanilla Greens 43-47 Level Range'), +(1000147, 3, 1024448, 0.4, 3, 'Vanilla Greens 44-48 Level Range'), +(1000147, 4, 1024549, 0.4, 3, 'Vanilla Greens 45-49 Level Range'), +(1000147, 5, 1024751, 0.4, 3, 'Vanilla Greens 47-51 Level Range'), +(1000147, 6, 1024650, 0.4, 3, 'Vanilla Greens 46-50 Level Range'), +(1000147, 7, 1034447, 0.025, 4, 'Vanilla Blues 44-47 Level Range'), +(1000147, 8, 1034649, 0.025, 4, 'Vanilla Blues 46-49 Level Range'), +(1000147, 9, 1034548, 0.025, 4, 'Vanilla Blues 45-48 Level Range'), +(1000147, 10, 1034750, 0.025, 4, 'Vanilla Blues 47-50 Level Range'), +(1000147, 11, 1044248, 0.0167, 5, 'Vanilla Purples 42-48 Level Range'), +(1000147, 12, 1044450, 0.0167, 5, 'Vanilla Purples 44-50 Level Range'), +(1000147, 13, 1044652, 0.0167, 5, 'Vanilla Purples 46-52 Level Range'), +(1000147, 14, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000147, 15, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000147, 16, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000147, 17, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000147, 18, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000147, 19, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000147, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000148, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000148, 2, 1024448, 0.4, 3, 'Vanilla Greens 44-48 Level Range'), +(1000148, 3, 1024549, 0.4, 3, 'Vanilla Greens 45-49 Level Range'), +(1000148, 4, 1024751, 0.4, 3, 'Vanilla Greens 47-51 Level Range'), +(1000148, 5, 1024852, 0.4, 3, 'Vanilla Greens 48-52 Level Range'), +(1000148, 6, 1024650, 0.4, 3, 'Vanilla Greens 46-50 Level Range'), +(1000148, 7, 1034649, 0.025, 4, 'Vanilla Blues 46-49 Level Range'), +(1000148, 8, 1034548, 0.025, 4, 'Vanilla Blues 45-48 Level Range'), +(1000148, 9, 1034851, 0.025, 4, 'Vanilla Blues 48-51 Level Range'), +(1000148, 10, 1034750, 0.025, 4, 'Vanilla Blues 47-50 Level Range'), +(1000148, 11, 1044248, 0.0125, 5, 'Vanilla Purples 42-48 Level Range'), +(1000148, 12, 1044854, 0.0125, 5, 'Vanilla Purples 48-54 Level Range'), +(1000148, 13, 1044450, 0.0125, 5, 'Vanilla Purples 44-50 Level Range'), +(1000148, 14, 1044652, 0.0125, 5, 'Vanilla Purples 46-52 Level Range'), +(1000148, 15, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000148, 16, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000148, 17, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000148, 18, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000148, 19, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000148, 20, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000148, 21, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000149, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000149, 2, 1024549, 0.4, 3, 'Vanilla Greens 45-49 Level Range'), +(1000149, 3, 1024751, 0.4, 3, 'Vanilla Greens 47-51 Level Range'), +(1000149, 4, 1024852, 0.4, 3, 'Vanilla Greens 48-52 Level Range'), +(1000149, 5, 1024953, 0.4, 3, 'Vanilla Greens 49-53 Level Range'), +(1000149, 6, 1024650, 0.4, 3, 'Vanilla Greens 46-50 Level Range'), +(1000149, 7, 1034649, 0.025, 4, 'Vanilla Blues 46-49 Level Range'), +(1000149, 8, 1034952, 0.025, 4, 'Vanilla Blues 49-52 Level Range'), +(1000149, 9, 1034851, 0.025, 4, 'Vanilla Blues 48-51 Level Range'), +(1000149, 10, 1034750, 0.025, 4, 'Vanilla Blues 47-50 Level Range'), +(1000149, 11, 1044854, 0.0167, 5, 'Vanilla Purples 48-54 Level Range'), +(1000149, 12, 1044450, 0.0167, 5, 'Vanilla Purples 44-50 Level Range'), +(1000149, 13, 1044652, 0.0167, 5, 'Vanilla Purples 46-52 Level Range'), +(1000149, 14, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000149, 15, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000149, 16, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000149, 17, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000149, 18, 1083650, 0.1, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000149, 19, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000149, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000150, 1, 1004150, 6, 0, 'Vanilla Greys 41-50 Level Range'), +(1000150, 2, 1024751, 0.4, 3, 'Vanilla Greens 47-51 Level Range'), +(1000150, 3, 1025054, 0.4, 3, 'Vanilla Greens 50-54 Level Range'), +(1000150, 4, 1024852, 0.4, 3, 'Vanilla Greens 48-52 Level Range'), +(1000150, 5, 1024953, 0.4, 3, 'Vanilla Greens 49-53 Level Range'), +(1000150, 6, 1024650, 0.4, 3, 'Vanilla Greens 46-50 Level Range'), +(1000150, 7, 1034952, 0.025, 4, 'Vanilla Blues 49-52 Level Range'), +(1000150, 8, 1034851, 0.025, 4, 'Vanilla Blues 48-51 Level Range'), +(1000150, 9, 1035053, 0.025, 4, 'Vanilla Blues 50-53 Level Range'), +(1000150, 10, 1034750, 0.025, 4, 'Vanilla Blues 47-50 Level Range'), +(1000150, 11, 1044854, 0.0125, 5, 'Vanilla Purples 48-54 Level Range'), +(1000150, 12, 1044450, 0.0125, 5, 'Vanilla Purples 44-50 Level Range'), +(1000150, 13, 1044652, 0.0125, 5, 'Vanilla Purples 46-52 Level Range'), +(1000150, 14, 1045056, 0.0125, 5, 'Vanilla Purples 50-56 Level Range'), +(1000150, 15, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000150, 16, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000150, 18, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000150, 19, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000150, 20, 1084660, 0.075, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000150, 21, 1083650, 0.075, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000150, 22, 1084055, 0.075, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000150, 23, 1085063, 0.075, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000150, 24, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000151, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000151, 2, 1025155, 0.4, 3, 'Vanilla Greens 51-55 Level Range'), +(1000151, 3, 1024751, 0.4, 3, 'Vanilla Greens 47-51 Level Range'), +(1000151, 4, 1025054, 0.4, 3, 'Vanilla Greens 50-54 Level Range'), +(1000151, 5, 1024852, 0.4, 3, 'Vanilla Greens 48-52 Level Range'), +(1000151, 6, 1024953, 0.4, 3, 'Vanilla Greens 49-53 Level Range'), +(1000151, 7, 1034952, 0.025, 4, 'Vanilla Blues 49-52 Level Range'), +(1000151, 8, 1034851, 0.025, 4, 'Vanilla Blues 48-51 Level Range'), +(1000151, 9, 1035154, 0.025, 4, 'Vanilla Blues 51-54 Level Range'), +(1000151, 10, 1035053, 0.025, 4, 'Vanilla Blues 50-53 Level Range'), +(1000151, 11, 1044854, 0.0167, 5, 'Vanilla Purples 48-54 Level Range'), +(1000151, 12, 1044652, 0.0167, 5, 'Vanilla Purples 46-52 Level Range'), +(1000151, 13, 1045056, 0.0167, 5, 'Vanilla Purples 50-56 Level Range'), +(1000151, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000151, 15, 1065155, 3, 0, 'Vanilla Potions 51-55 Level Range'), +(1000151, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000151, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000151, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000151, 20, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000151, 22, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000151, 23, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000152, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000152, 2, 1025155, 0.4, 3, 'Vanilla Greens 51-55 Level Range'), +(1000152, 3, 1025256, 0.4, 3, 'Vanilla Greens 52-56 Level Range'), +(1000152, 4, 1025054, 0.4, 3, 'Vanilla Greens 50-54 Level Range'), +(1000152, 5, 1024852, 0.4, 3, 'Vanilla Greens 48-52 Level Range'), +(1000152, 6, 1024953, 0.4, 3, 'Vanilla Greens 49-53 Level Range'), +(1000152, 7, 1035255, 0.025, 4, 'Vanilla Blues 52-55 Level Range'), +(1000152, 8, 1034952, 0.025, 4, 'Vanilla Blues 49-52 Level Range'), +(1000152, 9, 1035154, 0.025, 4, 'Vanilla Blues 51-54 Level Range'), +(1000152, 10, 1035053, 0.025, 4, 'Vanilla Blues 50-53 Level Range'), +(1000152, 11, 1044854, 0.0125, 5, 'Vanilla Purples 48-54 Level Range'), +(1000152, 12, 1044652, 0.0125, 5, 'Vanilla Purples 46-52 Level Range'), +(1000152, 13, 1045258, 0.0125, 5, 'Vanilla Purples 52-58 Level Range'), +(1000152, 14, 1045056, 0.0125, 5, 'Vanilla Purples 50-56 Level Range'), +(1000152, 15, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000152, 16, 1065155, 3, 0, 'Vanilla Potions 51-55 Level Range'), +(1000152, 17, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000152, 19, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000152, 20, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000152, 21, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000152, 22, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000152, 23, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000153, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000153, 2, 1025155, 0.4, 3, 'Vanilla Greens 51-55 Level Range'), +(1000153, 3, 1025357, 0.4, 3, 'Vanilla Greens 53-57 Level Range'), +(1000153, 4, 1025256, 0.4, 3, 'Vanilla Greens 52-56 Level Range'), +(1000153, 5, 1025054, 0.4, 3, 'Vanilla Greens 50-54 Level Range'), +(1000153, 6, 1024953, 0.4, 3, 'Vanilla Greens 49-53 Level Range'), +(1000153, 7, 1035255, 0.025, 4, 'Vanilla Blues 52-55 Level Range'), +(1000153, 8, 1035154, 0.025, 4, 'Vanilla Blues 51-54 Level Range'), +(1000153, 9, 1035356, 0.025, 4, 'Vanilla Blues 53-56 Level Range'), +(1000153, 10, 1035053, 0.025, 4, 'Vanilla Blues 50-53 Level Range'), +(1000153, 11, 1044854, 0.0167, 5, 'Vanilla Purples 48-54 Level Range'), +(1000153, 12, 1045258, 0.0167, 5, 'Vanilla Purples 52-58 Level Range'), +(1000153, 13, 1045056, 0.0167, 5, 'Vanilla Purples 50-56 Level Range'), +(1000153, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000153, 15, 1065155, 3, 0, 'Vanilla Potions 51-55 Level Range'), +(1000153, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000153, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000153, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000153, 20, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000153, 21, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000153, 22, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000154, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000154, 2, 1025458, 0.4, 3, 'Vanilla Greens 54-58 Level Range'), +(1000154, 3, 1025155, 0.4, 3, 'Vanilla Greens 51-55 Level Range'), +(1000154, 4, 1025357, 0.4, 3, 'Vanilla Greens 53-57 Level Range'), +(1000154, 5, 1025256, 0.4, 3, 'Vanilla Greens 52-56 Level Range'), +(1000154, 6, 1025054, 0.4, 3, 'Vanilla Greens 50-54 Level Range'), +(1000154, 7, 1035255, 0.025, 4, 'Vanilla Blues 52-55 Level Range'), +(1000154, 8, 1035457, 0.025, 4, 'Vanilla Blues 54-57 Level Range'), +(1000154, 9, 1035154, 0.025, 4, 'Vanilla Blues 51-54 Level Range'), +(1000154, 10, 1035356, 0.025, 4, 'Vanilla Blues 53-56 Level Range'), +(1000154, 11, 1044854, 0.0125, 5, 'Vanilla Purples 48-54 Level Range'), +(1000154, 12, 1045258, 0.0125, 5, 'Vanilla Purples 52-58 Level Range'), +(1000154, 13, 1045056, 0.0125, 5, 'Vanilla Purples 50-56 Level Range'), +(1000154, 14, 1045460, 0.0125, 5, 'Vanilla Purples 54-60 Level Range'), +(1000154, 15, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000154, 16, 1065155, 3, 0, 'Vanilla Potions 51-55 Level Range'), +(1000154, 17, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000154, 19, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000154, 20, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000154, 21, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000154, 22, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000154, 23, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000155, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000155, 2, 1025458, 0.4, 3, 'Vanilla Greens 54-58 Level Range'), +(1000155, 3, 1025559, 0.4, 3, 'Vanilla Greens 55-59 Level Range'), +(1000155, 4, 1025155, 0.4, 3, 'Vanilla Greens 51-55 Level Range'), +(1000155, 5, 1025357, 0.4, 3, 'Vanilla Greens 53-57 Level Range'), +(1000155, 6, 1025256, 0.4, 3, 'Vanilla Greens 52-56 Level Range'), +(1000155, 7, 1035255, 0.025, 4, 'Vanilla Blues 52-55 Level Range'), +(1000155, 8, 1035558, 0.025, 4, 'Vanilla Blues 55-58 Level Range'), +(1000155, 9, 1035457, 0.025, 4, 'Vanilla Blues 54-57 Level Range'), +(1000155, 10, 1035356, 0.025, 4, 'Vanilla Blues 53-56 Level Range'), +(1000155, 11, 1045258, 0.0167, 5, 'Vanilla Purples 52-58 Level Range'), +(1000155, 12, 1045056, 0.0167, 5, 'Vanilla Purples 50-56 Level Range'), +(1000155, 13, 1045460, 0.0167, 5, 'Vanilla Purples 54-60 Level Range'), +(1000155, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000155, 15, 1065155, 3, 0, 'Vanilla Potions 51-55 Level Range'), +(1000155, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000155, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000155, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000155, 20, 1084055, 0.1, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000155, 21, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000155, 22, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000156, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000156, 2, 1025660, 0.4, 3, 'Vanilla Greens 56-60 Level Range'), +(1000156, 3, 1025458, 0.4, 3, 'Vanilla Greens 54-58 Level Range'), +(1000156, 4, 1025559, 0.4, 3, 'Vanilla Greens 55-59 Level Range'), +(1000156, 5, 1025357, 0.4, 3, 'Vanilla Greens 53-57 Level Range'), +(1000156, 6, 1025256, 0.4, 3, 'Vanilla Greens 52-56 Level Range'), +(1000156, 7, 1035558, 0.025, 4, 'Vanilla Blues 55-58 Level Range'), +(1000156, 8, 1035457, 0.025, 4, 'Vanilla Blues 54-57 Level Range'), +(1000156, 9, 1035356, 0.025, 4, 'Vanilla Blues 53-56 Level Range'), +(1000156, 10, 1035659, 0.025, 4, 'Vanilla Blues 56-59 Level Range'), +(1000156, 11, 1045662, 0.0125, 5, 'Vanilla Purples 56-62 Level Range'), +(1000156, 12, 1045258, 0.0125, 5, 'Vanilla Purples 52-58 Level Range'), +(1000156, 13, 1045056, 0.0125, 5, 'Vanilla Purples 50-56 Level Range'), +(1000156, 14, 1045460, 0.0125, 5, 'Vanilla Purples 54-60 Level Range'), +(1000156, 15, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000156, 16, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000156, 17, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000156, 19, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000156, 20, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000156, 21, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000156, 22, 1085663, 0.1, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000156, 23, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000157, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000157, 2, 1025660, 0.4, 3, 'Vanilla Greens 56-60 Level Range'), +(1000157, 3, 1025458, 0.4, 3, 'Vanilla Greens 54-58 Level Range'), +(1000157, 4, 1025559, 0.4, 3, 'Vanilla Greens 55-59 Level Range'), +(1000157, 5, 1025357, 0.4, 3, 'Vanilla Greens 53-57 Level Range'), +(1000157, 6, 1025761, 0.4, 3, 'Vanilla Greens 57-61 Level Range'), +(1000157, 7, 1035558, 0.025, 4, 'Vanilla Blues 55-58 Level Range'), +(1000157, 8, 1035457, 0.025, 4, 'Vanilla Blues 54-57 Level Range'), +(1000157, 9, 1035760, 0.025, 4, 'Vanilla Blues 57-60 Level Range'), +(1000157, 10, 1035659, 0.025, 4, 'Vanilla Blues 56-59 Level Range'), +(1000157, 11, 1045662, 0.0167, 5, 'Vanilla Purples 56-62 Level Range'), +(1000157, 12, 1045258, 0.0167, 5, 'Vanilla Purples 52-58 Level Range'), +(1000157, 13, 1045460, 0.0167, 5, 'Vanilla Purples 54-60 Level Range'), +(1000157, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000157, 15, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000157, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000157, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000157, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000157, 20, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000157, 21, 1085663, 0.1, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000157, 22, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000158, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000158, 2, 1025660, 0.4, 3, 'Vanilla Greens 56-60 Level Range'), +(1000158, 3, 1025862, 0.4, 3, 'Vanilla Greens 58-62 Level Range'), +(1000158, 4, 1025458, 0.4, 3, 'Vanilla Greens 54-58 Level Range'), +(1000158, 5, 1025559, 0.4, 3, 'Vanilla Greens 55-59 Level Range'), +(1000158, 6, 1025761, 0.4, 3, 'Vanilla Greens 57-61 Level Range'), +(1000158, 7, 1035861, 0.025, 4, 'Vanilla Blues 58-61 Level Range'), +(1000158, 8, 1035558, 0.025, 4, 'Vanilla Blues 55-58 Level Range'), +(1000158, 9, 1035760, 0.025, 4, 'Vanilla Blues 57-60 Level Range'), +(1000158, 10, 1035659, 0.025, 4, 'Vanilla Blues 56-59 Level Range'), +(1000158, 11, 1045662, 0.0125, 5, 'Vanilla Purples 56-62 Level Range'), +(1000158, 12, 1045258, 0.0125, 5, 'Vanilla Purples 52-58 Level Range'), +(1000158, 13, 1045460, 0.0125, 5, 'Vanilla Purples 54-60 Level Range'), +(1000158, 14, 1045863, 0.0125, 5, 'Vanilla Purples 58-63 Level Range'), +(1000158, 15, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000158, 16, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000158, 17, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000158, 19, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000158, 20, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000158, 21, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000158, 22, 1085663, 0.1, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000158, 23, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000159, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000159, 2, 1025660, 0.4, 3, 'Vanilla Greens 56-60 Level Range'), +(1000159, 3, 1025862, 0.4, 3, 'Vanilla Greens 58-62 Level Range'), +(1000159, 4, 1025559, 0.4, 3, 'Vanilla Greens 55-59 Level Range'), +(1000159, 5, 1025963, 0.4, 3, 'Vanilla Greens 59-63 Level Range'), +(1000159, 6, 1025761, 0.4, 3, 'Vanilla Greens 57-61 Level Range'), +(1000159, 7, 1035861, 0.025, 4, 'Vanilla Blues 58-61 Level Range'), +(1000159, 8, 1035963, 0.025, 4, 'Vanilla Blues 59-63 Level Range'), +(1000159, 9, 1035760, 0.025, 4, 'Vanilla Blues 57-60 Level Range'), +(1000159, 10, 1035659, 0.025, 4, 'Vanilla Blues 56-59 Level Range'), +(1000159, 11, 1045662, 0.0167, 5, 'Vanilla Purples 56-62 Level Range'), +(1000159, 12, 1045460, 0.0167, 5, 'Vanilla Purples 54-60 Level Range'), +(1000159, 13, 1045863, 0.0167, 5, 'Vanilla Purples 58-63 Level Range'), +(1000159, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000159, 15, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000159, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000159, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000159, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000159, 20, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000159, 21, 1085663, 0.1, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000159, 22, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000160, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000160, 2, 1025660, 0.4, 3, 'Vanilla Greens 56-60 Level Range'), +(1000160, 3, 1025862, 0.4, 3, 'Vanilla Greens 58-62 Level Range'), +(1000160, 4, 1026063, 0.4, 3, 'Vanilla Greens 60-63 Level Range'), +(1000160, 5, 1025963, 0.4, 3, 'Vanilla Greens 59-63 Level Range'), +(1000160, 6, 1025761, 0.4, 3, 'Vanilla Greens 57-61 Level Range'), +(1000160, 7, 1035861, 0.0333, 4, 'Vanilla Blues 58-61 Level Range'), +(1000160, 8, 1035963, 0.0333, 4, 'Vanilla Blues 59-63 Level Range'), +(1000160, 9, 1035760, 0.0333, 4, 'Vanilla Blues 57-60 Level Range'), +(1000160, 10, 1045662, 0.0125, 5, 'Vanilla Purples 56-62 Level Range'), +(1000160, 11, 1046063, 0.0125, 5, 'Vanilla Purples 60-63 Level Range'), +(1000160, 12, 1045460, 0.0125, 5, 'Vanilla Purples 54-60 Level Range'), +(1000160, 13, 1045863, 0.0125, 5, 'Vanilla Purples 58-63 Level Range'), +(1000160, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000160, 15, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000160, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000160, 18, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000160, 19, 1084660, 0.1, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000160, 20, 1085063, 0.1, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000160, 21, 1085663, 0.1, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000160, 22, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000161, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000161, 2, 1025862, 0.4, 3, 'Vanilla Greens 58-62 Level Range'), +(1000161, 3, 1026163, 0.4, 3, 'Vanilla Greens 61-63 Level Range'), +(1000161, 4, 1026063, 0.4, 3, 'Vanilla Greens 60-63 Level Range'), +(1000161, 5, 1025963, 0.4, 3, 'Vanilla Greens 59-63 Level Range'), +(1000161, 6, 1025761, 0.4, 3, 'Vanilla Greens 57-61 Level Range'), +(1000161, 7, 1035861, 0.05, 4, 'Vanilla Blues 58-61 Level Range'), +(1000161, 8, 1035963, 0.05, 4, 'Vanilla Blues 59-63 Level Range'), +(1000161, 9, 1045662, 0.0167, 5, 'Vanilla Purples 56-62 Level Range'), +(1000161, 10, 1046063, 0.0167, 5, 'Vanilla Purples 60-63 Level Range'), +(1000161, 11, 1045863, 0.0167, 5, 'Vanilla Purples 58-63 Level Range'), +(1000161, 12, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000161, 13, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000161, 14, 1076163, 100, 0, 'Vanilla Miscellaneous 61-63 Level Range'), +(1000161, 16, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000161, 18, 1085063, 0.15, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000161, 19, 1085663, 0.15, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000161, 20, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1000162, 1, 1005163, 6, 0, 'Vanilla Greys 51-63 Level Range'), +(1000162, 2, 1025862, 0.4, 3, 'Vanilla Greens 58-62 Level Range'), +(1000162, 3, 1026263, 0.4, 3, 'Vanilla Greens 62-63 Level Range'), +(1000162, 4, 1026163, 0.4, 3, 'Vanilla Greens 61-63 Level Range'), +(1000162, 5, 1026063, 0.4, 3, 'Vanilla Greens 60-63 Level Range'), +(1000162, 6, 1025963, 0.4, 3, 'Vanilla Greens 59-63 Level Range'), +(1000162, 7, 1035963, 0.1, 4, 'Vanilla Blues 59-63 Level Range'), +(1000162, 8, 1045662, 0.0167, 5, 'Vanilla Purples 56-62 Level Range'), +(1000162, 9, 1046063, 0.0167, 5, 'Vanilla Purples 60-63 Level Range'), +(1000162, 10, 1045863, 0.0167, 5, 'Vanilla Purples 58-63 Level Range'), +(1000162, 11, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000162, 12, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000162, 13, 1076163, 100, 0, 'Vanilla Miscellaneous 61-63 Level Range'), +(1000162, 14, 1075061, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000162, 16, 1085063, 0.15, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000162, 17, 1085663, 0.15, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000162, 18, 1095162, 0.1, 0, 'Vanilla Bags 51-62 Level Range'), +(1100158, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100158, 2, 1125860, 2, 3, 'TBC Greens 58-60 Level Range'), +(1100158, 3, 1135861, 0.1, 4, 'TBC Blues 58-61 Level Range'), +(1100158, 4, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100158, 5, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100159, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100159, 2, 1125961, 1, 3, 'TBC Greens 59-61 Level Range'), +(1100159, 3, 1125860, 1, 3, 'TBC Greens 58-60 Level Range'), +(1100159, 4, 1135861, 0.05, 4, 'TBC Blues 58-61 Level Range'), +(1100159, 5, 1135962, 0.05, 4, 'TBC Blues 59-62 Level Range'), +(1100159, 6, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100159, 7, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100160, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100160, 2, 1126062, 0.67, 3, 'TBC Greens 60-62 Level Range'), +(1100160, 3, 1125961, 0.67, 3, 'TBC Greens 59-61 Level Range'), +(1100160, 4, 1125860, 0.67, 3, 'TBC Greens 58-60 Level Range'), +(1100160, 5, 1135861, 0.0333, 4, 'TBC Blues 58-61 Level Range'), +(1100160, 6, 1135962, 0.0333, 4, 'TBC Blues 59-62 Level Range'), +(1100160, 7, 1136063, 0.0333, 4, 'TBC Blues 60-63 Level Range'), +(1100160, 8, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100160, 9, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100161, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100161, 2, 1126062, 0.67, 3, 'TBC Greens 60-62 Level Range'), +(1100161, 3, 1125961, 0.67, 3, 'TBC Greens 59-61 Level Range'), +(1100161, 4, 1126163, 0.67, 3, 'TBC Greens 61-63 Level Range'), +(1100161, 5, 1136164, 0.025, 4, 'TBC Blues 61-64 Level Range'), +(1100161, 6, 1135861, 0.025, 4, 'TBC Blues 58-61 Level Range'), +(1100161, 7, 1135962, 0.025, 4, 'TBC Blues 59-62 Level Range'), +(1100161, 8, 1136063, 0.025, 4, 'TBC Blues 60-63 Level Range'), +(1100161, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100161, 10, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100161, 11, 1186165, 25, 0, 'TBC Patterns 61-65 Level Range'), +(1100162, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100162, 2, 1126062, 0.67, 3, 'TBC Greens 60-62 Level Range'), +(1100162, 3, 1126163, 0.67, 3, 'TBC Greens 61-63 Level Range'), +(1100162, 4, 1126264, 0.67, 3, 'TBC Greens 62-64 Level Range'), +(1100162, 5, 1136265, 0.025, 4, 'TBC Blues 62-65 Level Range'), +(1100162, 6, 1136164, 0.025, 4, 'TBC Blues 61-64 Level Range'), +(1100162, 7, 1135962, 0.025, 4, 'TBC Blues 59-62 Level Range'), +(1100162, 8, 1136063, 0.025, 4, 'TBC Blues 60-63 Level Range'), +(1100162, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100162, 10, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100162, 11, 1186165, 25, 0, 'TBC Patterns 61-65 Level Range'), +(1100163, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100163, 2, 1126365, 0.67, 3, 'TBC Greens 63-65 Level Range'), +(1100163, 3, 1126163, 0.67, 3, 'TBC Greens 61-63 Level Range'), +(1100163, 4, 1126264, 0.67, 3, 'TBC Greens 62-64 Level Range'), +(1100163, 5, 1136265, 0.025, 4, 'TBC Blues 62-65 Level Range'), +(1100163, 6, 1136164, 0.025, 4, 'TBC Blues 61-64 Level Range'), +(1100163, 7, 1136366, 0.025, 4, 'TBC Blues 63-66 Level Range'), +(1100163, 8, 1136063, 0.025, 4, 'TBC Blues 60-63 Level Range'), +(1100163, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100163, 10, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100163, 11, 1186165, 25, 0, 'TBC Patterns 61-65 Level Range'), +(1100164, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100164, 2, 1126466, 0.67, 3, 'TBC Greens 64-66 Level Range'), +(1100164, 3, 1126365, 0.67, 3, 'TBC Greens 63-65 Level Range'), +(1100164, 4, 1126264, 0.67, 3, 'TBC Greens 62-64 Level Range'), +(1100164, 5, 1136265, 0.025, 4, 'TBC Blues 62-65 Level Range'), +(1100164, 6, 1136164, 0.025, 4, 'TBC Blues 61-64 Level Range'), +(1100164, 7, 1136467, 0.025, 4, 'TBC Blues 64-67 Level Range'), +(1100164, 8, 1136366, 0.025, 4, 'TBC Blues 63-66 Level Range'), +(1100164, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100164, 10, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100164, 11, 1186165, 25, 0, 'TBC Patterns 61-65 Level Range'), +(1100165, 1, 1105865, 6, 1, 'TBC Greys 58-65 Level Range'), +(1100165, 2, 1126567, 0.67, 3, 'TBC Greens 65-67 Level Range'), +(1100165, 3, 1126466, 0.67, 3, 'TBC Greens 64-66 Level Range'), +(1100165, 4, 1126365, 0.67, 3, 'TBC Greens 63-65 Level Range'), +(1100165, 5, 1136265, 0.025, 4, 'TBC Blues 62-65 Level Range'), +(1100165, 6, 1136467, 0.025, 4, 'TBC Blues 64-67 Level Range'), +(1100165, 7, 1136568, 0.025, 4, 'TBC Blues 65-68 Level Range'), +(1100165, 8, 1136366, 0.025, 4, 'TBC Blues 63-66 Level Range'), +(1100165, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100165, 10, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100165, 12, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100165, 13, 1186165, 25, 0, 'TBC Patterns 61-65 Level Range'), +(1100166, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100166, 2, 1126567, 0.67, 3, 'TBC Greens 65-67 Level Range'), +(1100166, 3, 1126668, 0.67, 3, 'TBC Greens 66-68 Level Range'), +(1100166, 4, 1126466, 0.67, 3, 'TBC Greens 64-66 Level Range'), +(1100166, 5, 1136467, 0.025, 4, 'TBC Blues 64-67 Level Range'), +(1100166, 6, 1136568, 0.025, 4, 'TBC Blues 65-68 Level Range'), +(1100166, 7, 1136669, 0.025, 4, 'TBC Blues 66-69 Level Range'), +(1100166, 8, 1136366, 0.025, 4, 'TBC Blues 63-66 Level Range'), +(1100166, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100166, 10, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100166, 12, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100166, 13, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100167, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100167, 2, 1126567, 0.67, 3, 'TBC Greens 65-67 Level Range'), +(1100167, 3, 1126668, 0.67, 3, 'TBC Greens 66-68 Level Range'), +(1100167, 4, 1126769, 0.67, 3, 'TBC Greens 67-69 Level Range'), +(1100167, 5, 1136467, 0.025, 4, 'TBC Blues 64-67 Level Range'), +(1100167, 6, 1136568, 0.025, 4, 'TBC Blues 65-68 Level Range'), +(1100167, 7, 1136669, 0.025, 4, 'TBC Blues 66-69 Level Range'), +(1100167, 8, 1136770, 0.025, 4, 'TBC Blues 67-70 Level Range'), +(1100167, 9, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100167, 10, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100167, 11, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100167, 13, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100167, 14, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100168, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100168, 2, 1126668, 0.67, 3, 'TBC Greens 66-68 Level Range'), +(1100168, 3, 1126769, 0.67, 3, 'TBC Greens 67-69 Level Range'), +(1100168, 4, 1126870, 0.67, 3, 'TBC Greens 68-70 Level Range'), +(1100168, 5, 1136568, 0.025, 4, 'TBC Blues 65-68 Level Range'), +(1100168, 6, 1136669, 0.025, 4, 'TBC Blues 66-69 Level Range'), +(1100168, 7, 1136873, 0.025, 4, 'TBC Blues 68-73 Level Range'), +(1100168, 8, 1136770, 0.025, 4, 'TBC Blues 67-70 Level Range'), +(1100168, 9, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100168, 10, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100168, 11, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100168, 13, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100168, 14, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100169, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100169, 2, 1126971, 0.67, 3, 'TBC Greens 69-71 Level Range'), +(1100169, 3, 1126769, 0.67, 3, 'TBC Greens 67-69 Level Range'), +(1100169, 4, 1126870, 0.67, 3, 'TBC Greens 68-70 Level Range'), +(1100169, 5, 1136669, 0.0333, 4, 'TBC Blues 66-69 Level Range'), +(1100169, 6, 1136873, 0.0333, 4, 'TBC Blues 68-73 Level Range'), +(1100169, 7, 1136770, 0.0333, 4, 'TBC Blues 67-70 Level Range'), +(1100169, 8, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100169, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100169, 10, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100169, 12, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100169, 13, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100170, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100170, 2, 1126971, 0.67, 3, 'TBC Greens 69-71 Level Range'), +(1100170, 3, 1127072, 0.67, 3, 'TBC Greens 70-72 Level Range'), +(1100170, 4, 1126870, 0.67, 3, 'TBC Greens 68-70 Level Range'), +(1100170, 5, 1136873, 0.05, 4, 'TBC Blues 68-73 Level Range'), +(1100170, 6, 1136770, 0.05, 4, 'TBC Blues 67-70 Level Range'), +(1100170, 7, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100170, 8, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100170, 9, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100170, 11, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100170, 12, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100171, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100171, 2, 1126971, 0.67, 3, 'TBC Greens 69-71 Level Range'), +(1100171, 3, 1127072, 0.67, 3, 'TBC Greens 70-72 Level Range'), +(1100171, 4, 1127173, 0.67, 3, 'TBC Greens 71-73 Level Range'), +(1100171, 5, 1136873, 0.1, 4, 'TBC Blues 68-73 Level Range'), +(1100171, 6, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100171, 7, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100171, 8, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100171, 10, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100171, 11, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +(1100172, 1, 1106672, 6, 1, 'TBC Greys 66-72 Level Range'), +(1100172, 2, 1127072, 1, 3, 'TBC Greens 70-72 Level Range'), +(1100172, 3, 1127173, 1, 3, 'TBC Greens 71-73 Level Range'), +(1100172, 4, 1136873, 0.1, 4, 'TBC Blues 68-73 Level Range'), +(1100172, 5, 1146773, 0.05, 5, 'TBC Purples 67-73 Level Range'), +(1100172, 6, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100172, 7, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100172, 9, 1176571, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100172, 10, 1186673, 25, 0, 'TBC Patterns 66-73 Level Range'), +-- Elite: Greys: 10%, Greens: 4%, Patterns: 1%, Bags: 0.2% +(1000213, 1, 1001115, 10, 0, 'Vanilla Greys 11-15 Level Range'), +(1000213, 2, 1011314, 5, 2, 'Vanilla Whites 13-14 Level Range'), +(1000213, 3, 1011213, 5, 2, 'Vanilla Whites 12-13 Level Range'), +(1000213, 4, 1021317, 0.5, 3, 'Vanilla Greens 13-17 Level Range'), +(1000213, 5, 1021115, 0.5, 3, 'Vanilla Greens 11-15 Level Range'), +(1000213, 6, 1021014, 0.5, 3, 'Vanilla Greens 10-14 Level Range'), +(1000213, 7, 1021216, 0.5, 3, 'Vanilla Greens 12-16 Level Range'), +(1000213, 10, 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000213, 11, 1080620, 0.5, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000213, 12, 1081225, 0.5, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000213, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000214, 1, 1001115, 10, 0, 'Vanilla Greys 11-15 Level Range'), +(1000214, 2, 1011314, 5, 2, 'Vanilla Whites 13-14 Level Range'), +(1000214, 3, 1011415, 5, 2, 'Vanilla Whites 14-15 Level Range'), +(1000214, 4, 1021317, 0.8, 3, 'Vanilla Greens 13-17 Level Range'), +(1000214, 5, 1021115, 0.8, 3, 'Vanilla Greens 11-15 Level Range'), +(1000214, 6, 1021014, 0.8, 3, 'Vanilla Greens 10-14 Level Range'), +(1000214, 7, 1021216, 0.8, 3, 'Vanilla Greens 12-16 Level Range'), +(1000214, 8, 1021418, 0.8, 3, 'Vanilla Greens 14-18 Level Range'), +(1000214, 11, 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000214, 12, 1080620, 0.5, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000214, 13, 1081225, 0.5, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000214, 14, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +-- (1000215, 1, 1001115, 10, 0, 'Vanilla Greys 11-15 Level Range'), +-- (1000215, 2, 1011415, 10, 2, 'Vanilla Whites 14-15 Level Range'), +-- (1000215, 3, 1021317, 0.8, 3, 'Vanilla Greens 13-17 Level Range'), +-- (1000215, 4, 1021115, 0.8, 3, 'Vanilla Greens 11-15 Level Range'), +-- (1000215, 5, 1021216, 0.8, 3, 'Vanilla Greens 12-16 Level Range'), +-- (1000215, 6, 1021418, 0.8, 3, 'Vanilla Greens 14-18 Level Range'), +-- (1000215, 7, 1021519, 0.8, 3, 'Vanilla Greens 15-19 Level Range'), +-- (1000215, 10, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +-- (1000215, 11, 1080620, 0.5, 6, 'Vanilla Patterns 6-20 Level Range'), +-- (1000215, 12, 1081225, 0.5, 6, 'Vanilla Patterns 12-25 Level Range'), +-- (1000215, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +-- (1000216, 1, 1001620, 10, 0, 'Vanilla Greys 16-20 Level Range'), +-- (1000216, 2, 1021317, 0.8, 3, 'Vanilla Greens 13-17 Level Range'), +-- (1000216, 3, 1021216, 0.8, 3, 'Vanilla Greens 12-16 Level Range'), +-- (1000216, 4, 1021418, 0.8, 3, 'Vanilla Greens 14-18 Level Range'), +-- (1000216, 5, 1021519, 0.8, 3, 'Vanilla Greens 15-19 Level Range'), +-- (1000216, 6, 1021620, 0.8, 3, 'Vanilla Greens 16-20 Level Range'), +-- (1000216, 9, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +-- (1000216, 10, 1080620, 0.33, 6, 'Vanilla Patterns 6-20 Level Range'), +-- (1000216, 11, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +-- (1000216, 12, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +-- (1000216, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000217, 1, 1001620, 10, 0, 'Vanilla Greys 16-20 Level Range'), +(1000217, 2, 1021317, 0.8, 3, 'Vanilla Greens 13-17 Level Range'), +(1000217, 3, 1021418, 0.8, 3, 'Vanilla Greens 14-18 Level Range'), +(1000217, 4, 1021519, 0.8, 3, 'Vanilla Greens 15-19 Level Range'), +(1000217, 5, 1021620, 0.8, 3, 'Vanilla Greens 16-20 Level Range'), +(1000217, 6, 1021721, 0.8, 3, 'Vanilla Greens 17-21 Level Range'), +(1000217, 9, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000217, 10, 1080620, 0.33, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000217, 11, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000217, 12, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000217, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000218, 1, 1001620, 10, 0, 'Vanilla Greys 16-20 Level Range'), +(1000218, 2, 1011822, 2, 2, 'Vanilla Whites 18-22 Level Range'), +(1000218, 3, 1021418, 0.8, 3, 'Vanilla Greens 14-18 Level Range'), +(1000218, 4, 1021519, 0.8, 3, 'Vanilla Greens 15-19 Level Range'), +(1000218, 5, 1021620, 0.8, 3, 'Vanilla Greens 16-20 Level Range'), +(1000218, 6, 1021721, 0.8, 3, 'Vanilla Greens 17-21 Level Range'), +(1000218, 7, 1021822, 0.8, 3, 'Vanilla Greens 18-22 Level Range'), +(1000218, 10, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000218, 11, 1080620, 0.33, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000218, 12, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000218, 13, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000218, 14, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000219, 1, 1001620, 10, 0, 'Vanilla Greys 16-20 Level Range'), +(1000219, 2, 1011822, 1, 2, 'Vanilla Whites 18-22 Level Range'), +(1000219, 3, 1011923, 1, 2, 'Vanilla Whites 19-23 Level Range'), +(1000219, 4, 1021519, 0.8, 3, 'Vanilla Greens 15-19 Level Range'), +(1000219, 5, 1021620, 0.8, 3, 'Vanilla Greens 16-20 Level Range'), +(1000219, 6, 1021721, 0.8, 3, 'Vanilla Greens 17-21 Level Range'), +(1000219, 7, 1021822, 0.8, 3, 'Vanilla Greens 18-22 Level Range'), +(1000219, 8, 1021923, 0.8, 3, 'Vanilla Greens 19-23 Level Range'), +(1000219, 9, 1031922, 0.2, 4, 'Vanilla Blues 19-22 Level Range'), +(1000219, 12, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000219, 13, 1080620, 0.33, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000219, 14, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000219, 15, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000219, 16, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000220, 1, 1001620, 10, 0, 'Vanilla Greys 16-20 Level Range'), +(1000220, 2, 1012024, 0.667, 2, 'Vanilla Whites 20-24 Level Range'), +(1000220, 3, 1011822, 0.667, 2, 'Vanilla Whites 18-22 Level Range'), +(1000220, 4, 1011923, 0.667, 2, 'Vanilla Whites 19-23 Level Range'), +(1000220, 5, 1022024, 0.8, 3, 'Vanilla Greens 20-24 Level Range'), +(1000220, 6, 1021620, 0.8, 3, 'Vanilla Greens 16-20 Level Range'), +(1000220, 7, 1021721, 0.8, 3, 'Vanilla Greens 17-21 Level Range'), +(1000220, 8, 1021822, 0.8, 3, 'Vanilla Greens 18-22 Level Range'), +(1000220, 9, 1021923, 0.8, 3, 'Vanilla Greens 19-23 Level Range'), +(1000220, 10, 1032023, 0.1, 4, 'Vanilla Blues 20-23 Level Range'), +(1000220, 11, 1031922, 0.1, 4, 'Vanilla Blues 19-22 Level Range'), +(1000220, 14, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000220, 15, 1080620, 0.25, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000220, 16, 1081225, 0.25, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000220, 17, 1082035, 0.25, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000220, 18, 1081630, 0.25, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000220, 19, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000221, 1, 1002125, 10, 0, 'Vanilla Greys 21-25 Level Range'), +(1000221, 2, 1012024, 0.5, 2, 'Vanilla Whites 20-24 Level Range'), +(1000221, 3, 1012125, 0.5, 2, 'Vanilla Whites 21-25 Level Range'), +(1000221, 4, 1011822, 0.5, 2, 'Vanilla Whites 18-22 Level Range'), +(1000221, 5, 1011923, 0.5, 2, 'Vanilla Whites 19-23 Level Range'), +(1000221, 6, 1022125, 0.8, 3, 'Vanilla Greens 21-25 Level Range'), +(1000221, 7, 1022024, 0.8, 3, 'Vanilla Greens 20-24 Level Range'), +(1000221, 8, 1021721, 0.8, 3, 'Vanilla Greens 17-21 Level Range'), +(1000221, 9, 1021822, 0.8, 3, 'Vanilla Greens 18-22 Level Range'), +(1000221, 10, 1021923, 0.8, 3, 'Vanilla Greens 19-23 Level Range'), +(1000221, 11, 1032124, 0.0667, 4, 'Vanilla Blues 21-24 Level Range'), +(1000221, 12, 1032023, 0.0667, 4, 'Vanilla Blues 20-23 Level Range'), +(1000221, 13, 1031922, 0.0667, 4, 'Vanilla Blues 19-22 Level Range'), +(1000221, 16, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000221, 17, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000221, 18, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000221, 19, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000221, 20, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000222, 1, 1002125, 10, 0, 'Vanilla Greys 21-25 Level Range'), +(1000222, 2, 1012024, 0.5, 2, 'Vanilla Whites 20-24 Level Range'), +(1000222, 3, 1012125, 0.5, 2, 'Vanilla Whites 21-25 Level Range'), +(1000222, 4, 1011822, 0.5, 2, 'Vanilla Whites 18-22 Level Range'), +(1000222, 5, 1011923, 0.5, 2, 'Vanilla Whites 19-23 Level Range'), +(1000222, 6, 1022125, 0.8, 3, 'Vanilla Greens 21-25 Level Range'), +(1000222, 7, 1022024, 0.8, 3, 'Vanilla Greens 20-24 Level Range'), +(1000222, 8, 1022226, 0.8, 3, 'Vanilla Greens 22-26 Level Range'), +(1000222, 9, 1021822, 0.8, 3, 'Vanilla Greens 18-22 Level Range'), +(1000222, 10, 1021923, 0.8, 3, 'Vanilla Greens 19-23 Level Range'), +(1000222, 11, 1032124, 0.05, 4, 'Vanilla Blues 21-24 Level Range'), +(1000222, 12, 1032023, 0.05, 4, 'Vanilla Blues 20-23 Level Range'), +(1000222, 13, 1032225, 0.05, 4, 'Vanilla Blues 22-25 Level Range'), +(1000222, 14, 1031922, 0.05, 4, 'Vanilla Blues 19-22 Level Range'), +(1000222, 17, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000222, 18, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000222, 19, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000222, 20, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000222, 21, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000223, 1, 1002125, 10, 0, 'Vanilla Greys 21-25 Level Range'), +(1000223, 2, 1012024, 0.667, 2, 'Vanilla Whites 20-24 Level Range'), +(1000223, 3, 1012125, 0.667, 2, 'Vanilla Whites 21-25 Level Range'), +(1000223, 4, 1011923, 0.667, 2, 'Vanilla Whites 19-23 Level Range'), +(1000223, 5, 1022327, 0.8, 3, 'Vanilla Greens 23-27 Level Range'), +(1000223, 6, 1022125, 0.8, 3, 'Vanilla Greens 21-25 Level Range'), +(1000223, 7, 1022024, 0.8, 3, 'Vanilla Greens 20-24 Level Range'), +(1000223, 8, 1022226, 0.8, 3, 'Vanilla Greens 22-26 Level Range'), +(1000223, 9, 1021923, 0.8, 3, 'Vanilla Greens 19-23 Level Range'), +(1000223, 10, 1032124, 0.05, 4, 'Vanilla Blues 21-24 Level Range'), +(1000223, 11, 1032023, 0.05, 4, 'Vanilla Blues 20-23 Level Range'), +(1000223, 12, 1032225, 0.05, 4, 'Vanilla Blues 22-25 Level Range'), +(1000223, 13, 1032326, 0.05, 4, 'Vanilla Blues 23-26 Level Range'), +(1000223, 16, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000223, 17, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000223, 18, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000223, 19, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000223, 20, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +-- (1000224, 1, 1002125, 10, 0, 'Vanilla Greys 21-25 Level Range'), +-- (1000224, 2, 1012024, 1, 2, 'Vanilla Whites 20-24 Level Range'), +-- (1000224, 3, 1012125, 1, 2, 'Vanilla Whites 21-25 Level Range'), +-- (1000224, 4, 1022327, 0.8, 3, 'Vanilla Greens 23-27 Level Range'), +-- (1000224, 5, 1022428, 0.8, 3, 'Vanilla Greens 24-28 Level Range'), +-- (1000224, 6, 1022125, 0.8, 3, 'Vanilla Greens 21-25 Level Range'), +-- (1000224, 7, 1022024, 0.8, 3, 'Vanilla Greens 20-24 Level Range'), +-- (1000224, 8, 1022226, 0.8, 3, 'Vanilla Greens 22-26 Level Range'), +-- (1000224, 9, 1032427, 0.05, 4, 'Vanilla Blues 24-27 Level Range'), +-- (1000224, 10, 1032124, 0.05, 4, 'Vanilla Blues 21-24 Level Range'), +-- (1000224, 11, 1032225, 0.05, 4, 'Vanilla Blues 22-25 Level Range'), +-- (1000224, 12, 1032326, 0.05, 4, 'Vanilla Blues 23-26 Level Range'), +-- (1000224, 15, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +-- (1000224, 16, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +-- (1000224, 17, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +-- (1000224, 18, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +-- (1000224, 19, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000225, 1, 1002125, 10, 0, 'Vanilla Greys 21-25 Level Range'), +(1000225, 2, 1012125, 2, 2, 'Vanilla Whites 21-25 Level Range'), +(1000225, 3, 1022327, 0.8, 3, 'Vanilla Greens 23-27 Level Range'), +(1000225, 4, 1022428, 0.8, 3, 'Vanilla Greens 24-28 Level Range'), +(1000225, 5, 1022125, 0.8, 3, 'Vanilla Greens 21-25 Level Range'), +(1000225, 6, 1022226, 0.8, 3, 'Vanilla Greens 22-26 Level Range'), +(1000225, 7, 1022529, 0.8, 3, 'Vanilla Greens 25-29 Level Range'), +(1000225, 8, 1032427, 0.05, 4, 'Vanilla Blues 24-27 Level Range'), +(1000225, 9, 1032528, 0.05, 4, 'Vanilla Blues 25-28 Level Range'), +(1000225, 10, 1032225, 0.05, 4, 'Vanilla Blues 22-25 Level Range'), +(1000225, 11, 1032326, 0.05, 4, 'Vanilla Blues 23-26 Level Range'), +(1000225, 14, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000225, 15, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000225, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000225, 17, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000225, 18, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000226, 1, 1002630, 10, 0, 'Vanilla Greys 26-30 Level Range'), +(1000226, 2, 1022327, 0.8, 3, 'Vanilla Greens 23-27 Level Range'), +(1000226, 3, 1022428, 0.8, 3, 'Vanilla Greens 24-28 Level Range'), +(1000226, 4, 1022630, 0.8, 3, 'Vanilla Greens 26-30 Level Range'), +(1000226, 5, 1022226, 0.8, 3, 'Vanilla Greens 22-26 Level Range'), +(1000226, 6, 1022529, 0.8, 3, 'Vanilla Greens 25-29 Level Range'), +(1000226, 7, 1032427, 0.05, 4, 'Vanilla Blues 24-27 Level Range'), +(1000226, 8, 1032528, 0.05, 4, 'Vanilla Blues 25-28 Level Range'), +(1000226, 9, 1032629, 0.05, 4, 'Vanilla Blues 26-29 Level Range'), +(1000226, 10, 1032326, 0.05, 4, 'Vanilla Blues 23-26 Level Range'), +(1000226, 13, 1072627, 100, 0, 'Vanilla Miscellaneous 26-27 Level Range'), +(1000226, 14, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000226, 15, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000226, 16, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000226, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000227, 1, 1002630, 10, 0, 'Vanilla Greys 26-30 Level Range'), +(1000227, 2, 1022731, 0.8, 3, 'Vanilla Greens 27-31 Level Range'), +(1000227, 3, 1022327, 0.8, 3, 'Vanilla Greens 23-27 Level Range'), +(1000227, 4, 1022428, 0.8, 3, 'Vanilla Greens 24-28 Level Range'), +(1000227, 5, 1022630, 0.8, 3, 'Vanilla Greens 26-30 Level Range'), +(1000227, 6, 1022529, 0.8, 3, 'Vanilla Greens 25-29 Level Range'), +(1000227, 7, 1032427, 0.05, 4, 'Vanilla Blues 24-27 Level Range'), +(1000227, 8, 1032528, 0.05, 4, 'Vanilla Blues 25-28 Level Range'), +(1000227, 9, 1032629, 0.05, 4, 'Vanilla Blues 26-29 Level Range'), +(1000227, 10, 1032730, 0.05, 4, 'Vanilla Blues 27-30 Level Range'), +(1000227, 13, 1072627, 100, 0, 'Vanilla Miscellaneous 26-27 Level Range'), +(1000227, 14, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000227, 15, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000227, 16, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000227, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000228, 1, 1002630, 10, 0, 'Vanilla Greys 26-30 Level Range'), +(1000228, 2, 1022731, 0.8, 3, 'Vanilla Greens 27-31 Level Range'), +(1000228, 3, 1022832, 0.8, 3, 'Vanilla Greens 28-32 Level Range'), +(1000228, 4, 1022428, 0.8, 3, 'Vanilla Greens 24-28 Level Range'), +(1000228, 5, 1022630, 0.8, 3, 'Vanilla Greens 26-30 Level Range'), +(1000228, 6, 1022529, 0.8, 3, 'Vanilla Greens 25-29 Level Range'), +(1000228, 7, 1032528, 0.05, 4, 'Vanilla Blues 25-28 Level Range'), +(1000228, 8, 1032831, 0.05, 4, 'Vanilla Blues 28-31 Level Range'), +(1000228, 9, 1032629, 0.05, 4, 'Vanilla Blues 26-29 Level Range'), +(1000228, 10, 1032730, 0.05, 4, 'Vanilla Blues 27-30 Level Range'), +(1000228, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +(1000228, 14, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000228, 15, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000228, 16, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000228, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +-- (1000229, 1, 1002630, 10, 0, 'Vanilla Greys 26-30 Level Range'), +-- (1000229, 2, 1022731, 0.8, 3, 'Vanilla Greens 27-31 Level Range'), +-- (1000229, 3, 1022832, 0.8, 3, 'Vanilla Greens 28-32 Level Range'), +-- (1000229, 4, 1022933, 0.8, 3, 'Vanilla Greens 29-33 Level Range'), +-- (1000229, 5, 1022630, 0.8, 3, 'Vanilla Greens 26-30 Level Range'), +-- (1000229, 6, 1022529, 0.8, 3, 'Vanilla Greens 25-29 Level Range'), +-- (1000229, 7, 1032932, 0.05, 4, 'Vanilla Blues 29-32 Level Range'), +-- (1000229, 8, 1032831, 0.05, 4, 'Vanilla Blues 28-31 Level Range'), +-- (1000229, 9, 1032629, 0.05, 4, 'Vanilla Blues 26-29 Level Range'), +-- (1000229, 10, 1032730, 0.05, 4, 'Vanilla Blues 27-30 Level Range'), +-- (1000229, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +-- (1000229, 14, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +-- (1000229, 15, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +-- (1000229, 16, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +-- (1000229, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +-- (1000230, 1, 1002630, 10, 0, 'Vanilla Greys 26-30 Level Range'), +-- (1000230, 2, 1023034, 0.8, 3, 'Vanilla Greens 30-34 Level Range'), +-- (1000230, 3, 1022731, 0.8, 3, 'Vanilla Greens 27-31 Level Range'), +-- (1000230, 4, 1022832, 0.8, 3, 'Vanilla Greens 28-32 Level Range'), +-- (1000230, 5, 1022933, 0.8, 3, 'Vanilla Greens 29-33 Level Range'), +-- (1000230, 6, 1022630, 0.8, 3, 'Vanilla Greens 26-30 Level Range'), +-- (1000230, 7, 1032932, 0.05, 4, 'Vanilla Blues 29-32 Level Range'), +-- (1000230, 8, 1032831, 0.05, 4, 'Vanilla Blues 28-31 Level Range'), +-- (1000230, 9, 1033033, 0.05, 4, 'Vanilla Blues 30-33 Level Range'), +-- (1000230, 10, 1032730, 0.05, 4, 'Vanilla Blues 27-30 Level Range'), +-- (1000230, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +-- (1000230, 14, 1083045, 0.25, 6, 'Vanilla Patterns 30-45 Level Range'), +-- (1000230, 15, 1082640, 0.25, 6, 'Vanilla Patterns 26-40 Level Range'), +-- (1000230, 16, 1082035, 0.25, 6, 'Vanilla Patterns 20-35 Level Range'), +-- (1000230, 17, 1081630, 0.25, 6, 'Vanilla Patterns 16-30 Level Range'), +-- (1000230, 18, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +-- (1000231, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +-- (1000231, 2, 1023034, 0.8, 3, 'Vanilla Greens 30-34 Level Range'), +-- (1000231, 3, 1023135, 0.8, 3, 'Vanilla Greens 31-35 Level Range'), +-- (1000231, 4, 1022731, 0.8, 3, 'Vanilla Greens 27-31 Level Range'), +-- (1000231, 5, 1022832, 0.8, 3, 'Vanilla Greens 28-32 Level Range'), +-- (1000231, 6, 1022933, 0.8, 3, 'Vanilla Greens 29-33 Level Range'), +-- (1000231, 7, 1033134, 0.05, 4, 'Vanilla Blues 31-34 Level Range'), +-- (1000231, 8, 1032932, 0.05, 4, 'Vanilla Blues 29-32 Level Range'), +-- (1000231, 9, 1032831, 0.05, 4, 'Vanilla Blues 28-31 Level Range'), +-- (1000231, 10, 1033033, 0.05, 4, 'Vanilla Blues 30-33 Level Range'), +-- (1000231, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +-- (1000231, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +-- (1000231, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +-- (1000231, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +-- (1000231, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +-- (1000232, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +-- (1000232, 2, 1023034, 0.8, 3, 'Vanilla Greens 30-34 Level Range'), +-- (1000232, 3, 1023135, 0.8, 3, 'Vanilla Greens 31-35 Level Range'), +-- (1000232, 4, 1022832, 0.8, 3, 'Vanilla Greens 28-32 Level Range'), +-- (1000232, 5, 1022933, 0.8, 3, 'Vanilla Greens 29-33 Level Range'), +-- (1000232, 6, 1023236, 0.8, 3, 'Vanilla Greens 32-36 Level Range'), +-- (1000232, 7, 1033134, 0.05, 4, 'Vanilla Blues 31-34 Level Range'), +-- (1000232, 8, 1032932, 0.05, 4, 'Vanilla Blues 29-32 Level Range'), +-- (1000232, 9, 1033235, 0.05, 4, 'Vanilla Blues 32-35 Level Range'), +-- (1000232, 10, 1033033, 0.05, 4, 'Vanilla Blues 30-33 Level Range'), +-- (1000232, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +-- (1000232, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +-- (1000232, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +-- (1000232, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +-- (1000232, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000233, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000233, 2, 1023034, 0.8, 3, 'Vanilla Greens 30-34 Level Range'), +(1000233, 3, 1023135, 0.8, 3, 'Vanilla Greens 31-35 Level Range'), +(1000233, 4, 1022933, 0.8, 3, 'Vanilla Greens 29-33 Level Range'), +(1000233, 5, 1023337, 0.8, 3, 'Vanilla Greens 33-37 Level Range'), +(1000233, 6, 1023236, 0.8, 3, 'Vanilla Greens 32-36 Level Range'), +(1000233, 7, 1033134, 0.05, 4, 'Vanilla Blues 31-34 Level Range'), +(1000233, 8, 1033336, 0.05, 4, 'Vanilla Blues 33-36 Level Range'), +(1000233, 9, 1033235, 0.05, 4, 'Vanilla Blues 32-35 Level Range'), +(1000233, 10, 1033033, 0.05, 4, 'Vanilla Blues 30-33 Level Range'), +(1000233, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000233, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000233, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000233, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000233, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +-- (1000234, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +-- (1000234, 2, 1023034, 0.8, 3, 'Vanilla Greens 30-34 Level Range'), +-- (1000234, 3, 1023438, 0.8, 3, 'Vanilla Greens 34-38 Level Range'), +-- (1000234, 4, 1023135, 0.8, 3, 'Vanilla Greens 31-35 Level Range'), +-- (1000234, 5, 1023337, 0.8, 3, 'Vanilla Greens 33-37 Level Range'), +-- (1000234, 6, 1023236, 0.8, 3, 'Vanilla Greens 32-36 Level Range'), +-- (1000234, 7, 1033134, 0.05, 4, 'Vanilla Blues 31-34 Level Range'), +-- (1000234, 8, 1033336, 0.05, 4, 'Vanilla Blues 33-36 Level Range'), +-- (1000234, 9, 1033437, 0.05, 4, 'Vanilla Blues 34-37 Level Range'), +-- (1000234, 10, 1033235, 0.05, 4, 'Vanilla Blues 32-35 Level Range'), +-- (1000234, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +-- (1000234, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +-- (1000234, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +-- (1000234, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +-- (1000234, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +-- (1000235, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +-- (1000235, 2, 1023438, 0.8, 3, 'Vanilla Greens 34-38 Level Range'), +-- (1000235, 3, 1023135, 0.8, 3, 'Vanilla Greens 31-35 Level Range'), +-- (1000235, 4, 1023337, 0.8, 3, 'Vanilla Greens 33-37 Level Range'), +-- (1000235, 5, 1023539, 0.8, 3, 'Vanilla Greens 35-39 Level Range'), +-- (1000235, 6, 1023236, 0.8, 3, 'Vanilla Greens 32-36 Level Range'), +-- (1000235, 7, 1033336, 0.05, 4, 'Vanilla Blues 33-36 Level Range'), +-- (1000235, 8, 1033437, 0.05, 4, 'Vanilla Blues 34-37 Level Range'), +-- (1000235, 9, 1033235, 0.05, 4, 'Vanilla Blues 32-35 Level Range'), +-- (1000235, 10, 1033538, 0.05, 4, 'Vanilla Blues 35-38 Level Range'), +-- (1000235, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +-- (1000235, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +-- (1000235, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +-- (1000235, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +-- (1000235, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +-- (1000236, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +-- (1000236, 2, 1023438, 0.8, 3, 'Vanilla Greens 34-38 Level Range'), +-- (1000236, 3, 1023640, 0.8, 3, 'Vanilla Greens 36-40 Level Range'), +-- (1000236, 4, 1023337, 0.8, 3, 'Vanilla Greens 33-37 Level Range'), +-- (1000236, 5, 1023539, 0.8, 3, 'Vanilla Greens 35-39 Level Range'), +-- (1000236, 6, 1023236, 0.8, 3, 'Vanilla Greens 32-36 Level Range'), +-- (1000236, 7, 1033639, 0.05, 4, 'Vanilla Blues 36-39 Level Range'), +-- (1000236, 8, 1033336, 0.05, 4, 'Vanilla Blues 33-36 Level Range'), +-- (1000236, 9, 1033437, 0.05, 4, 'Vanilla Blues 34-37 Level Range'), +-- (1000236, 10, 1033538, 0.05, 4, 'Vanilla Blues 35-38 Level Range'), +-- (1000236, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +-- (1000236, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +-- (1000236, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +-- (1000236, 16, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +-- (1000236, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000237, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000237, 2, 1023438, 0.8, 3, 'Vanilla Greens 34-38 Level Range'), +(1000237, 3, 1023640, 0.8, 3, 'Vanilla Greens 36-40 Level Range'), +(1000237, 4, 1023741, 0.8, 3, 'Vanilla Greens 37-41 Level Range'), +(1000237, 5, 1023337, 0.8, 3, 'Vanilla Greens 33-37 Level Range'), +(1000237, 6, 1023539, 0.8, 3, 'Vanilla Greens 35-39 Level Range'), +(1000237, 7, 1033639, 0.05, 4, 'Vanilla Blues 36-39 Level Range'), +(1000237, 8, 1033740, 0.05, 4, 'Vanilla Blues 37-40 Level Range'), +(1000237, 9, 1033437, 0.05, 4, 'Vanilla Blues 34-37 Level Range'), +(1000237, 10, 1033538, 0.05, 4, 'Vanilla Blues 35-38 Level Range'), +(1000237, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000237, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000237, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000237, 16, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000237, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000238, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000238, 2, 1023438, 0.8, 3, 'Vanilla Greens 34-38 Level Range'), +(1000238, 3, 1023640, 0.8, 3, 'Vanilla Greens 36-40 Level Range'), +(1000238, 4, 1023741, 0.8, 3, 'Vanilla Greens 37-41 Level Range'), +(1000238, 5, 1023842, 0.8, 3, 'Vanilla Greens 38-42 Level Range'), +(1000238, 6, 1023539, 0.8, 3, 'Vanilla Greens 35-39 Level Range'), +(1000238, 7, 1033841, 0.05, 4, 'Vanilla Blues 38-41 Level Range'), +(1000238, 8, 1033639, 0.05, 4, 'Vanilla Blues 36-39 Level Range'), +(1000238, 9, 1033740, 0.05, 4, 'Vanilla Blues 37-40 Level Range'), +(1000238, 10, 1033538, 0.05, 4, 'Vanilla Blues 35-38 Level Range'), +(1000238, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000238, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000238, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000238, 16, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000238, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000239, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000239, 2, 1023640, 0.8, 3, 'Vanilla Greens 36-40 Level Range'), +(1000239, 3, 1023741, 0.8, 3, 'Vanilla Greens 37-41 Level Range'), +(1000239, 4, 1023842, 0.8, 3, 'Vanilla Greens 38-42 Level Range'), +(1000239, 5, 1023943, 0.8, 3, 'Vanilla Greens 39-43 Level Range'), +(1000239, 6, 1023539, 0.8, 3, 'Vanilla Greens 35-39 Level Range'), +(1000239, 7, 1033841, 0.05, 4, 'Vanilla Blues 38-41 Level Range'), +(1000239, 8, 1033639, 0.05, 4, 'Vanilla Blues 36-39 Level Range'), +(1000239, 9, 1033740, 0.05, 4, 'Vanilla Blues 37-40 Level Range'), +(1000239, 10, 1033942, 0.05, 4, 'Vanilla Blues 39-42 Level Range'), +(1000239, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000239, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000239, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000239, 16, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000239, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000240, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000240, 2, 1023640, 0.8, 3, 'Vanilla Greens 36-40 Level Range'), +(1000240, 3, 1023741, 0.8, 3, 'Vanilla Greens 37-41 Level Range'), +(1000240, 4, 1023842, 0.8, 3, 'Vanilla Greens 38-42 Level Range'), +(1000240, 5, 1023943, 0.8, 3, 'Vanilla Greens 39-43 Level Range'), +(1000240, 6, 1024044, 0.8, 3, 'Vanilla Greens 40-44 Level Range'), +(1000240, 7, 1033841, 0.05, 4, 'Vanilla Blues 38-41 Level Range'), +(1000240, 8, 1033740, 0.05, 4, 'Vanilla Blues 37-40 Level Range'), +(1000240, 9, 1034043, 0.05, 4, 'Vanilla Blues 40-43 Level Range'), +(1000240, 10, 1033942, 0.05, 4, 'Vanilla Blues 39-42 Level Range'), +(1000240, 11, 1044046, 0.05, 5, 'Vanilla Purples 40-46 Level Range'), +(1000240, 14, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000240, 15, 1083045, 0.25, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000240, 16, 1082640, 0.25, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000240, 17, 1083650, 0.25, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000240, 18, 1084055, 0.25, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000240, 19, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +-- (1000241, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +-- (1000241, 2, 1024145, 0.8, 3, 'Vanilla Greens 41-45 Level Range'), +-- (1000241, 3, 1023741, 0.8, 3, 'Vanilla Greens 37-41 Level Range'), +-- (1000241, 4, 1023842, 0.8, 3, 'Vanilla Greens 38-42 Level Range'), +-- (1000241, 5, 1023943, 0.8, 3, 'Vanilla Greens 39-43 Level Range'), +-- (1000241, 6, 1024044, 0.8, 3, 'Vanilla Greens 40-44 Level Range'), +-- (1000241, 7, 1033841, 0.05, 4, 'Vanilla Blues 38-41 Level Range'), +-- (1000241, 8, 1034043, 0.05, 4, 'Vanilla Blues 40-43 Level Range'), +-- (1000241, 9, 1033942, 0.05, 4, 'Vanilla Blues 39-42 Level Range'), +-- (1000241, 10, 1034144, 0.05, 4, 'Vanilla Blues 41-44 Level Range'), +-- (1000241, 11, 1044046, 0.05, 5, 'Vanilla Purples 40-46 Level Range'), +-- (1000241, 14, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +-- (1000241, 15, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +-- (1000241, 16, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +-- (1000241, 17, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +-- (1000241, 18, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +-- (1000242, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +-- (1000242, 2, 1024145, 0.8, 3, 'Vanilla Greens 41-45 Level Range'), +-- (1000242, 3, 1024246, 0.8, 3, 'Vanilla Greens 42-46 Level Range'), +-- (1000242, 4, 1023842, 0.8, 3, 'Vanilla Greens 38-42 Level Range'), +-- (1000242, 5, 1023943, 0.8, 3, 'Vanilla Greens 39-43 Level Range'), +-- (1000242, 6, 1024044, 0.8, 3, 'Vanilla Greens 40-44 Level Range'), +-- (1000242, 7, 1034245, 0.05, 4, 'Vanilla Blues 42-45 Level Range'), +-- (1000242, 8, 1034043, 0.05, 4, 'Vanilla Blues 40-43 Level Range'), +-- (1000242, 9, 1033942, 0.05, 4, 'Vanilla Blues 39-42 Level Range'), +-- (1000242, 10, 1034144, 0.05, 4, 'Vanilla Blues 41-44 Level Range'), +-- (1000242, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +-- (1000242, 12, 1044046, 0.025, 5, 'Vanilla Purples 40-46 Level Range'), +-- (1000242, 15, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +-- (1000242, 16, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +-- (1000242, 17, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +-- (1000242, 18, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +-- (1000242, 19, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000243, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000243, 2, 1024145, 0.8, 3, 'Vanilla Greens 41-45 Level Range'), +(1000243, 3, 1024347, 0.8, 3, 'Vanilla Greens 43-47 Level Range'), +(1000243, 4, 1024246, 0.8, 3, 'Vanilla Greens 42-46 Level Range'), +(1000243, 5, 1023943, 0.8, 3, 'Vanilla Greens 39-43 Level Range'), +(1000243, 6, 1024044, 0.8, 3, 'Vanilla Greens 40-44 Level Range'), +(1000243, 7, 1034245, 0.05, 4, 'Vanilla Blues 42-45 Level Range'), +(1000243, 8, 1034346, 0.05, 4, 'Vanilla Blues 43-46 Level Range'), +(1000243, 9, 1034043, 0.05, 4, 'Vanilla Blues 40-43 Level Range'), +(1000243, 10, 1034144, 0.05, 4, 'Vanilla Blues 41-44 Level Range'), +(1000243, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +(1000243, 12, 1044046, 0.025, 5, 'Vanilla Purples 40-46 Level Range'), +(1000243, 15, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000243, 16, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000243, 17, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000243, 18, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000243, 19, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000244, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000244, 2, 1024145, 0.8, 3, 'Vanilla Greens 41-45 Level Range'), +(1000244, 3, 1024347, 0.8, 3, 'Vanilla Greens 43-47 Level Range'), +(1000244, 4, 1024448, 0.8, 3, 'Vanilla Greens 44-48 Level Range'), +(1000244, 5, 1024246, 0.8, 3, 'Vanilla Greens 42-46 Level Range'), +(1000244, 6, 1024044, 0.8, 3, 'Vanilla Greens 40-44 Level Range'), +(1000244, 7, 1034245, 0.05, 4, 'Vanilla Blues 42-45 Level Range'), +(1000244, 8, 1034447, 0.05, 4, 'Vanilla Blues 44-47 Level Range'), +(1000244, 9, 1034346, 0.05, 4, 'Vanilla Blues 43-46 Level Range'), +(1000244, 10, 1034144, 0.05, 4, 'Vanilla Blues 41-44 Level Range'), +(1000244, 11, 1044248, 0.0334, 5, 'Vanilla Purples 42-48 Level Range'), +(1000244, 12, 1044046, 0.0334, 5, 'Vanilla Purples 40-46 Level Range'), +(1000244, 13, 1044450, 0.0334, 5, 'Vanilla Purples 44-50 Level Range'), +(1000244, 16, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000244, 17, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000244, 18, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000244, 19, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000244, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000245, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000245, 2, 1024145, 0.8, 3, 'Vanilla Greens 41-45 Level Range'), +(1000245, 3, 1024347, 0.8, 3, 'Vanilla Greens 43-47 Level Range'), +(1000245, 4, 1024448, 0.8, 3, 'Vanilla Greens 44-48 Level Range'), +(1000245, 5, 1024549, 0.8, 3, 'Vanilla Greens 45-49 Level Range'), +(1000245, 6, 1024246, 0.8, 3, 'Vanilla Greens 42-46 Level Range'), +(1000245, 7, 1034245, 0.05, 4, 'Vanilla Blues 42-45 Level Range'), +(1000245, 8, 1034447, 0.05, 4, 'Vanilla Blues 44-47 Level Range'), +(1000245, 9, 1034346, 0.05, 4, 'Vanilla Blues 43-46 Level Range'), +(1000245, 10, 1034548, 0.05, 4, 'Vanilla Blues 45-48 Level Range'), +(1000245, 11, 1044248, 0.0334, 5, 'Vanilla Purples 42-48 Level Range'), +(1000245, 12, 1044046, 0.0334, 5, 'Vanilla Purples 40-46 Level Range'), +(1000245, 13, 1044450, 0.0334, 5, 'Vanilla Purples 44-50 Level Range'), +(1000245, 16, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000245, 17, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000245, 18, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000245, 19, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000245, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000246, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000246, 2, 1024347, 0.8, 3, 'Vanilla Greens 43-47 Level Range'), +(1000246, 3, 1024448, 0.8, 3, 'Vanilla Greens 44-48 Level Range'), +(1000246, 4, 1024549, 0.8, 3, 'Vanilla Greens 45-49 Level Range'), +(1000246, 5, 1024246, 0.8, 3, 'Vanilla Greens 42-46 Level Range'), +(1000246, 6, 1024650, 0.8, 3, 'Vanilla Greens 46-50 Level Range'), +(1000246, 7, 1034447, 0.05, 4, 'Vanilla Blues 44-47 Level Range'), +(1000246, 8, 1034346, 0.05, 4, 'Vanilla Blues 43-46 Level Range'), +(1000246, 9, 1034649, 0.05, 4, 'Vanilla Blues 46-49 Level Range'), +(1000246, 10, 1034548, 0.05, 4, 'Vanilla Blues 45-48 Level Range'), +(1000246, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +(1000246, 12, 1044046, 0.025, 5, 'Vanilla Purples 40-46 Level Range'), +(1000246, 13, 1044450, 0.025, 5, 'Vanilla Purples 44-50 Level Range'), +(1000246, 14, 1044652, 0.025, 5, 'Vanilla Purples 46-52 Level Range'), +(1000246, 17, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000246, 18, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000246, 19, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000246, 20, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000246, 21, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000247, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000247, 2, 1024347, 0.8, 3, 'Vanilla Greens 43-47 Level Range'), +(1000247, 3, 1024448, 0.8, 3, 'Vanilla Greens 44-48 Level Range'), +(1000247, 4, 1024549, 0.8, 3, 'Vanilla Greens 45-49 Level Range'), +(1000247, 5, 1024751, 0.8, 3, 'Vanilla Greens 47-51 Level Range'), +(1000247, 6, 1024650, 0.8, 3, 'Vanilla Greens 46-50 Level Range'), +(1000247, 7, 1034447, 0.05, 4, 'Vanilla Blues 44-47 Level Range'), +(1000247, 8, 1034649, 0.05, 4, 'Vanilla Blues 46-49 Level Range'), +(1000247, 9, 1034548, 0.05, 4, 'Vanilla Blues 45-48 Level Range'), +(1000247, 10, 1034750, 0.05, 4, 'Vanilla Blues 47-50 Level Range'), +(1000247, 11, 1044248, 0.0334, 5, 'Vanilla Purples 42-48 Level Range'), +(1000247, 12, 1044450, 0.0334, 5, 'Vanilla Purples 44-50 Level Range'), +(1000247, 13, 1044652, 0.0334, 5, 'Vanilla Purples 46-52 Level Range'), +(1000247, 16, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000247, 17, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000247, 18, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000247, 19, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000247, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000248, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000248, 2, 1024448, 0.8, 3, 'Vanilla Greens 44-48 Level Range'), +(1000248, 3, 1024549, 0.8, 3, 'Vanilla Greens 45-49 Level Range'), +(1000248, 4, 1024751, 0.8, 3, 'Vanilla Greens 47-51 Level Range'), +(1000248, 5, 1024852, 0.8, 3, 'Vanilla Greens 48-52 Level Range'), +(1000248, 6, 1024650, 0.8, 3, 'Vanilla Greens 46-50 Level Range'), +(1000248, 7, 1034649, 0.05, 4, 'Vanilla Blues 46-49 Level Range'), +(1000248, 8, 1034548, 0.05, 4, 'Vanilla Blues 45-48 Level Range'), +(1000248, 9, 1034851, 0.05, 4, 'Vanilla Blues 48-51 Level Range'), +(1000248, 10, 1034750, 0.05, 4, 'Vanilla Blues 47-50 Level Range'), +(1000248, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +(1000248, 12, 1044854, 0.025, 5, 'Vanilla Purples 48-54 Level Range'), +(1000248, 13, 1044450, 0.025, 5, 'Vanilla Purples 44-50 Level Range'), +(1000248, 14, 1044652, 0.025, 5, 'Vanilla Purples 46-52 Level Range'), +(1000248, 17, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000248, 18, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000248, 19, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000248, 20, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000248, 21, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000249, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000249, 2, 1024549, 0.8, 3, 'Vanilla Greens 45-49 Level Range'), +(1000249, 3, 1024751, 0.8, 3, 'Vanilla Greens 47-51 Level Range'), +(1000249, 4, 1024852, 0.8, 3, 'Vanilla Greens 48-52 Level Range'), +(1000249, 5, 1024953, 0.8, 3, 'Vanilla Greens 49-53 Level Range'), +(1000249, 6, 1024650, 0.8, 3, 'Vanilla Greens 46-50 Level Range'), +(1000249, 7, 1034649, 0.05, 4, 'Vanilla Blues 46-49 Level Range'), +(1000249, 8, 1034952, 0.05, 4, 'Vanilla Blues 49-52 Level Range'), +(1000249, 9, 1034851, 0.05, 4, 'Vanilla Blues 48-51 Level Range'), +(1000249, 10, 1034750, 0.05, 4, 'Vanilla Blues 47-50 Level Range'), +(1000249, 11, 1044854, 0.0334, 5, 'Vanilla Purples 48-54 Level Range'), +(1000249, 12, 1044450, 0.0334, 5, 'Vanilla Purples 44-50 Level Range'), +(1000249, 13, 1044652, 0.0334, 5, 'Vanilla Purples 46-52 Level Range'), +(1000249, 16, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000249, 17, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000249, 18, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000249, 19, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000249, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000250, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000250, 2, 1024751, 0.8, 3, 'Vanilla Greens 47-51 Level Range'), +(1000250, 3, 1025054, 0.8, 3, 'Vanilla Greens 50-54 Level Range'), +(1000250, 4, 1024852, 0.8, 3, 'Vanilla Greens 48-52 Level Range'), +(1000250, 5, 1024953, 0.8, 3, 'Vanilla Greens 49-53 Level Range'), +(1000250, 6, 1024650, 0.8, 3, 'Vanilla Greens 46-50 Level Range'), +(1000250, 7, 1034952, 0.05, 4, 'Vanilla Blues 49-52 Level Range'), +(1000250, 8, 1034851, 0.05, 4, 'Vanilla Blues 48-51 Level Range'), +(1000250, 9, 1035053, 0.05, 4, 'Vanilla Blues 50-53 Level Range'), +(1000250, 10, 1034750, 0.05, 4, 'Vanilla Blues 47-50 Level Range'), +(1000250, 11, 1044854, 0.025, 5, 'Vanilla Purples 48-54 Level Range'), +(1000250, 12, 1044450, 0.025, 5, 'Vanilla Purples 44-50 Level Range'), +(1000250, 13, 1044652, 0.025, 5, 'Vanilla Purples 46-52 Level Range'), +(1000250, 14, 1045056, 0.025, 5, 'Vanilla Purples 50-56 Level Range'), +(1000250, 18, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000250, 19, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000250, 20, 1084660, 0.25, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000250, 21, 1083650, 0.25, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000250, 22, 1084055, 0.25, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000250, 23, 1085063, 0.25, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000250, 24, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000251, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000251, 2, 1025155, 0.8, 3, 'Vanilla Greens 51-55 Level Range'), +(1000251, 3, 1024751, 0.8, 3, 'Vanilla Greens 47-51 Level Range'), +(1000251, 4, 1025054, 0.8, 3, 'Vanilla Greens 50-54 Level Range'), +(1000251, 5, 1024852, 0.8, 3, 'Vanilla Greens 48-52 Level Range'), +(1000251, 6, 1024953, 0.8, 3, 'Vanilla Greens 49-53 Level Range'), +(1000251, 7, 1034952, 0.05, 4, 'Vanilla Blues 49-52 Level Range'), +(1000251, 8, 1034851, 0.05, 4, 'Vanilla Blues 48-51 Level Range'), +(1000251, 9, 1035154, 0.05, 4, 'Vanilla Blues 51-54 Level Range'), +(1000251, 10, 1035053, 0.05, 4, 'Vanilla Blues 50-53 Level Range'), +(1000251, 11, 1044854, 0.0334, 5, 'Vanilla Purples 48-54 Level Range'), +(1000251, 12, 1044652, 0.0334, 5, 'Vanilla Purples 46-52 Level Range'), +(1000251, 13, 1045056, 0.0334, 5, 'Vanilla Purples 50-56 Level Range'), +(1000251, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000251, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000251, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000251, 20, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000251, 21, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000251, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000252, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000252, 2, 1025155, 0.8, 3, 'Vanilla Greens 51-55 Level Range'), +(1000252, 3, 1025256, 0.8, 3, 'Vanilla Greens 52-56 Level Range'), +(1000252, 4, 1025054, 0.8, 3, 'Vanilla Greens 50-54 Level Range'), +(1000252, 5, 1024852, 0.8, 3, 'Vanilla Greens 48-52 Level Range'), +(1000252, 6, 1024953, 0.8, 3, 'Vanilla Greens 49-53 Level Range'), +(1000252, 7, 1035255, 0.05, 4, 'Vanilla Blues 52-55 Level Range'), +(1000252, 8, 1034952, 0.05, 4, 'Vanilla Blues 49-52 Level Range'), +(1000252, 9, 1035154, 0.05, 4, 'Vanilla Blues 51-54 Level Range'), +(1000252, 10, 1035053, 0.05, 4, 'Vanilla Blues 50-53 Level Range'), +(1000252, 11, 1044854, 0.025, 5, 'Vanilla Purples 48-54 Level Range'), +(1000252, 12, 1044652, 0.025, 5, 'Vanilla Purples 46-52 Level Range'), +(1000252, 13, 1045258, 0.025, 5, 'Vanilla Purples 52-58 Level Range'), +(1000252, 14, 1045056, 0.025, 5, 'Vanilla Purples 50-56 Level Range'), +(1000252, 17, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000252, 19, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000252, 20, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000252, 21, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000252, 22, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000252, 23, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000253, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000253, 2, 1025155, 0.8, 3, 'Vanilla Greens 51-55 Level Range'), +(1000253, 3, 1025357, 0.8, 3, 'Vanilla Greens 53-57 Level Range'), +(1000253, 4, 1025256, 0.8, 3, 'Vanilla Greens 52-56 Level Range'), +(1000253, 5, 1025054, 0.8, 3, 'Vanilla Greens 50-54 Level Range'), +(1000253, 6, 1024953, 0.8, 3, 'Vanilla Greens 49-53 Level Range'), +(1000253, 7, 1035255, 0.05, 4, 'Vanilla Blues 52-55 Level Range'), +(1000253, 8, 1035154, 0.05, 4, 'Vanilla Blues 51-54 Level Range'), +(1000253, 9, 1035356, 0.05, 4, 'Vanilla Blues 53-56 Level Range'), +(1000253, 10, 1035053, 0.05, 4, 'Vanilla Blues 50-53 Level Range'), +(1000253, 11, 1044854, 0.0334, 5, 'Vanilla Purples 48-54 Level Range'), +(1000253, 12, 1045258, 0.0334, 5, 'Vanilla Purples 52-58 Level Range'), +(1000253, 13, 1045056, 0.0334, 5, 'Vanilla Purples 50-56 Level Range'), +(1000253, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000253, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000253, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000253, 20, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000253, 21, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000253, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000254, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000254, 2, 1025458, 0.8, 3, 'Vanilla Greens 54-58 Level Range'), +(1000254, 3, 1025155, 0.8, 3, 'Vanilla Greens 51-55 Level Range'), +(1000254, 4, 1025357, 0.8, 3, 'Vanilla Greens 53-57 Level Range'), +(1000254, 5, 1025256, 0.8, 3, 'Vanilla Greens 52-56 Level Range'), +(1000254, 6, 1025054, 0.8, 3, 'Vanilla Greens 50-54 Level Range'), +(1000254, 7, 1035255, 0.05, 4, 'Vanilla Blues 52-55 Level Range'), +(1000254, 8, 1035457, 0.05, 4, 'Vanilla Blues 54-57 Level Range'), +(1000254, 9, 1035154, 0.05, 4, 'Vanilla Blues 51-54 Level Range'), +(1000254, 10, 1035356, 0.05, 4, 'Vanilla Blues 53-56 Level Range'), +(1000254, 11, 1044854, 0.025, 5, 'Vanilla Purples 48-54 Level Range'), +(1000254, 12, 1045258, 0.025, 5, 'Vanilla Purples 52-58 Level Range'), +(1000254, 13, 1045056, 0.025, 5, 'Vanilla Purples 50-56 Level Range'), +(1000254, 14, 1045460, 0.025, 5, 'Vanilla Purples 54-60 Level Range'), +(1000254, 17, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000254, 19, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000254, 20, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000254, 21, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000254, 22, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000254, 23, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000255, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000255, 2, 1025458, 0.8, 3, 'Vanilla Greens 54-58 Level Range'), +(1000255, 3, 1025559, 0.8, 3, 'Vanilla Greens 55-59 Level Range'), +(1000255, 4, 1025155, 0.8, 3, 'Vanilla Greens 51-55 Level Range'), +(1000255, 5, 1025357, 0.8, 3, 'Vanilla Greens 53-57 Level Range'), +(1000255, 6, 1025256, 0.8, 3, 'Vanilla Greens 52-56 Level Range'), +(1000255, 7, 1035255, 0.05, 4, 'Vanilla Blues 52-55 Level Range'), +(1000255, 8, 1035558, 0.05, 4, 'Vanilla Blues 55-58 Level Range'), +(1000255, 9, 1035457, 0.05, 4, 'Vanilla Blues 54-57 Level Range'), +(1000255, 10, 1035356, 0.05, 4, 'Vanilla Blues 53-56 Level Range'), +(1000255, 11, 1045258, 0.0334, 5, 'Vanilla Purples 52-58 Level Range'), +(1000255, 12, 1045056, 0.0334, 5, 'Vanilla Purples 50-56 Level Range'), +(1000255, 13, 1045460, 0.0334, 5, 'Vanilla Purples 54-60 Level Range'), +(1000255, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000255, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000255, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000255, 20, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000255, 21, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000255, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000256, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000256, 2, 1025660, 0.8, 3, 'Vanilla Greens 56-60 Level Range'), +(1000256, 3, 1025458, 0.8, 3, 'Vanilla Greens 54-58 Level Range'), +(1000256, 4, 1025559, 0.8, 3, 'Vanilla Greens 55-59 Level Range'), +(1000256, 5, 1025357, 0.8, 3, 'Vanilla Greens 53-57 Level Range'), +(1000256, 6, 1025256, 0.8, 3, 'Vanilla Greens 52-56 Level Range'), +(1000256, 7, 1035558, 0.05, 4, 'Vanilla Blues 55-58 Level Range'), +(1000256, 8, 1035457, 0.05, 4, 'Vanilla Blues 54-57 Level Range'), +(1000256, 9, 1035356, 0.05, 4, 'Vanilla Blues 53-56 Level Range'), +(1000256, 10, 1035659, 0.05, 4, 'Vanilla Blues 56-59 Level Range'), +(1000256, 11, 1045662, 0.025, 5, 'Vanilla Purples 56-62 Level Range'), +(1000256, 12, 1045258, 0.025, 5, 'Vanilla Purples 52-58 Level Range'), +(1000256, 13, 1045056, 0.025, 5, 'Vanilla Purples 50-56 Level Range'), +(1000256, 14, 1045460, 0.025, 5, 'Vanilla Purples 54-60 Level Range'), +(1000256, 17, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000256, 19, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000256, 20, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000256, 21, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000256, 22, 1085663, 0.33, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000256, 23, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000257, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000257, 2, 1025660, 0.8, 3, 'Vanilla Greens 56-60 Level Range'), +(1000257, 3, 1025458, 0.8, 3, 'Vanilla Greens 54-58 Level Range'), +(1000257, 4, 1025559, 0.8, 3, 'Vanilla Greens 55-59 Level Range'), +(1000257, 5, 1025357, 0.8, 3, 'Vanilla Greens 53-57 Level Range'), +(1000257, 6, 1025761, 0.8, 3, 'Vanilla Greens 57-61 Level Range'), +(1000257, 7, 1035558, 0.05, 4, 'Vanilla Blues 55-58 Level Range'), +(1000257, 8, 1035457, 0.05, 4, 'Vanilla Blues 54-57 Level Range'), +(1000257, 9, 1035760, 0.05, 4, 'Vanilla Blues 57-60 Level Range'), +(1000257, 10, 1035659, 0.05, 4, 'Vanilla Blues 56-59 Level Range'), +(1000257, 11, 1045662, 0.0334, 5, 'Vanilla Purples 56-62 Level Range'), +(1000257, 12, 1045258, 0.0334, 5, 'Vanilla Purples 52-58 Level Range'), +(1000257, 13, 1045460, 0.0334, 5, 'Vanilla Purples 54-60 Level Range'), +(1000257, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000257, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000257, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000257, 20, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000257, 21, 1085663, 0.33, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000257, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000258, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000258, 2, 1025660, 0.8, 3, 'Vanilla Greens 56-60 Level Range'), +(1000258, 3, 1025862, 0.8, 3, 'Vanilla Greens 58-62 Level Range'), +(1000258, 4, 1025458, 0.8, 3, 'Vanilla Greens 54-58 Level Range'), +(1000258, 5, 1025559, 0.8, 3, 'Vanilla Greens 55-59 Level Range'), +(1000258, 6, 1025761, 0.8, 3, 'Vanilla Greens 57-61 Level Range'), +(1000258, 7, 1035861, 0.05, 4, 'Vanilla Blues 58-61 Level Range'), +(1000258, 8, 1035558, 0.05, 4, 'Vanilla Blues 55-58 Level Range'), +(1000258, 9, 1035760, 0.05, 4, 'Vanilla Blues 57-60 Level Range'), +(1000258, 10, 1035659, 0.05, 4, 'Vanilla Blues 56-59 Level Range'), +(1000258, 11, 1045662, 0.025, 5, 'Vanilla Purples 56-62 Level Range'), +(1000258, 12, 1045258, 0.025, 5, 'Vanilla Purples 52-58 Level Range'), +(1000258, 13, 1045460, 0.025, 5, 'Vanilla Purples 54-60 Level Range'), +(1000258, 14, 1045863, 0.025, 5, 'Vanilla Purples 58-63 Level Range'), +(1000258, 17, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000258, 19, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000258, 20, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000258, 21, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000258, 22, 1085663, 0.33, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000258, 23, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000259, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000259, 2, 1025660, 0.8, 3, 'Vanilla Greens 56-60 Level Range'), +(1000259, 3, 1025862, 0.8, 3, 'Vanilla Greens 58-62 Level Range'), +(1000259, 4, 1025559, 0.8, 3, 'Vanilla Greens 55-59 Level Range'), +(1000259, 5, 1025963, 0.8, 3, 'Vanilla Greens 59-63 Level Range'), +(1000259, 6, 1025761, 0.8, 3, 'Vanilla Greens 57-61 Level Range'), +(1000259, 7, 1035861, 0.05, 4, 'Vanilla Blues 58-61 Level Range'), +(1000259, 8, 1035963, 0.05, 4, 'Vanilla Blues 59-63 Level Range'), +(1000259, 9, 1035760, 0.05, 4, 'Vanilla Blues 57-60 Level Range'), +(1000259, 10, 1035659, 0.05, 4, 'Vanilla Blues 56-59 Level Range'), +(1000259, 11, 1045662, 0.0334, 5, 'Vanilla Purples 56-62 Level Range'), +(1000259, 12, 1045460, 0.0334, 5, 'Vanilla Purples 54-60 Level Range'), +(1000259, 13, 1045863, 0.0334, 5, 'Vanilla Purples 58-63 Level Range'), +(1000259, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000259, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000259, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000259, 20, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000259, 21, 1085663, 0.33, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000259, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000260, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000260, 2, 1025660, 0.8, 3, 'Vanilla Greens 56-60 Level Range'), +(1000260, 3, 1025862, 0.8, 3, 'Vanilla Greens 58-62 Level Range'), +(1000260, 4, 1026063, 0.8, 3, 'Vanilla Greens 60-63 Level Range'), +(1000260, 5, 1025963, 0.8, 3, 'Vanilla Greens 59-63 Level Range'), +(1000260, 6, 1025761, 0.8, 3, 'Vanilla Greens 57-61 Level Range'), +(1000260, 7, 1035861, 0.0667, 4, 'Vanilla Blues 58-61 Level Range'), +(1000260, 8, 1035963, 0.0667, 4, 'Vanilla Blues 59-63 Level Range'), +(1000260, 9, 1035760, 0.0667, 4, 'Vanilla Blues 57-60 Level Range'), +(1000260, 10, 1045662, 0.025, 5, 'Vanilla Purples 56-62 Level Range'), +(1000260, 11, 1046063, 0.025, 5, 'Vanilla Purples 60-63 Level Range'), +(1000260, 12, 1045460, 0.025, 5, 'Vanilla Purples 54-60 Level Range'), +(1000260, 13, 1045863, 0.025, 5, 'Vanilla Purples 58-63 Level Range'), +(1000260, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000260, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000260, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000260, 20, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000260, 21, 1085663, 0.33, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000260, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000261, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000261, 2, 1025862, 0.8, 3, 'Vanilla Greens 58-62 Level Range'), +(1000261, 3, 1026163, 0.8, 3, 'Vanilla Greens 61-63 Level Range'), +(1000261, 4, 1026063, 0.8, 3, 'Vanilla Greens 60-63 Level Range'), +(1000261, 5, 1025963, 0.8, 3, 'Vanilla Greens 59-63 Level Range'), +(1000261, 6, 1025761, 0.8, 3, 'Vanilla Greens 57-61 Level Range'), +(1000261, 7, 1035861, 0.1, 4, 'Vanilla Blues 58-61 Level Range'), +(1000261, 8, 1035963, 0.1, 4, 'Vanilla Blues 59-63 Level Range'), +(1000261, 9, 1045662, 0.0334, 5, 'Vanilla Purples 56-62 Level Range'), +(1000261, 10, 1046063, 0.0334, 5, 'Vanilla Purples 60-63 Level Range'), +(1000261, 11, 1045863, 0.0334, 5, 'Vanilla Purples 58-63 Level Range'), +(1000261, 14, 1076163, 100, 0, 'Vanilla Miscellaneous 61-63 Level Range'), +(1000261, 16, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000261, 18, 1085063, 0.5, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000261, 19, 1085663, 0.5, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000261, 20, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000262, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000262, 2, 1025862, 0.8, 3, 'Vanilla Greens 58-62 Level Range'), +(1000262, 3, 1026263, 0.8, 3, 'Vanilla Greens 62-63 Level Range'), +(1000262, 4, 1026163, 0.8, 3, 'Vanilla Greens 61-63 Level Range'), +(1000262, 5, 1026063, 0.8, 3, 'Vanilla Greens 60-63 Level Range'), +(1000262, 6, 1025963, 0.8, 3, 'Vanilla Greens 59-63 Level Range'), +(1000262, 7, 1035963, 0.2, 4, 'Vanilla Blues 59-63 Level Range'), +(1000262, 8, 1045662, 0.0334, 5, 'Vanilla Purples 56-62 Level Range'), +(1000262, 9, 1046063, 0.0334, 5, 'Vanilla Purples 60-63 Level Range'), +(1000262, 10, 1045863, 0.0334, 5, 'Vanilla Purples 58-63 Level Range'), +(1000262, 13, 1076163, 100, 0, 'Vanilla Miscellaneous 61-63 Level Range'), +(1000262, 14, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000262, 16, 1085063, 0.5, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000262, 17, 1085663, 0.5, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000262, 18, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000263, 1 , 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000263, 2 , 1026263, 1, 3, 'Vanilla Greens 62-63 Level Range'), +(1000263, 3 , 1026163, 1, 3, 'Vanilla Greens 61-63 Level Range'), +(1000263, 4 , 1026063, 1, 3, 'Vanilla Greens 60-63 Level Range'), +(1000263, 5 , 1025963, 1, 3, 'Vanilla Greens 59-63 Level Range'), +(1000263, 6 , 1035963, 0.2, 4, 'Vanilla Blues 59-63 Level Range'), +(1000263, 7 , 1046063, 0.05, 5, 'Vanilla Purples 60-63 Level Range'), +(1000263, 8 , 1045863, 0.05, 5, 'Vanilla Purples 58-63 Level Range'), +(1000263, 9 , 1076163, 100, 0, 'Vanilla Miscellaneous 61-63 Level Range'), +(1000263, 10, 1075063, 100, 0, 'Vanilla Librams/Cards 50-63 Level Range'), +(1000263, 11, 1085063, 0.5, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000263, 12, 1085663, 0.5, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000263, 13, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +-- (1100258, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +-- (1100258, 2, 1125860, 2, 3, 'TBC Greens 58-60 Level Range'), +-- (1100258, 3, 1135861, 0.1, 4, 'TBC Blues 58-61 Level Range'), +-- (1100259, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +-- (1100259, 2, 1125961, 2, 3, 'TBC Greens 59-61 Level Range'), +-- (1100259, 3, 1125860, 2, 3, 'TBC Greens 58-60 Level Range'), +-- (1100259, 4, 1135861, 0.1, 4, 'TBC Blues 58-61 Level Range'), +-- (1100259, 5, 1135962, 0.1, 4, 'TBC Blues 59-62 Level Range'), +-- (1100260, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +-- (1100260, 2, 1126062, 1.34, 3, 'TBC Greens 60-62 Level Range'), +-- (1100260, 3, 1125961, 1.34, 3, 'TBC Greens 59-61 Level Range'), +-- (1100260, 4, 1125860, 1.34, 3, 'TBC Greens 58-60 Level Range'), +-- (1100260, 5, 1135861, 0.0666, 4, 'TBC Blues 58-61 Level Range'), +-- (1100260, 6, 1135962, 0.0666, 4, 'TBC Blues 59-62 Level Range'), +-- (1100260, 7, 1136063, 0.0666, 4, 'TBC Blues 60-63 Level Range'), +-- (1100261, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +-- (1100261, 2, 1126062, 1.34, 3, 'TBC Greens 60-62 Level Range'), +-- (1100261, 3, 1125961, 1.34, 3, 'TBC Greens 59-61 Level Range'), +-- (1100261, 4, 1126163, 1.34, 3, 'TBC Greens 61-63 Level Range'), +-- (1100261, 5, 1136164, 0.05, 4, 'TBC Blues 61-64 Level Range'), +-- (1100261, 6, 1135861, 0.05, 4, 'TBC Blues 58-61 Level Range'), +-- (1100261, 7, 1135962, 0.05, 4, 'TBC Blues 59-62 Level Range'), +-- (1100261, 8, 1136063, 0.05, 4, 'TBC Blues 60-63 Level Range'), +-- (1100261, 11, 1186165, 100, 0, 'TBC Patterns 61-65 Level Range'), +(1100262, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +(1100262, 2, 1126062, 1.34, 3, 'TBC Greens 60-62 Level Range'), +(1100262, 3, 1126163, 1.34, 3, 'TBC Greens 61-63 Level Range'), +(1100262, 4, 1126264, 1.34, 3, 'TBC Greens 62-64 Level Range'), +(1100262, 5, 1136265, 0.05, 4, 'TBC Blues 62-65 Level Range'), +(1100262, 6, 1136164, 0.05, 4, 'TBC Blues 61-64 Level Range'), +(1100262, 7, 1135962, 0.05, 4, 'TBC Blues 59-62 Level Range'), +(1100262, 8, 1136063, 0.05, 4, 'TBC Blues 60-63 Level Range'), +(1100262, 11, 1186165, 100, 0, 'TBC Patterns 61-65 Level Range'), +(1100263, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +(1100263, 2, 1126365, 1.34, 3, 'TBC Greens 63-65 Level Range'), +(1100263, 3, 1126163, 1.34, 3, 'TBC Greens 61-63 Level Range'), +(1100263, 4, 1126264, 1.34, 3, 'TBC Greens 62-64 Level Range'), +(1100263, 5, 1136265, 0.05, 4, 'TBC Blues 62-65 Level Range'), +(1100263, 6, 1136164, 0.05, 4, 'TBC Blues 61-64 Level Range'), +(1100263, 7, 1136366, 0.05, 4, 'TBC Blues 63-66 Level Range'), +(1100263, 8, 1136063, 0.05, 4, 'TBC Blues 60-63 Level Range'), +(1100263, 11, 1186165, 100, 0, 'TBC Patterns 61-65 Level Range'), +(1100264, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +(1100264, 2, 1126466, 1.34, 3, 'TBC Greens 64-66 Level Range'), +(1100264, 3, 1126365, 1.34, 3, 'TBC Greens 63-65 Level Range'), +(1100264, 4, 1126264, 1.34, 3, 'TBC Greens 62-64 Level Range'), +(1100264, 5, 1136265, 0.05, 4, 'TBC Blues 62-65 Level Range'), +(1100264, 6, 1136164, 0.05, 4, 'TBC Blues 61-64 Level Range'), +(1100264, 7, 1136467, 0.05, 4, 'TBC Blues 64-67 Level Range'), +(1100264, 8, 1136366, 0.05, 4, 'TBC Blues 63-66 Level Range'), +(1100264, 11, 1186165, 100, 0, 'TBC Patterns 61-65 Level Range'), +(1100265, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +(1100265, 2, 1126567, 1.34, 3, 'TBC Greens 65-67 Level Range'), +(1100265, 3, 1126466, 1.34, 3, 'TBC Greens 64-66 Level Range'), +(1100265, 4, 1126365, 1.34, 3, 'TBC Greens 63-65 Level Range'), +(1100265, 5, 1136265, 0.05, 4, 'TBC Blues 62-65 Level Range'), +(1100265, 6, 1136467, 0.05, 4, 'TBC Blues 64-67 Level Range'), +(1100265, 7, 1136568, 0.05, 4, 'TBC Blues 65-68 Level Range'), +(1100265, 8, 1136366, 0.05, 4, 'TBC Blues 63-66 Level Range'), +(1100265, 12, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100265, 13, 1186165, 100, 0, 'TBC Patterns 61-65 Level Range'), +(1100266, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100266, 2, 1126567, 1.34, 3, 'TBC Greens 65-67 Level Range'), +(1100266, 3, 1126668, 1.34, 3, 'TBC Greens 66-68 Level Range'), +(1100266, 4, 1126466, 1.34, 3, 'TBC Greens 64-66 Level Range'), +(1100266, 5, 1136467, 0.05, 4, 'TBC Blues 64-67 Level Range'), +(1100266, 6, 1136568, 0.05, 4, 'TBC Blues 65-68 Level Range'), +(1100266, 7, 1136669, 0.05, 4, 'TBC Blues 66-69 Level Range'), +(1100266, 8, 1136366, 0.05, 4, 'TBC Blues 63-66 Level Range'), +(1100266, 12, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100266, 13, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100267, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100267, 2, 1126567, 1.34, 3, 'TBC Greens 65-67 Level Range'), +(1100267, 3, 1126668, 1.34, 3, 'TBC Greens 66-68 Level Range'), +(1100267, 4, 1126769, 1.34, 3, 'TBC Greens 67-69 Level Range'), +(1100267, 5, 1136467, 0.05, 4, 'TBC Blues 64-67 Level Range'), +(1100267, 6, 1136568, 0.05, 4, 'TBC Blues 65-68 Level Range'), +(1100267, 7, 1136669, 0.05, 4, 'TBC Blues 66-69 Level Range'), +(1100267, 8, 1136770, 0.05, 4, 'TBC Blues 67-70 Level Range'), +(1100267, 9, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100267, 13, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100267, 14, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100268, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100268, 2, 1126668, 1.34, 3, 'TBC Greens 66-68 Level Range'), +(1100268, 3, 1126769, 1.34, 3, 'TBC Greens 67-69 Level Range'), +(1100268, 4, 1126870, 1.34, 3, 'TBC Greens 68-70 Level Range'), +(1100268, 5, 1136568, 0.05, 4, 'TBC Blues 65-68 Level Range'), +(1100268, 6, 1136669, 0.05, 4, 'TBC Blues 66-69 Level Range'), +(1100268, 7, 1136873, 0.05, 4, 'TBC Blues 68-73 Level Range'), +(1100268, 8, 1136770, 0.05, 4, 'TBC Blues 67-70 Level Range'), +(1100268, 9, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100268, 13, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100268, 14, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100269, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100269, 2, 1126971, 1.34, 3, 'TBC Greens 69-71 Level Range'), +(1100269, 3, 1126769, 1.34, 3, 'TBC Greens 67-69 Level Range'), +(1100269, 4, 1126870, 1.34, 3, 'TBC Greens 68-70 Level Range'), +(1100269, 5, 1136669, 0.0666, 4, 'TBC Blues 66-69 Level Range'), +(1100269, 6, 1136873, 0.0666, 4, 'TBC Blues 68-73 Level Range'), +(1100269, 7, 1136770, 0.0666, 4, 'TBC Blues 67-70 Level Range'), +(1100269, 8, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100269, 12, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100269, 13, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100270, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100270, 2, 1126971, 1.34, 3, 'TBC Greens 69-71 Level Range'), +(1100270, 3, 1127072, 1.34, 3, 'TBC Greens 70-72 Level Range'), +(1100270, 4, 1126870, 1.34, 3, 'TBC Greens 68-70 Level Range'), +(1100270, 5, 1136873, 0.1, 4, 'TBC Blues 68-73 Level Range'), +(1100270, 6, 1136770, 0.1, 4, 'TBC Blues 67-70 Level Range'), +(1100270, 7, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100270, 11, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100270, 12, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100271, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100271, 2, 1126971, 1.34, 3, 'TBC Greens 69-71 Level Range'), +(1100271, 3, 1127072, 1.34, 3, 'TBC Greens 70-72 Level Range'), +(1100271, 4, 1127173, 1.34, 3, 'TBC Greens 71-73 Level Range'), +(1100271, 5, 1136873, 0.2, 4, 'TBC Blues 68-73 Level Range'), +(1100271, 6, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100271, 10, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100271, 11, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100272, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100272, 2, 1127072, 2, 3, 'TBC Greens 70-72 Level Range'), +(1100272, 3, 1127173, 2, 3, 'TBC Greens 71-73 Level Range'), +(1100272, 4, 1136873, 0.2, 4, 'TBC Blues 68-73 Level Range'), +(1100272, 5, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100272, 9, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100272, 10, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1000313, 1 , 1001115, 10, 0, 'Vanilla Greys 11-15 Level Range'), +(1000313, 2 , 1011314, 5, 2, 'Vanilla Whites 13-14 Level Range'), +(1000313, 3 , 1011213, 5, 2, 'Vanilla Whites 12-13 Level Range'), +(1000313, 4 , 1021317, 0.5, 3, 'Vanilla Greens 13-17 Level Range'), +(1000313, 5 , 1021115, 0.5, 3, 'Vanilla Greens 11-15 Level Range'), +(1000313, 6 , 1021014, 0.5, 3, 'Vanilla Greens 10-14 Level Range'), +(1000313, 7 , 1021216, 0.5, 3, 'Vanilla Greens 12-16 Level Range'), +(1000313, 8 , 1050614, 3, 0, 'Vanilla Scrolls 6-14 Level Range'), +(1000313, 9 , 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000313, 10, 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000313, 11, 1080620, 0.5, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000313, 12, 1081225, 0.5, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000313, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000314, 1 , 1001115, 10, 0, 'Vanilla Greys 11-15 Level Range'), +(1000314, 2 , 1011314, 5, 2, 'Vanilla Whites 13-14 Level Range'), +(1000314, 3 , 1011415, 5, 2, 'Vanilla Whites 14-15 Level Range'), +(1000314, 4 , 1021317, 0.8, 3, 'Vanilla Greens 13-17 Level Range'), +(1000314, 5 , 1021115, 0.8, 3, 'Vanilla Greens 11-15 Level Range'), +(1000314, 6 , 1021014, 0.8, 3, 'Vanilla Greens 10-14 Level Range'), +(1000314, 7 , 1021216, 0.8, 3, 'Vanilla Greens 12-16 Level Range'), +(1000314, 8 , 1021418, 0.8, 3, 'Vanilla Greens 14-18 Level Range'), +(1000314, 9 , 1050614, 3, 0, 'Vanilla Scrolls 6-14 Level Range'), +(1000314, 10, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000314, 11, 1071114, 100, 0, 'Vanilla Miscellaneous 11-14 Level Range'), +(1000314, 12, 1080620, 0.5, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000314, 13, 1081225, 0.5, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000314, 14, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000315, 1, 1001115, 10, 0, 'Vanilla Greys 11-15 Level Range'), +(1000315, 2, 1011415, 10, 2, 'Vanilla Whites 14-15 Level Range'), +(1000315, 3, 1021317, 0.8, 3, 'Vanilla Greens 13-17 Level Range'), +(1000315, 4, 1021115, 0.8, 3, 'Vanilla Greens 11-15 Level Range'), +(1000315, 5, 1021216, 0.8, 3, 'Vanilla Greens 12-16 Level Range'), +(1000315, 6, 1021418, 0.8, 3, 'Vanilla Greens 14-18 Level Range'), +(1000315, 7, 1021519, 0.8, 3, 'Vanilla Greens 15-19 Level Range'), +(1000315, 8, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000315, 9, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000315, 10, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000315, 11, 1080620, 0.5, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000315, 12, 1081225, 0.5, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000315, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +-- (1000316, 1, 1001620, 10, 0, 'Vanilla Greys 16-20 Level Range'), +-- (1000316, 2, 1021317, 0.8, 3, 'Vanilla Greens 13-17 Level Range'), +-- (1000316, 3, 1021216, 0.8, 3, 'Vanilla Greens 12-16 Level Range'), +-- (1000316, 4, 1021418, 0.8, 3, 'Vanilla Greens 14-18 Level Range'), +-- (1000316, 5, 1021519, 0.8, 3, 'Vanilla Greens 15-19 Level Range'), +-- (1000316, 6, 1021620, 0.8, 3, 'Vanilla Greens 16-20 Level Range'), +-- (1000316, 7, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +-- (1000316, 8, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +-- (1000316, 9, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +-- (1000316, 10, 1080620, 0.33, 6, 'Vanilla Patterns 6-20 Level Range'), +-- (1000316, 11, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +-- (1000316, 12, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +-- (1000316, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000317, 1, 1001620, 10, 0, 'Vanilla Greys 16-20 Level Range'), +(1000317, 2, 1021317, 0.8, 3, 'Vanilla Greens 13-17 Level Range'), +(1000317, 3, 1021418, 0.8, 3, 'Vanilla Greens 14-18 Level Range'), +(1000317, 4, 1021519, 0.8, 3, 'Vanilla Greens 15-19 Level Range'), +(1000317, 5, 1021620, 0.8, 3, 'Vanilla Greens 16-20 Level Range'), +(1000317, 6, 1021721, 0.8, 3, 'Vanilla Greens 17-21 Level Range'), +(1000317, 7, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000317, 8, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000317, 9, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000317, 10, 1080620, 0.33, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000317, 11, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000317, 12, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000317, 13, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000318, 1, 1001620, 10, 0, 'Vanilla Greys 16-20 Level Range'), +(1000318, 2, 1011822, 2, 2, 'Vanilla Whites 18-22 Level Range'), +(1000318, 3, 1021418, 0.8, 3, 'Vanilla Greens 14-18 Level Range'), +(1000318, 4, 1021519, 0.8, 3, 'Vanilla Greens 15-19 Level Range'), +(1000318, 5, 1021620, 0.8, 3, 'Vanilla Greens 16-20 Level Range'), +(1000318, 6, 1021721, 0.8, 3, 'Vanilla Greens 17-21 Level Range'), +(1000318, 7, 1021822, 0.8, 3, 'Vanilla Greens 18-22 Level Range'), +(1000318, 8, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000318, 9, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000318, 10, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000318, 11, 1080620, 0.33, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000318, 12, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000318, 13, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000318, 14, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000319, 1, 1001620, 10, 0, 'Vanilla Greys 16-20 Level Range'), +(1000319, 2, 1011822, 1, 2, 'Vanilla Whites 18-22 Level Range'), +(1000319, 3, 1011923, 1, 2, 'Vanilla Whites 19-23 Level Range'), +(1000319, 4, 1021519, 0.8, 3, 'Vanilla Greens 15-19 Level Range'), +(1000319, 5, 1021620, 0.8, 3, 'Vanilla Greens 16-20 Level Range'), +(1000319, 6, 1021721, 0.8, 3, 'Vanilla Greens 17-21 Level Range'), +(1000319, 7, 1021822, 0.8, 3, 'Vanilla Greens 18-22 Level Range'), +(1000319, 8, 1021923, 0.8, 3, 'Vanilla Greens 19-23 Level Range'), +(1000319, 9, 1031922, 0.2, 4, 'Vanilla Blues 19-22 Level Range'), +(1000319, 10, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000319, 11, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000319, 12, 1071519, 100, 0, 'Vanilla Miscellaneous 15-19 Level Range'), +(1000319, 13, 1080620, 0.33, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000319, 14, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000319, 15, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000319, 16, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000320, 1, 1001620, 10, 0, 'Vanilla Greys 16-20 Level Range'), +(1000320, 2, 1012024, 0.667, 2, 'Vanilla Whites 20-24 Level Range'), +(1000320, 3, 1011822, 0.667, 2, 'Vanilla Whites 18-22 Level Range'), +(1000320, 4, 1011923, 0.667, 2, 'Vanilla Whites 19-23 Level Range'), +(1000320, 5, 1022024, 0.8, 3, 'Vanilla Greens 20-24 Level Range'), +(1000320, 6, 1021620, 0.8, 3, 'Vanilla Greens 16-20 Level Range'), +(1000320, 7, 1021721, 0.8, 3, 'Vanilla Greens 17-21 Level Range'), +(1000320, 8, 1021822, 0.8, 3, 'Vanilla Greens 18-22 Level Range'), +(1000320, 9, 1021923, 0.8, 3, 'Vanilla Greens 19-23 Level Range'), +(1000320, 10, 1032023, 0.1, 4, 'Vanilla Blues 20-23 Level Range'), +(1000320, 11, 1031922, 0.1, 4, 'Vanilla Blues 19-22 Level Range'), +(1000320, 12, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000320, 13, 1061120, 3, 0, 'Vanilla Potions 11-20 Level Range'), +(1000320, 14, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000320, 15, 1080620, 0.25, 6, 'Vanilla Patterns 6-20 Level Range'), +(1000320, 16, 1081225, 0.25, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000320, 17, 1082035, 0.25, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000320, 18, 1081630, 0.25, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000320, 19, 1091120, 0.4, 0, 'Vanilla Bags 11-20 Level Range'), +(1000321, 1, 1002125, 10, 0, 'Vanilla Greys 21-25 Level Range'), +(1000321, 2, 1012024, 0.5, 2, 'Vanilla Whites 20-24 Level Range'), +(1000321, 3, 1012125, 0.5, 2, 'Vanilla Whites 21-25 Level Range'), +(1000321, 4, 1011822, 0.5, 2, 'Vanilla Whites 18-22 Level Range'), +(1000321, 5, 1011923, 0.5, 2, 'Vanilla Whites 19-23 Level Range'), +(1000321, 6, 1022125, 0.8, 3, 'Vanilla Greens 21-25 Level Range'), +(1000321, 7, 1022024, 0.8, 3, 'Vanilla Greens 20-24 Level Range'), +(1000321, 8, 1021721, 0.8, 3, 'Vanilla Greens 17-21 Level Range'), +(1000321, 9, 1021822, 0.8, 3, 'Vanilla Greens 18-22 Level Range'), +(1000321, 10, 1021923, 0.8, 3, 'Vanilla Greens 19-23 Level Range'), +(1000321, 11, 1032124, 0.0667, 4, 'Vanilla Blues 21-24 Level Range'), +(1000321, 12, 1032023, 0.0667, 4, 'Vanilla Blues 20-23 Level Range'), +(1000321, 13, 1031922, 0.0667, 4, 'Vanilla Blues 19-22 Level Range'), +(1000321, 14, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000321, 15, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000321, 16, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000321, 17, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000321, 18, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000321, 19, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000321, 20, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000322, 1, 1002125, 10, 0, 'Vanilla Greys 21-25 Level Range'), +(1000322, 2, 1012024, 0.5, 2, 'Vanilla Whites 20-24 Level Range'), +(1000322, 3, 1012125, 0.5, 2, 'Vanilla Whites 21-25 Level Range'), +(1000322, 4, 1011822, 0.5, 2, 'Vanilla Whites 18-22 Level Range'), +(1000322, 5, 1011923, 0.5, 2, 'Vanilla Whites 19-23 Level Range'), +(1000322, 6, 1022125, 0.8, 3, 'Vanilla Greens 21-25 Level Range'), +(1000322, 7, 1022024, 0.8, 3, 'Vanilla Greens 20-24 Level Range'), +(1000322, 8, 1022226, 0.8, 3, 'Vanilla Greens 22-26 Level Range'), +(1000322, 9, 1021822, 0.8, 3, 'Vanilla Greens 18-22 Level Range'), +(1000322, 10, 1021923, 0.8, 3, 'Vanilla Greens 19-23 Level Range'), +(1000322, 11, 1032124, 0.05, 4, 'Vanilla Blues 21-24 Level Range'), +(1000322, 12, 1032023, 0.05, 4, 'Vanilla Blues 20-23 Level Range'), +(1000322, 13, 1032225, 0.05, 4, 'Vanilla Blues 22-25 Level Range'), +(1000322, 14, 1031922, 0.05, 4, 'Vanilla Blues 19-22 Level Range'), +(1000322, 15, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000322, 16, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000322, 17, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000322, 18, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000322, 19, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000322, 20, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000322, 21, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000323, 1, 1002125, 10, 0, 'Vanilla Greys 21-25 Level Range'), +(1000323, 2, 1012024, 0.667, 2, 'Vanilla Whites 20-24 Level Range'), +(1000323, 3, 1012125, 0.667, 2, 'Vanilla Whites 21-25 Level Range'), +(1000323, 4, 1011923, 0.667, 2, 'Vanilla Whites 19-23 Level Range'), +(1000323, 5, 1022327, 0.8, 3, 'Vanilla Greens 23-27 Level Range'), +(1000323, 6, 1022125, 0.8, 3, 'Vanilla Greens 21-25 Level Range'), +(1000323, 7, 1022024, 0.8, 3, 'Vanilla Greens 20-24 Level Range'), +(1000323, 8, 1022226, 0.8, 3, 'Vanilla Greens 22-26 Level Range'), +(1000323, 9, 1021923, 0.8, 3, 'Vanilla Greens 19-23 Level Range'), +(1000323, 10, 1032124, 0.05, 4, 'Vanilla Blues 21-24 Level Range'), +(1000323, 11, 1032023, 0.05, 4, 'Vanilla Blues 20-23 Level Range'), +(1000323, 12, 1032225, 0.05, 4, 'Vanilla Blues 22-25 Level Range'), +(1000323, 13, 1032326, 0.05, 4, 'Vanilla Blues 23-26 Level Range'), +(1000323, 14, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000323, 15, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000323, 16, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000323, 17, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000323, 18, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000323, 19, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000323, 20, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000324, 1, 1002125, 10, 0, 'Vanilla Greys 21-25 Level Range'), +(1000324, 2, 1012024, 1, 2, 'Vanilla Whites 20-24 Level Range'), +(1000324, 3, 1012125, 1, 2, 'Vanilla Whites 21-25 Level Range'), +(1000324, 4, 1022327, 0.8, 3, 'Vanilla Greens 23-27 Level Range'), +(1000324, 5, 1022428, 0.8, 3, 'Vanilla Greens 24-28 Level Range'), +(1000324, 6, 1022125, 0.8, 3, 'Vanilla Greens 21-25 Level Range'), +(1000324, 7, 1022024, 0.8, 3, 'Vanilla Greens 20-24 Level Range'), +(1000324, 8, 1022226, 0.8, 3, 'Vanilla Greens 22-26 Level Range'), +(1000324, 9, 1032427, 0.05, 4, 'Vanilla Blues 24-27 Level Range'), +(1000324, 10, 1032124, 0.05, 4, 'Vanilla Blues 21-24 Level Range'), +(1000324, 11, 1032225, 0.05, 4, 'Vanilla Blues 22-25 Level Range'), +(1000324, 12, 1032326, 0.05, 4, 'Vanilla Blues 23-26 Level Range'), +(1000324, 13, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000324, 14, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000324, 15, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000324, 16, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000324, 17, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000324, 18, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000324, 19, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000325, 1, 1002125, 10, 0, 'Vanilla Greys 21-25 Level Range'), +(1000325, 2, 1012125, 2, 2, 'Vanilla Whites 21-25 Level Range'), +(1000325, 3, 1022327, 0.8, 3, 'Vanilla Greens 23-27 Level Range'), +(1000325, 4, 1022428, 0.8, 3, 'Vanilla Greens 24-28 Level Range'), +(1000325, 5, 1022125, 0.8, 3, 'Vanilla Greens 21-25 Level Range'), +(1000325, 6, 1022226, 0.8, 3, 'Vanilla Greens 22-26 Level Range'), +(1000325, 7, 1022529, 0.8, 3, 'Vanilla Greens 25-29 Level Range'), +(1000325, 8, 1032427, 0.05, 4, 'Vanilla Blues 24-27 Level Range'), +(1000325, 9, 1032528, 0.05, 4, 'Vanilla Blues 25-28 Level Range'), +(1000325, 10, 1032225, 0.05, 4, 'Vanilla Blues 22-25 Level Range'), +(1000325, 11, 1032326, 0.05, 4, 'Vanilla Blues 23-26 Level Range'), +(1000325, 12, 1051525, 1, 0, 'Vanilla Scrolls 15-25 Level Range'), +(1000325, 13, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000325, 14, 1072025, 100, 0, 'Vanilla Miscellaneous 20-25 Level Range'), +(1000325, 15, 1081225, 0.33, 6, 'Vanilla Patterns 12-25 Level Range'), +(1000325, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000325, 17, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000325, 18, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000326, 1, 1002630, 10, 0, 'Vanilla Greys 26-30 Level Range'), +(1000326, 2, 1022327, 0.8, 3, 'Vanilla Greens 23-27 Level Range'), +(1000326, 3, 1022428, 0.8, 3, 'Vanilla Greens 24-28 Level Range'), +(1000326, 4, 1022630, 0.8, 3, 'Vanilla Greens 26-30 Level Range'), +(1000326, 5, 1022226, 0.8, 3, 'Vanilla Greens 22-26 Level Range'), +(1000326, 6, 1022529, 0.8, 3, 'Vanilla Greens 25-29 Level Range'), +(1000326, 7, 1032427, 0.05, 4, 'Vanilla Blues 24-27 Level Range'), +(1000326, 8, 1032528, 0.05, 4, 'Vanilla Blues 25-28 Level Range'), +(1000326, 9, 1032629, 0.05, 4, 'Vanilla Blues 26-29 Level Range'), +(1000326, 10, 1032326, 0.05, 4, 'Vanilla Blues 23-26 Level Range'), +(1000326, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000326, 12, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000326, 13, 1072627, 100, 0, 'Vanilla Miscellaneous 26-27 Level Range'), +(1000326, 14, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000326, 15, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000326, 16, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000326, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000327, 1, 1002630, 10, 0, 'Vanilla Greys 26-30 Level Range'), +(1000327, 2, 1022731, 0.8, 3, 'Vanilla Greens 27-31 Level Range'), +(1000327, 3, 1022327, 0.8, 3, 'Vanilla Greens 23-27 Level Range'), +(1000327, 4, 1022428, 0.8, 3, 'Vanilla Greens 24-28 Level Range'), +(1000327, 5, 1022630, 0.8, 3, 'Vanilla Greens 26-30 Level Range'), +(1000327, 6, 1022529, 0.8, 3, 'Vanilla Greens 25-29 Level Range'), +(1000327, 7, 1032427, 0.05, 4, 'Vanilla Blues 24-27 Level Range'), +(1000327, 8, 1032528, 0.05, 4, 'Vanilla Blues 25-28 Level Range'), +(1000327, 9, 1032629, 0.05, 4, 'Vanilla Blues 26-29 Level Range'), +(1000327, 10, 1032730, 0.05, 4, 'Vanilla Blues 27-30 Level Range'), +(1000327, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000327, 12, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000327, 13, 1072627, 100, 0, 'Vanilla Miscellaneous 26-27 Level Range'), +(1000327, 14, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000327, 15, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000327, 16, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000327, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000328, 1, 1002630, 10, 0, 'Vanilla Greys 26-30 Level Range'), +(1000328, 2, 1022731, 0.8, 3, 'Vanilla Greens 27-31 Level Range'), +(1000328, 3, 1022832, 0.8, 3, 'Vanilla Greens 28-32 Level Range'), +(1000328, 4, 1022428, 0.8, 3, 'Vanilla Greens 24-28 Level Range'), +(1000328, 5, 1022630, 0.8, 3, 'Vanilla Greens 26-30 Level Range'), +(1000328, 6, 1022529, 0.8, 3, 'Vanilla Greens 25-29 Level Range'), +(1000328, 7, 1032528, 0.05, 4, 'Vanilla Blues 25-28 Level Range'), +(1000328, 8, 1032831, 0.05, 4, 'Vanilla Blues 28-31 Level Range'), +(1000328, 9, 1032629, 0.05, 4, 'Vanilla Blues 26-29 Level Range'), +(1000328, 10, 1032730, 0.05, 4, 'Vanilla Blues 27-30 Level Range'), +(1000328, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000328, 12, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000328, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +(1000328, 14, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000328, 15, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000328, 16, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000328, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +-- (1000329, 1, 1002630, 10, 0, 'Vanilla Greys 26-30 Level Range'), +-- (1000329, 2, 1022731, 0.8, 3, 'Vanilla Greens 27-31 Level Range'), +-- (1000329, 3, 1022832, 0.8, 3, 'Vanilla Greens 28-32 Level Range'), +-- (1000329, 4, 1022933, 0.8, 3, 'Vanilla Greens 29-33 Level Range'), +-- (1000329, 5, 1022630, 0.8, 3, 'Vanilla Greens 26-30 Level Range'), +-- (1000329, 6, 1022529, 0.8, 3, 'Vanilla Greens 25-29 Level Range'), +-- (1000329, 7, 1032932, 0.05, 4, 'Vanilla Blues 29-32 Level Range'), +-- (1000329, 8, 1032831, 0.05, 4, 'Vanilla Blues 28-31 Level Range'), +-- (1000329, 9, 1032629, 0.05, 4, 'Vanilla Blues 26-29 Level Range'), +-- (1000329, 10, 1032730, 0.05, 4, 'Vanilla Blues 27-30 Level Range'), +-- (1000329, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +-- (1000329, 12, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +-- (1000329, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +-- (1000329, 14, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +-- (1000329, 15, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +-- (1000329, 16, 1081630, 0.33, 6, 'Vanilla Patterns 16-30 Level Range'), +-- (1000329, 17, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000330, 1, 1002630, 10, 0, 'Vanilla Greys 26-30 Level Range'), +(1000330, 2, 1023034, 0.8, 3, 'Vanilla Greens 30-34 Level Range'), +(1000330, 3, 1022731, 0.8, 3, 'Vanilla Greens 27-31 Level Range'), +(1000330, 4, 1022832, 0.8, 3, 'Vanilla Greens 28-32 Level Range'), +(1000330, 5, 1022933, 0.8, 3, 'Vanilla Greens 29-33 Level Range'), +(1000330, 6, 1022630, 0.8, 3, 'Vanilla Greens 26-30 Level Range'), +(1000330, 7, 1032932, 0.05, 4, 'Vanilla Blues 29-32 Level Range'), +(1000330, 8, 1032831, 0.05, 4, 'Vanilla Blues 28-31 Level Range'), +(1000330, 9, 1033033, 0.05, 4, 'Vanilla Blues 30-33 Level Range'), +(1000330, 10, 1032730, 0.05, 4, 'Vanilla Blues 27-30 Level Range'), +(1000330, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000330, 12, 1062130, 3, 0, 'Vanilla Potions 21-30 Level Range'), +(1000330, 13, 1072830, 100, 0, 'Vanilla Miscellaneous 28-30 Level Range'), +(1000330, 14, 1083045, 0.25, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000330, 15, 1082640, 0.25, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000330, 16, 1082035, 0.25, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000330, 17, 1081630, 0.25, 6, 'Vanilla Patterns 16-30 Level Range'), +(1000330, 18, 1092130, 0.3, 0, 'Vanilla Bags 21-30 Level Range'), +(1000331, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000331, 2, 1023034, 0.8, 3, 'Vanilla Greens 30-34 Level Range'), +(1000331, 3, 1023135, 0.8, 3, 'Vanilla Greens 31-35 Level Range'), +(1000331, 4, 1022731, 0.8, 3, 'Vanilla Greens 27-31 Level Range'), +(1000331, 5, 1022832, 0.8, 3, 'Vanilla Greens 28-32 Level Range'), +(1000331, 6, 1022933, 0.8, 3, 'Vanilla Greens 29-33 Level Range'), +(1000331, 7, 1033134, 0.05, 4, 'Vanilla Blues 31-34 Level Range'), +(1000331, 8, 1032932, 0.05, 4, 'Vanilla Blues 29-32 Level Range'), +(1000331, 9, 1032831, 0.05, 4, 'Vanilla Blues 28-31 Level Range'), +(1000331, 10, 1033033, 0.05, 4, 'Vanilla Blues 30-33 Level Range'), +(1000331, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000331, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000331, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000331, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000331, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000331, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000331, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000332, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000332, 2, 1023034, 0.8, 3, 'Vanilla Greens 30-34 Level Range'), +(1000332, 3, 1023135, 0.8, 3, 'Vanilla Greens 31-35 Level Range'), +(1000332, 4, 1022832, 0.8, 3, 'Vanilla Greens 28-32 Level Range'), +(1000332, 5, 1022933, 0.8, 3, 'Vanilla Greens 29-33 Level Range'), +(1000332, 6, 1023236, 0.8, 3, 'Vanilla Greens 32-36 Level Range'), +(1000332, 7, 1033134, 0.05, 4, 'Vanilla Blues 31-34 Level Range'), +(1000332, 8, 1032932, 0.05, 4, 'Vanilla Blues 29-32 Level Range'), +(1000332, 9, 1033235, 0.05, 4, 'Vanilla Blues 32-35 Level Range'), +(1000332, 10, 1033033, 0.05, 4, 'Vanilla Blues 30-33 Level Range'), +(1000332, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000332, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000332, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000332, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000332, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000332, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000332, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000333, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000333, 2, 1023034, 0.8, 3, 'Vanilla Greens 30-34 Level Range'), +(1000333, 3, 1023135, 0.8, 3, 'Vanilla Greens 31-35 Level Range'), +(1000333, 4, 1022933, 0.8, 3, 'Vanilla Greens 29-33 Level Range'), +(1000333, 5, 1023337, 0.8, 3, 'Vanilla Greens 33-37 Level Range'), +(1000333, 6, 1023236, 0.8, 3, 'Vanilla Greens 32-36 Level Range'), +(1000333, 7, 1033134, 0.05, 4, 'Vanilla Blues 31-34 Level Range'), +(1000333, 8, 1033336, 0.05, 4, 'Vanilla Blues 33-36 Level Range'), +(1000333, 9, 1033235, 0.05, 4, 'Vanilla Blues 32-35 Level Range'), +(1000333, 10, 1033033, 0.05, 4, 'Vanilla Blues 30-33 Level Range'), +(1000333, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000333, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000333, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000333, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000333, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000333, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000333, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000334, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000334, 2, 1023034, 0.8, 3, 'Vanilla Greens 30-34 Level Range'), +(1000334, 3, 1023438, 0.8, 3, 'Vanilla Greens 34-38 Level Range'), +(1000334, 4, 1023135, 0.8, 3, 'Vanilla Greens 31-35 Level Range'), +(1000334, 5, 1023337, 0.8, 3, 'Vanilla Greens 33-37 Level Range'), +(1000334, 6, 1023236, 0.8, 3, 'Vanilla Greens 32-36 Level Range'), +(1000334, 7, 1033134, 0.05, 4, 'Vanilla Blues 31-34 Level Range'), +(1000334, 8, 1033336, 0.05, 4, 'Vanilla Blues 33-36 Level Range'), +(1000334, 9, 1033437, 0.05, 4, 'Vanilla Blues 34-37 Level Range'), +(1000334, 10, 1033235, 0.05, 4, 'Vanilla Blues 32-35 Level Range'), +(1000334, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000334, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000334, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000334, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000334, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000334, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000334, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000335, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000335, 2, 1023438, 0.8, 3, 'Vanilla Greens 34-38 Level Range'), +(1000335, 3, 1023135, 0.8, 3, 'Vanilla Greens 31-35 Level Range'), +(1000335, 4, 1023337, 0.8, 3, 'Vanilla Greens 33-37 Level Range'), +(1000335, 5, 1023539, 0.8, 3, 'Vanilla Greens 35-39 Level Range'), +(1000335, 6, 1023236, 0.8, 3, 'Vanilla Greens 32-36 Level Range'), +(1000335, 7, 1033336, 0.05, 4, 'Vanilla Blues 33-36 Level Range'), +(1000335, 8, 1033437, 0.05, 4, 'Vanilla Blues 34-37 Level Range'), +(1000335, 9, 1033235, 0.05, 4, 'Vanilla Blues 32-35 Level Range'), +(1000335, 10, 1033538, 0.05, 4, 'Vanilla Blues 35-38 Level Range'), +(1000335, 11, 1052635, 1, 0, 'Vanilla Scrolls 26-35 Level Range'), +(1000335, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000335, 13, 1073135, 100, 0, 'Vanilla Miscellaneous 31-35 Level Range'), +(1000335, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000335, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000335, 16, 1082035, 0.33, 6, 'Vanilla Patterns 20-35 Level Range'), +(1000335, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000336, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000336, 2, 1023438, 0.8, 3, 'Vanilla Greens 34-38 Level Range'), +(1000336, 3, 1023640, 0.8, 3, 'Vanilla Greens 36-40 Level Range'), +(1000336, 4, 1023337, 0.8, 3, 'Vanilla Greens 33-37 Level Range'), +(1000336, 5, 1023539, 0.8, 3, 'Vanilla Greens 35-39 Level Range'), +(1000336, 6, 1023236, 0.8, 3, 'Vanilla Greens 32-36 Level Range'), +(1000336, 7, 1033639, 0.05, 4, 'Vanilla Blues 36-39 Level Range'), +(1000336, 8, 1033336, 0.05, 4, 'Vanilla Blues 33-36 Level Range'), +(1000336, 9, 1033437, 0.05, 4, 'Vanilla Blues 34-37 Level Range'), +(1000336, 10, 1033538, 0.05, 4, 'Vanilla Blues 35-38 Level Range'), +(1000336, 11, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000336, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000336, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000336, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000336, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000336, 16, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000336, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000337, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000337, 2, 1023438, 0.8, 3, 'Vanilla Greens 34-38 Level Range'), +(1000337, 3, 1023640, 0.8, 3, 'Vanilla Greens 36-40 Level Range'), +(1000337, 4, 1023741, 0.8, 3, 'Vanilla Greens 37-41 Level Range'), +(1000337, 5, 1023337, 0.8, 3, 'Vanilla Greens 33-37 Level Range'), +(1000337, 6, 1023539, 0.8, 3, 'Vanilla Greens 35-39 Level Range'), +(1000337, 7, 1033639, 0.05, 4, 'Vanilla Blues 36-39 Level Range'), +(1000337, 8, 1033740, 0.05, 4, 'Vanilla Blues 37-40 Level Range'), +(1000337, 9, 1033437, 0.05, 4, 'Vanilla Blues 34-37 Level Range'), +(1000337, 10, 1033538, 0.05, 4, 'Vanilla Blues 35-38 Level Range'), +(1000337, 11, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000337, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000337, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000337, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000337, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000337, 16, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000337, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000338, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000338, 2, 1023438, 0.8, 3, 'Vanilla Greens 34-38 Level Range'), +(1000338, 3, 1023640, 0.8, 3, 'Vanilla Greens 36-40 Level Range'), +(1000338, 4, 1023741, 0.8, 3, 'Vanilla Greens 37-41 Level Range'), +(1000338, 5, 1023842, 0.8, 3, 'Vanilla Greens 38-42 Level Range'), +(1000338, 6, 1023539, 0.8, 3, 'Vanilla Greens 35-39 Level Range'), +(1000338, 7, 1033841, 0.05, 4, 'Vanilla Blues 38-41 Level Range'), +(1000338, 8, 1033639, 0.05, 4, 'Vanilla Blues 36-39 Level Range'), +(1000338, 9, 1033740, 0.05, 4, 'Vanilla Blues 37-40 Level Range'), +(1000338, 10, 1033538, 0.05, 4, 'Vanilla Blues 35-38 Level Range'), +(1000338, 11, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000338, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000338, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000338, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000338, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000338, 16, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000338, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +(1000339, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +(1000339, 2, 1023640, 0.8, 3, 'Vanilla Greens 36-40 Level Range'), +(1000339, 3, 1023741, 0.8, 3, 'Vanilla Greens 37-41 Level Range'), +(1000339, 4, 1023842, 0.8, 3, 'Vanilla Greens 38-42 Level Range'), +(1000339, 5, 1023943, 0.8, 3, 'Vanilla Greens 39-43 Level Range'), +(1000339, 6, 1023539, 0.8, 3, 'Vanilla Greens 35-39 Level Range'), +(1000339, 7, 1033841, 0.05, 4, 'Vanilla Blues 38-41 Level Range'), +(1000339, 8, 1033639, 0.05, 4, 'Vanilla Blues 36-39 Level Range'), +(1000339, 9, 1033740, 0.05, 4, 'Vanilla Blues 37-40 Level Range'), +(1000339, 10, 1033942, 0.05, 4, 'Vanilla Blues 39-42 Level Range'), +(1000339, 11, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000339, 12, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +(1000339, 13, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +(1000339, 14, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000339, 15, 1082640, 0.33, 6, 'Vanilla Patterns 26-40 Level Range'), +(1000339, 16, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000339, 17, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +-- (1000340, 1, 1003140, 10, 0, 'Vanilla Greys 31-40 Level Range'), +-- (1000340, 2, 1023640, 0.8, 3, 'Vanilla Greens 36-40 Level Range'), +-- (1000340, 3, 1023741, 0.8, 3, 'Vanilla Greens 37-41 Level Range'), +-- (1000340, 4, 1023842, 0.8, 3, 'Vanilla Greens 38-42 Level Range'), +-- (1000340, 5, 1023943, 0.8, 3, 'Vanilla Greens 39-43 Level Range'), +-- (1000340, 6, 1024044, 0.8, 3, 'Vanilla Greens 40-44 Level Range'), +-- (1000340, 7, 1033841, 0.05, 4, 'Vanilla Blues 38-41 Level Range'), +-- (1000340, 8, 1033740, 0.05, 4, 'Vanilla Blues 37-40 Level Range'), +-- (1000340, 9, 1034043, 0.05, 4, 'Vanilla Blues 40-43 Level Range'), +-- (1000340, 10, 1033942, 0.05, 4, 'Vanilla Blues 39-42 Level Range'), +-- (1000340, 11, 1044046, 0.05, 5, 'Vanilla Purples 40-46 Level Range'), +-- (1000340, 12, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +-- (1000340, 13, 1063140, 3, 0, 'Vanilla Potions 31-40 Level Range'), +-- (1000340, 14, 1073640, 100, 0, 'Vanilla Miscellaneous 36-40 Level Range'), +-- (1000340, 15, 1083045, 0.25, 6, 'Vanilla Patterns 30-45 Level Range'), +-- (1000340, 16, 1082640, 0.25, 6, 'Vanilla Patterns 26-40 Level Range'), +-- (1000340, 17, 1083650, 0.25, 6, 'Vanilla Patterns 36-50 Level Range'), +-- (1000340, 18, 1084055, 0.25, 6, 'Vanilla Patterns 40-55 Level Range'), +-- (1000340, 19, 1093140, 0.2, 0, 'Vanilla Bags 31-40 Level Range'), +-- (1000341, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +-- (1000341, 2, 1024145, 0.8, 3, 'Vanilla Greens 41-45 Level Range'), +-- (1000341, 3, 1023741, 0.8, 3, 'Vanilla Greens 37-41 Level Range'), +-- (1000341, 4, 1023842, 0.8, 3, 'Vanilla Greens 38-42 Level Range'), +-- (1000341, 5, 1023943, 0.8, 3, 'Vanilla Greens 39-43 Level Range'), +-- (1000341, 6, 1024044, 0.8, 3, 'Vanilla Greens 40-44 Level Range'), +-- (1000341, 7, 1033841, 0.05, 4, 'Vanilla Blues 38-41 Level Range'), +-- (1000341, 8, 1034043, 0.05, 4, 'Vanilla Blues 40-43 Level Range'), +-- (1000341, 9, 1033942, 0.05, 4, 'Vanilla Blues 39-42 Level Range'), +-- (1000341, 10, 1034144, 0.05, 4, 'Vanilla Blues 41-44 Level Range'), +-- (1000341, 11, 1044046, 0.05, 5, 'Vanilla Purples 40-46 Level Range'), +-- (1000341, 12, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +-- (1000341, 13, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +-- (1000341, 14, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +-- (1000341, 15, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +-- (1000341, 16, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +-- (1000341, 17, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +-- (1000341, 18, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000342, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000342, 2, 1024145, 0.8, 3, 'Vanilla Greens 41-45 Level Range'), +(1000342, 3, 1024246, 0.8, 3, 'Vanilla Greens 42-46 Level Range'), +(1000342, 4, 1023842, 0.8, 3, 'Vanilla Greens 38-42 Level Range'), +(1000342, 5, 1023943, 0.8, 3, 'Vanilla Greens 39-43 Level Range'), +(1000342, 6, 1024044, 0.8, 3, 'Vanilla Greens 40-44 Level Range'), +(1000342, 7, 1034245, 0.05, 4, 'Vanilla Blues 42-45 Level Range'), +(1000342, 8, 1034043, 0.05, 4, 'Vanilla Blues 40-43 Level Range'), +(1000342, 9, 1033942, 0.05, 4, 'Vanilla Blues 39-42 Level Range'), +(1000342, 10, 1034144, 0.05, 4, 'Vanilla Blues 41-44 Level Range'), +(1000342, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +(1000342, 12, 1044046, 0.025, 5, 'Vanilla Purples 40-46 Level Range'), +(1000342, 13, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000342, 14, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000342, 15, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000342, 16, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000342, 17, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000342, 18, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000342, 19, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000343, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000343, 2, 1024145, 0.8, 3, 'Vanilla Greens 41-45 Level Range'), +(1000343, 3, 1024347, 0.8, 3, 'Vanilla Greens 43-47 Level Range'), +(1000343, 4, 1024246, 0.8, 3, 'Vanilla Greens 42-46 Level Range'), +(1000343, 5, 1023943, 0.8, 3, 'Vanilla Greens 39-43 Level Range'), +(1000343, 6, 1024044, 0.8, 3, 'Vanilla Greens 40-44 Level Range'), +(1000343, 7, 1034245, 0.05, 4, 'Vanilla Blues 42-45 Level Range'), +(1000343, 8, 1034346, 0.05, 4, 'Vanilla Blues 43-46 Level Range'), +(1000343, 9, 1034043, 0.05, 4, 'Vanilla Blues 40-43 Level Range'), +(1000343, 10, 1034144, 0.05, 4, 'Vanilla Blues 41-44 Level Range'), +(1000343, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +(1000343, 12, 1044046, 0.025, 5, 'Vanilla Purples 40-46 Level Range'), +(1000343, 13, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000343, 14, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000343, 15, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000343, 16, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000343, 17, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000343, 18, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000343, 19, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000344, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000344, 2, 1024145, 0.8, 3, 'Vanilla Greens 41-45 Level Range'), +(1000344, 3, 1024347, 0.8, 3, 'Vanilla Greens 43-47 Level Range'), +(1000344, 4, 1024448, 0.8, 3, 'Vanilla Greens 44-48 Level Range'), +(1000344, 5, 1024246, 0.8, 3, 'Vanilla Greens 42-46 Level Range'), +(1000344, 6, 1024044, 0.8, 3, 'Vanilla Greens 40-44 Level Range'), +(1000344, 7, 1034245, 0.05, 4, 'Vanilla Blues 42-45 Level Range'), +(1000344, 8, 1034447, 0.05, 4, 'Vanilla Blues 44-47 Level Range'), +(1000344, 9, 1034346, 0.05, 4, 'Vanilla Blues 43-46 Level Range'), +(1000344, 10, 1034144, 0.05, 4, 'Vanilla Blues 41-44 Level Range'), +(1000344, 11, 1044248, 0.0334, 5, 'Vanilla Purples 42-48 Level Range'), +(1000344, 12, 1044046, 0.0334, 5, 'Vanilla Purples 40-46 Level Range'), +(1000344, 13, 1044450, 0.0334, 5, 'Vanilla Purples 44-50 Level Range'), +(1000344, 14, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000344, 15, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000344, 16, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000344, 17, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000344, 18, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000344, 19, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000344, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000345, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000345, 2, 1024145, 0.8, 3, 'Vanilla Greens 41-45 Level Range'), +(1000345, 3, 1024347, 0.8, 3, 'Vanilla Greens 43-47 Level Range'), +(1000345, 4, 1024448, 0.8, 3, 'Vanilla Greens 44-48 Level Range'), +(1000345, 5, 1024549, 0.8, 3, 'Vanilla Greens 45-49 Level Range'), +(1000345, 6, 1024246, 0.8, 3, 'Vanilla Greens 42-46 Level Range'), +(1000345, 7, 1034245, 0.05, 4, 'Vanilla Blues 42-45 Level Range'), +(1000345, 8, 1034447, 0.05, 4, 'Vanilla Blues 44-47 Level Range'), +(1000345, 9, 1034346, 0.05, 4, 'Vanilla Blues 43-46 Level Range'), +(1000345, 10, 1034548, 0.05, 4, 'Vanilla Blues 45-48 Level Range'), +(1000345, 11, 1044248, 0.0334, 5, 'Vanilla Purples 42-48 Level Range'), +(1000345, 12, 1044046, 0.0334, 5, 'Vanilla Purples 40-46 Level Range'), +(1000345, 13, 1044450, 0.0334, 5, 'Vanilla Purples 44-50 Level Range'), +(1000345, 14, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000345, 15, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000345, 16, 1074145, 100, 0, 'Vanilla Miscellaneous 41-45 Level Range'), +(1000345, 17, 1083045, 0.33, 6, 'Vanilla Patterns 30-45 Level Range'), +(1000345, 18, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000345, 19, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000345, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000346, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000346, 2, 1024347, 0.8, 3, 'Vanilla Greens 43-47 Level Range'), +(1000346, 3, 1024448, 0.8, 3, 'Vanilla Greens 44-48 Level Range'), +(1000346, 4, 1024549, 0.8, 3, 'Vanilla Greens 45-49 Level Range'), +(1000346, 5, 1024246, 0.8, 3, 'Vanilla Greens 42-46 Level Range'), +(1000346, 6, 1024650, 0.8, 3, 'Vanilla Greens 46-50 Level Range'), +(1000346, 7, 1034447, 0.05, 4, 'Vanilla Blues 44-47 Level Range'), +(1000346, 8, 1034346, 0.05, 4, 'Vanilla Blues 43-46 Level Range'), +(1000346, 9, 1034649, 0.05, 4, 'Vanilla Blues 46-49 Level Range'), +(1000346, 10, 1034548, 0.05, 4, 'Vanilla Blues 45-48 Level Range'), +(1000346, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +(1000346, 12, 1044046, 0.025, 5, 'Vanilla Purples 40-46 Level Range'), +(1000346, 13, 1044450, 0.025, 5, 'Vanilla Purples 44-50 Level Range'), +(1000346, 14, 1044652, 0.025, 5, 'Vanilla Purples 46-52 Level Range'), +(1000346, 15, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000346, 16, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000346, 17, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000346, 18, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000346, 19, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000346, 20, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000346, 21, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000347, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000347, 2, 1024347, 0.8, 3, 'Vanilla Greens 43-47 Level Range'), +(1000347, 3, 1024448, 0.8, 3, 'Vanilla Greens 44-48 Level Range'), +(1000347, 4, 1024549, 0.8, 3, 'Vanilla Greens 45-49 Level Range'), +(1000347, 5, 1024751, 0.8, 3, 'Vanilla Greens 47-51 Level Range'), +(1000347, 6, 1024650, 0.8, 3, 'Vanilla Greens 46-50 Level Range'), +(1000347, 7, 1034447, 0.05, 4, 'Vanilla Blues 44-47 Level Range'), +(1000347, 8, 1034649, 0.05, 4, 'Vanilla Blues 46-49 Level Range'), +(1000347, 9, 1034548, 0.05, 4, 'Vanilla Blues 45-48 Level Range'), +(1000347, 10, 1034750, 0.05, 4, 'Vanilla Blues 47-50 Level Range'), +(1000347, 11, 1044248, 0.0334, 5, 'Vanilla Purples 42-48 Level Range'), +(1000347, 12, 1044450, 0.0334, 5, 'Vanilla Purples 44-50 Level Range'), +(1000347, 13, 1044652, 0.0334, 5, 'Vanilla Purples 46-52 Level Range'), +(1000347, 14, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000347, 15, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000347, 16, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000347, 17, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000347, 18, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000347, 19, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000347, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000348, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000348, 2, 1024448, 0.8, 3, 'Vanilla Greens 44-48 Level Range'), +(1000348, 3, 1024549, 0.8, 3, 'Vanilla Greens 45-49 Level Range'), +(1000348, 4, 1024751, 0.8, 3, 'Vanilla Greens 47-51 Level Range'), +(1000348, 5, 1024852, 0.8, 3, 'Vanilla Greens 48-52 Level Range'), +(1000348, 6, 1024650, 0.8, 3, 'Vanilla Greens 46-50 Level Range'), +(1000348, 7, 1034649, 0.05, 4, 'Vanilla Blues 46-49 Level Range'), +(1000348, 8, 1034548, 0.05, 4, 'Vanilla Blues 45-48 Level Range'), +(1000348, 9, 1034851, 0.05, 4, 'Vanilla Blues 48-51 Level Range'), +(1000348, 10, 1034750, 0.05, 4, 'Vanilla Blues 47-50 Level Range'), +(1000348, 11, 1044248, 0.025, 5, 'Vanilla Purples 42-48 Level Range'), +(1000348, 12, 1044854, 0.025, 5, 'Vanilla Purples 48-54 Level Range'), +(1000348, 13, 1044450, 0.025, 5, 'Vanilla Purples 44-50 Level Range'), +(1000348, 14, 1044652, 0.025, 5, 'Vanilla Purples 46-52 Level Range'), +(1000348, 15, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000348, 16, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000348, 17, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000348, 18, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000348, 19, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000348, 20, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000348, 21, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000349, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000349, 2, 1024549, 0.8, 3, 'Vanilla Greens 45-49 Level Range'), +(1000349, 3, 1024751, 0.8, 3, 'Vanilla Greens 47-51 Level Range'), +(1000349, 4, 1024852, 0.8, 3, 'Vanilla Greens 48-52 Level Range'), +(1000349, 5, 1024953, 0.8, 3, 'Vanilla Greens 49-53 Level Range'), +(1000349, 6, 1024650, 0.8, 3, 'Vanilla Greens 46-50 Level Range'), +(1000349, 7, 1034649, 0.05, 4, 'Vanilla Blues 46-49 Level Range'), +(1000349, 8, 1034952, 0.05, 4, 'Vanilla Blues 49-52 Level Range'), +(1000349, 9, 1034851, 0.05, 4, 'Vanilla Blues 48-51 Level Range'), +(1000349, 10, 1034750, 0.05, 4, 'Vanilla Blues 47-50 Level Range'), +(1000349, 11, 1044854, 0.0334, 5, 'Vanilla Purples 48-54 Level Range'), +(1000349, 12, 1044450, 0.0334, 5, 'Vanilla Purples 44-50 Level Range'), +(1000349, 13, 1044652, 0.0334, 5, 'Vanilla Purples 46-52 Level Range'), +(1000349, 14, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000349, 15, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000349, 16, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000349, 17, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000349, 18, 1083650, 0.33, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000349, 19, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000349, 20, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000350, 1, 1004150, 10, 0, 'Vanilla Greys 41-50 Level Range'), +(1000350, 2, 1024751, 0.8, 3, 'Vanilla Greens 47-51 Level Range'), +(1000350, 3, 1025054, 0.8, 3, 'Vanilla Greens 50-54 Level Range'), +(1000350, 4, 1024852, 0.8, 3, 'Vanilla Greens 48-52 Level Range'), +(1000350, 5, 1024953, 0.8, 3, 'Vanilla Greens 49-53 Level Range'), +(1000350, 6, 1024650, 0.8, 3, 'Vanilla Greens 46-50 Level Range'), +(1000350, 7, 1034952, 0.05, 4, 'Vanilla Blues 49-52 Level Range'), +(1000350, 8, 1034851, 0.05, 4, 'Vanilla Blues 48-51 Level Range'), +(1000350, 9, 1035053, 0.05, 4, 'Vanilla Blues 50-53 Level Range'), +(1000350, 10, 1034750, 0.05, 4, 'Vanilla Blues 47-50 Level Range'), +(1000350, 11, 1044854, 0.025, 5, 'Vanilla Purples 48-54 Level Range'), +(1000350, 12, 1044450, 0.025, 5, 'Vanilla Purples 44-50 Level Range'), +(1000350, 13, 1044652, 0.025, 5, 'Vanilla Purples 46-52 Level Range'), +(1000350, 14, 1045056, 0.025, 5, 'Vanilla Purples 50-56 Level Range'), +(1000350, 15, 1053650, 1, 0, 'Vanilla Scrolls 36-50 Level Range'), +(1000350, 16, 1064150, 3, 0, 'Vanilla Potions 41-50 Level Range'), +(1000350, 18, 1074650, 100, 0, 'Vanilla Miscellaneous 46-50 Level Range'), +(1000350, 19, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000350, 20, 1084660, 0.25, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000350, 21, 1083650, 0.25, 6, 'Vanilla Patterns 36-50 Level Range'), +(1000350, 22, 1084055, 0.25, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000350, 23, 1085063, 0.25, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000350, 24, 1094150, 0.2, 0, 'Vanilla Bags 41-50 Level Range'), +(1000351, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000351, 2, 1025155, 0.8, 3, 'Vanilla Greens 51-55 Level Range'), +(1000351, 3, 1024751, 0.8, 3, 'Vanilla Greens 47-51 Level Range'), +(1000351, 4, 1025054, 0.8, 3, 'Vanilla Greens 50-54 Level Range'), +(1000351, 5, 1024852, 0.8, 3, 'Vanilla Greens 48-52 Level Range'), +(1000351, 6, 1024953, 0.8, 3, 'Vanilla Greens 49-53 Level Range'), +(1000351, 7, 1034952, 0.05, 4, 'Vanilla Blues 49-52 Level Range'), +(1000351, 8, 1034851, 0.05, 4, 'Vanilla Blues 48-51 Level Range'), +(1000351, 9, 1035154, 0.05, 4, 'Vanilla Blues 51-54 Level Range'), +(1000351, 10, 1035053, 0.05, 4, 'Vanilla Blues 50-53 Level Range'), +(1000351, 11, 1044854, 0.0334, 5, 'Vanilla Purples 48-54 Level Range'), +(1000351, 12, 1044652, 0.0334, 5, 'Vanilla Purples 46-52 Level Range'), +(1000351, 13, 1045056, 0.0334, 5, 'Vanilla Purples 50-56 Level Range'), +(1000351, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000351, 15, 1065155, 3, 0, 'Vanilla Potions 51-55 Level Range'), +(1000351, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000351, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000351, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000351, 20, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000351, 21, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000351, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000352, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000352, 2, 1025155, 0.8, 3, 'Vanilla Greens 51-55 Level Range'), +(1000352, 3, 1025256, 0.8, 3, 'Vanilla Greens 52-56 Level Range'), +(1000352, 4, 1025054, 0.8, 3, 'Vanilla Greens 50-54 Level Range'), +(1000352, 5, 1024852, 0.8, 3, 'Vanilla Greens 48-52 Level Range'), +(1000352, 6, 1024953, 0.8, 3, 'Vanilla Greens 49-53 Level Range'), +(1000352, 7, 1035255, 0.05, 4, 'Vanilla Blues 52-55 Level Range'), +(1000352, 8, 1034952, 0.05, 4, 'Vanilla Blues 49-52 Level Range'), +(1000352, 9, 1035154, 0.05, 4, 'Vanilla Blues 51-54 Level Range'), +(1000352, 10, 1035053, 0.05, 4, 'Vanilla Blues 50-53 Level Range'), +(1000352, 11, 1044854, 0.025, 5, 'Vanilla Purples 48-54 Level Range'), +(1000352, 12, 1044652, 0.025, 5, 'Vanilla Purples 46-52 Level Range'), +(1000352, 13, 1045258, 0.025, 5, 'Vanilla Purples 52-58 Level Range'), +(1000352, 14, 1045056, 0.025, 5, 'Vanilla Purples 50-56 Level Range'), +(1000352, 15, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000352, 16, 1065155, 3, 0, 'Vanilla Potions 51-55 Level Range'), +(1000352, 17, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000352, 19, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000352, 20, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000352, 21, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000352, 22, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000352, 23, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000353, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000353, 2, 1025155, 0.8, 3, 'Vanilla Greens 51-55 Level Range'), +(1000353, 3, 1025357, 0.8, 3, 'Vanilla Greens 53-57 Level Range'), +(1000353, 4, 1025256, 0.8, 3, 'Vanilla Greens 52-56 Level Range'), +(1000353, 5, 1025054, 0.8, 3, 'Vanilla Greens 50-54 Level Range'), +(1000353, 6, 1024953, 0.8, 3, 'Vanilla Greens 49-53 Level Range'), +(1000353, 7, 1035255, 0.05, 4, 'Vanilla Blues 52-55 Level Range'), +(1000353, 8, 1035154, 0.05, 4, 'Vanilla Blues 51-54 Level Range'), +(1000353, 9, 1035356, 0.05, 4, 'Vanilla Blues 53-56 Level Range'), +(1000353, 10, 1035053, 0.05, 4, 'Vanilla Blues 50-53 Level Range'), +(1000353, 11, 1044854, 0.0334, 5, 'Vanilla Purples 48-54 Level Range'), +(1000353, 12, 1045258, 0.0334, 5, 'Vanilla Purples 52-58 Level Range'), +(1000353, 13, 1045056, 0.0334, 5, 'Vanilla Purples 50-56 Level Range'), +(1000353, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000353, 15, 1065155, 3, 0, 'Vanilla Potions 51-55 Level Range'), +(1000353, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000353, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000353, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000353, 20, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000353, 21, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000353, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000354, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000354, 2, 1025458, 0.8, 3, 'Vanilla Greens 54-58 Level Range'), +(1000354, 3, 1025155, 0.8, 3, 'Vanilla Greens 51-55 Level Range'), +(1000354, 4, 1025357, 0.8, 3, 'Vanilla Greens 53-57 Level Range'), +(1000354, 5, 1025256, 0.8, 3, 'Vanilla Greens 52-56 Level Range'), +(1000354, 6, 1025054, 0.8, 3, 'Vanilla Greens 50-54 Level Range'), +(1000354, 7, 1035255, 0.05, 4, 'Vanilla Blues 52-55 Level Range'), +(1000354, 8, 1035457, 0.05, 4, 'Vanilla Blues 54-57 Level Range'), +(1000354, 9, 1035154, 0.05, 4, 'Vanilla Blues 51-54 Level Range'), +(1000354, 10, 1035356, 0.05, 4, 'Vanilla Blues 53-56 Level Range'), +(1000354, 11, 1044854, 0.025, 5, 'Vanilla Purples 48-54 Level Range'), +(1000354, 12, 1045258, 0.025, 5, 'Vanilla Purples 52-58 Level Range'), +(1000354, 13, 1045056, 0.025, 5, 'Vanilla Purples 50-56 Level Range'), +(1000354, 14, 1045460, 0.025, 5, 'Vanilla Purples 54-60 Level Range'), +(1000354, 15, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000354, 16, 1065155, 3, 0, 'Vanilla Potions 51-55 Level Range'), +(1000354, 17, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000354, 19, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000354, 20, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000354, 21, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000354, 22, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000354, 23, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000355, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000355, 2, 1025458, 0.8, 3, 'Vanilla Greens 54-58 Level Range'), +(1000355, 3, 1025559, 0.8, 3, 'Vanilla Greens 55-59 Level Range'), +(1000355, 4, 1025155, 0.8, 3, 'Vanilla Greens 51-55 Level Range'), +(1000355, 5, 1025357, 0.8, 3, 'Vanilla Greens 53-57 Level Range'), +(1000355, 6, 1025256, 0.8, 3, 'Vanilla Greens 52-56 Level Range'), +(1000355, 7, 1035255, 0.05, 4, 'Vanilla Blues 52-55 Level Range'), +(1000355, 8, 1035558, 0.05, 4, 'Vanilla Blues 55-58 Level Range'), +(1000355, 9, 1035457, 0.05, 4, 'Vanilla Blues 54-57 Level Range'), +(1000355, 10, 1035356, 0.05, 4, 'Vanilla Blues 53-56 Level Range'), +(1000355, 11, 1045258, 0.0334, 5, 'Vanilla Purples 52-58 Level Range'), +(1000355, 12, 1045056, 0.0334, 5, 'Vanilla Purples 50-56 Level Range'), +(1000355, 13, 1045460, 0.0334, 5, 'Vanilla Purples 54-60 Level Range'), +(1000355, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000355, 15, 1065155, 3, 0, 'Vanilla Potions 51-55 Level Range'), +(1000355, 16, 1075155, 100, 0, 'Vanilla Miscellaneous 51-55 Level Range'), +(1000355, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000355, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000355, 20, 1084055, 0.33, 6, 'Vanilla Patterns 40-55 Level Range'), +(1000355, 21, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000355, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000356, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000356, 2, 1025660, 0.8, 3, 'Vanilla Greens 56-60 Level Range'), +(1000356, 3, 1025458, 0.8, 3, 'Vanilla Greens 54-58 Level Range'), +(1000356, 4, 1025559, 0.8, 3, 'Vanilla Greens 55-59 Level Range'), +(1000356, 5, 1025357, 0.8, 3, 'Vanilla Greens 53-57 Level Range'), +(1000356, 6, 1025256, 0.8, 3, 'Vanilla Greens 52-56 Level Range'), +(1000356, 7, 1035558, 0.05, 4, 'Vanilla Blues 55-58 Level Range'), +(1000356, 8, 1035457, 0.05, 4, 'Vanilla Blues 54-57 Level Range'), +(1000356, 9, 1035356, 0.05, 4, 'Vanilla Blues 53-56 Level Range'), +(1000356, 10, 1035659, 0.05, 4, 'Vanilla Blues 56-59 Level Range'), +(1000356, 11, 1045662, 0.025, 5, 'Vanilla Purples 56-62 Level Range'), +(1000356, 12, 1045258, 0.025, 5, 'Vanilla Purples 52-58 Level Range'), +(1000356, 13, 1045056, 0.025, 5, 'Vanilla Purples 50-56 Level Range'), +(1000356, 14, 1045460, 0.025, 5, 'Vanilla Purples 54-60 Level Range'), +(1000356, 15, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000356, 16, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000356, 17, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000356, 19, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000356, 20, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000356, 21, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000356, 22, 1085663, 0.33, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000356, 23, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000357, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000357, 2, 1025660, 0.8, 3, 'Vanilla Greens 56-60 Level Range'), +(1000357, 3, 1025458, 0.8, 3, 'Vanilla Greens 54-58 Level Range'), +(1000357, 4, 1025559, 0.8, 3, 'Vanilla Greens 55-59 Level Range'), +(1000357, 5, 1025357, 0.8, 3, 'Vanilla Greens 53-57 Level Range'), +(1000357, 6, 1025761, 0.8, 3, 'Vanilla Greens 57-61 Level Range'), +(1000357, 7, 1035558, 0.05, 4, 'Vanilla Blues 55-58 Level Range'), +(1000357, 8, 1035457, 0.05, 4, 'Vanilla Blues 54-57 Level Range'), +(1000357, 9, 1035760, 0.05, 4, 'Vanilla Blues 57-60 Level Range'), +(1000357, 10, 1035659, 0.05, 4, 'Vanilla Blues 56-59 Level Range'), +(1000357, 11, 1045662, 0.0334, 5, 'Vanilla Purples 56-62 Level Range'), +(1000357, 12, 1045258, 0.0334, 5, 'Vanilla Purples 52-58 Level Range'), +(1000357, 13, 1045460, 0.0334, 5, 'Vanilla Purples 54-60 Level Range'), +(1000357, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000357, 15, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000357, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000357, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000357, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000357, 20, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000357, 21, 1085663, 0.33, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000357, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000358, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000358, 2, 1025660, 0.8, 3, 'Vanilla Greens 56-60 Level Range'), +(1000358, 3, 1025862, 0.8, 3, 'Vanilla Greens 58-62 Level Range'), +(1000358, 4, 1025458, 0.8, 3, 'Vanilla Greens 54-58 Level Range'), +(1000358, 5, 1025559, 0.8, 3, 'Vanilla Greens 55-59 Level Range'), +(1000358, 6, 1025761, 0.8, 3, 'Vanilla Greens 57-61 Level Range'), +(1000358, 7, 1035861, 0.05, 4, 'Vanilla Blues 58-61 Level Range'), +(1000358, 8, 1035558, 0.05, 4, 'Vanilla Blues 55-58 Level Range'), +(1000358, 9, 1035760, 0.05, 4, 'Vanilla Blues 57-60 Level Range'), +(1000358, 10, 1035659, 0.05, 4, 'Vanilla Blues 56-59 Level Range'), +(1000358, 11, 1045662, 0.025, 5, 'Vanilla Purples 56-62 Level Range'), +(1000358, 12, 1045258, 0.025, 5, 'Vanilla Purples 52-58 Level Range'), +(1000358, 13, 1045460, 0.025, 5, 'Vanilla Purples 54-60 Level Range'), +(1000358, 14, 1045863, 0.025, 5, 'Vanilla Purples 58-63 Level Range'), +(1000358, 15, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000358, 16, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000358, 17, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000358, 19, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000358, 20, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000358, 21, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000358, 22, 1085663, 0.33, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000358, 23, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000359, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000359, 2, 1025660, 0.8, 3, 'Vanilla Greens 56-60 Level Range'), +(1000359, 3, 1025862, 0.8, 3, 'Vanilla Greens 58-62 Level Range'), +(1000359, 4, 1025559, 0.8, 3, 'Vanilla Greens 55-59 Level Range'), +(1000359, 5, 1025963, 0.8, 3, 'Vanilla Greens 59-63 Level Range'), +(1000359, 6, 1025761, 0.8, 3, 'Vanilla Greens 57-61 Level Range'), +(1000359, 7, 1035861, 0.05, 4, 'Vanilla Blues 58-61 Level Range'), +(1000359, 8, 1035963, 0.05, 4, 'Vanilla Blues 59-63 Level Range'), +(1000359, 9, 1035760, 0.05, 4, 'Vanilla Blues 57-60 Level Range'), +(1000359, 10, 1035659, 0.05, 4, 'Vanilla Blues 56-59 Level Range'), +(1000359, 11, 1045662, 0.0334, 5, 'Vanilla Purples 56-62 Level Range'), +(1000359, 12, 1045460, 0.0334, 5, 'Vanilla Purples 54-60 Level Range'), +(1000359, 13, 1045863, 0.0334, 5, 'Vanilla Purples 58-63 Level Range'), +(1000359, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000359, 15, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000359, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000359, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000359, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000359, 20, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000359, 21, 1085663, 0.33, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000359, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000360, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000360, 2, 1025660, 0.8, 3, 'Vanilla Greens 56-60 Level Range'), +(1000360, 3, 1025862, 0.8, 3, 'Vanilla Greens 58-62 Level Range'), +(1000360, 4, 1026063, 0.8, 3, 'Vanilla Greens 60-63 Level Range'), +(1000360, 5, 1025963, 0.8, 3, 'Vanilla Greens 59-63 Level Range'), +(1000360, 6, 1025761, 0.8, 3, 'Vanilla Greens 57-61 Level Range'), +(1000360, 7, 1035861, 0.0667, 4, 'Vanilla Blues 58-61 Level Range'), +(1000360, 8, 1035963, 0.0667, 4, 'Vanilla Blues 59-63 Level Range'), +(1000360, 9, 1035760, 0.0667, 4, 'Vanilla Blues 57-60 Level Range'), +(1000360, 10, 1045662, 0.025, 5, 'Vanilla Purples 56-62 Level Range'), +(1000360, 11, 1046063, 0.025, 5, 'Vanilla Purples 60-63 Level Range'), +(1000360, 12, 1045460, 0.025, 5, 'Vanilla Purples 54-60 Level Range'), +(1000360, 13, 1045863, 0.025, 5, 'Vanilla Purples 58-63 Level Range'), +(1000360, 14, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000360, 15, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000360, 16, 1075660, 100, 0, 'Vanilla Miscellaneous 56-60 Level Range'), +(1000360, 18, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000360, 19, 1084660, 0.33, 6, 'Vanilla Patterns 46-60 Level Range'), +(1000360, 20, 1085063, 0.33, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000360, 21, 1085663, 0.33, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000360, 22, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000361, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000361, 2, 1025862, 0.8, 3, 'Vanilla Greens 58-62 Level Range'), +(1000361, 3, 1026163, 0.8, 3, 'Vanilla Greens 61-63 Level Range'), +(1000361, 4, 1026063, 0.8, 3, 'Vanilla Greens 60-63 Level Range'), +(1000361, 5, 1025963, 0.8, 3, 'Vanilla Greens 59-63 Level Range'), +(1000361, 6, 1025761, 0.8, 3, 'Vanilla Greens 57-61 Level Range'), +(1000361, 7, 1035861, 0.1, 4, 'Vanilla Blues 58-61 Level Range'), +(1000361, 8, 1035963, 0.1, 4, 'Vanilla Blues 59-63 Level Range'), +(1000361, 9, 1045662, 0.0334, 5, 'Vanilla Purples 56-62 Level Range'), +(1000361, 10, 1046063, 0.0334, 5, 'Vanilla Purples 60-63 Level Range'), +(1000361, 11, 1045863, 0.0334, 5, 'Vanilla Purples 58-63 Level Range'), +(1000361, 12, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000361, 13, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000361, 14, 1076163, 100, 0, 'Vanilla Miscellaneous 61-63 Level Range'), +(1000361, 16, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000361, 18, 1085063, 0.5, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000361, 19, 1085663, 0.5, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000361, 20, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000362, 1, 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000362, 2, 1025862, 0.8, 3, 'Vanilla Greens 58-62 Level Range'), +(1000362, 3, 1026263, 0.8, 3, 'Vanilla Greens 62-63 Level Range'), +(1000362, 4, 1026163, 0.8, 3, 'Vanilla Greens 61-63 Level Range'), +(1000362, 5, 1026063, 0.8, 3, 'Vanilla Greens 60-63 Level Range'), +(1000362, 6, 1025963, 0.8, 3, 'Vanilla Greens 59-63 Level Range'), +(1000362, 7, 1035963, 0.2, 4, 'Vanilla Blues 59-63 Level Range'), +(1000362, 8, 1045662, 0.0334, 5, 'Vanilla Purples 56-62 Level Range'), +(1000362, 9, 1046063, 0.0334, 5, 'Vanilla Purples 60-63 Level Range'), +(1000362, 10, 1045863, 0.0334, 5, 'Vanilla Purples 58-63 Level Range'), +(1000362, 11, 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000362, 12, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000362, 13, 1076163, 100, 0, 'Vanilla Miscellaneous 61-63 Level Range'), +(1000362, 14, 1075063, 100, 0, 'Vanilla Librams/Cards 50-61 Level Range'), +(1000362, 16, 1085063, 0.5, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000362, 17, 1085663, 0.5, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000362, 18, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +(1000363, 1 , 1005163, 10, 0, 'Vanilla Greys 51-63 Level Range'), +(1000363, 2 , 1026263, 1, 3, 'Vanilla Greens 62-63 Level Range'), +(1000363, 3 , 1026163, 1, 3, 'Vanilla Greens 61-63 Level Range'), +(1000363, 4 , 1026063, 1, 3, 'Vanilla Greens 60-63 Level Range'), +(1000363, 5 , 1025963, 1, 3, 'Vanilla Greens 59-63 Level Range'), +(1000363, 6 , 1035963, 0.2, 4, 'Vanilla Blues 59-63 Level Range'), +(1000363, 7 , 1046063, 0.05, 5, 'Vanilla Purples 60-63 Level Range'), +(1000363, 8 , 1045863, 0.05, 5, 'Vanilla Purples 58-63 Level Range'), +(1000363, 9 , 1055163, 1, 0, 'Vanilla Scrolls 51-63 Level Range'), +(1000363, 10, 1065663, 3, 0, 'Vanilla Potions 56-63 Level Range'), +(1000363, 11, 1076163, 100, 0, 'Vanilla Miscellaneous 61-63 Level Range'), +(1000363, 12, 1075063, 100, 0, 'Vanilla Librams/Cards 50-63 Level Range'), +(1000363, 13, 1085063, 0.5, 6, 'Vanilla Patterns 50-63 Level Range'), +(1000363, 14, 1085663, 0.5, 6, 'Vanilla Patterns 56-63 Level Range'), +(1000363, 15, 1095162, 0.2, 0, 'Vanilla Bags 51-62 Level Range'), +-- (1100358, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +-- (1100358, 2, 1125860, 2, 3, 'TBC Greens 58-60 Level Range'), +-- (1100358, 3, 1135861, 0.1, 4, 'TBC Blues 58-61 Level Range'), +-- (1100358, 4, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +-- (1100358, 5, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +-- (1100359, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +-- (1100359, 2, 1125961, 2, 3, 'TBC Greens 59-61 Level Range'), +-- (1100359, 3, 1125860, 2, 3, 'TBC Greens 58-60 Level Range'), +-- (1100359, 4, 1135861, 0.1, 4, 'TBC Blues 58-61 Level Range'), +-- (1100359, 5, 1135962, 0.1, 4, 'TBC Blues 59-62 Level Range'), +-- (1100359, 6, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +-- (1100359, 7, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100360, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +(1100360, 2, 1126062, 1.34, 3, 'TBC Greens 60-62 Level Range'), +(1100360, 3, 1125961, 1.34, 3, 'TBC Greens 59-61 Level Range'), +(1100360, 4, 1125860, 1.34, 3, 'TBC Greens 58-60 Level Range'), +(1100360, 5, 1135861, 0.0666, 4, 'TBC Blues 58-61 Level Range'), +(1100360, 6, 1135962, 0.0666, 4, 'TBC Blues 59-62 Level Range'), +(1100360, 7, 1136063, 0.0666, 4, 'TBC Blues 60-63 Level Range'), +(1100360, 8, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100360, 9, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100361, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +(1100361, 2, 1126062, 1.34, 3, 'TBC Greens 60-62 Level Range'), +(1100361, 3, 1125961, 1.34, 3, 'TBC Greens 59-61 Level Range'), +(1100361, 4, 1126163, 1.34, 3, 'TBC Greens 61-63 Level Range'), +(1100361, 5, 1136164, 0.05, 4, 'TBC Blues 61-64 Level Range'), +(1100361, 6, 1135861, 0.05, 4, 'TBC Blues 58-61 Level Range'), +(1100361, 7, 1135962, 0.05, 4, 'TBC Blues 59-62 Level Range'), +(1100361, 8, 1136063, 0.05, 4, 'TBC Blues 60-63 Level Range'), +(1100361, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100361, 10, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100361, 11, 1186165, 100, 0, 'TBC Patterns 61-65 Level Range'), +(1100362, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +(1100362, 2, 1126062, 1.34, 3, 'TBC Greens 60-62 Level Range'), +(1100362, 3, 1126163, 1.34, 3, 'TBC Greens 61-63 Level Range'), +(1100362, 4, 1126264, 1.34, 3, 'TBC Greens 62-64 Level Range'), +(1100362, 5, 1136265, 0.05, 4, 'TBC Blues 62-65 Level Range'), +(1100362, 6, 1136164, 0.05, 4, 'TBC Blues 61-64 Level Range'), +(1100362, 7, 1135962, 0.05, 4, 'TBC Blues 59-62 Level Range'), +(1100362, 8, 1136063, 0.05, 4, 'TBC Blues 60-63 Level Range'), +(1100362, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100362, 10, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100362, 11, 1186165, 100, 0, 'TBC Patterns 61-65 Level Range'), +(1100363, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +(1100363, 2, 1126365, 1.34, 3, 'TBC Greens 63-65 Level Range'), +(1100363, 3, 1126163, 1.34, 3, 'TBC Greens 61-63 Level Range'), +(1100363, 4, 1126264, 1.34, 3, 'TBC Greens 62-64 Level Range'), +(1100363, 5, 1136265, 0.05, 4, 'TBC Blues 62-65 Level Range'), +(1100363, 6, 1136164, 0.05, 4, 'TBC Blues 61-64 Level Range'), +(1100363, 7, 1136366, 0.05, 4, 'TBC Blues 63-66 Level Range'), +(1100363, 8, 1136063, 0.05, 4, 'TBC Blues 60-63 Level Range'), +(1100363, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100363, 10, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100363, 11, 1186165, 100, 0, 'TBC Patterns 61-65 Level Range'), +(1100364, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +(1100364, 2, 1126466, 1.34, 3, 'TBC Greens 64-66 Level Range'), +(1100364, 3, 1126365, 1.34, 3, 'TBC Greens 63-65 Level Range'), +(1100364, 4, 1126264, 1.34, 3, 'TBC Greens 62-64 Level Range'), +(1100364, 5, 1136265, 0.05, 4, 'TBC Blues 62-65 Level Range'), +(1100364, 6, 1136164, 0.05, 4, 'TBC Blues 61-64 Level Range'), +(1100364, 7, 1136467, 0.05, 4, 'TBC Blues 64-67 Level Range'), +(1100364, 8, 1136366, 0.05, 4, 'TBC Blues 63-66 Level Range'), +(1100364, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100364, 10, 1165864, 3, 0, 'TBC Potions 58-64 Level Range'), +(1100364, 11, 1186165, 100, 0, 'TBC Patterns 61-65 Level Range'), +(1100365, 1, 1105865, 10, 1, 'TBC Greys 58-65 Level Range'), +(1100365, 2, 1126567, 1.34, 3, 'TBC Greens 65-67 Level Range'), +(1100365, 3, 1126466, 1.34, 3, 'TBC Greens 64-66 Level Range'), +(1100365, 4, 1126365, 1.34, 3, 'TBC Greens 63-65 Level Range'), +(1100365, 5, 1136265, 0.05, 4, 'TBC Blues 62-65 Level Range'), +(1100365, 6, 1136467, 0.05, 4, 'TBC Blues 64-67 Level Range'), +(1100365, 7, 1136568, 0.05, 4, 'TBC Blues 65-68 Level Range'), +(1100365, 8, 1136366, 0.05, 4, 'TBC Blues 63-66 Level Range'), +(1100365, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100365, 10, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100365, 12, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100365, 13, 1186165, 100, 0, 'TBC Patterns 61-65 Level Range'), +(1100366, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100366, 2, 1126567, 1.34, 3, 'TBC Greens 65-67 Level Range'), +(1100366, 3, 1126668, 1.34, 3, 'TBC Greens 66-68 Level Range'), +(1100366, 4, 1126466, 1.34, 3, 'TBC Greens 64-66 Level Range'), +(1100366, 5, 1136467, 0.05, 4, 'TBC Blues 64-67 Level Range'), +(1100366, 6, 1136568, 0.05, 4, 'TBC Blues 65-68 Level Range'), +(1100366, 7, 1136669, 0.05, 4, 'TBC Blues 66-69 Level Range'), +(1100366, 8, 1136366, 0.05, 4, 'TBC Blues 63-66 Level Range'), +(1100366, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100366, 10, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100366, 12, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100366, 13, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100367, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100367, 2, 1126567, 1.34, 3, 'TBC Greens 65-67 Level Range'), +(1100367, 3, 1126668, 1.34, 3, 'TBC Greens 66-68 Level Range'), +(1100367, 4, 1126769, 1.34, 3, 'TBC Greens 67-69 Level Range'), +(1100367, 5, 1136467, 0.05, 4, 'TBC Blues 64-67 Level Range'), +(1100367, 6, 1136568, 0.05, 4, 'TBC Blues 65-68 Level Range'), +(1100367, 7, 1136669, 0.05, 4, 'TBC Blues 66-69 Level Range'), +(1100367, 8, 1136770, 0.05, 4, 'TBC Blues 67-70 Level Range'), +(1100367, 9, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100367, 10, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100367, 11, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100367, 13, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100367, 14, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100368, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100368, 2, 1126668, 1.34, 3, 'TBC Greens 66-68 Level Range'), +(1100368, 3, 1126769, 1.34, 3, 'TBC Greens 67-69 Level Range'), +(1100368, 4, 1126870, 1.34, 3, 'TBC Greens 68-70 Level Range'), +(1100368, 5, 1136568, 0.05, 4, 'TBC Blues 65-68 Level Range'), +(1100368, 6, 1136669, 0.05, 4, 'TBC Blues 66-69 Level Range'), +(1100368, 7, 1136873, 0.05, 4, 'TBC Blues 68-73 Level Range'), +(1100368, 8, 1136770, 0.05, 4, 'TBC Blues 67-70 Level Range'), +(1100368, 9, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100368, 10, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100368, 11, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100368, 13, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100368, 14, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100369, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100369, 2, 1126971, 1.34, 3, 'TBC Greens 69-71 Level Range'), +(1100369, 3, 1126769, 1.34, 3, 'TBC Greens 67-69 Level Range'), +(1100369, 4, 1126870, 1.34, 3, 'TBC Greens 68-70 Level Range'), +(1100369, 5, 1136669, 0.0666, 4, 'TBC Blues 66-69 Level Range'), +(1100369, 6, 1136873, 0.0666, 4, 'TBC Blues 68-73 Level Range'), +(1100369, 7, 1136770, 0.0666, 4, 'TBC Blues 67-70 Level Range'), +(1100369, 8, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100369, 9, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100369, 10, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100369, 12, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100369, 13, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100370, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100370, 2, 1126971, 1.34, 3, 'TBC Greens 69-71 Level Range'), +(1100370, 3, 1127072, 1.34, 3, 'TBC Greens 70-72 Level Range'), +(1100370, 4, 1126870, 1.34, 3, 'TBC Greens 68-70 Level Range'), +(1100370, 5, 1136873, 0.1, 4, 'TBC Blues 68-73 Level Range'), +(1100370, 6, 1136770, 0.1, 4, 'TBC Blues 67-70 Level Range'), +(1100370, 7, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100370, 8, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100370, 9, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100370, 11, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100370, 12, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100371, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100371, 2, 1126971, 1.34, 3, 'TBC Greens 69-71 Level Range'), +(1100371, 3, 1127072, 1.34, 3, 'TBC Greens 70-72 Level Range'), +(1100371, 4, 1127173, 1.34, 3, 'TBC Greens 71-73 Level Range'), +(1100371, 5, 1136873, 0.2, 4, 'TBC Blues 68-73 Level Range'), +(1100371, 6, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100371, 7, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100371, 8, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100371, 10, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100371, 11, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'), +(1100372, 1, 1106672, 10, 1, 'TBC Greys 66-72 Level Range'), +(1100372, 2, 1127072, 2, 3, 'TBC Greens 70-72 Level Range'), +(1100372, 3, 1127173, 2, 3, 'TBC Greens 71-73 Level Range'), +(1100372, 4, 1136873, 0.2, 4, 'TBC Blues 68-73 Level Range'), +(1100372, 5, 1146773, 0.1, 5, 'TBC Purples 67-73 Level Range'), +(1100372, 6, 1155873, 1, 0, 'TBC Scrolls 58-73 Level Range'), +(1100372, 7, 1166573, 3, 0, 'TBC Potions 65-73 Level Range'), +(1100372, 9, 1176573, 100, 0, 'TBC Cards 65-72 Level Range'), +(1100372, 10, 1186673, 100, 0, 'TBC Patterns 66-73 Level Range'); + +-- Cleanup Old System +DELETE FROM `creature_loot_template` WHERE +`Reference` IN (1002125, 1012425, 1022425, 1032425, 1052130, 1062029, 1071930, 1080003, 1080016, 1000610, 1010506, 1050110, 1070518, 1080001, 1080013, 1001115, 1011112, 1021112, 1051120, 1061019, 1080002, 1080014, 1010607, 1020608, 1010809, 1020809, 1010910, 1020910, 1012122, 1022122, 1032122, 1010808, 1011111, 1021111, 1011010, 1021010, 1003140, 1023940, 1033940, 1043840, 1053140, 1064049, 1073545, 1080004, 1080020, 1001620, 1011718, 1021718, 1080015, 1011212, 1021212, 1011415, 1021415, 1011011, 1021011, 1011616, 1021616, 1011414, 1021414, 1011516, 1021516, 1011920, 1021920, 1031820, 1011213, 1021213, 1011819, 1021819, 1011617, 1021617, 1012324, 1022324, 1032324, 1012223, 1022223, 1032223, 1002630, 1022829, 1032829, 1080018, 1023030, 1033030, 1063039, 1022627, 1032627, 1080017, 1022930, 1032930, 1012323, 1022323, 1032323, 1023232, 1033232, 1080019, 1010909, 1020909, 1012424, 1022424, 1032424, 1010707, 1012020, 1022020, 1022626, 1032626, 1012525, 1022526, 1032526, 1010708, 1012021, 1022021, 1032021, 1022929, 1032929, 1011515, 1021515, 1023131, 1033131, 1011818, 1021818, 1011919, 1021919, 1022728, 1032728, 1023434, 1033434, 1022727, 1032727, 1023334, 1033334, 1023435, 1033435, 1011314, 1021314, 1023637, 1033637, 1023737, 1033737, 1004150, 1024142, 1034142, 1044142, 1054162, 1080005, 1080021, 1024444, 1034444, 1044444, 1024041, 1034041, 1044041, 1024242, 1034242, 1044242, 1024344, 1034344, 1044344, 1024545, 1034545, 1044545, 1023031, 1033031, 1023233, 1033233, 1023738, 1033738, 1023536, 1033536, 1023132, 1033132, 1024040, 1034040, 1024343, 1034343, 1044343, 1024141, 1034141, 1044141, 1024243, 1034243, 1044243, 1023939, 1033939, 1023839, 1033839, 1023838, 1033838, 1005163, 1025051, 1035051, 1045051, 1065054, 1075062, 1080007, 1080022, 1025050, 1035050, 1045050, 1025353, 1035353, 1045353, 1023636, 1033636, 1024747, 1034747, 1044747, 1080006, 1011717, 1021717, 1012222, 1022222, 1032222, 1012121, 1022121, 1032121, 1011313, 1021313, 1025152, 1035152, 1045152, 1025455, 1035455, 1045455, 1065562, 1025657, 1035657, 1045657, 1025556, 1035556, 1045556, 1025151, 1035151, 1045151, 1025757, 1035757, 1045757, 1025354, 1035354, 1045354, 1025253, 1035253, 1045253, 1026060, 1036060, 1046060, 1025858, 1035858, 1045858, 1025959, 1035959, 1045959, 1025252, 1035252, 1045252, 1025656, 1035656, 1045656, 1026262, 1036262, 1046262, 1025555, 1035555, 1045555, 1025859, 1035859, 1045859, 1023535, 1033535, 1023333, 1033333, 1022525, 1032525, 1024445, 1034445, 1044445, 1024646, 1034646, 1044646, 1024546, 1034546, 1044546, 1024647, 1034647, 1044647, 1024748, 1034748, 1044748, 1024849, 1034849, 1044849, 1024950, 1034950, 1044950, 1010606, 1022828, 1032828, 1025758, 1035758, 1045758, 1024848, 1034848, 1044848, 1024949, 1034949, 1044949, 1025454, 1035454, 1045454, 1025960, 1035960, 1045960, 1026161, 1036161, 1046161, 1026061, 1036061, 1046061) +AND `Entry` IN (3,30,36,40,43,46,48,60,61,79,92,94,95,97,98,99,100,113,114,115,116,117,118,119,121,122,123,124,125,126,127,154,157,171,199,202,203,205,206,210,212,213,215,217,218,232,285,300,315,327,330,345,390,391,397,422,423,424,426,428,429,430,431,432,433,434,435,436,437,440,441,442,445,446,449,452,453,454,456,458,462,471,472,473,474,475,476,478,480,481,485,499,500,501,502,503,504,505,506,507,511,513,515,517,518,519,520,521,524,525,533,534,539,544,545,547,548,550,565,568,569,570,572,573,574,578,579,580,584,587,588,589,590,594,595,596,597,599,604,615,616,619,623,624,625,626,628,660,667,669,670,671,672,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,694,696,697,699,701,702,703,709,710,711,712,723,728,729,730,732,735,736,740,741,742,743,744,745,746,747,750,751,752,754,755,757,759,760,761,762,763,764,765,766,767,768,769,771,772,780,781,782,783,784,785,787,813,814,818,819,822,824,830,831,832,833,834,846,854,855,856,858,861,862,863,864,865,868,871,873,875,877,879,880,881,889,891,892,898,905,909,910,920,921,922,923,930,937,938,939,940,941,942,943,947,948,949,950,976,977,978,979,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1051,1052,1053,1054,1057,1059,1061,1062,1063,1065,1069,1081,1082,1083,1084,1085,1087,1088,1094,1095,1096,1097,1106,1108,1109,1110,1111,1112,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1137,1138,1140,1142,1144,1150,1151,1152,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1169,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1183,1184,1185,1186,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1199,1201,1202,1205,1206,1207,1211,1216,1222,1224,1225,1236,1251,1258,1259,1260,1270,1353,1364,1388,1393,1397,1398,1399,1400,1417,1418,1424,1425,1426,1487,1488,1489,1490,1491,1520,1522,1523,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1543,1544,1545,1547,1548,1549,1550,1551,1552,1553,1554,1555,1557,1558,1559,1561,1562,1563,1564,1565,1653,1654,1655,1656,1657,1658,1660,1662,1664,1665,1674,1675,1689,1693,1713,1725,1726,1727,1753,1754,1765,1766,1767,1768,1769,1770,1772,1773,1778,1779,1780,1781,1782,1783,1784,1785,1787,1788,1789,1791,1793,1794,1795,1796,1797,1802,1804,1806,1808,1809,1812,1813,1815,1816,1817,1821,1822,1824,1826,1827,1831,1832,1833,1834,1835,1837,1844,1845,1847,1848,1851,1865,1866,1867,1868,1869,1870,1883,1884,1885,1888,1889,1891,1894,1895,1907,1908,1909,1910,1911,1912,1913,1914,1915,1920,1922,1923,1924,1934,1935,1936,1939,1940,1941,1942,1943,1944,1947,1948,1949,1953,1954,1955,1956,1957,1958,1961,1971,1972,1973,1974,1983,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2017,2018,2019,2020,2021,2022,2025,2027,2029,2030,2033,2034,2038,2039,2042,2043,2053,2054,2058,2069,2070,2071,2089,2090,2091,2102,2103,2106,2108,2120,2152,2156,2157,2162,2163,2164,2165,2166,2167,2168,2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,2185,2186,2187,2189,2190,2191,2192,2201,2202,2203,2204,2205,2206,2207,2208,2212,2231,2232,2233,2234,2235,2236,2237,2240,2241,2242,2243,2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,2260,2261,2264,2265,2266,2267,2268,2269,2270,2271,2272,2283,2287,2304,2305,2306,2318,2319,2320,2321,2322,2323,2324,2332,2335,2336,2337,2338,2339,2344,2345,2346,2347,2348,2349,2350,2351,2354,2356,2358,2359,2360,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2384,2385,2387,2403,2404,2406,2407,2408,2411,2412,2413,2414,2415,2416,2420,2421,2422,2423,2427,2428,2431,2440,2448,2449,2450,2451,2452,2453,2473,2474,2476,2478,2503,2505,2521,2522,2530,2534,2535,2536,2537,2541,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2569,2570,2571,2572,2573,2574,2575,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,2589,2590,2591,2592,2595,2596,2597,2599,2600,2603,2604,2605,2606,2607,2609,2611,2612,2618,2619,2628,2635,2636,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2680,2681,2686,2691,2692,2693,2694,2701,2714,2715,2716,2717,2718,2719,2720,2723,2725,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2738,2739,2740,2742,2743,2744,2751,2752,2753,2760,2761,2762,2764,2765,2773,2779,2780,2781,2782,2783,2791,2793,2817,2829,2830,2831,2850,2892,2893,2894,2906,2907,2923,2924,2925,2926,2927,2928,2929,2932,2944,2945,2949,2950,2951,2956,2957,2958,2959,2960,2962,2963,2964,2965,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,2989,2990,3035,3051,3056,3058,3068,3094,3099,3100,3103,3104,3105,3106,3107,3108,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3125,3126,3127,3128,3129,3130,3131,3141,3192,3195,3196,3197,3198,3199,3203,3204,3205,3206,3207,3225,3226,3227,3228,3231,3232,3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,3249,3250,3251,3252,3253,3254,3255,3256,3258,3260,3261,3263,3265,3266,3267,3268,3269,3271,3272,3273,3274,3275,3276,3277,3278,3279,3280,3282,3283,3284,3285,3286,3295,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3392,3393,3394,3396,3397,3414,3415,3416,3424,3425,3426,3434,3435,3436,3438,3445,3452,3454,3455,3456,3457,3458,3459,3461,3463,3465,3466,3467,3470,3471,3472,3473,3474,3476,3503,3528,3530,3532,3535,3566,3577,3578,3581,3630,3631,3632,3633,3634,3638,3641,3652,3655,3660,3661,3662,3664,3667,3672,3692,3696,3711,3712,3713,3715,3717,3721,3725,3727,3728,3730,3732,3733,3734,3735,3736,3737,3739,3740,3742,3743,3745,3746,3748,3749,3750,3752,3754,3755,3757,3758,3759,3762,3763,3765,3767,3770,3771,3772,3773,3774,3780,3781,3782,3783,3784,3789,3791,3792,3797,3801,3802,3803,3804,3806,3807,3808,3809,3810,3811,3812,3814,3815,3816,3817,3818,3819,3820,3821,3823,3824,3825,3833,3834,3917,3919,3921,3922,3923,3924,3925,3926,3928,3931,3932,3940,3941,3942,3943,3944,3986,3987,3988,3989,3991,3992,3993,3994,3999,4003,4004,4005,4006,4007,4008,4009,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4034,4035,4036,4037,4038,4040,4041,4042,4044,4050,4051,4052,4053,4054,4056,4057,4061,4062,4063,4064,4065,4066,4067,4070,4073,4074,4093,4094,4095,4096,4097,4099,4100,4101,4104,4107,4109,4110,4111,4112,4114,4116,4117,4118,4119,4120,4124,4126,4127,4128,4129,4130,4131,4132,4133,4139,4140,4142,4143,4144,4147,4150,4151,4154,4158,4202,4248,4249,4250,4260,4273,4280,4281,4282,4283,4284,4285,4316,4323,4324,4328,4329,4331,4334,4341,4343,4344,4345,4346,4347,4348,4351,4352,4356,4357,4359,4361,4362,4363,4376,4378,4379,4380,4382,4385,4387,4388,4389,4390,4393,4394,4397,4401,4403,4404,4409,4412,4414,4415,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,4467,4468,4469,4472,4474,4475,4479,4480,4481,4493,4494,4499,4505,4506,4548,4619,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,4644,4645,4646,4647,4648,4649,4651,4652,4653,4654,4655,4656,4657,4658,4659,4662,4663,4664,4665,4666,4667,4668,4670,4671,4672,4673,4674,4675,4676,4677,4678,4679,4680,4681,4682,4684,4685,4692,4693,4694,4695,4696,4697,4699,4700,4701,4702,4705,4711,4712,4713,4714,4715,4716,4718,4719,4723,4726,4727,4728,4729,4788,4789,4802,4803,4834,4841,4844,4845,4846,4851,4856,4872,5057,5085,5086,5184,5224,5225,5229,5232,5234,5235,5236,5237,5238,5239,5240,5241,5243,5244,5245,5246,5247,5249,5251,5253,5254,5255,5258,5260,5261,5262,5263,5268,5269,5272,5274,5278,5286,5287,5288,5292,5293,5295,5296,5297,5299,5300,5304,5305,5306,5307,5308,5327,5328,5331,5332,5333,5334,5335,5336,5337,5343,5345,5346,5347,5349,5350,5352,5354,5356,5362,5363,5364,5366,5399,5400,5401,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430,5431,5441,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461,5462,5465,5471,5472,5473,5474,5475,5477,5481,5485,5490,5600,5601,5602,5615,5616,5617,5618,5622,5643,5645,5646,5647,5682,5683,5771,5786,5787,5807,5808,5809,5823,5826,5829,5832,5833,5834,5835,5836,5837,5838,5839,5840,5843,5844,5846,5847,5848,5849,5850,5852,5853,5854,5855,5856,5857,5858,5860,5861,5862,5863,5865,5881,5928,5933,5974,5975,5976,5977,5978,5979,5982,5983,5984,5985,5988,5990,5991,5992,5993,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6020,6033,6068,6072,6073,6093,6113,6115,6116,6117,6118,6123,6124,6125,6126,6127,6128,6132,6133,6135,6136,6137,6138,6140,6167,6170,6184,6185,6186,6187,6188,6189,6190,6193,6194,6195,6196,6198,6199,6200,6201,6202,6208,6210,6213,6221,6231,6347,6348,6349,6350,6351,6352,6369,6370,6371,6372,6375,6377,6378,6379,6380,6466,6494,6497,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6516,6517,6518,6519,6520,6521,6523,6527,6547,6551,6552,6553,6554,6555,6556,6557,6559,6570,6581,6582,6585,6606,6647,6648,6649,6650,6651,6652,6668,6733,6788,6789,6846,6909,6927,7015,7016,7017,7025,7026,7027,7028,7029,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043,7044,7045,7046,7047,7048,7049,7053,7055,7086,7092,7093,7097,7098,7099,7100,7101,7105,7106,7107,7109,7110,7111,7112,7113,7114,7115,7118,7120,7125,7126,7132,7136,7138,7139,7149,7153,7154,7155,7156,7157,7158,7170,7234,7235,7318,7319,7369,7371,7372,7376,7379,7404,7430,7431,7432,7433,7434,7438,7439,7440,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7523,7524,7584,7668,7669,7670,7671,7725,7726,7727,7728,7843,7847,7855,7856,7857,7858,7864,7872,7873,7874,7883,7885,7886,7895,7977,7995,7996,8136,8201,8202,8203,8204,8205,8207,8208,8210,8211,8212,8213,8214,8216,8218,8219,8236,8277,8278,8279,8280,8281,8283,8296,8297,8298,8299,8300,8301,8302,8303,8304,8400,8408,8409,8419,8447,8503,8518,8519,8520,8521,8522,8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8534,8535,8538,8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8550,8551,8553,8555,8556,8557,8558,8560,8561,8562,8563,8564,8565,8566,8596,8597,8598,8600,8601,8602,8603,8605,8606,8607,8636,8637,8660,8667,8675,8759,8760,8761,8762,8763,8764,8766,8837,8917,8924,8956,8957,8958,8959,8960,8961,8977,8978,8979,8981,9043,9044,9046,9162,9163,9164,9165,9166,9167,9176,9318,9336,9377,9396,9397,9454,9462,9464,9517,9518,9602,9604,9622,9690,9691,9694,9695,9697,9698,9860,9861,9862,9877,9878,9879,9916,10077,10078,10157,10158,10159,10160,10197,10199,10200,10323,10356,10357,10358,10359,10559,10580,10605,10608,10617,10637,10639,10640,10641,10642,10643,10644,10647,10648,10659,10660,10661,10738,10756,10757,10758,10759,10760,10761,10801,10802,10806,10807,10816,10817,10821,10822,10823,10824,10825,10826,10827,10896,10916,11290,11291,11440,11442,11443,11516,11552,11559,11561,11562,11563,11576,11577,11578,11611,11613,11656,11680,11681,11682,11683,11684,11685,11686,11687,11688,11697,11698,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,11731,11732,11733,11734,11735,11736,11737,11738,11739,11740,11741,11744,11745,11746,11747,11777,11778,11781,11782,11785,11786,11787,11788,11858,11873,11880,11881,11882,11883,11896,11897,11910,11911,11912,11913,11914,11915,11917,11918,11921,12037,12046,12178,12179,12199,12248,12250,12262,12263,12322,12347,12387,12418,12431,12432,12433,12579,12676,12677,12678,12759,12856,12865,12896,12897,13019,13157,14123,14221,14222,14223,14224,14225,14226,14227,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14266,14268,14269,14270,14271,14272,14273,14276,14277,14278,14279,14280,14281,14339,14340,14342,14343,14344,14345,14356,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14446,14447,14448,14455,14458,14460,14462,14472,14476,14477,14478,14479,14487,14488,14490,14491,14492,14523,14661,15201,15202,15213,15407,15408,15409,15542,15635,15636,15637,15638,15641,15642,15643,15645,15647,15648,15649,15650,15651,15652,15654,15655,15656,15657,15658,15668,15670,15685,15692,15937,15949,15965,15966,15967,15968,16162,16247,16248,16249,16250,16294,16300,16301,16302,16303,16304,16305,16307,16308,16309,16310,16311,16313,16314,16315,16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327,16328,16330,16331,16332,16333,16334,16335,16337,16339,16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351,16352,16353,16354,16355,16402,16403,16404,16405,16469,17115,17183,17184,17185,17186,17187,17188,17189,17190,17191,17192,17193,17194,17195,17196,17197,17199,17200,17201,17202,17203,17210,17216,17217,17235,17236,17278,17279,17298,17300,17320,17321,17322,17323,17324,17325,17326,17327,17328,17329,17330,17331,17333,17334,17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347,17348,17349,17350,17352,17353,17358,17372,17373,17374,17447,17448,17475,17494,17496,17522,17523,17524,17525,17527,17528,17550,17556,17588,17589,17591,17604,17606,17607,17608,17661,17673,17683,17701,17702,17713,17714,17878,18241,23554,23555,23589,23590,23591,23592,23593,23594,23595,23620,23637,23714,23841,23873,24477,24818,24819,37214,37917,37984,38006,38016,38023); + +-- +/* +Cloths: (2589, 2592, 4306, 4338, 14047, 14256, 21877) +References with Cloth (12006, 44007) + +SELECT DISTINCT `Entry` FROM `creature_loot_template` WHERE +`Entry` IN (SELECT `Entry` FROM `creature_template` WHERE `rank` = 0 AND `exp` = 0 AND `lootid` != 0) AND +(`Item` IN (2589, 2592, 4306, 4338, 14047, 14256, 21877) OR `Reference` IN (12006, 44007)) AND +`Entry` IN (SELECT DISTINCT `Entry` FROM `creature_loot_template` WHERE `Reference` BETWEEN 1000000 AND 1100000) + +No Cloth +SELECT DISTINCT `Entry` FROM `creature_loot_template` WHERE +`Entry` IN (SELECT `Entry` FROM `creature_template` WHERE `rank` = 0 AND `exp` = 0 AND `lootid` != 0) AND `Entry` NOT IN +(SELECT DISTINCT `Entry` FROM `creature_loot_template` WHERE `Item` IN (2589, 2592, 4306, 4338, 14047, 14256, 21877) OR `Reference` IN (12006, 44007)) AND +`Entry` IN (SELECT DISTINCT `Entry` FROM `creature_loot_template` WHERE `Reference` BETWEEN 1000000 AND 1100000) +*/ + +-- INSERT INTO `creature_loot_template` +-- (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) +-- SELECT +-- T.LootId, +-- +-- -- ITEM ID INCREMENTER +-- -- n is 0, 1, 2... so we add 1 to make it 1, 2, 3... +-- numbers.n + 1, +-- +-- -- REFERENCE ID ([BASE_ID] + Level) +-- -- REPLACE [BASE_ID] BELOW with 1200100 or 1200000 +-- [BASE_ID] + (GREATEST(1, T.MinLvl) + numbers.n), +-- +-- -- CHANCE (0 = Equal distribution) +-- 0, +-- +-- 0, 1, 5, 1, 1, +-- +-- -- CLEAN COMMENT +-- CONCAT(T.CreatureName, ' - World Loot Level ', (GREATEST(1, T.MinLvl) + numbers.n)) +-- FROM +-- ( +-- SELECT +-- `lootid` AS LootId, +-- MAX(`name`) AS CreatureName, +-- MAX(`minlevel`) AS MinLvl, +-- MAX(`maxlevel`) AS MaxLvl +-- FROM `creature_template` +-- WHERE +-- -- Paste the creature list here +-- `entry` IN ( ... ) +-- +-- GROUP BY `lootid` +-- ) T +-- CROSS JOIN +-- (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) AS numbers +-- WHERE +-- (GREATEST(1, T.MinLvl) + numbers.n) <= LEAST(82, T.MaxLvl); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (3,30,36,40,43,46,48,60,61,79,92,94,95,97,98,99,100,113,114,115,116,117,118,119,121,122,123,124,125,126,127,154,157,171,199,202,203,205,206,210,212,213,215,217,218,232,285,300,315,327,330,345,390,391,397,422,423,424,426,428,429,430,431,432,433,434,435,436,437,440,441,442,445,446,449,452,453,454,456,458,462,471,472,473,474,475,476,478,480,481,485,499,500,501,502,503,504,505,506,507,511,513,515,517,518,519,520,521,524,525,533,534,539,544,545,547,548,550,565,568,569,570,572,573,574,578,579,580,584,587,588,589,590,594,595,596,597,599,604,615,616,619,623,624,625,626,628,660,667,669,670,671,672,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,694,696,697,699,701,702,703,709,710,711,712,723,728,729,730,732,735,736,740,741,742,743,744,745,746,747,750,751,752,754,755,757,759,760,761,762,763,764,765,766,767,768,769,771,772,780,781,782,783,784,785,787,813,814,818,819,822,824,830,831,832,833,834,846,854,855,856,858,861,862,863,864,865,868,871,873,875,877,879,880,881,889,891,892,898,905,909,910,920,921,922,923,930,937,938,939,940,941,942,943,947,948,949,950,976,977,978,979,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1051,1052,1053,1054,1057,1059,1061,1062,1063,1065,1069,1081,1082,1083,1084,1085,1087,1088,1094,1095,1096,1097,1106,1108,1109,1110,1111,1112,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1137,1138,1140,1142,1144,1150,1151,1152,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1169,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1183,1184,1185,1186,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1199,1201,1202,1205,1206,1207,1211,1216,1222,1224,1225,1236,1251,1258,1259,1260,1270,1353,1364,1388,1393,1397,1398,1399,1400,1417,1418,1424,1425,1426,1487,1488,1489,1490,1491,1520,1522,1523,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1543,1544,1545,1547,1548,1549,1550,1551,1552,1553,1554,1555,1557,1558,1559,1561,1562,1563,1564,1565,1653,1654,1655,1656,1657,1658,1660,1662,1664,1665,1674,1675,1689,1693,1713,1725,1726,1727,1753,1754,1765,1766,1767,1768,1769,1770,1772,1773,1778,1779,1780,1781,1782,1783,1784,1785,1787,1788,1789,1791,1793,1794,1795,1796,1797,1802,1804,1806,1808,1809,1812,1813,1815,1816,1817,1821,1822,1824,1826,1827,1831,1832,1833,1834,1835,1837,1844,1845,1847,1848,1851,1865,1866,1867,1868,1869,1870,1883,1884,1885,1888,1889,1891,1894,1895,1907,1908,1909,1910,1911,1912,1913,1914,1915,1920,1922,1923,1924,1934,1935,1936,1939,1940,1941,1942,1943,1944,1947,1948,1949,1953,1954,1955,1956,1957,1958,1961,1971,1972,1973,1974,1983,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2017,2018,2019,2020,2021,2022,2025,2027,2029,2030,2033,2034,2038,2039,2042,2043,2053,2054,2058,2069,2070,2071,2089,2090,2091,2102,2103,2106,2108,2120,2152,2156,2157,2162,2163,2164,2165,2166,2167,2168,2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,2185,2186,2187,2189,2190,2191,2192,2201,2202,2203,2204,2205,2206,2207,2208,2212,2231,2232,2233,2234,2235,2236,2237,2240,2241,2242,2243,2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,2260,2261,2264,2265,2266,2267,2268,2269,2270,2271,2272,2283,2287,2304,2305,2306,2318,2319,2320,2321,2322,2323,2324,2332,2335,2336,2337,2338,2339,2344,2345,2346,2347,2348,2349,2350,2351,2354,2356,2358,2359,2360,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2384,2385,2387,2403,2404,2406,2407,2408,2411,2412,2413,2414,2415,2416,2420,2421,2422,2423,2427,2428,2431,2440,2448,2449,2450,2451,2452,2453,2473,2474,2476,2478,2503,2505,2521,2522,2530,2534,2535,2536,2537,2541,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2569,2570,2571,2572,2573,2574,2575,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,2589,2590,2591,2592,2595,2596,2597,2599,2600,2603,2604,2605,2606,2607,2609,2611,2612,2618,2619,2628,2635,2636,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2680,2681,2686,2691,2692,2693,2694,2701,2714,2715,2716,2717,2718,2719,2720,2723,2725,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2738,2739,2740,2742,2743,2744,2751,2752,2753,2760,2761,2762,2764,2765,2773,2779,2780,2781,2782,2783,2791,2793,2817,2829,2830,2831,2850,2892,2893,2894,2906,2907,2923,2924,2925,2926,2927,2928,2929,2932,2944,2945,2949,2950,2951,2956,2957,2958,2959,2960,2962,2963,2964,2965,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,2989,2990,3035,3051,3056,3058,3068,3094,3099,3100,3103,3104,3105,3106,3107,3108,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3125,3126,3127,3128,3129,3130,3131,3141,3192,3195,3196,3197,3198,3199,3203,3204,3205,3206,3207,3225,3226,3227,3228,3231,3232,3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,3249,3250,3251,3252,3253,3254,3255,3256,3258,3260,3261,3263,3265,3266,3267,3268,3269,3271,3272,3273,3274,3275,3276,3277,3278,3279,3280,3282,3283,3284,3285,3286,3295,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3392,3393,3394,3396,3397,3414,3415,3416,3424,3425,3426,3434,3435,3436,3438,3445,3452,3454,3455,3456,3457,3458,3459,3461,3463,3465,3466,3467,3470,3471,3472,3473,3474,3476,3503,3528,3530,3532,3535,3566,3577,3578,3581,3630,3631,3632,3633,3634,3638,3641,3652,3655,3660,3661,3662,3664,3667,3672,3692,3696,3711,3712,3713,3715,3717,3721,3725,3727,3728,3730,3732,3733,3734,3735,3736,3737,3739,3740,3742,3743,3745,3746,3748,3749,3750,3752,3754,3755,3757,3758,3759,3762,3763,3765,3767,3770,3771,3772,3773,3774,3780,3781,3782,3783,3784,3789,3791,3792,3797,3801,3802,3803,3804,3806,3807,3808,3809,3810,3811,3812,3814,3815,3816,3817,3818,3819,3820,3821,3823,3824,3825,3833,3834,3917,3919,3921,3922,3923,3924,3925,3926,3928,3931,3932,3940,3941,3942,3943,3944,3986,3987,3988,3989,3991,3992,3993,3994,3999,4003,4004,4005,4006,4007,4008,4009,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4034,4035,4036,4037,4038,4040,4041,4042,4044,4050,4051,4052,4053,4054,4056,4057,4061,4062,4063,4064,4065,4066,4067,4070,4073,4074,4093,4094,4095,4096,4097,4099,4100,4101,4104,4107,4109,4110,4111,4112,4114,4116,4117,4118,4119,4120,4124,4126,4127,4128,4129,4130,4131,4132,4133,4139,4140,4142,4143,4144,4147,4150,4151,4154,4158,4202,4248,4249,4250,4260,4273,4280,4281,4282,4283,4284,4285,4316,4323,4324,4328,4329,4331,4334,4341,4343,4344,4345,4346,4347,4348,4351,4352,4356,4357,4359,4361,4362,4363,4376,4378,4379,4380,4382,4385,4387,4388,4389,4390,4393,4394,4397,4401,4403,4404,4409,4412,4414,4415,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,4467,4468,4469,4472,4474,4475,4479,4480,4481,4493,4494,4499,4505,4506,4548,4619,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,4644,4645,4646,4647,4648,4649,4651,4652,4653,4654,4655,4656,4657,4658,4659,4662,4663,4664,4665,4666,4667,4668,4670,4671,4672,4673,4674,4675,4676,4677,4678,4679,4680,4681,4682,4684,4685,4692,4693,4694,4695,4696,4697,4699,4700,4701,4702,4705,4711,4712,4713,4714,4715,4716,4718,4719,4723,4726,4727,4728,4729,4788,4789,4802,4803,4834,4841,4844,4845,4846,4851,4856,4872,5057,5085,5086,5184,5224,5225,5229,5232,5234,5235,5236,5237,5238,5239,5240,5241,5243,5244,5245,5246,5247,5249,5251,5253,5254,5255,5258,5260,5261,5262,5263,5268,5269,5272,5274,5278,5286,5287,5288,5292,5293,5295,5296,5297,5299,5300,5304,5305,5306,5307,5308,5327,5328,5331,5332,5333,5334,5335,5336,5337,5343,5345,5346,5347,5349,5350,5352,5354,5356,5362,5363,5364,5366,5399,5400,5401,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430,5431,5441,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461,5462,5465,5471,5472,5473,5474,5475,5477,5481,5485,5490,5600,5601,5602,5615,5616,5617,5618,5622,5643,5645,5646,5647,5682,5683,5771,5786,5787,5807,5808,5809,5823,5826,5829,5832,5833,5834,5835,5836,5837,5838,5839,5840,5843,5844,5846,5847,5848,5849,5850,5852,5853,5854,5855,5856,5857,5858,5860,5861,5862,5863,5865,5881,5928,5933,5974,5975,5976,5977,5978,5979,5982,5983,5984,5985,5988,5990,5991,5992,5993,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6020,6033,6068,6072,6073,6093,6113,6115,6116,6117,6118,6123,6124,6125,6126,6127,6128,6132,6133,6135,6136,6137,6138,6140,6167,6170,6184,6185,6186,6187,6188,6189,6190,6193,6194,6195,6196,6198,6199,6200,6201,6202,6208,6210,6213,6221,6231,6347,6348,6349,6350,6351,6352,6369,6370,6371,6372,6375,6377,6378,6379,6380,6466,6494,6497,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6516,6517,6518,6519,6520,6521,6523,6527,6547,6551,6552,6553,6554,6555,6556,6557,6559,6570,6581,6582,6585,6606,6647,6648,6649,6650,6651,6652,6668,6733,6788,6789,6846,6909,6927,7015,7016,7017,7025,7026,7027,7028,7029,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043,7044,7045,7046,7047,7048,7049,7053,7055,7086,7092,7093,7097,7098,7099,7100,7101,7105,7106,7107,7109,7110,7111,7112,7113,7114,7115,7118,7120,7125,7126,7132,7136,7138,7139,7149,7153,7154,7155,7156,7157,7158,7170,7234,7235,7318,7319,7369,7371,7372,7376,7379,7404,7430,7431,7432,7433,7434,7438,7439,7440,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7523,7524,7584,7668,7669,7670,7671,7725,7726,7727,7728,7843,7847,7855,7856,7857,7858,7864,7872,7873,7874,7883,7885,7886,7895,7977,7995,7996,8136,8201,8202,8203,8204,8205,8207,8208,8210,8211,8212,8213,8214,8216,8218,8219,8236,8277,8278,8279,8280,8281,8283,8296,8297,8298,8299,8300,8301,8302,8303,8304,8400,8408,8409,8419,8447,8503,8518,8519,8520,8521,8522,8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8534,8535,8538,8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8550,8551,8553,8555,8556,8557,8558,8560,8561,8562,8563,8564,8565,8566,8596,8597,8598,8600,8601,8602,8603,8605,8606,8607,8636,8637,8660,8667,8675,8759,8760,8761,8762,8763,8764,8766,8837,8917,8924,8956,8957,8958,8959,8960,8961,8977,8978,8979,8981,9043,9044,9046,9162,9163,9164,9165,9166,9167,9176,9318,9336,9377,9396,9397,9454,9462,9464,9517,9518,9602,9604,9622,9690,9691,9694,9695,9697,9698,9860,9861,9862,9877,9878,9879,9916,10077,10078,10157,10158,10159,10160,10197,10199,10200,10323,10356,10357,10358,10359,10559,10580,10605,10608,10617,10637,10639,10640,10641,10642,10643,10644,10647,10648,10659,10660,10661,10738,10756,10757,10758,10759,10760,10761,10801,10802,10806,10807,10816,10817,10821,10822,10823,10824,10825,10826,10827,10896,10916,11290,11291,11440,11442,11443,11516,11552,11559,11561,11562,11563,11576,11577,11578,11611,11613,11656,11680,11681,11682,11683,11684,11685,11686,11687,11688,11697,11698,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,11731,11732,11733,11734,11735,11736,11737,11738,11739,11740,11741,11744,11745,11746,11747,11777,11778,11781,11782,11785,11786,11787,11788,11858,11873,11880,11881,11882,11883,11896,11897,11910,11911,11912,11913,11914,11915,11917,11918,11921,12037,12046,12178,12179,12199,12248,12250,12262,12263,12322,12347,12387,12418,12431,12432,12433,12579,12676,12677,12678,12759,12856,12865,12896,12897,13019,13157,14123,14221,14222,14223,14224,14225,14226,14227,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14266,14268,14269,14270,14271,14272,14273,14276,14277,14278,14279,14280,14281,14339,14340,14342,14343,14344,14345,14356,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14446,14447,14448,14455,14458,14460,14462,14472,14476,14477,14478,14479,14487,14488,14490,14491,14492,14523,14661,15201,15202,15213,15407,15408,15409,15542,15635,15636,15637,15638,15641,15642,15643,15645,15647,15648,15649,15650,15651,15652,15654,15655,15656,15657,15658,15668,15670,15685,15692,15937,15949,15965,15966,15967,15968,16162,16247,16248,16249,16250,16294,16300,16301,16302,16303,16304,16305,16307,16308,16309,16310,16311,16313,16314,16315,16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327,16328,16330,16331,16332,16333,16334,16335,16337,16339,16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351,16352,16353,16354,16355,16402,16403,16404,16405,16469,17115,17183,17184,17185,17186,17187,17188,17189,17190,17191,17192,17193,17194,17195,17196,17197,17199,17200,17201,17202,17203,17210,17216,17217,17235,17236,17278,17279,17298,17300,17320,17321,17322,17323,17324,17325,17326,17327,17328,17329,17330,17331,17333,17334,17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347,17348,17349,17350,17352,17353,17358,17372,17373,17374,17447,17448,17475,17494,17496,17522,17523,17524,17525,17527,17528,17550,17556,17588,17589,17591,17604,17606,17607,17608,17661,17673,17683,17701,17702,17713,17714,17878,17968,18241,22917,23554,23555,23589,23590,23591,23592,23593,23594,23595,23620,23637,23714,23841,23873,23956,23960,23961,24069,24071,24078,24079,24080,24082,24083,24085,24477,24818,24819,24849,26550,26553,26554,26555,26620,26621,26622,26623,26624,26625,26626,26628,26635,26636,26637,26638,26639,26641,26669,26670,26672,26694,26696,26830,27431,27633,27635,27636,27639,27640,27641,27642,27649,27650,27729,27731,27732,27734,27736,27742,27743,27744,27960,27961,27962,27963,27964,27965,27969,27970,27971,27972,28199,28200,28201,28249,28368,28410,28547,28578,28579,28580,28581,28582,28583,28584,28732,28734,28826,28835,28836,28837,28838,28920,28961,28965,29128,29335,29768,29819,29820,29822,29826,29829,29830,29832,29836,29838,29874,29931,30179,30276,30277,30278,30279,30283,30284,30285,30286,30287,30319,30329,30414,30660,30666,30667,30668,30695,30747,30762,30764,30765,30766,30806,30816,30817,30818,30820,30821,30892,30893,30901,30902,30904,30905,30906,30909,30910,30915,30916,30925,30926,30927,30929,30930,30931,30932,30933,30935,30936,30938,30942,30964,30966,30967,30968,30971,30972,30974,30975,30976,30977,30978,30979,30980,30981,30982,30983,31104,31178,31179,31180,31184,31187,31188,31199,31200,31201,31202,31203,31206,31336,31337,31338,31339,31340,31342,31343,31345,31347,31351,31352,31354,31355,31357,31359,31363,31372,31373,31374,31375,31376,31377,31378,31383,31385,31387,31442,31443,31449,31450,31451,31455,31457,31459,31460,31466,31468,31470,31471,31472,31486,31490,31493,31501,31502,31503,31504,31604,31606,31608,31609,31658,31659,31660,31661,31662,31663,31665,31666,31667,31669,31675,31676,32191,32192,37214,37917,37984,38006,38016,38023) +AND ( +`Reference` BETWEEN 1000005 AND 1000063 OR +`Reference` BETWEEN 1000105 AND 1000163 +); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Forest Spider - World Loot Level 5'), +(30, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Forest Spider - World Loot Level 6'), +(36, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Harvest Golem - World Loot Level 11'), +(36, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Harvest Golem - World Loot Level 12'), +(43, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Mine Spider - World Loot Level 8'), +(43, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Mine Spider - World Loot Level 9'), +(46, 1, 1000109, 0, 0, 1, 5, 1, 1, 'Murloc Forager - World Loot Level 9'), +(46, 2, 1000110, 0, 0, 1, 5, 1, 1, 'Murloc Forager - World Loot Level 10'), +(92, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Rock Elemental - World Loot Level 39'), +(92, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Rock Elemental - World Loot Level 40'), +(113, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Stonetusk Boar - World Loot Level 5'), +(113, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Stonetusk Boar - World Loot Level 6'), +(114, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Harvest Watcher - World Loot Level 14'), +(114, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Harvest Watcher - World Loot Level 15'), +(115, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Harvest Reaper - World Loot Level 17'), +(115, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Harvest Reaper - World Loot Level 18'), +(118, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Prowler - World Loot Level 9'), +(118, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Prowler - World Loot Level 10'), +(119, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Longsnout - World Loot Level 10'), +(119, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Longsnout - World Loot Level 11'), +(126, 1, 1000112, 0, 0, 1, 5, 1, 1, 'Murloc Coastrunner - World Loot Level 12'), +(126, 2, 1000113, 0, 0, 1, 5, 1, 1, 'Murloc Coastrunner - World Loot Level 13'), +(154, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Greater Fleshripper - World Loot Level 16'), +(154, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Greater Fleshripper - World Loot Level 17'), +(157, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Goretusk - World Loot Level 14'), +(157, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Goretusk - World Loot Level 15'), +(171, 1, 1000115, 0, 0, 1, 5, 1, 1, 'Murloc Warrior - World Loot Level 15'), +(171, 2, 1000116, 0, 0, 1, 5, 1, 1, 'Murloc Warrior - World Loot Level 16'), +(199, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Young Fleshripper - World Loot Level 10'), +(199, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Young Fleshripper - World Loot Level 11'), +(330, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Princess - World Loot Level 9'), +(345, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Bellygrub - World Loot Level 24'), +(390, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Porcine Entourage - World Loot Level 7'), +(391, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Old Murk-Eye - World Loot Level 20'), +(422, 1, 1000118, 0, 0, 1, 5, 1, 1, 'Murloc Flesheater - World Loot Level 18'), +(422, 2, 1000119, 0, 0, 1, 5, 1, 1, 'Murloc Flesheater - World Loot Level 19'), +(428, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Dire Condor - World Loot Level 18'), +(428, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Dire Condor - World Loot Level 19'), +(441, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Black Dragon Whelp - World Loot Level 17'), +(441, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Black Dragon Whelp - World Loot Level 18'), +(442, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Tarantula - World Loot Level 15'), +(442, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Tarantula - World Loot Level 16'), +(454, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Young Goretusk - World Loot Level 12'), +(454, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Young Goretusk - World Loot Level 13'), +(458, 1, 1000116, 0, 0, 1, 5, 1, 1, 'Murloc Hunter - World Loot Level 16'), +(458, 2, 1000117, 0, 0, 1, 5, 1, 1, 'Murloc Hunter - World Loot Level 17'), +(480, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Rusty Harvest Golem - World Loot Level 9'), +(480, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Rusty Harvest Golem - World Loot Level 10'), +(505, 1, 1000019, 0, 0, 1, 5, 1, 1, 'Greater Tarantula - World Loot Level 19'), +(505, 2, 1000020, 0, 0, 1, 5, 1, 1, 'Greater Tarantula - World Loot Level 20'), +(513, 1, 1000114, 0, 0, 1, 5, 1, 1, 'Murloc Netter - World Loot Level 14'), +(513, 2, 1000115, 0, 0, 1, 5, 1, 1, 'Murloc Netter - World Loot Level 15'), +(517, 1, 1000117, 0, 0, 1, 5, 1, 1, 'Murloc Oracle - World Loot Level 17'), +(517, 2, 1000118, 0, 0, 1, 5, 1, 1, 'Murloc Oracle - World Loot Level 18'), +(539, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Pygmy Venom Web Spider - World Loot Level 18'), +(539, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Pygmy Venom Web Spider - World Loot Level 19'), +(569, 1, 1000021, 0, 0, 1, 5, 1, 1, 'Green Recluse - World Loot Level 21'), +(569, 2, 1000022, 0, 0, 1, 5, 1, 1, 'Green Recluse - World Loot Level 22'), +(578, 1, 1000119, 0, 0, 1, 5, 1, 1, 'Murloc Scout - World Loot Level 19'), +(578, 2, 1000120, 0, 0, 1, 5, 1, 1, 'Murloc Scout - World Loot Level 20'), +(681, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Young Stranglethorn Tiger - World Loot Level 30'), +(681, 2, 1000031, 0, 0, 1, 5, 1, 1, 'Young Stranglethorn Tiger - World Loot Level 31'), +(682, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Stranglethorn Tiger - World Loot Level 32'), +(682, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Stranglethorn Tiger - World Loot Level 33'), +(683, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Young Panther - World Loot Level 30'), +(683, 2, 1000031, 0, 0, 1, 5, 1, 1, 'Young Panther - World Loot Level 31'), +(684, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Shadowmaw Panther - World Loot Level 37'), +(684, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Shadowmaw Panther - World Loot Level 38'), +(685, 1, 1000033, 0, 0, 1, 5, 1, 1, 'Stranglethorn Raptor - World Loot Level 33'), +(685, 2, 1000034, 0, 0, 1, 5, 1, 1, 'Stranglethorn Raptor - World Loot Level 34'), +(687, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Jungle Stalker - World Loot Level 40'), +(687, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Jungle Stalker - World Loot Level 41'), +(688, 1, 1000031, 0, 0, 1, 5, 1, 1, 'Stone Maw Basilisk - World Loot Level 31'), +(688, 2, 1000032, 0, 0, 1, 5, 1, 1, 'Stone Maw Basilisk - World Loot Level 32'), +(689, 1, 1000034, 0, 0, 1, 5, 1, 1, 'Crystal Spine Basilisk - World Loot Level 34'), +(689, 2, 1000035, 0, 0, 1, 5, 1, 1, 'Crystal Spine Basilisk - World Loot Level 35'), +(690, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Cold Eye Basilisk - World Loot Level 39'), +(690, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Cold Eye Basilisk - World Loot Level 40'), +(691, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Lesser Water Elemental - World Loot Level 36'), +(691, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Lesser Water Elemental - World Loot Level 37'), +(728, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Bhag\'thera - World Loot Level 40'), +(729, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Sin\'Dall - World Loot Level 37'), +(730, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Tethis - World Loot Level 43'), +(735, 1, 1000006, 0, 0, 1, 5, 1, 1, 'Murloc Streamrunner - World Loot Level 6'), +(735, 2, 1000007, 0, 0, 1, 5, 1, 1, 'Murloc Streamrunner - World Loot Level 7'), +(736, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Panther - World Loot Level 32'), +(736, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Panther - World Loot Level 33'), +(740, 1, 1000034, 0, 0, 1, 5, 1, 1, 'Adolescent Whelp - World Loot Level 34'), +(740, 2, 1000035, 0, 0, 1, 5, 1, 1, 'Adolescent Whelp - World Loot Level 35'), +(741, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Dreaming Whelp - World Loot Level 35'), +(741, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Dreaming Whelp - World Loot Level 36'), +(742, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Green Wyrmkin - World Loot Level 41'), +(743, 1, 1000142, 0, 0, 1, 5, 1, 1, 'Wyrmkin Dreamwalker - World Loot Level 42'), +(743, 2, 1000143, 0, 0, 1, 5, 1, 1, 'Wyrmkin Dreamwalker - World Loot Level 43'), +(744, 1, 1000142, 0, 0, 1, 5, 1, 1, 'Green Scalebane - World Loot Level 42'), +(745, 1, 1000143, 0, 0, 1, 5, 1, 1, 'Scalebane Captain - World Loot Level 43'), +(745, 2, 1000144, 0, 0, 1, 5, 1, 1, 'Scalebane Captain - World Loot Level 44'), +(746, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Elder Dragonkin - World Loot Level 45'), +(747, 1, 1000141, 0, 0, 1, 5, 1, 1, 'Marsh Murloc - World Loot Level 41'), +(747, 2, 1000142, 0, 0, 1, 5, 1, 1, 'Marsh Murloc - World Loot Level 42'), +(752, 1, 1000145, 0, 0, 1, 5, 1, 1, 'Marsh Oracle - World Loot Level 45'), +(764, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Swampwalker - World Loot Level 38'), +(764, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Swampwalker - World Loot Level 39'), +(765, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Swampwalker Elder - World Loot Level 39'), +(765, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Swampwalker Elder - World Loot Level 40'), +(766, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Tangled Horror - World Loot Level 40'), +(766, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Tangled Horror - World Loot Level 41'), +(767, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Swamp Jaguar - World Loot Level 36'), +(767, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Swamp Jaguar - World Loot Level 37'), +(768, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Shadow Panther - World Loot Level 39'), +(769, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Deathstrike Tarantula - World Loot Level 40'), +(769, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Deathstrike Tarantula - World Loot Level 41'), +(772, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Stranglethorn Tigress - World Loot Level 37'), +(772, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Stranglethorn Tigress - World Loot Level 38'), +(830, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Sand Crawler - World Loot Level 13'), +(830, 2, 1000014, 0, 0, 1, 5, 1, 1, 'Sand Crawler - World Loot Level 14'), +(831, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Sea Crawler - World Loot Level 15'), +(831, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Sea Crawler - World Loot Level 16'), +(832, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Dust Devil - World Loot Level 18'), +(832, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Dust Devil - World Loot Level 19'), +(833, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Coyote Packleader - World Loot Level 11'), +(833, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Coyote Packleader - World Loot Level 12'), +(846, 1, 1000114, 0, 0, 1, 5, 1, 1, 'Rotten Ghoul - World Loot Level 14'), +(846, 2, 1000115, 0, 0, 1, 5, 1, 1, 'Rotten Ghoul - World Loot Level 15'), +(854, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Young Jungle Stalker - World Loot Level 36'), +(854, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Young Jungle Stalker - World Loot Level 37'), +(855, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Young Stranglethorn Raptor - World Loot Level 30'), +(855, 2, 1000031, 0, 0, 1, 5, 1, 1, 'Young Stranglethorn Raptor - World Loot Level 31'), +(856, 1, 1000033, 0, 0, 1, 5, 1, 1, 'Young Lashtail Raptor - World Loot Level 33'), +(856, 2, 1000034, 0, 0, 1, 5, 1, 1, 'Young Lashtail Raptor - World Loot Level 34'), +(858, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Sorrow Spinner - World Loot Level 36'), +(858, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Sorrow Spinner - World Loot Level 37'), +(877, 1, 1000135, 0, 0, 1, 5, 1, 1, 'Saltscale Forager - World Loot Level 35'), +(877, 2, 1000136, 0, 0, 1, 5, 1, 1, 'Saltscale Forager - World Loot Level 36'), +(879, 1, 1000135, 0, 0, 1, 5, 1, 1, 'Saltscale Hunter - World Loot Level 35'), +(879, 2, 1000136, 0, 0, 1, 5, 1, 1, 'Saltscale Hunter - World Loot Level 36'), +(905, 1, 1000031, 0, 0, 1, 5, 1, 1, 'Sharptooth Frenzy - World Loot Level 31'), +(905, 2, 1000032, 0, 0, 1, 5, 1, 1, 'Sharptooth Frenzy - World Loot Level 32'), +(920, 1, 1000130, 0, 0, 1, 5, 1, 1, 'Nightbane Tainted One - World Loot Level 30'), +(920, 2, 1000131, 0, 0, 1, 5, 1, 1, 'Nightbane Tainted One - World Loot Level 31'), +(923, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Young Black Ravager - World Loot Level 23'), +(923, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Young Black Ravager - World Loot Level 24'), +(949, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Carrion Recluse - World Loot Level 25'), +(949, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Carrion Recluse - World Loot Level 26'), +(950, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Swamp Talker - World Loot Level 50'), +(976, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Kurzen War Tiger - World Loot Level 32'), +(976, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Kurzen War Tiger - World Loot Level 33'), +(1015, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Highland Raptor - World Loot Level 23'), +(1015, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Highland Raptor - World Loot Level 24'), +(1016, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Highland Lashtail - World Loot Level 24'), +(1016, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Highland Lashtail - World Loot Level 25'), +(1017, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Highland Scytheclaw - World Loot Level 25'), +(1017, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Highland Scytheclaw - World Loot Level 26'), +(1018, 1, 1000027, 0, 0, 1, 5, 1, 1, 'Highland Razormaw - World Loot Level 27'), +(1018, 2, 1000028, 0, 0, 1, 5, 1, 1, 'Highland Razormaw - World Loot Level 28'), +(1019, 1, 1000029, 0, 0, 1, 5, 1, 1, 'Elder Razormaw - World Loot Level 29'), +(1020, 1, 1000022, 0, 0, 1, 5, 1, 1, 'Mottled Raptor - World Loot Level 22'), +(1020, 2, 1000023, 0, 0, 1, 5, 1, 1, 'Mottled Raptor - World Loot Level 23'), +(1021, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Mottled Screecher - World Loot Level 24'), +(1021, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Mottled Screecher - World Loot Level 25'), +(1022, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Mottled Scytheclaw - World Loot Level 25'), +(1022, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Mottled Scytheclaw - World Loot Level 26'), +(1023, 1, 1000026, 0, 0, 1, 5, 1, 1, 'Mottled Razormaw - World Loot Level 26'), +(1023, 2, 1000027, 0, 0, 1, 5, 1, 1, 'Mottled Razormaw - World Loot Level 27'), +(1024, 1, 1000120, 0, 0, 1, 5, 1, 1, 'Bluegill Murloc - World Loot Level 20'), +(1024, 2, 1000121, 0, 0, 1, 5, 1, 1, 'Bluegill Murloc - World Loot Level 21'), +(1025, 1, 1000121, 0, 0, 1, 5, 1, 1, 'Bluegill Puddlejumper - World Loot Level 21'), +(1025, 2, 1000122, 0, 0, 1, 5, 1, 1, 'Bluegill Puddlejumper - World Loot Level 22'), +(1026, 1, 1000122, 0, 0, 1, 5, 1, 1, 'Bluegill Forager - World Loot Level 22'), +(1026, 2, 1000123, 0, 0, 1, 5, 1, 1, 'Bluegill Forager - World Loot Level 23'), +(1027, 1, 1000124, 0, 0, 1, 5, 1, 1, 'Bluegill Warrior - World Loot Level 24'), +(1027, 2, 1000125, 0, 0, 1, 5, 1, 1, 'Bluegill Warrior - World Loot Level 25'), +(1028, 1, 1000123, 0, 0, 1, 5, 1, 1, 'Bluegill Muckdweller - World Loot Level 23'), +(1028, 2, 1000124, 0, 0, 1, 5, 1, 1, 'Bluegill Muckdweller - World Loot Level 24'), +(1029, 1, 1000125, 0, 0, 1, 5, 1, 1, 'Bluegill Oracle - World Loot Level 25'), +(1029, 2, 1000126, 0, 0, 1, 5, 1, 1, 'Bluegill Oracle - World Loot Level 26'), +(1030, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Black Slime - World Loot Level 20'), +(1030, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Black Slime - World Loot Level 21'), +(1031, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Crimson Ooze - World Loot Level 24'), +(1031, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Crimson Ooze - World Loot Level 25'), +(1032, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Black Ooze - World Loot Level 23'), +(1032, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Black Ooze - World Loot Level 24'), +(1033, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Monstrous Ooze - World Loot Level 25'), +(1033, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Monstrous Ooze - World Loot Level 26'), +(1039, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Fen Dweller - World Loot Level 20'), +(1039, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Fen Dweller - World Loot Level 21'), +(1040, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Fen Creeper - World Loot Level 24'), +(1040, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Fen Creeper - World Loot Level 25'), +(1041, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Fen Lord - World Loot Level 25'), +(1041, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Fen Lord - World Loot Level 26'), +(1042, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Red Whelp - World Loot Level 23'), +(1042, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Red Whelp - World Loot Level 24'), +(1043, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Lost Whelp - World Loot Level 24'), +(1043, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Lost Whelp - World Loot Level 25'), +(1044, 1, 1000026, 0, 0, 1, 5, 1, 1, 'Flamesnorting Whelp - World Loot Level 26'), +(1044, 2, 1000027, 0, 0, 1, 5, 1, 1, 'Flamesnorting Whelp - World Loot Level 27'), +(1069, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Crimson Whelp - World Loot Level 25'), +(1069, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Crimson Whelp - World Loot Level 26'), +(1081, 1, 1000042, 0, 0, 1, 5, 1, 1, 'Mire Lord - World Loot Level 42'), +(1082, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Sawtooth Crocolisk - World Loot Level 38'), +(1082, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Sawtooth Crocolisk - World Loot Level 39'), +(1083, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Murloc Shorestriker - World Loot Level 16'), +(1083, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Murloc Shorestriker - World Loot Level 17'), +(1084, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Young Sawtooth Crocolisk - World Loot Level 35'), +(1084, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Young Sawtooth Crocolisk - World Loot Level 36'), +(1085, 1, 1000034, 0, 0, 1, 5, 1, 1, 'Elder Stranglethorn Tiger - World Loot Level 34'), +(1085, 2, 1000035, 0, 0, 1, 5, 1, 1, 'Elder Stranglethorn Tiger - World Loot Level 35'), +(1087, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Sawtooth Snapper - World Loot Level 41'), +(1087, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Sawtooth Snapper - World Loot Level 42'), +(1088, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Monstrous Crawler - World Loot Level 43'), +(1088, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Monstrous Crawler - World Loot Level 44'), +(1108, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Mistvale Gorilla - World Loot Level 32'), +(1108, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Mistvale Gorilla - World Loot Level 33'), +(1109, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Fleshripper - World Loot Level 13'), +(1109, 2, 1000014, 0, 0, 1, 5, 1, 1, 'Fleshripper - World Loot Level 14'), +(1111, 1, 1000021, 0, 0, 1, 5, 1, 1, 'Leech Stalker - World Loot Level 21'), +(1111, 2, 1000022, 0, 0, 1, 5, 1, 1, 'Leech Stalker - World Loot Level 22'), +(1114, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Jungle Thunderer - World Loot Level 37'), +(1114, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Jungle Thunderer - World Loot Level 38'), +(1120, 1, 1000107, 0, 0, 1, 5, 1, 1, 'Frostmane Troll - World Loot Level 7'), +(1120, 2, 1000108, 0, 0, 1, 5, 1, 1, 'Frostmane Troll - World Loot Level 8'), +(1121, 1, 1000108, 0, 0, 1, 5, 1, 1, 'Frostmane Snowstrider - World Loot Level 8'), +(1121, 2, 1000109, 0, 0, 1, 5, 1, 1, 'Frostmane Snowstrider - World Loot Level 9'), +(1122, 1, 1000109, 0, 0, 1, 5, 1, 1, 'Frostmane Hideskinner - World Loot Level 9'), +(1122, 2, 1000110, 0, 0, 1, 5, 1, 1, 'Frostmane Hideskinner - World Loot Level 10'), +(1123, 1, 1000108, 0, 0, 1, 5, 1, 1, 'Frostmane Headhunter - World Loot Level 8'), +(1123, 2, 1000109, 0, 0, 1, 5, 1, 1, 'Frostmane Headhunter - World Loot Level 9'), +(1124, 1, 1000109, 0, 0, 1, 5, 1, 1, 'Frostmane Shadowcaster - World Loot Level 9'), +(1124, 2, 1000110, 0, 0, 1, 5, 1, 1, 'Frostmane Shadowcaster - World Loot Level 10'), +(1125, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Crag Boar - World Loot Level 5'), +(1125, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Crag Boar - World Loot Level 6'), +(1126, 1, 1000006, 0, 0, 1, 5, 1, 1, 'Large Crag Boar - World Loot Level 6'), +(1126, 2, 1000007, 0, 0, 1, 5, 1, 1, 'Large Crag Boar - World Loot Level 7'), +(1127, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Elder Crag Boar - World Loot Level 7'), +(1127, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Elder Crag Boar - World Loot Level 8'), +(1128, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Young Black Bear - World Loot Level 5'), +(1128, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Young Black Bear - World Loot Level 6'), +(1129, 1, 1000006, 0, 0, 1, 5, 1, 1, 'Black Bear - World Loot Level 6'), +(1129, 2, 1000007, 0, 0, 1, 5, 1, 1, 'Black Bear - World Loot Level 7'), +(1131, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Winter Wolf - World Loot Level 7'), +(1131, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Winter Wolf - World Loot Level 8'), +(1133, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Starving Winter Wolf - World Loot Level 8'), +(1133, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Starving Winter Wolf - World Loot Level 9'), +(1134, 1, 1000105, 0, 0, 1, 5, 1, 1, 'Young Wendigo - World Loot Level 5'), +(1134, 2, 1000106, 0, 0, 1, 5, 1, 1, 'Young Wendigo - World Loot Level 6'), +(1135, 1, 1000106, 0, 0, 1, 5, 1, 1, 'Wendigo - World Loot Level 6'), +(1135, 2, 1000107, 0, 0, 1, 5, 1, 1, 'Wendigo - World Loot Level 7'), +(1138, 1, 1000006, 0, 0, 1, 5, 1, 1, 'Snow Tracker Wolf - World Loot Level 6'), +(1138, 2, 1000007, 0, 0, 1, 5, 1, 1, 'Snow Tracker Wolf - World Loot Level 7'), +(1150, 1, 1000030, 0, 0, 1, 5, 1, 1, 'River Crocolisk - World Loot Level 30'), +(1150, 2, 1000031, 0, 0, 1, 5, 1, 1, 'River Crocolisk - World Loot Level 31'), +(1151, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Saltwater Crocolisk - World Loot Level 35'), +(1151, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Saltwater Crocolisk - World Loot Level 36'), +(1152, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Snapjaw Crocolisk - World Loot Level 35'), +(1152, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Snapjaw Crocolisk - World Loot Level 36'), +(1173, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Tunnel Rat Scout - World Loot Level 10'), +(1173, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Tunnel Rat Scout - World Loot Level 11'), +(1184, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Cliff Lurker - World Loot Level 13'), +(1184, 2, 1000014, 0, 0, 1, 5, 1, 1, 'Cliff Lurker - World Loot Level 14'), +(1185, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Wood Lurker - World Loot Level 17'), +(1185, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Wood Lurker - World Loot Level 18'), +(1186, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Elder Black Bear - World Loot Level 11'), +(1186, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Elder Black Bear - World Loot Level 12'), +(1188, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Grizzled Black Bear - World Loot Level 13'), +(1188, 2, 1000014, 0, 0, 1, 5, 1, 1, 'Grizzled Black Bear - World Loot Level 14'), +(1189, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Black Bear Patriarch - World Loot Level 16'), +(1189, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Black Bear Patriarch - World Loot Level 17'), +(1190, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Mountain Boar - World Loot Level 10'), +(1190, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Mountain Boar - World Loot Level 11'), +(1191, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Mangy Mountain Boar - World Loot Level 14'), +(1191, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Mangy Mountain Boar - World Loot Level 15'), +(1192, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Elder Mountain Boar - World Loot Level 16'), +(1192, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Elder Mountain Boar - World Loot Level 17'), +(1193, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Loch Frenzy - World Loot Level 12'), +(1193, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Loch Frenzy - World Loot Level 13'), +(1194, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Mountain Buzzard - World Loot Level 15'), +(1194, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Mountain Buzzard - World Loot Level 16'), +(1195, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Forest Lurker - World Loot Level 10'), +(1195, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Forest Lurker - World Loot Level 11'), +(1196, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Ice Claw Bear - World Loot Level 7'), +(1196, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Ice Claw Bear - World Loot Level 8'), +(1199, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Juvenile Snow Leopard - World Loot Level 5'), +(1199, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Juvenile Snow Leopard - World Loot Level 6'), +(1201, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Snow Leopard - World Loot Level 7'), +(1201, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Snow Leopard - World Loot Level 8'), +(1216, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Shore Crawler - World Loot Level 17'), +(1216, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Shore Crawler - World Loot Level 18'), +(1224, 1, 1000019, 0, 0, 1, 5, 1, 1, 'Young Threshadon - World Loot Level 19'), +(1224, 2, 1000020, 0, 0, 1, 5, 1, 1, 'Young Threshadon - World Loot Level 20'), +(1225, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Ol\' Sooty - World Loot Level 20'), +(1258, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Black Ravager Mastiff - World Loot Level 25'), +(1258, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Black Ravager Mastiff - World Loot Level 26'), +(1259, 1, 1000022, 0, 0, 1, 5, 1, 1, 'Gobbler - World Loot Level 22'), +(1353, 1, 1000029, 0, 0, 1, 5, 1, 1, 'Sarltooth - World Loot Level 29'), +(1388, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Vagash - World Loot Level 11'), +(1400, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Wetlands Crocolisk - World Loot Level 23'), +(1400, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Wetlands Crocolisk - World Loot Level 24'), +(1417, 1, 1000021, 0, 0, 1, 5, 1, 1, 'Young Wetlands Crocolisk - World Loot Level 21'), +(1417, 2, 1000022, 0, 0, 1, 5, 1, 1, 'Young Wetlands Crocolisk - World Loot Level 22'), +(1418, 1, 1000128, 0, 0, 1, 5, 1, 1, 'Bluegill Raider - World Loot Level 28'), +(1418, 2, 1000129, 0, 0, 1, 5, 1, 1, 'Bluegill Raider - World Loot Level 29'), +(1491, 1, 1000144, 0, 0, 1, 5, 1, 1, 'Zanzil Naga - World Loot Level 44'), +(1528, 1, 1000108, 0, 0, 1, 5, 1, 1, 'Shambling Horror - World Loot Level 8'), +(1528, 2, 1000109, 0, 0, 1, 5, 1, 1, 'Shambling Horror - World Loot Level 9'), +(1530, 1, 1000110, 0, 0, 1, 5, 1, 1, 'Rotting Ancestor - World Loot Level 10'), +(1530, 2, 1000111, 0, 0, 1, 5, 1, 1, 'Rotting Ancestor - World Loot Level 11'), +(1532, 1, 1000110, 0, 0, 1, 5, 1, 1, 'Wandering Spirit - World Loot Level 10'), +(1532, 2, 1000111, 0, 0, 1, 5, 1, 1, 'Wandering Spirit - World Loot Level 11'), +(1534, 1, 1000109, 0, 0, 1, 5, 1, 1, 'Wailing Ancestor - World Loot Level 9'), +(1534, 2, 1000110, 0, 0, 1, 5, 1, 1, 'Wailing Ancestor - World Loot Level 10'), +(1536, 1, 1000107, 0, 0, 1, 5, 1, 1, 'Scarlet Missionary - World Loot Level 7'), +(1536, 2, 1000108, 0, 0, 1, 5, 1, 1, 'Scarlet Missionary - World Loot Level 8'), +(1538, 1, 1000109, 0, 0, 1, 5, 1, 1, 'Scarlet Friar - World Loot Level 9'), +(1538, 2, 1000110, 0, 0, 1, 5, 1, 1, 'Scarlet Friar - World Loot Level 10'), +(1539, 1, 1000110, 0, 0, 1, 5, 1, 1, 'Scarlet Neophyte - World Loot Level 10'), +(1539, 2, 1000111, 0, 0, 1, 5, 1, 1, 'Scarlet Neophyte - World Loot Level 11'), +(1540, 1, 1000110, 0, 0, 1, 5, 1, 1, 'Scarlet Vanguard - World Loot Level 10'), +(1540, 2, 1000111, 0, 0, 1, 5, 1, 1, 'Scarlet Vanguard - World Loot Level 11'), +(1543, 1, 1000107, 0, 0, 1, 5, 1, 1, 'Vile Fin Puddlejumper - World Loot Level 7'), +(1543, 2, 1000108, 0, 0, 1, 5, 1, 1, 'Vile Fin Puddlejumper - World Loot Level 8'), +(1544, 1, 1000108, 0, 0, 1, 5, 1, 1, 'Vile Fin Minor Oracle - World Loot Level 8'), +(1544, 2, 1000109, 0, 0, 1, 5, 1, 1, 'Vile Fin Minor Oracle - World Loot Level 9'), +(1545, 1, 1000109, 0, 0, 1, 5, 1, 1, 'Vile Fin Muckdweller - World Loot Level 9'), +(1545, 2, 1000110, 0, 0, 1, 5, 1, 1, 'Vile Fin Muckdweller - World Loot Level 10'), +(1547, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Decrepit Darkhound - World Loot Level 5'), +(1547, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Decrepit Darkhound - World Loot Level 6'), +(1548, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Cursed Darkhound - World Loot Level 7'), +(1548, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Cursed Darkhound - World Loot Level 8'), +(1549, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Ravenous Darkhound - World Loot Level 9'), +(1549, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Ravenous Darkhound - World Loot Level 10'), +(1550, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Thrashtail Basilisk - World Loot Level 41'), +(1550, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Thrashtail Basilisk - World Loot Level 42'), +(1551, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Ironjaw Basilisk - World Loot Level 43'), +(1551, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Ironjaw Basilisk - World Loot Level 44'), +(1553, 1, 1000006, 0, 0, 1, 5, 1, 1, 'Greater Duskbat - World Loot Level 6'), +(1553, 2, 1000007, 0, 0, 1, 5, 1, 1, 'Greater Duskbat - World Loot Level 7'), +(1554, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Vampiric Duskbat - World Loot Level 8'), +(1554, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Vampiric Duskbat - World Loot Level 9'), +(1555, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Vicious Night Web Spider - World Loot Level 9'), +(1555, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Vicious Night Web Spider - World Loot Level 10'), +(1557, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Elder Mistvale Gorilla - World Loot Level 40'), +(1557, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Elder Mistvale Gorilla - World Loot Level 41'), +(1558, 1, 1000042, 0, 0, 1, 5, 1, 1, 'Silverback Patriarch - World Loot Level 42'), +(1558, 2, 1000043, 0, 0, 1, 5, 1, 1, 'Silverback Patriarch - World Loot Level 43'), +(1559, 1, 1000042, 0, 0, 1, 5, 1, 1, 'King Mukla - World Loot Level 42'), +(1689, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Scarred Crag Boar - World Loot Level 9'), +(1689, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Scarred Crag Boar - World Loot Level 10'), +(1693, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Loch Crocolisk - World Loot Level 14'), +(1693, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Loch Crocolisk - World Loot Level 15'), +(1713, 1, 1000042, 0, 0, 1, 5, 1, 1, 'Elder Shadowmaw Panther - World Loot Level 42'), +(1713, 2, 1000043, 0, 0, 1, 5, 1, 1, 'Elder Shadowmaw Panther - World Loot Level 43'), +(1765, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Worg - World Loot Level 10'), +(1765, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Worg - World Loot Level 11'), +(1767, 1, 1000112, 0, 0, 1, 5, 1, 1, 'Vile Fin Shredder - World Loot Level 12'), +(1767, 2, 1000113, 0, 0, 1, 5, 1, 1, 'Vile Fin Shredder - World Loot Level 13'), +(1769, 1, 1000110, 0, 0, 1, 5, 1, 1, 'Moonrage Whitescalp - World Loot Level 10'), +(1769, 2, 1000111, 0, 0, 1, 5, 1, 1, 'Moonrage Whitescalp - World Loot Level 11'), +(1780, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Moss Stalker - World Loot Level 12'), +(1780, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Moss Stalker - World Loot Level 13'), +(1781, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Mist Creeper - World Loot Level 13'), +(1781, 2, 1000014, 0, 0, 1, 5, 1, 1, 'Mist Creeper - World Loot Level 14'), +(1782, 1, 1000113, 0, 0, 1, 5, 1, 1, 'Moonrage Darksoul - World Loot Level 13'), +(1782, 2, 1000114, 0, 0, 1, 5, 1, 1, 'Moonrage Darksoul - World Loot Level 14'), +(1797, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Giant Grizzled Bear - World Loot Level 12'), +(1797, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Giant Grizzled Bear - World Loot Level 13'), +(1806, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Vile Slime - World Loot Level 54'), +(1806, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Vile Slime - World Loot Level 55'), +(1808, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Devouring Ooze - World Loot Level 55'), +(1808, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Devouring Ooze - World Loot Level 56'), +(1809, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Carrion Vulture - World Loot Level 50'), +(1809, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Carrion Vulture - World Loot Level 51'), +(1809, 3, 1000052, 0, 0, 1, 5, 1, 1, 'Carrion Vulture - World Loot Level 52'), +(1812, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Rotting Behemoth - World Loot Level 55'), +(1812, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Rotting Behemoth - World Loot Level 56'), +(1813, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Decaying Horror - World Loot Level 56'), +(1813, 2, 1000057, 0, 0, 1, 5, 1, 1, 'Decaying Horror - World Loot Level 57'), +(1815, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Diseased Black Bear - World Loot Level 51'), +(1815, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Diseased Black Bear - World Loot Level 52'), +(1816, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Diseased Grizzly - World Loot Level 55'), +(1816, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Diseased Grizzly - World Loot Level 56'), +(1817, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Diseased Wolf - World Loot Level 53'), +(1817, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Diseased Wolf - World Loot Level 54'), +(1821, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Carrion Lurker - World Loot Level 52'), +(1821, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Carrion Lurker - World Loot Level 53'), +(1822, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Venom Mist Lurker - World Loot Level 50'), +(1822, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Venom Mist Lurker - World Loot Level 51'), +(1824, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Plague Lurker - World Loot Level 54'), +(1824, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Plague Lurker - World Loot Level 55'), +(1922, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Gray Forest Wolf - World Loot Level 7'), +(1922, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Gray Forest Wolf - World Loot Level 8'), +(1923, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Bloodsnout Worg - World Loot Level 16'), +(1923, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Bloodsnout Worg - World Loot Level 17'), +(1924, 1, 1000115, 0, 0, 1, 5, 1, 1, 'Moonrage Bloodhowler - World Loot Level 15'), +(1924, 2, 1000116, 0, 0, 1, 5, 1, 1, 'Moonrage Bloodhowler - World Loot Level 16'), +(1953, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Lake Skulker - World Loot Level 15'), +(1953, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Lake Skulker - World Loot Level 16'), +(1954, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Elder Lake Skulker - World Loot Level 16'), +(1954, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Elder Lake Skulker - World Loot Level 17'), +(1955, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Lake Creeper - World Loot Level 17'), +(1955, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Lake Creeper - World Loot Level 18'), +(1956, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Elder Lake Creeper - World Loot Level 18'), +(1956, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Elder Lake Creeper - World Loot Level 19'), +(1961, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Mangeclaw - World Loot Level 11'), +(1972, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Grimson the Pale - World Loot Level 15'), +(1995, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Strigid Owl - World Loot Level 5'), +(1995, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Strigid Owl - World Loot Level 6'), +(1996, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Strigid Screecher - World Loot Level 7'), +(1996, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Strigid Screecher - World Loot Level 8'), +(1997, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Strigid Hunter - World Loot Level 8'), +(1997, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Strigid Hunter - World Loot Level 9'), +(1998, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Webwood Lurker - World Loot Level 5'), +(1998, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Webwood Lurker - World Loot Level 6'), +(1999, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Webwood Venomfang - World Loot Level 7'), +(1999, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Webwood Venomfang - World Loot Level 8'), +(2000, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Webwood Silkspinner - World Loot Level 8'), +(2000, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Webwood Silkspinner - World Loot Level 9'), +(2001, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Giant Webwood Spider - World Loot Level 10'), +(2001, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Giant Webwood Spider - World Loot Level 11'), +(2022, 1, 1000105, 0, 0, 1, 5, 1, 1, 'Timberling - World Loot Level 5'), +(2022, 2, 1000106, 0, 0, 1, 5, 1, 1, 'Timberling - World Loot Level 6'), +(2025, 1, 1000107, 0, 0, 1, 5, 1, 1, 'Timberling Bark Ripper - World Loot Level 7'), +(2025, 2, 1000108, 0, 0, 1, 5, 1, 1, 'Timberling Bark Ripper - World Loot Level 8'), +(2027, 1, 1000108, 0, 0, 1, 5, 1, 1, 'Timberling Trampler - World Loot Level 8'), +(2027, 2, 1000109, 0, 0, 1, 5, 1, 1, 'Timberling Trampler - World Loot Level 9'), +(2029, 1, 1000109, 0, 0, 1, 5, 1, 1, 'Timberling Mire Beast - World Loot Level 9'), +(2029, 2, 1000110, 0, 0, 1, 5, 1, 1, 'Timberling Mire Beast - World Loot Level 10'), +(2030, 1, 1000110, 0, 0, 1, 5, 1, 1, 'Elder Timberling - World Loot Level 10'), +(2030, 2, 1000111, 0, 0, 1, 5, 1, 1, 'Elder Timberling - World Loot Level 11'), +(2033, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Elder Nightsaber - World Loot Level 8'), +(2033, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Elder Nightsaber - World Loot Level 9'), +(2034, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Feral Nightsaber - World Loot Level 10'), +(2034, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Feral Nightsaber - World Loot Level 11'), +(2042, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Nightsaber - World Loot Level 5'), +(2042, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Nightsaber - World Loot Level 6'), +(2043, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Nightsaber Stalker - World Loot Level 7'), +(2043, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Nightsaber Stalker - World Loot Level 8'), +(2069, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Moonstalker - World Loot Level 14'), +(2069, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Moonstalker - World Loot Level 15'), +(2070, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Moonstalker Runt - World Loot Level 10'), +(2070, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Moonstalker Runt - World Loot Level 11'), +(2071, 1, 1000019, 0, 0, 1, 5, 1, 1, 'Moonstalker Matriarch - World Loot Level 19'), +(2071, 2, 1000020, 0, 0, 1, 5, 1, 1, 'Moonstalker Matriarch - World Loot Level 20'), +(2089, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Giant Wetlands Crocolisk - World Loot Level 25'), +(2089, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Giant Wetlands Crocolisk - World Loot Level 26'), +(2106, 1, 1000116, 0, 0, 1, 5, 1, 1, 'Apothecary Berard - World Loot Level 16'), +(2163, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Thistle Bear - World Loot Level 11'), +(2163, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Thistle Bear - World Loot Level 12'), +(2165, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Grizzled Thistle Bear - World Loot Level 16'), +(2165, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Grizzled Thistle Bear - World Loot Level 17'), +(2166, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Oakenscowl - World Loot Level 9'), +(2173, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Reef Frenzy - World Loot Level 14'), +(2173, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Reef Frenzy - World Loot Level 15'), +(2174, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Coastal Frenzy - World Loot Level 14'), +(2174, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Coastal Frenzy - World Loot Level 15'), +(2174, 3, 1000016, 0, 0, 1, 5, 1, 1, 'Coastal Frenzy - World Loot Level 16'), +(2182, 1, 1000119, 0, 0, 1, 5, 1, 1, 'Stormscale Sorceress - World Loot Level 19'), +(2182, 2, 1000120, 0, 0, 1, 5, 1, 1, 'Stormscale Sorceress - World Loot Level 20'), +(2185, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Darkshore Thresher - World Loot Level 12'), +(2185, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Darkshore Thresher - World Loot Level 13'), +(2185, 3, 1000014, 0, 0, 1, 5, 1, 1, 'Darkshore Thresher - World Loot Level 14'), +(2187, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Elder Darkshore Thresher - World Loot Level 16'), +(2187, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Elder Darkshore Thresher - World Loot Level 17'), +(2187, 3, 1000018, 0, 0, 1, 5, 1, 1, 'Elder Darkshore Thresher - World Loot Level 18'), +(2201, 1, 1000111, 0, 0, 1, 5, 1, 1, 'Greymist Raider - World Loot Level 11'), +(2201, 2, 1000112, 0, 0, 1, 5, 1, 1, 'Greymist Raider - World Loot Level 12'), +(2202, 1, 1000112, 0, 0, 1, 5, 1, 1, 'Greymist Coastrunner - World Loot Level 12'), +(2202, 2, 1000113, 0, 0, 1, 5, 1, 1, 'Greymist Coastrunner - World Loot Level 13'), +(2204, 1, 1000114, 0, 0, 1, 5, 1, 1, 'Greymist Netter - World Loot Level 14'), +(2204, 2, 1000115, 0, 0, 1, 5, 1, 1, 'Greymist Netter - World Loot Level 15'), +(2205, 1, 1000115, 0, 0, 1, 5, 1, 1, 'Greymist Warrior - World Loot Level 15'), +(2205, 2, 1000116, 0, 0, 1, 5, 1, 1, 'Greymist Warrior - World Loot Level 16'), +(2206, 1, 1000116, 0, 0, 1, 5, 1, 1, 'Greymist Hunter - World Loot Level 16'), +(2206, 2, 1000117, 0, 0, 1, 5, 1, 1, 'Greymist Hunter - World Loot Level 17'), +(2207, 1, 1000118, 0, 0, 1, 5, 1, 1, 'Greymist Oracle - World Loot Level 18'), +(2207, 2, 1000119, 0, 0, 1, 5, 1, 1, 'Greymist Oracle - World Loot Level 19'), +(2208, 1, 1000119, 0, 0, 1, 5, 1, 1, 'Greymist Tidehunter - World Loot Level 19'), +(2208, 2, 1000120, 0, 0, 1, 5, 1, 1, 'Greymist Tidehunter - World Loot Level 20'), +(2231, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Pygmy Tide Crawler - World Loot Level 9'), +(2231, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Pygmy Tide Crawler - World Loot Level 10'), +(2232, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Tide Crawler - World Loot Level 12'), +(2232, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Tide Crawler - World Loot Level 13'), +(2232, 3, 1000014, 0, 0, 1, 5, 1, 1, 'Tide Crawler - World Loot Level 14'), +(2233, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Encrusted Tide Crawler - World Loot Level 18'), +(2233, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Encrusted Tide Crawler - World Loot Level 19'), +(2233, 3, 1000020, 0, 0, 1, 5, 1, 1, 'Encrusted Tide Crawler - World Loot Level 20'), +(2234, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Young Reef Crawler - World Loot Level 10'), +(2234, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Young Reef Crawler - World Loot Level 11'), +(2235, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Reef Crawler - World Loot Level 15'), +(2235, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Reef Crawler - World Loot Level 16'), +(2235, 3, 1000017, 0, 0, 1, 5, 1, 1, 'Reef Crawler - World Loot Level 17'), +(2236, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Raging Reef Crawler - World Loot Level 20'), +(2236, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Raging Reef Crawler - World Loot Level 21'), +(2237, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Moonstalker Sire - World Loot Level 17'), +(2237, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Moonstalker Sire - World Loot Level 18'), +(2250, 1, 1000132, 0, 0, 1, 5, 1, 1, 'Mountain Yeti - World Loot Level 32'), +(2250, 2, 1000133, 0, 0, 1, 5, 1, 1, 'Mountain Yeti - World Loot Level 33'), +(2251, 1, 1000133, 0, 0, 1, 5, 1, 1, 'Giant Yeti - World Loot Level 33'), +(2251, 2, 1000134, 0, 0, 1, 5, 1, 1, 'Giant Yeti - World Loot Level 34'), +(2321, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Foreststrider Fledgling - World Loot Level 11'), +(2321, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Foreststrider Fledgling - World Loot Level 12'), +(2321, 3, 1000013, 0, 0, 1, 5, 1, 1, 'Foreststrider Fledgling - World Loot Level 13'), +(2322, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Foreststrider - World Loot Level 14'), +(2322, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Foreststrider - World Loot Level 15'), +(2322, 3, 1000016, 0, 0, 1, 5, 1, 1, 'Foreststrider - World Loot Level 16'), +(2323, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Giant Foreststrider - World Loot Level 17'), +(2323, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Giant Foreststrider - World Loot Level 18'), +(2323, 3, 1000019, 0, 0, 1, 5, 1, 1, 'Giant Foreststrider - World Loot Level 19'), +(2347, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Wild Gryphon - World Loot Level 40'), +(2348, 1, 1000026, 0, 0, 1, 5, 1, 1, 'Elder Moss Creeper - World Loot Level 26'), +(2348, 2, 1000027, 0, 0, 1, 5, 1, 1, 'Elder Moss Creeper - World Loot Level 27'), +(2349, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Giant Moss Creeper - World Loot Level 24'), +(2349, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Giant Moss Creeper - World Loot Level 25'), +(2350, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Forest Moss Creeper - World Loot Level 20'), +(2350, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Forest Moss Creeper - World Loot Level 21'), +(2351, 1, 1000021, 0, 0, 1, 5, 1, 1, 'Gray Bear - World Loot Level 21'), +(2351, 2, 1000022, 0, 0, 1, 5, 1, 1, 'Gray Bear - World Loot Level 22'), +(2354, 1, 1000022, 0, 0, 1, 5, 1, 1, 'Vicious Gray Bear - World Loot Level 22'), +(2354, 2, 1000023, 0, 0, 1, 5, 1, 1, 'Vicious Gray Bear - World Loot Level 23'), +(2356, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Elder Gray Bear - World Loot Level 25'), +(2356, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Elder Gray Bear - World Loot Level 26'), +(2368, 1, 1000128, 0, 0, 1, 5, 1, 1, 'Daggerspine Shorestalker - World Loot Level 28'), +(2368, 2, 1000129, 0, 0, 1, 5, 1, 1, 'Daggerspine Shorestalker - World Loot Level 29'), +(2369, 1, 1000130, 0, 0, 1, 5, 1, 1, 'Daggerspine Shorehunter - World Loot Level 30'), +(2369, 2, 1000131, 0, 0, 1, 5, 1, 1, 'Daggerspine Shorehunter - World Loot Level 31'), +(2370, 1, 1000129, 0, 0, 1, 5, 1, 1, 'Daggerspine Screamer - World Loot Level 29'), +(2370, 2, 1000130, 0, 0, 1, 5, 1, 1, 'Daggerspine Screamer - World Loot Level 30'), +(2371, 1, 1000131, 0, 0, 1, 5, 1, 1, 'Daggerspine Siren - World Loot Level 31'), +(2371, 2, 1000132, 0, 0, 1, 5, 1, 1, 'Daggerspine Siren - World Loot Level 32'), +(2384, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Starving Mountain Lion - World Loot Level 23'), +(2384, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Starving Mountain Lion - World Loot Level 24'), +(2385, 1, 1000027, 0, 0, 1, 5, 1, 1, 'Feral Mountain Lion - World Loot Level 27'), +(2385, 2, 1000028, 0, 0, 1, 5, 1, 1, 'Feral Mountain Lion - World Loot Level 28'), +(2406, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Mountain Lion - World Loot Level 32'), +(2406, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Mountain Lion - World Loot Level 33'), +(2407, 1, 1000033, 0, 0, 1, 5, 1, 1, 'Hulking Mountain Lion - World Loot Level 33'), +(2407, 2, 1000034, 0, 0, 1, 5, 1, 1, 'Hulking Mountain Lion - World Loot Level 34'), +(2408, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Snapjaw - World Loot Level 30'), +(2408, 2, 1000031, 0, 0, 1, 5, 1, 1, 'Snapjaw - World Loot Level 31'), +(2473, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Granistad - World Loot Level 40'), +(2474, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Kurdros - World Loot Level 40'), +(2505, 1, 1000044, 0, 0, 1, 5, 1, 1, 'Saltwater Snapjaw - World Loot Level 44'), +(2505, 2, 1000045, 0, 0, 1, 5, 1, 1, 'Saltwater Snapjaw - World Loot Level 45'), +(2544, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Southern Sand Crawler - World Loot Level 40'), +(2544, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Southern Sand Crawler - World Loot Level 41'), +(2551, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Brutus - World Loot Level 43'), +(2559, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Highland Strider - World Loot Level 30'), +(2559, 2, 1000031, 0, 0, 1, 5, 1, 1, 'Highland Strider - World Loot Level 31'), +(2560, 1, 1000033, 0, 0, 1, 5, 1, 1, 'Highland Thrasher - World Loot Level 33'), +(2560, 2, 1000034, 0, 0, 1, 5, 1, 1, 'Highland Thrasher - World Loot Level 34'), +(2561, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Highland Fleshstalker - World Loot Level 36'), +(2561, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Highland Fleshstalker - World Loot Level 37'), +(2563, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Plains Creeper - World Loot Level 32'), +(2563, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Plains Creeper - World Loot Level 33'), +(2565, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Giant Plains Creeper - World Loot Level 35'), +(2565, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Giant Plains Creeper - World Loot Level 36'), +(2578, 1, 1000031, 0, 0, 1, 5, 1, 1, 'Young Mesa Buzzard - World Loot Level 31'), +(2578, 2, 1000032, 0, 0, 1, 5, 1, 1, 'Young Mesa Buzzard - World Loot Level 32'), +(2579, 1, 1000034, 0, 0, 1, 5, 1, 1, 'Mesa Buzzard - World Loot Level 34'), +(2579, 2, 1000035, 0, 0, 1, 5, 1, 1, 'Mesa Buzzard - World Loot Level 35'), +(2580, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Elder Mesa Buzzard - World Loot Level 37'), +(2580, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Elder Mesa Buzzard - World Loot Level 38'), +(2592, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Rumbling Exile - World Loot Level 38'), +(2592, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Rumbling Exile - World Loot Level 39'), +(2595, 1, 1000138, 0, 0, 1, 5, 1, 1, 'Daggerspine Raider - World Loot Level 38'), +(2595, 2, 1000139, 0, 0, 1, 5, 1, 1, 'Daggerspine Raider - World Loot Level 39'), +(2596, 1, 1000139, 0, 0, 1, 5, 1, 1, 'Daggerspine Sorceress - World Loot Level 39'), +(2596, 2, 1000140, 0, 0, 1, 5, 1, 1, 'Daggerspine Sorceress - World Loot Level 40'), +(2611, 1, 1000042, 0, 0, 1, 5, 1, 1, 'Fozruk - World Loot Level 42'), +(2635, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Elder Saltwater Crocolisk - World Loot Level 38'), +(2657, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Trained Razorbeak - World Loot Level 40'), +(2657, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Trained Razorbeak - World Loot Level 41'), +(2657, 3, 1000042, 0, 0, 1, 5, 1, 1, 'Trained Razorbeak - World Loot Level 42'), +(2658, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Razorbeak Gryphon - World Loot Level 43'), +(2658, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Razorbeak Gryphon - World Loot Level 44'), +(2658, 3, 1000045, 0, 0, 1, 5, 1, 1, 'Razorbeak Gryphon - World Loot Level 45'), +(2659, 1, 1000046, 0, 0, 1, 5, 1, 1, 'Razorbeak Skylord - World Loot Level 46'), +(2659, 2, 1000047, 0, 0, 1, 5, 1, 1, 'Razorbeak Skylord - World Loot Level 47'), +(2659, 3, 1000048, 0, 0, 1, 5, 1, 1, 'Razorbeak Skylord - World Loot Level 48'), +(2680, 1, 1000046, 0, 0, 1, 5, 1, 1, 'Vilebranch Wolf Pup - World Loot Level 46'), +(2680, 2, 1000047, 0, 0, 1, 5, 1, 1, 'Vilebranch Wolf Pup - World Loot Level 47'), +(2681, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Vilebranch Raiding Wolf - World Loot Level 50'), +(2681, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Vilebranch Raiding Wolf - World Loot Level 51'), +(2686, 1, 1000044, 0, 0, 1, 5, 1, 1, 'Witherbark Broodguard - World Loot Level 44'), +(2686, 2, 1000045, 0, 0, 1, 5, 1, 1, 'Witherbark Broodguard - World Loot Level 45'), +(2725, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Scalding Whelp - World Loot Level 41'), +(2725, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Scalding Whelp - World Loot Level 42'), +(2725, 3, 1000043, 0, 0, 1, 5, 1, 1, 'Scalding Whelp - World Loot Level 43'), +(2728, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Feral Crag Coyote - World Loot Level 37'), +(2728, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Feral Crag Coyote - World Loot Level 38'), +(2729, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Elder Crag Coyote - World Loot Level 39'), +(2729, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Elder Crag Coyote - World Loot Level 40'), +(2730, 1, 1000042, 0, 0, 1, 5, 1, 1, 'Rabid Crag Coyote - World Loot Level 42'), +(2730, 2, 1000043, 0, 0, 1, 5, 1, 1, 'Rabid Crag Coyote - World Loot Level 43'), +(2731, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Ridge Stalker - World Loot Level 36'), +(2731, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Ridge Stalker - World Loot Level 37'), +(2732, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Ridge Huntress - World Loot Level 38'), +(2732, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Ridge Huntress - World Loot Level 39'), +(2734, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Ridge Stalker Patriarch - World Loot Level 40'), +(2734, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Ridge Stalker Patriarch - World Loot Level 41'), +(2735, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Lesser Rock Elemental - World Loot Level 37'), +(2735, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Lesser Rock Elemental - World Loot Level 38'), +(2735, 3, 1000039, 0, 0, 1, 5, 1, 1, 'Lesser Rock Elemental - World Loot Level 39'), +(2736, 1, 1000042, 0, 0, 1, 5, 1, 1, 'Greater Rock Elemental - World Loot Level 42'), +(2736, 2, 1000043, 0, 0, 1, 5, 1, 1, 'Greater Rock Elemental - World Loot Level 43'), +(2736, 3, 1000044, 0, 0, 1, 5, 1, 1, 'Greater Rock Elemental - World Loot Level 44'), +(2760, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Burning Exile - World Loot Level 38'), +(2760, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Burning Exile - World Loot Level 39'), +(2761, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Cresting Exile - World Loot Level 38'), +(2761, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Cresting Exile - World Loot Level 39'), +(2762, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Thundering Exile - World Loot Level 38'), +(2762, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Thundering Exile - World Loot Level 39'), +(2791, 1, 1000042, 0, 0, 1, 5, 1, 1, 'Enraged Rock Elemental - World Loot Level 42'), +(2791, 2, 1000043, 0, 0, 1, 5, 1, 1, 'Enraged Rock Elemental - World Loot Level 43'), +(2817, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Rigglefuzz - World Loot Level 37'), +(2829, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Starving Buzzard - World Loot Level 35'), +(2829, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Starving Buzzard - World Loot Level 36'), +(2829, 3, 1000037, 0, 0, 1, 5, 1, 1, 'Starving Buzzard - World Loot Level 37'), +(2830, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Buzzard - World Loot Level 37'), +(2830, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Buzzard - World Loot Level 38'), +(2830, 3, 1000039, 0, 0, 1, 5, 1, 1, 'Buzzard - World Loot Level 39'), +(2831, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Giant Buzzard - World Loot Level 39'), +(2831, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Giant Buzzard - World Loot Level 40'), +(2831, 3, 1000041, 0, 0, 1, 5, 1, 1, 'Giant Buzzard - World Loot Level 41'), +(2923, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Mangy Silvermane - World Loot Level 41'), +(2923, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Mangy Silvermane - World Loot Level 42'), +(2924, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Silvermane Wolf - World Loot Level 43'), +(2924, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Silvermane Wolf - World Loot Level 44'), +(2925, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Silvermane Howler - World Loot Level 45'), +(2925, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Silvermane Howler - World Loot Level 46'), +(2926, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Silvermane Stalker - World Loot Level 47'), +(2926, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Silvermane Stalker - World Loot Level 48'), +(2927, 1, 1000142, 0, 0, 1, 5, 1, 1, 'Vicious Owlbeast - World Loot Level 42'), +(2927, 2, 1000143, 0, 0, 1, 5, 1, 1, 'Vicious Owlbeast - World Loot Level 43'), +(2928, 1, 1000144, 0, 0, 1, 5, 1, 1, 'Primitive Owlbeast - World Loot Level 44'), +(2928, 2, 1000145, 0, 0, 1, 5, 1, 1, 'Primitive Owlbeast - World Loot Level 45'), +(2929, 1, 1000146, 0, 0, 1, 5, 1, 1, 'Savage Owlbeast - World Loot Level 46'), +(2929, 2, 1000147, 0, 0, 1, 5, 1, 1, 'Savage Owlbeast - World Loot Level 47'), +(2956, 1, 1000006, 0, 0, 1, 5, 1, 1, 'Adult Plainstrider - World Loot Level 6'), +(2956, 2, 1000007, 0, 0, 1, 5, 1, 1, 'Adult Plainstrider - World Loot Level 7'), +(2957, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Elder Plainstrider - World Loot Level 8'), +(2957, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Elder Plainstrider - World Loot Level 9'), +(2958, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Prairie Wolf - World Loot Level 5'), +(2958, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Prairie Wolf - World Loot Level 6'), +(2969, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Wiry Swoop - World Loot Level 5'), +(2969, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Wiry Swoop - World Loot Level 6'), +(2969, 3, 1000007, 0, 0, 1, 5, 1, 1, 'Wiry Swoop - World Loot Level 7'), +(2970, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Swoop - World Loot Level 7'), +(2970, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Swoop - World Loot Level 8'), +(2970, 3, 1000009, 0, 0, 1, 5, 1, 1, 'Swoop - World Loot Level 9'), +(2971, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Taloned Swoop - World Loot Level 8'), +(2971, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Taloned Swoop - World Loot Level 9'), +(2971, 3, 1000010, 0, 0, 1, 5, 1, 1, 'Taloned Swoop - World Loot Level 10'), +(2972, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Kodo Calf - World Loot Level 7'), +(2972, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Kodo Calf - World Loot Level 8'), +(2973, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Kodo Bull - World Loot Level 10'), +(2973, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Kodo Bull - World Loot Level 11'), +(2974, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Kodo Matriarch - World Loot Level 11'), +(2974, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Kodo Matriarch - World Loot Level 12'), +(3035, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Flatland Cougar - World Loot Level 7'), +(3035, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Flatland Cougar - World Loot Level 8'), +(3058, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Arra\'chea - World Loot Level 11'), +(3099, 1, 1000006, 0, 0, 1, 5, 1, 1, 'Dire Mottled Boar - World Loot Level 6'), +(3099, 2, 1000007, 0, 0, 1, 5, 1, 1, 'Dire Mottled Boar - World Loot Level 7'), +(3100, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Elder Mottled Boar - World Loot Level 8'), +(3100, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Elder Mottled Boar - World Loot Level 9'), +(3105, 1, 1000108, 0, 0, 1, 5, 1, 1, 'Makrura Snapclaw - World Loot Level 8'), +(3107, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Surf Crawler - World Loot Level 7'), +(3107, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Surf Crawler - World Loot Level 8'), +(3108, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Encrusted Surf Crawler - World Loot Level 9'), +(3108, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Encrusted Surf Crawler - World Loot Level 10'), +(3110, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Dreadmaw Crocolisk - World Loot Level 9'), +(3110, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Dreadmaw Crocolisk - World Loot Level 10'), +(3110, 3, 1000011, 0, 0, 1, 5, 1, 1, 'Dreadmaw Crocolisk - World Loot Level 11'), +(3123, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Bloodtalon Scythemaw - World Loot Level 8'), +(3123, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Bloodtalon Scythemaw - World Loot Level 9'), +(3123, 3, 1000010, 0, 0, 1, 5, 1, 1, 'Bloodtalon Scythemaw - World Loot Level 10'), +(3125, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Clattering Scorpid - World Loot Level 5'), +(3125, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Clattering Scorpid - World Loot Level 6'), +(3126, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Armored Scorpid - World Loot Level 7'), +(3126, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Armored Scorpid - World Loot Level 8'), +(3127, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Venomtail Scorpid - World Loot Level 9'), +(3127, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Venomtail Scorpid - World Loot Level 10'), +(3141, 1, 1000108, 0, 0, 1, 5, 1, 1, 'Makrura Elder - World Loot Level 8'), +(3141, 2, 1000109, 0, 0, 1, 5, 1, 1, 'Makrura Elder - World Loot Level 9'), +(3225, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Corrupted Mottled Boar - World Loot Level 10'), +(3225, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Corrupted Mottled Boar - World Loot Level 11'), +(3226, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Corrupted Scorpid - World Loot Level 10'), +(3226, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Corrupted Scorpid - World Loot Level 11'), +(3227, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Corrupted Bloodtalon Scythemaw - World Loot Level 10'), +(3227, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Corrupted Bloodtalon Scythemaw - World Loot Level 11'), +(3228, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Corrupted Surf Crawler - World Loot Level 10'), +(3228, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Corrupted Surf Crawler - World Loot Level 11'), +(3231, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Corrupted Dreadmaw Crocolisk - World Loot Level 11'), +(3231, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Corrupted Dreadmaw Crocolisk - World Loot Level 12'), +(3234, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Lost Barrens Kodo - World Loot Level 14'), +(3234, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Lost Barrens Kodo - World Loot Level 15'), +(3235, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Greater Barrens Kodo - World Loot Level 24'), +(3235, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Greater Barrens Kodo - World Loot Level 25'), +(3236, 1, 1000019, 0, 0, 1, 5, 1, 1, 'Barrens Kodo - World Loot Level 19'), +(3236, 2, 1000020, 0, 0, 1, 5, 1, 1, 'Barrens Kodo - World Loot Level 20'), +(3237, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Wooly Kodo - World Loot Level 25'), +(3237, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Wooly Kodo - World Loot Level 26'), +(3238, 1, 1000022, 0, 0, 1, 5, 1, 1, 'Stormhide - World Loot Level 22'), +(3238, 2, 1000023, 0, 0, 1, 5, 1, 1, 'Stormhide - World Loot Level 23'), +(3239, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Thunderhead - World Loot Level 20'), +(3239, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Thunderhead - World Loot Level 21'), +(3240, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Stormsnout - World Loot Level 18'), +(3240, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Stormsnout - World Loot Level 19'), +(3241, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Savannah Patriarch - World Loot Level 15'), +(3241, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Savannah Patriarch - World Loot Level 16'), +(3242, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Zhevra Runner - World Loot Level 13'), +(3242, 2, 1000014, 0, 0, 1, 5, 1, 1, 'Zhevra Runner - World Loot Level 14'), +(3243, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Savannah Highmane - World Loot Level 12'), +(3243, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Savannah Highmane - World Loot Level 13'), +(3244, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Greater Plainstrider - World Loot Level 11'), +(3244, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Greater Plainstrider - World Loot Level 12'), +(3245, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Ornery Plainstrider - World Loot Level 16'), +(3245, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Ornery Plainstrider - World Loot Level 17'), +(3246, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Fleeting Plainstrider - World Loot Level 12'), +(3246, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Fleeting Plainstrider - World Loot Level 13'), +(3247, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Thunderhawk Hatchling - World Loot Level 18'), +(3247, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Thunderhawk Hatchling - World Loot Level 19'), +(3247, 3, 1000020, 0, 0, 1, 5, 1, 1, 'Thunderhawk Hatchling - World Loot Level 20'), +(3248, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Barrens Giraffe - World Loot Level 15'), +(3248, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Barrens Giraffe - World Loot Level 16'), +(3249, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Greater Thunderhawk - World Loot Level 23'), +(3249, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Greater Thunderhawk - World Loot Level 24'), +(3250, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Silithid Creeper - World Loot Level 20'), +(3250, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Silithid Creeper - World Loot Level 21'), +(3251, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Silithid Grub - World Loot Level 20'), +(3252, 1, 1000021, 0, 0, 1, 5, 1, 1, 'Silithid Swarmer - World Loot Level 21'), +(3252, 2, 1000022, 0, 0, 1, 5, 1, 1, 'Silithid Swarmer - World Loot Level 22'), +(3254, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Sunscale Lashtail - World Loot Level 11'), +(3254, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Sunscale Lashtail - World Loot Level 12'), +(3254, 3, 1000013, 0, 0, 1, 5, 1, 1, 'Sunscale Lashtail - World Loot Level 13'), +(3255, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Sunscale Screecher - World Loot Level 13'), +(3255, 2, 1000014, 0, 0, 1, 5, 1, 1, 'Sunscale Screecher - World Loot Level 14'), +(3255, 3, 1000015, 0, 0, 1, 5, 1, 1, 'Sunscale Screecher - World Loot Level 15'), +(3256, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Sunscale Scytheclaw - World Loot Level 16'), +(3256, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Sunscale Scytheclaw - World Loot Level 17'), +(3256, 3, 1000018, 0, 0, 1, 5, 1, 1, 'Sunscale Scytheclaw - World Loot Level 18'), +(3415, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Savannah Huntress - World Loot Level 11'), +(3415, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Savannah Huntress - World Loot Level 12'), +(3416, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Savannah Matriarch - World Loot Level 17'), +(3416, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Savannah Matriarch - World Loot Level 18'), +(3424, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Thunderhawk Cloudscraper - World Loot Level 20'), +(3424, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Thunderhawk Cloudscraper - World Loot Level 21'), +(3424, 3, 1000022, 0, 0, 1, 5, 1, 1, 'Thunderhawk Cloudscraper - World Loot Level 22'), +(3425, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Savannah Prowler - World Loot Level 14'), +(3425, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Savannah Prowler - World Loot Level 15'), +(3426, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Zhevra Charger - World Loot Level 17'), +(3426, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Zhevra Charger - World Loot Level 18'), +(3461, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Oasis Snapjaw - World Loot Level 15'), +(3461, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Oasis Snapjaw - World Loot Level 16'), +(3463, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Wandering Barrens Giraffe - World Loot Level 18'), +(3463, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Wandering Barrens Giraffe - World Loot Level 19'), +(3466, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Zhevra Courser - World Loot Level 20'), +(3466, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Zhevra Courser - World Loot Level 21'), +(3472, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Washte Pawne - World Loot Level 25'), +(3473, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Owatanka - World Loot Level 24'), +(3474, 1, 1000022, 0, 0, 1, 5, 1, 1, 'Lakota\'mani - World Loot Level 22'), +(3476, 1, 1000027, 0, 0, 1, 5, 1, 1, 'Isha Awak - World Loot Level 27'), +(3503, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Silithid Protector - World Loot Level 18'), +(3503, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Silithid Protector - World Loot Level 19'), +(3630, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Deviate Coiler - World Loot Level 15'), +(3630, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Deviate Coiler - World Loot Level 16'), +(3631, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Deviate Stinglash - World Loot Level 16'), +(3631, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Deviate Stinglash - World Loot Level 17'), +(3632, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Deviate Creeper - World Loot Level 15'), +(3632, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Deviate Creeper - World Loot Level 16'), +(3633, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Deviate Slayer - World Loot Level 16'), +(3633, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Deviate Slayer - World Loot Level 17'), +(3634, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Deviate Stalker - World Loot Level 15'), +(3638, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Devouring Ectoplasm - World Loot Level 16'), +(3638, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Devouring Ectoplasm - World Loot Level 17'), +(3641, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Deviate Lurker - World Loot Level 16'), +(3641, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Deviate Lurker - World Loot Level 17'), +(3711, 1, 1000120, 0, 0, 1, 5, 1, 1, 'Wrathtail Myrmidon - World Loot Level 20'), +(3711, 2, 1000121, 0, 0, 1, 5, 1, 1, 'Wrathtail Myrmidon - World Loot Level 21'), +(3717, 1, 1000118, 0, 0, 1, 5, 1, 1, 'Wrathtail Sorceress - World Loot Level 18'), +(3717, 2, 1000119, 0, 0, 1, 5, 1, 1, 'Wrathtail Sorceress - World Loot Level 19'), +(3721, 1, 1000019, 0, 0, 1, 5, 1, 1, 'Mystlash Hydra - World Loot Level 19'), +(3721, 2, 1000020, 0, 0, 1, 5, 1, 1, 'Mystlash Hydra - World Loot Level 20'), +(3737, 1, 1000019, 0, 0, 1, 5, 1, 1, 'Saltspittle Puddlejumper - World Loot Level 19'), +(3737, 2, 1000020, 0, 0, 1, 5, 1, 1, 'Saltspittle Puddlejumper - World Loot Level 20'), +(3739, 1, 1000019, 0, 0, 1, 5, 1, 1, 'Saltspittle Warrior - World Loot Level 19'), +(3739, 2, 1000020, 0, 0, 1, 5, 1, 1, 'Saltspittle Warrior - World Loot Level 20'), +(3740, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Saltspittle Muckdweller - World Loot Level 20'), +(3740, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Saltspittle Muckdweller - World Loot Level 21'), +(3742, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Saltspittle Oracle - World Loot Level 20'), +(3742, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Saltspittle Oracle - World Loot Level 21'), +(3780, 1, 1000121, 0, 0, 1, 5, 1, 1, 'Shadethicket Moss Eater - World Loot Level 21'), +(3780, 2, 1000122, 0, 0, 1, 5, 1, 1, 'Shadethicket Moss Eater - World Loot Level 22'), +(3780, 3, 1000123, 0, 0, 1, 5, 1, 1, 'Shadethicket Moss Eater - World Loot Level 23'), +(3781, 1, 1000123, 0, 0, 1, 5, 1, 1, 'Shadethicket Wood Shaper - World Loot Level 23'), +(3781, 2, 1000124, 0, 0, 1, 5, 1, 1, 'Shadethicket Wood Shaper - World Loot Level 24'), +(3782, 1, 1000125, 0, 0, 1, 5, 1, 1, 'Shadethicket Stone Mover - World Loot Level 25'), +(3782, 2, 1000126, 0, 0, 1, 5, 1, 1, 'Shadethicket Stone Mover - World Loot Level 26'), +(3783, 1, 1000122, 0, 0, 1, 5, 1, 1, 'Shadethicket Raincaller - World Loot Level 22'), +(3783, 2, 1000123, 0, 0, 1, 5, 1, 1, 'Shadethicket Raincaller - World Loot Level 23'), +(3784, 1, 1000126, 0, 0, 1, 5, 1, 1, 'Shadethicket Bark Ripper - World Loot Level 26'), +(3784, 2, 1000127, 0, 0, 1, 5, 1, 1, 'Shadethicket Bark Ripper - World Loot Level 27'), +(3789, 1, 1000028, 0, 0, 1, 5, 1, 1, 'Terrowulf Fleshripper - World Loot Level 28'), +(3789, 2, 1000029, 0, 0, 1, 5, 1, 1, 'Terrowulf Fleshripper - World Loot Level 29'), +(3791, 1, 1000029, 0, 0, 1, 5, 1, 1, 'Terrowulf Shadow Weaver - World Loot Level 29'), +(3791, 2, 1000030, 0, 0, 1, 5, 1, 1, 'Terrowulf Shadow Weaver - World Loot Level 30'), +(3809, 1, 1000021, 0, 0, 1, 5, 1, 1, 'Ashenvale Bear - World Loot Level 21'), +(3809, 2, 1000022, 0, 0, 1, 5, 1, 1, 'Ashenvale Bear - World Loot Level 22'), +(3810, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Elder Ashenvale Bear - World Loot Level 25'), +(3810, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Elder Ashenvale Bear - World Loot Level 26'), +(3811, 1, 1000029, 0, 0, 1, 5, 1, 1, 'Giant Ashenvale Bear - World Loot Level 29'), +(3811, 2, 1000030, 0, 0, 1, 5, 1, 1, 'Giant Ashenvale Bear - World Loot Level 30'), +(3812, 1, 1000019, 0, 0, 1, 5, 1, 1, 'Clattering Crawler - World Loot Level 19'), +(3812, 2, 1000020, 0, 0, 1, 5, 1, 1, 'Clattering Crawler - World Loot Level 20'), +(3814, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Spined Crawler - World Loot Level 20'), +(3814, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Spined Crawler - World Loot Level 21'), +(3815, 1, 1000026, 0, 0, 1, 5, 1, 1, 'Blink Dragon - World Loot Level 26'), +(3816, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Wild Buck - World Loot Level 18'), +(3816, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Wild Buck - World Loot Level 19'), +(3817, 1, 1000022, 0, 0, 1, 5, 1, 1, 'Shadowhorn Stag - World Loot Level 22'), +(3817, 2, 1000023, 0, 0, 1, 5, 1, 1, 'Shadowhorn Stag - World Loot Level 23'), +(3818, 1, 1000026, 0, 0, 1, 5, 1, 1, 'Elder Shadowhorn Stag - World Loot Level 26'), +(3818, 2, 1000027, 0, 0, 1, 5, 1, 1, 'Elder Shadowhorn Stag - World Loot Level 27'), +(3820, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Wildthorn Venomspitter - World Loot Level 24'), +(3820, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Wildthorn Venomspitter - World Loot Level 25'), +(3821, 1, 1000028, 0, 0, 1, 5, 1, 1, 'Wildthorn Lurker - World Loot Level 28'), +(3821, 2, 1000029, 0, 0, 1, 5, 1, 1, 'Wildthorn Lurker - World Loot Level 29'), +(3824, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Ghostpaw Howler - World Loot Level 23'), +(3824, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Ghostpaw Howler - World Loot Level 24'), +(3825, 1, 1000027, 0, 0, 1, 5, 1, 1, 'Ghostpaw Alpha - World Loot Level 27'), +(3825, 2, 1000028, 0, 0, 1, 5, 1, 1, 'Ghostpaw Alpha - World Loot Level 28'), +(3834, 1, 1000127, 0, 0, 1, 5, 1, 1, 'Crazed Ancient - World Loot Level 27'), +(3834, 2, 1000128, 0, 0, 1, 5, 1, 1, 'Crazed Ancient - World Loot Level 28'), +(3919, 1, 1000126, 0, 0, 1, 5, 1, 1, 'Withered Ancient - World Loot Level 26'), +(3919, 2, 1000127, 0, 0, 1, 5, 1, 1, 'Withered Ancient - World Loot Level 27'), +(3928, 1, 1000020, 0, 0, 1, 5, 1, 1, 'Rotting Slime - World Loot Level 20'), +(3928, 2, 1000021, 0, 0, 1, 5, 1, 1, 'Rotting Slime - World Loot Level 21'), +(3928, 3, 1000022, 0, 0, 1, 5, 1, 1, 'Rotting Slime - World Loot Level 22'), +(3931, 1, 1000130, 0, 0, 1, 5, 1, 1, 'Shadethicket Oracle - World Loot Level 30'), +(3943, 1, 1000122, 0, 0, 1, 5, 1, 1, 'Ruuzel - World Loot Level 22'), +(3944, 1, 1000120, 0, 0, 1, 5, 1, 1, 'Wrathtail Priestess - World Loot Level 20'), +(3944, 2, 1000121, 0, 0, 1, 5, 1, 1, 'Wrathtail Priestess - World Loot Level 21'), +(4005, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Deepmoss Creeper - World Loot Level 16'), +(4005, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Deepmoss Creeper - World Loot Level 17'), +(4006, 1, 1000019, 0, 0, 1, 5, 1, 1, 'Deepmoss Webspinner - World Loot Level 19'), +(4006, 2, 1000020, 0, 0, 1, 5, 1, 1, 'Deepmoss Webspinner - World Loot Level 20'), +(4007, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Deepmoss Venomspitter - World Loot Level 17'), +(4007, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Deepmoss Venomspitter - World Loot Level 18'), +(4008, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Cliff Stormer - World Loot Level 15'), +(4008, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Cliff Stormer - World Loot Level 16'), +(4008, 3, 1000017, 0, 0, 1, 5, 1, 1, 'Cliff Stormer - World Loot Level 17'), +(4009, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Raging Cliff Stormer - World Loot Level 18'), +(4009, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Raging Cliff Stormer - World Loot Level 19'), +(4011, 1, 1000019, 0, 0, 1, 5, 1, 1, 'Young Pridewing - World Loot Level 19'), +(4011, 2, 1000020, 0, 0, 1, 5, 1, 1, 'Young Pridewing - World Loot Level 20'), +(4012, 1, 1000021, 0, 0, 1, 5, 1, 1, 'Pridewing Wyvern - World Loot Level 21'), +(4012, 2, 1000022, 0, 0, 1, 5, 1, 1, 'Pridewing Wyvern - World Loot Level 22'), +(4014, 1, 1000022, 0, 0, 1, 5, 1, 1, 'Pridewing Consort - World Loot Level 22'), +(4014, 2, 1000023, 0, 0, 1, 5, 1, 1, 'Pridewing Consort - World Loot Level 23'), +(4016, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Fey Dragon - World Loot Level 24'), +(4016, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Fey Dragon - World Loot Level 25'), +(4017, 1, 1000026, 0, 0, 1, 5, 1, 1, 'Wily Fey Dragon - World Loot Level 26'), +(4017, 2, 1000027, 0, 0, 1, 5, 1, 1, 'Wily Fey Dragon - World Loot Level 27'), +(4018, 1, 1000022, 0, 0, 1, 5, 1, 1, 'Antlered Courser - World Loot Level 22'), +(4018, 2, 1000023, 0, 0, 1, 5, 1, 1, 'Antlered Courser - World Loot Level 23'), +(4019, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Great Courser - World Loot Level 24'), +(4019, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Great Courser - World Loot Level 25'), +(4020, 1, 1000022, 0, 0, 1, 5, 1, 1, 'Sap Beast - World Loot Level 22'), +(4020, 2, 1000023, 0, 0, 1, 5, 1, 1, 'Sap Beast - World Loot Level 23'), +(4021, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Corrosive Sap Beast - World Loot Level 24'), +(4021, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Corrosive Sap Beast - World Loot Level 25'), +(4028, 1, 1000125, 0, 0, 1, 5, 1, 1, 'Charred Ancient - World Loot Level 25'), +(4028, 2, 1000126, 0, 0, 1, 5, 1, 1, 'Charred Ancient - World Loot Level 26'), +(4029, 1, 1000127, 0, 0, 1, 5, 1, 1, 'Blackened Ancient - World Loot Level 27'), +(4029, 2, 1000128, 0, 0, 1, 5, 1, 1, 'Blackened Ancient - World Loot Level 28'), +(4031, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Fledgling Chimaera - World Loot Level 25'), +(4031, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Fledgling Chimaera - World Loot Level 26'), +(4031, 3, 1000027, 0, 0, 1, 5, 1, 1, 'Fledgling Chimaera - World Loot Level 27'), +(4032, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Young Chimaera - World Loot Level 23'), +(4032, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Young Chimaera - World Loot Level 24'), +(4032, 3, 1000025, 0, 0, 1, 5, 1, 1, 'Young Chimaera - World Loot Level 25'), +(4034, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Enraged Stone Spirit - World Loot Level 24'), +(4034, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Enraged Stone Spirit - World Loot Level 25'), +(4035, 1, 1000026, 0, 0, 1, 5, 1, 1, 'Furious Stone Spirit - World Loot Level 26'), +(4035, 2, 1000027, 0, 0, 1, 5, 1, 1, 'Furious Stone Spirit - World Loot Level 27'), +(4036, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Rogue Flame Spirit - World Loot Level 23'), +(4036, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Rogue Flame Spirit - World Loot Level 24'), +(4037, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Burning Ravager - World Loot Level 24'), +(4037, 2, 1000025, 0, 0, 1, 5, 1, 1, 'Burning Ravager - World Loot Level 25'), +(4038, 1, 1000026, 0, 0, 1, 5, 1, 1, 'Burning Destroyer - World Loot Level 26'), +(4038, 2, 1000027, 0, 0, 1, 5, 1, 1, 'Burning Destroyer - World Loot Level 27'), +(4041, 1, 1000027, 0, 0, 1, 5, 1, 1, 'Scorched Basilisk - World Loot Level 27'), +(4041, 2, 1000028, 0, 0, 1, 5, 1, 1, 'Scorched Basilisk - World Loot Level 28'), +(4044, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Blackened Basilisk - World Loot Level 23'), +(4044, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Blackened Basilisk - World Loot Level 24'), +(4067, 1, 1000023, 0, 0, 1, 5, 1, 1, 'Twilight Runner - World Loot Level 23'), +(4067, 2, 1000024, 0, 0, 1, 5, 1, 1, 'Twilight Runner - World Loot Level 24'), +(4110, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Highperch Patriarch - World Loot Level 30'), +(4110, 2, 1000031, 0, 0, 1, 5, 1, 1, 'Highperch Patriarch - World Loot Level 31'), +(4117, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Cloud Serpent - World Loot Level 25'), +(4117, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Cloud Serpent - World Loot Level 26'), +(4118, 1, 1000026, 0, 0, 1, 5, 1, 1, 'Venomous Cloud Serpent - World Loot Level 26'), +(4118, 2, 1000027, 0, 0, 1, 5, 1, 1, 'Venomous Cloud Serpent - World Loot Level 27'), +(4118, 3, 1000028, 0, 0, 1, 5, 1, 1, 'Venomous Cloud Serpent - World Loot Level 28'), +(4119, 1, 1000027, 0, 0, 1, 5, 1, 1, 'Elder Cloud Serpent - World Loot Level 27'), +(4119, 2, 1000028, 0, 0, 1, 5, 1, 1, 'Elder Cloud Serpent - World Loot Level 28'), +(4119, 3, 1000029, 0, 0, 1, 5, 1, 1, 'Elder Cloud Serpent - World Loot Level 29'), +(4120, 1, 1000028, 0, 0, 1, 5, 1, 1, 'Thundering Boulderkin - World Loot Level 28'), +(4120, 2, 1000029, 0, 0, 1, 5, 1, 1, 'Thundering Boulderkin - World Loot Level 29'), +(4124, 1, 1000027, 0, 0, 1, 5, 1, 1, 'Needles Cougar - World Loot Level 27'), +(4124, 2, 1000028, 0, 0, 1, 5, 1, 1, 'Needles Cougar - World Loot Level 28'), +(4126, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Crag Stalker - World Loot Level 25'), +(4126, 2, 1000026, 0, 0, 1, 5, 1, 1, 'Crag Stalker - World Loot Level 26'), +(4127, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Hecklefang Hyena - World Loot Level 15'), +(4127, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Hecklefang Hyena - World Loot Level 16'), +(4128, 1, 1000022, 0, 0, 1, 5, 1, 1, 'Hecklefang Stalker - World Loot Level 22'), +(4128, 2, 1000023, 0, 0, 1, 5, 1, 1, 'Hecklefang Stalker - World Loot Level 23'), +(4129, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Hecklefang Snarler - World Loot Level 18'), +(4129, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Hecklefang Snarler - World Loot Level 19'), +(4139, 1, 1000033, 0, 0, 1, 5, 1, 1, 'Scorpid Terror - World Loot Level 33'), +(4139, 2, 1000034, 0, 0, 1, 5, 1, 1, 'Scorpid Terror - World Loot Level 34'), +(4140, 1, 1000031, 0, 0, 1, 5, 1, 1, 'Scorpid Reaver - World Loot Level 31'), +(4140, 2, 1000032, 0, 0, 1, 5, 1, 1, 'Scorpid Reaver - World Loot Level 32'), +(4142, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Sparkleshell Tortoise - World Loot Level 30'), +(4142, 2, 1000031, 0, 0, 1, 5, 1, 1, 'Sparkleshell Tortoise - World Loot Level 31'), +(4143, 1, 1000034, 0, 0, 1, 5, 1, 1, 'Sparkleshell Snapper - World Loot Level 34'), +(4143, 2, 1000035, 0, 0, 1, 5, 1, 1, 'Sparkleshell Snapper - World Loot Level 35'), +(4144, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Sparkleshell Borer - World Loot Level 32'), +(4144, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Sparkleshell Borer - World Loot Level 33'), +(4147, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Saltstone Basilisk - World Loot Level 30'), +(4147, 2, 1000031, 0, 0, 1, 5, 1, 1, 'Saltstone Basilisk - World Loot Level 31'), +(4150, 1, 1000034, 0, 0, 1, 5, 1, 1, 'Saltstone Gazer - World Loot Level 34'), +(4150, 2, 1000035, 0, 0, 1, 5, 1, 1, 'Saltstone Gazer - World Loot Level 35'), +(4151, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Saltstone Crystalhide - World Loot Level 32'), +(4151, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Saltstone Crystalhide - World Loot Level 33'), +(4154, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Salt Flats Scavenger - World Loot Level 30'), +(4154, 2, 1000031, 0, 0, 1, 5, 1, 1, 'Salt Flats Scavenger - World Loot Level 31'), +(4154, 3, 1000032, 0, 0, 1, 5, 1, 1, 'Salt Flats Scavenger - World Loot Level 32'), +(4158, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Salt Flats Vulture - World Loot Level 32'), +(4158, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Salt Flats Vulture - World Loot Level 33'), +(4158, 3, 1000034, 0, 0, 1, 5, 1, 1, 'Salt Flats Vulture - World Loot Level 34'), +(4248, 1, 1000026, 0, 0, 1, 5, 1, 1, 'Pesterhide Hyena - World Loot Level 26'), +(4248, 2, 1000027, 0, 0, 1, 5, 1, 1, 'Pesterhide Hyena - World Loot Level 27'), +(4249, 1, 1000028, 0, 0, 1, 5, 1, 1, 'Pesterhide Snarler - World Loot Level 28'), +(4249, 2, 1000029, 0, 0, 1, 5, 1, 1, 'Pesterhide Snarler - World Loot Level 29'), +(4250, 1, 1000024, 0, 0, 1, 5, 1, 1, 'Galak Packhound - World Loot Level 24'), +(4316, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Kolkar Packhound - World Loot Level 13'), +(4323, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Searing Hatchling - World Loot Level 39'), +(4323, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Searing Hatchling - World Loot Level 40'), +(4324, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Searing Whelp - World Loot Level 39'), +(4324, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Searing Whelp - World Loot Level 40'), +(4328, 1, 1000140, 0, 0, 1, 5, 1, 1, 'Firemane Scalebane - World Loot Level 40'), +(4328, 2, 1000141, 0, 0, 1, 5, 1, 1, 'Firemane Scalebane - World Loot Level 41'), +(4329, 1, 1000139, 0, 0, 1, 5, 1, 1, 'Firemane Scout - World Loot Level 39'), +(4329, 2, 1000140, 0, 0, 1, 5, 1, 1, 'Firemane Scout - World Loot Level 40'), +(4331, 1, 1000140, 0, 0, 1, 5, 1, 1, 'Firemane Ash Tail - World Loot Level 40'), +(4331, 2, 1000141, 0, 0, 1, 5, 1, 1, 'Firemane Ash Tail - World Loot Level 41'), +(4334, 1, 1000141, 0, 0, 1, 5, 1, 1, 'Firemane Flamecaller - World Loot Level 41'), +(4334, 2, 1000142, 0, 0, 1, 5, 1, 1, 'Firemane Flamecaller - World Loot Level 42'), +(4341, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Drywallow Crocolisk - World Loot Level 35'), +(4341, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Drywallow Crocolisk - World Loot Level 36'), +(4343, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Drywallow Snapper - World Loot Level 37'), +(4343, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Drywallow Snapper - World Loot Level 38'), +(4344, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Mottled Drywallow Crocolisk - World Loot Level 38'), +(4344, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Mottled Drywallow Crocolisk - World Loot Level 39'), +(4345, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Drywallow Daggermaw - World Loot Level 39'), +(4345, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Drywallow Daggermaw - World Loot Level 40'), +(4346, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Noxious Flayer - World Loot Level 35'), +(4346, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Noxious Flayer - World Loot Level 36'), +(4347, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Noxious Reaver - World Loot Level 37'), +(4347, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Noxious Reaver - World Loot Level 38'), +(4348, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Noxious Shredder - World Loot Level 38'), +(4348, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Noxious Shredder - World Loot Level 39'), +(4351, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Bloodfen Raptor - World Loot Level 36'), +(4351, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Bloodfen Raptor - World Loot Level 37'), +(4352, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Bloodfen Screecher - World Loot Level 36'), +(4352, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Bloodfen Screecher - World Loot Level 37'), +(4356, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Bloodfen Razormaw - World Loot Level 39'), +(4357, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Bloodfen Lashtail - World Loot Level 38'), +(4357, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Bloodfen Lashtail - World Loot Level 39'), +(4359, 1, 1000136, 0, 0, 1, 5, 1, 1, 'Mirefin Murloc - World Loot Level 36'), +(4359, 2, 1000137, 0, 0, 1, 5, 1, 1, 'Mirefin Murloc - World Loot Level 37'), +(4361, 1, 1000136, 0, 0, 1, 5, 1, 1, 'Mirefin Muckdweller - World Loot Level 36'), +(4361, 2, 1000137, 0, 0, 1, 5, 1, 1, 'Mirefin Muckdweller - World Loot Level 37'), +(4362, 1, 1000136, 0, 0, 1, 5, 1, 1, 'Mirefin Coastrunner - World Loot Level 36'), +(4362, 2, 1000137, 0, 0, 1, 5, 1, 1, 'Mirefin Coastrunner - World Loot Level 37'), +(4363, 1, 1000136, 0, 0, 1, 5, 1, 1, 'Mirefin Oracle - World Loot Level 36'), +(4363, 2, 1000137, 0, 0, 1, 5, 1, 1, 'Mirefin Oracle - World Loot Level 37'), +(4376, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Darkmist Spider - World Loot Level 36'), +(4376, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Darkmist Spider - World Loot Level 37'), +(4378, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Darkmist Recluse - World Loot Level 36'), +(4378, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Darkmist Recluse - World Loot Level 37'), +(4379, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Darkmist Silkspinner - World Loot Level 36'), +(4379, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Darkmist Silkspinner - World Loot Level 37'), +(4382, 1, 1000136, 0, 0, 1, 5, 1, 1, 'Withervine Creeper - World Loot Level 36'), +(4382, 2, 1000137, 0, 0, 1, 5, 1, 1, 'Withervine Creeper - World Loot Level 37'), +(4385, 1, 1000136, 0, 0, 1, 5, 1, 1, 'Withervine Rager - World Loot Level 36'), +(4385, 2, 1000137, 0, 0, 1, 5, 1, 1, 'Withervine Rager - World Loot Level 37'), +(4387, 1, 1000137, 0, 0, 1, 5, 1, 1, 'Withervine Mire Beast - World Loot Level 37'), +(4387, 2, 1000138, 0, 0, 1, 5, 1, 1, 'Withervine Mire Beast - World Loot Level 38'), +(4388, 1, 1000034, 0, 0, 1, 5, 1, 1, 'Young Murk Thresher - World Loot Level 34'), +(4388, 2, 1000035, 0, 0, 1, 5, 1, 1, 'Young Murk Thresher - World Loot Level 35'), +(4389, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Murk Thresher - World Loot Level 36'), +(4389, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Murk Thresher - World Loot Level 37'), +(4390, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Elder Murk Thresher - World Loot Level 37'), +(4390, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Elder Murk Thresher - World Loot Level 38'), +(4393, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Acidic Swamp Ooze - World Loot Level 39'), +(4393, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Acidic Swamp Ooze - World Loot Level 40'), +(4393, 3, 1000041, 0, 0, 1, 5, 1, 1, 'Acidic Swamp Ooze - World Loot Level 41'), +(4394, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Bubbling Swamp Ooze - World Loot Level 39'), +(4394, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Bubbling Swamp Ooze - World Loot Level 40'), +(4397, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Mudrock Spikeshell - World Loot Level 35'), +(4397, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Mudrock Spikeshell - World Loot Level 36'), +(4401, 1, 1000135, 0, 0, 1, 5, 1, 1, 'Muckshell Clacker - World Loot Level 35'), +(4401, 2, 1000136, 0, 0, 1, 5, 1, 1, 'Muckshell Clacker - World Loot Level 36'), +(4403, 1, 1000135, 0, 0, 1, 5, 1, 1, 'Muckshell Pincer - World Loot Level 35'), +(4403, 2, 1000136, 0, 0, 1, 5, 1, 1, 'Muckshell Pincer - World Loot Level 36'), +(4404, 1, 1000135, 0, 0, 1, 5, 1, 1, 'Muckshell Scrabbler - World Loot Level 35'), +(4404, 2, 1000136, 0, 0, 1, 5, 1, 1, 'Muckshell Scrabbler - World Loot Level 36'), +(4412, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Darkfang Creeper - World Loot Level 37'), +(4412, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Darkfang Creeper - World Loot Level 38'), +(4414, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Darkfang Venomspitter - World Loot Level 36'), +(4414, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Darkfang Venomspitter - World Loot Level 37'), +(4415, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Giant Darkfang Spider - World Loot Level 39'), +(4415, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Giant Darkfang Spider - World Loot Level 40'), +(4457, 1, 1000135, 0, 0, 1, 5, 1, 1, 'Murkgill Forager - World Loot Level 35'), +(4457, 2, 1000136, 0, 0, 1, 5, 1, 1, 'Murkgill Forager - World Loot Level 36'), +(4458, 1, 1000135, 0, 0, 1, 5, 1, 1, 'Murkgill Hunter - World Loot Level 35'), +(4458, 2, 1000136, 0, 0, 1, 5, 1, 1, 'Murkgill Hunter - World Loot Level 36'), +(4459, 1, 1000136, 0, 0, 1, 5, 1, 1, 'Murkgill Oracle - World Loot Level 36'), +(4459, 2, 1000137, 0, 0, 1, 5, 1, 1, 'Murkgill Oracle - World Loot Level 37'), +(4460, 1, 1000137, 0, 0, 1, 5, 1, 1, 'Murkgill Lord - World Loot Level 37'), +(4461, 1, 1000135, 0, 0, 1, 5, 1, 1, 'Murkgill Warrior - World Loot Level 35'), +(4461, 2, 1000136, 0, 0, 1, 5, 1, 1, 'Murkgill Warrior - World Loot Level 36'), +(4468, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Jade Sludge - World Loot Level 47'), +(4468, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Jade Sludge - World Loot Level 48'), +(4469, 1, 1000046, 0, 0, 1, 5, 1, 1, 'Emerald Ooze - World Loot Level 46'), +(4469, 2, 1000047, 0, 0, 1, 5, 1, 1, 'Emerald Ooze - World Loot Level 47'), +(4499, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Rok\'Alim the Pounder - World Loot Level 30'), +(4548, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Steelsnap - World Loot Level 30'), +(4662, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Magram Bonepaw - World Loot Level 37'), +(4662, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Magram Bonepaw - World Loot Level 38'), +(4676, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Lesser Infernal - World Loot Level 36'), +(4676, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Lesser Infernal - World Loot Level 37'), +(4678, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Mana Eater - World Loot Level 37'), +(4678, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Mana Eater - World Loot Level 38'), +(4681, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Mage Hunter - World Loot Level 38'), +(4681, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Mage Hunter - World Loot Level 39'), +(4685, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Ley Hunter - World Loot Level 39'), +(4685, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Ley Hunter - World Loot Level 40'), +(4692, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Dread Swoop - World Loot Level 32'), +(4692, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Dread Swoop - World Loot Level 33'), +(4693, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Dread Flyer - World Loot Level 36'), +(4693, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Dread Flyer - World Loot Level 37'), +(4694, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Dread Ripper - World Loot Level 39'), +(4694, 2, 1000040, 0, 0, 1, 5, 1, 1, 'Dread Ripper - World Loot Level 40'), +(4695, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Carrion Horror - World Loot Level 35'), +(4695, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Carrion Horror - World Loot Level 36'), +(4695, 3, 1000037, 0, 0, 1, 5, 1, 1, 'Carrion Horror - World Loot Level 37'), +(4696, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Scorpashi Snapper - World Loot Level 30'), +(4696, 2, 1000031, 0, 0, 1, 5, 1, 1, 'Scorpashi Snapper - World Loot Level 31'), +(4697, 1, 1000034, 0, 0, 1, 5, 1, 1, 'Scorpashi Lasher - World Loot Level 34'), +(4697, 2, 1000035, 0, 0, 1, 5, 1, 1, 'Scorpashi Lasher - World Loot Level 35'), +(4699, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Scorpashi Venomlash - World Loot Level 38'), +(4699, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Scorpashi Venomlash - World Loot Level 39'), +(4700, 1, 1000034, 0, 0, 1, 5, 1, 1, 'Aged Kodo - World Loot Level 34'), +(4700, 2, 1000035, 0, 0, 1, 5, 1, 1, 'Aged Kodo - World Loot Level 35'), +(4701, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Dying Kodo - World Loot Level 35'), +(4701, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Dying Kodo - World Loot Level 36'), +(4702, 1, 1000036, 0, 0, 1, 5, 1, 1, 'Ancient Kodo - World Loot Level 36'), +(4702, 2, 1000037, 0, 0, 1, 5, 1, 1, 'Ancient Kodo - World Loot Level 37'), +(4711, 1, 1000132, 0, 0, 1, 5, 1, 1, 'Slitherblade Naga - World Loot Level 32'), +(4711, 2, 1000133, 0, 0, 1, 5, 1, 1, 'Slitherblade Naga - World Loot Level 33'), +(4712, 1, 1000132, 0, 0, 1, 5, 1, 1, 'Slitherblade Sorceress - World Loot Level 32'), +(4712, 2, 1000133, 0, 0, 1, 5, 1, 1, 'Slitherblade Sorceress - World Loot Level 33'), +(4713, 1, 1000133, 0, 0, 1, 5, 1, 1, 'Slitherblade Warrior - World Loot Level 33'), +(4713, 2, 1000134, 0, 0, 1, 5, 1, 1, 'Slitherblade Warrior - World Loot Level 34'), +(4714, 1, 1000134, 0, 0, 1, 5, 1, 1, 'Slitherblade Myrmidon - World Loot Level 34'), +(4714, 2, 1000135, 0, 0, 1, 5, 1, 1, 'Slitherblade Myrmidon - World Loot Level 35'), +(4715, 1, 1000135, 0, 0, 1, 5, 1, 1, 'Slitherblade Razortail - World Loot Level 35'), +(4715, 2, 1000136, 0, 0, 1, 5, 1, 1, 'Slitherblade Razortail - World Loot Level 36'), +(4716, 1, 1000136, 0, 0, 1, 5, 1, 1, 'Slitherblade Tidehunter - World Loot Level 36'), +(4716, 2, 1000137, 0, 0, 1, 5, 1, 1, 'Slitherblade Tidehunter - World Loot Level 37'), +(4718, 1, 1000134, 0, 0, 1, 5, 1, 1, 'Slitherblade Oracle - World Loot Level 34'), +(4719, 1, 1000135, 0, 0, 1, 5, 1, 1, 'Slitherblade Sea Witch - World Loot Level 35'), +(4719, 2, 1000136, 0, 0, 1, 5, 1, 1, 'Slitherblade Sea Witch - World Loot Level 36'), +(4726, 1, 1000033, 0, 0, 1, 5, 1, 1, 'Raging Thunder Lizard - World Loot Level 33'), +(4726, 2, 1000034, 0, 0, 1, 5, 1, 1, 'Raging Thunder Lizard - World Loot Level 34'), +(4727, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Elder Thunder Lizard - World Loot Level 37'), +(4727, 2, 1000038, 0, 0, 1, 5, 1, 1, 'Elder Thunder Lizard - World Loot Level 38'), +(4728, 1, 1000031, 0, 0, 1, 5, 1, 1, 'Gritjaw Basilisk - World Loot Level 31'), +(4728, 2, 1000032, 0, 0, 1, 5, 1, 1, 'Gritjaw Basilisk - World Loot Level 32'), +(4729, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Hulking Gritjaw Basilisk - World Loot Level 35'), +(4729, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Hulking Gritjaw Basilisk - World Loot Level 36'), +(4802, 1, 1000120, 0, 0, 1, 5, 1, 1, 'Blackfathom Tide Priestess - World Loot Level 20'), +(4802, 2, 1000121, 0, 0, 1, 5, 1, 1, 'Blackfathom Tide Priestess - World Loot Level 21'), +(4803, 1, 1000121, 0, 0, 1, 5, 1, 1, 'Blackfathom Oracle - World Loot Level 21'), +(4841, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Deadmire - World Loot Level 41'), +(4872, 1, 1000037, 0, 0, 1, 5, 1, 1, 'Obsidian Golem - World Loot Level 37'), +(5224, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Murk Slitherer - World Loot Level 45'), +(5224, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Murk Slitherer - World Loot Level 46'), +(5225, 1, 1000046, 0, 0, 1, 5, 1, 1, 'Murk Spitter - World Loot Level 46'), +(5225, 2, 1000047, 0, 0, 1, 5, 1, 1, 'Murk Spitter - World Loot Level 47'), +(5235, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Fungal Ooze - World Loot Level 45'), +(5235, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Fungal Ooze - World Loot Level 46'), +(5244, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Zukk\'ash Stinger - World Loot Level 45'), +(5244, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Zukk\'ash Stinger - World Loot Level 46'), +(5245, 1, 1000044, 0, 0, 1, 5, 1, 1, 'Zukk\'ash Wasp - World Loot Level 44'), +(5245, 2, 1000045, 0, 0, 1, 5, 1, 1, 'Zukk\'ash Wasp - World Loot Level 45'), +(5246, 1, 1000044, 0, 0, 1, 5, 1, 1, 'Zukk\'ash Worker - World Loot Level 44'), +(5246, 2, 1000045, 0, 0, 1, 5, 1, 1, 'Zukk\'ash Worker - World Loot Level 45'), +(5247, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Zukk\'ash Tunneler - World Loot Level 45'), +(5247, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Zukk\'ash Tunneler - World Loot Level 46'), +(5260, 1, 1000042, 0, 0, 1, 5, 1, 1, 'Groddoc Ape - World Loot Level 42'), +(5260, 2, 1000043, 0, 0, 1, 5, 1, 1, 'Groddoc Ape - World Loot Level 43'), +(5262, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Groddoc Thunderer - World Loot Level 49'), +(5262, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Groddoc Thunderer - World Loot Level 50'), +(5268, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Ironfur Bear - World Loot Level 41'), +(5268, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Ironfur Bear - World Loot Level 42'), +(5272, 1, 1000044, 0, 0, 1, 5, 1, 1, 'Grizzled Ironfur Bear - World Loot Level 44'), +(5272, 2, 1000045, 0, 0, 1, 5, 1, 1, 'Grizzled Ironfur Bear - World Loot Level 45'), +(5274, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Ironfur Patriarch - World Loot Level 48'), +(5274, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Ironfur Patriarch - World Loot Level 49'), +(5278, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Sprite Darter - World Loot Level 43'), +(5278, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Sprite Darter - World Loot Level 44'), +(5278, 3, 1000045, 0, 0, 1, 5, 1, 1, 'Sprite Darter - World Loot Level 45'), +(5286, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Longtooth Runner - World Loot Level 40'), +(5286, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Longtooth Runner - World Loot Level 41'), +(5287, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Longtooth Howler - World Loot Level 43'), +(5287, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Longtooth Howler - World Loot Level 44'), +(5288, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Rabid Longtooth - World Loot Level 47'), +(5288, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Rabid Longtooth - World Loot Level 48'), +(5292, 1, 1000143, 0, 0, 1, 5, 1, 1, 'Feral Scar Yeti - World Loot Level 43'), +(5292, 2, 1000144, 0, 0, 1, 5, 1, 1, 'Feral Scar Yeti - World Loot Level 44'), +(5293, 1, 1000145, 0, 0, 1, 5, 1, 1, 'Hulking Feral Scar - World Loot Level 45'), +(5293, 2, 1000146, 0, 0, 1, 5, 1, 1, 'Hulking Feral Scar - World Loot Level 46'), +(5295, 1, 1000144, 0, 0, 1, 5, 1, 1, 'Enraged Feral Scar - World Loot Level 44'), +(5296, 1, 1000146, 0, 0, 1, 5, 1, 1, 'Rage Scar Yeti - World Loot Level 46'), +(5296, 2, 1000147, 0, 0, 1, 5, 1, 1, 'Rage Scar Yeti - World Loot Level 47'), +(5297, 1, 1000148, 0, 0, 1, 5, 1, 1, 'Elder Rage Scar - World Loot Level 48'), +(5297, 2, 1000149, 0, 0, 1, 5, 1, 1, 'Elder Rage Scar - World Loot Level 49'), +(5299, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Ferocious Rage Scar - World Loot Level 47'), +(5299, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Ferocious Rage Scar - World Loot Level 48'), +(5300, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Frayfeather Hippogryph - World Loot Level 43'), +(5300, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Frayfeather Hippogryph - World Loot Level 44'), +(5304, 1, 1000044, 0, 0, 1, 5, 1, 1, 'Frayfeather Stagwing - World Loot Level 44'), +(5304, 2, 1000045, 0, 0, 1, 5, 1, 1, 'Frayfeather Stagwing - World Loot Level 45'), +(5305, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Frayfeather Skystormer - World Loot Level 45'), +(5305, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Frayfeather Skystormer - World Loot Level 46'), +(5306, 1, 1000046, 0, 0, 1, 5, 1, 1, 'Frayfeather Patriarch - World Loot Level 46'), +(5306, 2, 1000047, 0, 0, 1, 5, 1, 1, 'Frayfeather Patriarch - World Loot Level 47'), +(5307, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Vale Screecher - World Loot Level 41'), +(5307, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Vale Screecher - World Loot Level 42'), +(5307, 3, 1000043, 0, 0, 1, 5, 1, 1, 'Vale Screecher - World Loot Level 43'), +(5308, 1, 1000044, 0, 0, 1, 5, 1, 1, 'Rogue Vale Screecher - World Loot Level 44'), +(5308, 2, 1000045, 0, 0, 1, 5, 1, 1, 'Rogue Vale Screecher - World Loot Level 45'), +(5308, 3, 1000046, 0, 0, 1, 5, 1, 1, 'Rogue Vale Screecher - World Loot Level 46'), +(5327, 1, 1000044, 0, 0, 1, 5, 1, 1, 'Coast Crawl Snapclaw - World Loot Level 44'), +(5327, 2, 1000045, 0, 0, 1, 5, 1, 1, 'Coast Crawl Snapclaw - World Loot Level 45'), +(5328, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Coast Crawl Deepseer - World Loot Level 43'), +(5328, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Coast Crawl Deepseer - World Loot Level 44'), +(5331, 1, 1000142, 0, 0, 1, 5, 1, 1, 'Hatecrest Warrior - World Loot Level 42'), +(5331, 2, 1000143, 0, 0, 1, 5, 1, 1, 'Hatecrest Warrior - World Loot Level 43'), +(5332, 1, 1000141, 0, 0, 1, 5, 1, 1, 'Hatecrest Wave Rider - World Loot Level 41'), +(5332, 2, 1000142, 0, 0, 1, 5, 1, 1, 'Hatecrest Wave Rider - World Loot Level 42'), +(5333, 1, 1000144, 0, 0, 1, 5, 1, 1, 'Hatecrest Serpent Guard - World Loot Level 44'), +(5333, 2, 1000145, 0, 0, 1, 5, 1, 1, 'Hatecrest Serpent Guard - World Loot Level 45'), +(5334, 1, 1000144, 0, 0, 1, 5, 1, 1, 'Hatecrest Myrmidon - World Loot Level 44'), +(5335, 1, 1000141, 0, 0, 1, 5, 1, 1, 'Hatecrest Screamer - World Loot Level 41'), +(5335, 2, 1000142, 0, 0, 1, 5, 1, 1, 'Hatecrest Screamer - World Loot Level 42'), +(5336, 1, 1000143, 0, 0, 1, 5, 1, 1, 'Hatecrest Sorceress - World Loot Level 43'), +(5336, 2, 1000144, 0, 0, 1, 5, 1, 1, 'Hatecrest Sorceress - World Loot Level 44'), +(5337, 1, 1000142, 0, 0, 1, 5, 1, 1, 'Hatecrest Siren - World Loot Level 42'), +(5337, 2, 1000143, 0, 0, 1, 5, 1, 1, 'Hatecrest Siren - World Loot Level 43'), +(5419, 1, 1000042, 0, 0, 1, 5, 1, 1, 'Glasshide Basilisk - World Loot Level 42'), +(5419, 2, 1000043, 0, 0, 1, 5, 1, 1, 'Glasshide Basilisk - World Loot Level 43'), +(5420, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Glasshide Gazer - World Loot Level 45'), +(5420, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Glasshide Gazer - World Loot Level 46'), +(5421, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Glasshide Petrifier - World Loot Level 48'), +(5421, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Glasshide Petrifier - World Loot Level 49'), +(5422, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Scorpid Hunter - World Loot Level 40'), +(5422, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Scorpid Hunter - World Loot Level 41'), +(5423, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Scorpid Tail Lasher - World Loot Level 43'), +(5423, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Scorpid Tail Lasher - World Loot Level 44'), +(5424, 1, 1000046, 0, 0, 1, 5, 1, 1, 'Scorpid Dunestalker - World Loot Level 46'), +(5424, 2, 1000047, 0, 0, 1, 5, 1, 1, 'Scorpid Dunestalker - World Loot Level 47'), +(5425, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Starving Blisterpaw - World Loot Level 41'), +(5425, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Starving Blisterpaw - World Loot Level 42'), +(5427, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Rabid Blisterpaw - World Loot Level 47'), +(5427, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Rabid Blisterpaw - World Loot Level 48'), +(5428, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Roc - World Loot Level 41'), +(5428, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Roc - World Loot Level 42'), +(5428, 3, 1000043, 0, 0, 1, 5, 1, 1, 'Roc - World Loot Level 43'), +(5430, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Searing Roc - World Loot Level 47'), +(5430, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Searing Roc - World Loot Level 48'), +(5430, 3, 1000049, 0, 0, 1, 5, 1, 1, 'Searing Roc - World Loot Level 49'), +(5431, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Surf Glider - World Loot Level 48'), +(5431, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Surf Glider - World Loot Level 49'), +(5431, 3, 1000050, 0, 0, 1, 5, 1, 1, 'Surf Glider - World Loot Level 50'), +(5441, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Hazzali Wasp - World Loot Level 47'), +(5441, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Hazzali Wasp - World Loot Level 48'), +(5450, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Hazzali Stinger - World Loot Level 49'), +(5450, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Hazzali Stinger - World Loot Level 50'), +(5451, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Hazzali Swarmer - World Loot Level 49'), +(5451, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Hazzali Swarmer - World Loot Level 50'), +(5452, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Hazzali Worker - World Loot Level 47'), +(5452, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Hazzali Worker - World Loot Level 48'), +(5453, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Hazzali Tunneler - World Loot Level 48'), +(5453, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Hazzali Tunneler - World Loot Level 49'), +(5454, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Hazzali Sandreaver - World Loot Level 49'), +(5454, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Hazzali Sandreaver - World Loot Level 50'), +(5455, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Centipaar Wasp - World Loot Level 47'), +(5455, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Centipaar Wasp - World Loot Level 48'), +(5456, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Centipaar Stinger - World Loot Level 48'), +(5456, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Centipaar Stinger - World Loot Level 49'), +(5457, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Centipaar Swarmer - World Loot Level 49'), +(5457, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Centipaar Swarmer - World Loot Level 50'), +(5458, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Centipaar Worker - World Loot Level 48'), +(5458, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Centipaar Worker - World Loot Level 49'), +(5459, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Centipaar Tunneler - World Loot Level 47'), +(5459, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Centipaar Tunneler - World Loot Level 48'), +(5460, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Centipaar Sandreaver - World Loot Level 49'), +(5460, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Centipaar Sandreaver - World Loot Level 50'), +(5461, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Sea Elemental - World Loot Level 48'), +(5461, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Sea Elemental - World Loot Level 49'), +(5462, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Sea Spray - World Loot Level 47'), +(5462, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Sea Spray - World Loot Level 48'), +(5465, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Land Rager - World Loot Level 45'), +(5465, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Land Rager - World Loot Level 46'), +(5465, 3, 1000047, 0, 0, 1, 5, 1, 1, 'Land Rager - World Loot Level 47'), +(5481, 1, 1000147, 0, 0, 1, 5, 1, 1, 'Thistleshrub Dew Collector - World Loot Level 47'), +(5481, 2, 1000148, 0, 0, 1, 5, 1, 1, 'Thistleshrub Dew Collector - World Loot Level 48'), +(5485, 1, 1000149, 0, 0, 1, 5, 1, 1, 'Thistleshrub Rootshaper - World Loot Level 49'), +(5485, 2, 1000150, 0, 0, 1, 5, 1, 1, 'Thistleshrub Rootshaper - World Loot Level 50'), +(5490, 1, 1000148, 0, 0, 1, 5, 1, 1, 'Gnarled Thistleshrub - World Loot Level 48'), +(5490, 2, 1000149, 0, 0, 1, 5, 1, 1, 'Gnarled Thistleshrub - World Loot Level 49'), +(5833, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Margol the Rager - World Loot Level 43'), +(5850, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Blazing Elemental - World Loot Level 45'), +(5850, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Blazing Elemental - World Loot Level 46'), +(5850, 3, 1000047, 0, 0, 1, 5, 1, 1, 'Blazing Elemental - World Loot Level 47'), +(5852, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Inferno Elemental - World Loot Level 47'), +(5852, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Inferno Elemental - World Loot Level 48'), +(5852, 3, 1000049, 0, 0, 1, 5, 1, 1, 'Inferno Elemental - World Loot Level 49'), +(5853, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Tempered War Golem - World Loot Level 45'), +(5853, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Tempered War Golem - World Loot Level 46'), +(5853, 3, 1000047, 0, 0, 1, 5, 1, 1, 'Tempered War Golem - World Loot Level 47'), +(5855, 1, 1000046, 0, 0, 1, 5, 1, 1, 'Magma Elemental - World Loot Level 46'), +(5855, 2, 1000047, 0, 0, 1, 5, 1, 1, 'Magma Elemental - World Loot Level 47'), +(5855, 3, 1000048, 0, 0, 1, 5, 1, 1, 'Magma Elemental - World Loot Level 48'), +(5856, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Glassweb Spider - World Loot Level 43'), +(5856, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Glassweb Spider - World Loot Level 44'), +(5856, 3, 1000045, 0, 0, 1, 5, 1, 1, 'Glassweb Spider - World Loot Level 45'), +(5857, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Searing Lava Spider - World Loot Level 45'), +(5857, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Searing Lava Spider - World Loot Level 46'), +(5857, 3, 1000047, 0, 0, 1, 5, 1, 1, 'Searing Lava Spider - World Loot Level 47'), +(5858, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Greater Lava Spider - World Loot Level 47'), +(5858, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Greater Lava Spider - World Loot Level 48'), +(5858, 3, 1000049, 0, 0, 1, 5, 1, 1, 'Greater Lava Spider - World Loot Level 49'), +(5881, 1, 1000145, 0, 0, 1, 5, 1, 1, 'Cursed Sycamore - World Loot Level 45'), +(5982, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Black Slayer - World Loot Level 47'), +(5982, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Black Slayer - World Loot Level 48'), +(5983, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Bonepicker - World Loot Level 49'), +(5983, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Bonepicker - World Loot Level 50'), +(5984, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Starving Snickerfang - World Loot Level 45'), +(5984, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Starving Snickerfang - World Loot Level 46'), +(5985, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Snickerfang Hyena - World Loot Level 49'), +(5985, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Snickerfang Hyena - World Loot Level 50'), +(5988, 1, 1000046, 0, 0, 1, 5, 1, 1, 'Scorpok Stinger - World Loot Level 46'), +(5988, 2, 1000047, 0, 0, 1, 5, 1, 1, 'Scorpok Stinger - World Loot Level 47'), +(5990, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Redstone Basilisk - World Loot Level 47'), +(5990, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Redstone Basilisk - World Loot Level 48'), +(5991, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Redstone Crystalhide - World Loot Level 51'), +(5991, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Redstone Crystalhide - World Loot Level 52'), +(5992, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Ashmane Boar - World Loot Level 48'), +(5992, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Ashmane Boar - World Loot Level 49'), +(5993, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Helboar - World Loot Level 52'), +(5993, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Helboar - World Loot Level 53'), +(6010, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Felhound - World Loot Level 54'), +(6010, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Felhound - World Loot Level 55'), +(6020, 1, 1000118, 0, 0, 1, 5, 1, 1, 'Slimeshell Makrura - World Loot Level 18'), +(6020, 2, 1000119, 0, 0, 1, 5, 1, 1, 'Slimeshell Makrura - World Loot Level 19'), +(6033, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Lake Frenzy - World Loot Level 15'), +(6033, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Lake Frenzy - World Loot Level 16'), +(6073, 1, 1000029, 0, 0, 1, 5, 1, 1, 'Searing Infernal - World Loot Level 29'), +(6073, 2, 1000030, 0, 0, 1, 5, 1, 1, 'Searing Infernal - World Loot Level 30'), +(6135, 1, 1000153, 0, 0, 1, 5, 1, 1, 'Arkkoran Clacker - World Loot Level 53'), +(6135, 2, 1000154, 0, 0, 1, 5, 1, 1, 'Arkkoran Clacker - World Loot Level 54'), +(6136, 1, 1000153, 0, 0, 1, 5, 1, 1, 'Arkkoran Muckdweller - World Loot Level 53'), +(6136, 2, 1000154, 0, 0, 1, 5, 1, 1, 'Arkkoran Muckdweller - World Loot Level 54'), +(6137, 1, 1000154, 0, 0, 1, 5, 1, 1, 'Arkkoran Pincer - World Loot Level 54'), +(6137, 2, 1000155, 0, 0, 1, 5, 1, 1, 'Arkkoran Pincer - World Loot Level 55'), +(6140, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Hetaera - World Loot Level 55'), +(6167, 1, 1000028, 0, 0, 1, 5, 1, 1, 'Chimaera Matriarch - World Loot Level 28'), +(6170, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Gutspill - World Loot Level 32'), +(6193, 1, 1000147, 0, 0, 1, 5, 1, 1, 'Spitelash Screamer - World Loot Level 47'), +(6193, 2, 1000148, 0, 0, 1, 5, 1, 1, 'Spitelash Screamer - World Loot Level 48'), +(6194, 1, 1000148, 0, 0, 1, 5, 1, 1, 'Spitelash Serpent Guard - World Loot Level 48'), +(6194, 2, 1000149, 0, 0, 1, 5, 1, 1, 'Spitelash Serpent Guard - World Loot Level 49'), +(6231, 1, 1000026, 0, 0, 1, 5, 1, 1, 'Techbot - World Loot Level 26'), +(6347, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Young Wavethrasher - World Loot Level 51'), +(6347, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Young Wavethrasher - World Loot Level 52'), +(6348, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Wavethrasher - World Loot Level 52'), +(6348, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Wavethrasher - World Loot Level 53'), +(6349, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Great Wavethrasher - World Loot Level 53'), +(6349, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Great Wavethrasher - World Loot Level 54'), +(6350, 1, 1000154, 0, 0, 1, 5, 1, 1, 'Makrinni Razorclaw - World Loot Level 54'), +(6350, 2, 1000155, 0, 0, 1, 5, 1, 1, 'Makrinni Razorclaw - World Loot Level 55'), +(6351, 1, 1000154, 0, 0, 1, 5, 1, 1, 'Storm Bay Oracle - World Loot Level 54'), +(6351, 2, 1000155, 0, 0, 1, 5, 1, 1, 'Storm Bay Oracle - World Loot Level 55'), +(6352, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Coralshell Lurker - World Loot Level 53'), +(6352, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Coralshell Lurker - World Loot Level 54'), +(6369, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Coralshell Tortoise - World Loot Level 50'), +(6369, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Coralshell Tortoise - World Loot Level 51'), +(6369, 3, 1000052, 0, 0, 1, 5, 1, 1, 'Coralshell Tortoise - World Loot Level 52'), +(6370, 1, 1000152, 0, 0, 1, 5, 1, 1, 'Makrinni Scrabbler - World Loot Level 52'), +(6370, 2, 1000153, 0, 0, 1, 5, 1, 1, 'Makrinni Scrabbler - World Loot Level 53'), +(6372, 1, 1000150, 0, 0, 1, 5, 1, 1, 'Makrinni Snapclaw - World Loot Level 50'), +(6372, 2, 1000151, 0, 0, 1, 5, 1, 1, 'Makrinni Snapclaw - World Loot Level 51'), +(6375, 1, 1000046, 0, 0, 1, 5, 1, 1, 'Thunderhead Hippogryph - World Loot Level 46'), +(6375, 2, 1000047, 0, 0, 1, 5, 1, 1, 'Thunderhead Hippogryph - World Loot Level 47'), +(6375, 3, 1000048, 0, 0, 1, 5, 1, 1, 'Thunderhead Hippogryph - World Loot Level 48'), +(6377, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Thunderhead Stagwing - World Loot Level 48'), +(6377, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Thunderhead Stagwing - World Loot Level 49'), +(6377, 3, 1000050, 0, 0, 1, 5, 1, 1, 'Thunderhead Stagwing - World Loot Level 50'), +(6378, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Thunderhead Skystormer - World Loot Level 50'), +(6378, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Thunderhead Skystormer - World Loot Level 51'), +(6378, 3, 1000052, 0, 0, 1, 5, 1, 1, 'Thunderhead Skystormer - World Loot Level 52'), +(6379, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Thunderhead Patriarch - World Loot Level 52'), +(6379, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Thunderhead Patriarch - World Loot Level 53'), +(6379, 3, 1000054, 0, 0, 1, 5, 1, 1, 'Thunderhead Patriarch - World Loot Level 54'), +(6380, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Thunderhead Consort - World Loot Level 52'), +(6380, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Thunderhead Consort - World Loot Level 53'), +(6380, 3, 1000054, 0, 0, 1, 5, 1, 1, 'Thunderhead Consort - World Loot Level 54'), +(6505, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Ravasaur - World Loot Level 48'), +(6505, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Ravasaur - World Loot Level 49'), +(6506, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Ravasaur Runner - World Loot Level 49'), +(6506, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Ravasaur Runner - World Loot Level 50'), +(6507, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Ravasaur Hunter - World Loot Level 49'), +(6507, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Ravasaur Hunter - World Loot Level 50'), +(6508, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Venomhide Ravasaur - World Loot Level 50'), +(6508, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Venomhide Ravasaur - World Loot Level 51'), +(6509, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Bloodpetal Lasher - World Loot Level 48'), +(6509, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Bloodpetal Lasher - World Loot Level 49'), +(6510, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Bloodpetal Flayer - World Loot Level 51'), +(6510, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Bloodpetal Flayer - World Loot Level 52'), +(6511, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Bloodpetal Thresher - World Loot Level 49'), +(6511, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Bloodpetal Thresher - World Loot Level 50'), +(6512, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Bloodpetal Trapper - World Loot Level 52'), +(6512, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Bloodpetal Trapper - World Loot Level 53'), +(6513, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Un\'Goro Stomper - World Loot Level 51'), +(6513, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Un\'Goro Stomper - World Loot Level 52'), +(6514, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Un\'Goro Gorilla - World Loot Level 50'), +(6514, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Un\'Goro Gorilla - World Loot Level 51'), +(6516, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Un\'Goro Thunderer - World Loot Level 52'), +(6516, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Un\'Goro Thunderer - World Loot Level 53'), +(6517, 1, 1000150, 0, 0, 1, 5, 1, 1, 'Tar Beast - World Loot Level 50'), +(6517, 2, 1000151, 0, 0, 1, 5, 1, 1, 'Tar Beast - World Loot Level 51'), +(6518, 1, 1000152, 0, 0, 1, 5, 1, 1, 'Tar Lurker - World Loot Level 52'), +(6518, 2, 1000153, 0, 0, 1, 5, 1, 1, 'Tar Lurker - World Loot Level 53'), +(6518, 3, 1000154, 0, 0, 1, 5, 1, 1, 'Tar Lurker - World Loot Level 54'), +(6519, 1, 1000153, 0, 0, 1, 5, 1, 1, 'Tar Lord - World Loot Level 53'), +(6519, 2, 1000154, 0, 0, 1, 5, 1, 1, 'Tar Lord - World Loot Level 54'), +(6520, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Scorching Elemental - World Loot Level 53'), +(6520, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Scorching Elemental - World Loot Level 54'), +(6521, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Living Blaze - World Loot Level 54'), +(6521, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Living Blaze - World Loot Level 55'), +(6527, 1, 1000151, 0, 0, 1, 5, 1, 1, 'Tar Creeper - World Loot Level 51'), +(6527, 2, 1000152, 0, 0, 1, 5, 1, 1, 'Tar Creeper - World Loot Level 52'), +(6551, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Gorishi Wasp - World Loot Level 51'), +(6551, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Gorishi Wasp - World Loot Level 52'), +(6552, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Gorishi Worker - World Loot Level 51'), +(6552, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Gorishi Worker - World Loot Level 52'), +(6553, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Gorishi Reaver - World Loot Level 51'), +(6553, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Gorishi Reaver - World Loot Level 52'), +(6553, 3, 1000053, 0, 0, 1, 5, 1, 1, 'Gorishi Reaver - World Loot Level 53'), +(6554, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Gorishi Stinger - World Loot Level 52'), +(6554, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Gorishi Stinger - World Loot Level 53'), +(6555, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Gorishi Tunneler - World Loot Level 52'), +(6555, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Gorishi Tunneler - World Loot Level 53'), +(6556, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Muculent Ooze - World Loot Level 48'), +(6556, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Muculent Ooze - World Loot Level 49'), +(6556, 3, 1000050, 0, 0, 1, 5, 1, 1, 'Muculent Ooze - World Loot Level 50'), +(6557, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Primal Ooze - World Loot Level 50'), +(6557, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Primal Ooze - World Loot Level 51'), +(6557, 3, 1000052, 0, 0, 1, 5, 1, 1, 'Primal Ooze - World Loot Level 52'), +(6559, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Glutinous Ooze - World Loot Level 52'), +(6559, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Glutinous Ooze - World Loot Level 53'), +(6559, 3, 1000054, 0, 0, 1, 5, 1, 1, 'Glutinous Ooze - World Loot Level 54'), +(6788, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Den Mother - World Loot Level 18'), +(6788, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Den Mother - World Loot Level 19'), +(6789, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Thistle Cub - World Loot Level 9'), +(6789, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Thistle Cub - World Loot Level 10'), +(7031, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Obsidian Elemental - World Loot Level 52'), +(7031, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Obsidian Elemental - World Loot Level 53'), +(7032, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Greater Obsidian Elemental - World Loot Level 55'), +(7032, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Greater Obsidian Elemental - World Loot Level 56'), +(7032, 3, 1000057, 0, 0, 1, 5, 1, 1, 'Greater Obsidian Elemental - World Loot Level 57'), +(7039, 1, 1000053, 0, 0, 1, 5, 1, 1, 'War Reaver - World Loot Level 53'), +(7039, 2, 1000054, 0, 0, 1, 5, 1, 1, 'War Reaver - World Loot Level 54'), +(7039, 3, 1000055, 0, 0, 1, 5, 1, 1, 'War Reaver - World Loot Level 55'), +(7044, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Black Drake - World Loot Level 52'), +(7045, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Scalding Drake - World Loot Level 53'), +(7045, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Scalding Drake - World Loot Level 54'), +(7045, 3, 1000055, 0, 0, 1, 5, 1, 1, 'Scalding Drake - World Loot Level 55'), +(7046, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Searscale Drake - World Loot Level 56'), +(7046, 2, 1000057, 0, 0, 1, 5, 1, 1, 'Searscale Drake - World Loot Level 57'), +(7046, 3, 1000058, 0, 0, 1, 5, 1, 1, 'Searscale Drake - World Loot Level 58'), +(7047, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Black Broodling - World Loot Level 51'), +(7047, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Black Broodling - World Loot Level 52'), +(7048, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Scalding Broodling - World Loot Level 53'), +(7048, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Scalding Broodling - World Loot Level 54'), +(7049, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Flamescale Broodling - World Loot Level 55'), +(7049, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Flamescale Broodling - World Loot Level 56'), +(7086, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Cursed Ooze - World Loot Level 49'), +(7086, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Cursed Ooze - World Loot Level 50'), +(7092, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Tainted Ooze - World Loot Level 51'), +(7092, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Tainted Ooze - World Loot Level 52'), +(7093, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Vile Ooze - World Loot Level 53'), +(7097, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Ironbeak Owl - World Loot Level 48'), +(7097, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Ironbeak Owl - World Loot Level 49'), +(7098, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Ironbeak Screecher - World Loot Level 52'), +(7098, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Ironbeak Screecher - World Loot Level 53'), +(7099, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Ironbeak Hunter - World Loot Level 50'), +(7099, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Ironbeak Hunter - World Loot Level 51'), +(7100, 1, 1000152, 0, 0, 1, 5, 1, 1, 'Warpwood Moss Flayer - World Loot Level 52'), +(7100, 2, 1000153, 0, 0, 1, 5, 1, 1, 'Warpwood Moss Flayer - World Loot Level 53'), +(7101, 1, 1000153, 0, 0, 1, 5, 1, 1, 'Warpwood Shredder - World Loot Level 53'), +(7101, 2, 1000154, 0, 0, 1, 5, 1, 1, 'Warpwood Shredder - World Loot Level 54'), +(7125, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Jaedenar Hound - World Loot Level 50'), +(7125, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Jaedenar Hound - World Loot Level 51'), +(7126, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Jaedenar Hunter - World Loot Level 52'), +(7126, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Jaedenar Hunter - World Loot Level 53'), +(7132, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Toxic Horror - World Loot Level 53'), +(7132, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Toxic Horror - World Loot Level 54'), +(7136, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Infernal Sentry - World Loot Level 52'), +(7136, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Infernal Sentry - World Loot Level 53'), +(7138, 1, 1000152, 0, 0, 1, 5, 1, 1, 'Irontree Wanderer - World Loot Level 52'), +(7138, 2, 1000153, 0, 0, 1, 5, 1, 1, 'Irontree Wanderer - World Loot Level 53'), +(7139, 1, 1000152, 0, 0, 1, 5, 1, 1, 'Irontree Stomper - World Loot Level 52'), +(7139, 2, 1000153, 0, 0, 1, 5, 1, 1, 'Irontree Stomper - World Loot Level 53'), +(7149, 1, 1000155, 0, 0, 1, 5, 1, 1, 'Withered Protector - World Loot Level 55'), +(7149, 2, 1000156, 0, 0, 1, 5, 1, 1, 'Withered Protector - World Loot Level 56'), +(7319, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Lady Sathrah - World Loot Level 12'), +(7376, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Sky Shadow - World Loot Level 55'), +(7376, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Sky Shadow - World Loot Level 56'), +(7430, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Frostsaber Cub - World Loot Level 55'), +(7430, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Frostsaber Cub - World Loot Level 56'), +(7431, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Frostsaber - World Loot Level 56'), +(7431, 2, 1000057, 0, 0, 1, 5, 1, 1, 'Frostsaber - World Loot Level 57'), +(7432, 1, 1000059, 0, 0, 1, 5, 1, 1, 'Frostsaber Stalker - World Loot Level 59'), +(7432, 2, 1000060, 0, 0, 1, 5, 1, 1, 'Frostsaber Stalker - World Loot Level 60'), +(7433, 1, 1000058, 0, 0, 1, 5, 1, 1, 'Frostsaber Huntress - World Loot Level 58'), +(7433, 2, 1000059, 0, 0, 1, 5, 1, 1, 'Frostsaber Huntress - World Loot Level 59'), +(7434, 1, 1000059, 0, 0, 1, 5, 1, 1, 'Frostsaber Pride Watcher - World Loot Level 59'), +(7434, 2, 1000060, 0, 0, 1, 5, 1, 1, 'Frostsaber Pride Watcher - World Loot Level 60'), +(7443, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Shardtooth Mauler - World Loot Level 55'), +(7443, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Shardtooth Mauler - World Loot Level 56'), +(7444, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Shardtooth Bear - World Loot Level 53'), +(7444, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Shardtooth Bear - World Loot Level 54'), +(7445, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Elder Shardtooth - World Loot Level 57'), +(7445, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Elder Shardtooth - World Loot Level 58'), +(7446, 1, 1000059, 0, 0, 1, 5, 1, 1, 'Rabid Shardtooth - World Loot Level 59'), +(7446, 2, 1000060, 0, 0, 1, 5, 1, 1, 'Rabid Shardtooth - World Loot Level 60'), +(7448, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Chillwind Chimaera - World Loot Level 55'), +(7448, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Chillwind Chimaera - World Loot Level 56'), +(7448, 3, 1000057, 0, 0, 1, 5, 1, 1, 'Chillwind Chimaera - World Loot Level 57'), +(7449, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Chillwind Ravager - World Loot Level 57'), +(7449, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Chillwind Ravager - World Loot Level 58'), +(7449, 3, 1000059, 0, 0, 1, 5, 1, 1, 'Chillwind Ravager - World Loot Level 59'), +(7450, 1, 1000153, 0, 0, 1, 5, 1, 1, 'Ragged Owlbeast - World Loot Level 53'), +(7450, 2, 1000154, 0, 0, 1, 5, 1, 1, 'Ragged Owlbeast - World Loot Level 54'), +(7450, 3, 1000155, 0, 0, 1, 5, 1, 1, 'Ragged Owlbeast - World Loot Level 55'), +(7451, 1, 1000154, 0, 0, 1, 5, 1, 1, 'Raging Owlbeast - World Loot Level 54'), +(7451, 2, 1000155, 0, 0, 1, 5, 1, 1, 'Raging Owlbeast - World Loot Level 55'), +(7451, 3, 1000156, 0, 0, 1, 5, 1, 1, 'Raging Owlbeast - World Loot Level 56'), +(7452, 1, 1000156, 0, 0, 1, 5, 1, 1, 'Crazed Owlbeast - World Loot Level 56'), +(7452, 2, 1000157, 0, 0, 1, 5, 1, 1, 'Crazed Owlbeast - World Loot Level 57'), +(7453, 1, 1000157, 0, 0, 1, 5, 1, 1, 'Moontouched Owlbeast - World Loot Level 57'), +(7453, 2, 1000158, 0, 0, 1, 5, 1, 1, 'Moontouched Owlbeast - World Loot Level 58'), +(7454, 1, 1000158, 0, 0, 1, 5, 1, 1, 'Berserk Owlbeast - World Loot Level 58'), +(7454, 2, 1000159, 0, 0, 1, 5, 1, 1, 'Berserk Owlbeast - World Loot Level 59'), +(7455, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Winterspring Owl - World Loot Level 54'), +(7455, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Winterspring Owl - World Loot Level 55'), +(7455, 3, 1000056, 0, 0, 1, 5, 1, 1, 'Winterspring Owl - World Loot Level 56'), +(7456, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Winterspring Screecher - World Loot Level 57'), +(7456, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Winterspring Screecher - World Loot Level 58'), +(7456, 3, 1000059, 0, 0, 1, 5, 1, 1, 'Winterspring Screecher - World Loot Level 59'), +(7457, 1, 1000153, 0, 0, 1, 5, 1, 1, 'Rogue Ice Thistle - World Loot Level 53'), +(7457, 2, 1000154, 0, 0, 1, 5, 1, 1, 'Rogue Ice Thistle - World Loot Level 54'), +(7457, 3, 1000155, 0, 0, 1, 5, 1, 1, 'Rogue Ice Thistle - World Loot Level 55'), +(7458, 1, 1000155, 0, 0, 1, 5, 1, 1, 'Ice Thistle Yeti - World Loot Level 55'), +(7458, 2, 1000156, 0, 0, 1, 5, 1, 1, 'Ice Thistle Yeti - World Loot Level 56'), +(7459, 1, 1000156, 0, 0, 1, 5, 1, 1, 'Ice Thistle Matriarch - World Loot Level 56'), +(7459, 2, 1000157, 0, 0, 1, 5, 1, 1, 'Ice Thistle Matriarch - World Loot Level 57'), +(7460, 1, 1000157, 0, 0, 1, 5, 1, 1, 'Ice Thistle Patriarch - World Loot Level 57'), +(7460, 2, 1000158, 0, 0, 1, 5, 1, 1, 'Ice Thistle Patriarch - World Loot Level 58'), +(7584, 1, 1000144, 0, 0, 1, 5, 1, 1, 'Wandering Forest Walker - World Loot Level 44'), +(7584, 2, 1000145, 0, 0, 1, 5, 1, 1, 'Wandering Forest Walker - World Loot Level 45'), +(7584, 3, 1000146, 0, 0, 1, 5, 1, 1, 'Wandering Forest Walker - World Loot Level 46'), +(7977, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Gammerita - World Loot Level 48'), +(8136, 1, 1000147, 0, 0, 1, 5, 1, 1, 'Lord Shalzaru - World Loot Level 47'), +(8236, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Muck Frenzy - World Loot Level 14'), +(8236, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Muck Frenzy - World Loot Level 15'), +(8400, 1, 1000046, 0, 0, 1, 5, 1, 1, 'Obsidion - World Loot Level 46'), +(8408, 1, 1000155, 0, 0, 1, 5, 1, 1, 'Warlord Krellian - World Loot Level 55'), +(8409, 1, 1000153, 0, 0, 1, 5, 1, 1, 'Caravan Master Tset - World Loot Level 53'), +(8519, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Blighted Surge - World Loot Level 54'), +(8520, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Plague Ravager - World Loot Level 55'), +(8520, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Plague Ravager - World Loot Level 56'), +(8521, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Blighted Horror - World Loot Level 56'), +(8521, 2, 1000057, 0, 0, 1, 5, 1, 1, 'Blighted Horror - World Loot Level 57'), +(8522, 1, 1000058, 0, 0, 1, 5, 1, 1, 'Plague Monstrosity - World Loot Level 58'), +(8534, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Putrid Gargoyle - World Loot Level 54'), +(8534, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Putrid Gargoyle - World Loot Level 55'), +(8534, 3, 1000056, 0, 0, 1, 5, 1, 1, 'Putrid Gargoyle - World Loot Level 56'), +(8535, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Putrid Shrieker - World Loot Level 56'), +(8535, 2, 1000057, 0, 0, 1, 5, 1, 1, 'Putrid Shrieker - World Loot Level 57'), +(8535, 3, 1000058, 0, 0, 1, 5, 1, 1, 'Putrid Shrieker - World Loot Level 58'), +(8556, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Crypt Walker - World Loot Level 55'), +(8556, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Crypt Walker - World Loot Level 56'), +(8557, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Crypt Horror - World Loot Level 57'), +(8557, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Crypt Horror - World Loot Level 58'), +(8596, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Plaguehound Runt - World Loot Level 53'), +(8596, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Plaguehound Runt - World Loot Level 54'), +(8597, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Plaguehound - World Loot Level 55'), +(8597, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Plaguehound - World Loot Level 56'), +(8598, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Frenzied Plaguehound - World Loot Level 57'), +(8598, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Frenzied Plaguehound - World Loot Level 58'), +(8600, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Plaguebat - World Loot Level 53'), +(8600, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Plaguebat - World Loot Level 54'), +(8600, 3, 1000055, 0, 0, 1, 5, 1, 1, 'Plaguebat - World Loot Level 55'), +(8601, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Noxious Plaguebat - World Loot Level 54'), +(8601, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Noxious Plaguebat - World Loot Level 55'), +(8601, 3, 1000056, 0, 0, 1, 5, 1, 1, 'Noxious Plaguebat - World Loot Level 56'), +(8602, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Monstrous Plaguebat - World Loot Level 56'), +(8602, 2, 1000057, 0, 0, 1, 5, 1, 1, 'Monstrous Plaguebat - World Loot Level 57'), +(8602, 3, 1000058, 0, 0, 1, 5, 1, 1, 'Monstrous Plaguebat - World Loot Level 58'), +(8603, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Carrion Grub - World Loot Level 54'), +(8603, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Carrion Grub - World Loot Level 55'), +(8605, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Carrion Devourer - World Loot Level 56'), +(8605, 2, 1000057, 0, 0, 1, 5, 1, 1, 'Carrion Devourer - World Loot Level 57'), +(8606, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Living Decay - World Loot Level 55'), +(8606, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Living Decay - World Loot Level 56'), +(8607, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Rotting Sludge - World Loot Level 54'), +(8607, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Rotting Sludge - World Loot Level 55'), +(8667, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Gusting Vortex - World Loot Level 43'), +(8667, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Gusting Vortex - World Loot Level 44'), +(8667, 3, 1000045, 0, 0, 1, 5, 1, 1, 'Gusting Vortex - World Loot Level 45'), +(8675, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Felbeast - World Loot Level 50'), +(8675, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Felbeast - World Loot Level 51'), +(8759, 1, 1000045, 0, 0, 1, 5, 1, 1, 'Mosshoof Runner - World Loot Level 45'), +(8759, 2, 1000046, 0, 0, 1, 5, 1, 1, 'Mosshoof Runner - World Loot Level 46'), +(8759, 3, 1000047, 0, 0, 1, 5, 1, 1, 'Mosshoof Runner - World Loot Level 47'), +(8760, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Mosshoof Stag - World Loot Level 49'), +(8760, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Mosshoof Stag - World Loot Level 50'), +(8761, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Mosshoof Courser - World Loot Level 52'), +(8761, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Mosshoof Courser - World Loot Level 53'), +(8762, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Timberweb Recluse - World Loot Level 47'), +(8762, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Timberweb Recluse - World Loot Level 48'), +(8763, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Mistwing Rogue - World Loot Level 49'), +(8763, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Mistwing Rogue - World Loot Level 50'), +(8764, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Mistwing Ravager - World Loot Level 52'), +(8764, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Mistwing Ravager - World Loot Level 53'), +(8766, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Forest Ooze - World Loot Level 52'), +(8766, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Forest Ooze - World Loot Level 53'), +(8837, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Muck Splash - World Loot Level 47'), +(8837, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Muck Splash - World Loot Level 48'), +(8837, 3, 1000049, 0, 0, 1, 5, 1, 1, 'Muck Splash - World Loot Level 49'), +(8956, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Angerclaw Bear - World Loot Level 47'), +(8956, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Angerclaw Bear - World Loot Level 48'), +(8957, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Angerclaw Grizzly - World Loot Level 51'), +(8957, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Angerclaw Grizzly - World Loot Level 52'), +(8958, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Angerclaw Mauler - World Loot Level 49'), +(8958, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Angerclaw Mauler - World Loot Level 50'), +(8959, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Felpaw Wolf - World Loot Level 47'), +(8959, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Felpaw Wolf - World Loot Level 48'), +(8960, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Felpaw Scavenger - World Loot Level 49'), +(8960, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Felpaw Scavenger - World Loot Level 50'), +(8961, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Felpaw Ravager - World Loot Level 51'), +(8961, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Felpaw Ravager - World Loot Level 52'), +(9162, 1, 1000049, 0, 0, 1, 5, 1, 1, 'Young Diemetradon - World Loot Level 49'), +(9162, 2, 1000050, 0, 0, 1, 5, 1, 1, 'Young Diemetradon - World Loot Level 50'), +(9163, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Diemetradon - World Loot Level 51'), +(9163, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Diemetradon - World Loot Level 52'), +(9164, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Elder Diemetradon - World Loot Level 54'), +(9164, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Elder Diemetradon - World Loot Level 55'), +(9165, 1, 1000048, 0, 0, 1, 5, 1, 1, 'Fledgling Pterrordax - World Loot Level 48'), +(9165, 2, 1000049, 0, 0, 1, 5, 1, 1, 'Fledgling Pterrordax - World Loot Level 49'), +(9165, 3, 1000050, 0, 0, 1, 5, 1, 1, 'Fledgling Pterrordax - World Loot Level 50'), +(9166, 1, 1000050, 0, 0, 1, 5, 1, 1, 'Pterrordax - World Loot Level 50'), +(9166, 2, 1000051, 0, 0, 1, 5, 1, 1, 'Pterrordax - World Loot Level 51'), +(9166, 3, 1000052, 0, 0, 1, 5, 1, 1, 'Pterrordax - World Loot Level 52'), +(9167, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Frenzied Pterrordax - World Loot Level 52'), +(9167, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Frenzied Pterrordax - World Loot Level 53'), +(9167, 3, 1000054, 0, 0, 1, 5, 1, 1, 'Frenzied Pterrordax - World Loot Level 54'), +(9318, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Incendosaur - World Loot Level 47'), +(9318, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Incendosaur - World Loot Level 48'), +(9318, 3, 1000049, 0, 0, 1, 5, 1, 1, 'Incendosaur - World Loot Level 49'), +(9377, 1, 1000033, 0, 0, 1, 5, 1, 1, 'Swirling Vortex - World Loot Level 33'), +(9377, 2, 1000034, 0, 0, 1, 5, 1, 1, 'Swirling Vortex - World Loot Level 34'), +(9396, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Ground Pounder - World Loot Level 41'), +(9396, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Ground Pounder - World Loot Level 42'), +(9396, 3, 1000043, 0, 0, 1, 5, 1, 1, 'Ground Pounder - World Loot Level 43'), +(9397, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Living Storm - World Loot Level 47'), +(9397, 2, 1000048, 0, 0, 1, 5, 1, 1, 'Living Storm - World Loot Level 48'), +(9397, 3, 1000049, 0, 0, 1, 5, 1, 1, 'Living Storm - World Loot Level 49'), +(9622, 1, 1000055, 0, 0, 1, 5, 1, 1, 'U\'cha - World Loot Level 55'), +(9690, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Ember Worg - World Loot Level 51'), +(9690, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Ember Worg - World Loot Level 52'), +(9691, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Venomtip Scorpid - World Loot Level 52'), +(9691, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Venomtip Scorpid - World Loot Level 53'), +(9694, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Slavering Ember Worg - World Loot Level 53'), +(9694, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Slavering Ember Worg - World Loot Level 54'), +(9695, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Deathlash Scorpid - World Loot Level 54'), +(9695, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Deathlash Scorpid - World Loot Level 55'), +(9697, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Giant Ember Worg - World Loot Level 55'), +(9697, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Giant Ember Worg - World Loot Level 56'), +(9698, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Firetail Scorpid - World Loot Level 56'), +(9698, 2, 1000057, 0, 0, 1, 5, 1, 1, 'Firetail Scorpid - World Loot Level 57'), +(9878, 1, 1000051, 0, 0, 1, 5, 1, 1, 'Entropic Beast - World Loot Level 51'), +(9878, 2, 1000052, 0, 0, 1, 5, 1, 1, 'Entropic Beast - World Loot Level 52'), +(9879, 1, 1000053, 0, 0, 1, 5, 1, 1, 'Entropic Horror - World Loot Level 53'), +(9879, 2, 1000054, 0, 0, 1, 5, 1, 1, 'Entropic Horror - World Loot Level 54'), +(10157, 1, 1000113, 0, 0, 1, 5, 1, 1, 'Moonkin Oracle - World Loot Level 13'), +(10157, 2, 1000114, 0, 0, 1, 5, 1, 1, 'Moonkin Oracle - World Loot Level 14'), +(10158, 1, 1000112, 0, 0, 1, 5, 1, 1, 'Moonkin - World Loot Level 12'), +(10158, 2, 1000113, 0, 0, 1, 5, 1, 1, 'Moonkin - World Loot Level 13'), +(10159, 1, 1000111, 0, 0, 1, 5, 1, 1, 'Young Moonkin - World Loot Level 11'), +(10159, 2, 1000112, 0, 0, 1, 5, 1, 1, 'Young Moonkin - World Loot Level 12'), +(10160, 1, 1000112, 0, 0, 1, 5, 1, 1, 'Raging Moonkin - World Loot Level 12'), +(10160, 2, 1000113, 0, 0, 1, 5, 1, 1, 'Raging Moonkin - World Loot Level 13'), +(10160, 3, 1000114, 0, 0, 1, 5, 1, 1, 'Raging Moonkin - World Loot Level 14'), +(10323, 1, 1000119, 0, 0, 1, 5, 1, 1, 'Murkdeep - World Loot Level 19'), +(10659, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Cobalt Whelp - World Loot Level 55'), +(10660, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Cobalt Broodling - World Loot Level 55'), +(10660, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Cobalt Broodling - World Loot Level 56'), +(10661, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Spell Eater - World Loot Level 54'), +(10661, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Spell Eater - World Loot Level 55'), +(10661, 3, 1000056, 0, 0, 1, 5, 1, 1, 'Spell Eater - World Loot Level 56'), +(10738, 1, 1000159, 0, 0, 1, 5, 1, 1, 'High Chief Winterfall - World Loot Level 59'), +(10756, 1, 1000028, 0, 0, 1, 5, 1, 1, 'Scalding Elemental - World Loot Level 28'), +(10756, 2, 1000029, 0, 0, 1, 5, 1, 1, 'Scalding Elemental - World Loot Level 29'), +(10757, 1, 1000027, 0, 0, 1, 5, 1, 1, 'Boiling Elemental - World Loot Level 27'), +(10757, 2, 1000028, 0, 0, 1, 5, 1, 1, 'Boiling Elemental - World Loot Level 28'), +(10806, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Ursius - World Loot Level 56'), +(10807, 1, 1000058, 0, 0, 1, 5, 1, 1, 'Brumeran - World Loot Level 58'), +(11562, 1, 1000033, 0, 0, 1, 5, 1, 1, 'Drysnap Crawler - World Loot Level 33'), +(11562, 2, 1000034, 0, 0, 1, 5, 1, 1, 'Drysnap Crawler - World Loot Level 34'), +(11563, 1, 1000034, 0, 0, 1, 5, 1, 1, 'Drysnap Pincer - World Loot Level 34'), +(11563, 2, 1000035, 0, 0, 1, 5, 1, 1, 'Drysnap Pincer - World Loot Level 35'), +(11576, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Whirlwind Ripper - World Loot Level 32'), +(11576, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Whirlwind Ripper - World Loot Level 33'), +(11576, 3, 1000034, 0, 0, 1, 5, 1, 1, 'Whirlwind Ripper - World Loot Level 34'), +(11577, 1, 1000035, 0, 0, 1, 5, 1, 1, 'Whirlwind Stormwalker - World Loot Level 35'), +(11577, 2, 1000036, 0, 0, 1, 5, 1, 1, 'Whirlwind Stormwalker - World Loot Level 36'), +(11577, 3, 1000037, 0, 0, 1, 5, 1, 1, 'Whirlwind Stormwalker - World Loot Level 37'), +(11578, 1, 1000032, 0, 0, 1, 5, 1, 1, 'Whirlwind Shredder - World Loot Level 32'), +(11578, 2, 1000033, 0, 0, 1, 5, 1, 1, 'Whirlwind Shredder - World Loot Level 33'), +(11578, 3, 1000034, 0, 0, 1, 5, 1, 1, 'Whirlwind Shredder - World Loot Level 34'), +(11698, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Hive\'Ashi Stinger - World Loot Level 57'), +(11698, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Hive\'Ashi Stinger - World Loot Level 58'), +(11721, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Hive\'Ashi Worker - World Loot Level 57'), +(11721, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Hive\'Ashi Worker - World Loot Level 58'), +(11722, 1, 1000058, 0, 0, 1, 5, 1, 1, 'Hive\'Ashi Defender - World Loot Level 58'), +(11722, 2, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Ashi Defender - World Loot Level 59'), +(11723, 1, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Ashi Sandstalker - World Loot Level 59'), +(11724, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Hive\'Ashi Swarmer - World Loot Level 57'), +(11724, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Hive\'Ashi Swarmer - World Loot Level 58'), +(11725, 1, 1000058, 0, 0, 1, 5, 1, 1, 'Hive\'Zora Waywatcher - World Loot Level 58'), +(11725, 2, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Zora Waywatcher - World Loot Level 59'), +(11726, 1, 1000058, 0, 0, 1, 5, 1, 1, 'Hive\'Zora Tunneler - World Loot Level 58'), +(11726, 2, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Zora Tunneler - World Loot Level 59'), +(11727, 1, 1000058, 0, 0, 1, 5, 1, 1, 'Hive\'Zora Wasp - World Loot Level 58'), +(11727, 2, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Zora Wasp - World Loot Level 59'), +(11728, 1, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Zora Reaver - World Loot Level 59'), +(11728, 2, 1000060, 0, 0, 1, 5, 1, 1, 'Hive\'Zora Reaver - World Loot Level 60'), +(11729, 1, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Zora Hive Sister - World Loot Level 59'), +(11729, 2, 1000060, 0, 0, 1, 5, 1, 1, 'Hive\'Zora Hive Sister - World Loot Level 60'), +(11730, 1, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Regal Ambusher - World Loot Level 59'), +(11730, 2, 1000060, 0, 0, 1, 5, 1, 1, 'Hive\'Regal Ambusher - World Loot Level 60'), +(11731, 1, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Regal Burrower - World Loot Level 59'), +(11731, 2, 1000060, 0, 0, 1, 5, 1, 1, 'Hive\'Regal Burrower - World Loot Level 60'), +(11732, 1, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Regal Spitfire - World Loot Level 59'), +(11732, 2, 1000060, 0, 0, 1, 5, 1, 1, 'Hive\'Regal Spitfire - World Loot Level 60'), +(11733, 1, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Regal Slavemaker - World Loot Level 59'), +(11733, 2, 1000060, 0, 0, 1, 5, 1, 1, 'Hive\'Regal Slavemaker - World Loot Level 60'), +(11734, 1, 1000059, 0, 0, 1, 5, 1, 1, 'Hive\'Regal Hive Lord - World Loot Level 59'), +(11734, 2, 1000060, 0, 0, 1, 5, 1, 1, 'Hive\'Regal Hive Lord - World Loot Level 60'), +(11734, 3, 1000061, 0, 0, 1, 5, 1, 1, 'Hive\'Regal Hive Lord - World Loot Level 61'), +(11735, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Stonelash Scorpid - World Loot Level 54'), +(11735, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Stonelash Scorpid - World Loot Level 55'), +(11736, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Stonelash Pincer - World Loot Level 56'), +(11737, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Stonelash Flayer - World Loot Level 57'), +(11737, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Stonelash Flayer - World Loot Level 58'), +(11738, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Sand Skitterer - World Loot Level 55'), +(11738, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Sand Skitterer - World Loot Level 56'), +(11739, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Rock Stalker - World Loot Level 57'), +(11739, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Rock Stalker - World Loot Level 58'), +(11740, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Dredge Striker - World Loot Level 55'), +(11740, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Dredge Striker - World Loot Level 56'), +(11741, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Dredge Crusher - World Loot Level 57'), +(11741, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Dredge Crusher - World Loot Level 58'), +(11744, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Dust Stormer - World Loot Level 55'), +(11744, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Dust Stormer - World Loot Level 56'), +(11744, 3, 1000057, 0, 0, 1, 5, 1, 1, 'Dust Stormer - World Loot Level 57'), +(11745, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Cyclone Warrior - World Loot Level 57'), +(11746, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Desert Rumbler - World Loot Level 56'), +(11746, 2, 1000057, 0, 0, 1, 5, 1, 1, 'Desert Rumbler - World Loot Level 57'), +(11746, 3, 1000058, 0, 0, 1, 5, 1, 1, 'Desert Rumbler - World Loot Level 58'), +(11747, 1, 1000058, 0, 0, 1, 5, 1, 1, 'Desert Rager - World Loot Level 58'), +(11747, 2, 1000059, 0, 0, 1, 5, 1, 1, 'Desert Rager - World Loot Level 59'), +(11777, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Shadowshard Rumbler - World Loot Level 40'), +(11777, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Shadowshard Rumbler - World Loot Level 41'), +(11778, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Shadowshard Smasher - World Loot Level 41'), +(11778, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Shadowshard Smasher - World Loot Level 42'), +(11781, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Ambershard Crusher - World Loot Level 40'), +(11781, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Ambershard Crusher - World Loot Level 41'), +(11782, 1, 1000042, 0, 0, 1, 5, 1, 1, 'Ambershard Destroyer - World Loot Level 42'), +(11782, 2, 1000043, 0, 0, 1, 5, 1, 1, 'Ambershard Destroyer - World Loot Level 43'), +(11785, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Ambereye Basilisk - World Loot Level 40'), +(11785, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Ambereye Basilisk - World Loot Level 41'), +(11786, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Ambereye Reaver - World Loot Level 41'), +(11786, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Ambereye Reaver - World Loot Level 42'), +(11787, 1, 1000040, 0, 0, 1, 5, 1, 1, 'Rock Borer - World Loot Level 40'), +(11787, 2, 1000041, 0, 0, 1, 5, 1, 1, 'Rock Borer - World Loot Level 41'), +(11788, 1, 1000041, 0, 0, 1, 5, 1, 1, 'Rock Worm - World Loot Level 41'), +(11788, 2, 1000042, 0, 0, 1, 5, 1, 1, 'Rock Worm - World Loot Level 42'), +(11896, 1, 1000061, 0, 0, 1, 5, 1, 1, 'Borelgore - World Loot Level 61'), +(11897, 1, 1000060, 0, 0, 1, 5, 1, 1, 'Duskwing - World Loot Level 60'), +(11921, 1, 1000021, 0, 0, 1, 5, 1, 1, 'Besseleth - World Loot Level 21'), +(12347, 1, 1000030, 0, 0, 1, 5, 1, 1, 'Enraged Reef Crawler - World Loot Level 30'), +(12347, 2, 1000031, 0, 0, 1, 5, 1, 1, 'Enraged Reef Crawler - World Loot Level 31'), +(12347, 3, 1000032, 0, 0, 1, 5, 1, 1, 'Enraged Reef Crawler - World Loot Level 32'), +(12387, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Large Vile Slime - World Loot Level 56'), +(12387, 2, 1000057, 0, 0, 1, 5, 1, 1, 'Large Vile Slime - World Loot Level 57'), +(12418, 1, 1000052, 0, 0, 1, 5, 1, 1, 'Gordok Hyena - World Loot Level 52'), +(12418, 2, 1000053, 0, 0, 1, 5, 1, 1, 'Gordok Hyena - World Loot Level 53'), +(12418, 3, 1000054, 0, 0, 1, 5, 1, 1, 'Gordok Hyena - World Loot Level 54'), +(12677, 1, 1000028, 0, 0, 1, 5, 1, 1, 'Shadumbra - World Loot Level 28'), +(12678, 1, 1000025, 0, 0, 1, 5, 1, 1, 'Ursangous - World Loot Level 25'), +(12759, 1, 1000027, 0, 0, 1, 5, 1, 1, 'Tideress - World Loot Level 27'), +(14123, 1, 1000042, 0, 0, 1, 5, 1, 1, 'Steeljaw Snapper - World Loot Level 42'), +(14123, 2, 1000043, 0, 0, 1, 5, 1, 1, 'Steeljaw Snapper - World Loot Level 43'), +(14356, 1, 1000038, 0, 0, 1, 5, 1, 1, 'Sawfin Frenzy - World Loot Level 38'), +(14356, 2, 1000039, 0, 0, 1, 5, 1, 1, 'Sawfin Frenzy - World Loot Level 39'), +(14356, 3, 1000040, 0, 0, 1, 5, 1, 1, 'Sawfin Frenzy - World Loot Level 40'), +(14455, 1, 1000057, 0, 0, 1, 5, 1, 1, 'Whirling Invader - World Loot Level 57'), +(14455, 2, 1000058, 0, 0, 1, 5, 1, 1, 'Whirling Invader - World Loot Level 58'), +(14458, 1, 1000056, 0, 0, 1, 5, 1, 1, 'Watery Invader - World Loot Level 56'), +(14458, 2, 1000057, 0, 0, 1, 5, 1, 1, 'Watery Invader - World Loot Level 57'), +(14458, 3, 1000058, 0, 0, 1, 5, 1, 1, 'Watery Invader - World Loot Level 58'), +(14460, 1, 1000054, 0, 0, 1, 5, 1, 1, 'Blazing Invader - World Loot Level 54'), +(14460, 2, 1000055, 0, 0, 1, 5, 1, 1, 'Blazing Invader - World Loot Level 55'), +(14460, 3, 1000056, 0, 0, 1, 5, 1, 1, 'Blazing Invader - World Loot Level 56'), +(14462, 1, 1000055, 0, 0, 1, 5, 1, 1, 'Thundering Invader - World Loot Level 55'), +(14462, 2, 1000056, 0, 0, 1, 5, 1, 1, 'Thundering Invader - World Loot Level 56'), +(14462, 3, 1000057, 0, 0, 1, 5, 1, 1, 'Thundering Invader - World Loot Level 57'), +(14661, 1, 1000047, 0, 0, 1, 5, 1, 1, 'Stinglasher - World Loot Level 47'), +(15409, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Old Whitebark - World Loot Level 10'), +(15635, 1, 1000105, 0, 0, 1, 5, 1, 1, 'Eversong Tender - World Loot Level 5'), +(15635, 2, 1000106, 0, 0, 1, 5, 1, 1, 'Eversong Tender - World Loot Level 6'), +(15635, 3, 1000107, 0, 0, 1, 5, 1, 1, 'Eversong Tender - World Loot Level 7'), +(15636, 1, 1000107, 0, 0, 1, 5, 1, 1, 'Eversong Green Keeper - World Loot Level 7'), +(15636, 2, 1000108, 0, 0, 1, 5, 1, 1, 'Eversong Green Keeper - World Loot Level 8'), +(15636, 3, 1000109, 0, 0, 1, 5, 1, 1, 'Eversong Green Keeper - World Loot Level 9'), +(15637, 1, 1000109, 0, 0, 1, 5, 1, 1, 'Withered Green Keeper - World Loot Level 9'), +(15637, 2, 1000110, 0, 0, 1, 5, 1, 1, 'Withered Green Keeper - World Loot Level 10'), +(15638, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Arcane Patroller - World Loot Level 5'), +(15638, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Arcane Patroller - World Loot Level 6'), +(15647, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Mana Stalker - World Loot Level 5'), +(15647, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Mana Stalker - World Loot Level 6'), +(15648, 1, 1000006, 0, 0, 1, 5, 1, 1, 'Manawraith - World Loot Level 6'), +(15648, 2, 1000007, 0, 0, 1, 5, 1, 1, 'Manawraith - World Loot Level 7'), +(15649, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Feral Dragonhawk Hatchling - World Loot Level 5'), +(15649, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Feral Dragonhawk Hatchling - World Loot Level 6'), +(15650, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Crazed Dragonhawk - World Loot Level 7'), +(15650, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Crazed Dragonhawk - World Loot Level 8'), +(15651, 1, 1000006, 0, 0, 1, 5, 1, 1, 'Springpaw Stalker - World Loot Level 6'), +(15651, 2, 1000007, 0, 0, 1, 5, 1, 1, 'Springpaw Stalker - World Loot Level 7'), +(15652, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Elder Springpaw - World Loot Level 8'), +(15652, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Elder Springpaw - World Loot Level 9'), +(15937, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Mmmrrrggglll - World Loot Level 9'), +(15966, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Mana Serpent - World Loot Level 9'), +(15966, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Mana Serpent - World Loot Level 10'), +(15967, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Ether Fiend - World Loot Level 9'), +(15967, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Ether Fiend - World Loot Level 10'), +(16304, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Arcane Devourer - World Loot Level 11'), +(16304, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Arcane Devourer - World Loot Level 12'), +(16310, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Mana Shifter - World Loot Level 12'), +(16313, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Nerubis Guard - World Loot Level 9'), +(16313, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Nerubis Guard - World Loot Level 10'), +(16316, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Stonewing Tracker - World Loot Level 16'), +(16316, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Stonewing Tracker - World Loot Level 17'), +(16319, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Nerubis Centurion - World Loot Level 18'), +(16319, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Nerubis Centurion - World Loot Level 19'), +(16324, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Stonewing Slayer - World Loot Level 13'), +(16324, 2, 1000014, 0, 0, 1, 5, 1, 1, 'Stonewing Slayer - World Loot Level 14'), +(16339, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Arcane Reaver - World Loot Level 15'), +(16339, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Arcane Reaver - World Loot Level 16'), +(16347, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Starving Ghostclaw - World Loot Level 9'), +(16347, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Starving Ghostclaw - World Loot Level 10'), +(16348, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Ghostclaw Lynx - World Loot Level 13'), +(16348, 2, 1000014, 0, 0, 1, 5, 1, 1, 'Ghostclaw Lynx - World Loot Level 14'), +(16349, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Ghostclaw Ravager - World Loot Level 16'), +(16349, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Ghostclaw Ravager - World Loot Level 17'), +(16350, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Spindleweb Spider - World Loot Level 10'), +(16350, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Spindleweb Spider - World Loot Level 11'), +(16351, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Spindleweb Lurker - World Loot Level 14'), +(16351, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Spindleweb Lurker - World Loot Level 15'), +(16352, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Greater Spindleweb - World Loot Level 17'), +(16352, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Greater Spindleweb - World Loot Level 18'), +(16353, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Mistbat - World Loot Level 9'), +(16353, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Mistbat - World Loot Level 10'), +(16354, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Vampiric Mistbat - World Loot Level 13'), +(16354, 2, 1000014, 0, 0, 1, 5, 1, 1, 'Vampiric Mistbat - World Loot Level 14'), +(16354, 3, 1000015, 0, 0, 1, 5, 1, 1, 'Vampiric Mistbat - World Loot Level 15'), +(16355, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Lesser Scourgebat - World Loot Level 16'), +(16355, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Lesser Scourgebat - World Loot Level 17'), +(16355, 3, 1000018, 0, 0, 1, 5, 1, 1, 'Lesser Scourgebat - World Loot Level 18'), +(16402, 1, 1000112, 0, 0, 1, 5, 1, 1, 'Zombified Grimscale - World Loot Level 12'), +(16402, 2, 1000113, 0, 0, 1, 5, 1, 1, 'Zombified Grimscale - World Loot Level 13'), +(16403, 1, 1000112, 0, 0, 1, 5, 1, 1, 'Withered Grimscale - World Loot Level 12'), +(16403, 2, 1000113, 0, 0, 1, 5, 1, 1, 'Withered Grimscale - World Loot Level 13'), +(16404, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Yellowgill Frenzy - World Loot Level 12'), +(16404, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Yellowgill Frenzy - World Loot Level 13'), +(16404, 3, 1000014, 0, 0, 1, 5, 1, 1, 'Yellowgill Frenzy - World Loot Level 14'), +(16405, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Whitetail Frenzy - World Loot Level 12'), +(16405, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Whitetail Frenzy - World Loot Level 13'), +(16405, 3, 1000014, 0, 0, 1, 5, 1, 1, 'Whitetail Frenzy - World Loot Level 14'), +(17190, 1, 1000108, 0, 0, 1, 5, 1, 1, 'Siltfin Murloc - World Loot Level 8'), +(17190, 2, 1000109, 0, 0, 1, 5, 1, 1, 'Siltfin Murloc - World Loot Level 9'), +(17190, 3, 1000110, 0, 0, 1, 5, 1, 1, 'Siltfin Murloc - World Loot Level 10'), +(17191, 1, 1000109, 0, 0, 1, 5, 1, 1, 'Siltfin Oracle - World Loot Level 9'), +(17191, 2, 1000110, 0, 0, 1, 5, 1, 1, 'Siltfin Oracle - World Loot Level 10'), +(17192, 1, 1000109, 0, 0, 1, 5, 1, 1, 'Siltfin Hunter - World Loot Level 9'), +(17192, 2, 1000110, 0, 0, 1, 5, 1, 1, 'Siltfin Hunter - World Loot Level 10'), +(17193, 1, 1000107, 0, 0, 1, 5, 1, 1, 'Wrathscale Naga - World Loot Level 7'), +(17193, 2, 1000108, 0, 0, 1, 5, 1, 1, 'Wrathscale Naga - World Loot Level 8'), +(17194, 1, 1000107, 0, 0, 1, 5, 1, 1, 'Wrathscale Myrmidon - World Loot Level 7'), +(17194, 2, 1000108, 0, 0, 1, 5, 1, 1, 'Wrathscale Myrmidon - World Loot Level 8'), +(17195, 1, 1000107, 0, 0, 1, 5, 1, 1, 'Wrathscale Siren - World Loot Level 7'), +(17195, 2, 1000108, 0, 0, 1, 5, 1, 1, 'Wrathscale Siren - World Loot Level 8'), +(17196, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Root Trapper - World Loot Level 5'), +(17196, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Root Trapper - World Loot Level 6'), +(17197, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Root Thresher - World Loot Level 7'), +(17197, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Root Thresher - World Loot Level 8'), +(17199, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Ravager Specimen - World Loot Level 9'), +(17199, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Ravager Specimen - World Loot Level 10'), +(17200, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Moongraze Stag - World Loot Level 5'), +(17200, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Moongraze Stag - World Loot Level 6'), +(17201, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Moongraze Buck - World Loot Level 7'), +(17201, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Moongraze Buck - World Loot Level 8'), +(17202, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Infected Nightstalker Runt - World Loot Level 7'), +(17202, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Infected Nightstalker Runt - World Loot Level 8'), +(17203, 1, 1000008, 0, 0, 1, 5, 1, 1, 'Nightstalker - World Loot Level 8'), +(17203, 2, 1000009, 0, 0, 1, 5, 1, 1, 'Nightstalker - World Loot Level 9'), +(17216, 1, 1000006, 0, 0, 1, 5, 1, 1, 'Skittering Crawler - World Loot Level 6'), +(17216, 2, 1000007, 0, 0, 1, 5, 1, 1, 'Skittering Crawler - World Loot Level 7'), +(17217, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Barbed Crawler - World Loot Level 7'), +(17217, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Barbed Crawler - World Loot Level 8'), +(17217, 3, 1000009, 0, 0, 1, 5, 1, 1, 'Barbed Crawler - World Loot Level 9'), +(17236, 1, 1000043, 0, 0, 1, 5, 1, 1, 'Tcha\'kaz - World Loot Level 43'), +(17236, 2, 1000044, 0, 0, 1, 5, 1, 1, 'Tcha\'kaz - World Loot Level 44'), +(17298, 1, 1000110, 0, 0, 1, 5, 1, 1, 'Warlord Sriss\'tiz - World Loot Level 10'), +(17325, 1, 1000111, 0, 0, 1, 5, 1, 1, 'Blacksilt Forager - World Loot Level 11'), +(17325, 2, 1000112, 0, 0, 1, 5, 1, 1, 'Blacksilt Forager - World Loot Level 12'), +(17326, 1, 1000112, 0, 0, 1, 5, 1, 1, 'Blacksilt Scout - World Loot Level 12'), +(17326, 2, 1000113, 0, 0, 1, 5, 1, 1, 'Blacksilt Scout - World Loot Level 13'), +(17327, 1, 1000111, 0, 0, 1, 5, 1, 1, 'Blacksilt Tidecaller - World Loot Level 11'), +(17327, 2, 1000112, 0, 0, 1, 5, 1, 1, 'Blacksilt Tidecaller - World Loot Level 12'), +(17327, 3, 1000113, 0, 0, 1, 5, 1, 1, 'Blacksilt Tidecaller - World Loot Level 13'), +(17328, 1, 1000115, 0, 0, 1, 5, 1, 1, 'Blacksilt Shorestriker - World Loot Level 15'), +(17328, 2, 1000116, 0, 0, 1, 5, 1, 1, 'Blacksilt Shorestriker - World Loot Level 16'), +(17329, 1, 1000116, 0, 0, 1, 5, 1, 1, 'Blacksilt Warrior - World Loot Level 16'), +(17329, 2, 1000117, 0, 0, 1, 5, 1, 1, 'Blacksilt Warrior - World Loot Level 17'), +(17330, 1, 1000115, 0, 0, 1, 5, 1, 1, 'Blacksilt Seer - World Loot Level 15'), +(17330, 2, 1000116, 0, 0, 1, 5, 1, 1, 'Blacksilt Seer - World Loot Level 16'), +(17330, 3, 1000117, 0, 0, 1, 5, 1, 1, 'Blacksilt Seer - World Loot Level 17'), +(17331, 1, 1000112, 0, 0, 1, 5, 1, 1, 'Wrathscale Shorestalker - World Loot Level 12'), +(17331, 2, 1000113, 0, 0, 1, 5, 1, 1, 'Wrathscale Shorestalker - World Loot Level 13'), +(17333, 1, 1000112, 0, 0, 1, 5, 1, 1, 'Wrathscale Screamer - World Loot Level 12'), +(17333, 2, 1000113, 0, 0, 1, 5, 1, 1, 'Wrathscale Screamer - World Loot Level 13'), +(17334, 1, 1000113, 0, 0, 1, 5, 1, 1, 'Wrathscale Marauder - World Loot Level 13'), +(17334, 2, 1000114, 0, 0, 1, 5, 1, 1, 'Wrathscale Marauder - World Loot Level 14'), +(17336, 1, 1000113, 0, 0, 1, 5, 1, 1, 'Wrathscale Sorceress - World Loot Level 13'), +(17336, 2, 1000114, 0, 0, 1, 5, 1, 1, 'Wrathscale Sorceress - World Loot Level 14'), +(17343, 1, 1000011, 0, 0, 1, 5, 1, 1, 'Thistle Lasher - World Loot Level 11'), +(17343, 2, 1000012, 0, 0, 1, 5, 1, 1, 'Thistle Lasher - World Loot Level 12'), +(17344, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Mutated Constrictor - World Loot Level 14'), +(17344, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Mutated Constrictor - World Loot Level 15'), +(17345, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Brown Bear - World Loot Level 9'), +(17345, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Brown Bear - World Loot Level 10'), +(17346, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Mutated Tangler - World Loot Level 17'), +(17346, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Mutated Tangler - World Loot Level 18'), +(17347, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Grizzled Brown Bear - World Loot Level 12'), +(17347, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Grizzled Brown Bear - World Loot Level 13'), +(17348, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Elder Brown Bear - World Loot Level 15'), +(17348, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Elder Brown Bear - World Loot Level 16'), +(17349, 1, 1000009, 0, 0, 1, 5, 1, 1, 'Blue Flutterer - World Loot Level 9'), +(17349, 2, 1000010, 0, 0, 1, 5, 1, 1, 'Blue Flutterer - World Loot Level 10'), +(17349, 3, 1000011, 0, 0, 1, 5, 1, 1, 'Blue Flutterer - World Loot Level 11'), +(17350, 1, 1000014, 0, 0, 1, 5, 1, 1, 'Royal Blue Flutterer - World Loot Level 14'), +(17350, 2, 1000015, 0, 0, 1, 5, 1, 1, 'Royal Blue Flutterer - World Loot Level 15'), +(17350, 3, 1000016, 0, 0, 1, 5, 1, 1, 'Royal Blue Flutterer - World Loot Level 16'), +(17352, 1, 1000111, 0, 0, 1, 5, 1, 1, 'Corrupted Treant - World Loot Level 11'), +(17352, 2, 1000112, 0, 0, 1, 5, 1, 1, 'Corrupted Treant - World Loot Level 12'), +(17352, 3, 1000113, 0, 0, 1, 5, 1, 1, 'Corrupted Treant - World Loot Level 13'), +(17353, 1, 1000116, 0, 0, 1, 5, 1, 1, 'Corrupted Stomper - World Loot Level 16'), +(17353, 2, 1000117, 0, 0, 1, 5, 1, 1, 'Corrupted Stomper - World Loot Level 17'), +(17353, 3, 1000118, 0, 0, 1, 5, 1, 1, 'Corrupted Stomper - World Loot Level 18'), +(17358, 1, 1000018, 0, 0, 1, 5, 1, 1, 'Fouled Water Spirit - World Loot Level 18'), +(17358, 2, 1000019, 0, 0, 1, 5, 1, 1, 'Fouled Water Spirit - World Loot Level 19'), +(17372, 1, 1000005, 0, 0, 1, 5, 1, 1, 'Timberstrider Fledgling - World Loot Level 5'), +(17372, 2, 1000006, 0, 0, 1, 5, 1, 1, 'Timberstrider Fledgling - World Loot Level 6'), +(17373, 1, 1000006, 0, 0, 1, 5, 1, 1, 'Timberstrider - World Loot Level 6'), +(17373, 2, 1000007, 0, 0, 1, 5, 1, 1, 'Timberstrider - World Loot Level 7'), +(17373, 3, 1000008, 0, 0, 1, 5, 1, 1, 'Timberstrider - World Loot Level 8'), +(17374, 1, 1000007, 0, 0, 1, 5, 1, 1, 'Greater Timberstrider - World Loot Level 7'), +(17374, 2, 1000008, 0, 0, 1, 5, 1, 1, 'Greater Timberstrider - World Loot Level 8'), +(17374, 3, 1000009, 0, 0, 1, 5, 1, 1, 'Greater Timberstrider - World Loot Level 9'), +(17447, 1, 1000012, 0, 0, 1, 5, 1, 1, 'The Kurken - World Loot Level 12'), +(17475, 1, 1000111, 0, 0, 1, 5, 1, 1, 'Murgurgula - World Loot Level 11'), +(17496, 1, 1000112, 0, 0, 1, 5, 1, 1, 'Cruelfin - World Loot Level 12'), +(17522, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Myst Spinner - World Loot Level 16'), +(17522, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Myst Spinner - World Loot Level 17'), +(17523, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Myst Leecher - World Loot Level 17'), +(17523, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Myst Leecher - World Loot Level 18'), +(17525, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Bloodmyst Hatchling - World Loot Level 10'), +(17525, 2, 1000011, 0, 0, 1, 5, 1, 1, 'Bloodmyst Hatchling - World Loot Level 11'), +(17527, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Enraged Ravager - World Loot Level 16'), +(17527, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Enraged Ravager - World Loot Level 17'), +(17550, 1, 1000015, 0, 0, 1, 5, 1, 1, 'Void Anomaly - World Loot Level 15'), +(17550, 2, 1000016, 0, 0, 1, 5, 1, 1, 'Void Anomaly - World Loot Level 16'), +(17556, 1, 1000010, 0, 0, 1, 5, 1, 1, 'Death Ravager - World Loot Level 10'), +(17588, 1, 1000016, 0, 0, 1, 5, 1, 1, 'Veridian Whelp - World Loot Level 16'), +(17588, 2, 1000017, 0, 0, 1, 5, 1, 1, 'Veridian Whelp - World Loot Level 17'), +(17589, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Veridian Broodling - World Loot Level 17'), +(17589, 2, 1000018, 0, 0, 1, 5, 1, 1, 'Veridian Broodling - World Loot Level 18'), +(17591, 1, 1000107, 0, 0, 1, 5, 1, 1, 'Blood Elf Bandit - World Loot Level 7'), +(17661, 1, 1000017, 0, 0, 1, 5, 1, 1, 'Deathclaw - World Loot Level 17'), +(17673, 1, 1000012, 0, 0, 1, 5, 1, 1, 'Stinkhorn Striker - World Loot Level 12'), +(17673, 2, 1000013, 0, 0, 1, 5, 1, 1, 'Stinkhorn Striker - World Loot Level 13'), +(17673, 3, 1000014, 0, 0, 1, 5, 1, 1, 'Stinkhorn Striker - World Loot Level 14'), +(17683, 1, 1000019, 0, 0, 1, 5, 1, 1, 'Zarakh - World Loot Level 19'), +(17701, 1, 1000013, 0, 0, 1, 5, 1, 1, 'Lord Xiz - World Loot Level 13'), +(17713, 1, 1000115, 0, 0, 1, 5, 1, 1, 'Bloodcursed Naga - World Loot Level 15'), +(17713, 2, 1000116, 0, 0, 1, 5, 1, 1, 'Bloodcursed Naga - World Loot Level 16'), +(23841, 1, 1000136, 0, 0, 1, 5, 1, 1, 'Razorspine - World Loot Level 36'), +(23873, 1, 1000039, 0, 0, 1, 5, 1, 1, 'Goreclaw the Ravenous - World Loot Level 39'), +(37214, 1, 1000108, 0, 0, 1, 5, 1, 1, 'Crown Lackey - World Loot Level 8'), +(37214, 2, 1000109, 0, 0, 1, 5, 1, 1, 'Crown Lackey - World Loot Level 9'), +(37917, 1, 1000116, 0, 0, 1, 5, 1, 1, 'Crown Thug - World Loot Level 16'), +(37917, 2, 1000117, 0, 0, 1, 5, 1, 1, 'Crown Thug - World Loot Level 17'), +(37984, 1, 1000125, 0, 0, 1, 5, 1, 1, 'Crown Duster - World Loot Level 25'), +(37984, 2, 1000126, 0, 0, 1, 5, 1, 1, 'Crown Duster - World Loot Level 26'), +(38006, 1, 1000133, 0, 0, 1, 5, 1, 1, 'Crown Hoodlum - World Loot Level 33'), +(38006, 2, 1000134, 0, 0, 1, 5, 1, 1, 'Crown Hoodlum - World Loot Level 34'), +(38016, 1, 1000144, 0, 0, 1, 5, 1, 1, 'Crown Agent - World Loot Level 44'), +(38016, 2, 1000145, 0, 0, 1, 5, 1, 1, 'Crown Agent - World Loot Level 45'), +(38023, 1, 1000154, 0, 0, 1, 5, 1, 1, 'Crown Sprinkler - World Loot Level 54'), +(38023, 2, 1000155, 0, 0, 1, 5, 1, 1, 'Crown Sprinkler - World Loot Level 55'), +(38023, 3, 1000156, 0, 0, 1, 5, 1, 1, 'Crown Sprinkler - World Loot Level 56'); + +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(3, 1, 1000124, 0, 5, 'Flesh Eater - World Loot Level 24'), +(3, 2, 1000125, 0, 5, 'Flesh Eater - World Loot Level 25'), +(40, 1, 1000106, 0, 5, 'Kobold Miner - World Loot Level 6'), +(40, 2, 1000107, 0, 5, 'Kobold Miner - World Loot Level 7'), +(48, 1, 1000121, 0, 5, 'Skeletal Warrior - World Loot Level 21'), +(48, 2, 1000122, 0, 5, 'Skeletal Warrior - World Loot Level 22'), +(60, 1, 1000108, 0, 5, 'Ruklar the Trapper - World Loot Level 8'), +(94, 1, 1000105, 0, 5, 'Defias Cutpurse - World Loot Level 5'), +(94, 2, 1000106, 0, 5, 'Defias Cutpurse - World Loot Level 6'), +(95, 1, 1000111, 0, 5, 'Defias Smuggler - World Loot Level 11'), +(95, 2, 1000112, 0, 5, 'Defias Smuggler - World Loot Level 12'), +(97, 1, 1000108, 0, 5, 'Riverpaw Runt - World Loot Level 8'), +(97, 2, 1000109, 0, 5, 'Riverpaw Runt - World Loot Level 9'), +(98, 1, 1000117, 0, 5, 'Riverpaw Taskmaster - World Loot Level 17'), +(98, 2, 1000118, 0, 5, 'Riverpaw Taskmaster - World Loot Level 18'), +(116, 1, 1000108, 0, 5, 'Defias Bandit - World Loot Level 8'), +(116, 2, 1000109, 0, 5, 'Defias Bandit - World Loot Level 9'), +(117, 1, 1000111, 0, 5, 'Riverpaw Gnoll - World Loot Level 11'), +(117, 2, 1000112, 0, 5, 'Riverpaw Gnoll - World Loot Level 12'), +(121, 1, 1000116, 0, 5, 'Defias Pathstalker - World Loot Level 16'), +(122, 1, 1000117, 0, 5, 'Defias Highwayman - World Loot Level 17'), +(122, 2, 1000118, 0, 5, 'Defias Highwayman - World Loot Level 18'), +(123, 1, 1000114, 0, 5, 'Riverpaw Mongrel - World Loot Level 14'), +(124, 1, 1000115, 0, 5, 'Riverpaw Brute - World Loot Level 15'), +(124, 2, 1000116, 0, 5, 'Riverpaw Brute - World Loot Level 16'), +(125, 1, 1000119, 0, 5, 'Riverpaw Overseer - World Loot Level 19'), +(125, 2, 1000120, 0, 5, 'Riverpaw Overseer - World Loot Level 20'), +(127, 1, 1000118, 0, 5, 'Murloc Tidehunter - World Loot Level 18'), +(127, 2, 1000119, 0, 5, 'Murloc Tidehunter - World Loot Level 19'), +(202, 1, 1000123, 0, 5, 'Skeletal Horror - World Loot Level 23'), +(202, 2, 1000124, 0, 5, 'Skeletal Horror - World Loot Level 24'), +(203, 1, 1000122, 0, 5, 'Skeletal Mage - World Loot Level 22'), +(203, 2, 1000123, 0, 5, 'Skeletal Mage - World Loot Level 23'), +(205, 1, 1000128, 0, 5, 'Nightbane Dark Runner - World Loot Level 28'), +(205, 2, 1000129, 0, 5, 'Nightbane Dark Runner - World Loot Level 29'), +(206, 1, 1000130, 0, 5, 'Nightbane Vile Fang - World Loot Level 30'), +(210, 1, 1000126, 0, 5, 'Bone Chewer - World Loot Level 26'), +(210, 2, 1000127, 0, 5, 'Bone Chewer - World Loot Level 27'), +(212, 1, 1000129, 0, 5, 'Splinter Fist Warrior - World Loot Level 29'), +(212, 2, 1000130, 0, 5, 'Splinter Fist Warrior - World Loot Level 30'), +(213, 1, 1000119, 0, 5, 'Starving Dire Wolf - World Loot Level 19'), +(213, 2, 1000120, 0, 5, 'Starving Dire Wolf - World Loot Level 20'), +(215, 1, 1000124, 0, 5, 'Defias Night Runner - World Loot Level 24'), +(215, 2, 1000125, 0, 5, 'Defias Night Runner - World Loot Level 25'), +(217, 1, 1000119, 0, 5, 'Venom Web Spider - World Loot Level 19'), +(217, 2, 1000120, 0, 5, 'Venom Web Spider - World Loot Level 20'), +(218, 1, 1000124, 0, 5, 'Grave Robber - World Loot Level 24'), +(218, 2, 1000125, 0, 5, 'Grave Robber - World Loot Level 25'), +(232, 1, 1000123, 0, 5, 'Farmer Ray - World Loot Level 23'), +(285, 1, 1000106, 0, 5, 'Murloc - World Loot Level 6'), +(285, 2, 1000107, 0, 5, 'Murloc - World Loot Level 7'), +(300, 1, 1000130, 0, 5, 'Zzarc\' Vul - World Loot Level 30'), +(315, 1, 1000132, 0, 5, 'Stalvan Mistmantle - World Loot Level 32'), +(327, 1, 1000108, 0, 5, 'Goldtooth - World Loot Level 8'), +(397, 1, 1000126, 0, 5, 'Morganth - World Loot Level 26'), +(423, 1, 1000115, 0, 5, 'Redridge Mongrel - World Loot Level 15'), +(423, 2, 1000116, 0, 5, 'Redridge Mongrel - World Loot Level 16'), +(424, 1, 1000116, 0, 5, 'Redridge Poacher - World Loot Level 16'), +(424, 2, 1000117, 0, 5, 'Redridge Poacher - World Loot Level 17'), +(426, 1, 1000117, 0, 5, 'Redridge Brute - World Loot Level 17'), +(426, 2, 1000118, 0, 5, 'Redridge Brute - World Loot Level 18'), +(429, 1, 1000125, 0, 5, 'Shadowhide Darkweaver - World Loot Level 25'), +(429, 2, 1000126, 0, 5, 'Shadowhide Darkweaver - World Loot Level 26'), +(430, 1, 1000118, 0, 5, 'Redridge Mystic - World Loot Level 18'), +(430, 2, 1000119, 0, 5, 'Redridge Mystic - World Loot Level 19'), +(431, 1, 1000125, 0, 5, 'Shadowhide Slayer - World Loot Level 25'), +(431, 2, 1000126, 0, 5, 'Shadowhide Slayer - World Loot Level 26'), +(432, 1, 1000123, 0, 5, 'Shadowhide Brute - World Loot Level 23'), +(432, 2, 1000124, 0, 5, 'Shadowhide Brute - World Loot Level 24'), +(433, 1, 1000122, 0, 5, 'Shadowhide Gnoll - World Loot Level 22'), +(433, 2, 1000123, 0, 5, 'Shadowhide Gnoll - World Loot Level 23'), +(434, 1, 1000121, 0, 5, 'Rabid Shadowhide Gnoll - World Loot Level 21'), +(434, 2, 1000122, 0, 5, 'Rabid Shadowhide Gnoll - World Loot Level 22'), +(435, 1, 1000124, 0, 5, 'Blackrock Champion - World Loot Level 24'), +(435, 2, 1000125, 0, 5, 'Blackrock Champion - World Loot Level 25'), +(436, 1, 1000122, 0, 5, 'Blackrock Shadowcaster - World Loot Level 22'), +(436, 2, 1000123, 0, 5, 'Blackrock Shadowcaster - World Loot Level 23'), +(437, 1, 1000121, 0, 5, 'Blackrock Renegade - World Loot Level 21'), +(437, 2, 1000122, 0, 5, 'Blackrock Renegade - World Loot Level 22'), +(440, 1, 1000119, 0, 5, 'Blackrock Grunt - World Loot Level 19'), +(440, 2, 1000120, 0, 5, 'Blackrock Grunt - World Loot Level 20'), +(445, 1, 1000119, 0, 5, 'Redridge Alpha - World Loot Level 19'), +(445, 2, 1000120, 0, 5, 'Redridge Alpha - World Loot Level 20'), +(446, 1, 1000118, 0, 5, 'Redridge Basher - World Loot Level 18'), +(446, 2, 1000119, 0, 5, 'Redridge Basher - World Loot Level 19'), +(449, 1, 1000116, 0, 5, 'Defias Knuckleduster - World Loot Level 16'), +(449, 2, 1000117, 0, 5, 'Defias Knuckleduster - World Loot Level 17'), +(452, 1, 1000116, 0, 5, 'Riverpaw Bandit - World Loot Level 16'), +(452, 2, 1000117, 0, 5, 'Riverpaw Bandit - World Loot Level 17'), +(453, 1, 1000118, 0, 5, 'Riverpaw Mystic - World Loot Level 18'), +(453, 2, 1000119, 0, 5, 'Riverpaw Mystic - World Loot Level 19'), +(456, 1, 1000114, 0, 5, 'Murloc Minor Oracle - World Loot Level 14'), +(473, 1, 1000110, 0, 5, 'Morgan the Collector - World Loot Level 10'), +(474, 1, 1000109, 0, 5, 'Defias Rogue Wizard - World Loot Level 9'), +(474, 2, 1000110, 0, 5, 'Defias Rogue Wizard - World Loot Level 10'), +(475, 1, 1000105, 0, 5, 'Kobold Tunneler - World Loot Level 5'), +(475, 2, 1000106, 0, 5, 'Kobold Tunneler - World Loot Level 6'), +(476, 1, 1000107, 0, 5, 'Kobold Geomancer - World Loot Level 7'), +(476, 2, 1000108, 0, 5, 'Kobold Geomancer - World Loot Level 8'), +(478, 1, 1000109, 0, 5, 'Riverpaw Outrunner - World Loot Level 9'), +(478, 2, 1000110, 0, 5, 'Riverpaw Outrunner - World Loot Level 10'), +(481, 1, 1000110, 0, 5, 'Defias Footpad - World Loot Level 10'), +(481, 2, 1000111, 0, 5, 'Defias Footpad - World Loot Level 11'), +(485, 1, 1000120, 0, 5, 'Blackrock Outrunner - World Loot Level 20'), +(485, 2, 1000121, 0, 5, 'Blackrock Outrunner - World Loot Level 21'), +(500, 1, 1000112, 0, 5, 'Riverpaw Scout - World Loot Level 12'), +(500, 2, 1000113, 0, 5, 'Riverpaw Scout - World Loot Level 13'), +(501, 1, 1000114, 0, 5, 'Riverpaw Herbalist - World Loot Level 14'), +(501, 2, 1000115, 0, 5, 'Riverpaw Herbalist - World Loot Level 15'), +(502, 1, 1000115, 0, 5, 'Benny Blaanco - World Loot Level 15'), +(504, 1, 1000112, 0, 5, 'Defias Trapper - World Loot Level 12'), +(504, 2, 1000113, 0, 5, 'Defias Trapper - World Loot Level 13'), +(511, 1, 1000126, 0, 5, 'Insane Ghoul - World Loot Level 26'), +(515, 1, 1000111, 0, 5, 'Murloc Raider - World Loot Level 11'), +(515, 2, 1000112, 0, 5, 'Murloc Raider - World Loot Level 12'), +(518, 1, 1000120, 0, 5, 'Yowler - World Loot Level 20'), +(524, 1, 1000107, 0, 5, 'Rockhide Boar - World Loot Level 7'), +(524, 2, 1000108, 0, 5, 'Rockhide Boar - World Loot Level 8'), +(525, 1, 1000105, 0, 5, 'Mangy Wolf - World Loot Level 5'), +(525, 2, 1000106, 0, 5, 'Mangy Wolf - World Loot Level 6'), +(533, 1, 1000127, 0, 5, 'Nightbane Shadow Weaver - World Loot Level 27'), +(533, 2, 1000128, 0, 5, 'Nightbane Shadow Weaver - World Loot Level 28'), +(544, 1, 1000121, 0, 5, 'Murloc Nightcrawler - World Loot Level 21'), +(544, 2, 1000122, 0, 5, 'Murloc Nightcrawler - World Loot Level 22'), +(545, 1, 1000119, 0, 5, 'Murloc Tidecaller - World Loot Level 19'), +(545, 2, 1000120, 0, 5, 'Murloc Tidecaller - World Loot Level 20'), +(547, 1, 1000016, 0, 5, 'Great Goretusk - World Loot Level 16'), +(547, 2, 1000017, 0, 5, 'Great Goretusk - World Loot Level 17'), +(548, 1, 1000117, 0, 5, 'Murloc Minor Tidecaller - World Loot Level 17'), +(548, 2, 1000118, 0, 5, 'Murloc Minor Tidecaller - World Loot Level 18'), +(550, 1, 1000114, 0, 5, 'Defias Messenger - World Loot Level 14'), +(565, 1, 1000020, 0, 5, 'Rabid Dire Wolf - World Loot Level 20'), +(565, 2, 1000021, 0, 5, 'Rabid Dire Wolf - World Loot Level 21'), +(568, 1, 1000124, 0, 5, 'Shadowhide Warrior - World Loot Level 24'), +(568, 2, 1000125, 0, 5, 'Shadowhide Warrior - World Loot Level 25'), +(570, 1, 1000128, 0, 5, 'Brain Eater - World Loot Level 28'), +(570, 2, 1000129, 0, 5, 'Brain Eater - World Loot Level 29'), +(579, 1, 1000124, 0, 5, 'Shadowhide Assassin - World Loot Level 24'), +(580, 1, 1000120, 0, 5, 'Redridge Drudger - World Loot Level 20'), +(580, 2, 1000121, 0, 5, 'Redridge Drudger - World Loot Level 21'), +(587, 1, 1000133, 0, 5, 'Bloodscalp Warrior - World Loot Level 33'), +(587, 2, 1000134, 0, 5, 'Bloodscalp Warrior - World Loot Level 34'), +(588, 1, 1000134, 0, 5, 'Bloodscalp Scout - World Loot Level 34'), +(588, 2, 1000135, 0, 5, 'Bloodscalp Scout - World Loot Level 35'), +(589, 1, 1000114, 0, 5, 'Defias Pillager - World Loot Level 14'), +(589, 2, 1000115, 0, 5, 'Defias Pillager - World Loot Level 15'), +(590, 1, 1000113, 0, 5, 'Defias Looter - World Loot Level 13'), +(590, 2, 1000114, 0, 5, 'Defias Looter - World Loot Level 14'), +(594, 1, 1000115, 0, 5, 'Defias Henchman - World Loot Level 15'), +(594, 2, 1000116, 0, 5, 'Defias Henchman - World Loot Level 16'), +(595, 1, 1000134, 0, 5, 'Bloodscalp Hunter - World Loot Level 34'), +(595, 2, 1000135, 0, 5, 'Bloodscalp Hunter - World Loot Level 35'), +(597, 1, 1000136, 0, 5, 'Bloodscalp Berserker - World Loot Level 36'), +(597, 2, 1000137, 0, 5, 'Bloodscalp Berserker - World Loot Level 37'), +(604, 1, 1000127, 0, 5, 'Plague Spreader - World Loot Level 27'), +(604, 2, 1000128, 0, 5, 'Plague Spreader - World Loot Level 28'), +(615, 1, 1000123, 0, 5, 'Blackrock Tracker - World Loot Level 23'), +(619, 1, 1000115, 0, 5, 'Defias Conjurer - World Loot Level 15'), +(619, 2, 1000116, 0, 5, 'Defias Conjurer - World Loot Level 16'), +(623, 1, 1000117, 0, 5, 'Skeletal Miner - World Loot Level 17'), +(623, 2, 1000118, 0, 5, 'Skeletal Miner - World Loot Level 18'), +(624, 1, 1000117, 0, 5, 'Undead Excavator - World Loot Level 17'), +(624, 2, 1000118, 0, 5, 'Undead Excavator - World Loot Level 18'), +(625, 1, 1000117, 0, 5, 'Undead Dynamiter - World Loot Level 17'), +(625, 2, 1000118, 0, 5, 'Undead Dynamiter - World Loot Level 18'), +(626, 1, 1000118, 0, 5, 'Foreman Thistlenettle - World Loot Level 18'), +(628, 1, 1000024, 0, 5, 'Black Ravager - World Loot Level 24'), +(628, 2, 1000025, 0, 5, 'Black Ravager - World Loot Level 25'), +(660, 1, 1000137, 0, 5, 'Bloodscalp Witch Doctor - World Loot Level 37'), +(667, 1, 1000139, 0, 5, 'Skullsplitter Warrior - World Loot Level 39'), +(667, 2, 1000140, 0, 5, 'Skullsplitter Warrior - World Loot Level 40'), +(669, 1, 1000141, 0, 5, 'Skullsplitter Hunter - World Loot Level 41'), +(669, 2, 1000142, 0, 5, 'Skullsplitter Hunter - World Loot Level 42'), +(670, 1, 1000141, 0, 5, 'Skullsplitter Witch Doctor - World Loot Level 41'), +(670, 2, 1000142, 0, 5, 'Skullsplitter Witch Doctor - World Loot Level 42'), +(671, 1, 1000136, 0, 5, 'Bloodscalp Headhunter - World Loot Level 36'), +(671, 2, 1000137, 0, 5, 'Bloodscalp Headhunter - World Loot Level 37'), +(672, 1, 1000144, 0, 5, 'Skullsplitter Spiritchaser - World Loot Level 44'), +(674, 1, 1000140, 0, 5, 'Venture Co. Strip Miner - World Loot Level 40'), +(674, 2, 1000141, 0, 5, 'Venture Co. Strip Miner - World Loot Level 41'), +(675, 1, 1000142, 0, 5, 'Venture Co. Foreman - World Loot Level 42'), +(676, 1, 1000141, 0, 5, 'Venture Co. Surveyor - World Loot Level 41'), +(676, 2, 1000142, 0, 5, 'Venture Co. Surveyor - World Loot Level 42'), +(677, 1, 1000140, 0, 5, 'Venture Co. Tinkerer - World Loot Level 40'), +(677, 2, 1000141, 0, 5, 'Venture Co. Tinkerer - World Loot Level 41'), +(678, 1, 1000143, 0, 5, 'Mosh\'Ogg Mauler - World Loot Level 43'), +(678, 2, 1000144, 0, 5, 'Mosh\'Ogg Mauler - World Loot Level 44'), +(679, 1, 1000143, 0, 5, 'Mosh\'Ogg Shaman - World Loot Level 43'), +(679, 2, 1000144, 0, 5, 'Mosh\'Ogg Shaman - World Loot Level 44'), +(680, 1, 1000145, 0, 5, 'Mosh\'Ogg Lord - World Loot Level 45'), +(686, 1, 1000035, 0, 5, 'Lashtail Raptor - World Loot Level 35'), +(686, 2, 1000036, 0, 5, 'Lashtail Raptor - World Loot Level 36'), +(694, 1, 1000133, 0, 5, 'Bloodscalp Axe Thrower - World Loot Level 33'), +(694, 2, 1000134, 0, 5, 'Bloodscalp Axe Thrower - World Loot Level 34'), +(696, 1, 1000139, 0, 5, 'Skullsplitter Axe Thrower - World Loot Level 39'), +(696, 2, 1000140, 0, 5, 'Skullsplitter Axe Thrower - World Loot Level 40'), +(697, 1, 1000133, 0, 5, 'Bloodscalp Shaman - World Loot Level 33'), +(697, 2, 1000134, 0, 5, 'Bloodscalp Shaman - World Loot Level 34'), +(699, 1, 1000134, 0, 5, 'Bloodscalp Beastmaster - World Loot Level 34'), +(699, 2, 1000135, 0, 5, 'Bloodscalp Beastmaster - World Loot Level 35'), +(701, 1, 1000134, 0, 5, 'Bloodscalp Mystic - World Loot Level 34'), +(701, 2, 1000135, 0, 5, 'Bloodscalp Mystic - World Loot Level 35'), +(702, 1, 1000133, 0, 5, 'Bloodscalp Scavenger - World Loot Level 33'), +(702, 2, 1000134, 0, 5, 'Bloodscalp Scavenger - World Loot Level 34'), +(703, 1, 1000126, 0, 5, 'Lieutenant Fangore - World Loot Level 26'), +(709, 1, 1000141, 0, 5, 'Mosh\'Ogg Warmonger - World Loot Level 41'), +(709, 2, 1000142, 0, 5, 'Mosh\'Ogg Warmonger - World Loot Level 42'), +(710, 1, 1000143, 0, 5, 'Mosh\'Ogg Spellcrafter - World Loot Level 43'), +(710, 2, 1000144, 0, 5, 'Mosh\'Ogg Spellcrafter - World Loot Level 44'), +(711, 1, 1000124, 0, 5, 'Ardo Dirtpaw - World Loot Level 24'), +(712, 1, 1000114, 0, 5, 'Redridge Thrasher - World Loot Level 14'), +(712, 2, 1000115, 0, 5, 'Redridge Thrasher - World Loot Level 15'), +(723, 1, 1000144, 0, 5, 'Mosh\'Ogg Butcher - World Loot Level 44'), +(732, 1, 1000109, 0, 5, 'Murloc Lurker - World Loot Level 9'), +(732, 2, 1000110, 0, 5, 'Murloc Lurker - World Loot Level 10'), +(750, 1, 1000142, 0, 5, 'Marsh Inkspewer - World Loot Level 42'), +(750, 2, 1000143, 0, 5, 'Marsh Inkspewer - World Loot Level 43'), +(751, 1, 1000143, 0, 5, 'Marsh Flesheater - World Loot Level 43'), +(751, 2, 1000144, 0, 5, 'Marsh Flesheater - World Loot Level 44'), +(754, 1, 1000131, 0, 5, 'Rebel Watchman - World Loot Level 31'), +(754, 2, 1000132, 0, 5, 'Rebel Watchman - World Loot Level 32'), +(755, 1, 1000134, 0, 5, 'Lost One Mudlurker - World Loot Level 34'), +(755, 2, 1000135, 0, 5, 'Lost One Mudlurker - World Loot Level 35'), +(757, 1, 1000135, 0, 5, 'Lost One Fisherman - World Loot Level 35'), +(757, 2, 1000136, 0, 5, 'Lost One Fisherman - World Loot Level 36'), +(759, 1, 1000136, 0, 5, 'Lost One Hunter - World Loot Level 36'), +(759, 2, 1000137, 0, 5, 'Lost One Hunter - World Loot Level 37'), +(760, 1, 1000136, 0, 5, 'Lost One Muckdweller - World Loot Level 36'), +(760, 2, 1000137, 0, 5, 'Lost One Muckdweller - World Loot Level 37'), +(761, 1, 1000137, 0, 5, 'Lost One Seer - World Loot Level 37'), +(761, 2, 1000138, 0, 5, 'Lost One Seer - World Loot Level 38'), +(762, 1, 1000137, 0, 5, 'Lost One Riftseeker - World Loot Level 37'), +(762, 2, 1000138, 0, 5, 'Lost One Riftseeker - World Loot Level 38'), +(780, 1, 1000139, 0, 5, 'Skullsplitter Mystic - World Loot Level 39'), +(780, 2, 1000140, 0, 5, 'Skullsplitter Mystic - World Loot Level 40'), +(781, 1, 1000143, 0, 5, 'Skullsplitter Headhunter - World Loot Level 43'), +(781, 2, 1000144, 0, 5, 'Skullsplitter Headhunter - World Loot Level 44'), +(782, 1, 1000141, 0, 5, 'Skullsplitter Scout - World Loot Level 41'), +(782, 2, 1000142, 0, 5, 'Skullsplitter Scout - World Loot Level 42'), +(783, 1, 1000143, 0, 5, 'Skullsplitter Berserker - World Loot Level 43'), +(783, 2, 1000144, 0, 5, 'Skullsplitter Berserker - World Loot Level 44'), +(784, 1, 1000141, 0, 5, 'Skullsplitter Beastmaster - World Loot Level 41'), +(784, 2, 1000142, 0, 5, 'Skullsplitter Beastmaster - World Loot Level 42'), +(785, 1, 1000128, 0, 5, 'Skeletal Warder - World Loot Level 28'), +(785, 2, 1000129, 0, 5, 'Skeletal Warder - World Loot Level 29'), +(787, 1, 1000126, 0, 5, 'Skeletal Healer - World Loot Level 26'), +(787, 2, 1000127, 0, 5, 'Skeletal Healer - World Loot Level 27'), +(813, 1, 1000140, 0, 5, 'Colonel Kurzen - World Loot Level 40'), +(814, 1, 1000138, 0, 5, 'Sergeant Malthus - World Loot Level 38'), +(818, 1, 1000145, 0, 5, 'Mai\'Zoth - World Loot Level 45'), +(819, 1, 1000124, 0, 5, 'Servant of Ilgalar - World Loot Level 24'), +(819, 2, 1000125, 0, 5, 'Servant of Ilgalar - World Loot Level 25'), +(822, 1, 1000008, 0, 5, 'Young Forest Bear - World Loot Level 8'), +(822, 2, 1000009, 0, 5, 'Young Forest Bear - World Loot Level 9'), +(824, 1, 1000115, 0, 5, 'Defias Digger - World Loot Level 15'), +(824, 2, 1000116, 0, 5, 'Defias Digger - World Loot Level 16'), +(834, 1, 1000010, 0, 5, 'Coyote - World Loot Level 10'), +(834, 2, 1000011, 0, 5, 'Coyote - World Loot Level 11'), +(861, 1, 1000136, 0, 5, 'Stonard Scout - World Loot Level 36'), +(861, 2, 1000137, 0, 5, 'Stonard Scout - World Loot Level 37'), +(862, 1, 1000137, 0, 5, 'Stonard Explorer - World Loot Level 37'), +(862, 2, 1000138, 0, 5, 'Stonard Explorer - World Loot Level 38'), +(863, 1, 1000150, 0, 5, 'Stonard Hunter - World Loot Level 50'), +(863, 2, 1000151, 0, 5, 'Stonard Hunter - World Loot Level 51'), +(864, 1, 1000150, 0, 5, 'Stonard Orc - World Loot Level 50'), +(865, 1, 1000150, 0, 5, 'Stonard Wayfinder - World Loot Level 50'), +(865, 2, 1000151, 0, 5, 'Stonard Wayfinder - World Loot Level 51'), +(868, 1, 1000153, 0, 5, 'Stonard Shaman - World Loot Level 53'), +(871, 1, 1000135, 0, 5, 'Saltscale Warrior - World Loot Level 35'), +(871, 2, 1000136, 0, 5, 'Saltscale Warrior - World Loot Level 36'), +(873, 1, 1000136, 0, 5, 'Saltscale Oracle - World Loot Level 36'), +(875, 1, 1000137, 0, 5, 'Saltscale Tide Lord - World Loot Level 37'), +(880, 1, 1000108, 0, 5, 'Erlan Drudgemoor - World Loot Level 8'), +(881, 1, 1000109, 0, 5, 'Surena Caledon - World Loot Level 9'), +(889, 1, 1000125, 0, 5, 'Splinter Fist Ogre - World Loot Level 25'), +(889, 2, 1000126, 0, 5, 'Splinter Fist Ogre - World Loot Level 26'), +(891, 1, 1000126, 0, 5, 'Splinter Fist Fire Weaver - World Loot Level 26'), +(891, 2, 1000127, 0, 5, 'Splinter Fist Fire Weaver - World Loot Level 27'), +(892, 1, 1000127, 0, 5, 'Splinter Fist Taskmaster - World Loot Level 27'), +(892, 2, 1000128, 0, 5, 'Splinter Fist Taskmaster - World Loot Level 28'), +(898, 1, 1000126, 0, 5, 'Nightbane Worgen - World Loot Level 26'), +(898, 2, 1000127, 0, 5, 'Nightbane Worgen - World Loot Level 27'), +(909, 1, 1000125, 0, 5, 'Defias Night Blade - World Loot Level 25'), +(909, 2, 1000126, 0, 5, 'Defias Night Blade - World Loot Level 26'), +(910, 1, 1000126, 0, 5, 'Defias Enchanter - World Loot Level 26'), +(910, 2, 1000127, 0, 5, 'Defias Enchanter - World Loot Level 27'), +(921, 1, 1000134, 0, 5, 'Venture Co. Lumberjack - World Loot Level 34'), +(921, 2, 1000135, 0, 5, 'Venture Co. Lumberjack - World Loot Level 35'), +(922, 1, 1000040, 0, 5, 'Silt Crawler - World Loot Level 40'), +(922, 2, 1000041, 0, 5, 'Silt Crawler - World Loot Level 41'), +(930, 1, 1000024, 0, 5, 'Black Widow Hatchling - World Loot Level 24'), +(930, 2, 1000025, 0, 5, 'Black Widow Hatchling - World Loot Level 25'), +(937, 1, 1000132, 0, 5, 'Kurzen Jungle Fighter - World Loot Level 32'), +(937, 2, 1000133, 0, 5, 'Kurzen Jungle Fighter - World Loot Level 33'), +(938, 1, 1000134, 0, 5, 'Kurzen Commando - World Loot Level 34'), +(938, 2, 1000135, 0, 5, 'Kurzen Commando - World Loot Level 35'), +(939, 1, 1000136, 0, 5, 'Kurzen Elite - World Loot Level 36'), +(939, 2, 1000137, 0, 5, 'Kurzen Elite - World Loot Level 37'), +(940, 1, 1000132, 0, 5, 'Kurzen Medicine Man - World Loot Level 32'), +(940, 2, 1000133, 0, 5, 'Kurzen Medicine Man - World Loot Level 33'), +(941, 1, 1000134, 0, 5, 'Kurzen Headshrinker - World Loot Level 34'), +(941, 2, 1000135, 0, 5, 'Kurzen Headshrinker - World Loot Level 35'), +(942, 1, 1000136, 0, 5, 'Kurzen Witch Doctor - World Loot Level 36'), +(942, 2, 1000137, 0, 5, 'Kurzen Witch Doctor - World Loot Level 37'), +(943, 1, 1000134, 0, 5, 'Kurzen Wrangler - World Loot Level 34'), +(948, 1, 1000125, 0, 5, 'Rotted One - World Loot Level 25'), +(948, 2, 1000126, 0, 5, 'Rotted One - World Loot Level 26'), +(977, 1, 1000132, 0, 5, 'Kurzen War Panther - World Loot Level 32'), +(977, 2, 1000133, 0, 5, 'Kurzen War Panther - World Loot Level 33'), +(978, 1, 1000138, 0, 5, 'Kurzen Subchief - World Loot Level 38'), +(979, 1, 1000138, 0, 5, 'Kurzen Shadow Hunter - World Loot Level 38'), +(1007, 1, 1000120, 0, 5, 'Mosshide Gnoll - World Loot Level 20'), +(1007, 2, 1000121, 0, 5, 'Mosshide Gnoll - World Loot Level 21'), +(1008, 1, 1000121, 0, 5, 'Mosshide Mongrel - World Loot Level 21'), +(1008, 2, 1000122, 0, 5, 'Mosshide Mongrel - World Loot Level 22'), +(1009, 1, 1000122, 0, 5, 'Mosshide Mistweaver - World Loot Level 22'), +(1009, 2, 1000123, 0, 5, 'Mosshide Mistweaver - World Loot Level 23'), +(1010, 1, 1000122, 0, 5, 'Mosshide Fenrunner - World Loot Level 22'), +(1010, 2, 1000123, 0, 5, 'Mosshide Fenrunner - World Loot Level 23'), +(1011, 1, 1000123, 0, 5, 'Mosshide Trapper - World Loot Level 23'), +(1011, 2, 1000124, 0, 5, 'Mosshide Trapper - World Loot Level 24'), +(1012, 1, 1000124, 0, 5, 'Mosshide Brute - World Loot Level 24'), +(1012, 2, 1000125, 0, 5, 'Mosshide Brute - World Loot Level 25'), +(1013, 1, 1000125, 0, 5, 'Mosshide Mystic - World Loot Level 25'), +(1013, 2, 1000126, 0, 5, 'Mosshide Mystic - World Loot Level 26'), +(1014, 1, 1000127, 0, 5, 'Mosshide Alpha - World Loot Level 27'), +(1034, 1, 1000123, 0, 5, 'Dragonmaw Raider - World Loot Level 23'), +(1034, 2, 1000124, 0, 5, 'Dragonmaw Raider - World Loot Level 24'), +(1035, 1, 1000123, 0, 5, 'Dragonmaw Swamprunner - World Loot Level 23'), +(1035, 2, 1000124, 0, 5, 'Dragonmaw Swamprunner - World Loot Level 24'), +(1036, 1, 1000124, 0, 5, 'Dragonmaw Centurion - World Loot Level 24'), +(1036, 2, 1000125, 0, 5, 'Dragonmaw Centurion - World Loot Level 25'), +(1038, 1, 1000123, 0, 5, 'Dragonmaw Shadowwarder - World Loot Level 23'), +(1038, 2, 1000124, 0, 5, 'Dragonmaw Shadowwarder - World Loot Level 24'), +(1051, 1, 1000127, 0, 5, 'Dark Iron Dwarf - World Loot Level 27'), +(1051, 2, 1000128, 0, 5, 'Dark Iron Dwarf - World Loot Level 28'), +(1052, 1, 1000128, 0, 5, 'Dark Iron Saboteur - World Loot Level 28'), +(1052, 2, 1000129, 0, 5, 'Dark Iron Saboteur - World Loot Level 29'), +(1053, 1, 1000129, 0, 5, 'Dark Iron Tunneler - World Loot Level 29'), +(1053, 2, 1000130, 0, 5, 'Dark Iron Tunneler - World Loot Level 30'), +(1054, 1, 1000130, 0, 5, 'Dark Iron Demolitionist - World Loot Level 30'), +(1054, 2, 1000131, 0, 5, 'Dark Iron Demolitionist - World Loot Level 31'), +(1057, 1, 1000123, 0, 5, 'Dragonmaw Bonewarder - World Loot Level 23'), +(1057, 2, 1000124, 0, 5, 'Dragonmaw Bonewarder - World Loot Level 24'), +(1059, 1, 1000145, 0, 5, 'Ana\'thek the Cruel - World Loot Level 45'), +(1061, 1, 1000141, 0, 5, 'Gan\'zulah - World Loot Level 41'), +(1062, 1, 1000140, 0, 5, 'Nezzliok the Dire - World Loot Level 40'), +(1065, 1, 1000112, 0, 5, 'Riverpaw Shaman - World Loot Level 12'), +(1065, 2, 1000113, 0, 5, 'Riverpaw Shaman - World Loot Level 13'), +(1094, 1, 1000134, 0, 5, 'Venture Co. Miner - World Loot Level 34'), +(1094, 2, 1000135, 0, 5, 'Venture Co. Miner - World Loot Level 35'), +(1095, 1, 1000136, 0, 5, 'Venture Co. Workboss - World Loot Level 36'), +(1096, 1, 1000135, 0, 5, 'Venture Co. Geologist - World Loot Level 35'), +(1096, 2, 1000136, 0, 5, 'Venture Co. Geologist - World Loot Level 36'), +(1097, 1, 1000134, 0, 5, 'Venture Co. Mechanic - World Loot Level 34'), +(1097, 2, 1000135, 0, 5, 'Venture Co. Mechanic - World Loot Level 35'), +(1110, 1, 1000127, 0, 5, 'Skeletal Raider - World Loot Level 27'), +(1110, 2, 1000128, 0, 5, 'Skeletal Raider - World Loot Level 28'), +(1115, 1, 1000108, 0, 5, 'Rockjaw Skullthumper - World Loot Level 8'), +(1115, 2, 1000109, 0, 5, 'Rockjaw Skullthumper - World Loot Level 9'), +(1116, 1, 1000109, 0, 5, 'Rockjaw Ambusher - World Loot Level 9'), +(1116, 2, 1000110, 0, 5, 'Rockjaw Ambusher - World Loot Level 10'), +(1117, 1, 1000109, 0, 5, 'Rockjaw Bonesnapper - World Loot Level 9'), +(1117, 2, 1000110, 0, 5, 'Rockjaw Bonesnapper - World Loot Level 10'), +(1118, 1, 1000111, 0, 5, 'Rockjaw Backbreaker - World Loot Level 11'), +(1118, 2, 1000112, 0, 5, 'Rockjaw Backbreaker - World Loot Level 12'), +(1142, 1, 1000136, 0, 5, 'Mosh\'Ogg Brute - World Loot Level 36'), +(1142, 2, 1000137, 0, 5, 'Mosh\'Ogg Brute - World Loot Level 37'), +(1144, 1, 1000136, 0, 5, 'Mosh\'Ogg Witch Doctor - World Loot Level 36'), +(1144, 2, 1000137, 0, 5, 'Mosh\'Ogg Witch Doctor - World Loot Level 37'), +(1157, 1, 1000126, 0, 5, 'Cursed Sailor - World Loot Level 26'), +(1157, 2, 1000127, 0, 5, 'Cursed Sailor - World Loot Level 27'), +(1158, 1, 1000127, 0, 5, 'Cursed Marine - World Loot Level 27'), +(1158, 2, 1000128, 0, 5, 'Cursed Marine - World Loot Level 28'), +(1159, 1, 1000129, 0, 5, 'First Mate Snellig - World Loot Level 29'), +(1160, 1, 1000130, 0, 5, 'Captain Halyndor - World Loot Level 30'), +(1161, 1, 1000111, 0, 5, 'Stonesplinter Trogg - World Loot Level 11'), +(1161, 2, 1000112, 0, 5, 'Stonesplinter Trogg - World Loot Level 12'), +(1162, 1, 1000111, 0, 5, 'Stonesplinter Scout - World Loot Level 11'), +(1162, 2, 1000112, 0, 5, 'Stonesplinter Scout - World Loot Level 12'), +(1163, 1, 1000113, 0, 5, 'Stonesplinter Skullthumper - World Loot Level 13'), +(1163, 2, 1000114, 0, 5, 'Stonesplinter Skullthumper - World Loot Level 14'), +(1164, 1, 1000115, 0, 5, 'Stonesplinter Bonesnapper - World Loot Level 15'), +(1164, 2, 1000116, 0, 5, 'Stonesplinter Bonesnapper - World Loot Level 16'), +(1165, 1, 1000117, 0, 5, 'Stonesplinter Geomancer - World Loot Level 17'), +(1165, 2, 1000118, 0, 5, 'Stonesplinter Geomancer - World Loot Level 18'), +(1166, 1, 1000113, 0, 5, 'Stonesplinter Seer - World Loot Level 13'), +(1166, 2, 1000114, 0, 5, 'Stonesplinter Seer - World Loot Level 14'), +(1167, 1, 1000118, 0, 5, 'Stonesplinter Digger - World Loot Level 18'), +(1167, 2, 1000119, 0, 5, 'Stonesplinter Digger - World Loot Level 19'), +(1169, 1, 1000118, 0, 5, 'Dark Iron Insurgent - World Loot Level 18'), +(1169, 2, 1000119, 0, 5, 'Dark Iron Insurgent - World Loot Level 19'), +(1172, 1, 1000110, 0, 5, 'Tunnel Rat Vermin - World Loot Level 10'), +(1172, 2, 1000111, 0, 5, 'Tunnel Rat Vermin - World Loot Level 11'), +(1174, 1, 1000112, 0, 5, 'Tunnel Rat Geomancer - World Loot Level 12'), +(1174, 2, 1000113, 0, 5, 'Tunnel Rat Geomancer - World Loot Level 13'), +(1175, 1, 1000112, 0, 5, 'Tunnel Rat Digger - World Loot Level 12'), +(1175, 2, 1000113, 0, 5, 'Tunnel Rat Digger - World Loot Level 13'), +(1176, 1, 1000111, 0, 5, 'Tunnel Rat Forager - World Loot Level 11'), +(1176, 2, 1000112, 0, 5, 'Tunnel Rat Forager - World Loot Level 12'), +(1177, 1, 1000114, 0, 5, 'Tunnel Rat Surveyor - World Loot Level 14'), +(1178, 1, 1000118, 0, 5, 'Mo\'grosh Ogre - World Loot Level 18'), +(1178, 2, 1000119, 0, 5, 'Mo\'grosh Ogre - World Loot Level 19'), +(1179, 1, 1000118, 0, 5, 'Mo\'grosh Enforcer - World Loot Level 18'), +(1179, 2, 1000119, 0, 5, 'Mo\'grosh Enforcer - World Loot Level 19'), +(1180, 1, 1000119, 0, 5, 'Mo\'grosh Brute - World Loot Level 19'), +(1180, 2, 1000120, 0, 5, 'Mo\'grosh Brute - World Loot Level 20'), +(1181, 1, 1000118, 0, 5, 'Mo\'grosh Shaman - World Loot Level 18'), +(1181, 2, 1000119, 0, 5, 'Mo\'grosh Shaman - World Loot Level 19'), +(1183, 1, 1000119, 0, 5, 'Mo\'grosh Mystic - World Loot Level 19'), +(1183, 2, 1000120, 0, 5, 'Mo\'grosh Mystic - World Loot Level 20'), +(1197, 1, 1000115, 0, 5, 'Stonesplinter Shaman - World Loot Level 15'), +(1197, 2, 1000116, 0, 5, 'Stonesplinter Shaman - World Loot Level 16'), +(1202, 1, 1000111, 0, 5, 'Tunnel Rat Kobold - World Loot Level 11'), +(1202, 2, 1000112, 0, 5, 'Tunnel Rat Kobold - World Loot Level 12'), +(1205, 1, 1000117, 0, 5, 'Grawmug - World Loot Level 17'), +(1206, 1, 1000116, 0, 5, 'Gnasher - World Loot Level 16'), +(1207, 1, 1000116, 0, 5, 'Brawler - World Loot Level 16'), +(1211, 1, 1000108, 0, 5, 'Leper Gnome - World Loot Level 8'), +(1211, 2, 1000109, 0, 5, 'Leper Gnome - World Loot Level 9'), +(1211, 3, 1000110, 0, 5, 'Leper Gnome - World Loot Level 10'), +(1222, 1, 1000117, 0, 5, 'Dark Iron Sapper - World Loot Level 17'), +(1236, 1, 1000112, 0, 5, 'Kobold Digger - World Loot Level 12'), +(1236, 2, 1000113, 0, 5, 'Kobold Digger - World Loot Level 13'), +(1251, 1, 1000128, 0, 5, 'Splinter Fist Firemonger - World Loot Level 28'), +(1251, 2, 1000129, 0, 5, 'Splinter Fist Firemonger - World Loot Level 29'), +(1270, 1, 1000129, 0, 5, 'Fetid Corpse - World Loot Level 29'), +(1270, 2, 1000130, 0, 5, 'Fetid Corpse - World Loot Level 30'), +(1364, 1, 1000131, 0, 5, 'Balgaras the Foul - World Loot Level 31'), +(1393, 1, 1000119, 0, 5, 'Berserk Trogg - World Loot Level 19'), +(1393, 2, 1000120, 0, 5, 'Berserk Trogg - World Loot Level 20'), +(1397, 1, 1000108, 0, 5, 'Frostmane Seer - World Loot Level 8'), +(1397, 2, 1000109, 0, 5, 'Frostmane Seer - World Loot Level 9'), +(1426, 1, 1000114, 0, 5, 'Riverpaw Miner - World Loot Level 14'), +(1426, 2, 1000115, 0, 5, 'Riverpaw Miner - World Loot Level 15'), +(1487, 1, 1000130, 0, 5, 'Splinter Fist Enslaver - World Loot Level 30'), +(1487, 2, 1000131, 0, 5, 'Splinter Fist Enslaver - World Loot Level 31'), +(1488, 1, 1000143, 0, 5, 'Zanzil Zombie - World Loot Level 43'), +(1488, 2, 1000144, 0, 5, 'Zanzil Zombie - World Loot Level 44'), +(1489, 1, 1000143, 0, 5, 'Zanzil Hunter - World Loot Level 43'), +(1489, 2, 1000144, 0, 5, 'Zanzil Hunter - World Loot Level 44'), +(1490, 1, 1000144, 0, 5, 'Zanzil Witch Doctor - World Loot Level 44'), +(1520, 1, 1000106, 0, 5, 'Rattlecage Soldier - World Loot Level 6'), +(1520, 2, 1000107, 0, 5, 'Rattlecage Soldier - World Loot Level 7'), +(1522, 1, 1000107, 0, 5, 'Darkeye Bonecaster - World Loot Level 7'), +(1522, 2, 1000108, 0, 5, 'Darkeye Bonecaster - World Loot Level 8'), +(1523, 1, 1000108, 0, 5, 'Cracked Skull Soldier - World Loot Level 8'), +(1523, 2, 1000109, 0, 5, 'Cracked Skull Soldier - World Loot Level 9'), +(1525, 1, 1000105, 0, 5, 'Rotting Dead - World Loot Level 5'), +(1525, 2, 1000106, 0, 5, 'Rotting Dead - World Loot Level 6'), +(1526, 1, 1000106, 0, 5, 'Ravaged Corpse - World Loot Level 6'), +(1526, 2, 1000107, 0, 5, 'Ravaged Corpse - World Loot Level 7'), +(1527, 1, 1000107, 0, 5, 'Hungering Dead - World Loot Level 7'), +(1527, 2, 1000108, 0, 5, 'Hungering Dead - World Loot Level 8'), +(1529, 1, 1000109, 0, 5, 'Bleeding Horror - World Loot Level 9'), +(1529, 2, 1000110, 0, 5, 'Bleeding Horror - World Loot Level 10'), +(1535, 1, 1000106, 0, 5, 'Scarlet Warrior - World Loot Level 6'), +(1535, 2, 1000107, 0, 5, 'Scarlet Warrior - World Loot Level 7'), +(1537, 1, 1000108, 0, 5, 'Scarlet Zealot - World Loot Level 8'), +(1537, 2, 1000109, 0, 5, 'Scarlet Zealot - World Loot Level 9'), +(1561, 1, 1000140, 0, 5, 'Bloodsail Raider - World Loot Level 40'), +(1561, 2, 1000141, 0, 5, 'Bloodsail Raider - World Loot Level 41'), +(1562, 1, 1000140, 0, 5, 'Bloodsail Mage - World Loot Level 40'), +(1562, 2, 1000141, 0, 5, 'Bloodsail Mage - World Loot Level 41'), +(1563, 1, 1000140, 0, 5, 'Bloodsail Swashbuckler - World Loot Level 40'), +(1563, 2, 1000141, 0, 5, 'Bloodsail Swashbuckler - World Loot Level 41'), +(1564, 1, 1000140, 0, 5, 'Bloodsail Warlock - World Loot Level 40'), +(1564, 2, 1000141, 0, 5, 'Bloodsail Warlock - World Loot Level 41'), +(1565, 1, 1000141, 0, 5, 'Bloodsail Sea Dog - World Loot Level 41'), +(1565, 2, 1000142, 0, 5, 'Bloodsail Sea Dog - World Loot Level 42'), +(1653, 1, 1000141, 0, 5, 'Bloodsail Elder Magus - World Loot Level 41'), +(1653, 2, 1000142, 0, 5, 'Bloodsail Elder Magus - World Loot Level 42'), +(1654, 1, 1000110, 0, 5, 'Gregor Agamand - World Loot Level 10'), +(1655, 1, 1000110, 0, 5, 'Nissa Agamand - World Loot Level 10'), +(1656, 1, 1000110, 0, 5, 'Thurman Agamand - World Loot Level 10'), +(1657, 1, 1000109, 0, 5, 'Devlin Agamand - World Loot Level 9'), +(1658, 1, 1000113, 0, 5, 'Captain Dargol - World Loot Level 13'), +(1660, 1, 1000108, 0, 5, 'Scarlet Bodyguard - World Loot Level 8'), +(1662, 1, 1000109, 0, 5, 'Captain Perrine - World Loot Level 9'), +(1664, 1, 1000111, 0, 5, 'Captain Vachon - World Loot Level 11'), +(1665, 1, 1000112, 0, 5, 'Captain Melrache - World Loot Level 12'), +(1674, 1, 1000106, 0, 5, 'Rot Hide Gnoll - World Loot Level 6'), +(1674, 2, 1000107, 0, 5, 'Rot Hide Gnoll - World Loot Level 7'), +(1675, 1, 1000107, 0, 5, 'Rot Hide Mongrel - World Loot Level 7'), +(1675, 2, 1000108, 0, 5, 'Rot Hide Mongrel - World Loot Level 8'), +(1725, 1, 1000115, 0, 5, 'Defias Watchman - World Loot Level 15'), +(1725, 2, 1000116, 0, 5, 'Defias Watchman - World Loot Level 16'), +(1725, 3, 1000117, 0, 5, 'Defias Watchman - World Loot Level 17'), +(1726, 1, 1000116, 0, 5, 'Defias Magician - World Loot Level 16'), +(1726, 2, 1000117, 0, 5, 'Defias Magician - World Loot Level 17'), +(1727, 1, 1000116, 0, 5, 'Defias Worker - World Loot Level 16'), +(1727, 2, 1000117, 0, 5, 'Defias Worker - World Loot Level 17'), +(1753, 1, 1000110, 0, 5, 'Maggot Eye - World Loot Level 10'), +(1754, 1, 1000131, 0, 5, 'Lord Gregor Lescovar - World Loot Level 31'), +(1766, 1, 1000011, 0, 5, 'Mottled Worg - World Loot Level 11'), +(1766, 2, 1000012, 0, 5, 'Mottled Worg - World Loot Level 12'), +(1768, 1, 1000113, 0, 5, 'Vile Fin Tidehunter - World Loot Level 13'), +(1768, 2, 1000114, 0, 5, 'Vile Fin Tidehunter - World Loot Level 14'), +(1770, 1, 1000111, 0, 5, 'Moonrage Darkrunner - World Loot Level 11'), +(1770, 2, 1000112, 0, 5, 'Moonrage Darkrunner - World Loot Level 12'), +(1772, 1, 1000111, 0, 5, 'Rot Hide Gladerunner - World Loot Level 11'), +(1772, 2, 1000112, 0, 5, 'Rot Hide Gladerunner - World Loot Level 12'), +(1773, 1, 1000112, 0, 5, 'Rot Hide Mystic - World Loot Level 12'), +(1773, 2, 1000113, 0, 5, 'Rot Hide Mystic - World Loot Level 13'), +(1778, 1, 1000011, 0, 5, 'Ferocious Grizzled Bear - World Loot Level 11'), +(1778, 2, 1000012, 0, 5, 'Ferocious Grizzled Bear - World Loot Level 12'), +(1779, 1, 1000112, 0, 5, 'Moonrage Glutton - World Loot Level 12'), +(1779, 2, 1000113, 0, 5, 'Moonrage Glutton - World Loot Level 13'), +(1783, 1, 1000150, 0, 5, 'Skeletal Flayer - World Loot Level 50'), +(1783, 2, 1000151, 0, 5, 'Skeletal Flayer - World Loot Level 51'), +(1784, 1, 1000151, 0, 5, 'Skeletal Sorcerer - World Loot Level 51'), +(1784, 2, 1000152, 0, 5, 'Skeletal Sorcerer - World Loot Level 52'), +(1785, 1, 1000152, 0, 5, 'Skeletal Terror - World Loot Level 52'), +(1785, 2, 1000153, 0, 5, 'Skeletal Terror - World Loot Level 53'), +(1785, 3, 1000154, 0, 5, 'Skeletal Terror - World Loot Level 54'), +(1787, 1, 1000154, 0, 5, 'Skeletal Executioner - World Loot Level 54'), +(1787, 2, 1000155, 0, 5, 'Skeletal Executioner - World Loot Level 55'), +(1788, 1, 1000156, 0, 5, 'Skeletal Warlord - World Loot Level 56'), +(1788, 2, 1000157, 0, 5, 'Skeletal Warlord - World Loot Level 57'), +(1789, 1, 1000155, 0, 5, 'Skeletal Acolyte - World Loot Level 55'), +(1789, 2, 1000156, 0, 5, 'Skeletal Acolyte - World Loot Level 56'), +(1791, 1, 1000150, 0, 5, 'Slavering Ghoul - World Loot Level 50'), +(1791, 2, 1000151, 0, 5, 'Slavering Ghoul - World Loot Level 51'), +(1791, 3, 1000152, 0, 5, 'Slavering Ghoul - World Loot Level 52'), +(1793, 1, 1000154, 0, 5, 'Rotting Ghoul - World Loot Level 54'), +(1793, 2, 1000155, 0, 5, 'Rotting Ghoul - World Loot Level 55'), +(1794, 1, 1000154, 0, 5, 'Soulless Ghoul - World Loot Level 54'), +(1794, 2, 1000155, 0, 5, 'Soulless Ghoul - World Loot Level 55'), +(1795, 1, 1000155, 0, 5, 'Searing Ghoul - World Loot Level 55'), +(1795, 2, 1000156, 0, 5, 'Searing Ghoul - World Loot Level 56'), +(1796, 1, 1000155, 0, 5, 'Freezing Ghoul - World Loot Level 55'), +(1796, 2, 1000156, 0, 5, 'Freezing Ghoul - World Loot Level 56'), +(1802, 1, 1000156, 0, 5, 'Hungering Wraith - World Loot Level 56'), +(1802, 2, 1000157, 0, 5, 'Hungering Wraith - World Loot Level 57'), +(1802, 3, 1000158, 0, 5, 'Hungering Wraith - World Loot Level 58'), +(1804, 1, 1000156, 0, 5, 'Wailing Death - World Loot Level 56'), +(1804, 2, 1000157, 0, 5, 'Wailing Death - World Loot Level 57'), +(1826, 1, 1000155, 0, 5, 'Scarlet Mage - World Loot Level 55'), +(1826, 2, 1000156, 0, 5, 'Scarlet Mage - World Loot Level 56'), +(1827, 1, 1000155, 0, 5, 'Scarlet Sentinel - World Loot Level 55'), +(1827, 2, 1000156, 0, 5, 'Scarlet Sentinel - World Loot Level 56'), +(1831, 1, 1000152, 0, 5, 'Scarlet Hunter - World Loot Level 52'), +(1831, 2, 1000153, 0, 5, 'Scarlet Hunter - World Loot Level 53'), +(1832, 1, 1000156, 0, 5, 'Scarlet Magus - World Loot Level 56'), +(1832, 2, 1000157, 0, 5, 'Scarlet Magus - World Loot Level 57'), +(1833, 1, 1000154, 0, 5, 'Scarlet Knight - World Loot Level 54'), +(1833, 2, 1000155, 0, 5, 'Scarlet Knight - World Loot Level 55'), +(1834, 1, 1000155, 0, 5, 'Scarlet Paladin - World Loot Level 55'), +(1834, 2, 1000156, 0, 5, 'Scarlet Paladin - World Loot Level 56'), +(1835, 1, 1000153, 0, 5, 'Scarlet Invoker - World Loot Level 53'), +(1835, 2, 1000154, 0, 5, 'Scarlet Invoker - World Loot Level 54'), +(1845, 1, 1000159, 0, 5, 'High Protector Tarsen - World Loot Level 59'), +(1865, 1, 1000112, 0, 5, 'Ravenclaw Raider - World Loot Level 12'), +(1865, 2, 1000113, 0, 5, 'Ravenclaw Raider - World Loot Level 13'), +(1866, 1, 1000111, 0, 5, 'Ravenclaw Slave - World Loot Level 11'), +(1866, 2, 1000112, 0, 5, 'Ravenclaw Slave - World Loot Level 12'), +(1867, 1, 1000113, 0, 5, 'Dalaran Apprentice - World Loot Level 13'), +(1867, 2, 1000114, 0, 5, 'Dalaran Apprentice - World Loot Level 14'), +(1868, 1, 1000113, 0, 5, 'Ravenclaw Servant - World Loot Level 13'), +(1868, 2, 1000114, 0, 5, 'Ravenclaw Servant - World Loot Level 14'), +(1869, 1, 1000114, 0, 5, 'Ravenclaw Champion - World Loot Level 14'), +(1869, 2, 1000115, 0, 5, 'Ravenclaw Champion - World Loot Level 15'), +(1870, 1, 1000115, 0, 5, 'Hand of Ravenclaw - World Loot Level 15'), +(1870, 2, 1000116, 0, 5, 'Hand of Ravenclaw - World Loot Level 16'), +(1883, 1, 1000155, 0, 5, 'Scarlet Worker - World Loot Level 55'), +(1883, 2, 1000156, 0, 5, 'Scarlet Worker - World Loot Level 56'), +(1883, 3, 1000157, 0, 5, 'Scarlet Worker - World Loot Level 57'), +(1884, 1, 1000154, 0, 5, 'Scarlet Lumberjack - World Loot Level 54'), +(1884, 2, 1000155, 0, 5, 'Scarlet Lumberjack - World Loot Level 55'), +(1884, 3, 1000156, 0, 5, 'Scarlet Lumberjack - World Loot Level 56'), +(1888, 1, 1000118, 0, 5, 'Dalaran Watcher - World Loot Level 18'), +(1888, 2, 1000119, 0, 5, 'Dalaran Watcher - World Loot Level 19'), +(1889, 1, 1000119, 0, 5, 'Dalaran Wizard - World Loot Level 19'), +(1889, 2, 1000120, 0, 5, 'Dalaran Wizard - World Loot Level 20'), +(1891, 1, 1000113, 0, 5, 'Pyrewood Watcher - World Loot Level 13'), +(1891, 2, 1000114, 0, 5, 'Pyrewood Watcher - World Loot Level 14'), +(1894, 1, 1000114, 0, 5, 'Pyrewood Sentry - World Loot Level 14'), +(1894, 2, 1000115, 0, 5, 'Pyrewood Sentry - World Loot Level 15'), +(1895, 1, 1000114, 0, 5, 'Pyrewood Elder - World Loot Level 14'), +(1895, 2, 1000115, 0, 5, 'Pyrewood Elder - World Loot Level 15'), +(1907, 1, 1000143, 0, 5, 'Naga Explorer - World Loot Level 43'), +(1907, 2, 1000144, 0, 5, 'Naga Explorer - World Loot Level 44'), +(1908, 1, 1000119, 0, 5, 'Vile Fin Oracle - World Loot Level 19'), +(1908, 2, 1000120, 0, 5, 'Vile Fin Oracle - World Loot Level 20'), +(1909, 1, 1000118, 0, 5, 'Vile Fin Lakestalker - World Loot Level 18'), +(1909, 2, 1000119, 0, 5, 'Vile Fin Lakestalker - World Loot Level 19'), +(1912, 1, 1000114, 0, 5, 'Dalaran Protector - World Loot Level 14'), +(1912, 2, 1000115, 0, 5, 'Dalaran Protector - World Loot Level 15'), +(1913, 1, 1000116, 0, 5, 'Dalaran Warder - World Loot Level 16'), +(1913, 2, 1000117, 0, 5, 'Dalaran Warder - World Loot Level 17'), +(1914, 1, 1000115, 0, 5, 'Dalaran Mage - World Loot Level 15'), +(1914, 2, 1000116, 0, 5, 'Dalaran Mage - World Loot Level 16'), +(1915, 1, 1000117, 0, 5, 'Dalaran Conjuror - World Loot Level 17'), +(1915, 2, 1000118, 0, 5, 'Dalaran Conjuror - World Loot Level 18'), +(1934, 1, 1000106, 0, 5, 'Tirisfal Farmer - World Loot Level 6'), +(1934, 2, 1000107, 0, 5, 'Tirisfal Farmer - World Loot Level 7'), +(1935, 1, 1000105, 0, 5, 'Tirisfal Farmhand - World Loot Level 5'), +(1935, 2, 1000106, 0, 5, 'Tirisfal Farmhand - World Loot Level 6'), +(1939, 1, 1000116, 0, 5, 'Rot Hide Brute - World Loot Level 16'), +(1939, 2, 1000117, 0, 5, 'Rot Hide Brute - World Loot Level 17'), +(1940, 1, 1000117, 0, 5, 'Rot Hide Plague Weaver - World Loot Level 17'), +(1940, 2, 1000118, 0, 5, 'Rot Hide Plague Weaver - World Loot Level 18'), +(1941, 1, 1000106, 0, 5, 'Rot Hide Graverobber - World Loot Level 6'), +(1941, 2, 1000107, 0, 5, 'Rot Hide Graverobber - World Loot Level 7'), +(1942, 1, 1000118, 0, 5, 'Rot Hide Savage - World Loot Level 18'), +(1942, 2, 1000119, 0, 5, 'Rot Hide Savage - World Loot Level 19'), +(1943, 1, 1000118, 0, 5, 'Raging Rot Hide - World Loot Level 18'), +(1943, 2, 1000119, 0, 5, 'Raging Rot Hide - World Loot Level 19'), +(1947, 1, 1000120, 0, 5, 'Thule Ravenclaw - World Loot Level 20'), +(1957, 1, 1000116, 0, 5, 'Vile Fin Shorecreeper - World Loot Level 16'), +(1957, 2, 1000117, 0, 5, 'Vile Fin Shorecreeper - World Loot Level 17'), +(1958, 1, 1000117, 0, 5, 'Vile Fin Tidecaller - World Loot Level 17'), +(1958, 2, 1000118, 0, 5, 'Vile Fin Tidecaller - World Loot Level 18'), +(1971, 1, 1000113, 0, 5, 'Ivar the Foul - World Loot Level 13'), +(1973, 1, 1000120, 0, 5, 'Ravenclaw Guardian - World Loot Level 20'), +(1973, 2, 1000121, 0, 5, 'Ravenclaw Guardian - World Loot Level 21'), +(1974, 1, 1000119, 0, 5, 'Ravenclaw Drudger - World Loot Level 19'), +(1974, 2, 1000120, 0, 5, 'Ravenclaw Drudger - World Loot Level 20'), +(1983, 1, 1000114, 0, 5, 'Nightlash - World Loot Level 14'), +(1993, 1, 1000110, 0, 5, 'Greenpaw - World Loot Level 10'), +(2002, 1, 1000105, 0, 5, 'Rascal Sprite - World Loot Level 5'), +(2002, 2, 1000106, 0, 5, 'Rascal Sprite - World Loot Level 6'), +(2003, 1, 1000105, 0, 5, 'Shadow Sprite - World Loot Level 5'), +(2003, 2, 1000106, 0, 5, 'Shadow Sprite - World Loot Level 6'), +(2004, 1, 1000106, 0, 5, 'Dark Sprite - World Loot Level 6'), +(2004, 2, 1000107, 0, 5, 'Dark Sprite - World Loot Level 7'), +(2005, 1, 1000107, 0, 5, 'Vicious Grell - World Loot Level 7'), +(2006, 1, 1000105, 0, 5, 'Gnarlpine Ursa - World Loot Level 5'), +(2006, 2, 1000106, 0, 5, 'Gnarlpine Ursa - World Loot Level 6'), +(2007, 1, 1000105, 0, 5, 'Gnarlpine Gardener - World Loot Level 5'), +(2007, 2, 1000106, 0, 5, 'Gnarlpine Gardener - World Loot Level 6'), +(2008, 1, 1000106, 0, 5, 'Gnarlpine Warrior - World Loot Level 6'), +(2008, 2, 1000107, 0, 5, 'Gnarlpine Warrior - World Loot Level 7'), +(2009, 1, 1000107, 0, 5, 'Gnarlpine Shaman - World Loot Level 7'), +(2009, 2, 1000108, 0, 5, 'Gnarlpine Shaman - World Loot Level 8'), +(2010, 1, 1000107, 0, 5, 'Gnarlpine Defender - World Loot Level 7'), +(2010, 2, 1000108, 0, 5, 'Gnarlpine Defender - World Loot Level 8'), +(2011, 1, 1000108, 0, 5, 'Gnarlpine Augur - World Loot Level 8'), +(2011, 2, 1000109, 0, 5, 'Gnarlpine Augur - World Loot Level 9'), +(2012, 1, 1000109, 0, 5, 'Gnarlpine Pathfinder - World Loot Level 9'), +(2012, 2, 1000110, 0, 5, 'Gnarlpine Pathfinder - World Loot Level 10'), +(2013, 1, 1000109, 0, 5, 'Gnarlpine Avenger - World Loot Level 9'), +(2013, 2, 1000110, 0, 5, 'Gnarlpine Avenger - World Loot Level 10'), +(2014, 1, 1000110, 0, 5, 'Gnarlpine Totemic - World Loot Level 10'), +(2014, 2, 1000111, 0, 5, 'Gnarlpine Totemic - World Loot Level 11'), +(2015, 1, 1000108, 0, 5, 'Bloodfeather Harpy - World Loot Level 8'), +(2015, 2, 1000109, 0, 5, 'Bloodfeather Harpy - World Loot Level 9'), +(2017, 1, 1000108, 0, 5, 'Bloodfeather Rogue - World Loot Level 8'), +(2017, 2, 1000109, 0, 5, 'Bloodfeather Rogue - World Loot Level 9'), +(2018, 1, 1000109, 0, 5, 'Bloodfeather Sorceress - World Loot Level 9'), +(2019, 1, 1000109, 0, 5, 'Bloodfeather Fury - World Loot Level 9'), +(2019, 2, 1000110, 0, 5, 'Bloodfeather Fury - World Loot Level 10'), +(2020, 1, 1000109, 0, 5, 'Bloodfeather Wind Witch - World Loot Level 9'), +(2020, 2, 1000110, 0, 5, 'Bloodfeather Wind Witch - World Loot Level 10'), +(2021, 1, 1000111, 0, 5, 'Bloodfeather Matriarch - World Loot Level 11'), +(2038, 1, 1000108, 0, 5, 'Lord Melenas - World Loot Level 8'), +(2039, 1, 1000112, 0, 5, 'Ursal the Mauler - World Loot Level 12'), +(2053, 1, 1000118, 0, 5, 'Haggard Refugee - World Loot Level 18'), +(2053, 2, 1000119, 0, 5, 'Haggard Refugee - World Loot Level 19'), +(2054, 1, 1000119, 0, 5, 'Sickly Refugee - World Loot Level 19'), +(2054, 2, 1000120, 0, 5, 'Sickly Refugee - World Loot Level 20'), +(2091, 1, 1000126, 0, 5, 'Chieftain Nek\'rosh - World Loot Level 26'), +(2102, 1, 1000120, 0, 5, 'Dragonmaw Grunt - World Loot Level 20'), +(2102, 2, 1000121, 0, 5, 'Dragonmaw Grunt - World Loot Level 21'), +(2103, 1, 1000119, 0, 5, 'Dragonmaw Scout - World Loot Level 19'), +(2103, 2, 1000120, 0, 5, 'Dragonmaw Scout - World Loot Level 20'), +(2120, 1, 1000122, 0, 5, 'Archmage Ataeric - World Loot Level 22'), +(2152, 1, 1000106, 0, 5, 'Gnarlpine Ambusher - World Loot Level 6'), +(2152, 2, 1000107, 0, 5, 'Gnarlpine Ambusher - World Loot Level 7'), +(2156, 1, 1000018, 0, 5, 'Cracked Golem - World Loot Level 18'), +(2156, 2, 1000019, 0, 5, 'Cracked Golem - World Loot Level 19'), +(2157, 1, 1000019, 0, 5, 'Stone Behemoth - World Loot Level 19'), +(2157, 2, 1000020, 0, 5, 'Stone Behemoth - World Loot Level 20'), +(2162, 1, 1000108, 0, 5, 'Agal - World Loot Level 8'), +(2164, 1, 1000013, 0, 5, 'Rabid Thistle Bear - World Loot Level 13'), +(2167, 1, 1000112, 0, 5, 'Blackwood Pathfinder - World Loot Level 12'), +(2167, 2, 1000113, 0, 5, 'Blackwood Pathfinder - World Loot Level 13'), +(2168, 1, 1000116, 0, 5, 'Blackwood Warrior - World Loot Level 16'), +(2168, 2, 1000117, 0, 5, 'Blackwood Warrior - World Loot Level 17'), +(2169, 1, 1000117, 0, 5, 'Blackwood Totemic - World Loot Level 17'), +(2169, 2, 1000118, 0, 5, 'Blackwood Totemic - World Loot Level 18'), +(2170, 1, 1000118, 0, 5, 'Blackwood Ursa - World Loot Level 18'), +(2170, 2, 1000119, 0, 5, 'Blackwood Ursa - World Loot Level 19'), +(2171, 1, 1000119, 0, 5, 'Blackwood Shaman - World Loot Level 19'), +(2171, 2, 1000120, 0, 5, 'Blackwood Shaman - World Loot Level 20'), +(2176, 1, 1000110, 0, 5, 'Cursed Highborne - World Loot Level 10'), +(2176, 2, 1000111, 0, 5, 'Cursed Highborne - World Loot Level 11'), +(2177, 1, 1000111, 0, 5, 'Writhing Highborne - World Loot Level 11'), +(2177, 2, 1000112, 0, 5, 'Writhing Highborne - World Loot Level 12'), +(2178, 1, 1000112, 0, 5, 'Wailing Highborne - World Loot Level 12'), +(2178, 2, 1000113, 0, 5, 'Wailing Highborne - World Loot Level 13'), +(2179, 1, 1000115, 0, 5, 'Stormscale Wave Rider - World Loot Level 15'), +(2179, 2, 1000116, 0, 5, 'Stormscale Wave Rider - World Loot Level 16'), +(2180, 1, 1000116, 0, 5, 'Stormscale Siren - World Loot Level 16'), +(2180, 2, 1000117, 0, 5, 'Stormscale Siren - World Loot Level 17'), +(2181, 1, 1000118, 0, 5, 'Stormscale Myrmidon - World Loot Level 18'), +(2181, 2, 1000119, 0, 5, 'Stormscale Myrmidon - World Loot Level 19'), +(2183, 1, 1000120, 0, 5, 'Stormscale Warrior - World Loot Level 20'), +(2183, 2, 1000121, 0, 5, 'Stormscale Warrior - World Loot Level 21'), +(2189, 1, 1000110, 0, 5, 'Vile Sprite - World Loot Level 10'), +(2189, 2, 1000111, 0, 5, 'Vile Sprite - World Loot Level 11'), +(2190, 1, 1000111, 0, 5, 'Wild Grell - World Loot Level 11'), +(2190, 2, 1000112, 0, 5, 'Wild Grell - World Loot Level 12'), +(2203, 1, 1000113, 0, 5, 'Greymist Seer - World Loot Level 13'), +(2203, 2, 1000114, 0, 5, 'Greymist Seer - World Loot Level 14'), +(2212, 1, 1000112, 0, 5, 'Deth\'ryll Satyr - World Loot Level 12'), +(2212, 2, 1000113, 0, 5, 'Deth\'ryll Satyr - World Loot Level 13'), +(2240, 1, 1000132, 0, 5, 'Syndicate Footpad - World Loot Level 32'), +(2240, 2, 1000133, 0, 5, 'Syndicate Footpad - World Loot Level 33'), +(2241, 1, 1000133, 0, 5, 'Syndicate Thief - World Loot Level 33'), +(2241, 2, 1000134, 0, 5, 'Syndicate Thief - World Loot Level 34'), +(2242, 1, 1000135, 0, 5, 'Syndicate Spy - World Loot Level 35'), +(2242, 2, 1000136, 0, 5, 'Syndicate Spy - World Loot Level 36'), +(2243, 1, 1000136, 0, 5, 'Syndicate Sentry - World Loot Level 36'), +(2243, 2, 1000137, 0, 5, 'Syndicate Sentry - World Loot Level 37'), +(2244, 1, 1000121, 0, 5, 'Syndicate Shadow Mage - World Loot Level 21'), +(2244, 2, 1000122, 0, 5, 'Syndicate Shadow Mage - World Loot Level 22'), +(2245, 1, 1000137, 0, 5, 'Syndicate Saboteur - World Loot Level 37'), +(2245, 2, 1000138, 0, 5, 'Syndicate Saboteur - World Loot Level 38'), +(2246, 1, 1000138, 0, 5, 'Syndicate Assassin - World Loot Level 38'), +(2246, 2, 1000139, 0, 5, 'Syndicate Assassin - World Loot Level 39'), +(2247, 1, 1000139, 0, 5, 'Syndicate Enforcer - World Loot Level 39'), +(2247, 2, 1000140, 0, 5, 'Syndicate Enforcer - World Loot Level 40'), +(2248, 1, 1000130, 0, 5, 'Cave Yeti - World Loot Level 30'), +(2248, 2, 1000131, 0, 5, 'Cave Yeti - World Loot Level 31'), +(2249, 1, 1000131, 0, 5, 'Ferocious Yeti - World Loot Level 31'), +(2249, 2, 1000132, 0, 5, 'Ferocious Yeti - World Loot Level 32'), +(2252, 1, 1000134, 0, 5, 'Crushridge Ogre - World Loot Level 34'), +(2252, 2, 1000135, 0, 5, 'Crushridge Ogre - World Loot Level 35'), +(2253, 1, 1000135, 0, 5, 'Crushridge Brute - World Loot Level 35'), +(2253, 2, 1000136, 0, 5, 'Crushridge Brute - World Loot Level 36'), +(2254, 1, 1000136, 0, 5, 'Crushridge Mauler - World Loot Level 36'), +(2254, 2, 1000137, 0, 5, 'Crushridge Mauler - World Loot Level 37'), +(2255, 1, 1000137, 0, 5, 'Crushridge Mage - World Loot Level 37'), +(2255, 2, 1000138, 0, 5, 'Crushridge Mage - World Loot Level 38'), +(2256, 1, 1000138, 0, 5, 'Crushridge Enforcer - World Loot Level 38'), +(2256, 2, 1000139, 0, 5, 'Crushridge Enforcer - World Loot Level 39'), +(2257, 1, 1000143, 0, 5, 'Mug\'thol - World Loot Level 43'), +(2260, 1, 1000121, 0, 5, 'Syndicate Rogue - World Loot Level 21'), +(2260, 2, 1000122, 0, 5, 'Syndicate Rogue - World Loot Level 22'), +(2261, 1, 1000120, 0, 5, 'Syndicate Watchman - World Loot Level 20'), +(2261, 2, 1000121, 0, 5, 'Syndicate Watchman - World Loot Level 21'), +(2264, 1, 1000124, 0, 5, 'Hillsbrad Tailor - World Loot Level 24'), +(2264, 2, 1000125, 0, 5, 'Hillsbrad Tailor - World Loot Level 25'), +(2265, 1, 1000124, 0, 5, 'Hillsbrad Apprentice Blacksmith - World Loot Level 24'), +(2265, 2, 1000125, 0, 5, 'Hillsbrad Apprentice Blacksmith - World Loot Level 25'), +(2266, 1, 1000123, 0, 5, 'Hillsbrad Farmer - World Loot Level 23'), +(2266, 2, 1000124, 0, 5, 'Hillsbrad Farmer - World Loot Level 24'), +(2267, 1, 1000124, 0, 5, 'Hillsbrad Peasant - World Loot Level 24'), +(2267, 2, 1000125, 0, 5, 'Hillsbrad Peasant - World Loot Level 25'), +(2268, 1, 1000125, 0, 5, 'Hillsbrad Footman - World Loot Level 25'), +(2268, 2, 1000126, 0, 5, 'Hillsbrad Footman - World Loot Level 26'), +(2269, 1, 1000126, 0, 5, 'Hillsbrad Miner - World Loot Level 26'), +(2269, 2, 1000127, 0, 5, 'Hillsbrad Miner - World Loot Level 27'), +(2270, 1, 1000127, 0, 5, 'Hillsbrad Sentry - World Loot Level 27'), +(2270, 2, 1000128, 0, 5, 'Hillsbrad Sentry - World Loot Level 28'), +(2271, 1, 1000131, 0, 5, 'Dalaran Shield Guard - World Loot Level 31'), +(2271, 2, 1000132, 0, 5, 'Dalaran Shield Guard - World Loot Level 32'), +(2272, 1, 1000132, 0, 5, 'Dalaran Theurgist - World Loot Level 32'), +(2272, 2, 1000133, 0, 5, 'Dalaran Theurgist - World Loot Level 33'), +(2287, 1, 1000139, 0, 5, 'Crushridge Warmonger - World Loot Level 39'), +(2287, 2, 1000140, 0, 5, 'Crushridge Warmonger - World Loot Level 40'), +(2304, 1, 1000132, 0, 5, 'Captain Ironhill - World Loot Level 32'), +(2305, 1, 1000130, 0, 5, 'Foreman Bonds - World Loot Level 30'), +(2306, 1, 1000140, 0, 5, 'Baron Vardus - World Loot Level 40'), +(2318, 1, 1000135, 0, 5, 'Argus Shadow Mage - World Loot Level 35'), +(2318, 2, 1000136, 0, 5, 'Argus Shadow Mage - World Loot Level 36'), +(2319, 1, 1000135, 0, 5, 'Syndicate Wizard - World Loot Level 35'), +(2320, 1, 1000140, 0, 5, 'Nagaz - World Loot Level 40'), +(2324, 1, 1000113, 0, 5, 'Blackwood Windtalker - World Loot Level 13'), +(2324, 2, 1000114, 0, 5, 'Blackwood Windtalker - World Loot Level 14'), +(2332, 1, 1000121, 0, 5, 'Valdred Moray - World Loot Level 21'), +(2335, 1, 1000130, 0, 5, 'Magistrate Burnside - World Loot Level 30'), +(2336, 1, 1000116, 0, 5, 'Dark Strand Fanatic - World Loot Level 16'), +(2336, 2, 1000117, 0, 5, 'Dark Strand Fanatic - World Loot Level 17'), +(2337, 1, 1000128, 0, 5, 'Dark Strand Voidcaller - World Loot Level 28'), +(2337, 2, 1000129, 0, 5, 'Dark Strand Voidcaller - World Loot Level 29'), +(2338, 1, 1000116, 0, 5, 'Twilight Disciple - World Loot Level 16'), +(2338, 2, 1000117, 0, 5, 'Twilight Disciple - World Loot Level 17'), +(2339, 1, 1000117, 0, 5, 'Twilight Thug - World Loot Level 17'), +(2339, 2, 1000118, 0, 5, 'Twilight Thug - World Loot Level 18'), +(2344, 1, 1000128, 0, 5, 'Dun Garok Mountaineer - World Loot Level 28'), +(2344, 2, 1000129, 0, 5, 'Dun Garok Mountaineer - World Loot Level 29'), +(2345, 1, 1000129, 0, 5, 'Dun Garok Rifleman - World Loot Level 29'), +(2345, 2, 1000130, 0, 5, 'Dun Garok Rifleman - World Loot Level 30'), +(2346, 1, 1000129, 0, 5, 'Dun Garok Priest - World Loot Level 29'), +(2346, 2, 1000130, 0, 5, 'Dun Garok Priest - World Loot Level 30'), +(2358, 1, 1000134, 0, 5, 'Dalaran Summoner - World Loot Level 34'), +(2358, 2, 1000135, 0, 5, 'Dalaran Summoner - World Loot Level 35'), +(2359, 1, 1000033, 0, 5, 'Elemental Slave - World Loot Level 33'), +(2359, 2, 1000034, 0, 5, 'Elemental Slave - World Loot Level 34'), +(2360, 1, 1000122, 0, 5, 'Hillsbrad Farmhand - World Loot Level 22'), +(2360, 2, 1000123, 0, 5, 'Hillsbrad Farmhand - World Loot Level 23'), +(2372, 1, 1000126, 0, 5, 'Mudsnout Gnoll - World Loot Level 26'), +(2372, 2, 1000127, 0, 5, 'Mudsnout Gnoll - World Loot Level 27'), +(2373, 1, 1000127, 0, 5, 'Mudsnout Shaman - World Loot Level 27'), +(2373, 2, 1000128, 0, 5, 'Mudsnout Shaman - World Loot Level 28'), +(2374, 1, 1000128, 0, 5, 'Torn Fin Muckdweller - World Loot Level 28'), +(2374, 2, 1000129, 0, 5, 'Torn Fin Muckdweller - World Loot Level 29'), +(2375, 1, 1000129, 0, 5, 'Torn Fin Coastrunner - World Loot Level 29'), +(2375, 2, 1000130, 0, 5, 'Torn Fin Coastrunner - World Loot Level 30'), +(2376, 1, 1000130, 0, 5, 'Torn Fin Oracle - World Loot Level 30'), +(2376, 2, 1000131, 0, 5, 'Torn Fin Oracle - World Loot Level 31'), +(2377, 1, 1000131, 0, 5, 'Torn Fin Tidehunter - World Loot Level 31'), +(2377, 2, 1000132, 0, 5, 'Torn Fin Tidehunter - World Loot Level 32'), +(2387, 1, 1000125, 0, 5, 'Hillsbrad Councilman - World Loot Level 25'), +(2387, 2, 1000126, 0, 5, 'Hillsbrad Councilman - World Loot Level 26'), +(2403, 1, 1000124, 0, 5, 'Farmer Getz - World Loot Level 24'), +(2404, 1, 1000126, 0, 5, 'Blacksmith Verringtan - World Loot Level 26'), +(2411, 1, 1000133, 0, 5, 'Ricter - World Loot Level 33'), +(2412, 1, 1000133, 0, 5, 'Alina - World Loot Level 33'), +(2413, 1, 1000134, 0, 5, 'Dermot - World Loot Level 34'), +(2414, 1, 1000135, 0, 5, 'Kegan Darkmar - World Loot Level 35'), +(2415, 1, 1000136, 0, 5, 'Warden Belamoore - World Loot Level 36'), +(2416, 1, 1000136, 0, 5, 'Crushridge Plunderer - World Loot Level 36'), +(2416, 2, 1000137, 0, 5, 'Crushridge Plunderer - World Loot Level 37'), +(2420, 1, 1000141, 0, 5, 'Targ - World Loot Level 41'), +(2421, 1, 1000140, 0, 5, 'Muckrake - World Loot Level 40'), +(2422, 1, 1000139, 0, 5, 'Glommus - World Loot Level 39'), +(2423, 1, 1000141, 0, 5, 'Lord Aliden Perenolde - World Loot Level 41'), +(2427, 1, 1000124, 0, 5, 'Jailor Eston - World Loot Level 24'), +(2428, 1, 1000124, 0, 5, 'Jailor Marlgen - World Loot Level 24'), +(2431, 1, 1000137, 0, 5, 'Jailor Borhuin - World Loot Level 37'), +(2440, 1, 1000132, 0, 5, 'Drunken Footpad - World Loot Level 32'), +(2440, 2, 1000133, 0, 5, 'Drunken Footpad - World Loot Level 33'), +(2448, 1, 1000126, 0, 5, 'Clerk Horrace Whitesteed - World Loot Level 26'), +(2449, 1, 1000125, 0, 5, 'Citizen Wilkes - World Loot Level 25'), +(2450, 1, 1000129, 0, 5, 'Miner Hackett - World Loot Level 29'), +(2451, 1, 1000125, 0, 5, 'Farmer Kalaba - World Loot Level 25'), +(2503, 1, 1000127, 0, 5, 'Hillsbrad Foreman - World Loot Level 27'), +(2503, 2, 1000128, 0, 5, 'Hillsbrad Foreman - World Loot Level 28'), +(2521, 1, 1000041, 0, 5, 'Skymane Gorilla - World Loot Level 41'), +(2522, 1, 1000041, 0, 5, 'Jaguero Stalker - World Loot Level 41'), +(2530, 1, 1000141, 0, 5, 'Yenniku - World Loot Level 41'), +(2534, 1, 1000146, 0, 5, 'Zanzil the Outcast - World Loot Level 46'), +(2535, 1, 1000143, 0, 5, 'Maury "Club Foot" Wilkins - World Loot Level 43'), +(2535, 2, 1000144, 0, 5, 'Maury "Club Foot" Wilkins - World Loot Level 44'), +(2536, 1, 1000143, 0, 5, 'Jon-Jon the Crow - World Loot Level 43'), +(2536, 2, 1000144, 0, 5, 'Jon-Jon the Crow - World Loot Level 44'), +(2537, 1, 1000143, 0, 5, 'Chucky "Ten Thumbs" - World Loot Level 43'), +(2537, 2, 1000144, 0, 5, 'Chucky "Ten Thumbs" - World Loot Level 44'), +(2545, 1, 1000139, 0, 5, '"Pretty Boy" Duncan - World Loot Level 39'), +(2546, 1, 1000142, 0, 5, 'Fleet Master Firallon - World Loot Level 42'), +(2547, 1, 1000143, 0, 5, 'Ironpatch - World Loot Level 43'), +(2548, 1, 1000142, 0, 5, 'Captain Keelhaul - World Loot Level 42'), +(2549, 1, 1000142, 0, 5, 'Garr Salthoof - World Loot Level 42'), +(2550, 1, 1000142, 0, 5, 'Captain Stillwater - World Loot Level 42'), +(2552, 1, 1000130, 0, 5, 'Witherbark Troll - World Loot Level 30'), +(2552, 2, 1000131, 0, 5, 'Witherbark Troll - World Loot Level 31'), +(2553, 1, 1000131, 0, 5, 'Witherbark Shadowcaster - World Loot Level 31'), +(2553, 2, 1000132, 0, 5, 'Witherbark Shadowcaster - World Loot Level 32'), +(2554, 1, 1000132, 0, 5, 'Witherbark Axe Thrower - World Loot Level 32'), +(2554, 2, 1000133, 0, 5, 'Witherbark Axe Thrower - World Loot Level 33'), +(2555, 1, 1000133, 0, 5, 'Witherbark Witch Doctor - World Loot Level 33'), +(2555, 2, 1000134, 0, 5, 'Witherbark Witch Doctor - World Loot Level 34'), +(2556, 1, 1000134, 0, 5, 'Witherbark Headhunter - World Loot Level 34'), +(2556, 2, 1000135, 0, 5, 'Witherbark Headhunter - World Loot Level 35'), +(2557, 1, 1000135, 0, 5, 'Witherbark Shadow Hunter - World Loot Level 35'), +(2557, 2, 1000136, 0, 5, 'Witherbark Shadow Hunter - World Loot Level 36'), +(2558, 1, 1000136, 0, 5, 'Witherbark Berserker - World Loot Level 36'), +(2558, 2, 1000137, 0, 5, 'Witherbark Berserker - World Loot Level 37'), +(2562, 1, 1000132, 0, 5, 'Boulderfist Ogre - World Loot Level 32'), +(2562, 2, 1000133, 0, 5, 'Boulderfist Ogre - World Loot Level 33'), +(2564, 1, 1000133, 0, 5, 'Boulderfist Enforcer - World Loot Level 33'), +(2564, 2, 1000134, 0, 5, 'Boulderfist Enforcer - World Loot Level 34'), +(2566, 1, 1000135, 0, 5, 'Boulderfist Brute - World Loot Level 35'), +(2566, 2, 1000136, 0, 5, 'Boulderfist Brute - World Loot Level 36'), +(2567, 1, 1000136, 0, 5, 'Boulderfist Magus - World Loot Level 36'), +(2567, 2, 1000137, 0, 5, 'Boulderfist Magus - World Loot Level 37'), +(2569, 1, 1000137, 0, 5, 'Boulderfist Mauler - World Loot Level 37'), +(2569, 2, 1000138, 0, 5, 'Boulderfist Mauler - World Loot Level 38'), +(2570, 1, 1000138, 0, 5, 'Boulderfist Shaman - World Loot Level 38'), +(2570, 2, 1000139, 0, 5, 'Boulderfist Shaman - World Loot Level 39'), +(2571, 1, 1000139, 0, 5, 'Boulderfist Lord - World Loot Level 39'), +(2571, 2, 1000140, 0, 5, 'Boulderfist Lord - World Loot Level 40'), +(2572, 1, 1000135, 0, 5, 'Drywhisker Kobold - World Loot Level 35'), +(2572, 2, 1000136, 0, 5, 'Drywhisker Kobold - World Loot Level 36'), +(2573, 1, 1000137, 0, 5, 'Drywhisker Surveyor - World Loot Level 37'), +(2573, 2, 1000138, 0, 5, 'Drywhisker Surveyor - World Loot Level 38'), +(2574, 1, 1000136, 0, 5, 'Drywhisker Digger - World Loot Level 36'), +(2574, 2, 1000137, 0, 5, 'Drywhisker Digger - World Loot Level 37'), +(2575, 1, 1000131, 0, 5, 'Dark Iron Supplier - World Loot Level 31'), +(2575, 2, 1000132, 0, 5, 'Dark Iron Supplier - World Loot Level 32'), +(2577, 1, 1000131, 0, 5, 'Dark Iron Shadowcaster - World Loot Level 31'), +(2577, 2, 1000132, 0, 5, 'Dark Iron Shadowcaster - World Loot Level 32'), +(2581, 1, 1000131, 0, 5, 'Dabyrie Militia - World Loot Level 31'), +(2581, 2, 1000132, 0, 5, 'Dabyrie Militia - World Loot Level 32'), +(2582, 1, 1000130, 0, 5, 'Dabyrie Laborer - World Loot Level 30'), +(2582, 2, 1000131, 0, 5, 'Dabyrie Laborer - World Loot Level 31'), +(2583, 1, 1000137, 0, 5, 'Stromgarde Troll Hunter - World Loot Level 37'), +(2583, 2, 1000138, 0, 5, 'Stromgarde Troll Hunter - World Loot Level 38'), +(2584, 1, 1000137, 0, 5, 'Stromgarde Defender - World Loot Level 37'), +(2584, 2, 1000138, 0, 5, 'Stromgarde Defender - World Loot Level 38'), +(2585, 1, 1000138, 0, 5, 'Stromgarde Vindicator - World Loot Level 38'), +(2585, 2, 1000139, 0, 5, 'Stromgarde Vindicator - World Loot Level 39'), +(2586, 1, 1000130, 0, 5, 'Syndicate Highwayman - World Loot Level 30'), +(2586, 2, 1000131, 0, 5, 'Syndicate Highwayman - World Loot Level 31'), +(2587, 1, 1000132, 0, 5, 'Syndicate Pathstalker - World Loot Level 32'), +(2587, 2, 1000133, 0, 5, 'Syndicate Pathstalker - World Loot Level 33'), +(2588, 1, 1000136, 0, 5, 'Syndicate Prowler - World Loot Level 36'), +(2588, 2, 1000137, 0, 5, 'Syndicate Prowler - World Loot Level 37'), +(2589, 1, 1000131, 0, 5, 'Syndicate Mercenary - World Loot Level 31'), +(2589, 2, 1000132, 0, 5, 'Syndicate Mercenary - World Loot Level 32'), +(2590, 1, 1000135, 0, 5, 'Syndicate Conjuror - World Loot Level 35'), +(2590, 2, 1000136, 0, 5, 'Syndicate Conjuror - World Loot Level 36'), +(2591, 1, 1000137, 0, 5, 'Syndicate Magus - World Loot Level 37'), +(2591, 2, 1000138, 0, 5, 'Syndicate Magus - World Loot Level 38'), +(2597, 1, 1000140, 0, 5, 'Lord Falconcrest - World Loot Level 40'), +(2599, 1, 1000138, 0, 5, 'Otto - World Loot Level 38'), +(2607, 1, 1000144, 0, 5, 'Prince Galen Trollbane - World Loot Level 44'), +(2612, 1, 1000138, 0, 5, 'Lieutenant Valorcall - World Loot Level 38'), +(2618, 1, 1000133, 0, 5, 'Hammerfall Peon - World Loot Level 33'), +(2618, 2, 1000134, 0, 5, 'Hammerfall Peon - World Loot Level 34'), +(2619, 1, 1000134, 0, 5, 'Hammerfall Grunt - World Loot Level 34'), +(2619, 2, 1000135, 0, 5, 'Hammerfall Grunt - World Loot Level 35'), +(2628, 1, 1000133, 0, 5, 'Dalaran Worker - World Loot Level 33'), +(2628, 2, 1000134, 0, 5, 'Dalaran Worker - World Loot Level 34'), +(2636, 1, 1000138, 0, 5, 'Blackwater Deckhand - World Loot Level 38'), +(2636, 2, 1000139, 0, 5, 'Blackwater Deckhand - World Loot Level 39'), +(2639, 1, 1000145, 0, 5, 'Vilebranch Axe Thrower - World Loot Level 45'), +(2639, 2, 1000146, 0, 5, 'Vilebranch Axe Thrower - World Loot Level 46'), +(2640, 1, 1000146, 0, 5, 'Vilebranch Witch Doctor - World Loot Level 46'), +(2640, 2, 1000147, 0, 5, 'Vilebranch Witch Doctor - World Loot Level 47'), +(2641, 1, 1000146, 0, 5, 'Vilebranch Headhunter - World Loot Level 46'), +(2641, 2, 1000147, 0, 5, 'Vilebranch Headhunter - World Loot Level 47'), +(2642, 1, 1000147, 0, 5, 'Vilebranch Shadowcaster - World Loot Level 47'), +(2642, 2, 1000148, 0, 5, 'Vilebranch Shadowcaster - World Loot Level 48'), +(2643, 1, 1000147, 0, 5, 'Vilebranch Berserker - World Loot Level 47'), +(2643, 2, 1000148, 0, 5, 'Vilebranch Berserker - World Loot Level 48'), +(2644, 1, 1000148, 0, 5, 'Vilebranch Hideskinner - World Loot Level 48'), +(2644, 2, 1000149, 0, 5, 'Vilebranch Hideskinner - World Loot Level 49'), +(2645, 1, 1000148, 0, 5, 'Vilebranch Shadow Hunter - World Loot Level 48'), +(2645, 2, 1000149, 0, 5, 'Vilebranch Shadow Hunter - World Loot Level 49'), +(2646, 1, 1000149, 0, 5, 'Vilebranch Blood Drinker - World Loot Level 49'), +(2646, 2, 1000150, 0, 5, 'Vilebranch Blood Drinker - World Loot Level 50'), +(2647, 1, 1000149, 0, 5, 'Vilebranch Soul Eater - World Loot Level 49'), +(2647, 2, 1000150, 0, 5, 'Vilebranch Soul Eater - World Loot Level 50'), +(2648, 1, 1000150, 0, 5, 'Vilebranch Aman\'zasi Guard - World Loot Level 50'), +(2648, 2, 1000151, 0, 5, 'Vilebranch Aman\'zasi Guard - World Loot Level 51'), +(2649, 1, 1000140, 0, 5, 'Witherbark Scalper - World Loot Level 40'), +(2649, 2, 1000141, 0, 5, 'Witherbark Scalper - World Loot Level 41'), +(2650, 1, 1000141, 0, 5, 'Witherbark Zealot - World Loot Level 41'), +(2650, 2, 1000142, 0, 5, 'Witherbark Zealot - World Loot Level 42'), +(2651, 1, 1000142, 0, 5, 'Witherbark Hideskinner - World Loot Level 42'), +(2651, 2, 1000143, 0, 5, 'Witherbark Hideskinner - World Loot Level 43'), +(2652, 1, 1000143, 0, 5, 'Witherbark Venomblood - World Loot Level 43'), +(2653, 1, 1000144, 0, 5, 'Witherbark Sadist - World Loot Level 44'), +(2653, 2, 1000145, 0, 5, 'Witherbark Sadist - World Loot Level 45'), +(2654, 1, 1000145, 0, 5, 'Witherbark Caller - World Loot Level 45'), +(2654, 2, 1000146, 0, 5, 'Witherbark Caller - World Loot Level 46'), +(2655, 1, 1000046, 0, 5, 'Green Sludge - World Loot Level 46'), +(2655, 2, 1000047, 0, 5, 'Green Sludge - World Loot Level 47'), +(2656, 1, 1000047, 0, 5, 'Jade Ooze - World Loot Level 47'), +(2656, 2, 1000048, 0, 5, 'Jade Ooze - World Loot Level 48'), +(2691, 1, 1000143, 0, 5, 'Highvale Outrunner - World Loot Level 43'), +(2691, 2, 1000144, 0, 5, 'Highvale Outrunner - World Loot Level 44'), +(2692, 1, 1000144, 0, 5, 'Highvale Scout - World Loot Level 44'), +(2692, 2, 1000145, 0, 5, 'Highvale Scout - World Loot Level 45'), +(2693, 1, 1000145, 0, 5, 'Highvale Marksman - World Loot Level 45'), +(2693, 2, 1000146, 0, 5, 'Highvale Marksman - World Loot Level 46'), +(2694, 1, 1000146, 0, 5, 'Highvale Ranger - World Loot Level 46'), +(2694, 2, 1000147, 0, 5, 'Highvale Ranger - World Loot Level 47'), +(2701, 1, 1000138, 0, 5, 'Dustbelcher Ogre - World Loot Level 38'), +(2701, 2, 1000139, 0, 5, 'Dustbelcher Ogre - World Loot Level 39'), +(2714, 1, 1000135, 0, 5, 'Forsaken Courier - World Loot Level 35'), +(2715, 1, 1000139, 0, 5, 'Dustbelcher Brute - World Loot Level 39'), +(2715, 2, 1000140, 0, 5, 'Dustbelcher Brute - World Loot Level 40'), +(2716, 1, 1000140, 0, 5, 'Dustbelcher Wyrmhunter - World Loot Level 40'), +(2716, 2, 1000141, 0, 5, 'Dustbelcher Wyrmhunter - World Loot Level 41'), +(2717, 1, 1000141, 0, 5, 'Dustbelcher Mauler - World Loot Level 41'), +(2717, 2, 1000142, 0, 5, 'Dustbelcher Mauler - World Loot Level 42'), +(2718, 1, 1000142, 0, 5, 'Dustbelcher Shaman - World Loot Level 42'), +(2718, 2, 1000143, 0, 5, 'Dustbelcher Shaman - World Loot Level 43'), +(2719, 1, 1000144, 0, 5, 'Dustbelcher Lord - World Loot Level 44'), +(2719, 2, 1000145, 0, 5, 'Dustbelcher Lord - World Loot Level 45'), +(2720, 1, 1000143, 0, 5, 'Dustbelcher Ogre Mage - World Loot Level 43'), +(2720, 2, 1000144, 0, 5, 'Dustbelcher Ogre Mage - World Loot Level 44'), +(2723, 1, 1000038, 0, 5, 'Stone Golem - World Loot Level 38'), +(2723, 2, 1000039, 0, 5, 'Stone Golem - World Loot Level 39'), +(2727, 1, 1000035, 0, 5, 'Crag Coyote - World Loot Level 35'), +(2727, 2, 1000036, 0, 5, 'Crag Coyote - World Loot Level 36'), +(2733, 1, 1000136, 0, 5, 'Apothecary Jorell - World Loot Level 36'), +(2738, 1, 1000136, 0, 5, 'Stromgarde Cavalryman - World Loot Level 36'), +(2738, 2, 1000137, 0, 5, 'Stromgarde Cavalryman - World Loot Level 37'), +(2739, 1, 1000135, 0, 5, 'Shadowforge Tunneler - World Loot Level 35'), +(2739, 2, 1000136, 0, 5, 'Shadowforge Tunneler - World Loot Level 36'), +(2740, 1, 1000136, 0, 5, 'Shadowforge Darkweaver - World Loot Level 36'), +(2740, 2, 1000137, 0, 5, 'Shadowforge Darkweaver - World Loot Level 37'), +(2742, 1, 1000138, 0, 5, 'Shadowforge Chanter - World Loot Level 38'), +(2742, 2, 1000139, 0, 5, 'Shadowforge Chanter - World Loot Level 39'), +(2743, 1, 1000138, 0, 5, 'Shadowforge Warrior - World Loot Level 38'), +(2743, 2, 1000139, 0, 5, 'Shadowforge Warrior - World Loot Level 39'), +(2764, 1, 1000140, 0, 5, 'Sleeby - World Loot Level 40'), +(2765, 1, 1000139, 0, 5, 'Znort - World Loot Level 39'), +(2773, 1, 1000140, 0, 5, 'Or\'Kalar - World Loot Level 40'), +(2780, 1, 1000141, 0, 5, 'Caretaker Nevlin - World Loot Level 41'), +(2781, 1, 1000141, 0, 5, 'Caretaker Weston - World Loot Level 41'), +(2782, 1, 1000141, 0, 5, 'Caretaker Alaric - World Loot Level 41'), +(2783, 1, 1000140, 0, 5, 'Marez Cowl - World Loot Level 40'), +(2793, 1, 1000139, 0, 5, 'Kor\'gresh Coldrage - World Loot Level 39'), +(2892, 1, 1000137, 0, 5, 'Stonevault Seer - World Loot Level 37'), +(2892, 2, 1000138, 0, 5, 'Stonevault Seer - World Loot Level 38'), +(2893, 1, 1000139, 0, 5, 'Stonevault Bonesnapper - World Loot Level 39'), +(2893, 2, 1000140, 0, 5, 'Stonevault Bonesnapper - World Loot Level 40'), +(2894, 1, 1000140, 0, 5, 'Stonevault Shaman - World Loot Level 40'), +(2894, 2, 1000141, 0, 5, 'Stonevault Shaman - World Loot Level 41'), +(2906, 1, 1000135, 0, 5, 'Dustbelcher Warrior - World Loot Level 35'), +(2906, 2, 1000136, 0, 5, 'Dustbelcher Warrior - World Loot Level 36'), +(2906, 3, 1000137, 0, 5, 'Dustbelcher Warrior - World Loot Level 37'), +(2907, 1, 1000137, 0, 5, 'Dustbelcher Mystic - World Loot Level 37'), +(2932, 1, 1000137, 0, 5, 'Magregan Deepshadow - World Loot Level 37'), +(2944, 1, 1000141, 0, 5, 'Boss Tho\'grun - World Loot Level 41'), +(2944, 2, 1000142, 0, 5, 'Boss Tho\'grun - World Loot Level 42'), +(2945, 1, 1000142, 0, 5, 'Murdaloc - World Loot Level 42'), +(2949, 1, 1000105, 0, 5, 'Palemane Tanner - World Loot Level 5'), +(2949, 2, 1000106, 0, 5, 'Palemane Tanner - World Loot Level 6'), +(2950, 1, 1000106, 0, 5, 'Palemane Skinner - World Loot Level 6'), +(2950, 2, 1000107, 0, 5, 'Palemane Skinner - World Loot Level 7'), +(2951, 1, 1000107, 0, 5, 'Palemane Poacher - World Loot Level 7'), +(2951, 2, 1000108, 0, 5, 'Palemane Poacher - World Loot Level 8'), +(2959, 1, 1000007, 0, 5, 'Prairie Stalker - World Loot Level 7'), +(2959, 2, 1000008, 0, 5, 'Prairie Stalker - World Loot Level 8'), +(2960, 1, 1000009, 0, 5, 'Prairie Wolf Alpha - World Loot Level 9'), +(2960, 2, 1000010, 0, 5, 'Prairie Wolf Alpha - World Loot Level 10'), +(2962, 1, 1000107, 0, 5, 'Windfury Harpy - World Loot Level 7'), +(2962, 2, 1000108, 0, 5, 'Windfury Harpy - World Loot Level 8'), +(2963, 1, 1000108, 0, 5, 'Windfury Wind Witch - World Loot Level 8'), +(2963, 2, 1000109, 0, 5, 'Windfury Wind Witch - World Loot Level 9'), +(2964, 1, 1000109, 0, 5, 'Windfury Sorceress - World Loot Level 9'), +(2964, 2, 1000110, 0, 5, 'Windfury Sorceress - World Loot Level 10'), +(2965, 1, 1000110, 0, 5, 'Windfury Matriarch - World Loot Level 10'), +(2965, 2, 1000111, 0, 5, 'Windfury Matriarch - World Loot Level 11'), +(2967, 1, 1000108, 0, 5, 'Galak Centaur - World Loot Level 8'), +(2967, 2, 1000109, 0, 5, 'Galak Centaur - World Loot Level 9'), +(2968, 1, 1000109, 0, 5, 'Galak Outrunner - World Loot Level 9'), +(2968, 2, 1000110, 0, 5, 'Galak Outrunner - World Loot Level 10'), +(2975, 1, 1000105, 0, 5, 'Venture Co. Hireling - World Loot Level 5'), +(2975, 2, 1000106, 0, 5, 'Venture Co. Hireling - World Loot Level 6'), +(2976, 1, 1000106, 0, 5, 'Venture Co. Laborer - World Loot Level 6'), +(2976, 2, 1000107, 0, 5, 'Venture Co. Laborer - World Loot Level 7'), +(2977, 1, 1000107, 0, 5, 'Venture Co. Taskmaster - World Loot Level 7'), +(2977, 2, 1000108, 0, 5, 'Venture Co. Taskmaster - World Loot Level 8'), +(2978, 1, 1000108, 0, 5, 'Venture Co. Worker - World Loot Level 8'), +(2978, 2, 1000109, 0, 5, 'Venture Co. Worker - World Loot Level 9'), +(2979, 1, 1000109, 0, 5, 'Venture Co. Supervisor - World Loot Level 9'), +(2979, 2, 1000110, 0, 5, 'Venture Co. Supervisor - World Loot Level 10'), +(2989, 1, 1000107, 0, 5, 'Bael\'dun Digger - World Loot Level 7'), +(2989, 2, 1000108, 0, 5, 'Bael\'dun Digger - World Loot Level 8'), +(2990, 1, 1000108, 0, 5, 'Bael\'dun Appraiser - World Loot Level 8'), +(2990, 2, 1000109, 0, 5, 'Bael\'dun Appraiser - World Loot Level 9'), +(3051, 1, 1000112, 0, 5, 'Supervisor Fizsprocket - World Loot Level 12'), +(3094, 1, 1000149, 0, 5, 'Unseen - World Loot Level 49'), +(3094, 2, 1000150, 0, 5, 'Unseen - World Loot Level 50'), +(3094, 3, 1000151, 0, 5, 'Unseen - World Loot Level 51'), +(3103, 1, 1000106, 0, 5, 'Makrura Clacker - World Loot Level 6'), +(3103, 2, 1000107, 0, 5, 'Makrura Clacker - World Loot Level 7'), +(3104, 1, 1000106, 0, 5, 'Makrura Shellhide - World Loot Level 6'), +(3104, 2, 1000107, 0, 5, 'Makrura Shellhide - World Loot Level 7'), +(3106, 1, 1000105, 0, 5, 'Pygmy Surf Crawler - World Loot Level 5'), +(3106, 2, 1000106, 0, 5, 'Pygmy Surf Crawler - World Loot Level 6'), +(3111, 1, 1000106, 0, 5, 'Razormane Quilboar - World Loot Level 6'), +(3111, 2, 1000107, 0, 5, 'Razormane Quilboar - World Loot Level 7'), +(3112, 1, 1000107, 0, 5, 'Razormane Scout - World Loot Level 7'), +(3112, 2, 1000108, 0, 5, 'Razormane Scout - World Loot Level 8'), +(3113, 1, 1000108, 0, 5, 'Razormane Dustrunner - World Loot Level 8'), +(3113, 2, 1000109, 0, 5, 'Razormane Dustrunner - World Loot Level 9'), +(3114, 1, 1000109, 0, 5, 'Razormane Battleguard - World Loot Level 9'), +(3114, 2, 1000110, 0, 5, 'Razormane Battleguard - World Loot Level 10'), +(3115, 1, 1000107, 0, 5, 'Dustwind Harpy - World Loot Level 7'), +(3115, 2, 1000108, 0, 5, 'Dustwind Harpy - World Loot Level 8'), +(3116, 1, 1000107, 0, 5, 'Dustwind Pillager - World Loot Level 7'), +(3116, 2, 1000108, 0, 5, 'Dustwind Pillager - World Loot Level 8'), +(3117, 1, 1000109, 0, 5, 'Dustwind Savage - World Loot Level 9'), +(3117, 2, 1000110, 0, 5, 'Dustwind Savage - World Loot Level 10'), +(3118, 1, 1000110, 0, 5, 'Dustwind Storm Witch - World Loot Level 10'), +(3118, 2, 1000111, 0, 5, 'Dustwind Storm Witch - World Loot Level 11'), +(3119, 1, 1000106, 0, 5, 'Kolkar Drudge - World Loot Level 6'), +(3119, 2, 1000107, 0, 5, 'Kolkar Drudge - World Loot Level 7'), +(3120, 1, 1000107, 0, 5, 'Kolkar Outrunner - World Loot Level 7'), +(3120, 2, 1000108, 0, 5, 'Kolkar Outrunner - World Loot Level 8'), +(3121, 1, 1000007, 0, 5, 'Durotar Tiger - World Loot Level 7'), +(3121, 2, 1000008, 0, 5, 'Durotar Tiger - World Loot Level 8'), +(3122, 1, 1000006, 0, 5, 'Bloodtalon Taillasher - World Loot Level 6'), +(3122, 2, 1000007, 0, 5, 'Bloodtalon Taillasher - World Loot Level 7'), +(3122, 3, 1000008, 0, 5, 'Bloodtalon Taillasher - World Loot Level 8'), +(3128, 1, 1000105, 0, 5, 'Kul Tiras Sailor - World Loot Level 5'), +(3128, 2, 1000106, 0, 5, 'Kul Tiras Sailor - World Loot Level 6'), +(3129, 1, 1000106, 0, 5, 'Kul Tiras Marine - World Loot Level 6'), +(3129, 2, 1000107, 0, 5, 'Kul Tiras Marine - World Loot Level 7'), +(3130, 1, 1000009, 0, 5, 'Thunder Lizard - World Loot Level 9'), +(3130, 2, 1000010, 0, 5, 'Thunder Lizard - World Loot Level 10'), +(3131, 1, 1000010, 0, 5, 'Lightning Hide - World Loot Level 10'), +(3131, 2, 1000011, 0, 5, 'Lightning Hide - World Loot Level 11'), +(3192, 1, 1000108, 0, 5, 'Lieutenant Benedict - World Loot Level 8'), +(3195, 1, 1000108, 0, 5, 'Burning Blade Thug - World Loot Level 8'), +(3195, 2, 1000109, 0, 5, 'Burning Blade Thug - World Loot Level 9'), +(3196, 1, 1000109, 0, 5, 'Burning Blade Neophyte - World Loot Level 9'), +(3196, 2, 1000110, 0, 5, 'Burning Blade Neophyte - World Loot Level 10'), +(3197, 1, 1000109, 0, 5, 'Burning Blade Fanatic - World Loot Level 9'), +(3197, 2, 1000110, 0, 5, 'Burning Blade Fanatic - World Loot Level 10'), +(3198, 1, 1000110, 0, 5, 'Burning Blade Apprentice - World Loot Level 10'), +(3198, 2, 1000111, 0, 5, 'Burning Blade Apprentice - World Loot Level 11'), +(3199, 1, 1000110, 0, 5, 'Burning Blade Cultist - World Loot Level 10'), +(3199, 2, 1000111, 0, 5, 'Burning Blade Cultist - World Loot Level 11'), +(3203, 1, 1000112, 0, 5, 'Fizzle Darkstorm - World Loot Level 12'), +(3204, 1, 1000110, 0, 5, 'Gazz\'uz - World Loot Level 10'), +(3205, 1, 1000110, 0, 5, 'Zalazane - World Loot Level 10'), +(3206, 1, 1000108, 0, 5, 'Voodoo Troll - World Loot Level 8'), +(3206, 2, 1000109, 0, 5, 'Voodoo Troll - World Loot Level 9'), +(3207, 1, 1000108, 0, 5, 'Hexed Troll - World Loot Level 8'), +(3207, 2, 1000109, 0, 5, 'Hexed Troll - World Loot Level 9'), +(3232, 1, 1000109, 0, 5, 'Bristleback Interloper - World Loot Level 9'), +(3232, 2, 1000110, 0, 5, 'Bristleback Interloper - World Loot Level 10'), +(3258, 1, 1000117, 0, 5, 'Bristleback Hunter - World Loot Level 17'), +(3258, 2, 1000118, 0, 5, 'Bristleback Hunter - World Loot Level 18'), +(3260, 1, 1000116, 0, 5, 'Bristleback Water Seeker - World Loot Level 16'), +(3260, 2, 1000117, 0, 5, 'Bristleback Water Seeker - World Loot Level 17'), +(3261, 1, 1000118, 0, 5, 'Bristleback Thornweaver - World Loot Level 18'), +(3261, 2, 1000119, 0, 5, 'Bristleback Thornweaver - World Loot Level 19'), +(3263, 1, 1000119, 0, 5, 'Bristleback Geomancer - World Loot Level 19'), +(3263, 2, 1000120, 0, 5, 'Bristleback Geomancer - World Loot Level 20'), +(3265, 1, 1000111, 0, 5, 'Razormane Hunter - World Loot Level 11'), +(3265, 2, 1000112, 0, 5, 'Razormane Hunter - World Loot Level 12'), +(3266, 1, 1000112, 0, 5, 'Razormane Defender - World Loot Level 12'), +(3266, 2, 1000113, 0, 5, 'Razormane Defender - World Loot Level 13'), +(3267, 1, 1000110, 0, 5, 'Razormane Water Seeker - World Loot Level 10'), +(3267, 2, 1000111, 0, 5, 'Razormane Water Seeker - World Loot Level 11'), +(3268, 1, 1000110, 0, 5, 'Razormane Thornweaver - World Loot Level 10'), +(3268, 2, 1000111, 0, 5, 'Razormane Thornweaver - World Loot Level 11'), +(3269, 1, 1000112, 0, 5, 'Razormane Geomancer - World Loot Level 12'), +(3269, 2, 1000113, 0, 5, 'Razormane Geomancer - World Loot Level 13'), +(3271, 1, 1000113, 0, 5, 'Razormane Mystic - World Loot Level 13'), +(3271, 2, 1000114, 0, 5, 'Razormane Mystic - World Loot Level 14'), +(3272, 1, 1000112, 0, 5, 'Kolkar Wrangler - World Loot Level 12'), +(3272, 2, 1000113, 0, 5, 'Kolkar Wrangler - World Loot Level 13'), +(3273, 1, 1000113, 0, 5, 'Kolkar Stormer - World Loot Level 13'), +(3273, 2, 1000114, 0, 5, 'Kolkar Stormer - World Loot Level 14'), +(3274, 1, 1000114, 0, 5, 'Kolkar Pack Runner - World Loot Level 14'), +(3274, 2, 1000115, 0, 5, 'Kolkar Pack Runner - World Loot Level 15'), +(3275, 1, 1000115, 0, 5, 'Kolkar Marauder - World Loot Level 15'), +(3275, 2, 1000116, 0, 5, 'Kolkar Marauder - World Loot Level 16'), +(3276, 1, 1000114, 0, 5, 'Witchwing Harpy - World Loot Level 14'), +(3276, 2, 1000115, 0, 5, 'Witchwing Harpy - World Loot Level 15'), +(3277, 1, 1000115, 0, 5, 'Witchwing Roguefeather - World Loot Level 15'), +(3277, 2, 1000116, 0, 5, 'Witchwing Roguefeather - World Loot Level 16'), +(3278, 1, 1000116, 0, 5, 'Witchwing Slayer - World Loot Level 16'), +(3278, 2, 1000117, 0, 5, 'Witchwing Slayer - World Loot Level 17'), +(3279, 1, 1000117, 0, 5, 'Witchwing Ambusher - World Loot Level 17'), +(3279, 2, 1000118, 0, 5, 'Witchwing Ambusher - World Loot Level 18'), +(3280, 1, 1000117, 0, 5, 'Witchwing Windcaller - World Loot Level 17'), +(3280, 2, 1000118, 0, 5, 'Witchwing Windcaller - World Loot Level 18'), +(3282, 1, 1000115, 0, 5, 'Venture Co. Mercenary - World Loot Level 15'), +(3282, 2, 1000116, 0, 5, 'Venture Co. Mercenary - World Loot Level 16'), +(3283, 1, 1000116, 0, 5, 'Venture Co. Enforcer - World Loot Level 16'), +(3283, 2, 1000117, 0, 5, 'Venture Co. Enforcer - World Loot Level 17'), +(3284, 1, 1000114, 0, 5, 'Venture Co. Drudger - World Loot Level 14'), +(3284, 2, 1000115, 0, 5, 'Venture Co. Drudger - World Loot Level 15'), +(3285, 1, 1000113, 0, 5, 'Venture Co. Peon - World Loot Level 13'), +(3285, 2, 1000114, 0, 5, 'Venture Co. Peon - World Loot Level 14'), +(3286, 1, 1000117, 0, 5, 'Venture Co. Overseer - World Loot Level 17'), +(3286, 2, 1000118, 0, 5, 'Venture Co. Overseer - World Loot Level 18'), +(3374, 1, 1000121, 0, 5, 'Bael\'dun Excavator - World Loot Level 21'), +(3374, 2, 1000122, 0, 5, 'Bael\'dun Excavator - World Loot Level 22'), +(3375, 1, 1000122, 0, 5, 'Bael\'dun Foreman - World Loot Level 22'), +(3375, 2, 1000123, 0, 5, 'Bael\'dun Foreman - World Loot Level 23'), +(3376, 1, 1000123, 0, 5, 'Bael\'dun Soldier - World Loot Level 23'), +(3376, 2, 1000124, 0, 5, 'Bael\'dun Soldier - World Loot Level 24'), +(3377, 1, 1000124, 0, 5, 'Bael\'dun Rifleman - World Loot Level 24'), +(3377, 2, 1000125, 0, 5, 'Bael\'dun Rifleman - World Loot Level 25'), +(3378, 1, 1000126, 0, 5, 'Bael\'dun Officer - World Loot Level 26'), +(3379, 1, 1000110, 0, 5, 'Burning Blade Bruiser - World Loot Level 10'), +(3379, 2, 1000111, 0, 5, 'Burning Blade Bruiser - World Loot Level 11'), +(3380, 1, 1000111, 0, 5, 'Burning Blade Acolyte - World Loot Level 11'), +(3380, 2, 1000112, 0, 5, 'Burning Blade Acolyte - World Loot Level 12'), +(3381, 1, 1000112, 0, 5, 'Southsea Brigand - World Loot Level 12'), +(3381, 2, 1000113, 0, 5, 'Southsea Brigand - World Loot Level 13'), +(3382, 1, 1000113, 0, 5, 'Southsea Cannoneer - World Loot Level 13'), +(3382, 2, 1000114, 0, 5, 'Southsea Cannoneer - World Loot Level 14'), +(3383, 1, 1000114, 0, 5, 'Southsea Cutthroat - World Loot Level 14'), +(3383, 2, 1000115, 0, 5, 'Southsea Cutthroat - World Loot Level 15'), +(3384, 1, 1000114, 0, 5, 'Southsea Privateer - World Loot Level 14'), +(3384, 2, 1000115, 0, 5, 'Southsea Privateer - World Loot Level 15'), +(3385, 1, 1000115, 0, 5, 'Theramore Marine - World Loot Level 15'), +(3385, 2, 1000116, 0, 5, 'Theramore Marine - World Loot Level 16'), +(3386, 1, 1000116, 0, 5, 'Theramore Preserver - World Loot Level 16'), +(3386, 2, 1000117, 0, 5, 'Theramore Preserver - World Loot Level 17'), +(3392, 1, 1000124, 0, 5, 'Prospector Khazgorm - World Loot Level 24'), +(3393, 1, 1000120, 0, 5, 'Captain Fairmount - World Loot Level 20'), +(3394, 1, 1000116, 0, 5, 'Barak Kodobane - World Loot Level 16'), +(3396, 1, 1000119, 0, 5, 'Hezrul Bloodmark - World Loot Level 19'), +(3397, 1, 1000114, 0, 5, 'Kolkar Bloodcharger - World Loot Level 14'), +(3397, 2, 1000115, 0, 5, 'Kolkar Bloodcharger - World Loot Level 15'), +(3414, 1, 1000130, 0, 5, 'General Twinbraid - World Loot Level 30'), +(3434, 1, 1000123, 0, 5, 'Nak - World Loot Level 23'), +(3435, 1, 1000125, 0, 5, 'Lok Orcbane - World Loot Level 25'), +(3436, 1, 1000121, 0, 5, 'Kuz - World Loot Level 21'), +(3438, 1, 1000115, 0, 5, 'Kreenig Snarlsnout - World Loot Level 15'), +(3445, 1, 1000118, 0, 5, 'Supervisor Lugwizzle - World Loot Level 18'), +(3452, 1, 1000120, 0, 5, 'Serena Bloodfeather - World Loot Level 20'), +(3454, 1, 1000119, 0, 5, 'Cannoneer Smythe - World Loot Level 19'), +(3455, 1, 1000119, 0, 5, 'Cannoneer Whessan - World Loot Level 19'), +(3456, 1, 1000120, 0, 5, 'Razormane Pathfinder - World Loot Level 20'), +(3456, 2, 1000121, 0, 5, 'Razormane Pathfinder - World Loot Level 21'), +(3457, 1, 1000122, 0, 5, 'Razormane Stalker - World Loot Level 22'), +(3457, 2, 1000123, 0, 5, 'Razormane Stalker - World Loot Level 23'), +(3458, 1, 1000123, 0, 5, 'Razormane Seer - World Loot Level 23'), +(3458, 2, 1000124, 0, 5, 'Razormane Seer - World Loot Level 24'), +(3459, 1, 1000124, 0, 5, 'Razormane Warfrenzy - World Loot Level 24'), +(3459, 2, 1000125, 0, 5, 'Razormane Warfrenzy - World Loot Level 25'), +(3465, 1, 1000117, 0, 5, 'Gilthares Firebough - World Loot Level 17'), +(3467, 1, 1000116, 0, 5, 'Baron Longshore - World Loot Level 16'), +(3471, 1, 1000116, 0, 5, 'Tinkerer Sniggles - World Loot Level 16'), +(3528, 1, 1000114, 0, 5, 'Pyrewood Armorer - World Loot Level 14'), +(3528, 2, 1000115, 0, 5, 'Pyrewood Armorer - World Loot Level 15'), +(3530, 1, 1000114, 0, 5, 'Pyrewood Tailor - World Loot Level 14'), +(3530, 2, 1000115, 0, 5, 'Pyrewood Tailor - World Loot Level 15'), +(3532, 1, 1000114, 0, 5, 'Pyrewood Leatherworker - World Loot Level 14'), +(3532, 2, 1000115, 0, 5, 'Pyrewood Leatherworker - World Loot Level 15'), +(3566, 1, 1000009, 0, 5, 'Flatland Prowler - World Loot Level 9'), +(3577, 1, 1000115, 0, 5, 'Dalaran Brewmaster - World Loot Level 15'), +(3577, 2, 1000116, 0, 5, 'Dalaran Brewmaster - World Loot Level 16'), +(3578, 1, 1000115, 0, 5, 'Dalaran Miner - World Loot Level 15'), +(3578, 2, 1000116, 0, 5, 'Dalaran Miner - World Loot Level 16'), +(3655, 1, 1000117, 0, 5, 'Mad Magglish - World Loot Level 17'), +(3660, 1, 1000131, 0, 5, 'Athrikus Narassin - World Loot Level 31'), +(3662, 1, 1000117, 0, 5, 'Delmanis the Hated - World Loot Level 17'), +(3664, 1, 1000124, 0, 5, 'Ilkrud Magthrull - World Loot Level 24'), +(3667, 1, 1000116, 0, 5, 'Anaya Dawnrunner - World Loot Level 16'), +(3696, 1, 1000130, 0, 5, 'Ran Bloodtooth - World Loot Level 30'), +(3712, 1, 1000119, 0, 5, 'Wrathtail Razortail - World Loot Level 19'), +(3712, 2, 1000120, 0, 5, 'Wrathtail Razortail - World Loot Level 20'), +(3713, 1, 1000118, 0, 5, 'Wrathtail Wave Rider - World Loot Level 18'), +(3713, 2, 1000119, 0, 5, 'Wrathtail Wave Rider - World Loot Level 19'), +(3715, 1, 1000119, 0, 5, 'Wrathtail Sea Witch - World Loot Level 19'), +(3715, 2, 1000120, 0, 5, 'Wrathtail Sea Witch - World Loot Level 20'), +(3725, 1, 1000118, 0, 5, 'Dark Strand Cultist - World Loot Level 18'), +(3725, 2, 1000119, 0, 5, 'Dark Strand Cultist - World Loot Level 19'), +(3727, 1, 1000120, 0, 5, 'Dark Strand Enforcer - World Loot Level 20'), +(3727, 2, 1000121, 0, 5, 'Dark Strand Enforcer - World Loot Level 21'), +(3728, 1, 1000118, 0, 5, 'Dark Strand Adept - World Loot Level 18'), +(3728, 2, 1000119, 0, 5, 'Dark Strand Adept - World Loot Level 19'), +(3730, 1, 1000119, 0, 5, 'Dark Strand Excavator - World Loot Level 19'), +(3730, 2, 1000120, 0, 5, 'Dark Strand Excavator - World Loot Level 20'), +(3732, 1, 1000118, 0, 5, 'Forsaken Seeker - World Loot Level 18'), +(3732, 2, 1000119, 0, 5, 'Forsaken Seeker - World Loot Level 19'), +(3733, 1, 1000118, 0, 5, 'Forsaken Herbalist - World Loot Level 18'), +(3733, 2, 1000119, 0, 5, 'Forsaken Herbalist - World Loot Level 19'), +(3734, 1, 1000120, 0, 5, 'Forsaken Thug - World Loot Level 20'), +(3736, 1, 1000123, 0, 5, 'Darkslayer Mordenthal - World Loot Level 23'), +(3743, 1, 1000123, 0, 5, 'Foulweald Warrior - World Loot Level 23'), +(3743, 2, 1000124, 0, 5, 'Foulweald Warrior - World Loot Level 24'), +(3745, 1, 1000123, 0, 5, 'Foulweald Pathfinder - World Loot Level 23'), +(3745, 2, 1000124, 0, 5, 'Foulweald Pathfinder - World Loot Level 24'), +(3746, 1, 1000124, 0, 5, 'Foulweald Den Watcher - World Loot Level 24'), +(3746, 2, 1000125, 0, 5, 'Foulweald Den Watcher - World Loot Level 25'), +(3748, 1, 1000124, 0, 5, 'Foulweald Shaman - World Loot Level 24'), +(3748, 2, 1000125, 0, 5, 'Foulweald Shaman - World Loot Level 25'), +(3749, 1, 1000124, 0, 5, 'Foulweald Ursa - World Loot Level 24'), +(3749, 2, 1000125, 0, 5, 'Foulweald Ursa - World Loot Level 25'), +(3750, 1, 1000123, 0, 5, 'Foulweald Totemic - World Loot Level 23'), +(3750, 2, 1000124, 0, 5, 'Foulweald Totemic - World Loot Level 24'), +(3752, 1, 1000129, 0, 5, 'Xavian Rogue - World Loot Level 29'), +(3752, 2, 1000130, 0, 5, 'Xavian Rogue - World Loot Level 30'), +(3754, 1, 1000128, 0, 5, 'Xavian Betrayer - World Loot Level 28'), +(3754, 2, 1000129, 0, 5, 'Xavian Betrayer - World Loot Level 29'), +(3755, 1, 1000128, 0, 5, 'Xavian Felsworn - World Loot Level 28'), +(3755, 2, 1000129, 0, 5, 'Xavian Felsworn - World Loot Level 29'), +(3757, 1, 1000129, 0, 5, 'Xavian Hellcaller - World Loot Level 29'), +(3757, 2, 1000130, 0, 5, 'Xavian Hellcaller - World Loot Level 30'), +(3758, 1, 1000125, 0, 5, 'Felmusk Satyr - World Loot Level 25'), +(3758, 2, 1000126, 0, 5, 'Felmusk Satyr - World Loot Level 26'), +(3759, 1, 1000126, 0, 5, 'Felmusk Rogue - World Loot Level 26'), +(3759, 2, 1000127, 0, 5, 'Felmusk Rogue - World Loot Level 27'), +(3762, 1, 1000126, 0, 5, 'Felmusk Felsworn - World Loot Level 26'), +(3763, 1, 1000126, 0, 5, 'Felmusk Shadowstalker - World Loot Level 26'), +(3763, 2, 1000127, 0, 5, 'Felmusk Shadowstalker - World Loot Level 27'), +(3765, 1, 1000126, 0, 5, 'Bleakheart Satyr - World Loot Level 26'), +(3765, 2, 1000127, 0, 5, 'Bleakheart Satyr - World Loot Level 27'), +(3767, 1, 1000127, 0, 5, 'Bleakheart Trickster - World Loot Level 27'), +(3767, 2, 1000128, 0, 5, 'Bleakheart Trickster - World Loot Level 28'), +(3770, 1, 1000127, 0, 5, 'Bleakheart Shadowstalker - World Loot Level 27'), +(3770, 2, 1000128, 0, 5, 'Bleakheart Shadowstalker - World Loot Level 28'), +(3771, 1, 1000126, 0, 5, 'Bleakheart Hellcaller - World Loot Level 26'), +(3771, 2, 1000127, 0, 5, 'Bleakheart Hellcaller - World Loot Level 27'), +(3772, 1, 1000123, 0, 5, 'Lesser Felguard - World Loot Level 23'), +(3772, 2, 1000124, 0, 5, 'Lesser Felguard - World Loot Level 24'), +(3774, 1, 1000122, 0, 5, 'Felslayer - World Loot Level 22'), +(3774, 2, 1000123, 0, 5, 'Felslayer - World Loot Level 23'), +(3797, 1, 1000125, 0, 5, 'Cenarion Protector - World Loot Level 25'), +(3797, 2, 1000126, 0, 5, 'Cenarion Protector - World Loot Level 26'), +(3801, 1, 1000128, 0, 5, 'Severed Sleeper - World Loot Level 28'), +(3801, 2, 1000129, 0, 5, 'Severed Sleeper - World Loot Level 29'), +(3802, 1, 1000129, 0, 5, 'Severed Dreamer - World Loot Level 29'), +(3802, 2, 1000130, 0, 5, 'Severed Dreamer - World Loot Level 30'), +(3803, 1, 1000129, 0, 5, 'Severed Keeper - World Loot Level 29'), +(3803, 2, 1000130, 0, 5, 'Severed Keeper - World Loot Level 30'), +(3804, 1, 1000128, 0, 5, 'Forsaken Intruder - World Loot Level 28'), +(3804, 2, 1000129, 0, 5, 'Forsaken Intruder - World Loot Level 29'), +(3806, 1, 1000129, 0, 5, 'Forsaken Infiltrator - World Loot Level 29'), +(3806, 2, 1000130, 0, 5, 'Forsaken Infiltrator - World Loot Level 30'), +(3807, 1, 1000129, 0, 5, 'Forsaken Assassin - World Loot Level 29'), +(3807, 2, 1000130, 0, 5, 'Forsaken Assassin - World Loot Level 30'), +(3808, 1, 1000128, 0, 5, 'Forsaken Dark Stalker - World Loot Level 28'), +(3808, 2, 1000129, 0, 5, 'Forsaken Dark Stalker - World Loot Level 29'), +(3819, 1, 1000020, 0, 5, 'Wildthorn Stalker - World Loot Level 20'), +(3819, 2, 1000021, 0, 5, 'Wildthorn Stalker - World Loot Level 21'), +(3823, 1, 1000019, 0, 5, 'Ghostpaw Runner - World Loot Level 19'), +(3823, 2, 1000020, 0, 5, 'Ghostpaw Runner - World Loot Level 20'), +(3833, 1, 1000126, 0, 5, 'Cenarion Vindicator - World Loot Level 26'), +(3833, 2, 1000127, 0, 5, 'Cenarion Vindicator - World Loot Level 27'), +(3917, 1, 1000023, 0, 5, 'Befouled Water Elemental - World Loot Level 23'), +(3917, 2, 1000024, 0, 5, 'Befouled Water Elemental - World Loot Level 24'), +(3917, 3, 1000025, 0, 5, 'Befouled Water Elemental - World Loot Level 25'), +(3921, 1, 1000123, 0, 5, 'Thistlefur Ursa - World Loot Level 23'), +(3921, 2, 1000124, 0, 5, 'Thistlefur Ursa - World Loot Level 24'), +(3922, 1, 1000123, 0, 5, 'Thistlefur Totemic - World Loot Level 23'), +(3922, 2, 1000124, 0, 5, 'Thistlefur Totemic - World Loot Level 24'), +(3923, 1, 1000123, 0, 5, 'Thistlefur Den Watcher - World Loot Level 23'), +(3923, 2, 1000124, 0, 5, 'Thistlefur Den Watcher - World Loot Level 24'), +(3924, 1, 1000123, 0, 5, 'Thistlefur Shaman - World Loot Level 23'), +(3924, 2, 1000124, 0, 5, 'Thistlefur Shaman - World Loot Level 24'), +(3925, 1, 1000123, 0, 5, 'Thistlefur Avenger - World Loot Level 23'), +(3925, 2, 1000124, 0, 5, 'Thistlefur Avenger - World Loot Level 24'), +(3926, 1, 1000123, 0, 5, 'Thistlefur Pathfinder - World Loot Level 23'), +(3926, 2, 1000124, 0, 5, 'Thistlefur Pathfinder - World Loot Level 24'), +(3932, 1, 1000127, 0, 5, 'Bloodtooth Guard - World Loot Level 27'), +(3932, 2, 1000128, 0, 5, 'Bloodtooth Guard - World Loot Level 28'), +(3940, 1, 1000132, 0, 5, 'Taneel Darkwood - World Loot Level 32'), +(3941, 1, 1000132, 0, 5, 'Uthil Mooncall - World Loot Level 32'), +(3942, 1, 1000132, 0, 5, 'Mavoris Cloudsbreak - World Loot Level 32'), +(3986, 1, 1000125, 0, 5, 'Sarilus Foulborne - World Loot Level 25'), +(3987, 1, 1000125, 0, 5, 'Dal Bloodclaw - World Loot Level 25'), +(3988, 1, 1000119, 0, 5, 'Venture Co. Operator - World Loot Level 19'), +(3988, 2, 1000120, 0, 5, 'Venture Co. Operator - World Loot Level 20'), +(3989, 1, 1000118, 0, 5, 'Venture Co. Logger - World Loot Level 18'), +(3989, 2, 1000119, 0, 5, 'Venture Co. Logger - World Loot Level 19'), +(3991, 1, 1000119, 0, 5, 'Venture Co. Deforester - World Loot Level 19'), +(3991, 2, 1000120, 0, 5, 'Venture Co. Deforester - World Loot Level 20'), +(3992, 1, 1000120, 0, 5, 'Venture Co. Engineer - World Loot Level 20'), +(3992, 2, 1000121, 0, 5, 'Venture Co. Engineer - World Loot Level 21'), +(3993, 1, 1000121, 0, 5, 'Venture Co. Machine Smith - World Loot Level 21'), +(3993, 2, 1000122, 0, 5, 'Venture Co. Machine Smith - World Loot Level 22'), +(3999, 1, 1000121, 0, 5, 'Windshear Digger - World Loot Level 21'), +(3999, 2, 1000122, 0, 5, 'Windshear Digger - World Loot Level 22'), +(4003, 1, 1000120, 0, 5, 'Windshear Geomancer - World Loot Level 20'), +(4003, 2, 1000121, 0, 5, 'Windshear Geomancer - World Loot Level 21'), +(4004, 1, 1000121, 0, 5, 'Windshear Overlord - World Loot Level 21'), +(4004, 2, 1000122, 0, 5, 'Windshear Overlord - World Loot Level 22'), +(4013, 1, 1000023, 0, 5, 'Pridewing Skyhunter - World Loot Level 23'), +(4013, 2, 1000024, 0, 5, 'Pridewing Skyhunter - World Loot Level 24'), +(4022, 1, 1000123, 0, 5, 'Bloodfury Harpy - World Loot Level 23'), +(4022, 2, 1000124, 0, 5, 'Bloodfury Harpy - World Loot Level 24'), +(4023, 1, 1000125, 0, 5, 'Bloodfury Roguefeather - World Loot Level 25'), +(4023, 2, 1000126, 0, 5, 'Bloodfury Roguefeather - World Loot Level 26'), +(4024, 1, 1000125, 0, 5, 'Bloodfury Slayer - World Loot Level 25'), +(4024, 2, 1000126, 0, 5, 'Bloodfury Slayer - World Loot Level 26'), +(4025, 1, 1000123, 0, 5, 'Bloodfury Ambusher - World Loot Level 23'), +(4025, 2, 1000124, 0, 5, 'Bloodfury Ambusher - World Loot Level 24'), +(4026, 1, 1000124, 0, 5, 'Bloodfury Windcaller - World Loot Level 24'), +(4026, 2, 1000125, 0, 5, 'Bloodfury Windcaller - World Loot Level 25'), +(4027, 1, 1000126, 0, 5, 'Bloodfury Storm Witch - World Loot Level 26'), +(4027, 2, 1000127, 0, 5, 'Bloodfury Storm Witch - World Loot Level 27'), +(4040, 1, 1000021, 0, 5, 'Cave Stalker - World Loot Level 21'), +(4040, 2, 1000022, 0, 5, 'Cave Stalker - World Loot Level 22'), +(4042, 1, 1000025, 0, 5, 'Singed Basilisk - World Loot Level 25'), +(4042, 2, 1000026, 0, 5, 'Singed Basilisk - World Loot Level 26'), +(4050, 1, 1000125, 0, 5, 'Cenarion Caretaker - World Loot Level 25'), +(4050, 2, 1000126, 0, 5, 'Cenarion Caretaker - World Loot Level 26'), +(4051, 1, 1000123, 0, 5, 'Cenarion Botanist - World Loot Level 23'), +(4051, 2, 1000124, 0, 5, 'Cenarion Botanist - World Loot Level 24'), +(4052, 1, 1000126, 0, 5, 'Cenarion Druid - World Loot Level 26'), +(4052, 2, 1000127, 0, 5, 'Cenarion Druid - World Loot Level 27'), +(4053, 1, 1000123, 0, 5, 'Daughter of Cenarius - World Loot Level 23'), +(4053, 2, 1000124, 0, 5, 'Daughter of Cenarius - World Loot Level 24'), +(4053, 3, 1000125, 0, 5, 'Daughter of Cenarius - World Loot Level 25'), +(4054, 1, 1000124, 0, 5, 'Laughing Sister - World Loot Level 24'), +(4054, 2, 1000125, 0, 5, 'Laughing Sister - World Loot Level 25'), +(4056, 1, 1000126, 0, 5, 'Mirkfallon Keeper - World Loot Level 26'), +(4056, 2, 1000127, 0, 5, 'Mirkfallon Keeper - World Loot Level 27'), +(4057, 1, 1000124, 0, 5, 'Son of Cenarius - World Loot Level 24'), +(4057, 2, 1000125, 0, 5, 'Son of Cenarius - World Loot Level 25'), +(4061, 1, 1000125, 0, 5, 'Mirkfallon Dryad - World Loot Level 25'), +(4061, 2, 1000126, 0, 5, 'Mirkfallon Dryad - World Loot Level 26'), +(4062, 1, 1000130, 0, 5, 'Dark Iron Bombardier - World Loot Level 30'), +(4062, 2, 1000131, 0, 5, 'Dark Iron Bombardier - World Loot Level 31'), +(4063, 1, 1000139, 0, 5, 'Feeboz - World Loot Level 39'), +(4064, 1, 1000120, 0, 5, 'Blackrock Scout - World Loot Level 20'), +(4064, 2, 1000121, 0, 5, 'Blackrock Scout - World Loot Level 21'), +(4065, 1, 1000121, 0, 5, 'Blackrock Sentry - World Loot Level 21'), +(4065, 2, 1000122, 0, 5, 'Blackrock Sentry - World Loot Level 22'), +(4070, 1, 1000120, 0, 5, 'Venture Co. Builder - World Loot Level 20'), +(4070, 2, 1000121, 0, 5, 'Venture Co. Builder - World Loot Level 21'), +(4073, 1, 1000123, 0, 5, 'XT:4 - World Loot Level 23'), +(4074, 1, 1000123, 0, 5, 'XT:9 - World Loot Level 23'), +(4093, 1, 1000125, 0, 5, 'Galak Wrangler - World Loot Level 25'), +(4093, 2, 1000126, 0, 5, 'Galak Wrangler - World Loot Level 26'), +(4094, 1, 1000124, 0, 5, 'Galak Scout - World Loot Level 24'), +(4094, 2, 1000125, 0, 5, 'Galak Scout - World Loot Level 25'), +(4095, 1, 1000127, 0, 5, 'Galak Mauler - World Loot Level 27'), +(4095, 2, 1000128, 0, 5, 'Galak Mauler - World Loot Level 28'), +(4096, 1, 1000124, 0, 5, 'Galak Windchaser - World Loot Level 24'), +(4096, 2, 1000125, 0, 5, 'Galak Windchaser - World Loot Level 25'), +(4097, 1, 1000126, 0, 5, 'Galak Stormer - World Loot Level 26'), +(4097, 2, 1000127, 0, 5, 'Galak Stormer - World Loot Level 27'), +(4099, 1, 1000126, 0, 5, 'Galak Marauder - World Loot Level 26'), +(4099, 2, 1000127, 0, 5, 'Galak Marauder - World Loot Level 27'), +(4100, 1, 1000128, 0, 5, 'Screeching Harpy - World Loot Level 28'), +(4100, 2, 1000129, 0, 5, 'Screeching Harpy - World Loot Level 29'), +(4101, 1, 1000129, 0, 5, 'Screeching Roguefeather - World Loot Level 29'), +(4101, 2, 1000130, 0, 5, 'Screeching Roguefeather - World Loot Level 30'), +(4104, 1, 1000130, 0, 5, 'Screeching Windcaller - World Loot Level 30'), +(4107, 1, 1000028, 0, 5, 'Highperch Wyvern - World Loot Level 28'), +(4107, 2, 1000029, 0, 5, 'Highperch Wyvern - World Loot Level 29'), +(4109, 1, 1000028, 0, 5, 'Highperch Consort - World Loot Level 28'), +(4109, 2, 1000029, 0, 5, 'Highperch Consort - World Loot Level 29'), +(4111, 1, 1000126, 0, 5, 'Gravelsnout Kobold - World Loot Level 26'), +(4111, 2, 1000127, 0, 5, 'Gravelsnout Kobold - World Loot Level 27'), +(4112, 1, 1000125, 0, 5, 'Gravelsnout Vermin - World Loot Level 25'), +(4112, 2, 1000126, 0, 5, 'Gravelsnout Vermin - World Loot Level 26'), +(4114, 1, 1000127, 0, 5, 'Gravelsnout Forager - World Loot Level 27'), +(4114, 2, 1000128, 0, 5, 'Gravelsnout Forager - World Loot Level 28'), +(4116, 1, 1000129, 0, 5, 'Gravelsnout Surveyor - World Loot Level 29'), +(4116, 2, 1000130, 0, 5, 'Gravelsnout Surveyor - World Loot Level 30'), +(4130, 1, 1000032, 0, 5, 'Silithid Searcher - World Loot Level 32'), +(4130, 2, 1000033, 0, 5, 'Silithid Searcher - World Loot Level 33'), +(4131, 1, 1000034, 0, 5, 'Silithid Invader - World Loot Level 34'), +(4131, 2, 1000035, 0, 5, 'Silithid Invader - World Loot Level 35'), +(4133, 1, 1000033, 0, 5, 'Silithid Hive Drone - World Loot Level 33'), +(4133, 2, 1000034, 0, 5, 'Silithid Hive Drone - World Loot Level 34'), +(4202, 1, 1000127, 0, 5, 'Gerenzo Wrenchwhistle - World Loot Level 27'), +(4260, 1, 1000137, 0, 5, 'Venture Co. Shredder - World Loot Level 37'), +(4273, 1, 1000129, 0, 5, 'Keeper Ordanus - World Loot Level 29'), +(4280, 1, 1000129, 0, 5, 'Scarlet Preserver - World Loot Level 29'), +(4280, 2, 1000130, 0, 5, 'Scarlet Preserver - World Loot Level 30'), +(4281, 1, 1000129, 0, 5, 'Scarlet Scout - World Loot Level 29'), +(4281, 2, 1000130, 0, 5, 'Scarlet Scout - World Loot Level 30'), +(4282, 1, 1000129, 0, 5, 'Scarlet Magician - World Loot Level 29'), +(4282, 2, 1000130, 0, 5, 'Scarlet Magician - World Loot Level 30'), +(4283, 1, 1000130, 0, 5, 'Scarlet Sentry - World Loot Level 30'), +(4283, 2, 1000131, 0, 5, 'Scarlet Sentry - World Loot Level 31'), +(4284, 1, 1000130, 0, 5, 'Scarlet Augur - World Loot Level 30'), +(4284, 2, 1000131, 0, 5, 'Scarlet Augur - World Loot Level 31'), +(4285, 1, 1000130, 0, 5, 'Scarlet Disciple - World Loot Level 30'), +(4285, 2, 1000131, 0, 5, 'Scarlet Disciple - World Loot Level 31'), +(4409, 1, 1000125, 0, 5, 'Gatekeeper Kordurus - World Loot Level 25'), +(4462, 1, 1000123, 0, 5, 'Blackrock Hunter - World Loot Level 23'), +(4462, 2, 1000124, 0, 5, 'Blackrock Hunter - World Loot Level 24'), +(4463, 1, 1000122, 0, 5, 'Blackrock Summoner - World Loot Level 22'), +(4464, 1, 1000124, 0, 5, 'Blackrock Gladiator - World Loot Level 24'), +(4464, 2, 1000125, 0, 5, 'Blackrock Gladiator - World Loot Level 25'), +(4465, 1, 1000145, 0, 5, 'Vilebranch Warrior - World Loot Level 45'), +(4465, 2, 1000146, 0, 5, 'Vilebranch Warrior - World Loot Level 46'), +(4466, 1, 1000146, 0, 5, 'Vilebranch Scalper - World Loot Level 46'), +(4466, 2, 1000147, 0, 5, 'Vilebranch Scalper - World Loot Level 47'), +(4467, 1, 1000146, 0, 5, 'Vilebranch Soothsayer - World Loot Level 46'), +(4467, 2, 1000147, 0, 5, 'Vilebranch Soothsayer - World Loot Level 47'), +(4472, 1, 1000157, 0, 5, 'Haunting Vision - World Loot Level 57'), +(4472, 2, 1000158, 0, 5, 'Haunting Vision - World Loot Level 58'), +(4474, 1, 1000153, 0, 5, 'Rotting Cadaver - World Loot Level 53'), +(4474, 2, 1000154, 0, 5, 'Rotting Cadaver - World Loot Level 54'), +(4475, 1, 1000152, 0, 5, 'Blighted Zombie - World Loot Level 52'), +(4475, 2, 1000153, 0, 5, 'Blighted Zombie - World Loot Level 53'), +(4479, 1, 1000133, 0, 5, 'Fardel Dabyrie - World Loot Level 33'), +(4480, 1, 1000135, 0, 5, 'Kenata Dabyrie - World Loot Level 35'), +(4481, 1, 1000134, 0, 5, 'Marcel Dabyrie - World Loot Level 34'), +(4493, 1, 1000156, 0, 5, 'Scarlet Avenger - World Loot Level 56'), +(4493, 2, 1000157, 0, 5, 'Scarlet Avenger - World Loot Level 57'), +(4494, 1, 1000157, 0, 5, 'Scarlet Spellbinder - World Loot Level 57'), +(4494, 2, 1000158, 0, 5, 'Scarlet Spellbinder - World Loot Level 58'), +(4505, 1, 1000141, 0, 5, 'Bloodsail Deckhand - World Loot Level 41'), +(4505, 2, 1000142, 0, 5, 'Bloodsail Deckhand - World Loot Level 42'), +(4506, 1, 1000140, 0, 5, 'Bloodsail Swabby - World Loot Level 40'), +(4506, 2, 1000141, 0, 5, 'Bloodsail Swabby - World Loot Level 41'), +(4619, 1, 1000132, 0, 5, 'Geltharis - World Loot Level 32'), +(4632, 1, 1000130, 0, 5, 'Kolkar Centaur - World Loot Level 30'), +(4632, 2, 1000131, 0, 5, 'Kolkar Centaur - World Loot Level 31'), +(4633, 1, 1000130, 0, 5, 'Kolkar Scout - World Loot Level 30'), +(4633, 2, 1000131, 0, 5, 'Kolkar Scout - World Loot Level 31'), +(4634, 1, 1000131, 0, 5, 'Kolkar Mauler - World Loot Level 31'), +(4634, 2, 1000132, 0, 5, 'Kolkar Mauler - World Loot Level 32'), +(4635, 1, 1000131, 0, 5, 'Kolkar Windchaser - World Loot Level 31'), +(4635, 2, 1000132, 0, 5, 'Kolkar Windchaser - World Loot Level 32'), +(4636, 1, 1000132, 0, 5, 'Kolkar Battle Lord - World Loot Level 32'), +(4636, 2, 1000133, 0, 5, 'Kolkar Battle Lord - World Loot Level 33'), +(4637, 1, 1000132, 0, 5, 'Kolkar Destroyer - World Loot Level 32'), +(4637, 2, 1000133, 0, 5, 'Kolkar Destroyer - World Loot Level 33'), +(4638, 1, 1000133, 0, 5, 'Magram Scout - World Loot Level 33'), +(4639, 1, 1000132, 0, 5, 'Magram Outrunner - World Loot Level 32'), +(4639, 2, 1000133, 0, 5, 'Magram Outrunner - World Loot Level 33'), +(4640, 1, 1000133, 0, 5, 'Magram Wrangler - World Loot Level 33'), +(4640, 2, 1000134, 0, 5, 'Magram Wrangler - World Loot Level 34'), +(4641, 1, 1000133, 0, 5, 'Magram Windchaser - World Loot Level 33'), +(4641, 2, 1000134, 0, 5, 'Magram Windchaser - World Loot Level 34'), +(4642, 1, 1000134, 0, 5, 'Magram Stormer - World Loot Level 34'), +(4642, 2, 1000135, 0, 5, 'Magram Stormer - World Loot Level 35'), +(4643, 1, 1000134, 0, 5, 'Magram Pack Runner - World Loot Level 34'), +(4643, 2, 1000135, 0, 5, 'Magram Pack Runner - World Loot Level 35'), +(4644, 1, 1000135, 0, 5, 'Magram Marauder - World Loot Level 35'), +(4644, 2, 1000136, 0, 5, 'Magram Marauder - World Loot Level 36'), +(4645, 1, 1000135, 0, 5, 'Magram Mauler - World Loot Level 35'), +(4645, 2, 1000136, 0, 5, 'Magram Mauler - World Loot Level 36'), +(4646, 1, 1000132, 0, 5, 'Gelkis Outrunner - World Loot Level 32'), +(4646, 2, 1000133, 0, 5, 'Gelkis Outrunner - World Loot Level 33'), +(4647, 1, 1000132, 0, 5, 'Gelkis Scout - World Loot Level 32'), +(4647, 2, 1000133, 0, 5, 'Gelkis Scout - World Loot Level 33'), +(4648, 1, 1000133, 0, 5, 'Gelkis Stamper - World Loot Level 33'), +(4648, 2, 1000134, 0, 5, 'Gelkis Stamper - World Loot Level 34'), +(4649, 1, 1000133, 0, 5, 'Gelkis Windchaser - World Loot Level 33'), +(4649, 2, 1000134, 0, 5, 'Gelkis Windchaser - World Loot Level 34'), +(4651, 1, 1000134, 0, 5, 'Gelkis Earthcaller - World Loot Level 34'), +(4651, 2, 1000135, 0, 5, 'Gelkis Earthcaller - World Loot Level 35'), +(4652, 1, 1000135, 0, 5, 'Gelkis Mauler - World Loot Level 35'), +(4652, 2, 1000136, 0, 5, 'Gelkis Mauler - World Loot Level 36'), +(4653, 1, 1000135, 0, 5, 'Gelkis Marauder - World Loot Level 35'), +(4653, 2, 1000136, 0, 5, 'Gelkis Marauder - World Loot Level 36'), +(4654, 1, 1000137, 0, 5, 'Maraudine Scout - World Loot Level 37'), +(4654, 2, 1000138, 0, 5, 'Maraudine Scout - World Loot Level 38'), +(4655, 1, 1000137, 0, 5, 'Maraudine Wrangler - World Loot Level 37'), +(4655, 2, 1000138, 0, 5, 'Maraudine Wrangler - World Loot Level 38'), +(4656, 1, 1000138, 0, 5, 'Maraudine Mauler - World Loot Level 38'), +(4656, 2, 1000139, 0, 5, 'Maraudine Mauler - World Loot Level 39'), +(4657, 1, 1000138, 0, 5, 'Maraudine Windchaser - World Loot Level 38'), +(4657, 2, 1000139, 0, 5, 'Maraudine Windchaser - World Loot Level 39'), +(4658, 1, 1000139, 0, 5, 'Maraudine Stormer - World Loot Level 39'), +(4658, 2, 1000140, 0, 5, 'Maraudine Stormer - World Loot Level 40'), +(4659, 1, 1000139, 0, 5, 'Maraudine Marauder - World Loot Level 39'), +(4659, 2, 1000140, 0, 5, 'Maraudine Marauder - World Loot Level 40'), +(4663, 1, 1000130, 0, 5, 'Burning Blade Augur - World Loot Level 30'), +(4663, 2, 1000131, 0, 5, 'Burning Blade Augur - World Loot Level 31'), +(4664, 1, 1000130, 0, 5, 'Burning Blade Reaver - World Loot Level 30'), +(4664, 2, 1000131, 0, 5, 'Burning Blade Reaver - World Loot Level 31'), +(4665, 1, 1000131, 0, 5, 'Burning Blade Adept - World Loot Level 31'), +(4665, 2, 1000132, 0, 5, 'Burning Blade Adept - World Loot Level 32'), +(4666, 1, 1000131, 0, 5, 'Burning Blade Felsworn - World Loot Level 31'), +(4666, 2, 1000132, 0, 5, 'Burning Blade Felsworn - World Loot Level 32'), +(4667, 1, 1000132, 0, 5, 'Burning Blade Shadowmage - World Loot Level 32'), +(4667, 2, 1000133, 0, 5, 'Burning Blade Shadowmage - World Loot Level 33'), +(4668, 1, 1000138, 0, 5, 'Burning Blade Summoner - World Loot Level 38'), +(4668, 2, 1000139, 0, 5, 'Burning Blade Summoner - World Loot Level 39'), +(4670, 1, 1000131, 0, 5, 'Hatefury Rogue - World Loot Level 31'), +(4670, 2, 1000132, 0, 5, 'Hatefury Rogue - World Loot Level 32'), +(4671, 1, 1000131, 0, 5, 'Hatefury Trickster - World Loot Level 31'), +(4671, 2, 1000132, 0, 5, 'Hatefury Trickster - World Loot Level 32'), +(4672, 1, 1000131, 0, 5, 'Hatefury Felsworn - World Loot Level 31'), +(4672, 2, 1000132, 0, 5, 'Hatefury Felsworn - World Loot Level 32'), +(4673, 1, 1000132, 0, 5, 'Hatefury Betrayer - World Loot Level 32'), +(4673, 2, 1000133, 0, 5, 'Hatefury Betrayer - World Loot Level 33'), +(4674, 1, 1000132, 0, 5, 'Hatefury Shadowstalker - World Loot Level 32'), +(4674, 2, 1000133, 0, 5, 'Hatefury Shadowstalker - World Loot Level 33'), +(4675, 1, 1000132, 0, 5, 'Hatefury Hellcaller - World Loot Level 32'), +(4675, 2, 1000133, 0, 5, 'Hatefury Hellcaller - World Loot Level 33'), +(4677, 1, 1000137, 0, 5, 'Doomwarder - World Loot Level 37'), +(4677, 2, 1000138, 0, 5, 'Doomwarder - World Loot Level 38'), +(4679, 1, 1000137, 0, 5, 'Nether Maiden - World Loot Level 37'), +(4679, 2, 1000138, 0, 5, 'Nether Maiden - World Loot Level 38'), +(4680, 1, 1000138, 0, 5, 'Doomwarder Captain - World Loot Level 38'), +(4680, 2, 1000139, 0, 5, 'Doomwarder Captain - World Loot Level 39'), +(4682, 1, 1000138, 0, 5, 'Nether Sister - World Loot Level 38'), +(4682, 2, 1000139, 0, 5, 'Nether Sister - World Loot Level 39'), +(4684, 1, 1000139, 0, 5, 'Nether Sorceress - World Loot Level 39'), +(4684, 2, 1000140, 0, 5, 'Nether Sorceress - World Loot Level 40'), +(4705, 1, 1000139, 0, 5, 'Burning Blade Invoker - World Loot Level 39'), +(4705, 2, 1000140, 0, 5, 'Burning Blade Invoker - World Loot Level 40'), +(4723, 1, 1000138, 0, 5, 'Foreman Cozzle - World Loot Level 38'), +(4788, 1, 1000120, 0, 5, 'Fallenroot Satyr - World Loot Level 20'), +(4788, 2, 1000121, 0, 5, 'Fallenroot Satyr - World Loot Level 21'), +(4789, 1, 1000121, 0, 5, 'Fallenroot Rogue - World Loot Level 21'), +(4834, 1, 1000135, 0, 5, 'Theramore Infiltrator - World Loot Level 35'), +(4834, 2, 1000136, 0, 5, 'Theramore Infiltrator - World Loot Level 36'), +(4844, 1, 1000135, 0, 5, 'Shadowforge Surveyor - World Loot Level 35'), +(4844, 2, 1000136, 0, 5, 'Shadowforge Surveyor - World Loot Level 36'), +(4845, 1, 1000135, 0, 5, 'Shadowforge Ruffian - World Loot Level 35'), +(4845, 2, 1000136, 0, 5, 'Shadowforge Ruffian - World Loot Level 36'), +(4846, 1, 1000135, 0, 5, 'Shadowforge Digger - World Loot Level 35'), +(4846, 2, 1000136, 0, 5, 'Shadowforge Digger - World Loot Level 36'), +(4851, 1, 1000136, 0, 5, 'Stonevault Rockchewer - World Loot Level 36'), +(4851, 2, 1000137, 0, 5, 'Stonevault Rockchewer - World Loot Level 37'), +(4856, 1, 1000136, 0, 5, 'Stonevault Cave Hunter - World Loot Level 36'), +(4856, 2, 1000137, 0, 5, 'Stonevault Cave Hunter - World Loot Level 37'), +(5057, 1, 1000137, 0, 5, 'Theramore Deserter - World Loot Level 37'), +(5085, 1, 1000132, 0, 5, 'Sentry Point Guard - World Loot Level 32'), +(5085, 2, 1000133, 0, 5, 'Sentry Point Guard - World Loot Level 33'), +(5086, 1, 1000134, 0, 5, 'Captain Wymor - World Loot Level 34'), +(5086, 2, 1000135, 0, 5, 'Captain Wymor - World Loot Level 35'), +(5184, 1, 1000135, 0, 5, 'Theramore Sentry - World Loot Level 35'), +(5184, 2, 1000136, 0, 5, 'Theramore Sentry - World Loot Level 36'), +(5229, 1, 1000140, 0, 5, 'Gordunni Ogre - World Loot Level 40'), +(5229, 2, 1000141, 0, 5, 'Gordunni Ogre - World Loot Level 41'), +(5232, 1, 1000142, 0, 5, 'Gordunni Brute - World Loot Level 42'), +(5232, 2, 1000143, 0, 5, 'Gordunni Brute - World Loot Level 43'), +(5234, 1, 1000143, 0, 5, 'Gordunni Mauler - World Loot Level 43'), +(5234, 2, 1000144, 0, 5, 'Gordunni Mauler - World Loot Level 44'), +(5236, 1, 1000144, 0, 5, 'Gordunni Shaman - World Loot Level 44'), +(5236, 2, 1000145, 0, 5, 'Gordunni Shaman - World Loot Level 45'), +(5237, 1, 1000141, 0, 5, 'Gordunni Ogre Mage - World Loot Level 41'), +(5237, 2, 1000142, 0, 5, 'Gordunni Ogre Mage - World Loot Level 42'), +(5238, 1, 1000145, 0, 5, 'Gordunni Battlemaster - World Loot Level 45'), +(5238, 2, 1000146, 0, 5, 'Gordunni Battlemaster - World Loot Level 46'), +(5239, 1, 1000145, 0, 5, 'Gordunni Mage-Lord - World Loot Level 45'), +(5239, 2, 1000146, 0, 5, 'Gordunni Mage-Lord - World Loot Level 46'), +(5240, 1, 1000143, 0, 5, 'Gordunni Warlock - World Loot Level 43'), +(5240, 2, 1000144, 0, 5, 'Gordunni Warlock - World Loot Level 44'), +(5241, 1, 1000146, 0, 5, 'Gordunni Warlord - World Loot Level 46'), +(5241, 2, 1000147, 0, 5, 'Gordunni Warlord - World Loot Level 47'), +(5243, 1, 1000145, 0, 5, 'Cursed Atal\'ai - World Loot Level 45'), +(5243, 2, 1000146, 0, 5, 'Cursed Atal\'ai - World Loot Level 46'), +(5249, 1, 1000140, 0, 5, 'Woodpaw Mongrel - World Loot Level 40'), +(5249, 2, 1000141, 0, 5, 'Woodpaw Mongrel - World Loot Level 41'), +(5251, 1, 1000141, 0, 5, 'Woodpaw Trapper - World Loot Level 41'), +(5251, 2, 1000142, 0, 5, 'Woodpaw Trapper - World Loot Level 42'), +(5253, 1, 1000141, 0, 5, 'Woodpaw Brute - World Loot Level 41'), +(5253, 2, 1000142, 0, 5, 'Woodpaw Brute - World Loot Level 42'), +(5254, 1, 1000142, 0, 5, 'Woodpaw Mystic - World Loot Level 42'), +(5254, 2, 1000143, 0, 5, 'Woodpaw Mystic - World Loot Level 43'), +(5255, 1, 1000142, 0, 5, 'Woodpaw Reaver - World Loot Level 42'), +(5255, 2, 1000143, 0, 5, 'Woodpaw Reaver - World Loot Level 43'), +(5258, 1, 1000143, 0, 5, 'Woodpaw Alpha - World Loot Level 43'), +(5258, 2, 1000144, 0, 5, 'Woodpaw Alpha - World Loot Level 44'), +(5261, 1, 1000145, 0, 5, 'Enthralled Atal\'ai - World Loot Level 45'), +(5263, 1, 1000146, 0, 5, 'Mummified Atal\'ai - World Loot Level 46'), +(5263, 2, 1000147, 0, 5, 'Mummified Atal\'ai - World Loot Level 47'), +(5269, 1, 1000146, 0, 5, 'Atal\'ai Priest - World Loot Level 46'), +(5269, 2, 1000147, 0, 5, 'Atal\'ai Priest - World Loot Level 47'), +(5362, 1, 1000148, 0, 5, 'Northspring Harpy - World Loot Level 48'), +(5362, 2, 1000149, 0, 5, 'Northspring Harpy - World Loot Level 49'), +(5363, 1, 1000148, 0, 5, 'Northspring Roguefeather - World Loot Level 48'), +(5363, 2, 1000149, 0, 5, 'Northspring Roguefeather - World Loot Level 49'), +(5364, 1, 1000149, 0, 5, 'Northspring Slayer - World Loot Level 49'), +(5364, 2, 1000150, 0, 5, 'Northspring Slayer - World Loot Level 50'), +(5366, 1, 1000149, 0, 5, 'Northspring Windcaller - World Loot Level 49'), +(5366, 2, 1000150, 0, 5, 'Northspring Windcaller - World Loot Level 50'), +(5401, 1, 1000148, 0, 5, 'Kazkaz the Unholy - World Loot Level 48'), +(5426, 1, 1000044, 0, 5, 'Blisterpaw Hyena - World Loot Level 44'), +(5426, 2, 1000045, 0, 5, 'Blisterpaw Hyena - World Loot Level 45'), +(5429, 1, 1000043, 0, 5, 'Fire Roc - World Loot Level 43'), +(5429, 2, 1000044, 0, 5, 'Fire Roc - World Loot Level 44'), +(5429, 3, 1000045, 0, 5, 'Fire Roc - World Loot Level 45'), +(5471, 1, 1000145, 0, 5, 'Dunemaul Ogre - World Loot Level 45'), +(5471, 2, 1000146, 0, 5, 'Dunemaul Ogre - World Loot Level 46'), +(5472, 1, 1000146, 0, 5, 'Dunemaul Enforcer - World Loot Level 46'), +(5472, 2, 1000147, 0, 5, 'Dunemaul Enforcer - World Loot Level 47'), +(5473, 1, 1000146, 0, 5, 'Dunemaul Ogre Mage - World Loot Level 46'), +(5473, 2, 1000147, 0, 5, 'Dunemaul Ogre Mage - World Loot Level 47'), +(5474, 1, 1000147, 0, 5, 'Dunemaul Brute - World Loot Level 47'), +(5474, 2, 1000148, 0, 5, 'Dunemaul Brute - World Loot Level 48'), +(5475, 1, 1000147, 0, 5, 'Dunemaul Warlock - World Loot Level 47'), +(5475, 2, 1000148, 0, 5, 'Dunemaul Warlock - World Loot Level 48'), +(5477, 1, 1000139, 0, 5, 'Noboru the Cudgel - World Loot Level 39'), +(5600, 1, 1000135, 0, 5, 'Khan Dez\'hepah - World Loot Level 35'), +(5601, 1, 1000137, 0, 5, 'Khan Jehn - World Loot Level 37'), +(5602, 1, 1000137, 0, 5, 'Khan Shaka - World Loot Level 37'), +(5615, 1, 1000143, 0, 5, 'Wastewander Rogue - World Loot Level 43'), +(5615, 2, 1000144, 0, 5, 'Wastewander Rogue - World Loot Level 44'), +(5616, 1, 1000140, 0, 5, 'Wastewander Thief - World Loot Level 40'), +(5616, 2, 1000141, 0, 5, 'Wastewander Thief - World Loot Level 41'), +(5617, 1, 1000142, 0, 5, 'Wastewander Shadow Mage - World Loot Level 42'), +(5617, 2, 1000143, 0, 5, 'Wastewander Shadow Mage - World Loot Level 43'), +(5618, 1, 1000141, 0, 5, 'Wastewander Bandit - World Loot Level 41'), +(5618, 2, 1000142, 0, 5, 'Wastewander Bandit - World Loot Level 42'), +(5622, 1, 1000137, 0, 5, 'Ongeku - World Loot Level 37'), +(5643, 1, 1000136, 0, 5, 'Tyranis Malem - World Loot Level 36'), +(5645, 1, 1000142, 0, 5, 'Sandfury Hideskinner - World Loot Level 42'), +(5645, 2, 1000143, 0, 5, 'Sandfury Hideskinner - World Loot Level 43'), +(5646, 1, 1000142, 0, 5, 'Sandfury Axe Thrower - World Loot Level 42'), +(5646, 2, 1000143, 0, 5, 'Sandfury Axe Thrower - World Loot Level 43'), +(5646, 3, 1000144, 0, 5, 'Sandfury Axe Thrower - World Loot Level 44'), +(5647, 1, 1000143, 0, 5, 'Sandfury Firecaller - World Loot Level 43'), +(5647, 2, 1000144, 0, 5, 'Sandfury Firecaller - World Loot Level 44'), +(5682, 1, 1000120, 0, 5, 'Dalin Forgewright - World Loot Level 20'), +(5683, 1, 1000122, 0, 5, 'Comar Villard - World Loot Level 22'), +(5771, 1, 1000140, 0, 5, 'Jugkar Grim\'rod - World Loot Level 40'), +(5839, 1, 1000143, 0, 5, 'Dark Iron Geologist - World Loot Level 43'), +(5839, 2, 1000144, 0, 5, 'Dark Iron Geologist - World Loot Level 44'), +(5840, 1, 1000146, 0, 5, 'Dark Iron Steamsmith - World Loot Level 46'), +(5840, 2, 1000147, 0, 5, 'Dark Iron Steamsmith - World Loot Level 47'), +(5843, 1, 1000145, 0, 5, 'Slave Worker - World Loot Level 45'), +(5843, 2, 1000146, 0, 5, 'Slave Worker - World Loot Level 46'), +(5843, 3, 1000147, 0, 5, 'Slave Worker - World Loot Level 47'), +(5844, 1, 1000145, 0, 5, 'Dark Iron Slaver - World Loot Level 45'), +(5844, 2, 1000146, 0, 5, 'Dark Iron Slaver - World Loot Level 46'), +(5846, 1, 1000147, 0, 5, 'Dark Iron Taskmaster - World Loot Level 47'), +(5846, 2, 1000148, 0, 5, 'Dark Iron Taskmaster - World Loot Level 48'), +(5854, 1, 1000047, 0, 5, 'Heavy War Golem - World Loot Level 47'), +(5854, 2, 1000048, 0, 5, 'Heavy War Golem - World Loot Level 48'), +(5854, 3, 1000049, 0, 5, 'Heavy War Golem - World Loot Level 49'), +(5860, 1, 1000143, 0, 5, 'Twilight Dark Shaman - World Loot Level 43'), +(5860, 2, 1000144, 0, 5, 'Twilight Dark Shaman - World Loot Level 44'), +(5861, 1, 1000144, 0, 5, 'Twilight Fire Guard - World Loot Level 44'), +(5861, 2, 1000145, 0, 5, 'Twilight Fire Guard - World Loot Level 45'), +(5861, 3, 1000146, 0, 5, 'Twilight Fire Guard - World Loot Level 46'), +(5862, 1, 1000144, 0, 5, 'Twilight Geomancer - World Loot Level 44'), +(5862, 2, 1000145, 0, 5, 'Twilight Geomancer - World Loot Level 45'), +(5974, 1, 1000145, 0, 5, 'Dreadmaul Ogre - World Loot Level 45'), +(5974, 2, 1000146, 0, 5, 'Dreadmaul Ogre - World Loot Level 46'), +(5975, 1, 1000146, 0, 5, 'Dreadmaul Ogre Mage - World Loot Level 46'), +(5975, 2, 1000147, 0, 5, 'Dreadmaul Ogre Mage - World Loot Level 47'), +(5976, 1, 1000146, 0, 5, 'Dreadmaul Brute - World Loot Level 46'), +(5976, 2, 1000147, 0, 5, 'Dreadmaul Brute - World Loot Level 47'), +(5977, 1, 1000153, 0, 5, 'Dreadmaul Mauler - World Loot Level 53'), +(5977, 2, 1000154, 0, 5, 'Dreadmaul Mauler - World Loot Level 54'), +(5978, 1, 1000154, 0, 5, 'Dreadmaul Warlock - World Loot Level 54'), +(5978, 2, 1000155, 0, 5, 'Dreadmaul Warlock - World Loot Level 55'), +(5979, 1, 1000145, 0, 5, 'Wretched Lost One - World Loot Level 45'), +(5979, 2, 1000146, 0, 5, 'Wretched Lost One - World Loot Level 46'), +(5979, 3, 1000147, 0, 5, 'Wretched Lost One - World Loot Level 47'), +(5996, 1, 1000147, 0, 5, 'Nethergarde Miner - World Loot Level 47'), +(5996, 2, 1000148, 0, 5, 'Nethergarde Miner - World Loot Level 48'), +(5997, 1, 1000147, 0, 5, 'Nethergarde Engineer - World Loot Level 47'), +(5997, 2, 1000148, 0, 5, 'Nethergarde Engineer - World Loot Level 48'), +(5998, 1, 1000146, 0, 5, 'Nethergarde Foreman - World Loot Level 46'), +(5998, 2, 1000147, 0, 5, 'Nethergarde Foreman - World Loot Level 47'), +(5998, 3, 1000148, 0, 5, 'Nethergarde Foreman - World Loot Level 48'), +(5999, 1, 1000149, 0, 5, 'Nethergarde Soldier - World Loot Level 49'), +(5999, 2, 1000150, 0, 5, 'Nethergarde Soldier - World Loot Level 50'), +(6000, 1, 1000149, 0, 5, 'Nethergarde Cleric - World Loot Level 49'), +(6000, 2, 1000150, 0, 5, 'Nethergarde Cleric - World Loot Level 50'), +(6000, 3, 1000151, 0, 5, 'Nethergarde Cleric - World Loot Level 51'), +(6001, 1, 1000149, 0, 5, 'Nethergarde Analyst - World Loot Level 49'), +(6001, 2, 1000150, 0, 5, 'Nethergarde Analyst - World Loot Level 50'), +(6001, 3, 1000151, 0, 5, 'Nethergarde Analyst - World Loot Level 51'), +(6002, 1, 1000149, 0, 5, 'Nethergarde Riftwatcher - World Loot Level 49'), +(6002, 2, 1000150, 0, 5, 'Nethergarde Riftwatcher - World Loot Level 50'), +(6002, 3, 1000151, 0, 5, 'Nethergarde Riftwatcher - World Loot Level 51'), +(6003, 1, 1000150, 0, 5, 'Nethergarde Officer - World Loot Level 50'), +(6003, 2, 1000151, 0, 5, 'Nethergarde Officer - World Loot Level 51'), +(6004, 1, 1000151, 0, 5, 'Shadowsworn Cultist - World Loot Level 51'), +(6004, 2, 1000152, 0, 5, 'Shadowsworn Cultist - World Loot Level 52'), +(6005, 1, 1000152, 0, 5, 'Shadowsworn Thug - World Loot Level 52'), +(6005, 2, 1000153, 0, 5, 'Shadowsworn Thug - World Loot Level 53'), +(6006, 1, 1000152, 0, 5, 'Shadowsworn Adept - World Loot Level 52'), +(6006, 2, 1000153, 0, 5, 'Shadowsworn Adept - World Loot Level 53'), +(6007, 1, 1000153, 0, 5, 'Shadowsworn Enforcer - World Loot Level 53'), +(6007, 2, 1000154, 0, 5, 'Shadowsworn Enforcer - World Loot Level 54'), +(6008, 1, 1000153, 0, 5, 'Shadowsworn Warlock - World Loot Level 53'), +(6008, 2, 1000154, 0, 5, 'Shadowsworn Warlock - World Loot Level 54'), +(6009, 1, 1000154, 0, 5, 'Shadowsworn Dreadweaver - World Loot Level 54'), +(6009, 2, 1000155, 0, 5, 'Shadowsworn Dreadweaver - World Loot Level 55'), +(6011, 1, 1000154, 0, 5, 'Felguard Sentry - World Loot Level 54'), +(6011, 2, 1000155, 0, 5, 'Felguard Sentry - World Loot Level 55'), +(6068, 1, 1000135, 0, 5, 'Warug\'s Bodyguard - World Loot Level 35'), +(6068, 2, 1000136, 0, 5, 'Warug\'s Bodyguard - World Loot Level 36'), +(6072, 1, 1000132, 0, 5, 'Diathorus the Seeker - World Loot Level 32'), +(6093, 1, 1000111, 0, 5, 'Dead-Tooth Jack - World Loot Level 11'), +(6113, 1, 1000111, 0, 5, 'Vejrek - World Loot Level 11'), +(6115, 1, 1000128, 0, 5, 'Roaming Felguard - World Loot Level 28'), +(6115, 2, 1000129, 0, 5, 'Roaming Felguard - World Loot Level 29'), +(6115, 3, 1000130, 0, 5, 'Roaming Felguard - World Loot Level 30'), +(6116, 1, 1000145, 0, 5, 'Highborne Apparition - World Loot Level 45'), +(6116, 2, 1000146, 0, 5, 'Highborne Apparition - World Loot Level 46'), +(6117, 1, 1000146, 0, 5, 'Highborne Lichling - World Loot Level 46'), +(6117, 2, 1000147, 0, 5, 'Highborne Lichling - World Loot Level 47'), +(6123, 1, 1000109, 0, 5, 'Dark Iron Spy - World Loot Level 9'), +(6123, 2, 1000110, 0, 5, 'Dark Iron Spy - World Loot Level 10'), +(6124, 1, 1000111, 0, 5, 'Captain Beld - World Loot Level 11'), +(6125, 1, 1000145, 0, 5, 'Haldarr Satyr - World Loot Level 45'), +(6125, 2, 1000146, 0, 5, 'Haldarr Satyr - World Loot Level 46'), +(6126, 1, 1000145, 0, 5, 'Haldarr Trickster - World Loot Level 45'), +(6126, 2, 1000146, 0, 5, 'Haldarr Trickster - World Loot Level 46'), +(6126, 3, 1000147, 0, 5, 'Haldarr Trickster - World Loot Level 47'), +(6127, 1, 1000146, 0, 5, 'Haldarr Felsworn - World Loot Level 46'), +(6127, 2, 1000147, 0, 5, 'Haldarr Felsworn - World Loot Level 47'), +(6128, 1, 1000110, 0, 5, 'Vorlus Vilehoof - World Loot Level 10'), +(6132, 1, 1000123, 0, 5, 'Razorfen Servitor - World Loot Level 23'), +(6132, 2, 1000124, 0, 5, 'Razorfen Servitor - World Loot Level 24'), +(6133, 1, 1000111, 0, 5, 'Shade of Elura - World Loot Level 11'), +(6138, 1, 1000154, 0, 5, 'Arkkoran Oracle - World Loot Level 54'), +(6138, 2, 1000155, 0, 5, 'Arkkoran Oracle - World Loot Level 55'), +(6184, 1, 1000146, 0, 5, 'Timbermaw Pathfinder - World Loot Level 46'), +(6184, 2, 1000147, 0, 5, 'Timbermaw Pathfinder - World Loot Level 47'), +(6185, 1, 1000147, 0, 5, 'Timbermaw Warrior - World Loot Level 47'), +(6185, 2, 1000148, 0, 5, 'Timbermaw Warrior - World Loot Level 48'), +(6186, 1, 1000148, 0, 5, 'Timbermaw Totemic - World Loot Level 48'), +(6186, 2, 1000149, 0, 5, 'Timbermaw Totemic - World Loot Level 49'), +(6187, 1, 1000149, 0, 5, 'Timbermaw Den Watcher - World Loot Level 49'), +(6187, 2, 1000150, 0, 5, 'Timbermaw Den Watcher - World Loot Level 50'), +(6188, 1, 1000150, 0, 5, 'Timbermaw Shaman - World Loot Level 50'), +(6188, 2, 1000151, 0, 5, 'Timbermaw Shaman - World Loot Level 51'), +(6189, 1, 1000151, 0, 5, 'Timbermaw Ursa - World Loot Level 51'), +(6189, 2, 1000152, 0, 5, 'Timbermaw Ursa - World Loot Level 52'), +(6190, 1, 1000146, 0, 5, 'Spitelash Warrior - World Loot Level 46'), +(6190, 2, 1000147, 0, 5, 'Spitelash Warrior - World Loot Level 47'), +(6195, 1, 1000151, 0, 5, 'Spitelash Siren - World Loot Level 51'), +(6195, 2, 1000152, 0, 5, 'Spitelash Siren - World Loot Level 52'), +(6196, 1, 1000150, 0, 5, 'Spitelash Myrmidon - World Loot Level 50'), +(6196, 2, 1000151, 0, 5, 'Spitelash Myrmidon - World Loot Level 51'), +(6198, 1, 1000151, 0, 5, 'Blood Elf Surveyor - World Loot Level 51'), +(6198, 2, 1000152, 0, 5, 'Blood Elf Surveyor - World Loot Level 52'), +(6199, 1, 1000152, 0, 5, 'Blood Elf Reclaimer - World Loot Level 52'), +(6199, 2, 1000153, 0, 5, 'Blood Elf Reclaimer - World Loot Level 53'), +(6200, 1, 1000151, 0, 5, 'Legashi Satyr - World Loot Level 51'), +(6200, 2, 1000152, 0, 5, 'Legashi Satyr - World Loot Level 52'), +(6201, 1, 1000151, 0, 5, 'Legashi Rogue - World Loot Level 51'), +(6201, 2, 1000152, 0, 5, 'Legashi Rogue - World Loot Level 52'), +(6201, 3, 1000153, 0, 5, 'Legashi Rogue - World Loot Level 53'), +(6202, 1, 1000152, 0, 5, 'Legashi Hellcaller - World Loot Level 52'), +(6202, 2, 1000153, 0, 5, 'Legashi Hellcaller - World Loot Level 53'), +(6208, 1, 1000125, 0, 5, 'Caverndeep Invader - World Loot Level 25'), +(6208, 2, 1000126, 0, 5, 'Caverndeep Invader - World Loot Level 26'), +(6210, 1, 1000124, 0, 5, 'Caverndeep Pillager - World Loot Level 24'), +(6210, 2, 1000125, 0, 5, 'Caverndeep Pillager - World Loot Level 25'), +(6213, 1, 1000124, 0, 5, 'Irradiated Invader - World Loot Level 24'), +(6213, 2, 1000125, 0, 5, 'Irradiated Invader - World Loot Level 25'), +(6213, 3, 1000126, 0, 5, 'Irradiated Invader - World Loot Level 26'), +(6221, 1, 1000124, 0, 5, 'Addled Leper - World Loot Level 24'), +(6221, 2, 1000125, 0, 5, 'Addled Leper - World Loot Level 25'), +(6371, 1, 1000151, 0, 5, 'Storm Bay Warrior - World Loot Level 51'), +(6371, 2, 1000152, 0, 5, 'Storm Bay Warrior - World Loot Level 52'), +(6466, 1, 1000112, 0, 5, 'Gamon - World Loot Level 12'), +(6494, 1, 1000113, 0, 5, 'Tazan - World Loot Level 13'), +(6497, 1, 1000113, 0, 5, 'Astor Hadren - World Loot Level 13'), +(6523, 1, 1000127, 0, 5, 'Dark Iron Rifleman - World Loot Level 27'), +(6523, 2, 1000128, 0, 5, 'Dark Iron Rifleman - World Loot Level 28'), +(6547, 1, 1000125, 0, 5, 'Suffering Victim - World Loot Level 25'), +(6570, 1, 1000116, 0, 5, 'Fenwick Thatros - World Loot Level 16'), +(6606, 1, 1000116, 0, 5, 'Overseer Glibby - World Loot Level 16'), +(6668, 1, 1000123, 0, 5, 'Lord Cyrik Blackforge - World Loot Level 23'), +(6733, 1, 1000137, 0, 5, 'Stonevault Basher - World Loot Level 37'), +(6733, 2, 1000138, 0, 5, 'Stonevault Basher - World Loot Level 38'), +(6846, 1, 1000110, 0, 5, 'Defias Dockmaster - World Loot Level 10'), +(6909, 1, 1000112, 0, 5, 'Sethir the Ancient - World Loot Level 12'), +(6927, 1, 1000108, 0, 5, 'Defias Dockworker - World Loot Level 8'), +(6927, 2, 1000109, 0, 5, 'Defias Dockworker - World Loot Level 9'), +(7025, 1, 1000155, 0, 5, 'Blackrock Soldier - World Loot Level 55'), +(7025, 2, 1000156, 0, 5, 'Blackrock Soldier - World Loot Level 56'), +(7026, 1, 1000155, 0, 5, 'Blackrock Sorcerer - World Loot Level 55'), +(7026, 2, 1000156, 0, 5, 'Blackrock Sorcerer - World Loot Level 56'), +(7027, 1, 1000156, 0, 5, 'Blackrock Slayer - World Loot Level 56'), +(7027, 2, 1000157, 0, 5, 'Blackrock Slayer - World Loot Level 57'), +(7028, 1, 1000156, 0, 5, 'Blackrock Warlock - World Loot Level 56'), +(7028, 2, 1000157, 0, 5, 'Blackrock Warlock - World Loot Level 57'), +(7029, 1, 1000157, 0, 5, 'Blackrock Battlemaster - World Loot Level 57'), +(7029, 2, 1000158, 0, 5, 'Blackrock Battlemaster - World Loot Level 58'), +(7033, 1, 1000150, 0, 5, 'Firegut Ogre - World Loot Level 50'), +(7033, 2, 1000151, 0, 5, 'Firegut Ogre - World Loot Level 51'), +(7034, 1, 1000151, 0, 5, 'Firegut Ogre Mage - World Loot Level 51'), +(7034, 2, 1000152, 0, 5, 'Firegut Ogre Mage - World Loot Level 52'), +(7035, 1, 1000152, 0, 5, 'Firegut Brute - World Loot Level 52'), +(7035, 2, 1000153, 0, 5, 'Firegut Brute - World Loot Level 53'), +(7036, 1, 1000153, 0, 5, 'Thaurissan Spy - World Loot Level 53'), +(7036, 2, 1000154, 0, 5, 'Thaurissan Spy - World Loot Level 54'), +(7037, 1, 1000153, 0, 5, 'Thaurissan Firewalker - World Loot Level 53'), +(7037, 2, 1000154, 0, 5, 'Thaurissan Firewalker - World Loot Level 54'), +(7037, 3, 1000155, 0, 5, 'Thaurissan Firewalker - World Loot Level 55'), +(7038, 1, 1000154, 0, 5, 'Thaurissan Agent - World Loot Level 54'), +(7038, 2, 1000155, 0, 5, 'Thaurissan Agent - World Loot Level 55'), +(7040, 1, 1000152, 0, 5, 'Black Dragonspawn - World Loot Level 52'), +(7040, 2, 1000153, 0, 5, 'Black Dragonspawn - World Loot Level 53'), +(7041, 1, 1000153, 0, 5, 'Black Wyrmkin - World Loot Level 53'), +(7041, 2, 1000154, 0, 5, 'Black Wyrmkin - World Loot Level 54'), +(7042, 1, 1000156, 0, 5, 'Flamescale Dragonspawn - World Loot Level 56'), +(7042, 2, 1000157, 0, 5, 'Flamescale Dragonspawn - World Loot Level 57'), +(7043, 1, 1000157, 0, 5, 'Flamescale Wyrmkin - World Loot Level 57'), +(7043, 2, 1000158, 0, 5, 'Flamescale Wyrmkin - World Loot Level 58'), +(7053, 1, 1000123, 0, 5, 'Klaven Mortwake - World Loot Level 23'), +(7055, 1, 1000054, 0, 5, 'Blackrock Worg - World Loot Level 54'), +(7055, 2, 1000055, 0, 5, 'Blackrock Worg - World Loot Level 55'), +(7105, 1, 1000149, 0, 5, 'Jadefire Satyr - World Loot Level 49'), +(7106, 1, 1000150, 0, 5, 'Jadefire Rogue - World Loot Level 50'), +(7106, 2, 1000151, 0, 5, 'Jadefire Rogue - World Loot Level 51'), +(7107, 1, 1000152, 0, 5, 'Jadefire Trickster - World Loot Level 52'), +(7107, 2, 1000153, 0, 5, 'Jadefire Trickster - World Loot Level 53'), +(7109, 1, 1000150, 0, 5, 'Jadefire Felsworn - World Loot Level 50'), +(7109, 2, 1000151, 0, 5, 'Jadefire Felsworn - World Loot Level 51'), +(7110, 1, 1000151, 0, 5, 'Jadefire Shadowstalker - World Loot Level 51'), +(7110, 2, 1000152, 0, 5, 'Jadefire Shadowstalker - World Loot Level 52'), +(7111, 1, 1000153, 0, 5, 'Jadefire Hellcaller - World Loot Level 53'), +(7111, 2, 1000154, 0, 5, 'Jadefire Hellcaller - World Loot Level 54'), +(7112, 1, 1000151, 0, 5, 'Jaedenar Cultist - World Loot Level 51'), +(7112, 2, 1000152, 0, 5, 'Jaedenar Cultist - World Loot Level 52'), +(7113, 1, 1000150, 0, 5, 'Jaedenar Guardian - World Loot Level 50'), +(7113, 2, 1000151, 0, 5, 'Jaedenar Guardian - World Loot Level 51'), +(7114, 1, 1000152, 0, 5, 'Jaedenar Enforcer - World Loot Level 52'), +(7114, 2, 1000153, 0, 5, 'Jaedenar Enforcer - World Loot Level 53'), +(7115, 1, 1000151, 0, 5, 'Jaedenar Adept - World Loot Level 51'), +(7115, 2, 1000152, 0, 5, 'Jaedenar Adept - World Loot Level 52'), +(7118, 1, 1000153, 0, 5, 'Jaedenar Darkweaver - World Loot Level 53'), +(7118, 2, 1000154, 0, 5, 'Jaedenar Darkweaver - World Loot Level 54'), +(7120, 1, 1000153, 0, 5, 'Jaedenar Warlock - World Loot Level 53'), +(7120, 2, 1000154, 0, 5, 'Jaedenar Warlock - World Loot Level 54'), +(7153, 1, 1000148, 0, 5, 'Deadwood Warrior - World Loot Level 48'), +(7153, 2, 1000149, 0, 5, 'Deadwood Warrior - World Loot Level 49'), +(7154, 1, 1000148, 0, 5, 'Deadwood Gardener - World Loot Level 48'), +(7154, 2, 1000149, 0, 5, 'Deadwood Gardener - World Loot Level 49'), +(7155, 1, 1000149, 0, 5, 'Deadwood Pathfinder - World Loot Level 49'), +(7155, 2, 1000150, 0, 5, 'Deadwood Pathfinder - World Loot Level 50'), +(7156, 1, 1000153, 0, 5, 'Deadwood Den Watcher - World Loot Level 53'), +(7156, 2, 1000154, 0, 5, 'Deadwood Den Watcher - World Loot Level 54'), +(7157, 1, 1000154, 0, 5, 'Deadwood Avenger - World Loot Level 54'), +(7157, 2, 1000155, 0, 5, 'Deadwood Avenger - World Loot Level 55'), +(7158, 1, 1000153, 0, 5, 'Deadwood Shaman - World Loot Level 53'), +(7158, 2, 1000154, 0, 5, 'Deadwood Shaman - World Loot Level 54'), +(7234, 1, 1000108, 0, 5, 'Ferocitas the Dream Eater - World Loot Level 8'), +(7235, 1, 1000106, 0, 5, 'Gnarlpine Mystic - World Loot Level 6'), +(7235, 2, 1000107, 0, 5, 'Gnarlpine Mystic - World Loot Level 7'), +(7318, 1, 1000110, 0, 5, 'Rageclaw - World Loot Level 10'), +(7369, 1, 1000155, 0, 5, 'Deadwind Brute - World Loot Level 55'), +(7369, 2, 1000156, 0, 5, 'Deadwind Brute - World Loot Level 56'), +(7371, 1, 1000156, 0, 5, 'Deadwind Mauler - World Loot Level 56'), +(7371, 2, 1000157, 0, 5, 'Deadwind Mauler - World Loot Level 57'), +(7372, 1, 1000157, 0, 5, 'Deadwind Warlock - World Loot Level 57'), +(7372, 2, 1000158, 0, 5, 'Deadwind Warlock - World Loot Level 58'), +(7379, 1, 1000155, 0, 5, 'Deadwind Ogre Mage - World Loot Level 55'), +(7379, 2, 1000156, 0, 5, 'Deadwind Ogre Mage - World Loot Level 56'), +(7379, 3, 1000157, 0, 5, 'Deadwind Ogre Mage - World Loot Level 57'), +(7404, 1, 1000130, 0, 5, 'Galak Flame Guard - World Loot Level 30'), +(7438, 1, 1000157, 0, 5, 'Winterfall Ursa - World Loot Level 57'), +(7438, 2, 1000158, 0, 5, 'Winterfall Ursa - World Loot Level 58'), +(7439, 1, 1000156, 0, 5, 'Winterfall Shaman - World Loot Level 56'), +(7439, 2, 1000157, 0, 5, 'Winterfall Shaman - World Loot Level 57'), +(7440, 1, 1000155, 0, 5, 'Winterfall Den Watcher - World Loot Level 55'), +(7440, 2, 1000156, 0, 5, 'Winterfall Den Watcher - World Loot Level 56'), +(7442, 1, 1000153, 0, 5, 'Winterfall Pathfinder - World Loot Level 53'), +(7442, 2, 1000154, 0, 5, 'Winterfall Pathfinder - World Loot Level 54'), +(7447, 1, 1000053, 0, 5, 'Fledgling Chillwind - World Loot Level 53'), +(7447, 2, 1000054, 0, 5, 'Fledgling Chillwind - World Loot Level 54'), +(7447, 3, 1000055, 0, 5, 'Fledgling Chillwind - World Loot Level 55'), +(7523, 1, 1000154, 0, 5, 'Suffering Highborne - World Loot Level 54'), +(7523, 2, 1000155, 0, 5, 'Suffering Highborne - World Loot Level 55'), +(7524, 1, 1000155, 0, 5, 'Anguished Highborne - World Loot Level 55'), +(7524, 2, 1000156, 0, 5, 'Anguished Highborne - World Loot Level 56'), +(7668, 1, 1000157, 0, 5, 'Servant of Razelikh - World Loot Level 57'), +(7669, 1, 1000153, 0, 5, 'Servant of Grol - World Loot Level 53'), +(7669, 2, 1000154, 0, 5, 'Servant of Grol - World Loot Level 54'), +(7670, 1, 1000154, 0, 5, 'Servant of Allistarj - World Loot Level 54'), +(7670, 2, 1000155, 0, 5, 'Servant of Allistarj - World Loot Level 55'), +(7671, 1, 1000156, 0, 5, 'Servant of Sevine - World Loot Level 56'), +(7725, 1, 1000142, 0, 5, 'Grimtotem Raider - World Loot Level 42'), +(7725, 2, 1000143, 0, 5, 'Grimtotem Raider - World Loot Level 43'), +(7726, 1, 1000141, 0, 5, 'Grimtotem Naturalist - World Loot Level 41'), +(7726, 2, 1000142, 0, 5, 'Grimtotem Naturalist - World Loot Level 42'), +(7727, 1, 1000143, 0, 5, 'Grimtotem Shaman - World Loot Level 43'), +(7727, 2, 1000144, 0, 5, 'Grimtotem Shaman - World Loot Level 44'), +(7728, 1, 1000155, 0, 5, 'Kirith the Damned - World Loot Level 55'), +(7847, 1, 1000146, 0, 5, 'Caliph Scorpidsting - World Loot Level 46'), +(7855, 1, 1000144, 0, 5, 'Southsea Pirate - World Loot Level 44'), +(7855, 2, 1000145, 0, 5, 'Southsea Pirate - World Loot Level 45'), +(7856, 1, 1000144, 0, 5, 'Southsea Freebooter - World Loot Level 44'), +(7856, 2, 1000145, 0, 5, 'Southsea Freebooter - World Loot Level 45'), +(7857, 1, 1000144, 0, 5, 'Southsea Dock Worker - World Loot Level 44'), +(7857, 2, 1000145, 0, 5, 'Southsea Dock Worker - World Loot Level 45'), +(7858, 1, 1000144, 0, 5, 'Southsea Swashbuckler - World Loot Level 44'), +(7858, 2, 1000145, 0, 5, 'Southsea Swashbuckler - World Loot Level 45'), +(7864, 1, 1000148, 0, 5, 'Lingering Highborne - World Loot Level 48'), +(7864, 2, 1000149, 0, 5, 'Lingering Highborne - World Loot Level 49'), +(7864, 3, 1000150, 0, 5, 'Lingering Highborne - World Loot Level 50'), +(7872, 1, 1000133, 0, 5, 'Death\'s Head Cultist - World Loot Level 33'), +(7872, 2, 1000134, 0, 5, 'Death\'s Head Cultist - World Loot Level 34'), +(7873, 1, 1000133, 0, 5, 'Razorfen Battleguard - World Loot Level 33'), +(7873, 2, 1000134, 0, 5, 'Razorfen Battleguard - World Loot Level 34'), +(7874, 1, 1000133, 0, 5, 'Razorfen Thornweaver - World Loot Level 33'), +(7874, 2, 1000134, 0, 5, 'Razorfen Thornweaver - World Loot Level 34'), +(7883, 1, 1000145, 0, 5, 'Andre Firebeard - World Loot Level 45'), +(7885, 1, 1000153, 0, 5, 'Spitelash Battlemaster - World Loot Level 53'), +(7885, 2, 1000154, 0, 5, 'Spitelash Battlemaster - World Loot Level 54'), +(7886, 1, 1000154, 0, 5, 'Spitelash Enchantress - World Loot Level 54'), +(7886, 2, 1000155, 0, 5, 'Spitelash Enchantress - World Loot Level 55'), +(7995, 1, 1000151, 0, 5, 'Vile Priestess Hexx - World Loot Level 51'), +(7996, 1, 1000150, 0, 5, 'Qiaga the Keeper - World Loot Level 50'), +(8419, 1, 1000145, 0, 5, 'Twilight Idolater - World Loot Level 45'), +(8419, 2, 1000146, 0, 5, 'Twilight Idolater - World Loot Level 46'), +(8447, 1, 1000144, 0, 5, 'Clunk - World Loot Level 44'), +(8518, 1, 1000129, 0, 5, 'Rynthariel the Keymaster - World Loot Level 29'), +(8523, 1, 1000153, 0, 5, 'Scourge Soldier - World Loot Level 53'), +(8523, 2, 1000154, 0, 5, 'Scourge Soldier - World Loot Level 54'), +(8524, 1, 1000154, 0, 5, 'Cursed Mage - World Loot Level 54'), +(8524, 2, 1000155, 0, 5, 'Cursed Mage - World Loot Level 55'), +(8525, 1, 1000155, 0, 5, 'Scourge Warder - World Loot Level 55'), +(8525, 2, 1000156, 0, 5, 'Scourge Warder - World Loot Level 56'), +(8526, 1, 1000156, 0, 5, 'Dark Caster - World Loot Level 56'), +(8526, 2, 1000157, 0, 5, 'Dark Caster - World Loot Level 57'), +(8527, 1, 1000157, 0, 5, 'Scourge Guard - World Loot Level 57'), +(8527, 2, 1000158, 0, 5, 'Scourge Guard - World Loot Level 58'), +(8528, 1, 1000158, 0, 5, 'Dread Weaver - World Loot Level 58'), +(8528, 2, 1000159, 0, 5, 'Dread Weaver - World Loot Level 59'), +(8529, 1, 1000159, 0, 5, 'Scourge Champion - World Loot Level 59'), +(8529, 2, 1000160, 0, 5, 'Scourge Champion - World Loot Level 60'), +(8530, 1, 1000154, 0, 5, 'Cannibal Ghoul - World Loot Level 54'), +(8530, 2, 1000155, 0, 5, 'Cannibal Ghoul - World Loot Level 55'), +(8531, 1, 1000156, 0, 5, 'Gibbering Ghoul - World Loot Level 56'), +(8531, 2, 1000157, 0, 5, 'Gibbering Ghoul - World Loot Level 57'), +(8532, 1, 1000158, 0, 5, 'Diseased Flayer - World Loot Level 58'), +(8532, 2, 1000159, 0, 5, 'Diseased Flayer - World Loot Level 59'), +(8538, 1, 1000155, 0, 5, 'Unseen Servant - World Loot Level 55'), +(8538, 2, 1000156, 0, 5, 'Unseen Servant - World Loot Level 56'), +(8539, 1, 1000157, 0, 5, 'Eyeless Watcher - World Loot Level 57'), +(8539, 2, 1000158, 0, 5, 'Eyeless Watcher - World Loot Level 58'), +(8540, 1, 1000153, 0, 5, 'Torn Screamer - World Loot Level 53'), +(8540, 2, 1000154, 0, 5, 'Torn Screamer - World Loot Level 54'), +(8540, 3, 1000155, 0, 5, 'Torn Screamer - World Loot Level 55'), +(8541, 1, 1000155, 0, 5, 'Hate Shrieker - World Loot Level 55'), +(8541, 2, 1000156, 0, 5, 'Hate Shrieker - World Loot Level 56'), +(8541, 3, 1000157, 0, 5, 'Hate Shrieker - World Loot Level 57'), +(8542, 1, 1000157, 0, 5, 'Death Singer - World Loot Level 57'), +(8542, 2, 1000158, 0, 5, 'Death Singer - World Loot Level 58'), +(8542, 3, 1000159, 0, 5, 'Death Singer - World Loot Level 59'), +(8543, 1, 1000157, 0, 5, 'Stitched Horror - World Loot Level 57'), +(8543, 2, 1000158, 0, 5, 'Stitched Horror - World Loot Level 58'), +(8544, 1, 1000158, 0, 5, 'Gangled Golem - World Loot Level 58'), +(8544, 2, 1000159, 0, 5, 'Gangled Golem - World Loot Level 59'), +(8545, 1, 1000159, 0, 5, 'Stitched Golem - World Loot Level 59'), +(8545, 2, 1000160, 0, 5, 'Stitched Golem - World Loot Level 60'), +(8546, 1, 1000158, 0, 5, 'Dark Adept - World Loot Level 58'), +(8546, 2, 1000159, 0, 5, 'Dark Adept - World Loot Level 59'), +(8547, 1, 1000154, 0, 5, 'Death Cultist - World Loot Level 54'), +(8548, 1, 1000156, 0, 5, 'Vile Tutor - World Loot Level 56'), +(8548, 2, 1000157, 0, 5, 'Vile Tutor - World Loot Level 57'), +(8550, 1, 1000159, 0, 5, 'Shadowmage - World Loot Level 59'), +(8550, 2, 1000160, 0, 5, 'Shadowmage - World Loot Level 60'), +(8551, 1, 1000155, 0, 5, 'Dark Summoner - World Loot Level 55'), +(8551, 2, 1000156, 0, 5, 'Dark Summoner - World Loot Level 56'), +(8553, 1, 1000154, 0, 5, 'Necromancer - World Loot Level 54'), +(8553, 2, 1000155, 0, 5, 'Necromancer - World Loot Level 55'), +(8555, 1, 1000053, 0, 5, 'Crypt Stalker - World Loot Level 53'), +(8555, 2, 1000054, 0, 5, 'Crypt Stalker - World Loot Level 54'), +(8558, 1, 1000058, 0, 5, 'Crypt Slayer - World Loot Level 58'), +(8558, 2, 1000059, 0, 5, 'Crypt Slayer - World Loot Level 59'), +(8560, 1, 1000157, 0, 5, 'Mossflayer Scout - World Loot Level 57'), +(8560, 2, 1000158, 0, 5, 'Mossflayer Scout - World Loot Level 58'), +(8561, 1, 1000158, 0, 5, 'Mossflayer Shadowhunter - World Loot Level 58'), +(8561, 2, 1000159, 0, 5, 'Mossflayer Shadowhunter - World Loot Level 59'), +(8562, 1, 1000157, 0, 5, 'Mossflayer Cannibal - World Loot Level 57'), +(8562, 2, 1000158, 0, 5, 'Mossflayer Cannibal - World Loot Level 58'), +(8562, 3, 1000159, 0, 5, 'Mossflayer Cannibal - World Loot Level 59'), +(8563, 1, 1000158, 0, 5, 'Woodsman - World Loot Level 58'), +(8563, 2, 1000159, 0, 5, 'Woodsman - World Loot Level 59'), +(8564, 1, 1000159, 0, 5, 'Ranger - World Loot Level 59'), +(8564, 2, 1000160, 0, 5, 'Ranger - World Loot Level 60'), +(8565, 1, 1000157, 0, 5, 'Pathstrider - World Loot Level 57'), +(8565, 2, 1000158, 0, 5, 'Pathstrider - World Loot Level 58'), +(8566, 1, 1000147, 0, 5, 'Dark Iron Lookout - World Loot Level 47'), +(8566, 2, 1000148, 0, 5, 'Dark Iron Lookout - World Loot Level 48'), +(8636, 1, 1000150, 0, 5, 'Morta\'gya the Keeper - World Loot Level 50'), +(8637, 1, 1000144, 0, 5, 'Dark Iron Watchman - World Loot Level 44'), +(8637, 2, 1000145, 0, 5, 'Dark Iron Watchman - World Loot Level 45'), +(8917, 1, 1000146, 0, 5, 'Quarry Slave - World Loot Level 46'), +(8917, 2, 1000147, 0, 5, 'Quarry Slave - World Loot Level 47'), +(8917, 3, 1000148, 0, 5, 'Quarry Slave - World Loot Level 48'), +(8977, 1, 1000154, 0, 5, 'Krom\'Grul - World Loot Level 54'), +(9043, 1, 1000153, 0, 5, 'Scarshield Grunt - World Loot Level 53'), +(9043, 2, 1000154, 0, 5, 'Scarshield Grunt - World Loot Level 54'), +(9044, 1, 1000153, 0, 5, 'Scarshield Sentry - World Loot Level 53'), +(9044, 2, 1000154, 0, 5, 'Scarshield Sentry - World Loot Level 54'), +(9176, 1, 1000154, 0, 5, 'Gor\'tesh - World Loot Level 54'), +(9336, 1, 1000119, 0, 5, 'Boss Copperplug - World Loot Level 19'), +(9454, 1, 1000154, 0, 5, 'Xavathras - World Loot Level 54'), +(9462, 1, 1000156, 0, 5, 'Chieftain Bloodmaw - World Loot Level 56'), +(9464, 1, 1000150, 0, 5, 'Overlord Ror - World Loot Level 50'), +(9464, 2, 1000151, 0, 5, 'Overlord Ror - World Loot Level 51'), +(9517, 1, 1000157, 0, 5, 'Shadow Lord Fel\'dan - World Loot Level 57'), +(9518, 1, 1000156, 0, 5, 'Rakaiah - World Loot Level 56'), +(9860, 1, 1000154, 0, 5, 'Salia - World Loot Level 54'), +(9861, 1, 1000152, 0, 5, 'Moora - World Loot Level 52'), +(9862, 1, 1000155, 0, 5, 'Jaedenar Legionnaire - World Loot Level 55'), +(9877, 1, 1000155, 0, 5, 'Prince Xavalis - World Loot Level 55'), +(9916, 1, 1000146, 0, 5, 'Jarquia - World Loot Level 46'), +(10580, 1, 1000154, 0, 5, 'Fetid Zombie - World Loot Level 54'), +(10580, 2, 1000155, 0, 5, 'Fetid Zombie - World Loot Level 55'), +(10580, 3, 1000156, 0, 5, 'Fetid Zombie - World Loot Level 56'), +(10605, 1, 1000152, 0, 5, 'Scarlet Medic - World Loot Level 52'), +(10605, 2, 1000153, 0, 5, 'Scarlet Medic - World Loot Level 53'), +(10605, 3, 1000154, 0, 5, 'Scarlet Medic - World Loot Level 54'), +(10608, 1, 1000155, 0, 5, 'Scarlet Priest - World Loot Level 55'), +(10608, 2, 1000156, 0, 5, 'Scarlet Priest - World Loot Level 56'), +(10608, 3, 1000157, 0, 5, 'Scarlet Priest - World Loot Level 57'), +(10617, 1, 1000126, 0, 5, 'Galak Messenger - World Loot Level 26'), +(10648, 1, 1000155, 0, 5, 'Xavaric - World Loot Level 55'), +(10758, 1, 1000125, 0, 5, 'Grimtotem Bandit - World Loot Level 25'), +(10758, 2, 1000126, 0, 5, 'Grimtotem Bandit - World Loot Level 26'), +(10759, 1, 1000126, 0, 5, 'Grimtotem Stomper - World Loot Level 26'), +(10759, 2, 1000127, 0, 5, 'Grimtotem Stomper - World Loot Level 27'), +(10760, 1, 1000125, 0, 5, 'Grimtotem Geomancer - World Loot Level 25'), +(10760, 2, 1000126, 0, 5, 'Grimtotem Geomancer - World Loot Level 26'), +(10760, 3, 1000127, 0, 5, 'Grimtotem Geomancer - World Loot Level 27'), +(10761, 1, 1000128, 0, 5, 'Grimtotem Reaver - World Loot Level 28'), +(10801, 1, 1000154, 0, 5, 'Jabbering Ghoul - World Loot Level 54'), +(10802, 1, 1000151, 0, 5, 'Hitah\'ya the Keeper - World Loot Level 51'), +(10816, 1, 1000155, 0, 5, 'Wandering Skeleton - World Loot Level 55'), +(10896, 1, 1000129, 0, 5, 'Arnak Grimtotem - World Loot Level 29'), +(10916, 1, 1000156, 0, 5, 'Winterfall Runner - World Loot Level 56'), +(10916, 2, 1000157, 0, 5, 'Winterfall Runner - World Loot Level 57'), +(11290, 1, 1000153, 0, 5, 'Mossflayer Zombie - World Loot Level 53'), +(11290, 2, 1000154, 0, 5, 'Mossflayer Zombie - World Loot Level 54'), +(11291, 1, 1000154, 0, 5, 'Unliving Mossflayer - World Loot Level 54'), +(11291, 2, 1000155, 0, 5, 'Unliving Mossflayer - World Loot Level 55'), +(11440, 1, 1000153, 0, 5, 'Gordok Enforcer - World Loot Level 53'), +(11440, 2, 1000154, 0, 5, 'Gordok Enforcer - World Loot Level 54'), +(11442, 1, 1000153, 0, 5, 'Gordok Mauler - World Loot Level 53'), +(11442, 2, 1000154, 0, 5, 'Gordok Mauler - World Loot Level 54'), +(11443, 1, 1000152, 0, 5, 'Gordok Ogre-Mage - World Loot Level 52'), +(11443, 2, 1000153, 0, 5, 'Gordok Ogre-Mage - World Loot Level 53'), +(11516, 1, 1000153, 0, 5, 'Timbermaw Warder - World Loot Level 53'), +(11516, 2, 1000154, 0, 5, 'Timbermaw Warder - World Loot Level 54'), +(11552, 1, 1000152, 0, 5, 'Timbermaw Mystic - World Loot Level 52'), +(11552, 2, 1000153, 0, 5, 'Timbermaw Mystic - World Loot Level 53'), +(11552, 3, 1000154, 0, 5, 'Timbermaw Mystic - World Loot Level 54'), +(11559, 1, 1000139, 0, 5, 'Outcast Necromancer - World Loot Level 39'), +(11559, 2, 1000140, 0, 5, 'Outcast Necromancer - World Loot Level 40'), +(11561, 1, 1000137, 0, 5, 'Undead Ravager - World Loot Level 37'), +(11561, 2, 1000138, 0, 5, 'Undead Ravager - World Loot Level 38'), +(11611, 1, 1000157, 0, 5, 'Cavalier Durgen - World Loot Level 57'), +(11613, 1, 1000156, 0, 5, 'Huntsman Radley - World Loot Level 56'), +(11656, 1, 1000126, 0, 5, 'Warsong Peon - World Loot Level 26'), +(11656, 2, 1000127, 0, 5, 'Warsong Peon - World Loot Level 27'), +(11680, 1, 1000126, 0, 5, 'Horde Scout - World Loot Level 26'), +(11680, 2, 1000127, 0, 5, 'Horde Scout - World Loot Level 27'), +(11680, 3, 1000128, 0, 5, 'Horde Scout - World Loot Level 28'), +(11681, 1, 1000127, 0, 5, 'Horde Deforester - World Loot Level 27'), +(11681, 2, 1000128, 0, 5, 'Horde Deforester - World Loot Level 28'), +(11682, 1, 1000129, 0, 5, 'Warsong Grunt - World Loot Level 29'), +(11682, 2, 1000130, 0, 5, 'Warsong Grunt - World Loot Level 30'), +(11683, 1, 1000128, 0, 5, 'Warsong Shaman - World Loot Level 28'), +(11683, 2, 1000129, 0, 5, 'Warsong Shaman - World Loot Level 29'), +(11684, 1, 1000127, 0, 5, 'Warsong Shredder - World Loot Level 27'), +(11685, 1, 1000140, 0, 5, 'Maraudine Priest - World Loot Level 40'), +(11685, 2, 1000141, 0, 5, 'Maraudine Priest - World Loot Level 41'), +(11685, 3, 1000142, 0, 5, 'Maraudine Priest - World Loot Level 42'), +(11686, 1, 1000140, 0, 5, 'Ghostly Raider - World Loot Level 40'), +(11686, 2, 1000141, 0, 5, 'Ghostly Raider - World Loot Level 41'), +(11687, 1, 1000141, 0, 5, 'Ghostly Marauder - World Loot Level 41'), +(11687, 2, 1000142, 0, 5, 'Ghostly Marauder - World Loot Level 42'), +(11697, 1, 1000129, 0, 5, 'Mannoroc Lasher - World Loot Level 29'), +(11697, 2, 1000130, 0, 5, 'Mannoroc Lasher - World Loot Level 30'), +(11858, 1, 1000118, 0, 5, 'Grundig Darkcloud - World Loot Level 18'), +(11873, 1, 1000160, 0, 5, 'Spectral Attendant - World Loot Level 60'), +(11880, 1, 1000158, 0, 5, 'Twilight Avenger - World Loot Level 58'), +(11880, 2, 1000159, 0, 5, 'Twilight Avenger - World Loot Level 59'), +(11881, 1, 1000159, 0, 5, 'Twilight Geolord - World Loot Level 59'), +(11881, 2, 1000160, 0, 5, 'Twilight Geolord - World Loot Level 60'), +(11882, 1, 1000159, 0, 5, 'Twilight Stonecaller - World Loot Level 59'), +(11882, 2, 1000160, 0, 5, 'Twilight Stonecaller - World Loot Level 60'), +(11883, 1, 1000160, 0, 5, 'Twilight Master - World Loot Level 60'), +(11910, 1, 1000114, 0, 5, 'Grimtotem Ruffian - World Loot Level 14'), +(11910, 2, 1000115, 0, 5, 'Grimtotem Ruffian - World Loot Level 15'), +(11911, 1, 1000114, 0, 5, 'Grimtotem Mercenary - World Loot Level 14'), +(11911, 2, 1000115, 0, 5, 'Grimtotem Mercenary - World Loot Level 15'), +(11912, 1, 1000115, 0, 5, 'Grimtotem Brute - World Loot Level 15'), +(11912, 2, 1000116, 0, 5, 'Grimtotem Brute - World Loot Level 16'), +(11913, 1, 1000115, 0, 5, 'Grimtotem Sorcerer - World Loot Level 15'), +(11913, 2, 1000116, 0, 5, 'Grimtotem Sorcerer - World Loot Level 16'), +(11914, 1, 1000117, 0, 5, 'Gorehoof the Black - World Loot Level 17'), +(11915, 1, 1000116, 0, 5, 'Gogger Rock Keeper - World Loot Level 16'), +(11915, 2, 1000117, 0, 5, 'Gogger Rock Keeper - World Loot Level 17'), +(11917, 1, 1000116, 0, 5, 'Gogger Geomancer - World Loot Level 16'), +(11917, 2, 1000117, 0, 5, 'Gogger Geomancer - World Loot Level 17'), +(11918, 1, 1000117, 0, 5, 'Gogger Stonepounder - World Loot Level 17'), +(11918, 2, 1000118, 0, 5, 'Gogger Stonepounder - World Loot Level 18'), +(12046, 1, 1000149, 0, 5, 'Gor\'marok the Ravager - World Loot Level 49'), +(12178, 1, 1000155, 0, 5, 'Tortured Druid - World Loot Level 55'), +(12178, 2, 1000156, 0, 5, 'Tortured Druid - World Loot Level 56'), +(12179, 1, 1000156, 0, 5, 'Tortured Sentinel - World Loot Level 56'), +(12179, 2, 1000157, 0, 5, 'Tortured Sentinel - World Loot Level 57'), +(12199, 1, 1000158, 0, 5, 'Shade of Ambermoon - World Loot Level 58'), +(12248, 1, 1000160, 0, 5, 'Infiltrator Hameya - World Loot Level 60'), +(12250, 1, 1000155, 0, 5, 'Zaeldarr the Outcast - World Loot Level 55'), +(12262, 1, 1000158, 0, 5, 'Ziggurat Protector - World Loot Level 58'), +(12263, 1, 1000158, 0, 5, 'Slaughterhouse Protector - World Loot Level 58'), +(12322, 1, 1000160, 0, 5, 'Quel\'Lithien Protector - World Loot Level 60'), +(12579, 1, 1000126, 0, 5, 'Bloodfury Ripper - World Loot Level 26'), +(12676, 1, 1000031, 0, 5, 'Sharptalon - World Loot Level 31'), +(12856, 1, 1000123, 0, 5, 'Ashenvale Outrunner - World Loot Level 23'), +(12856, 2, 1000124, 0, 5, 'Ashenvale Outrunner - World Loot Level 24'), +(12865, 1, 1000135, 0, 5, 'Ambassador Malcin - World Loot Level 35'), +(12896, 1, 1000122, 0, 5, 'Silverwing Sentinel - World Loot Level 22'), +(12896, 2, 1000123, 0, 5, 'Silverwing Sentinel - World Loot Level 23'), +(12897, 1, 1000121, 0, 5, 'Silverwing Warrior - World Loot Level 21'), +(12897, 2, 1000122, 0, 5, 'Silverwing Warrior - World Loot Level 22'), +(13019, 1, 1000133, 0, 5, 'Burning Blade Seer - World Loot Level 33'), +(13157, 1, 1000112, 0, 5, 'Makasgar - World Loot Level 12'), +(14523, 1, 1000157, 0, 5, 'Ulathek - World Loot Level 57'), +(15201, 1, 1000160, 0, 5, 'Twilight Flamereaver - World Loot Level 60'), +(15202, 1, 1000161, 0, 5, 'Vyral the Vile - World Loot Level 61'), +(15213, 1, 1000160, 0, 5, 'Twilight Overlord - World Loot Level 60'), +(15213, 2, 1000161, 0, 5, 'Twilight Overlord - World Loot Level 61'), +(15407, 1, 1000111, 0, 5, 'Chieftain Zul\'Marosh - World Loot Level 11'), +(15408, 1, 1000110, 0, 5, 'Spearcrafter Otembe - World Loot Level 10'), +(15542, 1, 1000158, 0, 5, 'Twilight Marauder - World Loot Level 58'), +(15542, 2, 1000159, 0, 5, 'Twilight Marauder - World Loot Level 59'), +(15641, 1, 1000108, 0, 5, 'Amani Axe Thrower - World Loot Level 8'), +(15641, 2, 1000109, 0, 5, 'Amani Axe Thrower - World Loot Level 9'), +(15642, 1, 1000108, 0, 5, 'Amani Shadowpriest - World Loot Level 8'), +(15642, 2, 1000109, 0, 5, 'Amani Shadowpriest - World Loot Level 9'), +(15642, 3, 1000110, 0, 5, 'Amani Shadowpriest - World Loot Level 10'), +(15643, 1, 1000109, 0, 5, 'Amani Berserker - World Loot Level 9'), +(15643, 2, 1000110, 0, 5, 'Amani Berserker - World Loot Level 10'), +(15645, 1, 1000107, 0, 5, 'Wretched Thug - World Loot Level 7'), +(15645, 2, 1000108, 0, 5, 'Wretched Thug - World Loot Level 8'), +(15654, 1, 1000105, 0, 5, 'Plaguebone Pillager - World Loot Level 5'), +(15654, 2, 1000106, 0, 5, 'Plaguebone Pillager - World Loot Level 6'), +(15655, 1, 1000106, 0, 5, 'Rotlimb Cannibal - World Loot Level 6'), +(15655, 2, 1000107, 0, 5, 'Rotlimb Cannibal - World Loot Level 7'), +(15656, 1, 1000107, 0, 5, 'Angershade - World Loot Level 7'), +(15656, 2, 1000108, 0, 5, 'Angershade - World Loot Level 8'), +(15657, 1, 1000109, 0, 5, 'Darkwraith - World Loot Level 9'), +(15657, 2, 1000110, 0, 5, 'Darkwraith - World Loot Level 10'), +(15658, 1, 1000108, 0, 5, 'Rotlimb Marauder - World Loot Level 8'), +(15658, 2, 1000109, 0, 5, 'Rotlimb Marauder - World Loot Level 9'), +(15668, 1, 1000107, 0, 5, 'Grimscale Murloc - World Loot Level 7'), +(15668, 2, 1000108, 0, 5, 'Grimscale Murloc - World Loot Level 8'), +(15670, 1, 1000106, 0, 5, 'Grimscale Forager - World Loot Level 6'), +(15670, 2, 1000107, 0, 5, 'Grimscale Forager - World Loot Level 7'), +(15685, 1, 1000145, 0, 5, 'Southsea Kidnapper - World Loot Level 45'), +(15692, 1, 1000145, 0, 5, 'Dark Iron Kidnapper - World Loot Level 45'), +(15949, 1, 1000106, 0, 5, 'Thaelis the Hungerer - World Loot Level 6'), +(15965, 1, 1000110, 0, 5, 'Duskwither Apprentice - World Loot Level 10'), +(15968, 1, 1000106, 0, 5, 'Darnassian Scout - World Loot Level 6'), +(15968, 2, 1000107, 0, 5, 'Darnassian Scout - World Loot Level 7'), +(16162, 1, 1000106, 0, 5, 'Wretched Hooligan - World Loot Level 6'), +(16162, 2, 1000107, 0, 5, 'Wretched Hooligan - World Loot Level 7'), +(16247, 1, 1000120, 0, 5, 'Borgoth the Bloodletter - World Loot Level 20'), +(16248, 1, 1000120, 0, 5, 'Jurion the Deceiver - World Loot Level 20'), +(16249, 1, 1000120, 0, 5, 'Masophet the Black - World Loot Level 20'), +(16250, 1, 1000120, 0, 5, 'Mirdoran the Fallen - World Loot Level 20'), +(16294, 1, 1000108, 0, 5, 'Aldaron the Reckless - World Loot Level 8'), +(16300, 1, 1000109, 0, 5, 'Risen Creeper - World Loot Level 9'), +(16300, 2, 1000110, 0, 5, 'Risen Creeper - World Loot Level 10'), +(16301, 1, 1000113, 0, 5, 'Risen Hungerer - World Loot Level 13'), +(16301, 2, 1000114, 0, 5, 'Risen Hungerer - World Loot Level 14'), +(16302, 1, 1000116, 0, 5, 'Risen Stalker - World Loot Level 16'), +(16302, 2, 1000117, 0, 5, 'Risen Stalker - World Loot Level 17'), +(16303, 1, 1000110, 0, 5, 'Dreadbone Skeleton - World Loot Level 10'), +(16303, 2, 1000111, 0, 5, 'Dreadbone Skeleton - World Loot Level 11'), +(16305, 1, 1000117, 0, 5, 'Dreadbone Sentinel - World Loot Level 17'), +(16305, 2, 1000118, 0, 5, 'Dreadbone Sentinel - World Loot Level 18'), +(16307, 1, 1000109, 0, 5, 'Deathcage Scryer - World Loot Level 9'), +(16307, 2, 1000110, 0, 5, 'Deathcage Scryer - World Loot Level 10'), +(16307, 3, 1000111, 0, 5, 'Deathcage Scryer - World Loot Level 11'), +(16308, 1, 1000116, 0, 5, 'Deathcage Sorcerer - World Loot Level 16'), +(16308, 2, 1000117, 0, 5, 'Deathcage Sorcerer - World Loot Level 17'), +(16308, 3, 1000118, 0, 5, 'Deathcage Sorcerer - World Loot Level 18'), +(16309, 1, 1000112, 0, 5, 'Gangled Cannibal - World Loot Level 12'), +(16309, 2, 1000113, 0, 5, 'Gangled Cannibal - World Loot Level 13'), +(16311, 1, 1000112, 0, 5, 'Phantasmal Watcher - World Loot Level 12'), +(16311, 2, 1000113, 0, 5, 'Phantasmal Watcher - World Loot Level 13'), +(16311, 3, 1000114, 0, 5, 'Phantasmal Watcher - World Loot Level 14'), +(16314, 1, 1000115, 0, 5, 'Fallen Ranger - World Loot Level 15'), +(16315, 1, 1000114, 0, 5, 'Deatholme Acolyte - World Loot Level 14'), +(16315, 2, 1000115, 0, 5, 'Deatholme Acolyte - World Loot Level 15'), +(16317, 1, 1000118, 0, 5, 'Deatholme Necromancer - World Loot Level 18'), +(16317, 2, 1000119, 0, 5, 'Deatholme Necromancer - World Loot Level 19'), +(16318, 1, 1000117, 0, 5, 'Deatholme Darkmage - World Loot Level 17'), +(16318, 2, 1000118, 0, 5, 'Deatholme Darkmage - World Loot Level 18'), +(16320, 1, 1000119, 0, 5, 'Eye of Dar\'Khan - World Loot Level 19'), +(16320, 2, 1000120, 0, 5, 'Eye of Dar\'Khan - World Loot Level 20'), +(16321, 1, 1000118, 0, 5, 'Wailer - World Loot Level 18'), +(16321, 2, 1000119, 0, 5, 'Wailer - World Loot Level 19'), +(16322, 1, 1000110, 0, 5, 'Gangled Flesheater - World Loot Level 10'), +(16322, 2, 1000111, 0, 5, 'Gangled Flesheater - World Loot Level 11'), +(16323, 1, 1000112, 0, 5, 'Phantasmal Seeker - World Loot Level 12'), +(16323, 2, 1000113, 0, 5, 'Phantasmal Seeker - World Loot Level 13'), +(16323, 3, 1000114, 0, 5, 'Phantasmal Seeker - World Loot Level 14'), +(16325, 1, 1000110, 0, 5, 'Quel\'dorei Ghost - World Loot Level 10'), +(16325, 2, 1000111, 0, 5, 'Quel\'dorei Ghost - World Loot Level 11'), +(16326, 1, 1000111, 0, 5, 'Quel\'dorei Wraith - World Loot Level 11'), +(16327, 1, 1000111, 0, 5, 'Ravening Apparition - World Loot Level 11'), +(16327, 2, 1000112, 0, 5, 'Ravening Apparition - World Loot Level 12'), +(16328, 1, 1000112, 0, 5, 'Vengeful Apparition - World Loot Level 12'), +(16330, 1, 1000110, 0, 5, 'Sentinel Spy - World Loot Level 10'), +(16330, 2, 1000111, 0, 5, 'Sentinel Spy - World Loot Level 11'), +(16331, 1, 1000113, 0, 5, 'Darnassian Druid - World Loot Level 13'), +(16331, 2, 1000114, 0, 5, 'Darnassian Druid - World Loot Level 14'), +(16332, 1, 1000114, 0, 5, 'Darnassian Huntress - World Loot Level 14'), +(16332, 2, 1000115, 0, 5, 'Darnassian Huntress - World Loot Level 15'), +(16333, 1, 1000115, 0, 5, 'Sentinel Infiltrator - World Loot Level 15'), +(16333, 2, 1000116, 0, 5, 'Sentinel Infiltrator - World Loot Level 16'), +(16334, 1, 1000113, 0, 5, 'Blackpaw Gnoll - World Loot Level 13'), +(16334, 2, 1000114, 0, 5, 'Blackpaw Gnoll - World Loot Level 14'), +(16335, 1, 1000112, 0, 5, 'Blackpaw Scavenger - World Loot Level 12'), +(16335, 2, 1000113, 0, 5, 'Blackpaw Scavenger - World Loot Level 13'), +(16337, 1, 1000112, 0, 5, 'Blackpaw Shaman - World Loot Level 12'), +(16337, 2, 1000113, 0, 5, 'Blackpaw Shaman - World Loot Level 13'), +(16337, 3, 1000114, 0, 5, 'Blackpaw Shaman - World Loot Level 14'), +(16340, 1, 1000110, 0, 5, 'Shadowpine Ripper - World Loot Level 10'), +(16340, 2, 1000111, 0, 5, 'Shadowpine Ripper - World Loot Level 11'), +(16341, 1, 1000111, 0, 5, 'Shadowpine Witch - World Loot Level 11'), +(16341, 2, 1000112, 0, 5, 'Shadowpine Witch - World Loot Level 12'), +(16342, 1, 1000116, 0, 5, 'Mummified Headhunter - World Loot Level 16'), +(16342, 2, 1000117, 0, 5, 'Mummified Headhunter - World Loot Level 17'), +(16343, 1, 1000115, 0, 5, 'Shadowpine Oracle - World Loot Level 15'), +(16343, 2, 1000116, 0, 5, 'Shadowpine Oracle - World Loot Level 16'), +(16344, 1, 1000117, 0, 5, 'Shadowpine Headhunter - World Loot Level 17'), +(16344, 2, 1000118, 0, 5, 'Shadowpine Headhunter - World Loot Level 18'), +(16345, 1, 1000118, 0, 5, 'Shadowpine Catlord - World Loot Level 18'), +(16345, 2, 1000119, 0, 5, 'Shadowpine Catlord - World Loot Level 19'), +(16346, 1, 1000117, 0, 5, 'Shadowpine Hexxer - World Loot Level 17'), +(16346, 2, 1000118, 0, 5, 'Shadowpine Hexxer - World Loot Level 18'), +(16346, 3, 1000119, 0, 5, 'Shadowpine Hexxer - World Loot Level 19'), +(16469, 1, 1000117, 0, 5, 'Shadowpine Shadowcaster - World Loot Level 17'), +(16469, 2, 1000118, 0, 5, 'Shadowpine Shadowcaster - World Loot Level 18'), +(17115, 1, 1000137, 0, 5, 'Cursed Lost One - World Loot Level 37'), +(17115, 2, 1000138, 0, 5, 'Cursed Lost One - World Loot Level 38'), +(17183, 1, 1000107, 0, 5, 'Bristlelimb Furbolg - World Loot Level 7'), +(17183, 2, 1000108, 0, 5, 'Bristlelimb Furbolg - World Loot Level 8'), +(17184, 1, 1000107, 0, 5, 'Bristlelimb Windcaller - World Loot Level 7'), +(17184, 2, 1000108, 0, 5, 'Bristlelimb Windcaller - World Loot Level 8'), +(17184, 3, 1000109, 0, 5, 'Bristlelimb Windcaller - World Loot Level 9'), +(17185, 1, 1000108, 0, 5, 'Bristlelimb Ursa - World Loot Level 8'), +(17185, 2, 1000109, 0, 5, 'Bristlelimb Ursa - World Loot Level 9'), +(17186, 1, 1000108, 0, 5, 'Deranged Owlbeast - World Loot Level 8'), +(17186, 2, 1000109, 0, 5, 'Deranged Owlbeast - World Loot Level 9'), +(17187, 1, 1000108, 0, 5, 'Aberrant Owlbeast - World Loot Level 8'), +(17187, 2, 1000109, 0, 5, 'Aberrant Owlbeast - World Loot Level 9'), +(17187, 3, 1000110, 0, 5, 'Aberrant Owlbeast - World Loot Level 10'), +(17188, 1, 1000109, 0, 5, 'Raving Owlbeast - World Loot Level 9'), +(17188, 2, 1000110, 0, 5, 'Raving Owlbeast - World Loot Level 10'), +(17189, 1, 1000109, 0, 5, 'Crazed Wildkin - World Loot Level 9'), +(17189, 2, 1000110, 0, 5, 'Crazed Wildkin - World Loot Level 10'), +(17210, 1, 1000111, 0, 5, 'Sentinel Leader - World Loot Level 11'), +(17235, 1, 1000146, 0, 5, 'Witch Doctor Mai\'jin - World Loot Level 46'), +(17278, 1, 1000106, 0, 5, 'Venture Co. Saboteur - World Loot Level 6'), +(17278, 2, 1000107, 0, 5, 'Venture Co. Saboteur - World Loot Level 7'), +(17279, 1, 1000106, 0, 5, 'Venture Co. Gemologist - World Loot Level 6'), +(17279, 2, 1000107, 0, 5, 'Venture Co. Gemologist - World Loot Level 7'), +(17300, 1, 1000132, 0, 5, 'Gorgannon - World Loot Level 32'), +(17320, 1, 1000110, 0, 5, 'Bristlelimb Shaman - World Loot Level 10'), +(17320, 2, 1000111, 0, 5, 'Bristlelimb Shaman - World Loot Level 11'), +(17321, 1, 1000110, 0, 5, 'Bristlelimb Warrior - World Loot Level 10'), +(17321, 2, 1000111, 0, 5, 'Bristlelimb Warrior - World Loot Level 11'), +(17322, 1, 1000114, 0, 5, 'Infected Wildkin - World Loot Level 14'), +(17322, 2, 1000115, 0, 5, 'Infected Wildkin - World Loot Level 15'), +(17323, 1, 1000115, 0, 5, 'Contaminated Wildkin - World Loot Level 15'), +(17323, 2, 1000116, 0, 5, 'Contaminated Wildkin - World Loot Level 16'), +(17324, 1, 1000114, 0, 5, 'Irradiated Wildkin - World Loot Level 14'), +(17324, 2, 1000115, 0, 5, 'Irradiated Wildkin - World Loot Level 15'), +(17324, 3, 1000116, 0, 5, 'Irradiated Wildkin - World Loot Level 16'), +(17337, 1, 1000112, 0, 5, 'Nazzivus Satyr - World Loot Level 12'), +(17337, 2, 1000113, 0, 5, 'Nazzivus Satyr - World Loot Level 13'), +(17338, 1, 1000113, 0, 5, 'Nazzivus Rogue - World Loot Level 13'), +(17338, 2, 1000114, 0, 5, 'Nazzivus Rogue - World Loot Level 14'), +(17339, 1, 1000112, 0, 5, 'Nazzivus Felsworn - World Loot Level 12'), +(17339, 2, 1000113, 0, 5, 'Nazzivus Felsworn - World Loot Level 13'), +(17339, 3, 1000114, 0, 5, 'Nazzivus Felsworn - World Loot Level 14'), +(17340, 1, 1000115, 0, 5, 'Axxarien Shadowstalker - World Loot Level 15'), +(17340, 2, 1000116, 0, 5, 'Axxarien Shadowstalker - World Loot Level 16'), +(17341, 1, 1000116, 0, 5, 'Axxarien Trickster - World Loot Level 16'), +(17342, 1, 1000115, 0, 5, 'Axxarien Hellcaller - World Loot Level 15'), +(17342, 2, 1000116, 0, 5, 'Axxarien Hellcaller - World Loot Level 16'), +(17342, 3, 1000117, 0, 5, 'Axxarien Hellcaller - World Loot Level 17'), +(17448, 1, 1000111, 0, 5, 'Chieftain Oomooroo - World Loot Level 11'), +(17494, 1, 1000118, 0, 5, 'Zevrax - World Loot Level 18'), +(17524, 1, 1000113, 0, 5, 'Nazzivus Summoner - World Loot Level 13'), +(17528, 1, 1000114, 0, 5, 'Tzerak - World Loot Level 14'), +(17604, 1, 1000113, 0, 5, 'Sunhawk Spy - World Loot Level 13'), +(17604, 2, 1000114, 0, 5, 'Sunhawk Spy - World Loot Level 14'), +(17606, 1, 1000116, 0, 5, 'Sunhawk Reclaimer - World Loot Level 16'), +(17606, 2, 1000117, 0, 5, 'Sunhawk Reclaimer - World Loot Level 17'), +(17607, 1, 1000116, 0, 5, 'Sunhawk Defender - World Loot Level 16'), +(17607, 2, 1000117, 0, 5, 'Sunhawk Defender - World Loot Level 17'), +(17608, 1, 1000117, 0, 5, 'Sunhawk Pyromancer - World Loot Level 17'), +(17608, 2, 1000118, 0, 5, 'Sunhawk Pyromancer - World Loot Level 18'), +(17702, 1, 1000113, 0, 5, 'High Chief Bristlelimb - World Loot Level 13'), +(17714, 1, 1000116, 0, 5, 'Bloodcursed Voyager - World Loot Level 16'), +(17714, 2, 1000117, 0, 5, 'Bloodcursed Voyager - World Loot Level 17'), +(17878, 1, 1000160, 0, 5, 'Scourge Siege Engineer - World Loot Level 60'), +(23554, 1, 1000135, 0, 5, 'Risen Spirit - World Loot Level 35'), +(23554, 2, 1000136, 0, 5, 'Risen Spirit - World Loot Level 36'), +(23555, 1, 1000135, 0, 5, 'Risen Husk - World Loot Level 35'), +(23555, 2, 1000136, 0, 5, 'Risen Husk - World Loot Level 36'), +(23589, 1, 1000136, 0, 5, 'Defias Rummager - World Loot Level 36'), +(23589, 2, 1000137, 0, 5, 'Defias Rummager - World Loot Level 37'), +(23590, 1, 1000136, 0, 5, 'Defias Conjuror - World Loot Level 36'), +(23590, 2, 1000137, 0, 5, 'Defias Conjuror - World Loot Level 37'), +(23591, 1, 1000137, 0, 5, 'Defias Diver - World Loot Level 37'), +(23591, 2, 1000138, 0, 5, 'Defias Diver - World Loot Level 38'), +(23592, 1, 1000136, 0, 5, 'Grimtotem Breaker - World Loot Level 36'), +(23592, 2, 1000137, 0, 5, 'Grimtotem Breaker - World Loot Level 37'), +(23593, 1, 1000136, 0, 5, 'Grimtotem Spirit-Shifter - World Loot Level 36'), +(23593, 2, 1000137, 0, 5, 'Grimtotem Spirit-Shifter - World Loot Level 37'), +(23594, 1, 1000138, 0, 5, 'Grimtotem Destroyer - World Loot Level 38'), +(23594, 2, 1000139, 0, 5, 'Grimtotem Destroyer - World Loot Level 39'), +(23595, 1, 1000138, 0, 5, 'Grimtotem Earthbinder - World Loot Level 38'), +(23595, 2, 1000139, 0, 5, 'Grimtotem Earthbinder - World Loot Level 39'), +(23620, 1, 1000135, 0, 5, 'Privateer - World Loot Level 35'), +(23620, 2, 1000136, 0, 5, 'Privateer - World Loot Level 36'), +(23637, 1, 1000137, 0, 5, 'Deserter Lieutenant - World Loot Level 37'), +(23714, 1, 1000136, 0, 5, 'Grimtotem Elder - World Loot Level 36'), +(23714, 2, 1000137, 0, 5, 'Grimtotem Elder - World Loot Level 37'), +(24477, 1, 1000136, 0, 5, 'Syndicate Thief - World Loot Level 36'), +(24477, 2, 1000137, 0, 5, 'Syndicate Thief - World Loot Level 37'), +(24818, 1, 1000148, 0, 5, 'Anvilrage Taskmaster - World Loot Level 48'), +(24818, 2, 1000149, 0, 5, 'Anvilrage Taskmaster - World Loot Level 49'), +(24819, 1, 1000149, 0, 5, 'Anvilrage Enforcer - World Loot Level 49'), +(24819, 2, 1000150, 0, 5, 'Anvilrage Enforcer - World Loot Level 50'); + +-- Those that shouldn't drop anything from what I noticed +DELETE FROM `creature_loot_template` WHERE (`Entry` IN (2058, 3661, 3692, 3994, 10637, 499, 1949, 7843, 19759)); +UPDATE `creature_template` SET `lootid` = 0 WHERE (`entry` IN (2058, 3661, 3692, 3994, 10637, 499, 1949, 7843, 19759)); + +-- Clear some trash +DELETE FROM `creature_loot_template` WHERE (`Entry` = 822) AND (`Item` IN (159, 787, 2589, 4536, 4540, 4604, 4656)); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 547) AND (`Item` IN (414, 1179, 2287, 2589, 4537, 4541, 4605, 5498)); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 565) AND (`Item` IN (422, 1205, 2592, 3770, 4538, 4542, 4606)); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 628) AND (`Item` IN (422, 1205, 2592, 3770, 4538, 4542, 4606, 4632)); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 686) AND (`Item` IN (1708, 3771, 4306, 4539, 4544, 4634, 4636)); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 922) AND (`Item` IN (1645, 4306, 4599, 4636, 4637)); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 930) AND (`Item` IN (422, 1205, 2592, 3770, 4538, 4542, 4593, 4606, 4632)); +-- There are a lot... + +-- Rares +DELETE FROM `creature_loot_template` WHERE +`Reference` IN (1002125,1012425,1022425,1032425,1052130,1062029,1071930,1080003,1080016,1000610,1010506,1050110,1070518,1080001,1080013,1001115,1011112,1021112,1051120,1061019,1080002,1080014,1010607,1020608,1010809,1020809,1010910,1020910,1012122,1022122,1032122,1010808,1011111,1021111,1011010,1021010,1003140,1023940,1033940,1043840,1053140,1064049,1073545,1080004,1080020,1001620,1011718,1021718,1080015,1011212,1021212,1011415,1021415,1011011,1021011,1011616,1021616,1011414,1021414,1011516,1021516,1011920,1021920,1031820,1011213,1021213,1011819,1021819,1011617,1021617,1012324,1022324,1032324,1012223,1022223,1032223,1002630,1022829,1032829,1080018,1023030,1033030,1063039,1022627,1032627,1080017,1022930,1032930,1012323,1022323,1032323,1023232,1033232,1080019,1010909,1020909,1012424,1022424,1032424,1010707,1012020,1022020,1022626,1032626,1012525,1022526,1032526,1010708,1012021,1022021,1032021,1022929,1032929,1011515,1021515,1023131,1033131,1011818,1021818,1011919,1021919,1022728,1032728,1023434,1033434,1022727,1032727,1023334,1033334,1023435,1033435,1011314,1021314,1023637,1033637,1023737,1033737,1004150,1024142,1034142,1044142,1054162,1080005,1080021,1024444,1034444,1044444,1024041,1034041,1044041,1024242,1034242,1044242,1024344,1034344,1044344,1024545,1034545,1044545,1023031,1033031,1023233,1033233,1023738,1033738,1023536,1033536,1023132,1033132,1024040,1034040,1024343,1034343,1044343,1024141,1034141,1044141,1024243,1034243,1044243,1023939,1033939,1023839,1033839,1023838,1033838,1005163,1025051,1035051,1045051,1065054,1075062,1080007,1080022,1025050,1035050,1045050,1025353,1035353,1045353,1023636,1033636,1024747,1034747,1044747,1080006,1011717,1021717,1012222,1022222,1032222,1012121,1022121,1032121,1011313,1021313,1025152,1035152,1045152,1025455,1035455,1045455,1065562,1025657,1035657,1045657,1025556,1035556,1045556,1025151,1035151,1045151,1025757,1035757,1045757,1025354,1035354,1045354,1025253,1035253,1045253,1026060,1036060,1046060,1025858,1035858,1045858,1025959,1035959,1045959,1025252,1035252,1045252,1025656,1035656,1045656,1026262,1036262,1046262,1025555,1035555,1045555,1025859,1035859,1045859,1023535,1033535,1023333,1033333,1022525,1032525,1024445,1034445,1044445,1024646,1034646,1044646,1024546,1034546,1044546,1024647,1034647,1044647,1024748,1034748,1044748,1024849,1034849,1044849,1024950,1034950,1044950,1010606,1022828,1032828,1025758,1035758,1045758,1024848,1034848,1044848,1024949,1034949,1044949,1025454,1035454,1045454,1025960,1035960,1045960,1026161,1036161,1046161,1026061,1036061,1046061) +AND `Entry` IN (61,79,99,100,462,471,472,503,506,507,519,520,521,534,572,573,574,584,596,599,616,763,771,947,1037,1063,1106,1112,1119,1130,1132,1137,1140,1260,1398,1399,1424,1425,1531,1533,1552,1837,1844,1847,1848,1851,1885,1910,1911,1920,1936,1944,1948,2090,2108,2172,2175,2184,2186,2191,2192,2258,2283,2452,2453,2476,2541,2600,2603,2604,2605,2606,2609,2744,2751,2752,2753,2779,2850,3056,3068,3253,3295,3470,3535,3581,3652,3672,3735,3773,3792,4015,4030,4066,4132,4380,5343,5345,5346,5347,5349,5350,5352,5354,5356,5399,5400,5786,5787,5807,5808,5809,5823,5826,5829,5832,5834,5835,5836,5837,5838,5847,5848,5849,5863,5865,5928,5933,6118,6581,6582,6585,6647,6648,6649,6650,6651,6652,7015,7016,7017,7895,8201,8202,8203,8204,8205,8207,8208,8210,8211,8212,8213,8214,8216,8218,8219,8277,8278,8279,8280,8281,8283,8296,8297,8298,8299,8300,8301,8302,8303,8304,8503,8660,8924,8978,8979,8981,9046,9602,9604,10077,10078,10197,10199,10200,10356,10357,10358,10359,10559,10639,10640,10641,10642,10643,10644,10647,10817,10821,10822,10823,10824,10825,10826,10827,11688,12037,12431,12432,12433,14221,14222,14223,14224,14225,14226,14227,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14266,14268,14269,14270,14271,14272,14273,14276,14277,14278,14279,14280,14281,14339,14340,14342,14343,14344,14345,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14446,14447,14448,14472,14476,14477,14478,14479,14487,14488,14490,14491,14492,18241); + +-- Should Rares drop greys and possibly extra loot? Idk. But just remove these if not. +DELETE FROM `creature_loot_template` WHERE `Entry` IN (61,79,99,100,462,471,472,503,506,507,519,520,521,534,572,573,574,584,596,599,616,763,771,947,1037,1063,1106,1112,1119,1130,1132,1137,1140,1260,1398,1399,1424,1425,1531,1533,1552,1837,1844,1847,1848,1851,1885,1910,1911,1920,1936,1944,1948,2090,2108,2172,2175,2184,2186,2191,2192,2258,2283,2452,2453,2476,2541,2600,2603,2604,2605,2606,2609,2744,2751,2752,2753,2779,2850,3056,3068,3253,3295,3470,3535,3581,3652,3672,3735,3773,3792,4015,4030,4066,4132,4380,5343,5345,5346,5347,5349,5350,5352,5354,5356,5399,5400,5786,5787,5807,5808,5809,5823,5826,5829,5832,5834,5835,5836,5837,5838,5847,5848,5849,5863,5865,5928,5933,6118,6581,6582,6585,6647,6648,6649,6650,6651,6652,7015,7016,7017,7895,8201,8202,8203,8204,8205,8207,8208,8210,8211,8212,8213,8214,8216,8218,8219,8277,8278,8279,8280,8281,8283,8296,8297,8298,8299,8300,8301,8302,8303,8304,8503,8660,8924,8978,8979,8981,9046,9602,9604,10077,10078,10197,10199,10200,10356,10357,10358,10359,10559,10639,10640,10641,10642,10643,10644,10647,10817,10821,10822,10823,10824,10825,10826,10827,11688,12037,12431,12432,12433,14221,14222,14223,14224,14225,14226,14227,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14266,14268,14269,14270,14271,14272,14273,14276,14277,14278,14279,14280,14281,14339,14340,14342,14343,14344,14345,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14446,14447,14448,14472,14476,14477,14478,14479,14487,14488,14490,14491,14492,18241) +AND ( +`Reference` BETWEEN 1000005 AND 1000063 OR +`Reference` BETWEEN 1000105 AND 1000163 OR +`Reference` IN (1000105,1000610,1001115,1001620,1002125,1002630,1003140,1004150,1005163,1010708,1010809,1010910,1011011,1011112,1011213,1011314,1011415,1011822,1011923,1012024,1012125,1020812,1021014,1021115,1021216,1021317,1021418,1021519,1021620,1021721,1021822,1021923,1022024,1022125,1022226,1022327,1022428,1022529,1022630,1022731,1022832,1022933,1023034,1023135,1023236,1023337,1023438,1023539,1023640,1023741,1023842,1023943,1024044,1024145,1024246,1024347,1024448,1024549,1024650,1024751,1024852,1024953,1025054,1025155,1025256,1025357,1025458,1025559,1025660,1025761,1025862,1025963,1026063,1026163,1026263,1031922,1032023,1032124,1032225,1032326,1032427,1032528,1032629,1032730,1032831,1032932,1033033,1033134,1033235,1033336,1033437,1033538,1033639,1033740,1033841,1033942,1034043,1034144,1034245,1034346,1034447,1034548,1034649,1034750,1034851,1034952,1035053,1035154,1035255,1035356,1035457,1035558,1035659,1035760,1035861,1035963,1044046,1044248,1044450,1044652,1044854,1045056,1045258,1045460,1045662,1045863,1046063,1050614,1051525,1052635,1053650,1055163,1060610,1061120,1062130,1063140,1064150,1065155,1065663,1070610,1071114,1071519,1072025,1072627,1072830,1073135,1073640,1074145,1074650,1075061,1075063,1075155,1075660,1076163,1080620,1081225,1081630,1082035,1082640,1083045,1083650,1084055,1084660,1085063,1085063,1086163,1090110,1091120,1092130,1093140,1094150,1095162,1100105,1105865,1106672,1125860,1125961,1126062,1126163,1126264,1126365,1126466,1126567,1126668,1126769,1126870,1126971,1127072,1127173,1135861,1135962,1136063,1136164,1136265,1136366,1136467,1136568,1136669,1136770,1136873,1146773,1155873,1165864,1166573,1176571,1176573,1186165,1186673) +); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(61, 1, 1000111, 0, 5, 'Thuros Lightfingers - World Loot Level 11'), +(79, 1, 1000110, 0, 5, 'Narg the Taskmaster - World Loot Level 10'), +(99, 1, 1000110, 0, 5, 'Morgaine the Sly - World Loot Level 10'), +(100, 1, 1000112, 0, 5, 'Gruff Swiftbite - World Loot Level 12'), +(462, 1, 1000026, 0, 5, 'Vultros - World Loot Level 26'), +(471, 1, 1000010, 0, 5, 'Mother Fang - World Loot Level 10'), +(472, 1, 1000112, 0, 5, 'Fedfennel - World Loot Level 12'), +(503, 1, 1000131, 0, 5, 'Lord Malathrom - World Loot Level 31'), +(506, 1, 1000118, 0, 5, 'Sergeant Brashclaw - World Loot Level 18'), +(507, 1, 1000132, 0, 5, 'Fenros - World Loot Level 32'), +(519, 1, 1000115, 0, 5, 'Slark - World Loot Level 15'), +(520, 1, 1000119, 0, 5, 'Brack - World Loot Level 19'), +(521, 1, 1000023, 0, 5, 'Lupos - World Loot Level 23'), +(534, 1, 1000134, 0, 5, 'Nefaru - World Loot Level 34'), +(572, 1, 1000119, 0, 5, 'Leprithus - World Loot Level 19'), +(573, 1, 1000020, 0, 5, 'Foe Reaper 4000 - World Loot Level 20'), +(574, 1, 1000027, 0, 5, 'Naraxis - World Loot Level 27'), +(584, 1, 1000127, 0, 5, 'Kazon - World Loot Level 27'), +(596, 1, 1000118, 0, 5, 'Brainwashed Noble - World Loot Level 18'), +(599, 1, 1000118, 0, 5, 'Marisa du\'Paige - World Loot Level 18'), +(616, 1, 1000023, 0, 5, 'Chatter - World Loot Level 23'), +(763, 1, 1000139, 0, 5, 'Lost One Chieftain - World Loot Level 39'), +(771, 1, 1000132, 0, 5, 'Commander Felstrom - World Loot Level 32'), +(947, 1, 1000126, 0, 5, 'Rohh the Silent - World Loot Level 26'), +(1037, 1, 1000124, 0, 5, 'Dragonmaw Battlemaster - World Loot Level 24'), +(1037, 2, 1000125, 0, 5, 'Dragonmaw Battlemaster - World Loot Level 25'), +(1063, 1, 1000047, 0, 5, 'Jade - World Loot Level 47'), +(1106, 1, 1000137, 0, 5, 'Lost One Cook - World Loot Level 37'), +(1112, 1, 1000024, 0, 5, 'Leech Widow - World Loot Level 24'), +(1119, 1, 1000112, 0, 5, 'Hammerspine - World Loot Level 12'), +(1130, 1, 1000012, 0, 5, 'Bjarn - World Loot Level 12'), +(1132, 1, 1000010, 0, 5, 'Timber - World Loot Level 10'), +(1137, 1, 1000109, 0, 5, 'Edan the Howler - World Loot Level 9'), +(1140, 1, 1000031, 0, 5, 'Razormaw Matriarch - World Loot Level 31'), +(1260, 1, 1000111, 0, 5, 'Great Father Arctikus - World Loot Level 11'), +(1398, 1, 1000122, 0, 5, 'Boss Galgosh - World Loot Level 22'), +(1399, 1, 1000121, 0, 5, 'Magosh - World Loot Level 21'), +(1424, 1, 1000115, 0, 5, 'Master Digger - World Loot Level 15'), +(1425, 1, 1000115, 0, 5, 'Grizlak - World Loot Level 15'), +(1531, 1, 1000106, 0, 5, 'Lost Soul - World Loot Level 6'), +(1531, 2, 1000107, 0, 5, 'Lost Soul - World Loot Level 7'), +(1533, 1, 1000108, 0, 5, 'Tormented Spirit - World Loot Level 8'), +(1533, 2, 1000109, 0, 5, 'Tormented Spirit - World Loot Level 9'), +(1552, 1, 1000145, 0, 5, 'Scale Belly - World Loot Level 45'), +(1837, 1, 1000160, 0, 5, 'Scarlet Judge - World Loot Level 60'), +(1844, 1, 1000158, 0, 5, 'Foreman Marcrid - World Loot Level 58'), +(1847, 1, 1000152, 0, 5, 'Foulmane - World Loot Level 52'), +(1848, 1, 1000156, 0, 5, 'Lord Maldazzar - World Loot Level 56'), +(1851, 1, 1000162, 0, 5, 'The Husk - World Loot Level 62'), +(1885, 1, 1000158, 0, 5, 'Scarlet Smith - World Loot Level 58'), +(1885, 2, 1000159, 0, 5, 'Scarlet Smith - World Loot Level 59'), +(1910, 1, 1000110, 0, 5, 'Muad - World Loot Level 10'), +(1911, 1, 1000112, 0, 5, 'Deeb - World Loot Level 12'), +(1920, 1, 1000121, 0, 5, 'Dalaran Spellscribe - World Loot Level 21'), +(1936, 1, 1000108, 0, 5, 'Farmer Solliden - World Loot Level 8'), +(1944, 1, 1000122, 0, 5, 'Rot Hide Bruiser - World Loot Level 22'), +(1948, 1, 1000123, 0, 5, 'Snarlmane - World Loot Level 23'), +(2090, 1, 1000123, 0, 5, 'Ma\'ruk Wyrmscale - World Loot Level 23'), +(2108, 1, 1000129, 0, 5, 'Garneg Charskull - World Loot Level 29'), +(2172, 1, 1000020, 0, 5, 'Strider Clutchmother - World Loot Level 20'), +(2175, 1, 1000013, 0, 5, 'Shadowclaw - World Loot Level 13'), +(2184, 1, 1000117, 0, 5, 'Lady Moongazer - World Loot Level 17'), +(2186, 1, 1000116, 0, 5, 'Carnivous the Breaker - World Loot Level 16'), +(2191, 1, 1000114, 0, 5, 'Licillin - World Loot Level 14'), +(2192, 1, 1000119, 0, 5, 'Firecaller Radison - World Loot Level 19'), +(2258, 1, 1000037, 0, 5, 'Stone Fury - World Loot Level 37'), +(2283, 1, 1000122, 0, 5, 'Ravenclaw Regent - World Loot Level 22'), +(2452, 1, 1000136, 0, 5, 'Skhowl - World Loot Level 36'), +(2453, 1, 1000139, 0, 5, 'Lo\'Grosh - World Loot Level 39'), +(2476, 1, 1000022, 0, 5, 'Large Loch Crocolisk - World Loot Level 22'), +(2541, 1, 1000145, 0, 5, 'Lord Sakrasis - World Loot Level 45'), +(2600, 1, 1000134, 0, 5, 'Singer - World Loot Level 34'), +(2603, 1, 1000136, 0, 5, 'Kovork - World Loot Level 36'), +(2604, 1, 1000139, 0, 5, 'Molok the Crusher - World Loot Level 39'), +(2605, 1, 1000140, 0, 5, 'Zalas Witherbark - World Loot Level 40'), +(2606, 1, 1000137, 0, 5, 'Nimar the Slayer - World Loot Level 37'), +(2609, 1, 1000140, 0, 5, 'Geomancer Flintdagger - World Loot Level 40'), +(2744, 1, 1000140, 0, 5, 'Shadowforge Commander - World Loot Level 40'), +(2751, 1, 1000036, 0, 5, 'War Golem - World Loot Level 36'), +(2752, 1, 1000045, 0, 5, 'Rumbler - World Loot Level 45'), +(2753, 1, 1000038, 0, 5, 'Barnabus - World Loot Level 38'), +(2779, 1, 1000141, 0, 5, 'Prince Nazjak - World Loot Level 41'), +(2850, 1, 1000037, 0, 5, 'Broken Tooth - World Loot Level 37'), +(3056, 1, 1000012, 0, 5, 'Ghost Howl - World Loot Level 12'), +(3068, 1, 1000009, 0, 5, 'Mazzranache - World Loot Level 9'), +(3253, 1, 1000024, 0, 5, 'Silithid Harvester - World Loot Level 24'), +(3295, 1, 1000119, 0, 5, 'Sludge Beast - World Loot Level 19'), +(3470, 1, 1000115, 0, 5, 'Rathorian - World Loot Level 15'), +(3535, 1, 1000113, 0, 5, 'Blackmoss the Fetid - World Loot Level 13'), +(3652, 1, 1000017, 0, 5, 'Trigore the Lasher - World Loot Level 17'), +(3672, 1, 1000117, 0, 5, 'Boahn - World Loot Level 17'), +(3735, 1, 1000122, 0, 5, 'Apothecary Falthis - World Loot Level 22'), +(3773, 1, 1000126, 0, 5, 'Akkrilus - World Loot Level 26'), +(3792, 1, 1000031, 0, 5, 'Terrowulf Packlord - World Loot Level 31'), +(3792, 2, 1000032, 0, 5, 'Terrowulf Packlord - World Loot Level 32'), +(4015, 1, 1000025, 0, 5, 'Pridewing Patriarch - World Loot Level 25'), +(4030, 1, 1000129, 0, 5, 'Vengeful Ancient - World Loot Level 29'), +(4030, 2, 1000130, 0, 5, 'Vengeful Ancient - World Loot Level 30'), +(4066, 1, 1000030, 0, 5, 'Nal\'taszar - World Loot Level 30'), +(4132, 1, 1000036, 0, 5, 'Silithid Ravager - World Loot Level 36'), +(4380, 1, 1000038, 0, 5, 'Darkmist Widow - World Loot Level 38'), +(5343, 1, 1000146, 0, 5, 'Lady Szallah - World Loot Level 46'), +(5345, 1, 1000145, 0, 5, 'Diamond Head - World Loot Level 45'), +(5346, 1, 1000148, 0, 5, 'Bloodroar the Stalker - World Loot Level 48'), +(5347, 1, 1000048, 0, 5, 'Antilus the Soarer - World Loot Level 48'), +(5349, 1, 1000049, 0, 5, 'Arash-ethis - World Loot Level 49'), +(5350, 1, 1000047, 0, 5, 'Qirot - World Loot Level 47'), +(5352, 1, 1000043, 0, 5, 'Old Grizzlegut - World Loot Level 43'), +(5354, 1, 1000144, 0, 5, 'Gnarl Leafbrother - World Loot Level 44'), +(5356, 1, 1000042, 0, 5, 'Snarler - World Loot Level 42'), +(5399, 1, 1000148, 0, 5, 'Veyzhak the Cannibal - World Loot Level 48'), +(5400, 1, 1000148, 0, 5, 'Zekkis - World Loot Level 48'), +(5786, 1, 1000109, 0, 5, 'Snagglespear - World Loot Level 9'), +(5787, 1, 1000111, 0, 5, 'Enforcer Emilgund - World Loot Level 11'), +(5807, 1, 1000010, 0, 5, 'The Rake - World Loot Level 10'), +(5808, 1, 1000109, 0, 5, 'Warlord Kolkanis - World Loot Level 9'), +(5809, 1, 1000109, 0, 5, 'Watch Commander Zalaphil - World Loot Level 9'), +(5823, 1, 1000011, 0, 5, 'Death Flayer - World Loot Level 11'), +(5826, 1, 1000109, 0, 5, 'Geolord Mottle - World Loot Level 9'), +(5829, 1, 1000017, 0, 5, 'Snort the Heckler - World Loot Level 17'), +(5832, 1, 1000024, 0, 5, 'Thunderstomp - World Loot Level 24'), +(5834, 1, 1000025, 0, 5, 'Azzere the Skyblade - World Loot Level 25'), +(5835, 1, 1000118, 0, 5, 'Foreman Grills - World Loot Level 18'), +(5836, 1, 1000119, 0, 5, 'Engineer Whirleygig - World Loot Level 19'), +(5837, 1, 1000115, 0, 5, 'Stonearm - World Loot Level 15'), +(5838, 1, 1000117, 0, 5, 'Brokespear - World Loot Level 17'), +(5847, 1, 1000124, 0, 5, 'Heggin Stonewhisker - World Loot Level 24'), +(5848, 1, 1000125, 0, 5, 'Malgin Barleybrew - World Loot Level 25'), +(5849, 1, 1000124, 0, 5, 'Digger Flameforge - World Loot Level 24'), +(5863, 1, 1000119, 0, 5, 'Geopriest Gukk\'rok - World Loot Level 19'), +(5865, 1, 1000013, 0, 5, 'Dishu - World Loot Level 13'), +(5928, 1, 1000027, 0, 5, 'Sorrow Wing - World Loot Level 27'), +(5933, 1, 1000131, 0, 5, 'Achellios the Banished - World Loot Level 31'), +(6118, 1, 1000148, 0, 5, 'Varo\'then\'s Ghost - World Loot Level 48'), +(6581, 1, 1000050, 0, 5, 'Ravasaur Matriarch - World Loot Level 50'), +(6582, 1, 1000054, 0, 5, 'Clutchmother Zavas - World Loot Level 54'), +(6585, 1, 1000052, 0, 5, 'Uhk\'loc - World Loot Level 52'), +(6585, 2, 1000053, 0, 5, 'Uhk\'loc - World Loot Level 53'), +(6647, 1, 1000151, 0, 5, 'Magister Hawkhelm - World Loot Level 51'), +(6647, 2, 1000152, 0, 5, 'Magister Hawkhelm - World Loot Level 52'), +(6648, 1, 1000050, 0, 5, 'Antilos - World Loot Level 50'), +(6649, 1, 1000151, 0, 5, 'Lady Sesspira - World Loot Level 51'), +(6650, 1, 1000150, 0, 5, 'General Fangferror - World Loot Level 50'), +(6650, 2, 1000151, 0, 5, 'General Fangferror - World Loot Level 51'), +(6651, 1, 1000149, 0, 5, 'Gatekeeper Rageroar - World Loot Level 49'), +(6651, 2, 1000150, 0, 5, 'Gatekeeper Rageroar - World Loot Level 50'), +(6652, 1, 1000151, 0, 5, 'Master Feardred - World Loot Level 51'), +(6652, 2, 1000152, 0, 5, 'Master Feardred - World Loot Level 52'), +(7015, 1, 1000116, 0, 5, 'Flagglemurk the Cruel - World Loot Level 16'), +(7016, 1, 1000122, 0, 5, 'Lady Vespira - World Loot Level 22'), +(7017, 1, 1000115, 0, 5, 'Lord Sinslayer - World Loot Level 15'), +(7017, 2, 1000116, 0, 5, 'Lord Sinslayer - World Loot Level 16'), +(7895, 1, 1000135, 0, 5, 'Ambassador Bloodrage - World Loot Level 35'), +(8201, 1, 1000150, 0, 5, 'Omgorn the Lost - World Loot Level 50'), +(8202, 1, 1000148, 0, 5, 'Cyclok the Mad - World Loot Level 48'), +(8203, 1, 1000147, 0, 5, 'Kregg Keelhaul - World Loot Level 47'), +(8204, 1, 1000050, 0, 5, 'Soriid the Devourer - World Loot Level 50'), +(8205, 1, 1000050, 0, 5, 'Haarka the Ravenous - World Loot Level 50'), +(8207, 1, 1000046, 0, 5, 'Greater Firebird - World Loot Level 46'), +(8208, 1, 1000043, 0, 5, 'Murderous Blisterpaw - World Loot Level 43'), +(8210, 1, 1000144, 0, 5, 'Razortalon - World Loot Level 44'), +(8211, 1, 1000042, 0, 5, 'Old Cliff Jumper - World Loot Level 42'), +(8212, 1, 1000049, 0, 5, 'The Reak - World Loot Level 49'), +(8213, 1, 1000051, 0, 5, 'Ironback - World Loot Level 51'), +(8214, 1, 1000149, 0, 5, 'Jalinde Summerdrake - World Loot Level 49'), +(8216, 1, 1000148, 0, 5, 'Retherokk the Berserker - World Loot Level 48'), +(8218, 1, 1000145, 0, 5, 'Witherheart the Stalker - World Loot Level 45'), +(8219, 1, 1000143, 0, 5, 'Zul\'arek Hatefowler - World Loot Level 43'), +(8277, 1, 1000048, 0, 5, 'Rekk\'tilac - World Loot Level 48'), +(8278, 1, 1000050, 0, 5, 'Smoldar - World Loot Level 50'), +(8279, 1, 1000046, 0, 5, 'Faulty War Golem - World Loot Level 46'), +(8280, 1, 1000047, 0, 5, 'Shleipnarr - World Loot Level 47'), +(8281, 1, 1000049, 0, 5, 'Scald - World Loot Level 49'), +(8283, 1, 1000150, 0, 5, 'Slave Master Blackheart - World Loot Level 50'), +(8296, 1, 1000148, 0, 5, 'Mojo the Twisted - World Loot Level 48'), +(8297, 1, 1000156, 0, 5, 'Magronos the Unyielding - World Loot Level 56'), +(8298, 1, 1000154, 0, 5, 'Akubar the Seer - World Loot Level 54'), +(8299, 1, 1000052, 0, 5, 'Spiteflayer - World Loot Level 52'), +(8300, 1, 1000051, 0, 5, 'Ravage - World Loot Level 51'), +(8301, 1, 1000053, 0, 5, 'Clack the Reaver - World Loot Level 53'), +(8302, 1, 1000049, 0, 5, 'Deatheye - World Loot Level 49'), +(8303, 1, 1000050, 0, 5, 'Grunter - World Loot Level 50'), +(8304, 1, 1000157, 0, 5, 'Dreadscorn - World Loot Level 57'), +(8503, 1, 1000111, 0, 5, 'Gibblewilt - World Loot Level 11'), +(8660, 1, 1000048, 0, 5, 'The Evalcharr - World Loot Level 48'), +(8924, 1, 1000150, 0, 5, 'The Behemoth - World Loot Level 50'), +(8978, 1, 1000157, 0, 5, 'Thauris Balgarr - World Loot Level 57'), +(8979, 1, 1000159, 0, 5, 'Gruklash - World Loot Level 59'), +(8981, 1, 1000056, 0, 5, 'Malfunctioning Reaver - World Loot Level 56'), +(9046, 1, 1000155, 0, 5, 'Scarshield Quartermaster - World Loot Level 55'), +(9602, 1, 1000154, 0, 5, 'Hahk\'Zor - World Loot Level 54'), +(9604, 1, 1000154, 0, 5, 'Gorgon\'och - World Loot Level 54'), +(10077, 1, 1000053, 0, 5, 'Deathmaw - World Loot Level 53'), +(10078, 1, 1000155, 0, 5, 'Terrorspark - World Loot Level 55'), +(10197, 1, 1000155, 0, 5, 'Mezzir the Howler - World Loot Level 55'), +(10199, 1, 1000159, 0, 5, 'Grizzle Snowpaw - World Loot Level 59'), +(10200, 1, 1000057, 0, 5, 'Rak\'shiri - World Loot Level 57'), +(10356, 1, 1000010, 0, 5, 'Bayne - World Loot Level 10'), +(10357, 1, 1000011, 0, 5, 'Ressan the Needler - World Loot Level 11'), +(10358, 1, 1000112, 0, 5, 'Fellicent\'s Shade - World Loot Level 12'), +(10359, 1, 1000013, 0, 5, 'Sri\'skulk - World Loot Level 13'), +(10559, 1, 1000122, 0, 5, 'Lady Vespia - World Loot Level 22'), +(10639, 1, 1000125, 0, 5, 'Rorgish Jowl - World Loot Level 25'), +(10640, 1, 1000127, 0, 5, 'Oakpaw - World Loot Level 27'), +(10641, 1, 1000125, 0, 5, 'Branch Snapper - World Loot Level 25'), +(10642, 1, 1000027, 0, 5, 'Eck\'alom - World Loot Level 27'), +(10643, 1, 1000123, 0, 5, 'Mugglefin - World Loot Level 23'), +(10644, 1, 1000022, 0, 5, 'Mist Howler - World Loot Level 22'), +(10647, 1, 1000132, 0, 5, 'Prince Raze - World Loot Level 32'), +(10817, 1, 1000155, 0, 5, 'Duggan Wildhammer - World Loot Level 55'), +(10821, 1, 1000157, 0, 5, 'Hed\'mush the Rotting - World Loot Level 57'), +(10822, 1, 1000158, 0, 5, 'Warlord Thresh\'jin - World Loot Level 58'), +(10823, 1, 1000159, 0, 5, 'Zul\'Brin Warpbranch - World Loot Level 59'), +(10824, 1, 1000160, 0, 5, 'Ranger Lord Hawkspear - World Loot Level 60'), +(10825, 1, 1000056, 0, 5, 'Gish the Unmoving - World Loot Level 56'), +(10826, 1, 1000157, 0, 5, 'Lord Darkscythe - World Loot Level 57'), +(10827, 1, 1000156, 0, 5, 'Deathspeaker Selendre - World Loot Level 56'), +(11688, 1, 1000143, 0, 5, 'Cursed Centaur - World Loot Level 43'), +(12037, 1, 1000031, 0, 5, 'Ursol\'lok - World Loot Level 31'), +(12431, 1, 1000013, 0, 5, 'Gorefang - World Loot Level 13'), +(12432, 1, 1000014, 0, 5, 'Old Vicejaw - World Loot Level 14'), +(12433, 1, 1000015, 0, 5, 'Krethis Shadowspinner - World Loot Level 15'), +(14221, 1, 1000136, 0, 5, 'Gravis Slipknot - World Loot Level 36'), +(14222, 1, 1000035, 0, 5, 'Araga - World Loot Level 35'), +(14223, 1, 1000032, 0, 5, 'Cranky Benj - World Loot Level 32'), +(14224, 1, 1000141, 0, 5, '7:XT - World Loot Level 41'), +(14225, 1, 1000133, 0, 5, 'Prince Kellen - World Loot Level 33'), +(14226, 1, 1000140, 0, 5, 'Kaskk - World Loot Level 40'), +(14227, 1, 1000037, 0, 5, 'Hissperak - World Loot Level 37'), +(14228, 1, 1000034, 0, 5, 'Giggler - World Loot Level 34'), +(14229, 1, 1000135, 0, 5, 'Accursed Slitherblade - World Loot Level 35'), +(14230, 1, 1000137, 0, 5, 'Burgle Eye - World Loot Level 37'), +(14231, 1, 1000137, 0, 5, 'Drogoth the Roamer - World Loot Level 37'), +(14232, 1, 1000038, 0, 5, 'Dart - World Loot Level 38'), +(14233, 1, 1000037, 0, 5, 'Ripscale - World Loot Level 37'), +(14234, 1, 1000039, 0, 5, 'Hayoc - World Loot Level 39'), +(14235, 1, 1000040, 0, 5, 'The Rot - World Loot Level 40'), +(14236, 1, 1000137, 0, 5, 'Lord Angler - World Loot Level 37'), +(14237, 1, 1000038, 0, 5, 'Oozeworm - World Loot Level 38'), +(14266, 1, 1000019, 0, 5, 'Shanda the Spinner - World Loot Level 19'), +(14268, 1, 1000015, 0, 5, 'Lord Condar - World Loot Level 15'), +(14268, 2, 1000016, 0, 5, 'Lord Condar - World Loot Level 16'), +(14269, 1, 1000021, 0, 5, 'Seeker Aqualon - World Loot Level 21'), +(14270, 1, 1000119, 0, 5, 'Squiddic - World Loot Level 19'), +(14271, 1, 1000117, 0, 5, 'Ribchaser - World Loot Level 17'), +(14272, 1, 1000018, 0, 5, 'Snarlflare - World Loot Level 18'), +(14273, 1, 1000025, 0, 5, 'Boulderheart - World Loot Level 25'), +(14276, 1, 1000130, 0, 5, 'Scargil - World Loot Level 30'), +(14277, 1, 1000133, 0, 5, 'Lady Zephris - World Loot Level 33'), +(14278, 1, 1000128, 0, 5, 'Ro\'Bark - World Loot Level 28'), +(14279, 1, 1000024, 0, 5, 'Creepthess - World Loot Level 24'), +(14280, 1, 1000027, 0, 5, 'Big Samras - World Loot Level 27'), +(14281, 1, 1000123, 0, 5, 'Jimmy the Bleeder - World Loot Level 23'), +(14339, 1, 1000049, 0, 5, 'Death Howl - World Loot Level 49'), +(14340, 1, 1000154, 0, 5, 'Alshirr Banebreath - World Loot Level 54'), +(14342, 1, 1000151, 0, 5, 'Ragepaw - World Loot Level 51'), +(14343, 1, 1000052, 0, 5, 'Olm the Wise - World Loot Level 52'), +(14344, 1, 1000050, 0, 5, 'Mongress - World Loot Level 50'), +(14345, 1, 1000051, 0, 5, 'The Ongar - World Loot Level 51'), +(14424, 1, 1000125, 0, 5, 'Mirelow - World Loot Level 25'), +(14425, 1, 1000124, 0, 5, 'Gnawbone - World Loot Level 24'), +(14426, 1, 1000127, 0, 5, 'Harb Foulmountain - World Loot Level 27'), +(14427, 1, 1000128, 0, 5, 'Gibblesnik - World Loot Level 28'), +(14428, 1, 1000107, 0, 5, 'Uruson - World Loot Level 7'), +(14429, 1, 1000111, 0, 5, 'Grimmaw - World Loot Level 11'), +(14430, 1, 1000009, 0, 5, 'Duskstalker - World Loot Level 9'), +(14431, 1, 1000108, 0, 5, 'Fury Shelda - World Loot Level 8'), +(14432, 1, 1000106, 0, 5, 'Threggil - World Loot Level 6'), +(14433, 1, 1000030, 0, 5, 'Sludginn - World Loot Level 30'), +(14446, 1, 1000143, 0, 5, 'Fingat - World Loot Level 43'), +(14447, 1, 1000143, 0, 5, 'Gilmorian - World Loot Level 43'), +(14448, 1, 1000142, 0, 5, 'Molt Thorn - World Loot Level 42'), +(14472, 1, 1000057, 0, 5, 'Gretheer - World Loot Level 57'), +(14476, 1, 1000056, 0, 5, 'Krellack - World Loot Level 56'), +(14477, 1, 1000058, 0, 5, 'Grubthor - World Loot Level 58'), +(14478, 1, 1000058, 0, 5, 'Huricanian - World Loot Level 58'), +(14479, 1, 1000160, 0, 5, 'Twilight Lord Everun - World Loot Level 60'), +(14487, 1, 1000137, 0, 5, 'Gluggle - World Loot Level 37'), +(14488, 1, 1000138, 0, 5, 'Roloch - World Loot Level 38'), +(14490, 1, 1000044, 0, 5, 'Rippa - World Loot Level 44'), +(14491, 1, 1000042, 0, 5, 'Kurmokk - World Loot Level 42'), +(14492, 1, 1000142, 0, 5, 'Verifonix - World Loot Level 42'), +(18241, 1, 1000030, 0, 5, 'Crusty - World Loot Level 30'), +(18241, 2, 1000031, 0, 5, 'Crusty - World Loot Level 31'), +(18241, 3, 1000032, 0, 5, 'Crusty - World Loot Level 32'); + +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(616, 2, 1012024, 0, 1, 'Chatter - Vanilla Whites 20-24 Level Range'), +(616, 3, 1012125, 0, 1, 'Chatter - Vanilla Whites 21-25 Level Range'), +(616, 4, 1011923, 0, 1, 'Chatter - Vanilla Whites 19-23 Level Range'), +(616, 5, 1022327, 0, 1, 'Chatter - Vanilla Greens 23-27 Level Range'), +(616, 6, 1022125, 0, 1, 'Chatter - Vanilla Greens 21-25 Level Range'), +(616, 7, 1022024, 0, 1, 'Chatter - Vanilla Greens 20-24 Level Range'), +(616, 8, 1022226, 0, 1, 'Chatter - Vanilla Greens 22-26 Level Range'), +(616, 9, 1021923, 0, 1, 'Chatter - Vanilla Greens 19-23 Level Range'), +(763, 2, 1023640, 0, 6, 'Lost One Chieftain - Vanilla Greens 36-40 Level Range'), +(763, 3, 1023741, 0, 6, 'Lost One Chieftain - Vanilla Greens 37-41 Level Range'), +(763, 4, 1023842, 0, 6, 'Lost One Chieftain - Vanilla Greens 38-42 Level Range'), +(763, 5, 1023943, 0, 6, 'Lost One Chieftain - Vanilla Greens 39-43 Level Range'), +(763, 6, 1023539, 0, 6, 'Lost One Chieftain - Vanilla Greens 35-39 Level Range'), +(1037, 3, 1022327, 0, 6, 'Dragonmaw Battlemaster - Vanilla Greens 23-27 Level Range'), +(1037, 4, 1022428, 0, 6, 'Dragonmaw Battlemaster - Vanilla Greens 24-28 Level Range'), +(1037, 5, 1022125, 0, 6, 'Dragonmaw Battlemaster - Vanilla Greens 21-25 Level Range'), +(1037, 6, 1022226, 0, 6, 'Dragonmaw Battlemaster - Vanilla Greens 22-26 Level Range'), +(1037, 7, 1022529, 0, 6, 'Dragonmaw Battlemaster - Vanilla Greens 25-29 Level Range'), +(1037, 8, 1022024, 0, 6, 'Dragonmaw Battlemaster - Vanilla Greens 20-24 Level Range'), +(1063, 2, 1024347, 0, 6, 'Jade - Vanilla Greens 43-47 Level Range'), +(1063, 3, 1024448, 0, 6, 'Jade - Vanilla Greens 44-48 Level Range'), +(1063, 4, 1024549, 0, 6, 'Jade - Vanilla Greens 45-49 Level Range'), +(1063, 5, 1024751, 0, 6, 'Jade - Vanilla Greens 47-51 Level Range'), +(1063, 6, 1024650, 0, 6, 'Jade - Vanilla Greens 46-50 Level Range'), +(1106, 2, 1023438, 0, 6, 'Lost One Cook - Vanilla Greens 34-38 Level Range'), +(1106, 3, 1023640, 0, 6, 'Lost One Cook - Vanilla Greens 36-40 Level Range'), +(1106, 4, 1023741, 0, 6, 'Lost One Cook - Vanilla Greens 37-41 Level Range'), +(1106, 5, 1023337, 0, 6, 'Lost One Cook - Vanilla Greens 33-37 Level Range'), +(1106, 6, 1023539, 0, 6, 'Lost One Cook - Vanilla Greens 35-39 Level Range'), +(1130, 2, 1011112, 0, 6, 'Bjarn - Vanilla Whites 11-12 Level Range'), +(1130, 3, 1011213, 0, 6, 'Bjarn - Vanilla Whites 12-13 Level Range'), +(1130, 4, 1021115, 0, 6, 'Bjarn - Vanilla Greens 11-15 Level Range'), +(1130, 5, 1021014, 0, 6, 'Bjarn - Vanilla Greens 10-14 Level Range'), +(1130, 6, 1021216, 0, 6, 'Bjarn - Vanilla Greens 12-16 Level Range'), +(1130, 7, 1020812, 0, 6, 'Bjarn - Vanilla Greens 8-12 Level Range'), +(1837, 2, 1025660, 0, 6, 'Scarlet Judge - Vanilla Greens 56-60 Level Range'), +(1837, 3, 1025862, 0, 6, 'Scarlet Judge - Vanilla Greens 58-62 Level Range'), +(1837, 4, 1026063, 0, 6, 'Scarlet Judge - Vanilla Greens 60-63 Level Range'), +(1837, 5, 1025963, 0, 6, 'Scarlet Judge - Vanilla Greens 59-63 Level Range'), +(1837, 6, 1025761, 0, 6, 'Scarlet Judge - Vanilla Greens 57-61 Level Range'), +(1844, 2, 1025660, 0, 6, 'Foreman Marcrid - Vanilla Greens 56-60 Level Range'), +(1844, 3, 1025862, 0, 6, 'Foreman Marcrid - Vanilla Greens 58-62 Level Range'), +(1844, 4, 1025458, 0, 6, 'Foreman Marcrid - Vanilla Greens 54-58 Level Range'), +(1844, 5, 1025559, 0, 6, 'Foreman Marcrid - Vanilla Greens 55-59 Level Range'), +(1844, 6, 1025761, 0, 6, 'Foreman Marcrid - Vanilla Greens 57-61 Level Range'), +(1847, 2, 1025155, 0, 6, 'Foulmane - Vanilla Greens 51-55 Level Range'), +(1847, 3, 1025256, 0, 6, 'Foulmane - Vanilla Greens 52-56 Level Range'), +(1847, 4, 1025054, 0, 6, 'Foulmane - Vanilla Greens 50-54 Level Range'), +(1847, 5, 1024852, 0, 6, 'Foulmane - Vanilla Greens 48-52 Level Range'), +(1847, 6, 1024953, 0, 6, 'Foulmane - Vanilla Greens 49-53 Level Range'), +(1848, 2, 1025660, 0, 6, 'Lord Maldazzar - Vanilla Greens 56-60 Level Range'), +(1848, 3, 1025458, 0, 6, 'Lord Maldazzar - Vanilla Greens 54-58 Level Range'), +(1848, 4, 1025559, 0, 6, 'Lord Maldazzar - Vanilla Greens 55-59 Level Range'), +(1848, 5, 1025357, 0, 6, 'Lord Maldazzar - Vanilla Greens 53-57 Level Range'), +(1848, 6, 1025256, 0, 6, 'Lord Maldazzar - Vanilla Greens 52-56 Level Range'), +(1851, 2, 1025862, 0, 6, 'The Husk - Vanilla Greens 58-62 Level Range'), +(1851, 3, 1026263, 0, 6, 'The Husk - Vanilla Greens 62-63 Level Range'), +(1851, 4, 1026163, 0, 6, 'The Husk - Vanilla Greens 61-63 Level Range'), +(1851, 5, 1026063, 0, 6, 'The Husk - Vanilla Greens 60-63 Level Range'), +(1851, 6, 1025963, 0, 6, 'The Husk - Vanilla Greens 59-63 Level Range'), +(1885, 3, 1025660, 0, 6, 'Scarlet Smith - Vanilla Greens 56-60 Level Range'), +(1885, 4, 1025862, 0, 6, 'Scarlet Smith - Vanilla Greens 58-62 Level Range'), +(1885, 5, 1025458, 0, 6, 'Scarlet Smith - Vanilla Greens 54-58 Level Range'), +(1885, 6, 1025559, 0, 6, 'Scarlet Smith - Vanilla Greens 55-59 Level Range'), +(1885, 7, 1025761, 0, 6, 'Scarlet Smith - Vanilla Greens 57-61 Level Range'), +(1885, 8, 1025963, 0, 6, 'Scarlet Smith - Vanilla Greens 59-63 Level Range'), +(1910, 2, 1010910, 0, 1, 'Muad - Vanilla Whites 9-10 Level Range'), +(1910, 3, 1011011, 0, 1, 'Muad - Vanilla Whites 10-11 Level Range'), +(1910, 4, 1021014, 10, 1, 'Muad - Vanilla Greens 10-14 Level Range'), +(1910, 5, 1020812, 10, 1, 'Muad - Vanilla Greens 8-12 Level Range'), +(1911, 2, 1011112, 0, 1, 'Deeb - Vanilla Whites 11-12 Level Range'), +(1911, 3, 1011213, 0, 1, 'Deeb - Vanilla Whites 12-13 Level Range'), +(1911, 4, 1021115, 0, 1, 'Deeb - Vanilla Greens 11-15 Level Range'), +(1911, 5, 1021014, 0, 1, 'Deeb - Vanilla Greens 10-14 Level Range'), +(1911, 6, 1021216, 0, 1, 'Deeb - Vanilla Greens 12-16 Level Range'), +(1911, 7, 1020812, 0, 1, 'Deeb - Vanilla Greens 8-12 Level Range'), +(1948, 2, 1012024, 0, 1, 'Snarlmane - Vanilla Whites 20-24 Level Range'), +(1948, 3, 1012125, 0, 1, 'Snarlmane - Vanilla Whites 21-25 Level Range'), +(1948, 4, 1011923, 0, 1, 'Snarlmane - Vanilla Whites 19-23 Level Range'), +(1948, 5, 1022327, 0, 1, 'Snarlmane - Vanilla Greens 23-27 Level Range'), +(1948, 6, 1022125, 0, 1, 'Snarlmane - Vanilla Greens 21-25 Level Range'), +(1948, 7, 1022024, 0, 1, 'Snarlmane - Vanilla Greens 20-24 Level Range'), +(1948, 8, 1022226, 0, 1, 'Snarlmane - Vanilla Greens 22-26 Level Range'), +(1948, 9, 1021923, 0, 1, 'Snarlmane - Vanilla Greens 19-23 Level Range'), +(2172, 2, 1012024, 0, 6, 'Strider Clutchmother - Vanilla Whites 20-24 Level Range'), +(2172, 3, 1011822, 0, 6, 'Strider Clutchmother - Vanilla Whites 18-22 Level Range'), +(2172, 4, 1011923, 0, 6, 'Strider Clutchmother - Vanilla Whites 19-23 Level Range'), +(2172, 5, 1022024, 0, 6, 'Strider Clutchmother - Vanilla Greens 20-24 Level Range'), +(2172, 6, 1021620, 0, 6, 'Strider Clutchmother - Vanilla Greens 16-20 Level Range'), +(2172, 7, 1021721, 0, 6, 'Strider Clutchmother - Vanilla Greens 17-21 Level Range'), +(2172, 8, 1021822, 0, 6, 'Strider Clutchmother - Vanilla Greens 18-22 Level Range'), +(2172, 9, 1021923, 0, 6, 'Strider Clutchmother - Vanilla Greens 19-23 Level Range'), +(2175, 2, 1011314, 0, 6, 'Shadowclaw - Vanilla Whites 13-14 Level Range'), +(2175, 3, 1011213, 0, 6, 'Shadowclaw - Vanilla Whites 12-13 Level Range'), +(2175, 4, 1021317, 0, 6, 'Shadowclaw - Vanilla Greens 13-17 Level Range'), +(2175, 5, 1021115, 0, 6, 'Shadowclaw - Vanilla Greens 11-15 Level Range'), +(2175, 6, 1021014, 0, 6, 'Shadowclaw - Vanilla Greens 10-14 Level Range'), +(2175, 7, 1021216, 0, 6, 'Shadowclaw - Vanilla Greens 12-16 Level Range'), +(2184, 2, 1021317, 0, 6, 'Lady Moongazer - Vanilla Greens 13-17 Level Range'), +(2184, 3, 1021418, 0, 6, 'Lady Moongazer - Vanilla Greens 14-18 Level Range'), +(2184, 4, 1021519, 0, 6, 'Lady Moongazer - Vanilla Greens 15-19 Level Range'), +(2184, 5, 1021620, 0, 6, 'Lady Moongazer - Vanilla Greens 16-20 Level Range'), +(2184, 6, 1021721, 0, 6, 'Lady Moongazer - Vanilla Greens 17-21 Level Range'), +(2186, 2, 1021317, 0, 6, 'Carnivous the Breaker - Vanilla Greens 13-17 Level Range'), +(2186, 3, 1021216, 0, 6, 'Carnivous the Breaker - Vanilla Greens 12-16 Level Range'), +(2186, 4, 1021418, 0, 6, 'Carnivous the Breaker - Vanilla Greens 14-18 Level Range'), +(2186, 5, 1021519, 0, 6, 'Carnivous the Breaker - Vanilla Greens 15-19 Level Range'), +(2186, 6, 1021620, 0, 6, 'Carnivous the Breaker - Vanilla Greens 16-20 Level Range'), +(2191, 2, 1011314, 0, 6, 'Licillin - Vanilla Whites 13-14 Level Range'), +(2191, 3, 1011415, 0, 6, 'Licillin - Vanilla Whites 14-15 Level Range'), +(2191, 4, 1021317, 0, 6, 'Licillin - Vanilla Greens 13-17 Level Range'), +(2191, 5, 1021115, 0, 6, 'Licillin - Vanilla Greens 11-15 Level Range'), +(2191, 6, 1021014, 0, 6, 'Licillin - Vanilla Greens 10-14 Level Range'), +(2191, 7, 1021216, 0, 6, 'Licillin - Vanilla Greens 12-16 Level Range'), +(2191, 8, 1021418, 0, 6, 'Licillin - Vanilla Greens 14-18 Level Range'), +(2192, 2, 1011822, 0, 6, 'Firecaller Radison - Vanilla Whites 18-22 Level Range'), +(2192, 3, 1011923, 0, 6, 'Firecaller Radison - Vanilla Whites 19-23 Level Range'), +(2192, 4, 1021519, 0, 6, 'Firecaller Radison - Vanilla Greens 15-19 Level Range'), +(2192, 5, 1021620, 0, 6, 'Firecaller Radison - Vanilla Greens 16-20 Level Range'), +(2192, 6, 1021721, 0, 6, 'Firecaller Radison - Vanilla Greens 17-21 Level Range'), +(2192, 7, 1021822, 0, 6, 'Firecaller Radison - Vanilla Greens 18-22 Level Range'), +(2192, 8, 1021923, 0, 6, 'Firecaller Radison - Vanilla Greens 19-23 Level Range'), +(2258, 2, 1023438, 0, 6, 'Stone Fury - Vanilla Greens 34-38 Level Range'), +(2258, 3, 1023640, 0, 6, 'Stone Fury - Vanilla Greens 36-40 Level Range'), +(2258, 4, 1023741, 0, 6, 'Stone Fury - Vanilla Greens 37-41 Level Range'), +(2258, 5, 1023337, 0, 6, 'Stone Fury - Vanilla Greens 33-37 Level Range'), +(2258, 6, 1023539, 0, 6, 'Stone Fury - Vanilla Greens 35-39 Level Range'), +(2603, 2, 1023438, 0, 1, 'Kovork - Vanilla Greens 34-38 Level Range'), +(2603, 3, 1023640, 0, 1, 'Kovork - Vanilla Greens 36-40 Level Range'), +(2603, 4, 1023337, 0, 1, 'Kovork - Vanilla Greens 33-37 Level Range'), +(2603, 5, 1023539, 0, 1, 'Kovork - Vanilla Greens 35-39 Level Range'), +(2603, 6, 1023236, 0, 1, 'Kovork - Vanilla Greens 32-36 Level Range'), +(2604, 2, 1023640, 0, 6, 'Molok the Crusher - Vanilla Greens 36-40 Level Range'), +(2604, 3, 1023741, 0, 6, 'Molok the Crusher - Vanilla Greens 37-41 Level Range'), +(2604, 4, 1023842, 0, 6, 'Molok the Crusher - Vanilla Greens 38-42 Level Range'), +(2604, 5, 1023943, 0, 6, 'Molok the Crusher - Vanilla Greens 39-43 Level Range'), +(2604, 6, 1023539, 0, 6, 'Molok the Crusher - Vanilla Greens 35-39 Level Range'), +(2605, 2, 1023640, 0, 6, 'Zalas Witherbark - Vanilla Greens 36-40 Level Range'), +(2605, 3, 1023741, 0, 6, 'Zalas Witherbark - Vanilla Greens 37-41 Level Range'), +(2605, 4, 1023842, 0, 6, 'Zalas Witherbark - Vanilla Greens 38-42 Level Range'), +(2605, 5, 1023943, 0, 6, 'Zalas Witherbark - Vanilla Greens 39-43 Level Range'), +(2605, 6, 1024044, 0, 6, 'Zalas Witherbark - Vanilla Greens 40-44 Level Range'), +(2744, 2, 1023640, 0, 6, 'Shadowforge Commander - Vanilla Greens 36-40 Level Range'), +(2744, 3, 1023741, 0, 6, 'Shadowforge Commander - Vanilla Greens 37-41 Level Range'), +(2744, 4, 1023842, 0, 6, 'Shadowforge Commander - Vanilla Greens 38-42 Level Range'), +(2744, 5, 1023943, 0, 6, 'Shadowforge Commander - Vanilla Greens 39-43 Level Range'), +(2744, 6, 1024044, 0, 6, 'Shadowforge Commander - Vanilla Greens 40-44 Level Range'), +(2751, 2, 1023438, 0, 6, 'War Golem - Vanilla Greens 34-38 Level Range'), +(2751, 3, 1023640, 0, 6, 'War Golem - Vanilla Greens 36-40 Level Range'), +(2751, 4, 1023337, 0, 6, 'War Golem - Vanilla Greens 33-37 Level Range'), +(2751, 5, 1023539, 0, 6, 'War Golem - Vanilla Greens 35-39 Level Range'), +(2751, 6, 1023236, 0, 6, 'War Golem - Vanilla Greens 32-36 Level Range'), +(2752, 2, 1024145, 0, 6, 'Rumbler - Vanilla Greens 41-45 Level Range'), +(2752, 3, 1024347, 0, 6, 'Rumbler - Vanilla Greens 43-47 Level Range'), +(2752, 4, 1024448, 0, 6, 'Rumbler - Vanilla Greens 44-48 Level Range'), +(2752, 5, 1024549, 0, 6, 'Rumbler - Vanilla Greens 45-49 Level Range'), +(2752, 6, 1024246, 0, 6, 'Rumbler - Vanilla Greens 42-46 Level Range'), +(2753, 2, 1023438, 0, 6, 'Barnabus - Vanilla Greens 34-38 Level Range'), +(2753, 3, 1023640, 0, 6, 'Barnabus - Vanilla Greens 36-40 Level Range'), +(2753, 4, 1023741, 0, 6, 'Barnabus - Vanilla Greens 37-41 Level Range'), +(2753, 5, 1023842, 0, 6, 'Barnabus - Vanilla Greens 38-42 Level Range'), +(2753, 6, 1023539, 0, 6, 'Barnabus - Vanilla Greens 35-39 Level Range'), +(2779, 2, 1024145, 0, 1, 'Prince Nazjak - Vanilla Greens 41-45 Level Range'), +(2779, 3, 1023741, 0, 1, 'Prince Nazjak - Vanilla Greens 37-41 Level Range'), +(2779, 4, 1023842, 0, 1, 'Prince Nazjak - Vanilla Greens 38-42 Level Range'), +(2779, 5, 1023943, 0, 1, 'Prince Nazjak - Vanilla Greens 39-43 Level Range'), +(2779, 6, 1024044, 0, 1, 'Prince Nazjak - Vanilla Greens 40-44 Level Range'), +(2850, 2, 1023438, 0, 6, 'Broken Tooth - Vanilla Greens 34-38 Level Range'), +(2850, 3, 1023640, 0, 6, 'Broken Tooth - Vanilla Greens 36-40 Level Range'), +(2850, 4, 1023741, 0, 6, 'Broken Tooth - Vanilla Greens 37-41 Level Range'), +(2850, 5, 1023337, 0, 6, 'Broken Tooth - Vanilla Greens 33-37 Level Range'), +(2850, 6, 1023539, 0, 6, 'Broken Tooth - Vanilla Greens 35-39 Level Range'), +(3068, 2, 1010910, 0, 1, 'Mazzranache - Vanilla Whites 9-10 Level Range'), +(3068, 3, 1010809, 0, 1, 'Mazzranache - Vanilla Whites 8-9 Level Range'), +(3068, 4, 1020812, 0, 1, 'Mazzranache - Vanilla Greens 8-12 Level Range'), +(3295, 2, 1011822, 0, 6, 'Sludge Beast - Vanilla Whites 18-22 Level Range'), +(3295, 3, 1011923, 0, 6, 'Sludge Beast - Vanilla Whites 19-23 Level Range'), +(3295, 4, 1021519, 0, 6, 'Sludge Beast - Vanilla Greens 15-19 Level Range'), +(3295, 5, 1021620, 0, 6, 'Sludge Beast - Vanilla Greens 16-20 Level Range'), +(3295, 6, 1021721, 0, 6, 'Sludge Beast - Vanilla Greens 17-21 Level Range'), +(3295, 7, 1021822, 0, 6, 'Sludge Beast - Vanilla Greens 18-22 Level Range'), +(3295, 8, 1021923, 0, 6, 'Sludge Beast - Vanilla Greens 19-23 Level Range'), +(3735, 2, 1012024, 0, 6, 'Apothecary Falthis - Vanilla Whites 20-24 Level Range'), +(3735, 3, 1012125, 0, 6, 'Apothecary Falthis - Vanilla Whites 21-25 Level Range'), +(3735, 4, 1011822, 0, 6, 'Apothecary Falthis - Vanilla Whites 18-22 Level Range'), +(3735, 5, 1011923, 0, 6, 'Apothecary Falthis - Vanilla Whites 19-23 Level Range'), +(3735, 6, 1022125, 0, 6, 'Apothecary Falthis - Vanilla Greens 21-25 Level Range'), +(3735, 7, 1022024, 0, 6, 'Apothecary Falthis - Vanilla Greens 20-24 Level Range'), +(3735, 8, 1022226, 0, 6, 'Apothecary Falthis - Vanilla Greens 22-26 Level Range'), +(3735, 9, 1021822, 0, 6, 'Apothecary Falthis - Vanilla Greens 18-22 Level Range'), +(3735, 10, 1021923, 0, 6, 'Apothecary Falthis - Vanilla Greens 19-23 Level Range'), +(3773, 2, 1022327, 0, 6, 'Akkrilus - Vanilla Greens 23-27 Level Range'), +(3773, 3, 1022428, 0, 6, 'Akkrilus - Vanilla Greens 24-28 Level Range'), +(3773, 4, 1022630, 0, 6, 'Akkrilus - Vanilla Greens 26-30 Level Range'), +(3773, 5, 1022226, 0, 6, 'Akkrilus - Vanilla Greens 22-26 Level Range'), +(3773, 6, 1022529, 0, 6, 'Akkrilus - Vanilla Greens 25-29 Level Range'), +(4030, 3, 1022731, 0, 6, 'Vengeful Ancient - Vanilla Greens 27-31 Level Range'), +(4030, 4, 1022832, 0, 6, 'Vengeful Ancient - Vanilla Greens 28-32 Level Range'), +(4030, 5, 1022933, 0, 6, 'Vengeful Ancient - Vanilla Greens 29-33 Level Range'), +(4030, 6, 1022630, 0, 6, 'Vengeful Ancient - Vanilla Greens 26-30 Level Range'), +(4030, 7, 1022529, 0, 6, 'Vengeful Ancient - Vanilla Greens 25-29 Level Range'), +(4030, 8, 1023034, 0, 6, 'Vengeful Ancient - Vanilla Greens 30-34 Level Range'), +(4066, 2, 1023034, 0, 6, 'Nal\'taszar - Vanilla Greens 30-34 Level Range'), +(4066, 3, 1022731, 0, 6, 'Nal\'taszar - Vanilla Greens 27-31 Level Range'), +(4066, 4, 1022832, 0, 6, 'Nal\'taszar - Vanilla Greens 28-32 Level Range'), +(4066, 5, 1022933, 0, 6, 'Nal\'taszar - Vanilla Greens 29-33 Level Range'), +(4066, 6, 1022630, 0, 6, 'Nal\'taszar - Vanilla Greens 26-30 Level Range'), +(4132, 2, 1023438, 0, 1, 'Silithid Ravager - Vanilla Greens 34-38 Level Range'), +(4132, 3, 1023640, 0, 1, 'Silithid Ravager - Vanilla Greens 36-40 Level Range'), +(4132, 4, 1023337, 0, 1, 'Silithid Ravager - Vanilla Greens 33-37 Level Range'), +(4132, 5, 1023539, 0, 1, 'Silithid Ravager - Vanilla Greens 35-39 Level Range'), +(4132, 6, 1023236, 0, 1, 'Silithid Ravager - Vanilla Greens 32-36 Level Range'), +(4380, 2, 1023438, 0, 6, 'Darkmist Widow - Vanilla Greens 34-38 Level Range'), +(4380, 3, 1023640, 0, 6, 'Darkmist Widow - Vanilla Greens 36-40 Level Range'), +(4380, 4, 1023741, 0, 6, 'Darkmist Widow - Vanilla Greens 37-41 Level Range'), +(4380, 5, 1023842, 0, 6, 'Darkmist Widow - Vanilla Greens 38-42 Level Range'), +(4380, 6, 1023539, 0, 6, 'Darkmist Widow - Vanilla Greens 35-39 Level Range'), +(5343, 2, 1024347, 0, 6, 'Lady Szallah - Vanilla Greens 43-47 Level Range'), +(5343, 3, 1024448, 0, 6, 'Lady Szallah - Vanilla Greens 44-48 Level Range'), +(5343, 4, 1024549, 0, 6, 'Lady Szallah - Vanilla Greens 45-49 Level Range'), +(5343, 5, 1024246, 0, 6, 'Lady Szallah - Vanilla Greens 42-46 Level Range'), +(5343, 6, 1024650, 0, 6, 'Lady Szallah - Vanilla Greens 46-50 Level Range'), +(5345, 2, 1024145, 0, 6, 'Diamond Head - Vanilla Greens 41-45 Level Range'), +(5345, 3, 1024347, 0, 6, 'Diamond Head - Vanilla Greens 43-47 Level Range'), +(5345, 4, 1024448, 0, 6, 'Diamond Head - Vanilla Greens 44-48 Level Range'), +(5345, 5, 1024549, 0, 6, 'Diamond Head - Vanilla Greens 45-49 Level Range'), +(5345, 6, 1024246, 0, 6, 'Diamond Head - Vanilla Greens 42-46 Level Range'), +(5346, 2, 1024448, 0, 6, 'Bloodroar the Stalker - Vanilla Greens 44-48 Level Range'), +(5346, 3, 1024549, 0, 6, 'Bloodroar the Stalker - Vanilla Greens 45-49 Level Range'), +(5346, 4, 1024751, 0, 6, 'Bloodroar the Stalker - Vanilla Greens 47-51 Level Range'), +(5346, 5, 1024852, 0, 6, 'Bloodroar the Stalker - Vanilla Greens 48-52 Level Range'), +(5346, 6, 1024650, 0, 6, 'Bloodroar the Stalker - Vanilla Greens 46-50 Level Range'), +(5347, 2, 1024448, 0, 6, 'Antilus the Soarer - Vanilla Greens 44-48 Level Range'), +(5347, 3, 1024549, 0, 6, 'Antilus the Soarer - Vanilla Greens 45-49 Level Range'), +(5347, 4, 1024751, 0, 6, 'Antilus the Soarer - Vanilla Greens 47-51 Level Range'), +(5347, 5, 1024852, 0, 6, 'Antilus the Soarer - Vanilla Greens 48-52 Level Range'), +(5347, 6, 1024650, 0, 6, 'Antilus the Soarer - Vanilla Greens 46-50 Level Range'), +(5349, 2, 1024549, 0, 6, 'Arash-ethis - Vanilla Greens 45-49 Level Range'), +(5349, 3, 1024751, 0, 6, 'Arash-ethis - Vanilla Greens 47-51 Level Range'), +(5349, 4, 1024852, 0, 6, 'Arash-ethis - Vanilla Greens 48-52 Level Range'), +(5349, 5, 1024953, 0, 6, 'Arash-ethis - Vanilla Greens 49-53 Level Range'), +(5349, 6, 1024650, 0, 6, 'Arash-ethis - Vanilla Greens 46-50 Level Range'), +(5350, 2, 1024347, 0, 6, 'Qirot - Vanilla Greens 43-47 Level Range'), +(5350, 3, 1024448, 0, 6, 'Qirot - Vanilla Greens 44-48 Level Range'), +(5350, 4, 1024549, 0, 6, 'Qirot - Vanilla Greens 45-49 Level Range'), +(5350, 5, 1024751, 0, 6, 'Qirot - Vanilla Greens 47-51 Level Range'), +(5350, 6, 1024650, 0, 6, 'Qirot - Vanilla Greens 46-50 Level Range'), +(5352, 2, 1024145, 0, 6, 'Old Grizzlegut - Vanilla Greens 41-45 Level Range'), +(5352, 3, 1024347, 0, 6, 'Old Grizzlegut - Vanilla Greens 43-47 Level Range'), +(5352, 4, 1024246, 0, 6, 'Old Grizzlegut - Vanilla Greens 42-46 Level Range'), +(5352, 5, 1023943, 0, 6, 'Old Grizzlegut - Vanilla Greens 39-43 Level Range'), +(5352, 6, 1024044, 0, 6, 'Old Grizzlegut - Vanilla Greens 40-44 Level Range'), +(5354, 2, 1024145, 0, 6, 'Gnarl Leafbrother - Vanilla Greens 41-45 Level Range'), +(5354, 3, 1024347, 0, 6, 'Gnarl Leafbrother - Vanilla Greens 43-47 Level Range'), +(5354, 4, 1024448, 0, 6, 'Gnarl Leafbrother - Vanilla Greens 44-48 Level Range'), +(5354, 5, 1024246, 0, 6, 'Gnarl Leafbrother - Vanilla Greens 42-46 Level Range'), +(5354, 6, 1024044, 0, 6, 'Gnarl Leafbrother - Vanilla Greens 40-44 Level Range'), +(5356, 2, 1024145, 0, 6, 'Snarler - Vanilla Greens 41-45 Level Range'), +(5356, 3, 1024246, 0, 6, 'Snarler - Vanilla Greens 42-46 Level Range'), +(5356, 4, 1023842, 0, 6, 'Snarler - Vanilla Greens 38-42 Level Range'), +(5356, 5, 1023943, 0, 6, 'Snarler - Vanilla Greens 39-43 Level Range'), +(5356, 6, 1024044, 0, 6, 'Snarler - Vanilla Greens 40-44 Level Range'), +(5399, 2, 1024448, 0, 6, 'Veyzhak the Cannibal - Vanilla Greens 44-48 Level Range'), +(5399, 3, 1024549, 0, 6, 'Veyzhak the Cannibal - Vanilla Greens 45-49 Level Range'), +(5399, 4, 1024751, 0, 6, 'Veyzhak the Cannibal - Vanilla Greens 47-51 Level Range'), +(5399, 5, 1024852, 0, 6, 'Veyzhak the Cannibal - Vanilla Greens 48-52 Level Range'), +(5399, 6, 1024650, 0, 6, 'Veyzhak the Cannibal - Vanilla Greens 46-50 Level Range'), +(5400, 2, 1024448, 0, 6, 'Zekkis - Vanilla Greens 44-48 Level Range'), +(5400, 3, 1024549, 0, 6, 'Zekkis - Vanilla Greens 45-49 Level Range'), +(5400, 4, 1024751, 0, 6, 'Zekkis - Vanilla Greens 47-51 Level Range'), +(5400, 5, 1024852, 0, 6, 'Zekkis - Vanilla Greens 48-52 Level Range'), +(5400, 6, 1024650, 0, 6, 'Zekkis - Vanilla Greens 46-50 Level Range'), +(5786, 2, 1010910, 0, 6, 'Snagglespear - Vanilla Whites 9-10 Level Range'), +(5786, 3, 1010809, 0, 6, 'Snagglespear - Vanilla Whites 8-9 Level Range'), +(5786, 4, 1020812, 0, 6, 'Snagglespear - Vanilla Greens 8-12 Level Range'), +(5787, 2, 1011112, 0, 6, 'Enforcer Emilgund - Vanilla Whites 11-12 Level Range'), +(5787, 3, 1011011, 0, 6, 'Enforcer Emilgund - Vanilla Whites 10-11 Level Range'), +(5787, 4, 1021115, 0, 6, 'Enforcer Emilgund - Vanilla Greens 11-15 Level Range'), +(5787, 5, 1021014, 0, 6, 'Enforcer Emilgund - Vanilla Greens 10-14 Level Range'), +(5787, 6, 1020812, 0, 6, 'Enforcer Emilgund - Vanilla Greens 8-12 Level Range'), +(5808, 2, 1010910, 0, 6, 'Warlord Kolkanis - Vanilla Whites 9-10 Level Range'), +(5808, 3, 1010809, 0, 6, 'Warlord Kolkanis - Vanilla Whites 8-9 Level Range'), +(5808, 4, 1020812, 0, 6, 'Warlord Kolkanis - Vanilla Greens 8-12 Level Range'), +(5809, 2, 1010910, 0, 6, 'Watch Commander Zalaphil - Vanilla Whites 9-10 Level Range'), +(5809, 3, 1010809, 0, 6, 'Watch Commander Zalaphil - Vanilla Whites 8-9 Level Range'), +(5809, 4, 1020812, 0, 6, 'Watch Commander Zalaphil - Vanilla Greens 8-12 Level Range'), +(5823, 2, 1011112, 0, 6, 'Death Flayer - Vanilla Whites 11-12 Level Range'), +(5823, 3, 1011011, 0, 6, 'Death Flayer - Vanilla Whites 10-11 Level Range'), +(5823, 4, 1021115, 0, 6, 'Death Flayer - Vanilla Greens 11-15 Level Range'), +(5823, 5, 1021014, 0, 6, 'Death Flayer - Vanilla Greens 10-14 Level Range'), +(5823, 6, 1020812, 0, 6, 'Death Flayer - Vanilla Greens 8-12 Level Range'), +(5826, 2, 1010910, 0, 6, 'Geolord Mottle - Vanilla Whites 9-10 Level Range'), +(5826, 3, 1010809, 0, 6, 'Geolord Mottle - Vanilla Whites 8-9 Level Range'), +(5826, 4, 1020812, 0, 6, 'Geolord Mottle - Vanilla Greens 8-12 Level Range'), +(5829, 2, 1021317, 0, 6, 'Snort the Heckler - Vanilla Greens 13-17 Level Range'), +(5829, 3, 1021418, 0, 6, 'Snort the Heckler - Vanilla Greens 14-18 Level Range'), +(5829, 4, 1021519, 0, 6, 'Snort the Heckler - Vanilla Greens 15-19 Level Range'), +(5829, 5, 1021620, 0, 6, 'Snort the Heckler - Vanilla Greens 16-20 Level Range'), +(5829, 6, 1021721, 0, 6, 'Snort the Heckler - Vanilla Greens 17-21 Level Range'), +(5832, 4, 1022327, 0, 6, 'Thunderstomp - Vanilla Greens 23-27 Level Range'), +(5832, 5, 1022428, 0, 6, 'Thunderstomp - Vanilla Greens 24-28 Level Range'), +(5832, 6, 1022125, 0, 6, 'Thunderstomp - Vanilla Greens 21-25 Level Range'), +(5832, 7, 1022024, 0, 6, 'Thunderstomp - Vanilla Greens 20-24 Level Range'), +(5832, 8, 1022226, 0, 6, 'Thunderstomp - Vanilla Greens 22-26 Level Range'), +(5834, 2, 1012125, 0, 6, 'Azzere the Skyblade - Vanilla Whites 21-25 Level Range'), +(5834, 3, 1022327, 0, 6, 'Azzere the Skyblade - Vanilla Greens 23-27 Level Range'), +(5834, 4, 1022428, 0, 6, 'Azzere the Skyblade - Vanilla Greens 24-28 Level Range'), +(5834, 5, 1022125, 0, 6, 'Azzere the Skyblade - Vanilla Greens 21-25 Level Range'), +(5834, 6, 1022226, 0, 6, 'Azzere the Skyblade - Vanilla Greens 22-26 Level Range'), +(5834, 7, 1022529, 0, 6, 'Azzere the Skyblade - Vanilla Greens 25-29 Level Range'), +(5835, 3 , 1011822, 0, 6, 'Foreman Grills - Vanilla Whites 18-22 Level Range'), +(5835, 4 , 1021418, 0, 6, 'Foreman Grills - Vanilla Greens 14-18 Level Range'), +(5835, 5 , 1021519, 0, 6, 'Foreman Grills - Vanilla Greens 15-19 Level Range'), +(5835, 6 , 1021620, 0, 6, 'Foreman Grills - Vanilla Greens 16-20 Level Range'), +(5835, 7 , 1021721, 0, 6, 'Foreman Grills - Vanilla Greens 17-21 Level Range'), +(5835, 8 , 1021822, 0, 6, 'Foreman Grills - Vanilla Greens 18-22 Level Range'), +(5835, 9 , 1011923, 0, 6, 'Foreman Grills - Vanilla Whites 19-23 Level Range'), +(5835, 10, 1021923, 0, 6, 'Foreman Grills - Vanilla Greens 19-23 Level Range'), +(5836, 2, 1011822, 0, 6, 'Engineer Whirleygig - Vanilla Whites 18-22 Level Range'), +(5836, 3, 1011923, 0, 6, 'Engineer Whirleygig - Vanilla Whites 19-23 Level Range'), +(5836, 4, 1021519, 0, 6, 'Engineer Whirleygig - Vanilla Greens 15-19 Level Range'), +(5836, 5, 1021620, 0, 6, 'Engineer Whirleygig - Vanilla Greens 16-20 Level Range'), +(5836, 6, 1021721, 0, 6, 'Engineer Whirleygig - Vanilla Greens 17-21 Level Range'), +(5836, 7, 1021822, 0, 6, 'Engineer Whirleygig - Vanilla Greens 18-22 Level Range'), +(5836, 8, 1021923, 0, 6, 'Engineer Whirleygig - Vanilla Greens 19-23 Level Range'), +(5837, 2, 1011415, 0, 6, 'Stonearm - Vanilla Whites 14-15 Level Range'), +(5837, 3, 1021317, 0, 6, 'Stonearm - Vanilla Greens 13-17 Level Range'), +(5837, 4, 1021115, 0, 6, 'Stonearm - Vanilla Greens 11-15 Level Range'), +(5837, 5, 1021216, 0, 6, 'Stonearm - Vanilla Greens 12-16 Level Range'), +(5837, 6, 1021418, 0, 6, 'Stonearm - Vanilla Greens 14-18 Level Range'), +(5837, 7, 1021519, 0, 6, 'Stonearm - Vanilla Greens 15-19 Level Range'), +(5838, 2, 1021317, 0, 1, 'Brokespear - Vanilla Greens 13-17 Level Range'), +(5838, 3, 1021418, 0, 1, 'Brokespear - Vanilla Greens 14-18 Level Range'), +(5838, 4, 1021519, 0, 1, 'Brokespear - Vanilla Greens 15-19 Level Range'), +(5838, 5, 1021620, 0, 1, 'Brokespear - Vanilla Greens 16-20 Level Range'), +(5838, 6, 1021721, 0, 1, 'Brokespear - Vanilla Greens 17-21 Level Range'), +(5847, 2, 1012024, 0, 1, 'Heggin Stonewhisker - Vanilla Whites 20-24 Level Range'), +(5847, 3, 1012125, 0, 1, 'Heggin Stonewhisker - Vanilla Whites 21-25 Level Range'), +(5847, 4, 1022327, 0, 1, 'Heggin Stonewhisker - Vanilla Greens 23-27 Level Range'), +(5847, 5, 1022428, 0, 1, 'Heggin Stonewhisker - Vanilla Greens 24-28 Level Range'), +(5847, 6, 1022125, 0, 1, 'Heggin Stonewhisker - Vanilla Greens 21-25 Level Range'), +(5847, 7, 1022024, 0, 1, 'Heggin Stonewhisker - Vanilla Greens 20-24 Level Range'), +(5847, 8, 1022226, 0, 1, 'Heggin Stonewhisker - Vanilla Greens 22-26 Level Range'), +(5848, 2, 1012125, 0, 6, 'Malgin Barleybrew - Vanilla Whites 21-25 Level Range'), +(5848, 3, 1022327, 0, 6, 'Malgin Barleybrew - Vanilla Greens 23-27 Level Range'), +(5848, 4, 1022428, 0, 6, 'Malgin Barleybrew - Vanilla Greens 24-28 Level Range'), +(5848, 5, 1022125, 0, 6, 'Malgin Barleybrew - Vanilla Greens 21-25 Level Range'), +(5848, 6, 1022226, 0, 6, 'Malgin Barleybrew - Vanilla Greens 22-26 Level Range'), +(5848, 7, 1022529, 0, 6, 'Malgin Barleybrew - Vanilla Greens 25-29 Level Range'), +(5849, 2, 1012125, 0, 6, 'Digger Flameforge - Vanilla Whites 21-25 Level Range'), +(5849, 3, 1022327, 0, 6, 'Digger Flameforge - Vanilla Greens 23-27 Level Range'), +(5849, 4, 1022428, 0, 6, 'Digger Flameforge - Vanilla Greens 24-28 Level Range'), +(5849, 5, 1022125, 0, 6, 'Digger Flameforge - Vanilla Greens 21-25 Level Range'), +(5849, 6, 1022226, 0, 6, 'Digger Flameforge - Vanilla Greens 22-26 Level Range'), +(5849, 7, 1022529, 0, 6, 'Digger Flameforge - Vanilla Greens 25-29 Level Range'), +(5863, 2, 1011822, 0, 1, 'Geopriest Gukk\'rok - Vanilla Whites 18-22 Level Range'), +(5863, 3, 1011923, 0, 1, 'Geopriest Gukk\'rok - Vanilla Whites 19-23 Level Range'), +(5863, 4, 1021519, 0, 1, 'Geopriest Gukk\'rok - Vanilla Greens 15-19 Level Range'), +(5863, 5, 1021620, 0, 1, 'Geopriest Gukk\'rok - Vanilla Greens 16-20 Level Range'), +(5863, 6, 1021721, 0, 1, 'Geopriest Gukk\'rok - Vanilla Greens 17-21 Level Range'), +(5863, 7, 1021822, 0, 1, 'Geopriest Gukk\'rok - Vanilla Greens 18-22 Level Range'), +(5863, 8, 1021923, 0, 1, 'Geopriest Gukk\'rok - Vanilla Greens 19-23 Level Range'), +(5865, 2, 1011314, 0, 6, 'Dishu - Vanilla Whites 13-14 Level Range'), +(5865, 3, 1011213, 0, 6, 'Dishu - Vanilla Whites 12-13 Level Range'), +(5865, 4, 1021317, 0, 6, 'Dishu - Vanilla Greens 13-17 Level Range'), +(5865, 5, 1021115, 0, 6, 'Dishu - Vanilla Greens 11-15 Level Range'), +(5865, 6, 1021014, 0, 6, 'Dishu - Vanilla Greens 10-14 Level Range'), +(5865, 7, 1021216, 0, 6, 'Dishu - Vanilla Greens 12-16 Level Range'), +(5928, 2, 1022731, 0, 6, 'Sorrow Wing - Vanilla Greens 27-31 Level Range'), +(5928, 3, 1022327, 0, 6, 'Sorrow Wing - Vanilla Greens 23-27 Level Range'), +(5928, 4, 1022428, 0, 6, 'Sorrow Wing - Vanilla Greens 24-28 Level Range'), +(5928, 5, 1022630, 0, 6, 'Sorrow Wing - Vanilla Greens 26-30 Level Range'), +(5928, 6, 1022529, 0, 6, 'Sorrow Wing - Vanilla Greens 25-29 Level Range'), +(5933, 2, 1023034, 0, 6, 'Achellios the Banished - Vanilla Greens 30-34 Level Range'), +(5933, 3, 1023135, 0, 6, 'Achellios the Banished - Vanilla Greens 31-35 Level Range'), +(5933, 4, 1022731, 0, 6, 'Achellios the Banished - Vanilla Greens 27-31 Level Range'), +(5933, 5, 1022832, 0, 6, 'Achellios the Banished - Vanilla Greens 28-32 Level Range'), +(5933, 6, 1022933, 0, 6, 'Achellios the Banished - Vanilla Greens 29-33 Level Range'), +(6118, 2, 1024448, 0, 6, 'Varo\'then\'s Ghost - Vanilla Greens 44-48 Level Range'), +(6118, 3, 1024549, 0, 6, 'Varo\'then\'s Ghost - Vanilla Greens 45-49 Level Range'), +(6118, 4, 1024751, 0, 6, 'Varo\'then\'s Ghost - Vanilla Greens 47-51 Level Range'), +(6118, 5, 1024852, 0, 6, 'Varo\'then\'s Ghost - Vanilla Greens 48-52 Level Range'), +(6118, 6, 1024650, 0, 6, 'Varo\'then\'s Ghost - Vanilla Greens 46-50 Level Range'), +(6581, 2, 1024751, 0, 6, 'Ravasaur Matriarch - Vanilla Greens 47-51 Level Range'), +(6581, 3, 1025054, 0, 6, 'Ravasaur Matriarch - Vanilla Greens 50-54 Level Range'), +(6581, 4, 1024852, 0, 6, 'Ravasaur Matriarch - Vanilla Greens 48-52 Level Range'), +(6581, 5, 1024953, 0, 6, 'Ravasaur Matriarch - Vanilla Greens 49-53 Level Range'), +(6581, 6, 1024650, 0, 6, 'Ravasaur Matriarch - Vanilla Greens 46-50 Level Range'), +(6582, 2, 1025458, 0, 6, 'Clutchmother Zavas - Vanilla Greens 54-58 Level Range'), +(6582, 3, 1025155, 0, 6, 'Clutchmother Zavas - Vanilla Greens 51-55 Level Range'), +(6582, 4, 1025357, 0, 6, 'Clutchmother Zavas - Vanilla Greens 53-57 Level Range'), +(6582, 5, 1025256, 0, 6, 'Clutchmother Zavas - Vanilla Greens 52-56 Level Range'), +(6582, 6, 1025054, 0, 6, 'Clutchmother Zavas - Vanilla Greens 50-54 Level Range'), +(6585, 3, 1025155, 0, 6, 'Uhk\'loc - Vanilla Greens 51-55 Level Range'), +(6585, 4, 1025256, 0, 6, 'Uhk\'loc - Vanilla Greens 52-56 Level Range'), +(6585, 5, 1025054, 0, 6, 'Uhk\'loc - Vanilla Greens 50-54 Level Range'), +(6585, 6, 1024852, 0, 6, 'Uhk\'loc - Vanilla Greens 48-52 Level Range'), +(6585, 7, 1024953, 0, 6, 'Uhk\'loc - Vanilla Greens 49-53 Level Range'), +(6585, 8, 1025357, 0, 6, 'Uhk\'loc - Vanilla Greens 53-57 Level Range'), +(6647, 3, 1025155, 0, 6, 'Magister Hawkhelm - Vanilla Greens 51-55 Level Range'), +(6647, 4, 1024751, 0, 6, 'Magister Hawkhelm - Vanilla Greens 47-51 Level Range'), +(6647, 5, 1025054, 0, 6, 'Magister Hawkhelm - Vanilla Greens 50-54 Level Range'), +(6647, 6, 1024852, 0, 6, 'Magister Hawkhelm - Vanilla Greens 48-52 Level Range'), +(6647, 7, 1024953, 0, 6, 'Magister Hawkhelm - Vanilla Greens 49-53 Level Range'), +(6647, 8, 1025256, 0, 6, 'Magister Hawkhelm - Vanilla Greens 52-56 Level Range'), +(6648, 2, 1024751, 0, 6, 'Antilos - Vanilla Greens 47-51 Level Range'), +(6648, 3, 1025054, 0, 6, 'Antilos - Vanilla Greens 50-54 Level Range'), +(6648, 4, 1024852, 0, 6, 'Antilos - Vanilla Greens 48-52 Level Range'), +(6648, 5, 1024953, 0, 6, 'Antilos - Vanilla Greens 49-53 Level Range'), +(6648, 6, 1024650, 0, 6, 'Antilos - Vanilla Greens 46-50 Level Range'), +(6649, 2, 1025155, 0, 6, 'Lady Sesspira - Vanilla Greens 51-55 Level Range'), +(6649, 3, 1024751, 0, 6, 'Lady Sesspira - Vanilla Greens 47-51 Level Range'), +(6649, 4, 1025054, 0, 6, 'Lady Sesspira - Vanilla Greens 50-54 Level Range'), +(6649, 5, 1024852, 0, 6, 'Lady Sesspira - Vanilla Greens 48-52 Level Range'), +(6649, 6, 1024953, 0, 6, 'Lady Sesspira - Vanilla Greens 49-53 Level Range'), +(6650, 3, 1024751, 0, 1, 'General Fangferror - Vanilla Greens 47-51 Level Range'), +(6650, 4, 1025054, 0, 1, 'General Fangferror - Vanilla Greens 50-54 Level Range'), +(6650, 5, 1024852, 0, 1, 'General Fangferror - Vanilla Greens 48-52 Level Range'), +(6650, 6, 1024953, 0, 1, 'General Fangferror - Vanilla Greens 49-53 Level Range'), +(6650, 7, 1024650, 0, 1, 'General Fangferror - Vanilla Greens 46-50 Level Range'), +(6650, 8, 1025155, 0, 1, 'General Fangferror - Vanilla Greens 51-55 Level Range'), +(6651, 3, 1024549, 0, 6, 'Gatekeeper Rageroar - Vanilla Greens 45-49 Level Range'), +(6651, 4, 1024751, 0, 6, 'Gatekeeper Rageroar - Vanilla Greens 47-51 Level Range'), +(6651, 5, 1024852, 0, 6, 'Gatekeeper Rageroar - Vanilla Greens 48-52 Level Range'), +(6651, 6, 1024953, 0, 6, 'Gatekeeper Rageroar - Vanilla Greens 49-53 Level Range'), +(6651, 7, 1024650, 0, 6, 'Gatekeeper Rageroar - Vanilla Greens 46-50 Level Range'), +(6651, 8, 1025054, 0, 6, 'Gatekeeper Rageroar - Vanilla Greens 50-54 Level Range'), +(6652, 3, 1025155, 0, 6, 'Master Feardred - Vanilla Greens 51-55 Level Range'), +(6652, 4, 1024751, 0, 6, 'Master Feardred - Vanilla Greens 47-51 Level Range'), +(6652, 5, 1025054, 0, 6, 'Master Feardred - Vanilla Greens 50-54 Level Range'), +(6652, 6, 1024852, 0, 6, 'Master Feardred - Vanilla Greens 48-52 Level Range'), +(6652, 7, 1024953, 0, 6, 'Master Feardred - Vanilla Greens 49-53 Level Range'), +(6652, 8, 1025256, 0, 6, 'Master Feardred - Vanilla Greens 52-56 Level Range'), +(7015, 2, 1021317, 0, 6, 'Flagglemurk the Cruel - Vanilla Greens 13-17 Level Range'), +(7015, 3, 1021216, 0, 6, 'Flagglemurk the Cruel - Vanilla Greens 12-16 Level Range'), +(7015, 4, 1021418, 0, 6, 'Flagglemurk the Cruel - Vanilla Greens 14-18 Level Range'), +(7015, 5, 1021519, 0, 6, 'Flagglemurk the Cruel - Vanilla Greens 15-19 Level Range'), +(7015, 6, 1021620, 0, 6, 'Flagglemurk the Cruel - Vanilla Greens 16-20 Level Range'), +(7017, 3, 1011415, 5, 2, 'Lord Sinslayer - Vanilla Whites 14-15 Level Range'), +(7017, 4, 1021317, 0, 6, 'Lord Sinslayer - Vanilla Greens 13-17 Level Range'), +(7017, 5, 1021115, 0, 6, 'Lord Sinslayer - Vanilla Greens 11-15 Level Range'), +(7017, 6, 1021216, 0, 6, 'Lord Sinslayer - Vanilla Greens 12-16 Level Range'), +(7017, 7, 1021418, 0, 6, 'Lord Sinslayer - Vanilla Greens 14-18 Level Range'), +(7017, 8, 1021519, 0, 6, 'Lord Sinslayer - Vanilla Greens 15-19 Level Range'), +(7017, 9, 1021620, 0, 6, 'Lord Sinslayer - Vanilla Greens 16-20 Level Range'), +(7895, 2, 1023438, 0, 6, 'Ambassador Bloodrage - Vanilla Greens 34-38 Level Range'), +(7895, 3, 1023135, 0, 6, 'Ambassador Bloodrage - Vanilla Greens 31-35 Level Range'), +(7895, 4, 1023337, 0, 6, 'Ambassador Bloodrage - Vanilla Greens 33-37 Level Range'), +(7895, 5, 1023539, 0, 6, 'Ambassador Bloodrage - Vanilla Greens 35-39 Level Range'), +(7895, 6, 1023236, 0, 6, 'Ambassador Bloodrage - Vanilla Greens 32-36 Level Range'), +(8201, 2, 1024751, 0, 1, 'Omgorn the Lost - Vanilla Greens 47-51 Level Range'), +(8201, 3, 1025054, 0, 1, 'Omgorn the Lost - Vanilla Greens 50-54 Level Range'), +(8201, 4, 1024852, 0, 1, 'Omgorn the Lost - Vanilla Greens 48-52 Level Range'), +(8201, 5, 1024953, 0, 1, 'Omgorn the Lost - Vanilla Greens 49-53 Level Range'), +(8201, 6, 1024650, 0, 1, 'Omgorn the Lost - Vanilla Greens 46-50 Level Range'), +(8202, 2, 1024448, 0, 6, 'Cyclok the Mad - Vanilla Greens 44-48 Level Range'), +(8202, 3, 1024549, 0, 6, 'Cyclok the Mad - Vanilla Greens 45-49 Level Range'), +(8202, 4, 1024751, 0, 6, 'Cyclok the Mad - Vanilla Greens 47-51 Level Range'), +(8202, 5, 1024852, 0, 6, 'Cyclok the Mad - Vanilla Greens 48-52 Level Range'), +(8202, 6, 1024650, 0, 6, 'Cyclok the Mad - Vanilla Greens 46-50 Level Range'), +(8203, 2, 1024347, 0, 6, 'Kregg Keelhaul - Vanilla Greens 43-47 Level Range'), +(8203, 3, 1024448, 0, 6, 'Kregg Keelhaul - Vanilla Greens 44-48 Level Range'), +(8203, 4, 1024549, 0, 6, 'Kregg Keelhaul - Vanilla Greens 45-49 Level Range'), +(8203, 5, 1024751, 0, 6, 'Kregg Keelhaul - Vanilla Greens 47-51 Level Range'), +(8203, 6, 1024650, 0, 6, 'Kregg Keelhaul - Vanilla Greens 46-50 Level Range'), +(8204, 2, 1024751, 0, 6, 'Soriid the Devourer - Vanilla Greens 47-51 Level Range'), +(8204, 3, 1025054, 0, 6, 'Soriid the Devourer - Vanilla Greens 50-54 Level Range'), +(8204, 4, 1024852, 0, 6, 'Soriid the Devourer - Vanilla Greens 48-52 Level Range'), +(8204, 5, 1024953, 0, 6, 'Soriid the Devourer - Vanilla Greens 49-53 Level Range'), +(8204, 6, 1024650, 0, 6, 'Soriid the Devourer - Vanilla Greens 46-50 Level Range'), +(8205, 2, 1024751, 0, 6, 'Haarka the Ravenous - Vanilla Greens 47-51 Level Range'), +(8205, 3, 1025054, 0, 6, 'Haarka the Ravenous - Vanilla Greens 50-54 Level Range'), +(8205, 4, 1024852, 0, 6, 'Haarka the Ravenous - Vanilla Greens 48-52 Level Range'), +(8205, 5, 1024953, 0, 6, 'Haarka the Ravenous - Vanilla Greens 49-53 Level Range'), +(8205, 6, 1024650, 0, 6, 'Haarka the Ravenous - Vanilla Greens 46-50 Level Range'), +(8207, 2, 1024347, 0, 6, 'Greater Firebird - Vanilla Greens 43-47 Level Range'), +(8207, 3, 1024448, 0, 6, 'Greater Firebird - Vanilla Greens 44-48 Level Range'), +(8207, 4, 1024549, 0, 6, 'Greater Firebird - Vanilla Greens 45-49 Level Range'), +(8207, 5, 1024246, 0, 6, 'Greater Firebird - Vanilla Greens 42-46 Level Range'), +(8207, 6, 1024650, 0, 6, 'Greater Firebird - Vanilla Greens 46-50 Level Range'), +(8208, 2, 1024145, 0, 6, 'Murderous Blisterpaw - Vanilla Greens 41-45 Level Range'), +(8208, 3, 1024347, 0, 6, 'Murderous Blisterpaw - Vanilla Greens 43-47 Level Range'), +(8208, 4, 1024246, 0, 6, 'Murderous Blisterpaw - Vanilla Greens 42-46 Level Range'), +(8208, 5, 1023943, 0, 6, 'Murderous Blisterpaw - Vanilla Greens 39-43 Level Range'), +(8208, 6, 1024044, 0, 6, 'Murderous Blisterpaw - Vanilla Greens 40-44 Level Range'), +(8210, 2, 1024145, 0, 6, 'Razortalon - Vanilla Greens 41-45 Level Range'), +(8210, 3, 1024347, 0, 6, 'Razortalon - Vanilla Greens 43-47 Level Range'), +(8210, 4, 1024448, 0, 6, 'Razortalon - Vanilla Greens 44-48 Level Range'), +(8210, 5, 1024246, 0, 6, 'Razortalon - Vanilla Greens 42-46 Level Range'), +(8210, 6, 1024044, 0, 6, 'Razortalon - Vanilla Greens 40-44 Level Range'), +(8211, 2, 1024145, 0, 6, 'Old Cliff Jumper - Vanilla Greens 41-45 Level Range'), +(8211, 3, 1024246, 0, 6, 'Old Cliff Jumper - Vanilla Greens 42-46 Level Range'), +(8211, 4, 1023842, 0, 6, 'Old Cliff Jumper - Vanilla Greens 38-42 Level Range'), +(8211, 5, 1023943, 0, 6, 'Old Cliff Jumper - Vanilla Greens 39-43 Level Range'), +(8211, 6, 1024044, 0, 6, 'Old Cliff Jumper - Vanilla Greens 40-44 Level Range'), +(8212, 2, 1024549, 0, 6, 'The Reak - Vanilla Greens 45-49 Level Range'), +(8212, 3, 1024751, 0, 6, 'The Reak - Vanilla Greens 47-51 Level Range'), +(8212, 4, 1024852, 0, 6, 'The Reak - Vanilla Greens 48-52 Level Range'), +(8212, 5, 1024953, 0, 6, 'The Reak - Vanilla Greens 49-53 Level Range'), +(8212, 6, 1024650, 0, 6, 'The Reak - Vanilla Greens 46-50 Level Range'), +(8213, 2, 1025155, 0, 6, 'Ironback - Vanilla Greens 51-55 Level Range'), +(8213, 3, 1024751, 0, 6, 'Ironback - Vanilla Greens 47-51 Level Range'), +(8213, 4, 1025054, 0, 6, 'Ironback - Vanilla Greens 50-54 Level Range'), +(8213, 5, 1024852, 0, 6, 'Ironback - Vanilla Greens 48-52 Level Range'), +(8213, 6, 1024953, 0, 6, 'Ironback - Vanilla Greens 49-53 Level Range'), +(8214, 2, 1024549, 0, 6, 'Jalinde Summerdrake - Vanilla Greens 45-49 Level Range'), +(8214, 3, 1024751, 0, 6, 'Jalinde Summerdrake - Vanilla Greens 47-51 Level Range'), +(8214, 4, 1024852, 0, 6, 'Jalinde Summerdrake - Vanilla Greens 48-52 Level Range'), +(8214, 5, 1024953, 0, 6, 'Jalinde Summerdrake - Vanilla Greens 49-53 Level Range'), +(8214, 6, 1024650, 0, 6, 'Jalinde Summerdrake - Vanilla Greens 46-50 Level Range'), +(8216, 2, 1024448, 0, 6, 'Retherokk the Berserker - Vanilla Greens 44-48 Level Range'), +(8216, 3, 1024549, 0, 6, 'Retherokk the Berserker - Vanilla Greens 45-49 Level Range'), +(8216, 4, 1024751, 0, 6, 'Retherokk the Berserker - Vanilla Greens 47-51 Level Range'), +(8216, 5, 1024852, 0, 6, 'Retherokk the Berserker - Vanilla Greens 48-52 Level Range'), +(8216, 6, 1024650, 0, 6, 'Retherokk the Berserker - Vanilla Greens 46-50 Level Range'), +(8218, 2, 1024145, 0, 6, 'Witherheart the Stalker - Vanilla Greens 41-45 Level Range'), +(8218, 3, 1024347, 0, 6, 'Witherheart the Stalker - Vanilla Greens 43-47 Level Range'), +(8218, 4, 1024448, 0, 6, 'Witherheart the Stalker - Vanilla Greens 44-48 Level Range'), +(8218, 5, 1024549, 0, 6, 'Witherheart the Stalker - Vanilla Greens 45-49 Level Range'), +(8218, 6, 1024246, 0, 6, 'Witherheart the Stalker - Vanilla Greens 42-46 Level Range'), +(8219, 2, 1024145, 0, 6, 'Zul\'arek Hatefowler - Vanilla Greens 41-45 Level Range'), +(8219, 3, 1024347, 0, 6, 'Zul\'arek Hatefowler - Vanilla Greens 43-47 Level Range'), +(8219, 4, 1024246, 0, 6, 'Zul\'arek Hatefowler - Vanilla Greens 42-46 Level Range'), +(8219, 5, 1023943, 0, 6, 'Zul\'arek Hatefowler - Vanilla Greens 39-43 Level Range'), +(8219, 6, 1024044, 0, 6, 'Zul\'arek Hatefowler - Vanilla Greens 40-44 Level Range'), +(8277, 2, 1024448, 0, 6, 'Rekk\'tilac - Vanilla Greens 44-48 Level Range'), +(8277, 3, 1024549, 0, 6, 'Rekk\'tilac - Vanilla Greens 45-49 Level Range'), +(8277, 4, 1024751, 0, 6, 'Rekk\'tilac - Vanilla Greens 47-51 Level Range'), +(8277, 5, 1024852, 0, 6, 'Rekk\'tilac - Vanilla Greens 48-52 Level Range'), +(8277, 6, 1024650, 0, 6, 'Rekk\'tilac - Vanilla Greens 46-50 Level Range'), +(8278, 2, 1024751, 0, 6, 'Smoldar - Vanilla Greens 47-51 Level Range'), +(8278, 3, 1025054, 0, 6, 'Smoldar - Vanilla Greens 50-54 Level Range'), +(8278, 4, 1024852, 0, 6, 'Smoldar - Vanilla Greens 48-52 Level Range'), +(8278, 5, 1024953, 0, 6, 'Smoldar - Vanilla Greens 49-53 Level Range'), +(8278, 6, 1024650, 0, 6, 'Smoldar - Vanilla Greens 46-50 Level Range'), +(8279, 2, 1024347, 0, 6, 'Faulty War Golem - Vanilla Greens 43-47 Level Range'), +(8279, 3, 1024448, 0, 6, 'Faulty War Golem - Vanilla Greens 44-48 Level Range'), +(8279, 4, 1024549, 0, 6, 'Faulty War Golem - Vanilla Greens 45-49 Level Range'), +(8279, 5, 1024246, 0, 6, 'Faulty War Golem - Vanilla Greens 42-46 Level Range'), +(8279, 6, 1024650, 0, 6, 'Faulty War Golem - Vanilla Greens 46-50 Level Range'), +(8280, 2, 1024347, 0, 6, 'Shleipnarr - Vanilla Greens 43-47 Level Range'), +(8280, 3, 1024448, 0, 6, 'Shleipnarr - Vanilla Greens 44-48 Level Range'), +(8280, 4, 1024549, 0, 6, 'Shleipnarr - Vanilla Greens 45-49 Level Range'), +(8280, 5, 1024751, 0, 6, 'Shleipnarr - Vanilla Greens 47-51 Level Range'), +(8280, 6, 1024650, 0, 6, 'Shleipnarr - Vanilla Greens 46-50 Level Range'), +(8281, 2, 1024549, 0, 6, 'Scald - Vanilla Greens 45-49 Level Range'), +(8281, 3, 1024751, 0, 6, 'Scald - Vanilla Greens 47-51 Level Range'), +(8281, 4, 1024852, 0, 6, 'Scald - Vanilla Greens 48-52 Level Range'), +(8281, 5, 1024953, 0, 6, 'Scald - Vanilla Greens 49-53 Level Range'), +(8281, 6, 1024650, 0, 6, 'Scald - Vanilla Greens 46-50 Level Range'), +(8283, 2, 1024751, 0, 6, 'Slave Master Blackheart - Vanilla Greens 47-51 Level Range'), +(8283, 3, 1025054, 0, 6, 'Slave Master Blackheart - Vanilla Greens 50-54 Level Range'), +(8283, 4, 1024852, 0, 6, 'Slave Master Blackheart - Vanilla Greens 48-52 Level Range'), +(8283, 5, 1024953, 0, 6, 'Slave Master Blackheart - Vanilla Greens 49-53 Level Range'), +(8283, 6, 1024650, 0, 6, 'Slave Master Blackheart - Vanilla Greens 46-50 Level Range'), +(8296, 2, 1024448, 0, 6, 'Mojo the Twisted - Vanilla Greens 44-48 Level Range'), +(8296, 3, 1024549, 0, 6, 'Mojo the Twisted - Vanilla Greens 45-49 Level Range'), +(8296, 4, 1024751, 0, 6, 'Mojo the Twisted - Vanilla Greens 47-51 Level Range'), +(8296, 5, 1024852, 0, 6, 'Mojo the Twisted - Vanilla Greens 48-52 Level Range'), +(8296, 6, 1024650, 0, 6, 'Mojo the Twisted - Vanilla Greens 46-50 Level Range'), +(8297, 2, 1025660, 0, 6, 'Magronos the Unyielding - Vanilla Greens 56-60 Level Range'), +(8297, 3, 1025458, 0, 6, 'Magronos the Unyielding - Vanilla Greens 54-58 Level Range'), +(8297, 4, 1025559, 0, 6, 'Magronos the Unyielding - Vanilla Greens 55-59 Level Range'), +(8297, 5, 1025357, 0, 6, 'Magronos the Unyielding - Vanilla Greens 53-57 Level Range'), +(8297, 6, 1025256, 0, 6, 'Magronos the Unyielding - Vanilla Greens 52-56 Level Range'), +(8298, 2, 1025458, 0, 6, 'Akubar the Seer - Vanilla Greens 54-58 Level Range'), +(8298, 3, 1025155, 0, 6, 'Akubar the Seer - Vanilla Greens 51-55 Level Range'), +(8298, 4, 1025357, 0, 6, 'Akubar the Seer - Vanilla Greens 53-57 Level Range'), +(8298, 5, 1025256, 0, 6, 'Akubar the Seer - Vanilla Greens 52-56 Level Range'), +(8298, 6, 1025054, 0, 6, 'Akubar the Seer - Vanilla Greens 50-54 Level Range'), +(8299, 2, 1025155, 0, 6, 'Spiteflayer - Vanilla Greens 51-55 Level Range'), +(8299, 3, 1025256, 0, 6, 'Spiteflayer - Vanilla Greens 52-56 Level Range'), +(8299, 4, 1025054, 0, 6, 'Spiteflayer - Vanilla Greens 50-54 Level Range'), +(8299, 5, 1024852, 0, 6, 'Spiteflayer - Vanilla Greens 48-52 Level Range'), +(8299, 6, 1024953, 0, 6, 'Spiteflayer - Vanilla Greens 49-53 Level Range'), +(8300, 2, 1025155, 0, 6, 'Ravage - Vanilla Greens 51-55 Level Range'), +(8300, 3, 1024751, 0, 6, 'Ravage - Vanilla Greens 47-51 Level Range'), +(8300, 4, 1025054, 0, 6, 'Ravage - Vanilla Greens 50-54 Level Range'), +(8300, 5, 1024852, 0, 6, 'Ravage - Vanilla Greens 48-52 Level Range'), +(8300, 6, 1024953, 0, 6, 'Ravage - Vanilla Greens 49-53 Level Range'), +(8301, 2, 1025155, 0, 6, 'Clack the Reaver - Vanilla Greens 51-55 Level Range'), +(8301, 3, 1025357, 0, 6, 'Clack the Reaver - Vanilla Greens 53-57 Level Range'), +(8301, 4, 1025256, 0, 6, 'Clack the Reaver - Vanilla Greens 52-56 Level Range'), +(8301, 5, 1025054, 0, 6, 'Clack the Reaver - Vanilla Greens 50-54 Level Range'), +(8301, 6, 1024953, 0, 6, 'Clack the Reaver - Vanilla Greens 49-53 Level Range'), +(8302, 2, 1024549, 0, 6, 'Deatheye - Vanilla Greens 45-49 Level Range'), +(8302, 3, 1024751, 0, 6, 'Deatheye - Vanilla Greens 47-51 Level Range'), +(8302, 4, 1024852, 0, 6, 'Deatheye - Vanilla Greens 48-52 Level Range'), +(8302, 5, 1024953, 0, 6, 'Deatheye - Vanilla Greens 49-53 Level Range'), +(8302, 6, 1024650, 0, 6, 'Deatheye - Vanilla Greens 46-50 Level Range'), +(8303, 2, 1024751, 0, 6, 'Grunter - Vanilla Greens 47-51 Level Range'), +(8303, 3, 1025054, 0, 6, 'Grunter - Vanilla Greens 50-54 Level Range'), +(8303, 4, 1024852, 0, 6, 'Grunter - Vanilla Greens 48-52 Level Range'), +(8303, 5, 1024953, 0, 6, 'Grunter - Vanilla Greens 49-53 Level Range'), +(8303, 6, 1024650, 0, 6, 'Grunter - Vanilla Greens 46-50 Level Range'), +(8304, 2, 1025660, 0, 6, 'Dreadscorn - Vanilla Greens 56-60 Level Range'), +(8304, 3, 1025458, 0, 6, 'Dreadscorn - Vanilla Greens 54-58 Level Range'), +(8304, 4, 1025559, 0, 6, 'Dreadscorn - Vanilla Greens 55-59 Level Range'), +(8304, 5, 1025357, 0, 6, 'Dreadscorn - Vanilla Greens 53-57 Level Range'), +(8304, 6, 1025761, 0, 6, 'Dreadscorn - Vanilla Greens 57-61 Level Range'), +(8660, 2, 1024448, 0, 6, 'The Evalcharr - Vanilla Greens 44-48 Level Range'), +(8660, 3, 1024549, 0, 6, 'The Evalcharr - Vanilla Greens 45-49 Level Range'), +(8660, 4, 1024751, 0, 6, 'The Evalcharr - Vanilla Greens 47-51 Level Range'), +(8660, 5, 1024852, 0, 6, 'The Evalcharr - Vanilla Greens 48-52 Level Range'), +(8660, 6, 1024650, 0, 6, 'The Evalcharr - Vanilla Greens 46-50 Level Range'), +(8924, 2, 1024751, 0, 1, 'The Behemoth - Vanilla Greens 47-51 Level Range'), +(8924, 3, 1025054, 0, 1, 'The Behemoth - Vanilla Greens 50-54 Level Range'), +(8924, 4, 1024852, 0, 1, 'The Behemoth - Vanilla Greens 48-52 Level Range'), +(8924, 5, 1024953, 0, 1, 'The Behemoth - Vanilla Greens 49-53 Level Range'), +(8924, 6, 1024650, 0, 1, 'The Behemoth - Vanilla Greens 46-50 Level Range'), +(8978, 2, 1025660, 0, 6, 'Thauris Balgarr - Vanilla Greens 56-60 Level Range'), +(8978, 3, 1025458, 0, 6, 'Thauris Balgarr - Vanilla Greens 54-58 Level Range'), +(8978, 4, 1025559, 0, 6, 'Thauris Balgarr - Vanilla Greens 55-59 Level Range'), +(8978, 5, 1025357, 0, 6, 'Thauris Balgarr - Vanilla Greens 53-57 Level Range'), +(8978, 6, 1025761, 0, 6, 'Thauris Balgarr - Vanilla Greens 57-61 Level Range'), +(8979, 2, 1025660, 0, 6, 'Gruklash - Vanilla Greens 56-60 Level Range'), +(8979, 3, 1025862, 0, 6, 'Gruklash - Vanilla Greens 58-62 Level Range'), +(8979, 4, 1025559, 0, 6, 'Gruklash - Vanilla Greens 55-59 Level Range'), +(8979, 5, 1025963, 0, 6, 'Gruklash - Vanilla Greens 59-63 Level Range'), +(8979, 6, 1025761, 0, 6, 'Gruklash - Vanilla Greens 57-61 Level Range'), +(8981, 2, 1025660, 0, 6, 'Malfunctioning Reaver - Vanilla Greens 56-60 Level Range'), +(8981, 3, 1025458, 0, 6, 'Malfunctioning Reaver - Vanilla Greens 54-58 Level Range'), +(8981, 4, 1025559, 0, 6, 'Malfunctioning Reaver - Vanilla Greens 55-59 Level Range'), +(8981, 5, 1025357, 0, 6, 'Malfunctioning Reaver - Vanilla Greens 53-57 Level Range'), +(8981, 6, 1025256, 0, 6, 'Malfunctioning Reaver - Vanilla Greens 52-56 Level Range'), +(9602, 2, 1025458, 0, 6, 'Hahk\'Zor - Vanilla Greens 54-58 Level Range'), +(9602, 3, 1025155, 0, 6, 'Hahk\'Zor - Vanilla Greens 51-55 Level Range'), +(9602, 4, 1025357, 0, 6, 'Hahk\'Zor - Vanilla Greens 53-57 Level Range'), +(9602, 5, 1025256, 0, 6, 'Hahk\'Zor - Vanilla Greens 52-56 Level Range'), +(9602, 6, 1025054, 0, 6, 'Hahk\'Zor - Vanilla Greens 50-54 Level Range'), +(9604, 2, 1025458, 0, 6, 'Gorgon\'och - Vanilla Greens 54-58 Level Range'), +(9604, 3, 1025155, 0, 6, 'Gorgon\'och - Vanilla Greens 51-55 Level Range'), +(9604, 4, 1025357, 0, 6, 'Gorgon\'och - Vanilla Greens 53-57 Level Range'), +(9604, 5, 1025256, 0, 6, 'Gorgon\'och - Vanilla Greens 52-56 Level Range'), +(9604, 6, 1025054, 0, 6, 'Gorgon\'och - Vanilla Greens 50-54 Level Range'), +(10077, 2, 1025155, 0, 6, 'Deathmaw - Vanilla Greens 51-55 Level Range'), +(10077, 3, 1025357, 0, 6, 'Deathmaw - Vanilla Greens 53-57 Level Range'), +(10077, 4, 1025256, 0, 6, 'Deathmaw - Vanilla Greens 52-56 Level Range'), +(10077, 5, 1025054, 0, 6, 'Deathmaw - Vanilla Greens 50-54 Level Range'), +(10077, 6, 1024953, 0, 6, 'Deathmaw - Vanilla Greens 49-53 Level Range'), +(10078, 2, 1025458, 0, 6, 'Terrorspark - Vanilla Greens 54-58 Level Range'), +(10078, 3, 1025559, 0, 6, 'Terrorspark - Vanilla Greens 55-59 Level Range'), +(10078, 4, 1025155, 0, 6, 'Terrorspark - Vanilla Greens 51-55 Level Range'), +(10078, 5, 1025357, 0, 6, 'Terrorspark - Vanilla Greens 53-57 Level Range'), +(10078, 6, 1025256, 0, 6, 'Terrorspark - Vanilla Greens 52-56 Level Range'), +(10197, 2, 1025458, 0, 6, 'Mezzir the Howler - Vanilla Greens 54-58 Level Range'), +(10197, 3, 1025559, 0, 6, 'Mezzir the Howler - Vanilla Greens 55-59 Level Range'), +(10197, 4, 1025155, 0, 6, 'Mezzir the Howler - Vanilla Greens 51-55 Level Range'), +(10197, 5, 1025357, 0, 6, 'Mezzir the Howler - Vanilla Greens 53-57 Level Range'), +(10197, 6, 1025256, 0, 6, 'Mezzir the Howler - Vanilla Greens 52-56 Level Range'), +(10199, 2, 1025660, 0, 6, 'Grizzle Snowpaw - Vanilla Greens 56-60 Level Range'), +(10199, 3, 1025862, 0, 6, 'Grizzle Snowpaw - Vanilla Greens 58-62 Level Range'), +(10199, 4, 1025559, 0, 6, 'Grizzle Snowpaw - Vanilla Greens 55-59 Level Range'), +(10199, 5, 1025963, 0, 6, 'Grizzle Snowpaw - Vanilla Greens 59-63 Level Range'), +(10199, 6, 1025761, 0, 6, 'Grizzle Snowpaw - Vanilla Greens 57-61 Level Range'), +(10200, 2, 1025660, 0, 6, 'Rak\'shiri - Vanilla Greens 56-60 Level Range'), +(10200, 3, 1025458, 0, 6, 'Rak\'shiri - Vanilla Greens 54-58 Level Range'), +(10200, 4, 1025559, 0, 6, 'Rak\'shiri - Vanilla Greens 55-59 Level Range'), +(10200, 5, 1025357, 0, 6, 'Rak\'shiri - Vanilla Greens 53-57 Level Range'), +(10200, 6, 1025761, 0, 6, 'Rak\'shiri - Vanilla Greens 57-61 Level Range'), +(10356, 2, 1010910, 0, 6, 'Bayne - Vanilla Whites 9-10 Level Range'), +(10356, 3, 1011011, 0, 6, 'Bayne - Vanilla Whites 10-11 Level Range'), +(10356, 4, 1021014, 0, 6, 'Bayne - Vanilla Greens 10-14 Level Range'), +(10356, 5, 1020812, 0, 6, 'Bayne - Vanilla Greens 8-12 Level Range'), +(10357, 2, 1011112, 0, 6, 'Ressan the Needler - Vanilla Whites 11-12 Level Range'), +(10357, 3, 1011011, 0, 6, 'Ressan the Needler - Vanilla Whites 10-11 Level Range'), +(10357, 4, 1021115, 0, 6, 'Ressan the Needler - Vanilla Greens 11-15 Level Range'), +(10357, 5, 1021014, 0, 6, 'Ressan the Needler - Vanilla Greens 10-14 Level Range'), +(10357, 6, 1020812, 0, 6, 'Ressan the Needler - Vanilla Greens 8-12 Level Range'), +(10358, 2, 1011112, 0, 6, 'Fellicent\'s Shade - Vanilla Whites 11-12 Level Range'), +(10358, 3, 1011213, 0, 6, 'Fellicent\'s Shade - Vanilla Whites 12-13 Level Range'), +(10358, 4, 1021115, 0, 6, 'Fellicent\'s Shade - Vanilla Greens 11-15 Level Range'), +(10358, 5, 1021014, 0, 6, 'Fellicent\'s Shade - Vanilla Greens 10-14 Level Range'), +(10358, 6, 1021216, 0, 6, 'Fellicent\'s Shade - Vanilla Greens 12-16 Level Range'), +(10358, 7, 1020812, 0, 6, 'Fellicent\'s Shade - Vanilla Greens 8-12 Level Range'), +(10359, 2, 1011314, 0, 6, 'Sri\'skulk - Vanilla Whites 13-14 Level Range'), +(10359, 3, 1011213, 0, 6, 'Sri\'skulk - Vanilla Whites 12-13 Level Range'), +(10359, 4, 1021317, 0, 6, 'Sri\'skulk - Vanilla Greens 13-17 Level Range'), +(10359, 5, 1021115, 0, 6, 'Sri\'skulk - Vanilla Greens 11-15 Level Range'), +(10359, 6, 1021014, 0, 6, 'Sri\'skulk - Vanilla Greens 10-14 Level Range'), +(10359, 7, 1021216, 0, 6, 'Sri\'skulk - Vanilla Greens 12-16 Level Range'), +(10559, 2, 1012024, 0, 6, 'Lady Vespia - Vanilla Whites 20-24 Level Range'), +(10559, 3, 1012125, 0, 6, 'Lady Vespia - Vanilla Whites 21-25 Level Range'), +(10559, 4, 1011822, 0, 6, 'Lady Vespia - Vanilla Whites 18-22 Level Range'), +(10559, 5, 1011923, 0, 6, 'Lady Vespia - Vanilla Whites 19-23 Level Range'), +(10559, 6, 1022125, 0, 6, 'Lady Vespia - Vanilla Greens 21-25 Level Range'), +(10559, 7, 1022024, 0, 6, 'Lady Vespia - Vanilla Greens 20-24 Level Range'), +(10559, 8, 1022226, 0, 6, 'Lady Vespia - Vanilla Greens 22-26 Level Range'), +(10559, 9, 1021822, 0, 6, 'Lady Vespia - Vanilla Greens 18-22 Level Range'), +(10559, 10, 1021923, 0, 6, 'Lady Vespia - Vanilla Greens 19-23 Level Range'), +(10639, 2, 1012125, 0, 6, 'Rorgish Jowl - Vanilla Whites 21-25 Level Range'), +(10639, 3, 1022327, 0, 6, 'Rorgish Jowl - Vanilla Greens 23-27 Level Range'), +(10639, 4, 1022428, 0, 6, 'Rorgish Jowl - Vanilla Greens 24-28 Level Range'), +(10639, 5, 1022125, 0, 6, 'Rorgish Jowl - Vanilla Greens 21-25 Level Range'), +(10639, 6, 1022226, 0, 6, 'Rorgish Jowl - Vanilla Greens 22-26 Level Range'), +(10639, 7, 1022529, 0, 6, 'Rorgish Jowl - Vanilla Greens 25-29 Level Range'), +(10640, 2, 1022731, 0, 6, 'Oakpaw - Vanilla Greens 27-31 Level Range'), +(10640, 3, 1022327, 0, 6, 'Oakpaw - Vanilla Greens 23-27 Level Range'), +(10640, 4, 1022428, 0, 6, 'Oakpaw - Vanilla Greens 24-28 Level Range'), +(10640, 5, 1022630, 0, 6, 'Oakpaw - Vanilla Greens 26-30 Level Range'), +(10640, 6, 1022529, 0, 6, 'Oakpaw - Vanilla Greens 25-29 Level Range'), +(10641, 2, 1012125, 0, 6, 'Branch Snapper - Vanilla Whites 21-25 Level Range'), +(10641, 3, 1022327, 0, 6, 'Branch Snapper - Vanilla Greens 23-27 Level Range'), +(10641, 4, 1022428, 0, 6, 'Branch Snapper - Vanilla Greens 24-28 Level Range'), +(10641, 5, 1022125, 0, 6, 'Branch Snapper - Vanilla Greens 21-25 Level Range'), +(10641, 6, 1022226, 0, 6, 'Branch Snapper - Vanilla Greens 22-26 Level Range'), +(10641, 7, 1022529, 0, 6, 'Branch Snapper - Vanilla Greens 25-29 Level Range'), +(10642, 2, 1022731, 0, 6, 'Eck\'alom - Vanilla Greens 27-31 Level Range'), +(10642, 3, 1022327, 0, 6, 'Eck\'alom - Vanilla Greens 23-27 Level Range'), +(10642, 4, 1022428, 0, 6, 'Eck\'alom - Vanilla Greens 24-28 Level Range'), +(10642, 5, 1022630, 0, 6, 'Eck\'alom - Vanilla Greens 26-30 Level Range'), +(10642, 6, 1022529, 0, 6, 'Eck\'alom - Vanilla Greens 25-29 Level Range'), +(10643, 2, 1012024, 0, 6, 'Mugglefin - Vanilla Whites 20-24 Level Range'), +(10643, 3, 1012125, 0, 6, 'Mugglefin - Vanilla Whites 21-25 Level Range'), +(10643, 4, 1011923, 0, 6, 'Mugglefin - Vanilla Whites 19-23 Level Range'), +(10643, 5, 1022327, 0, 6, 'Mugglefin - Vanilla Greens 23-27 Level Range'), +(10643, 6, 1022125, 0, 6, 'Mugglefin - Vanilla Greens 21-25 Level Range'), +(10643, 7, 1022024, 0, 6, 'Mugglefin - Vanilla Greens 20-24 Level Range'), +(10643, 8, 1022226, 0, 6, 'Mugglefin - Vanilla Greens 22-26 Level Range'), +(10643, 9, 1021923, 0, 6, 'Mugglefin - Vanilla Greens 19-23 Level Range'), +(10644, 2, 1012024, 0, 6, 'Mist Howler - Vanilla Whites 20-24 Level Range'), +(10644, 3, 1012125, 0, 6, 'Mist Howler - Vanilla Whites 21-25 Level Range'), +(10644, 4, 1011822, 0, 6, 'Mist Howler - Vanilla Whites 18-22 Level Range'), +(10644, 5, 1011923, 0, 6, 'Mist Howler - Vanilla Whites 19-23 Level Range'), +(10644, 6, 1022125, 0, 6, 'Mist Howler - Vanilla Greens 21-25 Level Range'), +(10644, 7, 1022024, 0, 6, 'Mist Howler - Vanilla Greens 20-24 Level Range'), +(10644, 8, 1022226, 0, 6, 'Mist Howler - Vanilla Greens 22-26 Level Range'), +(10644, 9, 1021822, 0, 6, 'Mist Howler - Vanilla Greens 18-22 Level Range'), +(10644, 10, 1021923, 0, 6, 'Mist Howler - Vanilla Greens 19-23 Level Range'), +(10647, 2, 1023034, 0, 6, 'Prince Raze - Vanilla Greens 30-34 Level Range'), +(10647, 3, 1023135, 0, 6, 'Prince Raze - Vanilla Greens 31-35 Level Range'), +(10647, 4, 1022832, 0, 6, 'Prince Raze - Vanilla Greens 28-32 Level Range'), +(10647, 5, 1022933, 0, 6, 'Prince Raze - Vanilla Greens 29-33 Level Range'), +(10647, 6, 1023236, 0, 6, 'Prince Raze - Vanilla Greens 32-36 Level Range'), +(10817, 2, 1025458, 0, 6, 'Duggan Wildhammer - Vanilla Greens 54-58 Level Range'), +(10817, 3, 1025559, 0, 6, 'Duggan Wildhammer - Vanilla Greens 55-59 Level Range'), +(10817, 4, 1025155, 0, 6, 'Duggan Wildhammer - Vanilla Greens 51-55 Level Range'), +(10817, 5, 1025357, 0, 6, 'Duggan Wildhammer - Vanilla Greens 53-57 Level Range'), +(10817, 6, 1025256, 0, 6, 'Duggan Wildhammer - Vanilla Greens 52-56 Level Range'), +(10821, 2, 1025660, 0, 6, 'Hed\'mush the Rotting - Vanilla Greens 56-60 Level Range'), +(10821, 3, 1025458, 0, 6, 'Hed\'mush the Rotting - Vanilla Greens 54-58 Level Range'), +(10821, 4, 1025559, 0, 6, 'Hed\'mush the Rotting - Vanilla Greens 55-59 Level Range'), +(10821, 5, 1025357, 0, 6, 'Hed\'mush the Rotting - Vanilla Greens 53-57 Level Range'), +(10821, 6, 1025761, 0, 6, 'Hed\'mush the Rotting - Vanilla Greens 57-61 Level Range'), +(10822, 2, 1025660, 0, 6, 'Warlord Thresh\'jin - Vanilla Greens 56-60 Level Range'), +(10822, 3, 1025862, 0, 6, 'Warlord Thresh\'jin - Vanilla Greens 58-62 Level Range'), +(10822, 4, 1025458, 0, 6, 'Warlord Thresh\'jin - Vanilla Greens 54-58 Level Range'), +(10822, 5, 1025559, 0, 6, 'Warlord Thresh\'jin - Vanilla Greens 55-59 Level Range'), +(10822, 6, 1025761, 0, 6, 'Warlord Thresh\'jin - Vanilla Greens 57-61 Level Range'), +(10823, 2, 1025660, 0, 6, 'Zul\'Brin Warpbranch - Vanilla Greens 56-60 Level Range'), +(10823, 3, 1025862, 0, 6, 'Zul\'Brin Warpbranch - Vanilla Greens 58-62 Level Range'), +(10823, 4, 1025559, 0, 6, 'Zul\'Brin Warpbranch - Vanilla Greens 55-59 Level Range'), +(10823, 5, 1025963, 0, 6, 'Zul\'Brin Warpbranch - Vanilla Greens 59-63 Level Range'), +(10823, 6, 1025761, 0, 6, 'Zul\'Brin Warpbranch - Vanilla Greens 57-61 Level Range'), +(10824, 2, 1025660, 0, 6, 'Ranger Lord Hawkspear - Vanilla Greens 56-60 Level Range'), +(10824, 3, 1025862, 0, 6, 'Ranger Lord Hawkspear - Vanilla Greens 58-62 Level Range'), +(10824, 4, 1026063, 0, 6, 'Ranger Lord Hawkspear - Vanilla Greens 60-63 Level Range'), +(10824, 5, 1025963, 0, 6, 'Ranger Lord Hawkspear - Vanilla Greens 59-63 Level Range'), +(10824, 6, 1025761, 0, 6, 'Ranger Lord Hawkspear - Vanilla Greens 57-61 Level Range'), +(10825, 2, 1025660, 0, 6, 'Gish the Unmoving - Vanilla Greens 56-60 Level Range'), +(10825, 3, 1025458, 0, 6, 'Gish the Unmoving - Vanilla Greens 54-58 Level Range'), +(10825, 4, 1025559, 0, 6, 'Gish the Unmoving - Vanilla Greens 55-59 Level Range'), +(10825, 5, 1025357, 0, 6, 'Gish the Unmoving - Vanilla Greens 53-57 Level Range'), +(10825, 6, 1025256, 0, 6, 'Gish the Unmoving - Vanilla Greens 52-56 Level Range'), +(10826, 2, 1025660, 0, 1, 'Lord Darkscythe - Vanilla Greens 56-60 Level Range'), +(10826, 3, 1025458, 0, 1, 'Lord Darkscythe - Vanilla Greens 54-58 Level Range'), +(10826, 4, 1025559, 0, 1, 'Lord Darkscythe - Vanilla Greens 55-59 Level Range'), +(10826, 5, 1025357, 0, 1, 'Lord Darkscythe - Vanilla Greens 53-57 Level Range'), +(10826, 6, 1025761, 0, 1, 'Lord Darkscythe - Vanilla Greens 57-61 Level Range'), +(10827, 2, 1025660, 0, 6, 'Deathspeaker Selendre - Vanilla Greens 56-60 Level Range'), +(10827, 3, 1025458, 0, 6, 'Deathspeaker Selendre - Vanilla Greens 54-58 Level Range'), +(10827, 4, 1025559, 0, 6, 'Deathspeaker Selendre - Vanilla Greens 55-59 Level Range'), +(10827, 5, 1025357, 0, 6, 'Deathspeaker Selendre - Vanilla Greens 53-57 Level Range'), +(10827, 6, 1025256, 0, 6, 'Deathspeaker Selendre - Vanilla Greens 52-56 Level Range'), +(11688, 2, 1024145, 0, 6, 'Cursed Centaur - Vanilla Greens 41-45 Level Range'), +(11688, 3, 1024347, 0, 6, 'Cursed Centaur - Vanilla Greens 43-47 Level Range'), +(11688, 4, 1024246, 0, 6, 'Cursed Centaur - Vanilla Greens 42-46 Level Range'), +(11688, 5, 1023943, 0, 6, 'Cursed Centaur - Vanilla Greens 39-43 Level Range'), +(11688, 6, 1024044, 0, 6, 'Cursed Centaur - Vanilla Greens 40-44 Level Range'), +(12037, 2, 1023034, 0, 6, 'Ursol\'lok - Vanilla Greens 30-34 Level Range'), +(12037, 3, 1023135, 0, 6, 'Ursol\'lok - Vanilla Greens 31-35 Level Range'), +(12037, 4, 1022731, 0, 6, 'Ursol\'lok - Vanilla Greens 27-31 Level Range'), +(12037, 5, 1022832, 0, 6, 'Ursol\'lok - Vanilla Greens 28-32 Level Range'), +(12037, 6, 1022933, 0, 6, 'Ursol\'lok - Vanilla Greens 29-33 Level Range'), +(12431, 2, 1011314, 0, 6, 'Gorefang - Vanilla Whites 13-14 Level Range'), +(12431, 3, 1011213, 0, 6, 'Gorefang - Vanilla Whites 12-13 Level Range'), +(12431, 4, 1021317, 0, 6, 'Gorefang - Vanilla Greens 13-17 Level Range'), +(12431, 5, 1021115, 0, 6, 'Gorefang - Vanilla Greens 11-15 Level Range'), +(12431, 6, 1021014, 0, 6, 'Gorefang - Vanilla Greens 10-14 Level Range'), +(12431, 7, 1021216, 0, 6, 'Gorefang - Vanilla Greens 12-16 Level Range'), +(12432, 2, 1011314, 0, 6, 'Old Vicejaw - Vanilla Whites 13-14 Level Range'), +(12432, 3, 1011415, 0, 6, 'Old Vicejaw - Vanilla Whites 14-15 Level Range'), +(12432, 4, 1021317, 0, 6, 'Old Vicejaw - Vanilla Greens 13-17 Level Range'), +(12432, 5, 1021115, 0, 6, 'Old Vicejaw - Vanilla Greens 11-15 Level Range'), +(12432, 6, 1021014, 0, 6, 'Old Vicejaw - Vanilla Greens 10-14 Level Range'), +(12432, 7, 1021216, 0, 6, 'Old Vicejaw - Vanilla Greens 12-16 Level Range'), +(12432, 8, 1021418, 0, 6, 'Old Vicejaw - Vanilla Greens 14-18 Level Range'), +(12433, 2, 1011415, 0, 6, 'Krethis Shadowspinner - Vanilla Whites 14-15 Level Range'), +(12433, 3, 1021317, 0, 6, 'Krethis Shadowspinner - Vanilla Greens 13-17 Level Range'), +(12433, 4, 1021115, 0, 6, 'Krethis Shadowspinner - Vanilla Greens 11-15 Level Range'), +(12433, 5, 1021216, 0, 6, 'Krethis Shadowspinner - Vanilla Greens 12-16 Level Range'), +(12433, 6, 1021418, 0, 6, 'Krethis Shadowspinner - Vanilla Greens 14-18 Level Range'), +(12433, 7, 1021519, 0, 6, 'Krethis Shadowspinner - Vanilla Greens 15-19 Level Range'), +(14221, 2, 1023438, 0, 6, 'Gravis Slipknot - Vanilla Greens 34-38 Level Range'), +(14221, 3, 1023640, 0, 6, 'Gravis Slipknot - Vanilla Greens 36-40 Level Range'), +(14221, 4, 1023337, 0, 6, 'Gravis Slipknot - Vanilla Greens 33-37 Level Range'), +(14221, 5, 1023539, 0, 6, 'Gravis Slipknot - Vanilla Greens 35-39 Level Range'), +(14221, 6, 1023236, 0, 6, 'Gravis Slipknot - Vanilla Greens 32-36 Level Range'), +(14222, 2, 1023438, 0, 6, 'Araga - Vanilla Greens 34-38 Level Range'), +(14222, 3, 1023135, 0, 6, 'Araga - Vanilla Greens 31-35 Level Range'), +(14222, 4, 1023337, 0, 6, 'Araga - Vanilla Greens 33-37 Level Range'), +(14222, 5, 1023539, 0, 6, 'Araga - Vanilla Greens 35-39 Level Range'), +(14222, 6, 1023236, 0, 6, 'Araga - Vanilla Greens 32-36 Level Range'), +(14223, 2, 1023034, 0, 6, 'Cranky Benj - Vanilla Greens 30-34 Level Range'), +(14223, 3, 1023135, 0, 6, 'Cranky Benj - Vanilla Greens 31-35 Level Range'), +(14223, 4, 1022832, 0, 6, 'Cranky Benj - Vanilla Greens 28-32 Level Range'), +(14223, 5, 1022933, 0, 6, 'Cranky Benj - Vanilla Greens 29-33 Level Range'), +(14223, 6, 1023236, 0, 6, 'Cranky Benj - Vanilla Greens 32-36 Level Range'), +(14224, 2, 1024145, 0, 6, '7:XT - Vanilla Greens 41-45 Level Range'), +(14224, 3, 1023741, 0, 6, '7:XT - Vanilla Greens 37-41 Level Range'), +(14224, 4, 1023842, 0, 6, '7:XT - Vanilla Greens 38-42 Level Range'), +(14224, 5, 1023943, 0, 6, '7:XT - Vanilla Greens 39-43 Level Range'), +(14224, 6, 1024044, 0, 6, '7:XT - Vanilla Greens 40-44 Level Range'), +(14225, 2, 1023034, 0, 6, 'Prince Kellen - Vanilla Greens 30-34 Level Range'), +(14225, 3, 1023135, 0, 6, 'Prince Kellen - Vanilla Greens 31-35 Level Range'), +(14225, 4, 1022933, 0, 6, 'Prince Kellen - Vanilla Greens 29-33 Level Range'), +(14225, 5, 1023337, 0, 6, 'Prince Kellen - Vanilla Greens 33-37 Level Range'), +(14225, 6, 1023236, 0, 6, 'Prince Kellen - Vanilla Greens 32-36 Level Range'), +(14226, 2, 1023640, 0, 6, 'Kaskk - Vanilla Greens 36-40 Level Range'), +(14226, 3, 1023741, 0, 6, 'Kaskk - Vanilla Greens 37-41 Level Range'), +(14226, 4, 1023842, 0, 6, 'Kaskk - Vanilla Greens 38-42 Level Range'), +(14226, 5, 1023943, 0, 6, 'Kaskk - Vanilla Greens 39-43 Level Range'), +(14226, 6, 1024044, 0, 6, 'Kaskk - Vanilla Greens 40-44 Level Range'), +(14227, 2, 1023438, 0, 6, 'Hissperak - Vanilla Greens 34-38 Level Range'), +(14227, 3, 1023640, 0, 6, 'Hissperak - Vanilla Greens 36-40 Level Range'), +(14227, 4, 1023741, 0, 6, 'Hissperak - Vanilla Greens 37-41 Level Range'), +(14227, 5, 1023337, 0, 6, 'Hissperak - Vanilla Greens 33-37 Level Range'), +(14227, 6, 1023539, 0, 6, 'Hissperak - Vanilla Greens 35-39 Level Range'), +(14228, 2, 1023034, 0, 6, 'Giggler - Vanilla Greens 30-34 Level Range'), +(14228, 3, 1023438, 0, 6, 'Giggler - Vanilla Greens 34-38 Level Range'), +(14228, 4, 1023135, 0, 6, 'Giggler - Vanilla Greens 31-35 Level Range'), +(14228, 5, 1023337, 0, 6, 'Giggler - Vanilla Greens 33-37 Level Range'), +(14228, 6, 1023236, 0, 6, 'Giggler - Vanilla Greens 32-36 Level Range'), +(14229, 2, 1023438, 0, 6, 'Accursed Slitherblade - Vanilla Greens 34-38 Level Range'), +(14229, 3, 1023135, 0, 6, 'Accursed Slitherblade - Vanilla Greens 31-35 Level Range'), +(14229, 4, 1023337, 0, 6, 'Accursed Slitherblade - Vanilla Greens 33-37 Level Range'), +(14229, 5, 1023539, 0, 6, 'Accursed Slitherblade - Vanilla Greens 35-39 Level Range'), +(14229, 6, 1023236, 0, 6, 'Accursed Slitherblade - Vanilla Greens 32-36 Level Range'), +(14230, 2, 1023438, 0, 6, 'Burgle Eye - Vanilla Greens 34-38 Level Range'), +(14230, 3, 1023640, 0, 6, 'Burgle Eye - Vanilla Greens 36-40 Level Range'), +(14230, 4, 1023741, 0, 6, 'Burgle Eye - Vanilla Greens 37-41 Level Range'), +(14230, 5, 1023337, 0, 6, 'Burgle Eye - Vanilla Greens 33-37 Level Range'), +(14230, 6, 1023539, 0, 6, 'Burgle Eye - Vanilla Greens 35-39 Level Range'), +(14231, 2, 1023438, 0, 6, 'Drogoth the Roamer - Vanilla Greens 34-38 Level Range'), +(14231, 3, 1023640, 0, 6, 'Drogoth the Roamer - Vanilla Greens 36-40 Level Range'), +(14231, 4, 1023741, 0, 6, 'Drogoth the Roamer - Vanilla Greens 37-41 Level Range'), +(14231, 5, 1023337, 0, 6, 'Drogoth the Roamer - Vanilla Greens 33-37 Level Range'), +(14231, 6, 1023539, 0, 6, 'Drogoth the Roamer - Vanilla Greens 35-39 Level Range'), +(14232, 2, 1023438, 0, 6, 'Dart - Vanilla Greens 34-38 Level Range'), +(14232, 3, 1023640, 0, 6, 'Dart - Vanilla Greens 36-40 Level Range'), +(14232, 4, 1023741, 0, 6, 'Dart - Vanilla Greens 37-41 Level Range'), +(14232, 5, 1023842, 0, 6, 'Dart - Vanilla Greens 38-42 Level Range'), +(14232, 6, 1023539, 0, 6, 'Dart - Vanilla Greens 35-39 Level Range'), +(14233, 2, 1023438, 0, 6, 'Ripscale - Vanilla Greens 34-38 Level Range'), +(14233, 3, 1023640, 0, 6, 'Ripscale - Vanilla Greens 36-40 Level Range'), +(14233, 4, 1023741, 0, 6, 'Ripscale - Vanilla Greens 37-41 Level Range'), +(14233, 5, 1023337, 0, 6, 'Ripscale - Vanilla Greens 33-37 Level Range'), +(14233, 6, 1023539, 0, 6, 'Ripscale - Vanilla Greens 35-39 Level Range'), +(14234, 2, 1023640, 0, 6, 'Hayoc - Vanilla Greens 36-40 Level Range'), +(14234, 3, 1023741, 0, 6, 'Hayoc - Vanilla Greens 37-41 Level Range'), +(14234, 4, 1023842, 0, 6, 'Hayoc - Vanilla Greens 38-42 Level Range'), +(14234, 5, 1023943, 0, 6, 'Hayoc - Vanilla Greens 39-43 Level Range'), +(14234, 6, 1023539, 0, 6, 'Hayoc - Vanilla Greens 35-39 Level Range'), +(14235, 2, 1023640, 0, 6, 'The Rot - Vanilla Greens 36-40 Level Range'), +(14235, 3, 1023741, 0, 6, 'The Rot - Vanilla Greens 37-41 Level Range'), +(14235, 4, 1023842, 0, 6, 'The Rot - Vanilla Greens 38-42 Level Range'), +(14235, 5, 1023943, 0, 6, 'The Rot - Vanilla Greens 39-43 Level Range'), +(14235, 6, 1024044, 0, 6, 'The Rot - Vanilla Greens 40-44 Level Range'), +(14236, 2, 1023438, 0, 6, 'Lord Angler - Vanilla Greens 34-38 Level Range'), +(14236, 3, 1023640, 0, 6, 'Lord Angler - Vanilla Greens 36-40 Level Range'), +(14236, 4, 1023741, 0, 6, 'Lord Angler - Vanilla Greens 37-41 Level Range'), +(14236, 5, 1023337, 0, 6, 'Lord Angler - Vanilla Greens 33-37 Level Range'), +(14236, 6, 1023539, 0, 6, 'Lord Angler - Vanilla Greens 35-39 Level Range'), +(14237, 2, 1023438, 0, 6, 'Oozeworm - Vanilla Greens 34-38 Level Range'), +(14237, 3, 1023640, 0, 6, 'Oozeworm - Vanilla Greens 36-40 Level Range'), +(14237, 4, 1023741, 0, 6, 'Oozeworm - Vanilla Greens 37-41 Level Range'), +(14237, 5, 1023842, 0, 6, 'Oozeworm - Vanilla Greens 38-42 Level Range'), +(14237, 6, 1023539, 0, 6, 'Oozeworm - Vanilla Greens 35-39 Level Range'), +(14266, 2, 1011822, 0, 6, 'Shanda the Spinner - Vanilla Whites 18-22 Level Range'), +(14266, 3, 1011923, 0, 6, 'Shanda the Spinner - Vanilla Whites 19-23 Level Range'), +(14266, 4, 1021519, 0, 6, 'Shanda the Spinner - Vanilla Greens 15-19 Level Range'), +(14266, 5, 1021620, 0, 6, 'Shanda the Spinner - Vanilla Greens 16-20 Level Range'), +(14266, 6, 1021721, 0, 6, 'Shanda the Spinner - Vanilla Greens 17-21 Level Range'), +(14266, 7, 1021822, 0, 6, 'Shanda the Spinner - Vanilla Greens 18-22 Level Range'), +(14266, 8, 1021923, 0, 6, 'Shanda the Spinner - Vanilla Greens 19-23 Level Range'), +(14268, 3, 1011415, 0, 6, 'Lord Condar - Vanilla Whites 14-15 Level Range'), +(14268, 4, 1021317, 0, 6, 'Lord Condar - Vanilla Greens 13-17 Level Range'), +(14268, 5, 1021115, 0, 6, 'Lord Condar - Vanilla Greens 11-15 Level Range'), +(14268, 6, 1021216, 0, 6, 'Lord Condar - Vanilla Greens 12-16 Level Range'), +(14268, 7, 1021418, 0, 6, 'Lord Condar - Vanilla Greens 14-18 Level Range'), +(14268, 8, 1021519, 0, 6, 'Lord Condar - Vanilla Greens 15-19 Level Range'), +(14268, 9, 1021620, 0, 6, 'Lord Condar - Vanilla Greens 16-20 Level Range'), +(14269, 2, 1012024, 0, 6, 'Seeker Aqualon - Vanilla Whites 20-24 Level Range'), +(14269, 3, 1012125, 0, 6, 'Seeker Aqualon - Vanilla Whites 21-25 Level Range'), +(14269, 4, 1011822, 0, 6, 'Seeker Aqualon - Vanilla Whites 18-22 Level Range'), +(14269, 5, 1011923, 0, 6, 'Seeker Aqualon - Vanilla Whites 19-23 Level Range'), +(14269, 6, 1022125, 0, 6, 'Seeker Aqualon - Vanilla Greens 21-25 Level Range'), +(14269, 7, 1022024, 0, 6, 'Seeker Aqualon - Vanilla Greens 20-24 Level Range'), +(14269, 8, 1021721, 0, 6, 'Seeker Aqualon - Vanilla Greens 17-21 Level Range'), +(14269, 9, 1021822, 0, 6, 'Seeker Aqualon - Vanilla Greens 18-22 Level Range'), +(14269, 10, 1021923, 0, 6, 'Seeker Aqualon - Vanilla Greens 19-23 Level Range'), +(14270, 2, 1011822, 0, 6, 'Squiddic - Vanilla Whites 18-22 Level Range'), +(14270, 3, 1011923, 0, 6, 'Squiddic - Vanilla Whites 19-23 Level Range'), +(14270, 4, 1021519, 0, 6, 'Squiddic - Vanilla Greens 15-19 Level Range'), +(14270, 5, 1021620, 0, 6, 'Squiddic - Vanilla Greens 16-20 Level Range'), +(14270, 6, 1021721, 0, 6, 'Squiddic - Vanilla Greens 17-21 Level Range'), +(14270, 7, 1021822, 0, 6, 'Squiddic - Vanilla Greens 18-22 Level Range'), +(14270, 8, 1021923, 0, 6, 'Squiddic - Vanilla Greens 19-23 Level Range'), +(14271, 2, 1021317, 0, 6, 'Ribchaser - Vanilla Greens 13-17 Level Range'), +(14271, 3, 1021418, 0, 6, 'Ribchaser - Vanilla Greens 14-18 Level Range'), +(14271, 4, 1021519, 0, 6, 'Ribchaser - Vanilla Greens 15-19 Level Range'), +(14271, 5, 1021620, 0, 6, 'Ribchaser - Vanilla Greens 16-20 Level Range'), +(14271, 6, 1021721, 0, 6, 'Ribchaser - Vanilla Greens 17-21 Level Range'), +(14272, 2, 1011822, 0, 6, 'Snarlflare - Vanilla Whites 18-22 Level Range'), +(14272, 3, 1021418, 0, 6, 'Snarlflare - Vanilla Greens 14-18 Level Range'), +(14272, 4, 1021519, 0, 6, 'Snarlflare - Vanilla Greens 15-19 Level Range'), +(14272, 5, 1021620, 0, 6, 'Snarlflare - Vanilla Greens 16-20 Level Range'), +(14272, 6, 1021721, 0, 6, 'Snarlflare - Vanilla Greens 17-21 Level Range'), +(14272, 7, 1021822, 0, 6, 'Snarlflare - Vanilla Greens 18-22 Level Range'), +(14273, 2, 1012125, 0, 6, 'Boulderheart - Vanilla Whites 21-25 Level Range'), +(14273, 3, 1022327, 0, 6, 'Boulderheart - Vanilla Greens 23-27 Level Range'), +(14273, 4, 1022428, 0, 6, 'Boulderheart - Vanilla Greens 24-28 Level Range'), +(14273, 5, 1022125, 0, 6, 'Boulderheart - Vanilla Greens 21-25 Level Range'), +(14273, 6, 1022226, 0, 6, 'Boulderheart - Vanilla Greens 22-26 Level Range'), +(14273, 7, 1022529, 0, 6, 'Boulderheart - Vanilla Greens 25-29 Level Range'), +(14276, 2, 1023034, 0, 6, 'Scargil - Vanilla Greens 30-34 Level Range'), +(14276, 3, 1022731, 0, 6, 'Scargil - Vanilla Greens 27-31 Level Range'), +(14276, 4, 1022832, 0, 6, 'Scargil - Vanilla Greens 28-32 Level Range'), +(14276, 5, 1022933, 0, 6, 'Scargil - Vanilla Greens 29-33 Level Range'), +(14276, 6, 1022630, 0, 6, 'Scargil - Vanilla Greens 26-30 Level Range'), +(14277, 2, 1023034, 0, 6, 'Lady Zephris - Vanilla Greens 30-34 Level Range'), +(14277, 3, 1023135, 0, 6, 'Lady Zephris - Vanilla Greens 31-35 Level Range'), +(14277, 4, 1022933, 0, 6, 'Lady Zephris - Vanilla Greens 29-33 Level Range'), +(14277, 5, 1023337, 0, 6, 'Lady Zephris - Vanilla Greens 33-37 Level Range'), +(14277, 6, 1023236, 0, 6, 'Lady Zephris - Vanilla Greens 32-36 Level Range'), +(14278, 2, 1022731, 0, 6, 'Ro\'Bark - Vanilla Greens 27-31 Level Range'), +(14278, 3, 1022832, 0, 6, 'Ro\'Bark - Vanilla Greens 28-32 Level Range'), +(14278, 4, 1022428, 0, 6, 'Ro\'Bark - Vanilla Greens 24-28 Level Range'), +(14278, 5, 1022630, 0, 6, 'Ro\'Bark - Vanilla Greens 26-30 Level Range'), +(14278, 6, 1022529, 0, 6, 'Ro\'Bark - Vanilla Greens 25-29 Level Range'), +(14279, 2, 1012024, 0, 6, 'Creepthess - Vanilla Whites 20-24 Level Range'), +(14279, 3, 1012125, 0, 6, 'Creepthess - Vanilla Whites 21-25 Level Range'), +(14279, 4, 1022327, 0, 6, 'Creepthess - Vanilla Greens 23-27 Level Range'), +(14279, 5, 1022428, 0, 6, 'Creepthess - Vanilla Greens 24-28 Level Range'), +(14279, 6, 1022125, 0, 6, 'Creepthess - Vanilla Greens 21-25 Level Range'), +(14279, 7, 1022024, 0, 6, 'Creepthess - Vanilla Greens 20-24 Level Range'), +(14279, 8, 1022226, 0, 6, 'Creepthess - Vanilla Greens 22-26 Level Range'), +(14280, 2, 1022731, 0, 6, 'Big Samras - Vanilla Greens 27-31 Level Range'), +(14280, 3, 1022327, 0, 6, 'Big Samras - Vanilla Greens 23-27 Level Range'), +(14280, 4, 1022428, 0, 6, 'Big Samras - Vanilla Greens 24-28 Level Range'), +(14280, 5, 1022630, 0, 6, 'Big Samras - Vanilla Greens 26-30 Level Range'), +(14280, 6, 1022529, 0, 6, 'Big Samras - Vanilla Greens 25-29 Level Range'), +(14281, 2, 1012024, 0, 6, 'Jimmy the Bleeder - Vanilla Whites 20-24 Level Range'), +(14281, 3, 1012125, 0, 6, 'Jimmy the Bleeder - Vanilla Whites 21-25 Level Range'), +(14281, 4, 1011923, 0, 6, 'Jimmy the Bleeder - Vanilla Whites 19-23 Level Range'), +(14281, 5, 1022327, 0, 6, 'Jimmy the Bleeder - Vanilla Greens 23-27 Level Range'), +(14281, 6, 1022125, 0, 6, 'Jimmy the Bleeder - Vanilla Greens 21-25 Level Range'), +(14281, 7, 1022024, 0, 6, 'Jimmy the Bleeder - Vanilla Greens 20-24 Level Range'), +(14281, 8, 1022226, 0, 6, 'Jimmy the Bleeder - Vanilla Greens 22-26 Level Range'), +(14281, 9, 1021923, 0, 6, 'Jimmy the Bleeder - Vanilla Greens 19-23 Level Range'), +(14339, 2, 1024549, 0, 6, 'Death Howl - Vanilla Greens 45-49 Level Range'), +(14339, 3, 1024751, 0, 6, 'Death Howl - Vanilla Greens 47-51 Level Range'), +(14339, 4, 1024852, 0, 6, 'Death Howl - Vanilla Greens 48-52 Level Range'), +(14339, 5, 1024953, 0, 6, 'Death Howl - Vanilla Greens 49-53 Level Range'), +(14339, 6, 1024650, 0, 6, 'Death Howl - Vanilla Greens 46-50 Level Range'), +(14340, 2, 1025458, 0, 6, 'Alshirr Banebreath - Vanilla Greens 54-58 Level Range'), +(14340, 3, 1025155, 0, 6, 'Alshirr Banebreath - Vanilla Greens 51-55 Level Range'), +(14340, 4, 1025357, 0, 6, 'Alshirr Banebreath - Vanilla Greens 53-57 Level Range'), +(14340, 5, 1025256, 0, 6, 'Alshirr Banebreath - Vanilla Greens 52-56 Level Range'), +(14340, 6, 1025054, 0, 6, 'Alshirr Banebreath - Vanilla Greens 50-54 Level Range'), +(14342, 2, 1025155, 0, 6, 'Ragepaw - Vanilla Greens 51-55 Level Range'), +(14342, 3, 1024751, 0, 6, 'Ragepaw - Vanilla Greens 47-51 Level Range'), +(14342, 4, 1025054, 0, 6, 'Ragepaw - Vanilla Greens 50-54 Level Range'), +(14342, 5, 1024852, 0, 6, 'Ragepaw - Vanilla Greens 48-52 Level Range'), +(14342, 6, 1024953, 0, 6, 'Ragepaw - Vanilla Greens 49-53 Level Range'), +(14343, 2, 1025155, 0, 6, 'Olm the Wise - Vanilla Greens 51-55 Level Range'), +(14343, 3, 1025256, 0, 6, 'Olm the Wise - Vanilla Greens 52-56 Level Range'), +(14343, 4, 1025054, 0, 6, 'Olm the Wise - Vanilla Greens 50-54 Level Range'), +(14343, 5, 1024852, 0, 6, 'Olm the Wise - Vanilla Greens 48-52 Level Range'), +(14343, 6, 1024953, 0, 6, 'Olm the Wise - Vanilla Greens 49-53 Level Range'), +(14344, 2, 1024751, 0, 6, 'Mongress - Vanilla Greens 47-51 Level Range'), +(14344, 3, 1025054, 0, 6, 'Mongress - Vanilla Greens 50-54 Level Range'), +(14344, 4, 1024852, 0, 6, 'Mongress - Vanilla Greens 48-52 Level Range'), +(14344, 5, 1024953, 0, 6, 'Mongress - Vanilla Greens 49-53 Level Range'), +(14344, 6, 1024650, 0, 6, 'Mongress - Vanilla Greens 46-50 Level Range'), +(14345, 2, 1025155, 0, 6, 'The Ongar - Vanilla Greens 51-55 Level Range'), +(14345, 3, 1024751, 0, 6, 'The Ongar - Vanilla Greens 47-51 Level Range'), +(14345, 4, 1025054, 0, 6, 'The Ongar - Vanilla Greens 50-54 Level Range'), +(14345, 5, 1024852, 0, 6, 'The Ongar - Vanilla Greens 48-52 Level Range'), +(14345, 6, 1024953, 0, 6, 'The Ongar - Vanilla Greens 49-53 Level Range'), +(14424, 2, 1012125, 0, 6, 'Mirelow - Vanilla Whites 21-25 Level Range'), +(14424, 3, 1022327, 0, 6, 'Mirelow - Vanilla Greens 23-27 Level Range'), +(14424, 4, 1022428, 0, 6, 'Mirelow - Vanilla Greens 24-28 Level Range'), +(14424, 5, 1022125, 0, 6, 'Mirelow - Vanilla Greens 21-25 Level Range'), +(14424, 6, 1022226, 0, 6, 'Mirelow - Vanilla Greens 22-26 Level Range'), +(14424, 7, 1022529, 0, 6, 'Mirelow - Vanilla Greens 25-29 Level Range'), +(14425, 2, 1012024, 0, 6, 'Gnawbone - Vanilla Whites 20-24 Level Range'), +(14425, 3, 1012125, 0, 6, 'Gnawbone - Vanilla Whites 21-25 Level Range'), +(14425, 4, 1022327, 0, 6, 'Gnawbone - Vanilla Greens 23-27 Level Range'), +(14425, 5, 1022428, 0, 6, 'Gnawbone - Vanilla Greens 24-28 Level Range'), +(14425, 6, 1022125, 0, 6, 'Gnawbone - Vanilla Greens 21-25 Level Range'), +(14425, 7, 1022024, 0, 6, 'Gnawbone - Vanilla Greens 20-24 Level Range'), +(14425, 8, 1022226, 0, 6, 'Gnawbone - Vanilla Greens 22-26 Level Range'), +(14426, 2, 1022731, 0, 6, 'Harb Foulmountain - Vanilla Greens 27-31 Level Range'), +(14426, 3, 1022327, 0, 6, 'Harb Foulmountain - Vanilla Greens 23-27 Level Range'), +(14426, 4, 1022428, 0, 6, 'Harb Foulmountain - Vanilla Greens 24-28 Level Range'), +(14426, 5, 1022630, 0, 6, 'Harb Foulmountain - Vanilla Greens 26-30 Level Range'), +(14426, 6, 1022529, 0, 6, 'Harb Foulmountain - Vanilla Greens 25-29 Level Range'), +(14427, 2, 1022731, 0, 6, 'Gibblesnik - Vanilla Greens 27-31 Level Range'), +(14427, 3, 1022832, 0, 6, 'Gibblesnik - Vanilla Greens 28-32 Level Range'), +(14427, 4, 1022428, 0, 6, 'Gibblesnik - Vanilla Greens 24-28 Level Range'), +(14427, 5, 1022630, 0, 6, 'Gibblesnik - Vanilla Greens 26-30 Level Range'), +(14427, 6, 1022529, 0, 6, 'Gibblesnik - Vanilla Greens 25-29 Level Range'), +(14429, 2, 1011112, 0, 6, 'Grimmaw - Vanilla Whites 11-12 Level Range'), +(14429, 3, 1011011, 0, 6, 'Grimmaw - Vanilla Whites 10-11 Level Range'), +(14429, 4, 1021115, 0, 6, 'Grimmaw - Vanilla Greens 11-15 Level Range'), +(14429, 5, 1021014, 0, 6, 'Grimmaw - Vanilla Greens 10-14 Level Range'), +(14429, 6, 1020812, 0, 6, 'Grimmaw - Vanilla Greens 8-12 Level Range'), +(14430, 2, 1010910, 0, 6, 'Duskstalker - Vanilla Whites 9-10 Level Range'), +(14430, 3, 1010809, 0, 6, 'Duskstalker - Vanilla Whites 8-9 Level Range'), +(14430, 4, 1020812, 0, 6, 'Duskstalker - Vanilla Greens 8-12 Level Range'), +(14433, 2, 1023034, 0, 6, 'Sludginn - Vanilla Greens 30-34 Level Range'), +(14433, 3, 1022731, 0, 6, 'Sludginn - Vanilla Greens 27-31 Level Range'), +(14433, 4, 1022832, 0, 6, 'Sludginn - Vanilla Greens 28-32 Level Range'), +(14433, 5, 1022933, 0, 6, 'Sludginn - Vanilla Greens 29-33 Level Range'), +(14433, 6, 1022630, 0, 6, 'Sludginn - Vanilla Greens 26-30 Level Range'), +(14446, 2, 1024145, 0, 6, 'Fingat - Vanilla Greens 41-45 Level Range'), +(14446, 3, 1024347, 0, 6, 'Fingat - Vanilla Greens 43-47 Level Range'), +(14446, 4, 1024246, 0, 6, 'Fingat - Vanilla Greens 42-46 Level Range'), +(14446, 5, 1023943, 0, 6, 'Fingat - Vanilla Greens 39-43 Level Range'), +(14446, 6, 1024044, 0, 6, 'Fingat - Vanilla Greens 40-44 Level Range'), +(14447, 2, 1024145, 0, 6, 'Gilmorian - Vanilla Greens 41-45 Level Range'), +(14447, 3, 1024347, 0, 6, 'Gilmorian - Vanilla Greens 43-47 Level Range'), +(14447, 4, 1024246, 0, 6, 'Gilmorian - Vanilla Greens 42-46 Level Range'), +(14447, 5, 1023943, 0, 6, 'Gilmorian - Vanilla Greens 39-43 Level Range'), +(14447, 6, 1024044, 0, 6, 'Gilmorian - Vanilla Greens 40-44 Level Range'), +(14448, 2, 1024145, 0, 6, 'Molt Thorn - Vanilla Greens 41-45 Level Range'), +(14448, 3, 1024246, 0, 6, 'Molt Thorn - Vanilla Greens 42-46 Level Range'), +(14448, 4, 1023842, 0, 6, 'Molt Thorn - Vanilla Greens 38-42 Level Range'), +(14448, 5, 1023943, 0, 6, 'Molt Thorn - Vanilla Greens 39-43 Level Range'), +(14448, 6, 1024044, 0, 6, 'Molt Thorn - Vanilla Greens 40-44 Level Range'), +(14472, 2, 1025660, 0, 6, 'Gretheer - Vanilla Greens 56-60 Level Range'), +(14472, 3, 1025458, 0, 6, 'Gretheer - Vanilla Greens 54-58 Level Range'), +(14472, 4, 1025559, 0, 6, 'Gretheer - Vanilla Greens 55-59 Level Range'), +(14472, 5, 1025357, 0, 6, 'Gretheer - Vanilla Greens 53-57 Level Range'), +(14472, 6, 1025761, 0, 6, 'Gretheer - Vanilla Greens 57-61 Level Range'), +(14476, 2, 1025660, 0, 6, 'Krellack - Vanilla Greens 56-60 Level Range'), +(14476, 3, 1025458, 0, 6, 'Krellack - Vanilla Greens 54-58 Level Range'), +(14476, 4, 1025559, 0, 6, 'Krellack - Vanilla Greens 55-59 Level Range'), +(14476, 5, 1025357, 0, 6, 'Krellack - Vanilla Greens 53-57 Level Range'), +(14476, 6, 1025256, 0, 6, 'Krellack - Vanilla Greens 52-56 Level Range'), +(14477, 2, 1025660, 0, 6, 'Grubthor - Vanilla Greens 56-60 Level Range'), +(14477, 3, 1025862, 0, 6, 'Grubthor - Vanilla Greens 58-62 Level Range'), +(14477, 4, 1025458, 0, 6, 'Grubthor - Vanilla Greens 54-58 Level Range'), +(14477, 5, 1025559, 0, 6, 'Grubthor - Vanilla Greens 55-59 Level Range'), +(14477, 6, 1025761, 0, 6, 'Grubthor - Vanilla Greens 57-61 Level Range'), +(14478, 2, 1025660, 0, 6, 'Huricanian - Vanilla Greens 56-60 Level Range'), +(14478, 3, 1025862, 0, 6, 'Huricanian - Vanilla Greens 58-62 Level Range'), +(14478, 4, 1025458, 0, 6, 'Huricanian - Vanilla Greens 54-58 Level Range'), +(14478, 5, 1025559, 0, 6, 'Huricanian - Vanilla Greens 55-59 Level Range'), +(14478, 6, 1025761, 0, 6, 'Huricanian - Vanilla Greens 57-61 Level Range'), +(14479, 2, 1025660, 0, 6, 'Twilight Lord Everun - Vanilla Greens 56-60 Level Range'), +(14479, 3, 1025862, 0, 6, 'Twilight Lord Everun - Vanilla Greens 58-62 Level Range'), +(14479, 4, 1026063, 0, 6, 'Twilight Lord Everun - Vanilla Greens 60-63 Level Range'), +(14479, 5, 1025963, 0, 6, 'Twilight Lord Everun - Vanilla Greens 59-63 Level Range'), +(14479, 6, 1025761, 0, 6, 'Twilight Lord Everun - Vanilla Greens 57-61 Level Range'), +(14487, 2, 1023438, 0, 6, 'Gluggle - Vanilla Greens 34-38 Level Range'), +(14487, 3, 1023640, 0, 6, 'Gluggle - Vanilla Greens 36-40 Level Range'), +(14487, 4, 1023741, 0, 6, 'Gluggle - Vanilla Greens 37-41 Level Range'), +(14487, 5, 1023337, 0, 6, 'Gluggle - Vanilla Greens 33-37 Level Range'), +(14487, 6, 1023539, 0, 6, 'Gluggle - Vanilla Greens 35-39 Level Range'), +(14488, 2, 1023438, 0, 6, 'Roloch - Vanilla Greens 34-38 Level Range'), +(14488, 3, 1023640, 0, 6, 'Roloch - Vanilla Greens 36-40 Level Range'), +(14488, 4, 1023741, 0, 6, 'Roloch - Vanilla Greens 37-41 Level Range'), +(14488, 5, 1023842, 0, 6, 'Roloch - Vanilla Greens 38-42 Level Range'), +(14488, 6, 1023539, 0, 6, 'Roloch - Vanilla Greens 35-39 Level Range'), +(14490, 2, 1024145, 0, 6, 'Rippa - Vanilla Greens 41-45 Level Range'), +(14490, 3, 1024347, 0, 6, 'Rippa - Vanilla Greens 43-47 Level Range'), +(14490, 4, 1024448, 0, 6, 'Rippa - Vanilla Greens 44-48 Level Range'), +(14490, 5, 1024246, 0, 6, 'Rippa - Vanilla Greens 42-46 Level Range'), +(14490, 6, 1024044, 0, 6, 'Rippa - Vanilla Greens 40-44 Level Range'), +(14491, 2, 1024145, 0, 6, 'Kurmokk - Vanilla Greens 41-45 Level Range'), +(14491, 3, 1024246, 0, 6, 'Kurmokk - Vanilla Greens 42-46 Level Range'), +(14491, 4, 1023842, 0, 6, 'Kurmokk - Vanilla Greens 38-42 Level Range'), +(14491, 5, 1023943, 0, 6, 'Kurmokk - Vanilla Greens 39-43 Level Range'), +(14491, 6, 1024044, 0, 6, 'Kurmokk - Vanilla Greens 40-44 Level Range'), +(14492, 2, 1024145, 0, 6, 'Verifonix - Vanilla Greens 41-45 Level Range'), +(14492, 3, 1024246, 0, 6, 'Verifonix - Vanilla Greens 42-46 Level Range'), +(14492, 4, 1023842, 0, 6, 'Verifonix - Vanilla Greens 38-42 Level Range'), +(14492, 5, 1023943, 0, 6, 'Verifonix - Vanilla Greens 39-43 Level Range'), +(14492, 6, 1024044, 0, 6, 'Verifonix - Vanilla Greens 40-44 Level Range'), +(18241, 4 , 1023034, 0, 6, 'Crusty - Vanilla Greens 30-34 Level Range'), +(18241, 5 , 1022731, 0, 6, 'Crusty - Vanilla Greens 27-31 Level Range'), +(18241, 6 , 1022832, 0, 6, 'Crusty - Vanilla Greens 28-32 Level Range'), +(18241, 7 , 1022933, 0, 6, 'Crusty - Vanilla Greens 29-33 Level Range'), +(18241, 8 , 1022630, 0, 6, 'Crusty - Vanilla Greens 26-30 Level Range'), +(18241, 9 , 1023135, 0, 6, 'Crusty - Vanilla Greens 31-35 Level Range'), +(18241, 10, 1023236, 0, 6, 'Crusty - Vanilla Greens 32-36 Level Range'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 2779) AND (`Item` IN (1404)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(2779, 1404, 0, 50, 0, 1, 1, 1, 1, 'Prince Nazjak - Tidal Charm'); -- Set to Group 1 to share chances with random greens +DELETE FROM `creature_loot_template` WHERE (`Entry` = 3581); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(3581, 770, 0, 100, 0, 1, 0, 1, 1, 'Sewer Beast - Pointy Crocolisk Tooth'); -- Sewer Beast has no drops other than this trash + +/* Dungeon Maps +389, -- RFC +43, -- Wailing Caverns +36, -- Deadmines +33, -- SFK +34, -- Stockades +48, -- BFD +90, -- Gnomeregan +47, -- RFK +189, -- Scarlet Monastery +129, -- RFD +70, -- Uldaman +209, -- Zul'Farrak +349, -- Maraudon +109, -- Sunken Temple +230, -- BRD +229, -- BRS +289, -- Scholomance +329, -- Stratholme +429 -- Dire Maul + + Raid Maps +409, -- MC +469, -- BWL +309, -- ZG +509, -- AQ20 +531 -- AQ40 +*/ +DELETE FROM `creature_loot_template` WHERE `Entry` IN (5053,7078,7269,7405,8311,8886,9416,9696,9701,10177,10221,10375,11789,12218,13036,13160,13599,8319,10442,10678,8318,8921,8922,12216,12217,13276,5055,13022,14400,11360,11368,15333,15168,4308,5263,7333,7334,7344,7346,10390,10391,10411,10480,10481,10485,11476,11477,598,1725,4283,4416,4787,4851,5269,6207,6222,6224,7011,7012,7076,7077,7175,7309,7396,7397,7603,8896,8897,8900,8902,8904,8915,8916,8920,9545,9547,10316,10399,11387,11388,11390,11391,3636,3637,3861,3862,3864,3866,3868,4304,4512,4514,4538,4539,4821,4822,4823,4824,4825,4827,4861,4863,5048,5056,5226,5291,5755,5756,7022,7268,8095,10374,11320,13323,13533,14398,4857,4860,5761,6220,7079,7206,8384,8905,8906,8908,8909,8910,8911,9816,11321,11480,11483,11484,11784,12219,12220,13196,13197,13285,14303,14399,12206,3863,10408,10409,10412,10413,11551,6225,6226,6227,6230,6232,6233,6234,7023,8907,3640,4541,5228,6218,6219,8120,12221,12222,11357,11359,11361,11365,11370,11371,11372,11373,11673,14532,14821,14880,15043,15067,15230,15233,15320,15323,15505,11665,11666,11667,11668,12076,12100,12101,15338,11658,11659,15229,15235,15236,15240,15247,15249,15250,15252,15262,15264,15277,15311,15312,15318,15319,15324,15325,15327,15335,15336,15343,15355,15385,15386,15388,15389,15390,15391,15392,15461,15462,4425,5708,10376,5912,9042,10263,8923,12237,5277,5280,5283,9096,10083,10366,10371,10372,10447,10814,4798,4799,11451,11452,11453,11454,11455,11456,11457,11790,11791,11792,11458,11459,11461,11462,11464,11465,12223,12224,13021,13141,13142,3873,3875,3877,5267,5270,5271,7327,7328,7329,7332,7341,7342,7345,7347,7348,7352,7353,7357,7358,10381,10382,10384,10385,10405,10406,10407,10414,10416,10417,10463,10464,10478,10486,10487,10488,10489,10491,10495,10498,10499,10500,11469,11470,11471,11472,11473,11475,622,634,636,641,657,1706,1707,1708,1711,1715,1729,1731,1732,2529,3840,3851,3853,3854,3855,3857,3859,3947,4286,4287,4288,4289,4290,4291,4292,4294,4295,4296,4297,4298,4299,4300,4301,4302,4303,4306,4417,4418,4427,4435,4436,4437,4440,4442,4515,4516,4517,4518,4519,4520,4522,4523,4525,4530,4531,4532,4540,4623,4805,4807,4809,4810,4811,4812,4813,4814,4815,4818,4819,4820,4847,4848,4849,4850,4852,4853,4855,5256,5259,5273,5648,5649,5650,6035,6206,6211,6212,6223,6329,6391,6392,6407,7030,7246,7247,7274,7290,7320,7321,7335,7337,8889,8890,8891,8892,8893,8894,8895,8898,8899,8903,8912,8913,8914,9045,9097,9098,9197,9198,9199,9200,9201,9216,9239,9240,9241,9257,9258,9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9554,9583,9692,9693,9716,9717,9817,9818,9819,10317,10318,10319,10398,10400,10418,10419,10420,10421,10422,10423,10424,10425,10426,10469,10470,10471,10472,10475,10476,10477,10762,11043,11257,11318,11319,11322,11323,11324,11441,11444,11445,11448,11450,11582,11793,11794,12457,12460,12461,12463,12464,12465,12467,12468,15111,14825,11338,11339,11340,11350,11351,11352,11353,11356,11661,11662,11830,11831,12119,12459,13996,14750,14882,14883,3872,6488,6489,6490,10393,10558,10809,11467,1720,3586,4438,4842,6228,7354,9024,9041,9217,9218,9219,9596,9718,10080,10081,10082,10509,10899,12902) AND +`Reference` IN (1000117,1000118,1000318,1000319,1000317,1000320,1000323,1000324,1000325,1000115,1000116,1000218,1000219,1000217,1000220,1000221,1000321,1000130,1000131,1000335,1000333,1000334,1000336,1000337,1000338,1000339,1000233,1000330,1000331,1000119,1000227,1000326,1000226,1000225,1000120,1000322,1000222,1000223,1000327,1000136,1000137,1000240,1000239,1000237,1000238,1000018,1000019,1000247,1000248,1000348,1000347,1000146,1000147,1000349,1000249,1000343,1000344,1000345,1000124,1000125,1000126,1000127,1000328,1000332,1000138,1000139,1000036,1000228,1000135,1000245,1000044,1000346,1000134,1000037,1000038,1000244,1000045,1000046,1000047,1000048,1000350,1000351,1000150,1000151,1000353,1000354,1000154,1000152,1000355,1000155,1000252,1000254,1000255,1000250,1000251,1000352,1000153,1000049,1000050,1000052,1000053,1000256,1000253,1000358,1000359,1000357,1000356,1000054,1000148,1000149,1000056,1000057,1000058,1000260,1000360,1000257,1000159,1000160,1000361,1000362,1000258,1000055,1000156,1000157,1000259,1000158,1000059,1000313,1000314,1000315,1000213,1000214,1000261,1000060,1000161,1000262,1000263,1000246,1000342,1000042,1000243,1000363); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(598, 1, 1000117, 0, 5, 'Defias Miner - World Loot Level 17'), +(598, 2, 1000118, 0, 5, 'Defias Miner - World Loot Level 18'), +(622, 1, 1000318, 0, 5, 'Goblin Engineer - World Loot Level 18'), +(622, 2, 1000319, 0, 5, 'Goblin Engineer - World Loot Level 19'), +(634, 1, 1000317, 0, 5, 'Defias Overseer - World Loot Level 17'), +(634, 2, 1000318, 0, 5, 'Defias Overseer - World Loot Level 18'), +(636, 1, 1000319, 0, 5, 'Defias Blackguard - World Loot Level 19'), +(641, 1, 1000318, 0, 5, 'Goblin Woodcarver - World Loot Level 18'), +(641, 2, 1000319, 0, 5, 'Goblin Woodcarver - World Loot Level 19'), +(657, 1, 1000319, 0, 5, 'Defias Pirate - World Loot Level 19'), +(657, 2, 1000320, 0, 5, 'Defias Pirate - World Loot Level 20'), +(1706, 1, 1000323, 0, 5, 'Defias Prisoner - World Loot Level 23'), +(1707, 1, 1000323, 0, 5, 'Defias Captive - World Loot Level 23'), +(1708, 1, 1000323, 0, 5, 'Defias Inmate - World Loot Level 23'), +(1708, 2, 1000324, 0, 5, 'Defias Inmate - World Loot Level 24'), +(1711, 1, 1000323, 0, 5, 'Defias Convict - World Loot Level 23'), +(1711, 2, 1000324, 0, 5, 'Defias Convict - World Loot Level 24'), +(1715, 1, 1000324, 0, 5, 'Defias Insurgent - World Loot Level 24'), +(1720, 1, 1000325, 0, 5, 'Bruegal Ironknuckle - World Loot Level 25'), +(1725, 1, 1000115, 0, 5, 'Defias Watchman - World Loot Level 15'), +(1725, 2, 1000116, 0, 5, 'Defias Watchman - World Loot Level 16'), +(1725, 3, 1000117, 0, 5, 'Defias Watchman - World Loot Level 17'), +(1729, 1, 1000317, 0, 5, 'Defias Evoker - World Loot Level 17'), +(1729, 2, 1000318, 0, 5, 'Defias Evoker - World Loot Level 18'), +(1731, 1, 1000318, 0, 5, 'Goblin Craftsman - World Loot Level 18'), +(1731, 2, 1000319, 0, 5, 'Goblin Craftsman - World Loot Level 19'), +(1732, 1, 1000319, 0, 5, 'Defias Squallshaper - World Loot Level 19'), +(2529, 1, 1000320, 0, 5, 'Son of Arugal - World Loot Level 20'), +(3586, 1, 1000319, 0, 5, 'Miner Johnson - World Loot Level 19'), +(3636, 1, 1000218, 0, 5, 'Deviate Ravager - World Loot Level 18'), +(3636, 2, 1000219, 0, 5, 'Deviate Ravager - World Loot Level 19'), +(3637, 1, 1000218, 0, 5, 'Deviate Guardian - World Loot Level 18'), +(3637, 2, 1000219, 0, 5, 'Deviate Guardian - World Loot Level 19'), +(3640, 1, 1000217, 0, 5, 'Evolving Ectoplasm - World Loot Level 17'), +(3640, 2, 1000218, 0, 5, 'Evolving Ectoplasm - World Loot Level 18'), +(3840, 1, 1000319, 0, 5, 'Druid of the Fang - World Loot Level 19'), +(3851, 1, 1000318, 0, 5, 'Shadowfang Whitescalp - World Loot Level 18'), +(3851, 2, 1000319, 0, 5, 'Shadowfang Whitescalp - World Loot Level 19'), +(3853, 1, 1000319, 0, 5, 'Shadowfang Moonwalker - World Loot Level 19'), +(3854, 1, 1000320, 0, 5, 'Shadowfang Wolfguard - World Loot Level 20'), +(3855, 1, 1000319, 0, 5, 'Shadowfang Darksoul - World Loot Level 19'), +(3857, 1, 1000319, 0, 5, 'Shadowfang Glutton - World Loot Level 19'), +(3859, 1, 1000320, 0, 5, 'Shadowfang Ragetooth - World Loot Level 20'), +(3861, 1, 1000218, 0, 5, 'Bleak Worg - World Loot Level 18'), +(3861, 2, 1000219, 0, 5, 'Bleak Worg - World Loot Level 19'), +(3861, 3, 1000220, 0, 5, 'Bleak Worg - World Loot Level 20'), +(3861, 4, 1000221, 0, 5, 'Bleak Worg - World Loot Level 21'), +(3862, 1, 1000218, 0, 5, 'Slavering Worg - World Loot Level 18'), +(3862, 2, 1000219, 0, 5, 'Slavering Worg - World Loot Level 19'), +(3862, 3, 1000220, 0, 5, 'Slavering Worg - World Loot Level 20'), +(3862, 4, 1000221, 0, 5, 'Slavering Worg - World Loot Level 21'), +(3863, 1, 1000220, 0, 5, 'Lupine Horror - World Loot Level 20'), +(3863, 2, 1000221, 0, 5, 'Lupine Horror - World Loot Level 21'), +(3864, 1, 1000219, 0, 5, 'Fel Steed - World Loot Level 19'), +(3866, 1, 1000220, 0, 5, 'Vile Bat - World Loot Level 20'), +(3868, 1, 1000220, 0, 5, 'Blood Seeker - World Loot Level 20'), +(3872, 1, 1000321, 0, 5, 'Deathsworn Captain - World Loot Level 21'), +(3873, 1, 1000320, 0, 5, 'Tormented Officer - World Loot Level 20'), +(3875, 1, 1000318, 0, 5, 'Haunted Servitor - World Loot Level 18'), +(3875, 2, 1000319, 0, 5, 'Haunted Servitor - World Loot Level 19'), +(3877, 1, 1000319, 0, 5, 'Wailing Guardsman - World Loot Level 19'), +(3947, 1, 1000319, 0, 5, 'Goblin Shipbuilder - World Loot Level 19'), +(3947, 2, 1000320, 0, 5, 'Goblin Shipbuilder - World Loot Level 20'), +(4283, 1, 1000130, 0, 5, 'Scarlet Sentry - World Loot Level 30'), +(4283, 2, 1000131, 0, 5, 'Scarlet Sentry - World Loot Level 31'), +(4286, 1, 1000335, 0, 5, 'Scarlet Soldier - World Loot Level 35'), +(4287, 1, 1000333, 0, 5, 'Scarlet Gallant - World Loot Level 33'), +(4287, 2, 1000334, 0, 5, 'Scarlet Gallant - World Loot Level 34'), +(4288, 1, 1000333, 0, 5, 'Scarlet Beastmaster - World Loot Level 33'), +(4288, 2, 1000334, 0, 5, 'Scarlet Beastmaster - World Loot Level 34'), +(4289, 1, 1000335, 0, 5, 'Scarlet Evoker - World Loot Level 35'), +(4289, 2, 1000336, 0, 5, 'Scarlet Evoker - World Loot Level 36'), +(4290, 1, 1000335, 0, 5, 'Scarlet Guardsman - World Loot Level 35'), +(4290, 2, 1000336, 0, 5, 'Scarlet Guardsman - World Loot Level 36'), +(4291, 1, 1000334, 0, 5, 'Scarlet Diviner - World Loot Level 34'), +(4292, 1, 1000335, 0, 5, 'Scarlet Protector - World Loot Level 35'), +(4292, 2, 1000336, 0, 5, 'Scarlet Protector - World Loot Level 36'), +(4294, 1, 1000337, 0, 5, 'Scarlet Sorcerer - World Loot Level 37'), +(4294, 2, 1000338, 0, 5, 'Scarlet Sorcerer - World Loot Level 38'), +(4295, 1, 1000336, 0, 5, 'Scarlet Myrmidon - World Loot Level 36'), +(4296, 1, 1000333, 0, 5, 'Scarlet Adept - World Loot Level 33'), +(4296, 2, 1000334, 0, 5, 'Scarlet Adept - World Loot Level 34'), +(4297, 1, 1000335, 0, 5, 'Scarlet Conjuror - World Loot Level 35'), +(4298, 1, 1000336, 0, 5, 'Scarlet Defender - World Loot Level 36'), +(4299, 1, 1000334, 0, 5, 'Scarlet Chaplain - World Loot Level 34'), +(4300, 1, 1000338, 0, 5, 'Scarlet Wizard - World Loot Level 38'), +(4300, 2, 1000339, 0, 5, 'Scarlet Wizard - World Loot Level 39'), +(4301, 1, 1000338, 0, 5, 'Scarlet Centurion - World Loot Level 38'), +(4301, 2, 1000339, 0, 5, 'Scarlet Centurion - World Loot Level 39'), +(4302, 1, 1000339, 0, 5, 'Scarlet Champion - World Loot Level 39'), +(4303, 1, 1000339, 0, 5, 'Scarlet Abbot - World Loot Level 39'), +(4304, 1, 1000233, 0, 5, 'Scarlet Tracking Hound - World Loot Level 33'), +(4306, 1, 1000330, 0, 5, 'Scarlet Torturer - World Loot Level 30'), +(4306, 2, 1000331, 0, 5, 'Scarlet Torturer - World Loot Level 31'), +(4308, 1, 1000130, 0, 5, 'Unfettered Spirit - World Loot Level 30'), +(4308, 2, 1000131, 0, 5, 'Unfettered Spirit - World Loot Level 31'), +(4416, 1, 1000118, 0, 5, 'Defias Strip Miner - World Loot Level 18'), +(4416, 2, 1000119, 0, 5, 'Defias Strip Miner - World Loot Level 19'), +(4417, 1, 1000318, 0, 5, 'Defias Taskmaster - World Loot Level 18'), +(4417, 2, 1000319, 0, 5, 'Defias Taskmaster - World Loot Level 19'), +(4418, 1, 1000318, 0, 5, 'Defias Wizard - World Loot Level 18'), +(4418, 2, 1000319, 0, 5, 'Defias Wizard - World Loot Level 19'), +(4425, 1, 1000227, 0, 5, 'Blind Hunter - World Loot Level 27'), +(4427, 1, 1000326, 0, 5, 'Ward Guardian - World Loot Level 26'), +(4435, 1, 1000324, 0, 5, 'Razorfen Warrior - World Loot Level 24'), +(4435, 2, 1000325, 0, 5, 'Razorfen Warrior - World Loot Level 25'), +(4436, 1, 1000325, 0, 5, 'Razorfen Quilguard - World Loot Level 25'), +(4437, 1, 1000325, 0, 5, 'Razorfen Warden - World Loot Level 25'), +(4438, 1, 1000325, 0, 5, 'Razorfen Spearhide - World Loot Level 25'), +(4438, 2, 1000326, 0, 5, 'Razorfen Spearhide - World Loot Level 26'), +(4440, 1, 1000325, 0, 5, 'Razorfen Totemic - World Loot Level 25'), +(4440, 2, 1000326, 0, 5, 'Razorfen Totemic - World Loot Level 26'), +(4442, 1, 1000325, 0, 5, 'Razorfen Defender - World Loot Level 25'), +(4442, 2, 1000326, 0, 5, 'Razorfen Defender - World Loot Level 26'), +(4512, 1, 1000226, 0, 5, 'Rotting Agam\'ar - World Loot Level 26'), +(4514, 1, 1000225, 0, 5, 'Raging Agam\'ar - World Loot Level 25'), +(4515, 1, 1000325, 0, 5, 'Death\'s Head Acolyte - World Loot Level 25'), +(4515, 2, 1000326, 0, 5, 'Death\'s Head Acolyte - World Loot Level 26'), +(4516, 1, 1000325, 0, 5, 'Death\'s Head Adept - World Loot Level 25'), +(4516, 2, 1000326, 0, 5, 'Death\'s Head Adept - World Loot Level 26'), +(4517, 1, 1000325, 0, 5, 'Death\'s Head Priest - World Loot Level 25'), +(4518, 1, 1000325, 0, 5, 'Death\'s Head Sage - World Loot Level 25'), +(4518, 2, 1000326, 0, 5, 'Death\'s Head Sage - World Loot Level 26'), +(4519, 1, 1000325, 0, 5, 'Death\'s Head Seer - World Loot Level 25'), +(4519, 2, 1000326, 0, 5, 'Death\'s Head Seer - World Loot Level 26'), +(4520, 1, 1000325, 0, 5, 'Razorfen Geomancer - World Loot Level 25'), +(4522, 1, 1000325, 0, 5, 'Razorfen Dustweaver - World Loot Level 25'), +(4522, 2, 1000326, 0, 5, 'Razorfen Dustweaver - World Loot Level 26'), +(4523, 1, 1000325, 0, 5, 'Razorfen Groundshaker - World Loot Level 25'), +(4523, 2, 1000326, 0, 5, 'Razorfen Groundshaker - World Loot Level 26'), +(4525, 1, 1000326, 0, 5, 'Razorfen Earthbreaker - World Loot Level 26'), +(4530, 1, 1000325, 0, 5, 'Razorfen Handler - World Loot Level 25'), +(4531, 1, 1000325, 0, 5, 'Razorfen Beast Trainer - World Loot Level 25'), +(4531, 2, 1000326, 0, 5, 'Razorfen Beast Trainer - World Loot Level 26'), +(4532, 1, 1000326, 0, 5, 'Razorfen Beastmaster - World Loot Level 26'), +(4538, 1, 1000226, 0, 5, 'Kraul Bat - World Loot Level 26'), +(4539, 1, 1000226, 0, 5, 'Greater Kraul Bat - World Loot Level 26'), +(4540, 1, 1000334, 0, 5, 'Scarlet Monk - World Loot Level 34'), +(4541, 1, 1000226, 0, 5, 'Blood of Agamaggan - World Loot Level 26'), +(4623, 1, 1000326, 0, 5, 'Quilguard Champion - World Loot Level 26'), +(4787, 1, 1000120, 0, 5, 'Argent Guard Thaelrid - World Loot Level 20'), +(4798, 1, 1000322, 0, 5, 'Fallenroot Shadowstalker - World Loot Level 22'), +(4798, 2, 1000323, 0, 5, 'Fallenroot Shadowstalker - World Loot Level 23'), +(4799, 1, 1000322, 0, 5, 'Fallenroot Hellcaller - World Loot Level 22'), +(4799, 2, 1000323, 0, 5, 'Fallenroot Hellcaller - World Loot Level 23'), +(4805, 1, 1000322, 0, 5, 'Blackfathom Sea Witch - World Loot Level 22'), +(4805, 2, 1000323, 0, 5, 'Blackfathom Sea Witch - World Loot Level 23'), +(4807, 1, 1000322, 0, 5, 'Blackfathom Myrmidon - World Loot Level 22'), +(4809, 1, 1000322, 0, 5, 'Twilight Acolyte - World Loot Level 22'), +(4809, 2, 1000323, 0, 5, 'Twilight Acolyte - World Loot Level 23'), +(4810, 1, 1000323, 0, 5, 'Twilight Reaver - World Loot Level 23'), +(4811, 1, 1000323, 0, 5, 'Twilight Aquamancer - World Loot Level 23'), +(4812, 1, 1000322, 0, 5, 'Twilight Loreseeker - World Loot Level 22'), +(4812, 2, 1000323, 0, 5, 'Twilight Loreseeker - World Loot Level 23'), +(4813, 1, 1000323, 0, 5, 'Twilight Shadowmage - World Loot Level 23'), +(4814, 1, 1000323, 0, 5, 'Twilight Elementalist - World Loot Level 23'), +(4815, 1, 1000322, 0, 5, 'Murkshallow Snapclaw - World Loot Level 22'), +(4818, 1, 1000322, 0, 5, 'Blindlight Murloc - World Loot Level 22'), +(4819, 1, 1000323, 0, 5, 'Blindlight Muckdweller - World Loot Level 23'), +(4820, 1, 1000323, 0, 5, 'Blindlight Oracle - World Loot Level 23'), +(4821, 1, 1000222, 0, 5, 'Skittering Crustacean - World Loot Level 22'), +(4822, 1, 1000222, 0, 5, 'Snapping Crustacean - World Loot Level 22'), +(4822, 2, 1000223, 0, 5, 'Snapping Crustacean - World Loot Level 23'), +(4823, 1, 1000223, 0, 5, 'Barbed Crustacean - World Loot Level 23'), +(4824, 1, 1000222, 0, 5, 'Aku\'mai Fisher - World Loot Level 22'), +(4824, 2, 1000223, 0, 5, 'Aku\'mai Fisher - World Loot Level 23'), +(4825, 1, 1000223, 0, 5, 'Aku\'mai Snapjaw - World Loot Level 23'), +(4827, 1, 1000222, 0, 5, 'Deep Pool Threshfin - World Loot Level 22'), +(4827, 2, 1000223, 0, 5, 'Deep Pool Threshfin - World Loot Level 23'), +(4842, 1, 1000327, 0, 5, 'Earthcaller Halmgar - World Loot Level 27'), +(4847, 1, 1000338, 0, 5, 'Shadowforge Relic Hunter - World Loot Level 38'), +(4847, 2, 1000339, 0, 5, 'Shadowforge Relic Hunter - World Loot Level 39'), +(4848, 1, 1000338, 0, 5, 'Shadowforge Darkcaster - World Loot Level 38'), +(4848, 2, 1000339, 0, 5, 'Shadowforge Darkcaster - World Loot Level 39'), +(4849, 1, 1000338, 0, 5, 'Shadowforge Archaeologist - World Loot Level 38'), +(4849, 2, 1000339, 0, 5, 'Shadowforge Archaeologist - World Loot Level 39'), +(4850, 1, 1000337, 0, 5, 'Stonevault Cave Lurker - World Loot Level 37'), +(4850, 2, 1000338, 0, 5, 'Stonevault Cave Lurker - World Loot Level 38'), +(4851, 1, 1000136, 0, 5, 'Stonevault Rockchewer - World Loot Level 36'), +(4851, 2, 1000137, 0, 5, 'Stonevault Rockchewer - World Loot Level 37'), +(4852, 1, 1000337, 0, 5, 'Stonevault Oracle - World Loot Level 37'), +(4853, 1, 1000338, 0, 5, 'Stonevault Geomancer - World Loot Level 38'), +(4853, 2, 1000339, 0, 5, 'Stonevault Geomancer - World Loot Level 39'), +(4855, 1, 1000338, 0, 5, 'Stonevault Brawler - World Loot Level 38'), +(4855, 2, 1000339, 0, 5, 'Stonevault Brawler - World Loot Level 39'), +(4857, 1, 1000240, 0, 5, 'Stone Keeper - World Loot Level 40'), +(4860, 1, 1000239, 0, 5, 'Stone Steward - World Loot Level 39'), +(4861, 1, 1000237, 0, 5, 'Shrike Bat - World Loot Level 37'), +(4861, 2, 1000238, 0, 5, 'Shrike Bat - World Loot Level 38'), +(4863, 1, 1000237, 0, 5, 'Jadespine Basilisk - World Loot Level 37'), +(4863, 2, 1000238, 0, 5, 'Jadespine Basilisk - World Loot Level 38'), +(5048, 1, 1000218, 0, 5, 'Deviate Adder - World Loot Level 18'), +(5048, 2, 1000219, 0, 5, 'Deviate Adder - World Loot Level 19'), +(5053, 1, 1000018, 0, 5, 'Deviate Crocolisk - World Loot Level 18'), +(5053, 2, 1000019, 0, 5, 'Deviate Crocolisk - World Loot Level 19'), +(5055, 1, 1000019, 30, 5, 'Deviate Lasher - World Loot Level 19'), +(5056, 1, 1000219, 0, 5, 'Deviate Dreadfang - World Loot Level 19'), +(5226, 1, 1000247, 0, 5, 'Murk Worm - World Loot Level 47'), +(5226, 2, 1000248, 0, 5, 'Murk Worm - World Loot Level 48'), +(5228, 1, 1000247, 0, 5, 'Saturated Ooze - World Loot Level 47'), +(5228, 2, 1000248, 0, 5, 'Saturated Ooze - World Loot Level 48'), +(5256, 1, 1000348, 0, 5, 'Atal\'ai Warrior - World Loot Level 48'), +(5259, 1, 1000347, 0, 5, 'Atal\'ai Witch Doctor - World Loot Level 47'), +(5259, 2, 1000348, 0, 5, 'Atal\'ai Witch Doctor - World Loot Level 48'), +(5263, 1, 1000146, 0, 5, 'Mummified Atal\'ai - World Loot Level 46'), +(5263, 2, 1000147, 0, 5, 'Mummified Atal\'ai - World Loot Level 47'), +(5267, 1, 1000347, 0, 5, 'Unliving Atal\'ai - World Loot Level 47'), +(5267, 2, 1000348, 0, 5, 'Unliving Atal\'ai - World Loot Level 48'), +(5269, 1, 1000146, 0, 5, 'Atal\'ai Priest - World Loot Level 46'), +(5269, 2, 1000147, 0, 5, 'Atal\'ai Priest - World Loot Level 47'), +(5270, 1, 1000348, 0, 5, 'Atal\'ai Corpse Eater - World Loot Level 48'), +(5271, 1, 1000348, 0, 5, 'Atal\'ai Deathwalker - World Loot Level 48'), +(5271, 2, 1000349, 0, 5, 'Atal\'ai Deathwalker - World Loot Level 49'), +(5273, 1, 1000348, 0, 5, 'Atal\'ai High Priest - World Loot Level 48'), +(5273, 2, 1000349, 0, 5, 'Atal\'ai High Priest - World Loot Level 49'), +(5277, 1, 1000349, 0, 5, 'Nightmare Scalebane - World Loot Level 49'), +(5280, 1, 1000348, 0, 5, 'Nightmare Wyrmkin - World Loot Level 48'), +(5280, 2, 1000349, 0, 5, 'Nightmare Wyrmkin - World Loot Level 49'), +(5283, 1, 1000348, 0, 5, 'Nightmare Wanderer - World Loot Level 48'), +(5283, 2, 1000349, 0, 5, 'Nightmare Wanderer - World Loot Level 49'), +(5291, 1, 1000248, 0, 5, 'Hakkari Frostwing - World Loot Level 48'), +(5291, 2, 1000249, 0, 5, 'Hakkari Frostwing - World Loot Level 49'), +(5648, 1, 1000343, 0, 5, 'Sandfury Shadowcaster - World Loot Level 43'), +(5648, 2, 1000344, 0, 5, 'Sandfury Shadowcaster - World Loot Level 44'), +(5649, 1, 1000344, 0, 5, 'Sandfury Blood Drinker - World Loot Level 44'), +(5649, 2, 1000345, 0, 5, 'Sandfury Blood Drinker - World Loot Level 45'), +(5650, 1, 1000344, 0, 5, 'Sandfury Witch Doctor - World Loot Level 44'), +(5650, 2, 1000345, 0, 5, 'Sandfury Witch Doctor - World Loot Level 45'), +(5708, 1, 1000249, 0, 5, 'Spawn of Hakkar - World Loot Level 49'), +(5755, 1, 1000219, 0, 5, 'Deviate Viper - World Loot Level 19'), +(5756, 1, 1000219, 0, 5, 'Deviate Venomwing - World Loot Level 19'), +(5761, 1, 1000219, 0, 5, 'Deviate Shambler - World Loot Level 19'), +(5912, 1, 1000219, 0, 5, 'Deviate Faerie Dragon - World Loot Level 19'), +(6035, 1, 1000325, 0, 5, 'Razorfen Stalker - World Loot Level 25'), +(6035, 2, 1000326, 0, 5, 'Razorfen Stalker - World Loot Level 26'), +(6206, 1, 1000324, 0, 5, 'Caverndeep Burrower - World Loot Level 24'), +(6206, 2, 1000325, 0, 5, 'Caverndeep Burrower - World Loot Level 25'), +(6206, 3, 1000326, 0, 5, 'Caverndeep Burrower - World Loot Level 26'), +(6207, 1, 1000124, 0, 5, 'Caverndeep Ambusher - World Loot Level 24'), +(6207, 2, 1000125, 0, 5, 'Caverndeep Ambusher - World Loot Level 25'), +(6207, 3, 1000126, 0, 5, 'Caverndeep Ambusher - World Loot Level 26'), +(6211, 1, 1000326, 0, 5, 'Caverndeep Reaver - World Loot Level 26'), +(6212, 1, 1000327, 0, 5, 'Dark Iron Agent - World Loot Level 27'), +(6218, 1, 1000226, 0, 5, 'Irradiated Slime - World Loot Level 26'), +(6219, 1, 1000226, 0, 5, 'Corrosive Lurker - World Loot Level 26'), +(6219, 2, 1000227, 0, 5, 'Corrosive Lurker - World Loot Level 27'), +(6220, 1, 1000226, 0, 5, 'Irradiated Horror - World Loot Level 26'), +(6220, 2, 1000227, 0, 5, 'Irradiated Horror - World Loot Level 27'), +(6222, 1, 1000126, 0, 5, 'Leprous Technician - World Loot Level 26'), +(6222, 2, 1000127, 0, 5, 'Leprous Technician - World Loot Level 27'), +(6223, 1, 1000326, 0, 5, 'Leprous Defender - World Loot Level 26'), +(6223, 2, 1000327, 0, 5, 'Leprous Defender - World Loot Level 27'), +(6224, 1, 1000126, 0, 5, 'Leprous Machinesmith - World Loot Level 26'), +(6224, 2, 1000127, 0, 5, 'Leprous Machinesmith - World Loot Level 27'), +(6225, 1, 1000226, 0, 5, 'Mechano-Tank - World Loot Level 26'), +(6225, 2, 1000227, 0, 5, 'Mechano-Tank - World Loot Level 27'), +(6226, 1, 1000227, 0, 5, 'Mechano-Flamewalker - World Loot Level 27'), +(6227, 1, 1000227, 0, 5, 'Mechano-Frostwalker - World Loot Level 27'), +(6228, 1, 1000328, 0, 5, 'Dark Iron Ambassador - World Loot Level 28'), +(6230, 1, 1000227, 0, 5, 'Peacekeeper Security Suit - World Loot Level 27'), +(6232, 1, 1000227, 0, 5, 'Arcane Nullifier X-21 - World Loot Level 27'), +(6233, 1, 1000225, 0, 5, 'Mechanized Sentry - World Loot Level 25'), +(6233, 2, 1000226, 0, 5, 'Mechanized Sentry - World Loot Level 26'), +(6233, 3, 1000227, 0, 5, 'Mechanized Sentry - World Loot Level 27'), +(6234, 1, 1000227, 0, 5, 'Mechanized Guardian - World Loot Level 27'), +(6329, 1, 1000325, 0, 5, 'Irradiated Pillager - World Loot Level 25'), +(6329, 2, 1000326, 0, 5, 'Irradiated Pillager - World Loot Level 26'), +(6391, 1, 1000326, 0, 5, 'Holdout Warrior - World Loot Level 26'), +(6391, 2, 1000327, 0, 5, 'Holdout Warrior - World Loot Level 27'), +(6392, 1, 1000326, 0, 5, 'Holdout Medic - World Loot Level 26'), +(6392, 2, 1000327, 0, 5, 'Holdout Medic - World Loot Level 27'), +(6407, 1, 1000326, 0, 5, 'Holdout Technician - World Loot Level 26'), +(6407, 2, 1000327, 0, 5, 'Holdout Technician - World Loot Level 27'), +(6488, 1, 1000332, 0, 5, 'Fallen Champion - World Loot Level 32'), +(6489, 1, 1000332, 0, 5, 'Ironspine - World Loot Level 32'), +(6490, 1, 1000332, 0, 5, 'Azshir the Sleepless - World Loot Level 32'), +(7011, 1, 1000138, 0, 5, 'Earthen Rocksmasher - World Loot Level 38'), +(7011, 2, 1000139, 0, 5, 'Earthen Rocksmasher - World Loot Level 39'), +(7012, 1, 1000138, 0, 5, 'Earthen Sculptor - World Loot Level 38'), +(7012, 2, 1000139, 0, 5, 'Earthen Sculptor - World Loot Level 39'), +(7022, 1, 1000237, 0, 5, 'Venomlash Scorpid - World Loot Level 37'), +(7022, 2, 1000238, 0, 5, 'Venomlash Scorpid - World Loot Level 38'), +(7023, 1, 1000240, 0, 5, 'Obsidian Sentinel - World Loot Level 40'), +(7030, 1, 1000338, 0, 5, 'Shadowforge Geologist - World Loot Level 38'), +(7030, 2, 1000339, 0, 5, 'Shadowforge Geologist - World Loot Level 39'), +(7076, 1, 1000138, 25, 5, 'Earthen Guardian - World Loot Level 38'), +(7077, 1, 1000138, 25, 5, 'Earthen Hallshaper - World Loot Level 38'), +(7078, 1, 1000036, 0, 5, 'Cleft Scorpid - World Loot Level 36'), +(7079, 1, 1000228, 0, 5, 'Viscous Fallout - World Loot Level 28'), +(7175, 1, 1000135, 0, 5, 'Stonevault Ambusher - World Loot Level 35'), +(7206, 1, 1000240, 0, 5, 'Ancient Stone Keeper - World Loot Level 40'), +(7246, 1, 1000343, 0, 5, 'Sandfury Shadowhunter - World Loot Level 43'), +(7246, 2, 1000344, 0, 5, 'Sandfury Shadowhunter - World Loot Level 44'), +(7247, 1, 1000344, 0, 5, 'Sandfury Soul Eater - World Loot Level 44'), +(7247, 2, 1000345, 0, 5, 'Sandfury Soul Eater - World Loot Level 45'), +(7268, 1, 1000245, 0, 5, 'Sandfury Guardian - World Loot Level 45'), +(7269, 1, 1000044, 0, 5, 'Scarab - World Loot Level 44'), +(7274, 1, 1000346, 0, 5, 'Sandfury Executioner - World Loot Level 46'), +(7290, 1, 1000338, 0, 5, 'Shadowforge Sharpshooter - World Loot Level 38'), +(7290, 2, 1000339, 0, 5, 'Shadowforge Sharpshooter - World Loot Level 39'), +(7309, 1, 1000138, 25, 5, 'Earthen Custodian - World Loot Level 38'), +(7320, 1, 1000338, 0, 5, 'Stonevault Mauler - World Loot Level 38'), +(7320, 2, 1000339, 0, 5, 'Stonevault Mauler - World Loot Level 39'), +(7321, 1, 1000338, 0, 5, 'Stonevault Flameweaver - World Loot Level 38'), +(7321, 2, 1000339, 0, 5, 'Stonevault Flameweaver - World Loot Level 39'), +(7327, 1, 1000334, 0, 5, 'Withered Warrior - World Loot Level 34'), +(7327, 2, 1000335, 0, 5, 'Withered Warrior - World Loot Level 35'), +(7328, 1, 1000335, 0, 5, 'Withered Reaver - World Loot Level 35'), +(7328, 2, 1000336, 0, 5, 'Withered Reaver - World Loot Level 36'), +(7329, 1, 1000335, 0, 5, 'Withered Quilguard - World Loot Level 35'), +(7329, 2, 1000336, 0, 5, 'Withered Quilguard - World Loot Level 36'), +(7332, 1, 1000334, 0, 5, 'Withered Spearhide - World Loot Level 34'), +(7332, 2, 1000335, 0, 5, 'Withered Spearhide - World Loot Level 35'), +(7333, 1, 1000134, 0, 5, 'Withered Battle Boar - World Loot Level 34'), +(7334, 1, 1000135, 0, 5, 'Battle Boar Horror - World Loot Level 35'), +(7334, 2, 1000136, 0, 5, 'Battle Boar Horror - World Loot Level 36'), +(7335, 1, 1000335, 0, 5, 'Death\'s Head Geomancer - World Loot Level 35'), +(7337, 1, 1000335, 0, 5, 'Death\'s Head Necromancer - World Loot Level 35'), +(7341, 1, 1000335, 0, 5, 'Skeletal Frostweaver - World Loot Level 35'), +(7341, 2, 1000336, 0, 5, 'Skeletal Frostweaver - World Loot Level 36'), +(7342, 1, 1000336, 0, 5, 'Skeletal Summoner - World Loot Level 36'), +(7344, 1, 1000135, 0, 5, 'Splinterbone Warrior - World Loot Level 35'), +(7344, 2, 1000136, 0, 5, 'Splinterbone Warrior - World Loot Level 36'), +(7345, 1, 1000336, 0, 5, 'Splinterbone Captain - World Loot Level 36'), +(7346, 1, 1000136, 0, 5, 'Splinterbone Centurion - World Loot Level 36'), +(7347, 1, 1000336, 0, 5, 'Boneflayer Ghoul - World Loot Level 36'), +(7348, 1, 1000335, 0, 5, 'Thorn Eater Ghoul - World Loot Level 35'), +(7348, 2, 1000336, 0, 5, 'Thorn Eater Ghoul - World Loot Level 36'), +(7352, 1, 1000335, 0, 5, 'Frozen Soul - World Loot Level 35'), +(7352, 2, 1000336, 0, 5, 'Frozen Soul - World Loot Level 36'), +(7353, 1, 1000336, 0, 5, 'Freezing Spirit - World Loot Level 36'), +(7354, 1, 1000337, 0, 5, 'Ragglesnout - World Loot Level 37'), +(7357, 1, 1000337, 0, 5, 'Mordresh Fire Eye - World Loot Level 37'), +(7358, 1, 1000337, 0, 5, 'Amnennar the Coldbringer - World Loot Level 37'), +(7396, 1, 1000139, 0, 5, 'Earthen Stonebreaker - World Loot Level 39'), +(7397, 1, 1000139, 0, 5, 'Earthen Stonecarver - World Loot Level 39'), +(7405, 1, 1000037, 0, 5, 'Deadly Cleft Scorpid - World Loot Level 37'), +(7405, 2, 1000038, 0, 5, 'Deadly Cleft Scorpid - World Loot Level 38'), +(7603, 1, 1000126, 0, 5, 'Leprous Assistant - World Loot Level 26'), +(7603, 2, 1000127, 0, 5, 'Leprous Assistant - World Loot Level 27'), +(8095, 1, 1000244, 0, 5, 'Sul\'lithuz Sandcrawler - World Loot Level 44'), +(8095, 2, 1000245, 0, 5, 'Sul\'lithuz Sandcrawler - World Loot Level 45'), +(8120, 1, 1000245, 0, 5, 'Sul\'lithuz Abomination - World Loot Level 45'), +(8311, 1, 1000045, 0, 5, 'Slime Maggot - World Loot Level 45'), +(8311, 2, 1000046, 0, 5, 'Slime Maggot - World Loot Level 46'), +(8318, 1, 1000046, 0, 5, 'Atal\'ai Slave - World Loot Level 46'), +(8318, 2, 1000047, 0, 5, 'Atal\'ai Slave - World Loot Level 47'), +(8319, 1, 1000048, 0, 5, 'Nightmare Whelp - World Loot Level 48'), +(8384, 1, 1000247, 0, 5, 'Deep Lurker - World Loot Level 47'), +(8384, 2, 1000248, 0, 5, 'Deep Lurker - World Loot Level 48'), +(8886, 1, 1000018, 0, 5, 'Deviate Python - World Loot Level 18'), +(8886, 2, 1000019, 0, 5, 'Deviate Python - World Loot Level 19'), +(8891, 1, 1000350, 0, 5, 'Anvilrage Warden - World Loot Level 50'), +(8891, 2, 1000351, 0, 5, 'Anvilrage Warden - World Loot Level 51'), +(8892, 1, 1000350, 0, 5, 'Anvilrage Footman - World Loot Level 50'), +(8892, 2, 1000351, 0, 5, 'Anvilrage Footman - World Loot Level 51'), +(8893, 1, 1000350, 0, 5, 'Anvilrage Soldier - World Loot Level 50'), +(8894, 1, 1000350, 0, 5, 'Anvilrage Medic - World Loot Level 50'), +(8894, 2, 1000351, 0, 5, 'Anvilrage Medic - World Loot Level 51'), +(8895, 1, 1000351, 0, 5, 'Anvilrage Officer - World Loot Level 51'), +(8896, 1, 1000150, 0, 5, 'Shadowforge Peasant - World Loot Level 50'), +(8896, 2, 1000151, 0, 5, 'Shadowforge Peasant - World Loot Level 51'), +(8897, 1, 1000151, 0, 5, 'Doomforge Craftsman - World Loot Level 51'), +(8898, 1, 1000353, 0, 5, 'Anvilrage Marshal - World Loot Level 53'), +(8898, 2, 1000354, 0, 5, 'Anvilrage Marshal - World Loot Level 54'), +(8899, 1, 1000353, 0, 5, 'Doomforge Dragoon - World Loot Level 53'), +(8899, 2, 1000354, 0, 5, 'Doomforge Dragoon - World Loot Level 54'), +(8900, 1, 1000154, 0, 5, 'Doomforge Arcanasmith - World Loot Level 54'), +(8902, 1, 1000151, 0, 5, 'Shadowforge Citizen - World Loot Level 51'), +(8902, 2, 1000152, 0, 5, 'Shadowforge Citizen - World Loot Level 52'), +(8903, 1, 1000355, 0, 5, 'Anvilrage Captain - World Loot Level 55'), +(8904, 1, 1000154, 0, 5, 'Shadowforge Senator - World Loot Level 54'), +(8904, 2, 1000155, 0, 5, 'Shadowforge Senator - World Loot Level 55'), +(8905, 1, 1000252, 0, 5, 'Warbringer Construct - World Loot Level 52'), +(8906, 1, 1000254, 0, 5, 'Ragereaver Golem - World Loot Level 54'), +(8907, 1, 1000254, 0, 5, 'Wrath Hammer Construct - World Loot Level 54'), +(8908, 1, 1000255, 0, 5, 'Molten War Golem - World Loot Level 55'), +(8909, 1, 1000250, 0, 5, 'Fireguard - World Loot Level 50'), +(8909, 2, 1000251, 0, 5, 'Fireguard - World Loot Level 51'), +(8909, 3, 1000252, 0, 5, 'Fireguard - World Loot Level 52'), +(8910, 1, 1000252, 0, 5, 'Blazing Fireguard - World Loot Level 52'), +(8911, 1, 1000254, 0, 5, 'Fireguard Destroyer - World Loot Level 54'), +(8912, 1, 1000350, 0, 5, 'Twilight\'s Hammer Torturer - World Loot Level 50'), +(8912, 2, 1000351, 0, 5, 'Twilight\'s Hammer Torturer - World Loot Level 51'), +(8913, 1, 1000351, 0, 5, 'Twilight Emissary - World Loot Level 51'), +(8913, 2, 1000352, 0, 5, 'Twilight Emissary - World Loot Level 52'), +(8914, 1, 1000352, 0, 5, 'Twilight Bodyguard - World Loot Level 52'), +(8915, 1, 1000154, 0, 5, 'Twilight\'s Hammer Ambassador - World Loot Level 54'), +(8915, 2, 1000155, 0, 5, 'Twilight\'s Hammer Ambassador - World Loot Level 55'), +(8916, 1, 1000150, 0, 5, 'Arena Spectator - World Loot Level 50'), +(8916, 2, 1000151, 0, 5, 'Arena Spectator - World Loot Level 51'), +(8920, 1, 1000153, 0, 5, 'Weapon Technician - World Loot Level 53'), +(8920, 2, 1000154, 0, 5, 'Weapon Technician - World Loot Level 54'), +(8921, 1, 1000049, 0, 5, 'Bloodhound - World Loot Level 49'), +(8921, 2, 1000050, 0, 5, 'Bloodhound - World Loot Level 50'), +(8922, 1, 1000052, 0, 5, 'Bloodhound Mastiff - World Loot Level 52'), +(8922, 2, 1000053, 0, 5, 'Bloodhound Mastiff - World Loot Level 53'), +(8923, 1, 1000256, 0, 5, 'Panzor the Invincible - World Loot Level 56'), +(9024, 1, 1000352, 0, 5, 'Pyromancer Loregrain - World Loot Level 52'), +(9041, 1, 1000354, 0, 5, 'Warder Stilgiss - World Loot Level 54'), +(9042, 1, 1000253, 0, 5, 'Verek - World Loot Level 53'), +(9045, 1, 1000354, 0, 5, 'Scarshield Acolyte - World Loot Level 54'), +(9045, 2, 1000355, 0, 5, 'Scarshield Acolyte - World Loot Level 55'), +(9096, 1, 1000358, 0, 5, 'Rage Talon Dragonspawn - World Loot Level 58'), +(9096, 2, 1000359, 0, 5, 'Rage Talon Dragonspawn - World Loot Level 59'), +(9097, 1, 1000354, 0, 5, 'Scarshield Legionnaire - World Loot Level 54'), +(9097, 2, 1000355, 0, 5, 'Scarshield Legionnaire - World Loot Level 55'), +(9098, 1, 1000354, 0, 5, 'Scarshield Spellbinder - World Loot Level 54'), +(9098, 2, 1000355, 0, 5, 'Scarshield Spellbinder - World Loot Level 55'), +(9197, 1, 1000357, 0, 5, 'Spirestone Battle Mage - World Loot Level 57'), +(9197, 2, 1000358, 0, 5, 'Spirestone Battle Mage - World Loot Level 58'), +(9198, 1, 1000355, 0, 5, 'Spirestone Mystic - World Loot Level 55'), +(9198, 2, 1000356, 0, 5, 'Spirestone Mystic - World Loot Level 56'), +(9199, 1, 1000354, 0, 5, 'Spirestone Enforcer - World Loot Level 54'), +(9199, 2, 1000355, 0, 5, 'Spirestone Enforcer - World Loot Level 55'), +(9200, 1, 1000355, 0, 5, 'Spirestone Reaver - World Loot Level 55'), +(9200, 2, 1000356, 0, 5, 'Spirestone Reaver - World Loot Level 56'), +(9201, 1, 1000354, 0, 5, 'Spirestone Ogre Magus - World Loot Level 54'), +(9201, 2, 1000355, 0, 5, 'Spirestone Ogre Magus - World Loot Level 55'), +(9216, 1, 1000357, 0, 5, 'Spirestone Warlord - World Loot Level 57'), +(9216, 2, 1000358, 0, 5, 'Spirestone Warlord - World Loot Level 58'), +(9217, 1, 1000358, 0, 5, 'Spirestone Lord Magus - World Loot Level 58'), +(9218, 1, 1000358, 0, 5, 'Spirestone Battle Lord - World Loot Level 58'), +(9219, 1, 1000357, 0, 5, 'Spirestone Butcher - World Loot Level 57'), +(9239, 1, 1000355, 0, 5, 'Smolderthorn Mystic - World Loot Level 55'), +(9239, 2, 1000356, 0, 5, 'Smolderthorn Mystic - World Loot Level 56'), +(9240, 1, 1000355, 0, 5, 'Smolderthorn Shadow Priest - World Loot Level 55'), +(9240, 2, 1000356, 0, 5, 'Smolderthorn Shadow Priest - World Loot Level 56'), +(9241, 1, 1000356, 0, 5, 'Smolderthorn Headhunter - World Loot Level 56'), +(9241, 2, 1000357, 0, 5, 'Smolderthorn Headhunter - World Loot Level 57'), +(9257, 1, 1000354, 0, 5, 'Scarshield Warlock - World Loot Level 54'), +(9257, 2, 1000355, 0, 5, 'Scarshield Warlock - World Loot Level 55'), +(9258, 1, 1000355, 0, 5, 'Scarshield Raider - World Loot Level 55'), +(9258, 2, 1000356, 0, 5, 'Scarshield Raider - World Loot Level 56'), +(9259, 1, 1000356, 0, 5, 'Firebrand Grunt - World Loot Level 56'), +(9259, 2, 1000357, 0, 5, 'Firebrand Grunt - World Loot Level 57'), +(9260, 1, 1000357, 0, 5, 'Firebrand Legionnaire - World Loot Level 57'), +(9260, 2, 1000358, 0, 5, 'Firebrand Legionnaire - World Loot Level 58'), +(9261, 1, 1000356, 0, 5, 'Firebrand Darkweaver - World Loot Level 56'), +(9261, 2, 1000357, 0, 5, 'Firebrand Darkweaver - World Loot Level 57'), +(9262, 1, 1000356, 0, 5, 'Firebrand Invoker - World Loot Level 56'), +(9262, 2, 1000357, 0, 5, 'Firebrand Invoker - World Loot Level 57'), +(9263, 1, 1000357, 0, 5, 'Firebrand Dreadweaver - World Loot Level 57'), +(9263, 2, 1000358, 0, 5, 'Firebrand Dreadweaver - World Loot Level 58'), +(9264, 1, 1000357, 0, 5, 'Firebrand Pyromancer - World Loot Level 57'), +(9265, 1, 1000356, 0, 5, 'Smolderthorn Shadow Hunter - World Loot Level 56'), +(9265, 2, 1000357, 0, 5, 'Smolderthorn Shadow Hunter - World Loot Level 57'), +(9266, 1, 1000356, 0, 5, 'Smolderthorn Witch Doctor - World Loot Level 56'), +(9266, 2, 1000357, 0, 5, 'Smolderthorn Witch Doctor - World Loot Level 57'), +(9267, 1, 1000355, 0, 5, 'Smolderthorn Axe Thrower - World Loot Level 55'), +(9267, 2, 1000356, 0, 5, 'Smolderthorn Axe Thrower - World Loot Level 56'), +(9268, 1, 1000357, 0, 5, 'Smolderthorn Berserker - World Loot Level 57'), +(9268, 2, 1000358, 0, 5, 'Smolderthorn Berserker - World Loot Level 58'), +(9269, 1, 1000356, 0, 5, 'Smolderthorn Seer - World Loot Level 56'), +(9269, 2, 1000357, 0, 5, 'Smolderthorn Seer - World Loot Level 57'), +(9416, 1, 1000053, 0, 5, 'Scarshield Worg - World Loot Level 53'), +(9416, 2, 1000054, 0, 5, 'Scarshield Worg - World Loot Level 54'), +(9545, 1, 1000148, 0, 5, 'Grim Patron - World Loot Level 48'), +(9545, 2, 1000149, 0, 5, 'Grim Patron - World Loot Level 49'), +(9545, 3, 1000150, 0, 5, 'Grim Patron - World Loot Level 50'), +(9545, 4, 1000151, 0, 5, 'Grim Patron - World Loot Level 51'), +(9545, 5, 1000152, 0, 5, 'Grim Patron - World Loot Level 52'), +(9547, 1, 1000148, 0, 5, 'Guzzling Patron - World Loot Level 48'), +(9547, 2, 1000149, 0, 5, 'Guzzling Patron - World Loot Level 49'), +(9547, 3, 1000150, 0, 5, 'Guzzling Patron - World Loot Level 50'), +(9547, 4, 1000151, 0, 5, 'Guzzling Patron - World Loot Level 51'), +(9547, 5, 1000152, 0, 5, 'Guzzling Patron - World Loot Level 52'), +(9554, 1, 1000348, 0, 5, 'Hammered Patron - World Loot Level 48'), +(9554, 2, 1000349, 0, 5, 'Hammered Patron - World Loot Level 49'), +(9554, 3, 1000350, 0, 5, 'Hammered Patron - World Loot Level 50'), +(9554, 4, 1000351, 0, 5, 'Hammered Patron - World Loot Level 51'), +(9554, 5, 1000352, 0, 5, 'Hammered Patron - World Loot Level 52'), +(9583, 1, 1000358, 0, 5, 'Bloodaxe Veteran - World Loot Level 58'), +(9583, 2, 1000359, 0, 5, 'Bloodaxe Veteran - World Loot Level 59'), +(9596, 1, 1000359, 0, 5, 'Bannok Grimaxe - World Loot Level 59'), +(9692, 1, 1000357, 0, 5, 'Bloodaxe Raider - World Loot Level 57'), +(9692, 2, 1000358, 0, 5, 'Bloodaxe Raider - World Loot Level 58'), +(9693, 1, 1000358, 0, 5, 'Bloodaxe Evoker - World Loot Level 58'), +(9693, 2, 1000359, 0, 5, 'Bloodaxe Evoker - World Loot Level 59'), +(9696, 1, 1000056, 0, 5, 'Bloodaxe Worg - World Loot Level 56'), +(9696, 2, 1000057, 0, 5, 'Bloodaxe Worg - World Loot Level 57'), +(9701, 1, 1000058, 0, 5, 'Spire Scorpid - World Loot Level 58'), +(9716, 1, 1000357, 0, 5, 'Bloodaxe Warmonger - World Loot Level 57'), +(9716, 2, 1000358, 0, 5, 'Bloodaxe Warmonger - World Loot Level 58'), +(9717, 1, 1000357, 0, 5, 'Bloodaxe Summoner - World Loot Level 57'), +(9717, 2, 1000358, 0, 5, 'Bloodaxe Summoner - World Loot Level 58'), +(9718, 1, 1000359, 0, 5, 'Ghok Bashguud - World Loot Level 59'), +(9816, 1, 1000260, 0, 5, 'Pyroguard Emberseer - World Loot Level 60'), +(9817, 1, 1000359, 0, 5, 'Blackhand Dreadweaver - World Loot Level 59'), +(9817, 2, 1000360, 0, 5, 'Blackhand Dreadweaver - World Loot Level 60'), +(9818, 1, 1000359, 0, 5, 'Blackhand Summoner - World Loot Level 59'), +(9818, 2, 1000360, 0, 5, 'Blackhand Summoner - World Loot Level 60'), +(9819, 1, 1000359, 0, 5, 'Blackhand Veteran - World Loot Level 59'), +(9819, 2, 1000360, 0, 5, 'Blackhand Veteran - World Loot Level 60'), +(10080, 1, 1000345, 0, 5, 'Sandarr Dunereaver - World Loot Level 45'), +(10081, 1, 1000346, 0, 5, 'Dustwraith - World Loot Level 46'), +(10082, 1, 1000345, 0, 5, 'Zerillis - World Loot Level 45'), +(10083, 1, 1000358, 0, 5, 'Rage Talon Flamescale - World Loot Level 58'), +(10083, 2, 1000359, 0, 5, 'Rage Talon Flamescale - World Loot Level 59'), +(10177, 1, 1000058, 0, 5, 'Spire Scarab - World Loot Level 58'), +(10221, 1, 1000052, 0, 5, 'Bloodaxe Worg Pup - World Loot Level 52'), +(10221, 2, 1000053, 0, 5, 'Bloodaxe Worg Pup - World Loot Level 53'), +(10263, 1, 1000256, 0, 5, 'Burning Felguard - World Loot Level 56'), +(10263, 2, 1000257, 0, 5, 'Burning Felguard - World Loot Level 57'), +(10316, 1, 1000159, 0, 5, 'Blackhand Incarcerator - World Loot Level 59'), +(10316, 2, 1000160, 0, 5, 'Blackhand Incarcerator - World Loot Level 60'), +(10317, 1, 1000360, 0, 5, 'Blackhand Elite - World Loot Level 60'), +(10317, 2, 1000361, 0, 5, 'Blackhand Elite - World Loot Level 61'), +(10318, 1, 1000360, 0, 5, 'Blackhand Assassin - World Loot Level 60'), +(10318, 2, 1000361, 0, 5, 'Blackhand Assassin - World Loot Level 61'), +(10319, 1, 1000360, 0, 5, 'Blackhand Iron Guard - World Loot Level 60'), +(10319, 2, 1000361, 0, 5, 'Blackhand Iron Guard - World Loot Level 61'), +(10366, 1, 1000360, 0, 5, 'Rage Talon Dragon Guard - World Loot Level 60'), +(10366, 2, 1000361, 0, 5, 'Rage Talon Dragon Guard - World Loot Level 61'), +(10371, 1, 1000362, 0, 5, 'Rage Talon Captain - World Loot Level 62'), +(10372, 1, 1000360, 0, 5, 'Rage Talon Fire Tongue - World Loot Level 60'), +(10372, 2, 1000361, 0, 5, 'Rage Talon Fire Tongue - World Loot Level 61'), +(10374, 1, 1000257, 0, 5, 'Spire Spider - World Loot Level 57'), +(10374, 2, 1000258, 0, 5, 'Spire Spider - World Loot Level 58'), +(10375, 1, 1000055, 0, 5, 'Spire Spiderling - World Loot Level 55'), +(10375, 2, 1000056, 0, 5, 'Spire Spiderling - World Loot Level 56'), +(10376, 1, 1000260, 0, 5, 'Crystal Fang - World Loot Level 60'), +(10381, 1, 1000356, 0, 5, 'Ravaged Cadaver - World Loot Level 56'), +(10381, 2, 1000357, 0, 5, 'Ravaged Cadaver - World Loot Level 57'), +(10382, 1, 1000355, 0, 5, 'Mangled Cadaver - World Loot Level 55'), +(10382, 2, 1000356, 0, 5, 'Mangled Cadaver - World Loot Level 56'), +(10384, 1, 1000355, 0, 5, 'Spectral Citizen - World Loot Level 55'), +(10384, 2, 1000356, 0, 5, 'Spectral Citizen - World Loot Level 56'), +(10385, 1, 1000356, 0, 5, 'Ghostly Citizen - World Loot Level 56'), +(10385, 2, 1000357, 0, 5, 'Ghostly Citizen - World Loot Level 57'), +(10390, 1, 1000155, 0, 5, 'Skeletal Guardian - World Loot Level 55'), +(10390, 2, 1000156, 0, 5, 'Skeletal Guardian - World Loot Level 56'), +(10391, 1, 1000156, 0, 5, 'Skeletal Berserker - World Loot Level 56'), +(10391, 2, 1000157, 0, 5, 'Skeletal Berserker - World Loot Level 57'), +(10393, 1, 1000358, 0, 5, 'Skul - World Loot Level 58'), +(10398, 1, 1000358, 0, 5, 'Thuzadin Shadowcaster - World Loot Level 58'), +(10398, 2, 1000359, 0, 5, 'Thuzadin Shadowcaster - World Loot Level 59'), +(10399, 1, 1000159, 0, 5, 'Thuzadin Acolyte - World Loot Level 59'), +(10399, 2, 1000160, 0, 5, 'Thuzadin Acolyte - World Loot Level 60'), +(10400, 1, 1000360, 0, 5, 'Thuzadin Necromancer - World Loot Level 60'), +(10400, 2, 1000361, 0, 5, 'Thuzadin Necromancer - World Loot Level 61'), +(10405, 1, 1000357, 0, 5, 'Plague Ghoul - World Loot Level 57'), +(10405, 2, 1000358, 0, 5, 'Plague Ghoul - World Loot Level 58'), +(10406, 1, 1000358, 0, 5, 'Ghoul Ravener - World Loot Level 58'), +(10406, 2, 1000359, 0, 5, 'Ghoul Ravener - World Loot Level 59'), +(10407, 1, 1000359, 0, 5, 'Fleshflayer Ghoul - World Loot Level 59'), +(10407, 2, 1000360, 0, 5, 'Fleshflayer Ghoul - World Loot Level 60'), +(10408, 1, 1000255, 0, 5, 'Rockwing Gargoyle - World Loot Level 55'), +(10408, 2, 1000256, 0, 5, 'Rockwing Gargoyle - World Loot Level 56'), +(10408, 3, 1000257, 0, 5, 'Rockwing Gargoyle - World Loot Level 57'), +(10408, 4, 1000258, 0, 5, 'Rockwing Gargoyle - World Loot Level 58'), +(10409, 1, 1000258, 0, 5, 'Rockwing Screecher - World Loot Level 58'), +(10409, 2, 1000259, 0, 5, 'Rockwing Screecher - World Loot Level 59'), +(10411, 1, 1000155, 3.34, 5, 'Eye of Naxxramas - World Loot Level 55'), +(10411, 2, 1000156, 3.34, 5, 'Eye of Naxxramas - World Loot Level 56'), +(10411, 3, 1000157, 3.34, 5, 'Eye of Naxxramas - World Loot Level 57'), +(10412, 1, 1000258, 0, 5, 'Crypt Crawler - World Loot Level 58'), +(10412, 2, 1000259, 0, 5, 'Crypt Crawler - World Loot Level 59'), +(10413, 1, 1000259, 0, 5, 'Crypt Beast - World Loot Level 59'), +(10413, 2, 1000260, 0, 5, 'Crypt Beast - World Loot Level 60'), +(10414, 1, 1000357, 0, 5, 'Patchwork Horror - World Loot Level 57'), +(10414, 2, 1000358, 0, 5, 'Patchwork Horror - World Loot Level 58'), +(10416, 1, 1000359, 0, 5, 'Bile Spewer - World Loot Level 59'), +(10416, 2, 1000360, 0, 5, 'Bile Spewer - World Loot Level 60'), +(10417, 1, 1000360, 0, 5, 'Venom Belcher - World Loot Level 60'), +(10417, 2, 1000361, 0, 5, 'Venom Belcher - World Loot Level 61'), +(10418, 1, 1000357, 0, 5, 'Crimson Guardsman - World Loot Level 57'), +(10418, 2, 1000358, 0, 5, 'Crimson Guardsman - World Loot Level 58'), +(10419, 1, 1000357, 0, 5, 'Crimson Conjuror - World Loot Level 57'), +(10419, 2, 1000358, 0, 5, 'Crimson Conjuror - World Loot Level 58'), +(10420, 1, 1000357, 0, 5, 'Crimson Initiate - World Loot Level 57'), +(10420, 2, 1000358, 0, 5, 'Crimson Initiate - World Loot Level 58'), +(10421, 1, 1000358, 0, 5, 'Crimson Defender - World Loot Level 58'), +(10421, 2, 1000359, 0, 5, 'Crimson Defender - World Loot Level 59'), +(10422, 1, 1000358, 0, 5, 'Crimson Sorcerer - World Loot Level 58'), +(10422, 2, 1000359, 0, 5, 'Crimson Sorcerer - World Loot Level 59'), +(10423, 1, 1000358, 0, 5, 'Crimson Priest - World Loot Level 58'), +(10423, 2, 1000359, 0, 5, 'Crimson Priest - World Loot Level 59'), +(10424, 1, 1000359, 0, 5, 'Crimson Gallant - World Loot Level 59'), +(10424, 2, 1000360, 0, 5, 'Crimson Gallant - World Loot Level 60'), +(10425, 1, 1000359, 0, 5, 'Crimson Battle Mage - World Loot Level 59'), +(10425, 2, 1000360, 0, 5, 'Crimson Battle Mage - World Loot Level 60'), +(10426, 1, 1000359, 0, 5, 'Crimson Inquisitor - World Loot Level 59'), +(10426, 2, 1000360, 0, 5, 'Crimson Inquisitor - World Loot Level 60'), +(10442, 1, 1000057, 0, 5, 'Chromatic Whelp - World Loot Level 57'), +(10442, 2, 1000058, 0, 5, 'Chromatic Whelp - World Loot Level 58'), +(10447, 1, 1000359, 0, 5, 'Chromatic Dragonspawn - World Loot Level 59'), +(10447, 2, 1000360, 0, 5, 'Chromatic Dragonspawn - World Loot Level 60'), +(10463, 1, 1000357, 0, 5, 'Shrieking Banshee - World Loot Level 57'), +(10463, 2, 1000358, 0, 5, 'Shrieking Banshee - World Loot Level 58'), +(10464, 1, 1000358, 0, 5, 'Wailing Banshee - World Loot Level 58'), +(10464, 2, 1000359, 0, 5, 'Wailing Banshee - World Loot Level 59'), +(10469, 1, 1000358, 0, 5, 'Scholomance Adept - World Loot Level 58'), +(10469, 2, 1000359, 0, 5, 'Scholomance Adept - World Loot Level 59'), +(10470, 1, 1000357, 0, 5, 'Scholomance Neophyte - World Loot Level 57'), +(10470, 2, 1000358, 0, 5, 'Scholomance Neophyte - World Loot Level 58'), +(10471, 1, 1000357, 0, 5, 'Scholomance Acolyte - World Loot Level 57'), +(10471, 2, 1000358, 0, 5, 'Scholomance Acolyte - World Loot Level 58'), +(10472, 1, 1000358, 0, 5, 'Scholomance Occultist - World Loot Level 58'), +(10472, 2, 1000359, 0, 5, 'Scholomance Occultist - World Loot Level 59'), +(10475, 1, 1000358, 0, 5, 'Scholomance Student - World Loot Level 58'), +(10475, 2, 1000359, 0, 5, 'Scholomance Student - World Loot Level 59'), +(10476, 1, 1000357, 0, 5, 'Scholomance Necrolyte - World Loot Level 57'), +(10476, 2, 1000358, 0, 5, 'Scholomance Necrolyte - World Loot Level 58'), +(10477, 1, 1000358, 0, 5, 'Scholomance Necromancer - World Loot Level 58'), +(10477, 2, 1000359, 0, 5, 'Scholomance Necromancer - World Loot Level 59'), +(10478, 1, 1000359, 0, 5, 'Splintered Skeleton - World Loot Level 59'), +(10478, 2, 1000360, 0, 5, 'Splintered Skeleton - World Loot Level 60'), +(10480, 1, 1000158, 0, 5, 'Unstable Corpse - World Loot Level 58'), +(10480, 2, 1000159, 0, 5, 'Unstable Corpse - World Loot Level 59'), +(10481, 1, 1000158, 0, 5, 'Reanimated Corpse - World Loot Level 58'), +(10481, 2, 1000159, 0, 5, 'Reanimated Corpse - World Loot Level 59'), +(10485, 1, 1000157, 0, 5, 'Risen Aberration - World Loot Level 57'), +(10485, 2, 1000158, 0, 5, 'Risen Aberration - World Loot Level 58'), +(10486, 1, 1000359, 0, 5, 'Risen Warrior - World Loot Level 59'), +(10486, 2, 1000360, 0, 5, 'Risen Warrior - World Loot Level 60'), +(10486, 3, 1000361, 0, 5, 'Risen Warrior - World Loot Level 61'), +(10487, 1, 1000358, 0, 5, 'Risen Protector - World Loot Level 58'), +(10487, 2, 1000359, 0, 5, 'Risen Protector - World Loot Level 59'), +(10487, 3, 1000360, 0, 5, 'Risen Protector - World Loot Level 60'), +(10488, 1, 1000358, 0, 5, 'Risen Construct - World Loot Level 58'), +(10488, 2, 1000359, 0, 5, 'Risen Construct - World Loot Level 59'), +(10488, 3, 1000360, 0, 5, 'Risen Construct - World Loot Level 60'), +(10488, 4, 1000361, 0, 5, 'Risen Construct - World Loot Level 61'), +(10489, 1, 1000357, 0, 5, 'Risen Guard - World Loot Level 57'), +(10489, 2, 1000358, 0, 5, 'Risen Guard - World Loot Level 58'), +(10489, 3, 1000359, 0, 5, 'Risen Guard - World Loot Level 59'), +(10491, 1, 1000358, 0, 5, 'Risen Bonewarder - World Loot Level 58'), +(10491, 2, 1000359, 0, 5, 'Risen Bonewarder - World Loot Level 59'), +(10495, 1, 1000358, 0, 5, 'Diseased Ghoul - World Loot Level 58'), +(10495, 2, 1000359, 0, 5, 'Diseased Ghoul - World Loot Level 59'), +(10498, 1, 1000358, 0, 5, 'Spectral Tutor - World Loot Level 58'), +(10498, 2, 1000359, 0, 5, 'Spectral Tutor - World Loot Level 59'), +(10498, 3, 1000360, 0, 5, 'Spectral Tutor - World Loot Level 60'), +(10499, 1, 1000358, 0, 5, 'Spectral Researcher - World Loot Level 58'), +(10499, 2, 1000359, 0, 5, 'Spectral Researcher - World Loot Level 59'), +(10499, 3, 1000360, 0, 5, 'Spectral Researcher - World Loot Level 60'), +(10500, 1, 1000358, 0, 5, 'Spectral Teacher - World Loot Level 58'), +(10500, 2, 1000359, 0, 5, 'Spectral Teacher - World Loot Level 59'), +(10500, 3, 1000360, 0, 5, 'Spectral Teacher - World Loot Level 60'), +(10500, 4, 1000361, 0, 5, 'Spectral Teacher - World Loot Level 61'), +(10509, 1, 1000359, 0, 5, 'Jed Runewatcher - World Loot Level 59'), +(10558, 1, 1000357, 0, 5, 'Hearthsinger Forresten - World Loot Level 57'), +(10678, 1, 1000057, 0, 5, 'Plagued Hatchling - World Loot Level 57'), +(10678, 2, 1000058, 0, 5, 'Plagued Hatchling - World Loot Level 58'), +(10678, 3, 1000059, 0, 5, 'Plagued Hatchling - World Loot Level 59'), +(10762, 1, 1000360, 0, 5, 'Blackhand Thug - World Loot Level 60'), +(10809, 1, 1000360, 0, 5, 'Stonespine - World Loot Level 60'), +(10814, 1, 1000359, 0, 5, 'Chromatic Elite Guard - World Loot Level 59'), +(10814, 2, 1000360, 0, 5, 'Chromatic Elite Guard - World Loot Level 60'), +(10899, 1, 1000361, 0, 5, 'Goraluk Anvilcrack - World Loot Level 61'), +(11043, 1, 1000358, 0, 5, 'Crimson Monk - World Loot Level 58'), +(11043, 2, 1000359, 0, 5, 'Crimson Monk - World Loot Level 59'), +(11043, 3, 1000360, 0, 5, 'Crimson Monk - World Loot Level 60'), +(11257, 1, 1000359, 0, 5, 'Scholomance Handler - World Loot Level 59'), +(11257, 2, 1000360, 0, 5, 'Scholomance Handler - World Loot Level 60'), +(11318, 1, 1000313, 0, 5, 'Ragefire Trogg - World Loot Level 13'), +(11318, 2, 1000314, 0, 5, 'Ragefire Trogg - World Loot Level 14'), +(11318, 3, 1000315, 0, 5, 'Ragefire Trogg - World Loot Level 15'), +(11319, 1, 1000313, 0, 5, 'Ragefire Shaman - World Loot Level 13'), +(11319, 2, 1000314, 0, 5, 'Ragefire Shaman - World Loot Level 14'), +(11319, 3, 1000315, 0, 5, 'Ragefire Shaman - World Loot Level 15'), +(11320, 1, 1000213, 0, 5, 'Earthborer - World Loot Level 13'), +(11320, 2, 1000214, 0, 5, 'Earthborer - World Loot Level 14'), +(11321, 1, 1000213, 0, 5, 'Molten Elemental - World Loot Level 13'), +(11322, 1, 1000313, 0, 5, 'Searing Blade Cultist - World Loot Level 13'), +(11322, 2, 1000314, 0, 5, 'Searing Blade Cultist - World Loot Level 14'), +(11322, 3, 1000315, 0, 5, 'Searing Blade Cultist - World Loot Level 15'), +(11323, 1, 1000313, 0, 5, 'Searing Blade Enforcer - World Loot Level 13'), +(11323, 2, 1000314, 0, 5, 'Searing Blade Enforcer - World Loot Level 14'), +(11323, 3, 1000315, 0, 5, 'Searing Blade Enforcer - World Loot Level 15'), +(11324, 1, 1000313, 0, 5, 'Searing Blade Warlock - World Loot Level 13'), +(11324, 2, 1000314, 0, 5, 'Searing Blade Warlock - World Loot Level 14'), +(11324, 3, 1000315, 0, 5, 'Searing Blade Warlock - World Loot Level 15'), +(11338, 1, 1000361, 0, 5, 'Hakkari Shadowcaster - World Loot Level 61'), +(11339, 1, 1000361, 0, 5, 'Hakkari Shadow Hunter - World Loot Level 61'), +(11340, 1, 1000361, 0, 5, 'Hakkari Blood Priest - World Loot Level 61'), +(11350, 1, 1000360, 0, 5, 'Gurubashi Axe Thrower - World Loot Level 60'), +(11351, 1, 1000360, 0, 5, 'Gurubashi Headhunter - World Loot Level 60'), +(11352, 1, 1000362, 0, 5, 'Gurubashi Berserker - World Loot Level 62'), +(11353, 1, 1000360, 0, 5, 'Gurubashi Blood Drinker - World Loot Level 60'), +(11356, 1, 1000361, 0, 5, 'Gurubashi Champion - World Loot Level 61'), +(11357, 1, 1000260, 0, 5, 'Son of Hakkar - World Loot Level 60'), +(11359, 1, 1000261, 0, 5, 'Soulflayer - World Loot Level 61'), +(11360, 1, 1000060, 0, 5, 'Zulian Cub - World Loot Level 60'), +(11361, 1, 1000260, 0, 5, 'Zulian Tiger - World Loot Level 60'), +(11365, 1, 1000260, 0, 5, 'Zulian Panther - World Loot Level 60'), +(11368, 1, 1000060, 0, 5, 'Bloodseeker Bat - World Loot Level 60'), +(11370, 1, 1000261, 0, 5, 'Razzashi Broodwidow - World Loot Level 61'), +(11371, 1, 1000260, 0, 5, 'Razzashi Serpent - World Loot Level 60'), +(11372, 1, 1000260, 0, 5, 'Razzashi Adder - World Loot Level 60'), +(11373, 1, 1000260, 0, 5, 'Razzashi Cobra - World Loot Level 60'), +(11387, 1, 1000161, 0, 5, 'Sandfury Speaker - World Loot Level 61'), +(11388, 1, 1000161, 0, 5, 'Witherbark Speaker - World Loot Level 61'), +(11390, 1, 1000161, 0, 5, 'Skullsplitter Speaker - World Loot Level 61'), +(11391, 1, 1000161, 0, 5, 'Vilebranch Speaker - World Loot Level 61'), +(11441, 1, 1000357, 0, 5, 'Gordok Brute - World Loot Level 57'), +(11441, 2, 1000358, 0, 5, 'Gordok Brute - World Loot Level 58'), +(11444, 1, 1000357, 0, 5, 'Gordok Mage-Lord - World Loot Level 57'), +(11444, 2, 1000358, 0, 5, 'Gordok Mage-Lord - World Loot Level 58'), +(11445, 1, 1000359, 0, 5, 'Gordok Captain - World Loot Level 59'), +(11445, 2, 1000360, 0, 5, 'Gordok Captain - World Loot Level 60'), +(11448, 1, 1000359, 0, 5, 'Gordok Warlock - World Loot Level 59'), +(11448, 2, 1000360, 0, 5, 'Gordok Warlock - World Loot Level 60'), +(11450, 1, 1000358, 0, 5, 'Gordok Reaver - World Loot Level 58'), +(11450, 2, 1000359, 0, 5, 'Gordok Reaver - World Loot Level 59'), +(11451, 1, 1000355, 0, 5, 'Wildspawn Satyr - World Loot Level 55'), +(11451, 2, 1000356, 0, 5, 'Wildspawn Satyr - World Loot Level 56'), +(11452, 1, 1000356, 0, 5, 'Wildspawn Rogue - World Loot Level 56'), +(11452, 2, 1000357, 0, 5, 'Wildspawn Rogue - World Loot Level 57'), +(11453, 1, 1000356, 0, 5, 'Wildspawn Trickster - World Loot Level 56'), +(11453, 2, 1000357, 0, 5, 'Wildspawn Trickster - World Loot Level 57'), +(11454, 1, 1000355, 0, 5, 'Wildspawn Betrayer - World Loot Level 55'), +(11454, 2, 1000356, 0, 5, 'Wildspawn Betrayer - World Loot Level 56'), +(11455, 1, 1000355, 0, 5, 'Wildspawn Felsworn - World Loot Level 55'), +(11455, 2, 1000356, 0, 5, 'Wildspawn Felsworn - World Loot Level 56'), +(11456, 1, 1000356, 0, 5, 'Wildspawn Shadowstalker - World Loot Level 56'), +(11457, 1, 1000356, 0, 5, 'Wildspawn Hellcaller - World Loot Level 56'), +(11457, 2, 1000357, 0, 5, 'Wildspawn Hellcaller - World Loot Level 57'), +(11458, 1, 1000357, 0, 5, 'Petrified Treant - World Loot Level 57'), +(11458, 2, 1000358, 0, 5, 'Petrified Treant - World Loot Level 58'), +(11458, 3, 1000359, 0, 5, 'Petrified Treant - World Loot Level 59'), +(11459, 1, 1000357, 0, 5, 'Ironbark Protector - World Loot Level 57'), +(11459, 2, 1000358, 0, 5, 'Ironbark Protector - World Loot Level 58'), +(11459, 3, 1000359, 0, 5, 'Ironbark Protector - World Loot Level 59'), +(11461, 1, 1000357, 0, 5, 'Warpwood Guardian - World Loot Level 57'), +(11461, 2, 1000358, 0, 5, 'Warpwood Guardian - World Loot Level 58'), +(11462, 1, 1000354, 0, 5, 'Warpwood Treant - World Loot Level 54'), +(11462, 2, 1000355, 0, 5, 'Warpwood Treant - World Loot Level 55'), +(11464, 1, 1000355, 0, 5, 'Warpwood Tangler - World Loot Level 55'), +(11464, 2, 1000356, 0, 5, 'Warpwood Tangler - World Loot Level 56'), +(11465, 1, 1000357, 0, 5, 'Warpwood Stomper - World Loot Level 57'), +(11465, 2, 1000358, 0, 5, 'Warpwood Stomper - World Loot Level 58'), +(11467, 1, 1000359, 0, 5, 'Tsu\'zee - World Loot Level 59'), +(11469, 1, 1000358, 0, 5, 'Eldreth Seether - World Loot Level 58'), +(11469, 2, 1000359, 0, 5, 'Eldreth Seether - World Loot Level 59'), +(11470, 1, 1000358, 0, 5, 'Eldreth Sorcerer - World Loot Level 58'), +(11470, 2, 1000359, 0, 5, 'Eldreth Sorcerer - World Loot Level 59'), +(11471, 1, 1000357, 0, 5, 'Eldreth Apparition - World Loot Level 57'), +(11471, 2, 1000358, 0, 5, 'Eldreth Apparition - World Loot Level 58'), +(11472, 1, 1000357, 0, 5, 'Eldreth Spirit - World Loot Level 57'), +(11472, 2, 1000358, 0, 5, 'Eldreth Spirit - World Loot Level 58'), +(11473, 1, 1000358, 0, 5, 'Eldreth Spectre - World Loot Level 58'), +(11473, 2, 1000359, 0, 5, 'Eldreth Spectre - World Loot Level 59'), +(11475, 1, 1000358, 0, 5, 'Eldreth Phantasm - World Loot Level 58'), +(11475, 2, 1000359, 0, 5, 'Eldreth Phantasm - World Loot Level 59'), +(11476, 1, 1000157, 0, 5, 'Skeletal Highborne - World Loot Level 57'), +(11476, 2, 1000158, 0, 5, 'Skeletal Highborne - World Loot Level 58'), +(11477, 1, 1000158, 0, 5, 'Rotting Highborne - World Loot Level 58'), +(11477, 2, 1000159, 0, 5, 'Rotting Highborne - World Loot Level 59'), +(11480, 1, 1000259, 0, 5, 'Arcane Aberration - World Loot Level 59'), +(11480, 2, 1000260, 0, 5, 'Arcane Aberration - World Loot Level 60'), +(11483, 1, 1000257, 0, 5, 'Mana Remnant - World Loot Level 57'), +(11483, 2, 1000258, 0, 5, 'Mana Remnant - World Loot Level 58'), +(11483, 3, 1000259, 0, 5, 'Mana Remnant - World Loot Level 59'), +(11484, 1, 1000259, 0, 5, 'Residual Monstrosity - World Loot Level 59'), +(11484, 2, 1000260, 0, 5, 'Residual Monstrosity - World Loot Level 60'), +(11551, 1, 1000258, 0, 5, 'Necrofiend - World Loot Level 58'), +(11551, 2, 1000259, 0, 5, 'Necrofiend - World Loot Level 59'), +(11551, 3, 1000260, 0, 5, 'Necrofiend - World Loot Level 60'), +(11582, 1, 1000358, 0, 5, 'Scholomance Dark Summoner - World Loot Level 58'), +(11582, 2, 1000359, 0, 5, 'Scholomance Dark Summoner - World Loot Level 59'), +(11658, 1, 1000262, 0, 5, 'Molten Giant - World Loot Level 62'), +(11659, 1, 1000263, 0, 5, 'Molten Destroyer - World Loot Level 63'), +(11661, 1, 1000362, 0, 5, 'Flamewaker - World Loot Level 62'), +(11662, 1, 1000362, 0, 5, 'Flamewaker Priest - World Loot Level 62'), +(11665, 1, 1000261, 0, 5, 'Lava Annihilator - World Loot Level 61'), +(11665, 2, 1000262, 0, 5, 'Lava Annihilator - World Loot Level 62'), +(11666, 1, 1000261, 0, 5, 'Firewalker - World Loot Level 61'), +(11666, 2, 1000262, 0, 5, 'Firewalker - World Loot Level 62'), +(11667, 1, 1000261, 0, 5, 'Flameguard - World Loot Level 61'), +(11667, 2, 1000262, 0, 5, 'Flameguard - World Loot Level 62'), +(11668, 1, 1000261, 0, 5, 'Firelord - World Loot Level 61'), +(11668, 2, 1000262, 0, 5, 'Firelord - World Loot Level 62'), +(11673, 1, 1000262, 0, 5, 'Ancient Core Hound - World Loot Level 62'), +(11784, 1, 1000246, 0, 5, 'Theradrim Guardian - World Loot Level 46'), +(11784, 2, 1000247, 0, 5, 'Theradrim Guardian - World Loot Level 47'), +(11789, 1, 1000046, 0, 5, 'Deep Borer - World Loot Level 46'), +(11789, 2, 1000047, 0, 5, 'Deep Borer - World Loot Level 47'), +(11790, 1, 1000342, 0, 5, 'Putridus Satyr - World Loot Level 42'), +(11790, 2, 1000343, 0, 5, 'Putridus Satyr - World Loot Level 43'), +(11791, 1, 1000343, 0, 5, 'Putridus Trickster - World Loot Level 43'), +(11792, 1, 1000342, 0, 5, 'Putridus Shadowstalker - World Loot Level 42'), +(11792, 2, 1000343, 0, 5, 'Putridus Shadowstalker - World Loot Level 43'), +(11793, 1, 1000345, 0, 5, 'Celebrian Dryad - World Loot Level 45'), +(11794, 1, 1000345, 0, 5, 'Sister of Celebras - World Loot Level 45'), +(11830, 1, 1000360, 0, 5, 'Hakkari Priest - World Loot Level 60'), +(11831, 1, 1000360, 0, 5, 'Hakkari Witch Doctor - World Loot Level 60'), +(12076, 1, 1000261, 0, 5, 'Lava Elemental - World Loot Level 61'), +(12076, 2, 1000262, 0, 5, 'Lava Elemental - World Loot Level 62'), +(12100, 1, 1000262, 0, 5, 'Lava Reaver - World Loot Level 62'), +(12100, 2, 1000263, 0, 5, 'Lava Reaver - World Loot Level 63'), +(12101, 1, 1000261, 0, 5, 'Lava Surger - World Loot Level 61'), +(12101, 2, 1000262, 0, 5, 'Lava Surger - World Loot Level 62'), +(12119, 1, 1000362, 0, 5, 'Flamewaker Protector - World Loot Level 62'), +(12206, 1, 1000247, 0, 5, 'Primordial Behemoth - World Loot Level 47'), +(12216, 1, 1000042, 0, 5, 'Poison Sprite - World Loot Level 42'), +(12217, 1, 1000042, 0, 5, 'Corruptor - World Loot Level 42'), +(12218, 1, 1000044, 0, 5, 'Vile Larva - World Loot Level 44'), +(12219, 1, 1000245, 0, 5, 'Barbed Lasher - World Loot Level 45'), +(12220, 1, 1000244, 0, 5, 'Constrictor Vine - World Loot Level 44'), +(12220, 2, 1000245, 0, 5, 'Constrictor Vine - World Loot Level 45'), +(12221, 1, 1000243, 0, 5, 'Noxious Slime - World Loot Level 43'), +(12221, 2, 1000244, 0, 5, 'Noxious Slime - World Loot Level 44'), +(12222, 1, 1000243, 0, 5, 'Creeping Sludge - World Loot Level 43'), +(12222, 2, 1000244, 0, 5, 'Creeping Sludge - World Loot Level 44'), +(12223, 1, 1000344, 0, 5, 'Cavern Lurker - World Loot Level 44'), +(12223, 2, 1000345, 0, 5, 'Cavern Lurker - World Loot Level 45'), +(12224, 1, 1000345, 0, 5, 'Cavern Shambler - World Loot Level 45'), +(12237, 1, 1000246, 0, 5, 'Meshlok the Harvester - World Loot Level 46'), +(12457, 1, 1000362, 0, 5, 'Blackwing Spellbinder - World Loot Level 62'), +(12459, 1, 1000361, 0, 5, 'Blackwing Warlock - World Loot Level 61'), +(12460, 1, 1000363, 0, 5, 'Death Talon Wyrmguard - World Loot Level 63'), +(12461, 1, 1000362, 0, 5, 'Death Talon Overseer - World Loot Level 62'), +(12463, 1, 1000362, 0, 5, 'Death Talon Flamescale - World Loot Level 62'), +(12464, 1, 1000362, 0, 5, 'Death Talon Seether - World Loot Level 62'), +(12465, 1, 1000361, 0, 5, 'Death Talon Wyrmkin - World Loot Level 61'), +(12467, 1, 1000362, 0, 5, 'Death Talon Captain - World Loot Level 62'), +(12468, 1, 1000361, 0, 5, 'Death Talon Hatcher - World Loot Level 61'), +(12902, 1, 1000324, 0, 5, 'Lorgus Jett - World Loot Level 24'), +(13021, 1, 1000356, 0, 5, 'Warpwood Crusher - World Loot Level 56'), +(13022, 1, 1000054, 0, 5, 'Whip Lasher - World Loot Level 54'), +(13036, 1, 1000057, 0, 5, 'Gordok Mastiff - World Loot Level 57'), +(13036, 2, 1000058, 0, 5, 'Gordok Mastiff - World Loot Level 58'), +(13036, 3, 1000059, 0, 5, 'Gordok Mastiff - World Loot Level 59'), +(13141, 1, 1000342, 0, 5, 'Deeprot Stomper - World Loot Level 42'), +(13141, 2, 1000343, 0, 5, 'Deeprot Stomper - World Loot Level 43'), +(13142, 1, 1000343, 0, 5, 'Deeprot Tangler - World Loot Level 43'), +(13160, 1, 1000057, 15, 5, 'Carrion Swarmer - World Loot Level 57'), +(13160, 2, 1000058, 15, 5, 'Carrion Swarmer - World Loot Level 58'), +(13196, 1, 1000254, 0, 5, 'Phase Lasher - World Loot Level 54'), +(13196, 2, 1000255, 0, 5, 'Phase Lasher - World Loot Level 55'), +(13197, 1, 1000256, 0, 5, 'Fel Lash - World Loot Level 56'), +(13276, 1, 1000056, 0, 5, 'Wildspawn Imp - World Loot Level 56'), +(13285, 1, 1000257, 0, 5, 'Death Lash - World Loot Level 57'), +(13285, 2, 1000258, 0, 5, 'Death Lash - World Loot Level 58'), +(13323, 1, 1000246, 0, 5, 'Subterranean Diemetradon - World Loot Level 46'), +(13323, 2, 1000247, 0, 5, 'Subterranean Diemetradon - World Loot Level 47'), +(13533, 1, 1000244, 0, 5, 'Spewed Larva - World Loot Level 44'), +(13533, 2, 1000245, 0, 5, 'Spewed Larva - World Loot Level 45'), +(13599, 1, 1000045, 0, 5, 'Stolid Snapjaw - World Loot Level 45'), +(13599, 2, 1000046, 0, 5, 'Stolid Snapjaw - World Loot Level 46'), +(13996, 1, 1000360, 0, 5, 'Blackwing Technician - World Loot Level 60'), +(14303, 1, 1000257, 0, 5, 'Petrified Guardian - World Loot Level 57'), +(14303, 2, 1000258, 0, 5, 'Petrified Guardian - World Loot Level 58'), +(14303, 3, 1000259, 0, 5, 'Petrified Guardian - World Loot Level 59'), +(14398, 1, 1000258, 0, 5, 'Eldreth Darter - World Loot Level 58'), +(14398, 2, 1000259, 0, 5, 'Eldreth Darter - World Loot Level 59'), +(14399, 1, 1000259, 0, 5, 'Arcane Torrent - World Loot Level 59'), +(14399, 2, 1000260, 0, 5, 'Arcane Torrent - World Loot Level 60'), +(14400, 1, 1000059, 0, 5, 'Arcane Feedback - World Loot Level 59'), +(14400, 2, 1000060, 0, 5, 'Arcane Feedback - World Loot Level 60'), +(14532, 1, 1000260, 0, 5, 'Razzashi Venombrood - World Loot Level 60'), +(14750, 1, 1000359, 0, 5, 'Gurubashi Bat Rider - World Loot Level 59'), +(14750, 2, 1000360, 0, 5, 'Gurubashi Bat Rider - World Loot Level 60'), +(14750, 3, 1000361, 0, 5, 'Gurubashi Bat Rider - World Loot Level 61'), +(14821, 1, 1000260, 0, 5, 'Razzashi Raptor - World Loot Level 60'), +(14825, 1, 1000360, 0, 5, 'Withered Mistress - World Loot Level 60'), +(14880, 1, 1000256, 0, 5, 'Razzashi Skitterer - World Loot Level 56'), +(14880, 2, 1000257, 0, 5, 'Razzashi Skitterer - World Loot Level 57'), +(14880, 3, 1000258, 0, 5, 'Razzashi Skitterer - World Loot Level 58'), +(14882, 1, 1000360, 0, 5, 'Atal\'ai Mistress - World Loot Level 60'), +(14883, 1, 1000360, 0, 5, 'Voodoo Slave - World Loot Level 60'), +(15043, 1, 1000259, 0, 5, 'Zulian Crocolisk - World Loot Level 59'), +(15043, 2, 1000260, 0, 5, 'Zulian Crocolisk - World Loot Level 60'), +(15067, 1, 1000261, 0, 5, 'Zulian Stalker - World Loot Level 61'), +(15111, 1, 1000361, 0, 5, 'Mad Servant - World Loot Level 61'), +(15168, 1, 1000055, 0, 5, 'Vile Scarab - World Loot Level 55'), +(15229, 1, 1000261, 0, 5, 'Vekniss Soldier - World Loot Level 61'), +(15230, 1, 1000261, 0, 5, 'Vekniss Warrior - World Loot Level 61'), +(15233, 1, 1000261, 0, 5, 'Vekniss Guardian - World Loot Level 61'), +(15235, 1, 1000262, 0, 5, 'Vekniss Stinger - World Loot Level 62'), +(15236, 1, 1000260, 0, 5, 'Vekniss Wasp - World Loot Level 60'), +(15240, 1, 1000262, 0, 5, 'Vekniss Hive Crawler - World Loot Level 62'), +(15247, 1, 1000261, 0, 5, 'Qiraji Brainwasher - World Loot Level 61'), +(15249, 1, 1000261, 0, 5, 'Qiraji Lasher - World Loot Level 61'), +(15250, 1, 1000261, 0, 5, 'Qiraji Slayer - World Loot Level 61'), +(15252, 1, 1000263, 0, 5, 'Qiraji Champion - World Loot Level 63'), +(15262, 1, 1000260, 0, 5, 'Obsidian Eradicator - World Loot Level 60'), +(15264, 1, 1000261, 0, 5, 'Anubisath Sentinel - World Loot Level 61'), +(15277, 1, 1000262, 0, 5, 'Anubisath Defender - World Loot Level 62'), +(15311, 1, 1000263, 0, 5, 'Anubisath Warder - World Loot Level 63'), +(15312, 1, 1000261, 0, 5, 'Obsidian Nullifier - World Loot Level 61'), +(15318, 1, 1000260, 0, 5, 'Hive\'Zara Drone - World Loot Level 60'), +(15319, 1, 1000260, 0, 5, 'Hive\'Zara Collector - World Loot Level 60'), +(15320, 1, 1000261, 0, 5, 'Hive\'Zara Soldier - World Loot Level 61'), +(15323, 1, 1000261, 0, 5, 'Hive\'Zara Sandstalker - World Loot Level 61'), +(15324, 1, 1000261, 0, 5, 'Qiraji Gladiator - World Loot Level 61'), +(15325, 1, 1000261, 0, 5, 'Hive\'Zara Wasp - World Loot Level 61'), +(15327, 1, 1000261, 0, 5, 'Hive\'Zara Stinger - World Loot Level 61'), +(15333, 1, 1000055, 0, 5, 'Silicate Feeder - World Loot Level 55'), +(15335, 1, 1000262, 0, 5, 'Flesh Hunter - World Loot Level 62'), +(15336, 1, 1000261, 0, 5, 'Hive\'Zara Tail Lasher - World Loot Level 61'), +(15338, 1, 1000261, 0, 5, 'Obsidian Destroyer - World Loot Level 61'), +(15343, 1, 1000261, 0, 5, 'Qiraji Swarmguard - World Loot Level 61'), +(15355, 1, 1000262, 0, 5, 'Anubisath Guardian - World Loot Level 62'), +(15385, 1, 1000263, 0, 5, 'Colonel Zerran - World Loot Level 63'), +(15386, 1, 1000263, 0, 5, 'Major Yeggeth - World Loot Level 63'), +(15388, 1, 1000263, 0, 5, 'Major Pakkon - World Loot Level 63'), +(15389, 1, 1000263, 0, 5, 'Captain Drenn - World Loot Level 63'), +(15390, 1, 1000263, 0, 5, 'Captain Xurrem - World Loot Level 63'), +(15391, 1, 1000263, 0, 5, 'Captain Qeez - World Loot Level 63'), +(15392, 1, 1000263, 0, 5, 'Captain Tuubid - World Loot Level 63'), +(15461, 1, 1000260, 0, 5, 'Shrieker Scarab - World Loot Level 60'), +(15462, 1, 1000260, 0, 5, 'Spitting Scarab - World Loot Level 60'), +(15505, 1, 1000260, 0, 5, 'Canal Frenzy - World Loot Level 60'); + +-- Deadmines Zone Drops +DELETE FROM `creature_loot_template` WHERE (`Entry` IN (1729, 4418, 657, 1732, 634, 4417, 1725, 598, 4416, 636, 641, 3947, 622, 1731)) AND (`Item` IN (1929, 1951, 10400, 10401, 1925, 1930, 10402, 1934, 1945, 1943, 1936, 1944)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1729, 1929, 0, 6, 0, 'Silk-threaded Trousers'), +(4418, 1929, 0, 6, 0, 'Silk-threaded Trousers'), +(657, 1951, 0, 6, 0, 'Blackwater Cutlass'), +(1732, 1951, 0, 6, 0, 'Blackwater Cutlass'), +(634, 10400, 0, 3, 4, 'Blackened Defias Leggings'), +(4417, 10400, 0, 3, 4, 'Blackened Defias Leggings'), +(634, 10401, 0, 3, 4, 'Blackened Defias Gloves'), +(4417, 10401, 0, 3, 4, 'Blackened Defias Gloves'), +(1725, 1925, 0, 6, 0, 'Defias Rapier'), +(598, 1930, 0, 3, 0, 'Stonemason Cloak'), +(4416, 10402, 0, 3, 0, 'Blackened Defias Boots'), +(636, 1934, 0, 6, 0, 'Stonemason Trousers'), +(641, 1945, 0, 6, 0, 'Woodworking Gloves'), +(3947, 1943, 0, 6, 0, 'Goblin Mail Leggings'), +(622, 1936, 0, 6, 0, 'Goblin Screwdriver'), +(1731, 1944, 0, 6, 0, 'Metalworking Gloves'); + +-- Shadowfang Keep Zone Drops +DELETE FROM `reference_loot_template` WHERE `Entry` = 1033000; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1033000, 1318, 0, 0, 1, 'Shadowfang Keep BoEs - Night Reaver'), +(1033000, 1482, 0, 0, 1, 'Shadowfang Keep BoEs - Shadowfang'), +(1033000, 1483, 0, 0, 1, 'Shadowfang Keep BoEs - Face Smasher'), +(1033000, 1484, 0, 0, 1, 'Shadowfang Keep BoEs - Witching Stave'), +(1033000, 1489, 0, 0, 1, 'Shadowfang Keep BoEs - Gloomshroud Armor'), +(1033000, 1935, 0, 0, 1, 'Shadowfang Keep BoEs - Assassin\'s Blade'), +(1033000, 1974, 0, 0, 1, 'Shadowfang Keep BoEs - Mindthrust Bracers'), +(1033000, 2205, 0, 0, 1, 'Shadowfang Keep BoEs - Duskbringer'), +(1033000, 2292, 0, 0, 1, 'Shadowfang Keep BoEs - Necrology Robes'), +(1033000, 2807, 0, 0, 1, 'Shadowfang Keep BoEs - Guillotine Axe'), +(1033000, 3194, 0, 0, 1, 'Shadowfang Keep BoEs - Black Malice'); + +DELETE FROM `creature_loot_template` WHERE (`Entry` = 3864) AND (`Item` IN (6341)); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(3864, 6341, 0, 6, 0, 1, 0, 1, 1, 'Fel Steed - Eerie Stable Lantern'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (3861,3862,3864,3866,3868,3863,3873,3875,3877,2529,3851,3853,3854,3855,3857,3859,3872) AND `Item` IN (1318,1482,1483,1484,1489,1935,1974,2205,2292,2807,3194); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (3861,3862,3864,3866,3868,3863,3873,3875,3877,2529,3851,3853,3854,3855,3857,3859,3872) AND `Reference` = 1033000; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(3861, 33, 1033000, 0.5, 0, 'Bleak Worg - Shadowfang Keep BoEs'), +(3862, 33, 1033000, 0.5, 0, 'Slavering Worg - Shadowfang Keep BoEs'), +(3864, 33, 1033000, 0.5, 0, 'Fel Steed - Shadowfang Keep BoEs'), +(3866, 33, 1033000, 0.5, 0, 'Vile Bat - Shadowfang Keep BoEs'), +(3868, 33, 1033000, 0.5, 0, 'Blood Seeker - Shadowfang Keep BoEs'), +(3863, 33, 1033000, 0.5, 0, 'Lupine Horror - Shadowfang Keep BoEs'), +(3873, 33, 1033000, 0.5, 0, 'Tormented Officer - Shadowfang Keep BoEs'), +(3875, 33, 1033000, 0.5, 0, 'Haunted Servitor - Shadowfang Keep BoEs'), +(3877, 33, 1033000, 0.5, 0, 'Wailing Guardsman - Shadowfang Keep BoEs'), +(2529, 33, 1033000, 0.5, 0, 'Son of Arugal - Shadowfang Keep BoEs'), +(3851, 33, 1033000, 0.5, 0, 'Shadowfang Whitescalp - Shadowfang Keep BoEs'), +(3853, 33, 1033000, 0.5, 0, 'Shadowfang Moonwalker - Shadowfang Keep BoEs'), +(3854, 33, 1033000, 0.5, 0, 'Shadowfang Wolfguard - Shadowfang Keep BoEs'), +(3855, 33, 1033000, 0.5, 0, 'Shadowfang Darksoul - Shadowfang Keep BoEs'), +(3857, 33, 1033000, 0.5, 0, 'Shadowfang Glutton - Shadowfang Keep BoEs'), +(3859, 33, 1033000, 0.5, 0, 'Shadowfang Ragetooth - Shadowfang Keep BoEs'), +(3872, 33, 1033000, 0.5, 0, 'Deathsworn Captain - Shadowfang Keep BoEs'); + +-- Stockades +DELETE FROM `creature_loot_template` WHERE `Entry` IN (1707,1706,1708,1711,1715) AND `Item` = 1076; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1707, 1076, 0, 1, 0, 'The Stockade - Defias Renegade Ring'), +(1706, 1076, 0, 1, 0, 'The Stockade - Defias Renegade Ring'), +(1711, 1076, 0, 1, 0, 'The Stockade - Defias Renegade Ring'), +(1708, 1076, 0, 1, 0, 'The Stockade - Defias Renegade Ring'), +(1715, 1076, 0, 1, 0, 'The Stockade - Defias Renegade Ring'); + +-- Blackfathom Deep Zone Drops +DELETE FROM `reference_loot_template` WHERE `Entry` = 1048000; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1048000, 1454, 0, 0, 1, 'Blackfathom Deep BoEs - Axe of the Enforcer'), +(1048000, 1481, 0, 0, 1, 'Blackfathom Deep BoEs - Grimclaw'), +(1048000, 1486, 0, 0, 1, 'Blackfathom Deep BoEs - Tree Bark Jacket'), +(1048000, 1491, 0, 0, 1, 'Blackfathom Deep BoEs - Ring of Precision'), +(1048000, 2271, 0, 0, 1, 'Blackfathom Deep BoEs - Staff of the Blessed Seer'), +(1048000, 2567, 0, 0, 1, 'Blackfathom Deep BoEs - Evocator\'s Blade'), +(1048000, 3413, 0, 0, 1, 'Blackfathom Deep BoEs - Doomspike'), +(1048000, 3414, 0, 0, 1, 'Blackfathom Deep BoEs - Crested Scepter'), +(1048000, 3415, 0, 0, 1, 'Blackfathom Deep BoEs - Staff of the Friar'), +(1048000, 3416, 0, 0, 1, 'Blackfathom Deep BoEs - Martyr\'s Chain'), +(1048000, 3417, 0, 0, 1, 'Blackfathom Deep BoEs - Onyx Claymore'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (4814,4811,4813,4810,4812,4809) AND `Item` = 2034; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(4814, 2034, 0, 2, 0, 'Blackfathom Deep - Scholarly Robes'), +(4811, 2034, 0, 2, 0, 'Blackfathom Deep - Scholarly Robes'), +(4813, 2034, 0, 2, 0, 'Blackfathom Deep - Scholarly Robes'), +(4810, 2034, 0, 2, 0, 'Blackfathom Deep - Scholarly Robes'), +(4812, 2034, 0, 2, 0, 'Blackfathom Deep - Scholarly Robes'), +(4809, 2034, 0, 2, 0, 'Blackfathom Deep - Scholarly Robes'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (4821,4822,4823,4824,4825,4827,4798,4799,4805,4807,4809,4810,4811,4812,4813,4814,4815,4818,4819,4820) AND `Item` IN (1454,1481,1486,1491,2271,2567,3413,3414,3415,3416,3417); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (4821,4822,4823,4824,4825,4827,4798,4799,4805,4807,4809,4810,4811,4812,4813,4814,4815,4818,4819,4820) AND `Reference` = 1048000; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(4821, 48, 1048000, 0.5, 0, 'Skittering Crustacean - Blackfathom Deep BoEs'), +(4822, 48, 1048000, 0.5, 0, 'Snapping Crustacean - Blackfathom Deep BoEs'), +(4823, 48, 1048000, 0.5, 0, 'Barbed Crustacean - Blackfathom Deep BoEs'), +(4824, 48, 1048000, 0.5, 0, 'Aku\'mai Fisher - Blackfathom Deep BoEs'), +(4825, 48, 1048000, 0.5, 0, 'Aku\'mai Snapjaw - Blackfathom Deep BoEs'), +(4827, 48, 1048000, 0.5, 0, 'Deep Pool Threshfin - Blackfathom Deep BoEs'), +(4798, 48, 1048000, 0.5, 0, 'Fallenroot Shadowstalker - Blackfathom Deep BoEs'), +(4799, 48, 1048000, 0.5, 0, 'Fallenroot Hellcaller - Blackfathom Deep BoEs'), +(4805, 48, 1048000, 0.5, 0, 'Blackfathom Sea Witch - Blackfathom Deep BoEs'), +(4807, 48, 1048000, 0.5, 0, 'Blackfathom Myrmidon - Blackfathom Deep BoEs'), +(4809, 48, 1048000, 0.5, 0, 'Twilight Acolyte - Blackfathom Deep BoEs'), +(4810, 48, 1048000, 0.5, 0, 'Twilight Reaver - Blackfathom Deep BoEs'), +(4811, 48, 1048000, 0.5, 0, 'Twilight Aquamancer - Blackfathom Deep BoEs'), +(4812, 48, 1048000, 0.5, 0, 'Twilight Loreseeker - Blackfathom Deep BoEs'), +(4813, 48, 1048000, 0.5, 0, 'Twilight Shadowmage - Blackfathom Deep BoEs'), +(4814, 48, 1048000, 0.5, 0, 'Twilight Elementalist - Blackfathom Deep BoEs'), +(4815, 48, 1048000, 0.5, 0, 'Murkshallow Snapclaw - Blackfathom Deep BoEs'), +(4818, 48, 1048000, 0.5, 0, 'Blindlight Murloc - Blackfathom Deep BoEs'), +(4819, 48, 1048000, 0.5, 0, 'Blindlight Muckdweller - Blackfathom Deep BoEs'), +(4820, 48, 1048000, 0.5, 0, 'Blindlight Oracle - Blackfathom Deep BoEs'); + +-- Gnomeregan Zone Drops +DELETE FROM `reference_loot_template` WHERE `Entry` = 1090000; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1090000, 9485, 0, 0, 1, 'Gnomeregan BoEs - Vibroblade'), +(1090000, 9486, 0, 0, 1, 'Gnomeregan BoEs - Supercharger Battle Axe'), +(1090000, 9487, 0, 0, 1, 'Gnomeregan BoEs - Hi-tech Supergun'), +(1090000, 9488, 0, 0, 1, 'Gnomeregan BoEs - Oscillating Power Hammer'), +(1090000, 9489, 0, 0, 1, 'Gnomeregan BoEs - Gyromatic Icemaker'), +(1090000, 9490, 0, 0, 1, 'Gnomeregan BoEs - Gizmotron Megachopper'), +(1090000, 9491, 0, 0, 1, 'Gnomeregan BoEs - Hotshot Pilot\'s Gloves'), +(1090000, 9508, 0, 0, 1, 'Gnomeregan BoEs - Mechbuilder\'s Overalls'), +(1090000, 9509, 0, 0, 1, 'Gnomeregan BoEs - Petrolspill Leggings'), +(1090000, 9510, 0, 0, 1, 'Gnomeregan BoEs - Caverndeep Trudgers'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (6220,7079,6206,6211,6212,6223,6329,6391,6392,6407,6225,6226,6227,6230,6232,6233,6234,6218,6219,6228) AND `Item` IN (9485,9486,9487,9488,9489,9490,9491,9508,9509,9510); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (6220,7079,6206,6211,6212,6223,6329,6391,6392,6407,6225,6226,6227,6230,6232,6233,6234,6218,6219,6228) AND `Reference` = 1090000; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(6220, 90, 1090000, 0.5, 0, 'Irradiated Horror - Gnomeregan BoEs'), +(7079, 90, 1090000, 0.5, 0, 'Viscous Fallout - Gnomeregan BoEs'), +(6206, 90, 1090000, 0.5, 0, 'Caverndeep Burrower - Gnomeregan BoEs'), +(6211, 90, 1090000, 0.5, 0, 'Caverndeep Reaver - Gnomeregan BoEs'), +(6212, 90, 1090000, 0.5, 0, 'Dark Iron Agent - Gnomeregan BoEs'), +(6223, 90, 1090000, 0.5, 0, 'Leprous Defender - Gnomeregan BoEs'), +(6329, 90, 1090000, 0.5, 0, 'Irradiated Pillager - Gnomeregan BoEs'), +(6391, 90, 1090000, 0.5, 0, 'Holdout Warrior - Gnomeregan BoEs'), +(6392, 90, 1090000, 0.5, 0, 'Holdout Medic - Gnomeregan BoEs'), +(6407, 90, 1090000, 0.5, 0, 'Holdout Technician - Gnomeregan BoEs'), +(6225, 90, 1090000, 0.5, 0, 'Mechano-Tank - Gnomeregan BoEs'), +(6226, 90, 1090000, 0.5, 0, 'Mechano-Flamewalker - Gnomeregan BoEs'), +(6227, 90, 1090000, 0.5, 0, 'Mechano-Frostwalker - Gnomeregan BoEs'), +(6230, 90, 1090000, 0.5, 0, 'Peacekeeper Security Suit - Gnomeregan BoEs'), +(6232, 90, 1090000, 0.5, 0, 'Arcane Nullifier X-21 - Gnomeregan BoEs'), +(6233, 90, 1090000, 0.5, 0, 'Mechanized Sentry - Gnomeregan BoEs'), +(6234, 90, 1090000, 0.5, 0, 'Mechanized Guardian - Gnomeregan BoEs'), +(6218, 90, 1090000, 0.5, 0, 'Irradiated Slime - Gnomeregan BoEs'), +(6219, 90, 1090000, 0.5, 0, 'Corrosive Lurker - Gnomeregan BoEs'), +(6228, 90, 1090000, 0.5, 0, 'Dark Iron Ambassador - Gnomeregan BoEs'); + +-- Razorfen Kraul Zone Drops +DELETE FROM `reference_loot_template` WHERE `Entry` = 1047000; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1047000, 776, 0, 0, 1, 'Razorfen Kraul BoEs - Vendetta'), +(1047000, 1488, 0, 0, 1, 'Razorfen Kraul BoEs - Avenger\'s Armor'), +(1047000, 1727, 0, 0, 1, 'Razorfen Kraul BoEs - Sword of Decay'), +(1047000, 1975, 0, 0, 1, 'Razorfen Kraul BoEs - Pysan\'s Old Greatsword'), +(1047000, 1976, 0, 0, 1, 'Razorfen Kraul BoEs - Slaghammer'), +(1047000, 1978, 0, 0, 1, 'Razorfen Kraul BoEs - Wolfclaw Gloves'), +(1047000, 2039, 0, 0, 1, 'Razorfen Kraul BoEs - Plains Ring'), +(1047000, 2264, 0, 0, 1, 'Razorfen Kraul BoEs - Mantle of Thieves'), +(1047000, 2549, 0, 0, 1, 'Razorfen Kraul BoEs - Staff of the Shade'), +(1047000, 4438, 0, 0, 1, 'Razorfen Kraul BoEs - Pugilist Bracers'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (4512,4514,4538,4539,4427,4435,4436,4437,4440,4442,4515,4516,4517,4518,4519,4520,4522,4523,4525,4530,4531,4532,4623,6035,4541,4425,4438,4842) AND `Item` IN (776,1488,1727,1975,1976,1978,2039,2264,2549,4438); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (4512,4514,4538,4539,4427,4435,4436,4437,4440,4442,4515,4516,4517,4518,4519,4520,4522,4523,4525,4530,4531,4532,4623,6035,4541,4425,4438,4842) AND `Reference` = 1047000; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(4512, 47, 1047000, 0.5, 0, 'Rotting Agam\'ar - Razorfen Kraul BoEs'), +(4514, 47, 1047000, 0.5, 0, 'Raging Agam\'ar - Razorfen Kraul BoEs'), +(4538, 47, 1047000, 0.5, 0, 'Kraul Bat - Razorfen Kraul BoEs'), +(4539, 47, 1047000, 0.5, 0, 'Greater Kraul Bat - Razorfen Kraul BoEs'), +(4427, 47, 1047000, 0.5, 0, 'Ward Guardian - Razorfen Kraul BoEs'), +(4435, 47, 1047000, 0.5, 0, 'Razorfen Warrior - Razorfen Kraul BoEs'), +(4436, 47, 1047000, 0.5, 0, 'Razorfen Quilguard - Razorfen Kraul BoEs'), +(4437, 47, 1047000, 0.5, 0, 'Razorfen Warden - Razorfen Kraul BoEs'), +(4440, 47, 1047000, 0.5, 0, 'Razorfen Totemic - Razorfen Kraul BoEs'), +(4442, 47, 1047000, 0.5, 0, 'Razorfen Defender - Razorfen Kraul BoEs'), +(4515, 47, 1047000, 0.5, 0, 'Death\'s Head Acolyte - Razorfen Kraul BoEs'), +(4516, 47, 1047000, 0.5, 0, 'Death\'s Head Adept - Razorfen Kraul BoEs'), +(4517, 47, 1047000, 0.5, 0, 'Death\'s Head Priest - Razorfen Kraul BoEs'), +(4518, 47, 1047000, 0.5, 0, 'Death\'s Head Sage - Razorfen Kraul BoEs'), +(4519, 47, 1047000, 0.5, 0, 'Death\'s Head Seer - Razorfen Kraul BoEs'), +(4520, 47, 1047000, 0.5, 0, 'Razorfen Geomancer - Razorfen Kraul BoEs'), +(4522, 47, 1047000, 0.5, 0, 'Razorfen Dustweaver - Razorfen Kraul BoEs'), +(4523, 47, 1047000, 0.5, 0, 'Razorfen Groundshaker - Razorfen Kraul BoEs'), +(4525, 47, 1047000, 0.5, 0, 'Razorfen Earthbreaker - Razorfen Kraul BoEs'), +(4530, 47, 1047000, 0.5, 0, 'Razorfen Handler - Razorfen Kraul BoEs'), +(4531, 47, 1047000, 0.5, 0, 'Razorfen Beast Trainer - Razorfen Kraul BoEs'), +(4532, 47, 1047000, 0.5, 0, 'Razorfen Beastmaster - Razorfen Kraul BoEs'), +(4623, 47, 1047000, 0.5, 0, 'Quilguard Champion - Razorfen Kraul BoEs'), +(6035, 47, 1047000, 0.5, 0, 'Razorfen Stalker - Razorfen Kraul BoEs'), +(4541, 47, 1047000, 0.5, 0, 'Blood of Agamaggan - Razorfen Kraul BoEs'), +(4425, 47, 1047000, 0.5, 0, 'Blind Hunter - Razorfen Kraul BoEs'), +(4438, 47, 1047000, 0.5, 0, 'Razorfen Spearhide - Razorfen Kraul BoEs'), +(4842, 47, 1047000, 0.5, 0, 'Earthcaller Halmgar - Razorfen Kraul BoEs'); + +-- Scarlet Monastery Zone Drops +-- Unsure if these are separated by wings, but the lowest ilvl drops from Cathedral so might as well keep them together +DELETE FROM `reference_loot_template` WHERE `Entry` = 1189000; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1189000, 7736 , 0, 0, 1, 'Scarlet Monastery BoEs - Fight Club'), +(1189000, 7758 , 0, 0, 1, 'Scarlet Monastery BoEs - Ruthless Shiv'), +(1189000, 7760 , 0, 0, 1, 'Scarlet Monastery BoEs - Warchief Kilt'), +(1189000, 1992 , 0, 0, 1, 'Scarlet Monastery BoEs - Swampchill Fetish'), +(1189000, 7755 , 0, 0, 1, 'Scarlet Monastery BoEs - Flintrock Shoulders'), +(1189000, 7759 , 0, 0, 1, 'Scarlet Monastery BoEs - Archon Chestpiece'), +(1189000, 7761 , 0, 0, 1, 'Scarlet Monastery BoEs - Steelclaw Reaver'), +(1189000, 5756 , 0, 0, 1, 'Scarlet Monastery BoEs - Sliverblade'), +(1189000, 7757 , 0, 0, 1, 'Scarlet Monastery BoEs - Windweaver Staff'), +(1189000, 2262 , 0, 0, 1, 'Scarlet Monastery BoEs - Mark of Kern'), +(1189000, 8225 , 0, 0, 1, 'Scarlet Monastery BoEs - Tainted Pierce'), +(1189000, 10332, 0, 0, 1, 'Scarlet Monastery BoEs - Scarlet Boots'), +(1189000, 7728 , 0, 0, 1, 'Scarlet Monastery BoEs - Beguiler Robes'), +(1189000, 7730 , 0, 0, 1, 'Scarlet Monastery BoEs - Cobalt Crusher'), +(1189000, 5819 , 0, 0, 1, 'Scarlet Monastery BoEs - Sunblaze Coif'), +(1189000, 7729 , 0, 0, 1, 'Scarlet Monastery BoEs - Chesterfall Musket'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (4304,4286,4287,4288,4289,4290,4291,4292,4294,4295,4296,4297,4298,4299,4300,4301,4302,4303,4306,4540,6488,6489,6490) AND `Item` IN (7736,7758,7760,1992,7755,7759,7761,5756,7757,2262,8225,10332,7728,7730,5819,7729); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (4304,4286,4287,4288,4289,4290,4291,4292,4294,4295,4296,4297,4298,4299,4300,4301,4302,4303,4306,4540,6488,6489,6490) AND `Reference` = 1189000; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(4304, 189, 1189000, 0.5, 0, 'Scarlet Tracking Hound - Scarlet Monastery BoEs'), +(4286, 189, 1189000, 0.5, 0, 'Scarlet Soldier - Scarlet Monastery BoEs'), +(4287, 189, 1189000, 0.5, 0, 'Scarlet Gallant - Scarlet Monastery BoEs'), +(4288, 189, 1189000, 0.5, 0, 'Scarlet Beastmaster - Scarlet Monastery BoEs'), +(4289, 189, 1189000, 0.5, 0, 'Scarlet Evoker - Scarlet Monastery BoEs'), +(4290, 189, 1189000, 0.5, 0, 'Scarlet Guardsman - Scarlet Monastery BoEs'), +(4291, 189, 1189000, 0.5, 0, 'Scarlet Diviner - Scarlet Monastery BoEs'), +(4292, 189, 1189000, 0.5, 0, 'Scarlet Protector - Scarlet Monastery BoEs'), +(4294, 189, 1189000, 0.5, 0, 'Scarlet Sorcerer - Scarlet Monastery BoEs'), +(4295, 189, 1189000, 0.5, 0, 'Scarlet Myrmidon - Scarlet Monastery BoEs'), +(4296, 189, 1189000, 0.5, 0, 'Scarlet Adept - Scarlet Monastery BoEs'), +(4297, 189, 1189000, 0.5, 0, 'Scarlet Conjuror - Scarlet Monastery BoEs'), +(4298, 189, 1189000, 0.5, 0, 'Scarlet Defender - Scarlet Monastery BoEs'), +(4299, 189, 1189000, 0.5, 0, 'Scarlet Chaplain - Scarlet Monastery BoEs'), +(4300, 189, 1189000, 0.5, 0, 'Scarlet Wizard - Scarlet Monastery BoEs'), +(4301, 189, 1189000, 0.5, 0, 'Scarlet Centurion - Scarlet Monastery BoEs'), +(4302, 189, 1189000, 0.5, 0, 'Scarlet Champion - Scarlet Monastery BoEs'), +(4303, 189, 1189000, 0.5, 0, 'Scarlet Abbot - Scarlet Monastery BoEs'), +(4306, 189, 1189000, 0.5, 0, 'Scarlet Torturer - Scarlet Monastery BoEs'), +(4540, 189, 1189000, 0.5, 0, 'Scarlet Monk - Scarlet Monastery BoEs'), +(6488, 189, 1189000, 0.5, 0, 'Fallen Champion - Scarlet Monastery BoEs'), +(6489, 189, 1189000, 0.5, 0, 'Ironspine - Scarlet Monastery BoEs'), +(6490, 189, 1189000, 0.5, 0, 'Azshir the Sleepless - Scarlet Monastery BoEs'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (4290,4292,4295,4298) AND `Item` IN (10329,10333); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(4290, 10333, 0, 2, 0, 'Scarlet Wristguards'), +(4292, 10333, 0, 2, 0, 'Scarlet Wristguards'), +(4295, 10329, 0, 2, 0, 'Scarlet Belt'), +(4298, 10329, 0, 2, 0, 'Scarlet Belt'); + +-- Razorfen Downs Zone Drops +DELETE FROM `reference_loot_template` WHERE `Entry` = 1129000; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1129000, 10567, 0, 0, 1, 'Razorfen Downs BoEs - Quillshooter'), +(1129000, 10570, 0, 0, 1, 'Razorfen Downs BoEs - Manslayer'), +(1129000, 10572, 0, 0, 1, 'Razorfen Downs BoEs - Freezing Shard'), +(1129000, 10573, 0, 0, 1, 'Razorfen Downs BoEs - Boneslasher'), +(1129000, 10574, 0, 0, 1, 'Razorfen Downs BoEs - Corpseshroud'), +(1129000, 10578, 0, 0, 1, 'Razorfen Downs BoEs - Thoughtcast Boots'), +(1129000, 10581, 0, 0, 1, 'Razorfen Downs BoEs - Death\'s Head Vestment'), +(1129000, 10583, 0, 0, 1, 'Razorfen Downs BoEs - Quillward Harness'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (7327,7328,7329,7332,7341,7342,7345,7347,7348,7352,7353,7357,7358,7335,7337,7354) AND `Item` IN (10567,10570,10572,10573,10574,10578,10581,10583); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (7327,7328,7329,7332,7341,7342,7345,7347,7348,7352,7353,7357,7358,7335,7337,7354) AND `Reference` = 1129000; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(7327, 129, 1129000, 0.5, 0, 'Withered Warrior - Razorfen Downs BoEs'), +(7328, 129, 1129000, 0.5, 0, 'Withered Reaver - Razorfen Downs BoEs'), +(7329, 129, 1129000, 0.5, 0, 'Withered Quilguard - Razorfen Downs BoEs'), +(7332, 129, 1129000, 0.5, 0, 'Withered Spearhide - Razorfen Downs BoEs'), +(7341, 129, 1129000, 0.5, 0, 'Skeletal Frostweaver - Razorfen Downs BoEs'), +(7342, 129, 1129000, 0.5, 0, 'Skeletal Summoner - Razorfen Downs BoEs'), +(7345, 129, 1129000, 0.5, 0, 'Splinterbone Captain - Razorfen Downs BoEs'), +(7347, 129, 1129000, 0.5, 0, 'Boneflayer Ghoul - Razorfen Downs BoEs'), +(7348, 129, 1129000, 0.5, 0, 'Thorn Eater Ghoul - Razorfen Downs BoEs'), +(7352, 129, 1129000, 0.5, 0, 'Frozen Soul - Razorfen Downs BoEs'), +(7353, 129, 1129000, 0.5, 0, 'Freezing Spirit - Razorfen Downs BoEs'), +(7357, 129, 1129000, 0.5, 0, 'Mordresh Fire Eye - Razorfen Downs BoEs'), +(7358, 129, 1129000, 0.5, 0, 'Amnennar the Coldbringer - Razorfen Downs BoEs'), +(7335, 129, 1129000, 0.5, 0, 'Death\'s Head Geomancer - Razorfen Downs BoEs'), +(7337, 129, 1129000, 0.5, 0, 'Death\'s Head Necromancer - Razorfen Downs BoEs'), +(7354, 129, 1129000, 0.5, 0, 'Ragglesnout - Razorfen Downs BoEs'); + +-- Uldaman Zone Drops +DELETE FROM `reference_loot_template` WHERE `Entry` = 1070000; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1070000, 9383, 0, 0, 1, 'Uldaman BoEs - Obsidian Cleaver'), +(1070000, 9392, 0, 0, 1, 'Uldaman BoEs - Annealed Blade'), +(1070000, 9422, 0, 0, 1, 'Uldaman BoEs - Shadowforge Bushmaster'), +(1070000, 9424, 0, 0, 1, 'Uldaman BoEs - Ginn-su Sword'), +(1070000, 9425, 0, 0, 1, 'Uldaman BoEs - Pendulum of Doom'), +(1070000, 9426, 0, 0, 1, 'Uldaman BoEs - Monolithic Bow'), +(1070000, 9427, 0, 0, 1, 'Uldaman BoEs - Stonevault Bonebreaker'), +(1070000, 9432, 0, 0, 1, 'Uldaman BoEs - Skullplate Bracers'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (4861,4863,7022,4857,4860,7206,4847,4848,4849,4850,4852,4853,4855,7030,7290,7320,7321,7023) AND `Item` IN (9383,9392,9422,9424,9425,9426,9427,9432); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (4861,4863,7022,4857,4860,7206,4847,4848,4849,4850,4852,4853,4855,7030,7290,7320,7321,7023) AND `Reference` = 1070000; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(4861, 70, 1070000, 0.5, 0, 'Shrike Bat - Uldaman BoEs'), +(4863, 70, 1070000, 0.5, 0, 'Jadespine Basilisk - Uldaman BoEs'), +(7022, 70, 1070000, 0.5, 0, 'Venomlash Scorpid - Uldaman BoEs'), +(4857, 70, 1070000, 0.5, 0, 'Stone Keeper - Uldaman BoEs'), +(4860, 70, 1070000, 0.5, 0, 'Stone Steward - Uldaman BoEs'), +(7206, 70, 1070000, 0.5, 0, 'Ancient Stone Keeper - Uldaman BoEs'), +(4847, 70, 1070000, 0.5, 0, 'Shadowforge Relic Hunter - Uldaman BoEs'), +(4848, 70, 1070000, 0.5, 0, 'Shadowforge Darkcaster - Uldaman BoEs'), +(4849, 70, 1070000, 0.5, 0, 'Shadowforge Archaeologist - Uldaman BoEs'), +(4850, 70, 1070000, 0.5, 0, 'Stonevault Cave Lurker - Uldaman BoEs'), +(4852, 70, 1070000, 0.5, 0, 'Stonevault Oracle - Uldaman BoEs'), +(4853, 70, 1070000, 0.5, 0, 'Stonevault Geomancer - Uldaman BoEs'), +(4855, 70, 1070000, 0.5, 0, 'Stonevault Brawler - Uldaman BoEs'), +(7030, 70, 1070000, 0.5, 0, 'Shadowforge Geologist - Uldaman BoEs'), +(7290, 70, 1070000, 0.5, 0, 'Shadowforge Sharpshooter - Uldaman BoEs'), +(7320, 70, 1070000, 0.5, 0, 'Stonevault Mauler - Uldaman BoEs'), +(7321, 70, 1070000, 0.5, 0, 'Stonevault Flameweaver - Uldaman BoEs'), +(7023, 70, 1070000, 0.5, 0, 'Obsidian Sentinel - Uldaman BoEs'); + +-- Zul'Farrak +-- It looks like it was broken in Wowhead or later builds? +-- Source for drops: https://www.wowhead.com/wotlk/zone=1176/zulfarrak#comments:id=282203 +DELETE FROM `reference_loot_template` WHERE `Entry` = 1209000; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1209000, 5616, 0, 0, 1, 'Zul\'Farrak BoEs - Gutwrencher'), +(1209000, 9512, 0, 0, 1, 'Zul\'Farrak BoEs - Blackmetal Cape'), +(1209000, 2040, 0, 0, 1, 'Zul\'Farrak BoEs - Troll Protector'), +(1209000, 9482, 0, 0, 1, 'Zul\'Farrak BoEs - Witch Doctor\'s Cane'), +(1209000, 9481, 0, 0, 1, 'Zul\'Farrak BoEs - The Minotaur'), +(1209000, 9484, 0, 0, 1, 'Zul\'Farrak BoEs - Spellshock Leggings'), +(1209000, 6440, 0, 0, 1, 'Zul\'Farrak BoEs - Brainlash'), +(1209000, 9511, 0, 0, 1, 'Zul\'Farrak BoEs - Bloodletter Scalpel'), +(1209000, 9480, 0, 0, 1, 'Zul\'Farrak BoEs - Eyegouger'), +(1209000, 9483, 0, 0, 1, 'Zul\'Farrak BoEs - Flaming Incinerator'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (7268,8095,5648,5649,5650,7246,7247,7274,8120,10080,10081,10082) AND `Item` IN (5616,9512,2040,9482,9481,9484,6440,9511,9480,9483); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (7268,8095,5648,5649,5650,7246,7247,7274,8120,10080,10081,10082) AND `Reference` = 1209000; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(7268 , 209, 1209000, 0.5, 0, 'Sandfury Guardian - Zul\'Farrak BoEs'), +(8095 , 209, 1209000, 0.5, 0, 'Sul\'lithuz Sandcrawler - Zul\'Farrak BoEs'), +(5648 , 209, 1209000, 0.5, 0, 'Sandfury Shadowcaster - Zul\'Farrak BoEs'), +(5649 , 209, 1209000, 0.5, 0, 'Sandfury Blood Drinker - Zul\'Farrak BoEs'), +(5650 , 209, 1209000, 0.5, 0, 'Sandfury Witch Doctor - Zul\'Farrak BoEs'), +(7246 , 209, 1209000, 0.5, 0, 'Sandfury Shadowhunter - Zul\'Farrak BoEs'), +(7247 , 209, 1209000, 0.5, 0, 'Sandfury Soul Eater - Zul\'Farrak BoEs'), +(7274 , 209, 1209000, 0.5, 0, 'Sandfury Executioner - Zul\'Farrak BoEs'), +(8120 , 209, 1209000, 0.5, 0, 'Sul\'lithuz Abomination - Zul\'Farrak BoEs'), +(10080, 209, 1209000, 0.5, 0, 'Sandarr Dunereaver - Zul\'Farrak BoEs'), +(10081, 209, 1209000, 0.5, 0, 'Dustwraith - Zul\'Farrak BoEs'), +(10082, 209, 1209000, 0.5, 0, 'Zerillis - Zul\'Farrak BoEs'); + +-- Maraudon seems not to have anything. Could be like in ZF but there was nothing helpful in the comments + +-- Sunken Temple +DELETE FROM `reference_loot_template` WHERE `Entry` = 1109000; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1109000, 10625, 0, 0, 1, 'Sunken Temple BoEs - Stealthblade'), +(1109000, 10626, 0, 0, 1, 'Sunken Temple BoEs - Ragehammer'), +(1109000, 10628, 0, 0, 1, 'Sunken Temple BoEs - Deathblow'), +(1109000, 10629, 0, 0, 1, 'Sunken Temple BoEs - Mistwalker Boots'), +(1109000, 10630, 0, 0, 1, 'Sunken Temple BoEs - Soulcatcher Halo'), +(1109000, 10631, 0, 0, 1, 'Sunken Temple BoEs - Murkwater Gauntlets'), +(1109000, 10632, 0, 0, 1, 'Sunken Temple BoEs - Slimescale Bracers'), +(1109000, 10633, 0, 0, 1, 'Sunken Temple BoEs - Silvershell Leggings'), +(1109000, 10624, 0, 0, 1, 'Sunken Temple BoEs - Stinging Bow'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (5226,5291,5277,5280,5283,8384,5267,5270,5271,5256,5259,5273,5228,5708) AND `Item` IN (10625,10626,10628,10629,10630,10631,10632,10633,10624); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (5226,5291,5277,5280,5283,8384,5267,5270,5271,5256,5259,5273,5228,5708) AND `Reference` = 1109000; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(5226, 109, 1109000, 0.5, 0, 'Murk Worm - Sunken Temple BoEs'), +(5291, 109, 1109000, 0.5, 0, 'Hakkari Frostwing - Sunken Temple BoEs'), +(5277, 109, 1109000, 0.5, 0, 'Nightmare Scalebane - Sunken Temple BoEs'), +(5280, 109, 1109000, 0.5, 0, 'Nightmare Wyrmkin - Sunken Temple BoEs'), +(5283, 109, 1109000, 0.5, 0, 'Nightmare Wanderer - Sunken Temple BoEs'), +(8384, 109, 1109000, 0.5, 0, 'Deep Lurker - Sunken Temple BoEs'), +(5267, 109, 1109000, 0.5, 0, 'Unliving Atal\'ai - Sunken Temple BoEs'), +(5270, 109, 1109000, 0.5, 0, 'Atal\'ai Corpse Eater - Sunken Temple BoEs'), +(5271, 109, 1109000, 0.5, 0, 'Atal\'ai Deathwalker - Sunken Temple BoEs'), +(5256, 109, 1109000, 0.5, 0, 'Atal\'ai Warrior - Sunken Temple BoEs'), +(5259, 109, 1109000, 0.5, 0, 'Atal\'ai Witch Doctor - Sunken Temple BoEs'), +(5273, 109, 1109000, 0.5, 0, 'Atal\'ai High Priest - Sunken Temple BoEs'), +(5228, 109, 1109000, 0.5, 0, 'Saturated Ooze - Sunken Temple BoEs'), +(5708, 109, 1109000, 0.5, 0, 'Spawn of Hakkar - Sunken Temple BoEs'); + +-- Blackrock Depths +DELETE FROM `reference_loot_template` WHERE `Entry` = 1230000; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1230000, 12527, 0, 0, 1, 'Blackrock Depths BoEs - Ribsplitter'), +(1230000, 12528, 0, 0, 1, 'Blackrock Depths BoEs - The Judge\'s Gavel'), +(1230000, 12531, 0, 0, 1, 'Blackrock Depths BoEs - Searing Needle'), +(1230000, 12532, 0, 0, 1, 'Blackrock Depths BoEs - Spire of the Stoneshaper'), +(1230000, 12535, 0, 0, 1, 'Blackrock Depths BoEs - Doomforged Straightedge'), +(1230000, 12542, 0, 0, 1, 'Blackrock Depths BoEs - Funeral Pyre Vestment'), +(1230000, 12546, 0, 0, 1, 'Blackrock Depths BoEs - Aristocratic Cuffs'), +(1230000, 12547, 0, 0, 1, 'Blackrock Depths BoEs - Mar Alom\'s Grip'), +(1230000, 12550, 0, 0, 1, 'Blackrock Depths BoEs - Runed Golem Shackles'), +(1230000, 12551, 0, 0, 1, 'Blackrock Depths BoEs - Stoneshield Cloak'), +(1230000, 12552, 0, 0, 1, 'Blackrock Depths BoEs - Blisterbane Wrap'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (8905,8906,8908,8909,8910,8911,8889,8890,8891,8892,8893,8894,8895,8898,8899,8903,8912,8913,8914,9554,8907,9042,8923,9024,9041) AND `Item` IN (12527,12528,12531,12532,12535,12542,12546,12547,12550,12551,12552); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (8905,8906,8908,8909,8910,8911,8889,8890,8891,8892,8893,8894,8895,8898,8899,8903,8912,8913,8914,9554,8907,9042,8923,9024,9041) AND `Reference` = 1230000; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(8905, 209, 1230000, 0.5, 0, 'Warbringer Construct - Blackrock Depths BoEs'), +(8906, 209, 1230000, 0.5, 0, 'Ragereaver Golem - Blackrock Depths BoEs'), +(8908, 209, 1230000, 0.5, 0, 'Molten War Golem - Blackrock Depths BoEs'), +(8909, 209, 1230000, 0.5, 0, 'Fireguard - Blackrock Depths BoEs'), +(8910, 209, 1230000, 0.5, 0, 'Blazing Fireguard - Blackrock Depths BoEs'), +(8911, 209, 1230000, 0.5, 0, 'Fireguard Destroyer - Blackrock Depths BoEs'), +(8889, 209, 1230000, 0.5, 0, 'Anvilrage Overseer - Blackrock Depths BoEs'), +(8890, 209, 1230000, 0.5, 0, 'Anvilrage Warden - Blackrock Depths BoEs'), +(8891, 209, 1230000, 0.5, 0, 'Anvilrage Guardsman - Blackrock Depths BoEs'), +(8892, 209, 1230000, 0.5, 0, 'Anvilrage Footman - Blackrock Depths BoEs'), +(8893, 209, 1230000, 0.5, 0, 'Anvilrage Soldier - Blackrock Depths BoEs'), +(8894, 209, 1230000, 0.5, 0, 'Anvilrage Medic - Blackrock Depths BoEs'), +(8895, 209, 1230000, 0.5, 0, 'Anvilrage Officer - Blackrock Depths BoEs'), +(8898, 209, 1230000, 0.5, 0, 'Anvilrage Marshal - Blackrock Depths BoEs'), +(8899, 209, 1230000, 0.5, 0, 'Doomforge Dragoon - Blackrock Depths BoEs'), +(8903, 209, 1230000, 0.5, 0, 'Anvilrage Captain - Blackrock Depths BoEs'), +(8912, 209, 1230000, 0.5, 0, 'Twilight\'s Hammer Torturer - Blackrock Depths BoEs'), +(8913, 209, 1230000, 0.5, 0, 'Twilight Emissary - Blackrock Depths BoEs'), +(8914, 209, 1230000, 0.5, 0, 'Twilight Bodyguard - Blackrock Depths BoEs'), +(9554, 209, 1230000, 0.5, 0, 'Hammered Patron - Blackrock Depths BoEs'), +(8907, 209, 1230000, 0.5, 0, 'Wrath Hammer Construct - Blackrock Depths BoEs'), +(9042, 209, 1230000, 0.5, 0, 'Verek - Blackrock Depths BoEs'), +(8923, 209, 1230000, 0.5, 0, 'Panzor the Invincible - Blackrock Depths BoEs'), +(9024, 209, 1230000, 0.5, 0, 'Pyromancer Loregrain - Blackrock Depths BoEs'), +(9041, 209, 1230000, 0.5, 0, 'Warder Stilgiss - Blackrock Depths BoEs'); + +-- Stratholme +DELETE FROM `reference_loot_template` WHERE `Entry` = 1329000; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1329000, 17061, 0, 0, 1, 'Stratholme BoEs - Juno\'s Shadow'), +(1329000, 18736, 0, 0, 1, 'Stratholme BoEs - Plaguehound Leggings'), +(1329000, 18741, 0, 0, 1, 'Stratholme BoEs - Morlune\'s Bracer'), +(1329000, 18742, 0, 0, 1, 'Stratholme BoEs - Stratholme Militia Shoulderguard'), +(1329000, 18743, 0, 0, 1, 'Stratholme BoEs - Gracious Cape'), +(1329000, 18744, 0, 0, 1, 'Stratholme BoEs - Plaguebat Fur Gloves'), +(1329000, 18745, 0, 0, 1, 'Stratholme BoEs - Sacred Cloth Leggings'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (10381,10382,10384,10385,10405,10406,10407,10408,10409,10412,10413,10414,10416,10417,10463,10464,10398,10400,10418,10419,10420,10421,10422,10423,10424,10425,10426,11043,10393,10558,10809) AND `Item` IN (17061,18736,18741,18742,18743,18744,18745); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (10381,10382,10384,10385,10405,10406,10407,10408,10409,10412,10413,10414,10416,10417,10463,10464,10398,10400,10418,10419,10420,10421,10422,10423,10424,10425,10426,11043,10393,10558,10809) AND `Reference` = 1329000; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(10381, 329, 1329000, 0.5, 0, 'Ravaged Cadaver - Stratholme BoEs'), +(10382, 329, 1329000, 0.5, 0, 'Mangled Cadaver - Stratholme BoEs'), +(10384, 329, 1329000, 0.5, 0, 'Spectral Citizen - Stratholme BoEs'), +(10385, 329, 1329000, 0.5, 0, 'Ghostly Citizen - Stratholme BoEs'), +(10405, 329, 1329000, 0.5, 0, 'Plague Ghoul - Stratholme BoEs'), +(10406, 329, 1329000, 0.5, 0, 'Ghoul Ravener - Stratholme BoEs'), +(10407, 329, 1329000, 0.5, 0, 'Fleshflayer Ghoul - Stratholme BoEs'), +(10408, 329, 1329000, 0.5, 0, 'Rockwing Gargoyle - Stratholme BoEs'), +(10409, 329, 1329000, 0.5, 0, 'Rockwing Screecher - Stratholme BoEs'), +(10412, 329, 1329000, 0.5, 0, 'Crypt Crawler - Stratholme BoEs'), +(10413, 329, 1329000, 0.5, 0, 'Crypt Beast - Stratholme BoEs'), +(10414, 329, 1329000, 0.5, 0, 'Patchwork Horror - Stratholme BoEs'), +(10416, 329, 1329000, 0.5, 0, 'Bile Spewer - Stratholme BoEs'), +(10417, 329, 1329000, 0.5, 0, 'Venom Belcher - Stratholme BoEs'), +(10463, 329, 1329000, 0.5, 0, 'Shrieking Banshee - Stratholme BoEs'), +(10464, 329, 1329000, 0.5, 0, 'Wailing Banshee - Stratholme BoEs'), +(10398, 329, 1329000, 0.5, 0, 'Thuzadin Shadowcaster - Stratholme BoEs'), +(10400, 329, 1329000, 0.5, 0, 'Thuzadin Necromancer - Stratholme BoEs'), +(10418, 329, 1329000, 0.5, 0, 'Crimson Guardsman - Stratholme BoEs'), +(10419, 329, 1329000, 0.5, 0, 'Crimson Conjuror - Stratholme BoEs'), +(10420, 329, 1329000, 0.5, 0, 'Crimson Initiate - Stratholme BoEs'), +(10421, 329, 1329000, 0.5, 0, 'Crimson Defender - Stratholme BoEs'), +(10422, 329, 1329000, 0.5, 0, 'Crimson Sorcerer - Stratholme BoEs'), +(10423, 329, 1329000, 0.5, 0, 'Crimson Priest - Stratholme BoEs'), +(10424, 329, 1329000, 0.5, 0, 'Crimson Gallant - Stratholme BoEs'), +(10425, 329, 1329000, 0.5, 0, 'Crimson Battle Mage - Stratholme BoEs'), +(10426, 329, 1329000, 0.5, 0, 'Crimson Inquisitor - Stratholme BoEs'), +(11043, 329, 1329000, 0.5, 0, 'Crimson Monk - Stratholme BoEs'), +(10393, 329, 1329000, 0.5, 0, 'Skul - Stratholme BoEs'), +(10558, 329, 1329000, 0.5, 0, 'Hearthsinger Forresten - Stratholme BoEs'), +(10809, 329, 1329000, 0.5, 0, 'Stonespine - Stratholme BoEs'); + +-- Dire Maul +-- Warpwood Drops +DELETE FROM `reference_loot_template` WHERE `Entry` IN (1429000, 1429001, 1429002, 1429003, 1429004); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1429001, 18296, 0, 0, 1, 'Dire Maul Wildspawn BoEs - Marksman Bands'), +(1429001, 18298, 0, 0, 1, 'Dire Maul Wildspawn BoEs - Unbridled Leggings'), +-- Librams +(1429000, 18332, 0, 0, 1, 'Dire Maul Librams - Libram of Rapidity'), +(1429000, 18333, 0, 0, 1, 'Dire Maul Librams - Libram of Focus'), +(1429000, 18334, 0, 0, 1, 'Dire Maul Librams - Libram of Protection'), +-- Arcane (Arcane Torrent, Residual Monstrosity, Mana Remnant, Arcane Aberration) +(1429002, 18337, 0, 0, 1, 'Dire Maul Arcane BoEs - Orphic Bracers'), +(1429002, 18338, 0, 0, 1, 'Dire Maul Arcane BoEs - Wand of Arcane Potency'), +-- Eldreth +(1429003, 18339, 0, 0, 1, 'Dire Maul Eldreth BoEs - Eidolon Cloak'), +(1429003, 18340, 0, 0, 1, 'Dire Maul Eldreth BoEs - Eidolon Talisman'), +-- Nature (Ironbark & Petrified) +(1429004, 18343, 0, 0, 1, 'Dire Maul Nature BoEs - Petrified Band'), +(1429004, 18344, 0, 0, 1, 'Dire Maul Nature BoEs - Stonebark Gauntlets'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (11441,11444,11445,11446,11448,11450,11451,11452,11453,11454,11455,11456,11457,11458,11459,11461,11462,11464,11465,11466,11469,11470,11471,11472,11473,11475,11480,11483,11484,13021,13196,13197,13285,14303,14398,14399) AND `Item` IN (18289,18296,18298,18332,18333,18334,18337,18338,18339,18340,18343,18344); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (11441,11444,11445,11446,11448,11450,11451,11452,11453,11454,11455,11456,11457,11458,11459,11461,11462,11464,11465,11466,11469,11470,11471,11472,11473,11475,11480,11483,11484,13021,13196,13197,13285,14303,14398,14399) AND `Reference` IN (1429000, 1429001, 1429002, 1429003, 1429004); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(13021, 18289, 0, 1.5, 0, 'Warpwood Crusher - Barbed Thorn Necklace'), +(11461, 18289, 0, 1.5, 0, 'Warpwood Guardian - Barbed Thorn Necklace'), +(11465, 18289, 0, 1.5, 0, 'Warpwood Stomper - Barbed Thorn Necklace'), +(11464, 18289, 0, 1.5, 0, 'Warpwood Tangler - Barbed Thorn Necklace'), +(11462, 18289, 0, 1.5, 0, 'Warpwood Treant - Barbed Thorn Necklace'), + +(11454, 430, 1429001, 1.5, 4, 'Wildspawn Betrayer - Dire Maul Wildspawn BoEs'), +(11455, 430, 1429001, 1.5, 4, 'Wildspawn Felsworn - Dire Maul Wildspawn BoEs'), +(11457, 430, 1429001, 1.5, 4, 'Wildspawn Hellcaller - Dire Maul Wildspawn BoEs'), +(11452, 430, 1429001, 1.5, 4, 'Wildspawn Rogue - Dire Maul Wildspawn BoEs'), +(11451, 430, 1429001, 1.5, 4, 'Wildspawn Satyr - Dire Maul Wildspawn BoEs'), +(11456, 430, 1429001, 1.5, 4, 'Wildspawn Shadowstalker - Dire Maul Wildspawn BoEs'), +(11453, 430, 1429001, 1.5, 4, 'Wildspawn Trickster - Dire Maul Wildspawn BoEs'), + +(11480, 430, 1429002, 1.5, 4, 'Arcane Aberration - Dire Maul Arcane BoEs'), +(14399, 430, 1429002, 1.5, 4, 'Arcane Torrent - Dire Maul Arcane BoEs'), +(11483, 430, 1429002, 1.5, 4, 'Mana Remnant - Dire Maul Arcane BoEs'), +(11484, 430, 1429002, 1.5, 4, 'Residual Monstrosity - Dire Maul Arcane BoEs'), + +(11471, 430, 1429003, 1.5, 4, 'Eldreth Apparition - Dire Maul Eldreth BoEs'), +(14398, 430, 1429003, 1.5, 4, 'Eldreth Darter - Dire Maul Eldreth BoEs'), +(11475, 430, 1429003, 1.5, 4, 'Eldreth Phantasm - Dire Maul Eldreth BoEs'), +(11469, 430, 1429003, 1.5, 4, 'Eldreth Seether - Dire Maul Eldreth BoEs'), +(11470, 430, 1429003, 1.5, 4, 'Eldreth Sorcerer - Dire Maul Eldreth BoEs'), +(11473, 430, 1429003, 1.5, 4, 'Eldreth Spectre - Dire Maul Eldreth BoEs'), +(11472, 430, 1429003, 1.5, 4, 'Eldreth Spirit - Dire Maul Eldreth BoEs'), + +(11459, 430, 1429004, 1.5, 4, 'Ironbark Protector - Dire Maul Nature BoEs'), +(14303, 430, 1429004, 1.5, 4, 'Petrified Guardian - Dire Maul Nature BoEs'), +(11458, 430, 1429004, 1.5, 4, 'Petrified Treant - Dire Maul Nature BoEs'), + +(11441, 429, 1429000, 3, 3, 'Gordok Brute - Dire Maul Librams'), +(11444, 429, 1429000, 3, 3, 'Gordok Mage-Lord - Dire Maul Librams'), +(11445, 429, 1429000, 3, 3, 'Gordok Captain - Dire Maul Librams'), +(11448, 429, 1429000, 3, 3, 'Gordok Warlock - Dire Maul Librams'), +(11450, 429, 1429000, 3, 3, 'Gordok Reaver - Dire Maul Librams'), +(11451, 429, 1429000, 3, 3, 'Wildspawn Satyr - Dire Maul Librams'), +(11452, 429, 1429000, 3, 3, 'Wildspawn Rogue - Dire Maul Librams'), +(11453, 429, 1429000, 3, 3, 'Wildspawn Trickster - Dire Maul Librams'), +(11454, 429, 1429000, 3, 3, 'Wildspawn Betrayer - Dire Maul Librams'), +(11455, 429, 1429000, 3, 3, 'Wildspawn Felsworn - Dire Maul Librams'), +(11456, 429, 1429000, 3, 3, 'Wildspawn Shadowstalker - Dire Maul Librams'), +(11457, 429, 1429000, 3, 3, 'Wildspawn Hellcaller - Dire Maul Librams'), +(11458, 429, 1429000, 3, 3, 'Petrified Treant - Dire Maul Librams'), +(11459, 429, 1429000, 3, 3, 'Ironbark Protector - Dire Maul Librams'), +(11461, 429, 1429000, 3, 3, 'Warpwood Guardian - Dire Maul Librams'), +(11462, 429, 1429000, 3, 3, 'Warpwood Treant - Dire Maul Librams'), +(11464, 429, 1429000, 3, 3, 'Warpwood Tangler - Dire Maul Librams'), +(11465, 429, 1429000, 3, 3, 'Warpwood Stomper - Dire Maul Librams'), +(11469, 429, 1429000, 3, 3, 'Eldreth Seether - Dire Maul Librams'), +(11470, 429, 1429000, 3, 3, 'Eldreth Sorcerer - Dire Maul Librams'), +(11471, 429, 1429000, 3, 3, 'Eldreth Apparition - Dire Maul Librams'), +(11472, 429, 1429000, 3, 3, 'Eldreth Spirit - Dire Maul Librams'), +(11473, 429, 1429000, 3, 3, 'Eldreth Spectre - Dire Maul Librams'), +(11475, 429, 1429000, 3, 3, 'Eldreth Phantasm - Dire Maul Librams'), +(11480, 429, 1429000, 3, 3, 'Arcane Aberration - Dire Maul Librams'), +(11483, 429, 1429000, 3, 3, 'Mana Remnant - Dire Maul Librams'), +(11484, 429, 1429000, 3, 3, 'Residual Monstrosity - Dire Maul Librams'), +(13021, 429, 1429000, 3, 3, 'Warpwood Crusher - Dire Maul Librams'), +(13196, 429, 1429000, 3, 3, 'Phase Lasher - Dire Maul Librams'), +(13197, 429, 1429000, 3, 3, 'Fel Lash - Dire Maul Librams'), +(13285, 429, 1429000, 3, 3, 'Death Lash - Dire Maul Librams'), +(14303, 429, 1429000, 3, 3, 'Petrified Guardian - Dire Maul Librams'), +(14398, 429, 1429000, 3, 3, 'Eldreth Darter - Dire Maul Librams'), +(14399, 429, 1429000, 3, 3, 'Arcane Torrent - Dire Maul Librams'); + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 10) AND (`SourceGroup` IN (1075061, 1075063)) AND (`SourceEntry` IN (11732, 11733, 11734, 11736, 11737)) AND (`ConditionTypeOrReference` = 22) AND (`ConditionValue1` = 429); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(10, 1075061, 11732, 0, 0, 22, 0, 429, 0, 0, 1, 0, 0, '', 'Librams of Rumination, Constitution, Tenacity, Resilience & Voracity does not drop inside Dire Maul'), +(10, 1075061, 11733, 0, 0, 22, 0, 429, 0, 0, 1, 0, 0, '', 'Librams of Rumination, Constitution, Tenacity, Resilience & Voracity does not drop inside Dire Maul'), +(10, 1075061, 11734, 0, 0, 22, 0, 429, 0, 0, 1, 0, 0, '', 'Librams of Rumination, Constitution, Tenacity, Resilience & Voracity does not drop inside Dire Maul'), +(10, 1075061, 11736, 0, 0, 22, 0, 429, 0, 0, 1, 0, 0, '', 'Librams of Rumination, Constitution, Tenacity, Resilience & Voracity does not drop inside Dire Maul'), +(10, 1075061, 11737, 0, 0, 22, 0, 429, 0, 0, 1, 0, 0, '', 'Librams of Rumination, Constitution, Tenacity, Resilience & Voracity does not drop inside Dire Maul'), + +(10, 1075063, 11732, 0, 0, 22, 0, 429, 0, 0, 1, 0, 0, '', 'Librams of Rumination, Constitution, Tenacity, Resilience & Voracity does not drop inside Dire Maul'), +(10, 1075063, 11733, 0, 0, 22, 0, 429, 0, 0, 1, 0, 0, '', 'Librams of Rumination, Constitution, Tenacity, Resilience & Voracity does not drop inside Dire Maul'), +(10, 1075063, 11734, 0, 0, 22, 0, 429, 0, 0, 1, 0, 0, '', 'Librams of Rumination, Constitution, Tenacity, Resilience & Voracity does not drop inside Dire Maul'), +(10, 1075063, 11736, 0, 0, 22, 0, 429, 0, 0, 1, 0, 0, '', 'Librams of Rumination, Constitution, Tenacity, Resilience & Voracity does not drop inside Dire Maul'), +(10, 1075063, 11737, 0, 0, 22, 0, 429, 0, 0, 1, 0, 0, '', 'Librams of Rumination, Constitution, Tenacity, Resilience & Voracity does not drop inside Dire Maul'); + +-- Molten Core +DELETE FROM `reference_loot_template` WHERE `Entry` IN (1409000); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1409000, 16799, 0, 0, 1, 'Arcanist Bindings'), +(1409000, 16802, 0, 0, 1, 'Arcanist Belt'), +(1409000, 16804, 0, 0, 1, 'Felheart Bracers'), +(1409000, 16806, 0, 0, 1, 'Felheart Belt'), +(1409000, 16817, 0, 0, 1, 'Girdle of Prophecy'), +(1409000, 16819, 0, 0, 1, 'Vambraces of Prophecy'), +(1409000, 16825, 0, 0, 1, 'Nightslayer Bracelets'), +(1409000, 16827, 0, 0, 1, 'Nightslayer Belt'), +(1409000, 16828, 0, 0, 1, 'Cenarion Belt'), +(1409000, 16830, 0, 0, 1, 'Cenarion Bracers'), +(1409000, 16838, 0, 0, 1, 'Earthfury Belt'), +(1409000, 16840, 0, 0, 1, 'Earthfury Bracers'), +(1409000, 16850, 0, 0, 1, 'Giantstalker\'s Bracers'), +(1409000, 16851, 0, 0, 1, 'Giantstalker\'s Belt'), +(1409000, 16857, 0, 0, 1, 'Lawbringer Bracers'), +(1409000, 16858, 0, 0, 1, 'Lawbringer Belt'), +(1409000, 16861, 0, 0, 1, 'Bracers of Might'), +(1409000, 16864, 0, 0, 1, 'Belt of Might'); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (11672,12099,11671,11669,11666,12100,11667,12076,12101,11662,11668,11665,11661,12119,11673,11658,11659) AND `Item` IN (16799,16802,16804,16806,16817,16819,16825,16827,16828,16830,16838,16840,16850,16851,16857,16858,16861,16864); +DELETE FROM `creature_loot_template` WHERE `Entry` IN (11672,12099,11671,11669,11666,12100,11667,12076,12101,11662,11668,11665,11661,12119,11673,11658,11659) AND `Reference` IN (1409000); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(11666, 1409000, 1409000, 5, 0, 'Firewalker - Molten Core BoEs'), +(12100, 1409000, 1409000, 5, 0, 'Lava Reaver - Molten Core BoEs'), +(11667, 1409000, 1409000, 5, 0, 'Flameguard - Molten Core BoEs'), +(12076, 1409000, 1409000, 5, 0, 'Lava Elemental - Molten Core BoEs'), +(12101, 1409000, 1409000, 5, 0, 'Lava Surger - Molten Core BoEs'), +(11662, 1409000, 1409000, 5, 0, 'Flamewaker Priest - Molten Core BoEs'), +(11668, 1409000, 1409000, 5, 0, 'Firelord - Molten Core BoEs'), +(11665, 1409000, 1409000, 5, 0, 'Lava Annihilator - Molten Core BoEs'), +(11661, 1409000, 1409000, 5, 0, 'Flamewaker - Molten Core BoEs'), +(12119, 1409000, 1409000, 5, 0, 'Flamewaker Protector - Molten Core BoEs'), +(11673, 1409000, 1409000, 5, 0, 'Ancient Core Hound - Molten Core BoEs'), +(11658, 1409000, 1409000, 5, 0, 'Molten Giant - Molten Core BoEs'), +(11659, 1409000, 1409000, 5, 0, 'Molten Destroyer - Molten Core BoEs'); + +/* Final Vanilla Cleanup +All Affected Creatures: +3,30,36,40,43,46,48,60,61,79,92,94,95,97,98,99,100,113,114,115,116,117,118,119,121,122,123,124,125,126,127,154,157,171,199,202,203,205,206,210,212,213,215,217,218,232,285,300,315,327,330,345,390,391,397,422,423,424,426,428,429,430,431,432,433,434,435,436,437,440,441,442,445,446,449,452,453,454,456,458,462,471,472,473,474,475,476,478,480,481,485,500,501,502,503,504,505,506,507,511,513,515,517,518,519,520,521,524,525,533,534,539,544,545,547,548,550,565,568,569,570,572,573,574,578,579,580,584,587,588,589,590,594,595,596,597,598,599,604,615,616,619,622,623,624,625,626,628,634,636,641,657,660,667,669,670,671,672,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,694,696,697,699,701,702,703,709,710,711,712,723,728,729,730,732,735,736,740,741,742,743,744,745,746,747,750,751,752,754,755,757,759,760,761,762,763,764,765,766,767,768,769,771,772,780,781,782,783,784,785,787,813,814,818,819,822,824,830,831,832,833,834,846,854,855,856,858,861,862,863,864,865,868,871,873,875,877,879,880,881,889,891,892,898,905,909,910,920,921,922,923,930,937,938,939,940,941,942,943,947,948,949,950,976,977,978,979,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1051,1052,1053,1054,1057,1059,1061,1062,1063,1065,1069,1081,1082,1083,1084,1085,1087,1088,1094,1095,1096,1097,1106,1108,1109,1110,1111,1112,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1137,1138,1140,1142,1144,1150,1151,1152,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1169,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1183,1184,1185,1186,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1199,1201,1202,1205,1206,1207,1211,1216,1222,1224,1225,1236,1251,1258,1259,1260,1270,1353,1364,1388,1393,1397,1398,1399,1400,1417,1418,1424,1425,1426,1487,1488,1489,1490,1491,1520,1522,1523,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1543,1544,1545,1547,1548,1549,1550,1551,1552,1553,1554,1555,1557,1558,1559,1561,1562,1563,1564,1565,1653,1654,1655,1656,1657,1658,1660,1662,1664,1665,1674,1675,1689,1693,1706,1707,1708,1711,1713,1715,1720,1725,1726,1727,1729,1731,1732,1753,1754,1765,1766,1767,1768,1769,1770,1772,1773,1778,1779,1780,1781,1782,1783,1784,1785,1787,1788,1789,1791,1793,1794,1795,1796,1797,1802,1804,1806,1808,1809,1812,1813,1815,1816,1817,1821,1822,1824,1826,1827,1831,1832,1833,1834,1835,1837,1844,1845,1847,1848,1851,1865,1866,1867,1868,1869,1870,1883,1884,1885,1888,1889,1891,1894,1895,1907,1908,1909,1910,1911,1912,1913,1914,1915,1920,1922,1923,1924,1934,1935,1936,1939,1940,1941,1942,1943,1944,1947,1948,1953,1954,1955,1956,1957,1958,1961,1971,1972,1973,1974,1983,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2017,2018,2019,2020,2021,2022,2025,2027,2029,2030,2033,2034,2038,2039,2042,2043,2053,2054,2069,2070,2071,2089,2090,2091,2102,2103,2106,2108,2120,2152,2156,2157,2162,2163,2164,2165,2166,2167,2168,2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,2185,2186,2187,2189,2190,2191,2192,2201,2202,2203,2204,2205,2206,2207,2208,2212,2231,2232,2233,2234,2235,2236,2237,2240,2241,2242,2243,2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,2260,2261,2264,2265,2266,2267,2268,2269,2270,2271,2272,2283,2287,2304,2305,2306,2318,2319,2320,2321,2322,2323,2324,2332,2335,2336,2337,2338,2339,2344,2345,2346,2347,2348,2349,2350,2351,2354,2356,2358,2359,2360,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2384,2385,2387,2403,2404,2406,2407,2408,2411,2412,2413,2414,2415,2416,2420,2421,2422,2423,2427,2428,2431,2440,2448,2449,2450,2451,2452,2453,2473,2474,2476,2503,2505,2521,2522,2529,2530,2534,2535,2536,2537,2541,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2569,2570,2571,2572,2573,2574,2575,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,2589,2590,2591,2592,2595,2596,2597,2599,2600,2603,2604,2605,2606,2607,2609,2611,2612,2618,2619,2628,2635,2636,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2680,2681,2686,2691,2692,2693,2694,2701,2714,2715,2716,2717,2718,2719,2720,2723,2725,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2738,2739,2740,2742,2743,2744,2751,2752,2753,2760,2761,2762,2764,2765,2773,2779,2780,2781,2782,2783,2791,2793,2817,2829,2830,2831,2850,2892,2893,2894,2906,2907,2923,2924,2925,2926,2927,2928,2929,2932,2944,2945,2949,2950,2951,2956,2957,2958,2959,2960,2962,2963,2964,2965,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,2989,2990,3035,3051,3056,3058,3068,3094,3099,3100,3103,3104,3105,3106,3107,3108,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3125,3126,3127,3128,3129,3130,3131,3141,3192,3195,3196,3197,3198,3199,3203,3204,3205,3206,3207,3225,3226,3227,3228,3231,3232,3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,3249,3250,3251,3252,3253,3254,3255,3256,3258,3260,3261,3263,3265,3266,3267,3268,3269,3271,3272,3273,3274,3275,3276,3277,3278,3279,3280,3282,3283,3284,3285,3286,3295,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3392,3393,3394,3396,3397,3414,3415,3416,3424,3425,3426,3434,3435,3436,3438,3445,3452,3454,3455,3456,3457,3458,3459,3461,3463,3465,3466,3467,3470,3471,3472,3473,3474,3476,3503,3528,3530,3532,3535,3566,3577,3578,3586,3630,3631,3632,3633,3634,3636,3637,3638,3640,3641,3652,3655,3660,3662,3664,3667,3672,3696,3711,3712,3713,3715,3717,3721,3725,3727,3728,3730,3732,3733,3734,3735,3736,3737,3739,3740,3742,3743,3745,3746,3748,3749,3750,3752,3754,3755,3757,3758,3759,3762,3763,3765,3767,3770,3771,3772,3773,3774,3780,3781,3782,3783,3784,3789,3791,3792,3797,3801,3802,3803,3804,3806,3807,3808,3809,3810,3811,3812,3814,3815,3816,3817,3818,3819,3820,3821,3823,3824,3825,3833,3834,3840,3851,3853,3854,3855,3857,3859,3861,3862,3863,3864,3866,3868,3872,3873,3875,3877,3917,3919,3921,3922,3923,3924,3925,3926,3928,3931,3932,3940,3941,3942,3943,3944,3947,3986,3987,3988,3989,3991,3992,3993,3999,4003,4004,4005,4006,4007,4008,4009,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4034,4035,4036,4037,4038,4040,4041,4042,4044,4050,4051,4052,4053,4054,4056,4057,4061,4062,4063,4064,4065,4066,4067,4070,4073,4074,4093,4094,4095,4096,4097,4099,4100,4101,4104,4107,4109,4110,4111,4112,4114,4116,4117,4118,4119,4120,4124,4126,4127,4128,4129,4130,4131,4132,4133,4139,4140,4142,4143,4144,4147,4150,4151,4154,4158,4202,4248,4249,4250,4260,4273,4280,4281,4282,4283,4284,4285,4286,4287,4288,4289,4290,4291,4292,4294,4295,4296,4297,4298,4299,4300,4301,4302,4303,4304,4306,4308,4316,4323,4324,4328,4329,4331,4334,4341,4343,4344,4345,4346,4347,4348,4351,4352,4356,4357,4359,4361,4362,4363,4376,4378,4379,4380,4382,4385,4387,4388,4389,4390,4393,4394,4397,4401,4403,4404,4409,4412,4414,4415,4416,4417,4418,4425,4427,4435,4436,4437,4438,4440,4442,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,4467,4468,4469,4472,4474,4475,4479,4480,4481,4493,4494,4499,4505,4506,4512,4514,4515,4516,4517,4518,4519,4520,4522,4523,4525,4530,4531,4532,4538,4539,4540,4541,4548,4619,4623,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,4644,4645,4646,4647,4648,4649,4651,4652,4653,4654,4655,4656,4657,4658,4659,4662,4663,4664,4665,4666,4667,4668,4670,4671,4672,4673,4674,4675,4676,4677,4678,4679,4680,4681,4682,4684,4685,4692,4693,4694,4695,4696,4697,4699,4700,4701,4702,4705,4711,4712,4713,4714,4715,4716,4718,4719,4723,4726,4727,4728,4729,4787,4788,4789,4798,4799,4802,4803,4805,4807,4809,4810,4811,4812,4813,4814,4815,4818,4819,4820,4821,4822,4823,4824,4825,4827,4834,4841,4842,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,4855,4856,4857,4860,4861,4863,4872,5048,5053,5055,5056,5057,5085,5086,5184,5224,5225,5226,5228,5229,5232,5234,5235,5236,5237,5238,5239,5240,5241,5243,5244,5245,5246,5247,5249,5251,5253,5254,5255,5256,5258,5259,5260,5261,5262,5263,5267,5268,5269,5270,5271,5272,5273,5274,5277,5278,5280,5283,5286,5287,5288,5291,5292,5293,5295,5296,5297,5299,5300,5304,5305,5306,5307,5308,5327,5328,5331,5332,5333,5334,5335,5336,5337,5343,5345,5346,5347,5349,5350,5352,5354,5356,5362,5363,5364,5366,5399,5400,5401,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430,5431,5441,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461,5462,5465,5471,5472,5473,5474,5475,5477,5481,5485,5490,5600,5601,5602,5615,5616,5617,5618,5622,5643,5645,5646,5647,5648,5649,5650,5682,5683,5708,5755,5756,5761,5771,5786,5787,5807,5808,5809,5823,5826,5829,5832,5833,5834,5835,5836,5837,5838,5839,5840,5843,5844,5846,5847,5848,5849,5850,5852,5853,5854,5855,5856,5857,5858,5860,5861,5862,5863,5865,5881,5912,5928,5933,5974,5975,5976,5977,5978,5979,5982,5983,5984,5985,5988,5990,5991,5992,5993,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6020,6033,6035,6068,6072,6073,6093,6113,6115,6116,6117,6118,6123,6124,6125,6126,6127,6128,6132,6133,6135,6136,6137,6138,6140,6167,6170,6184,6185,6186,6187,6188,6189,6190,6193,6194,6195,6196,6198,6199,6200,6201,6202,6206,6207,6208,6210,6211,6212,6213,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6230,6231,6232,6233,6234,6329,6347,6348,6349,6350,6351,6352,6369,6370,6371,6372,6375,6377,6378,6379,6380,6391,6392,6407,6466,6488,6489,6490,6494,6497,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6516,6517,6518,6519,6520,6521,6523,6527,6547,6551,6552,6553,6554,6555,6556,6557,6559,6570,6581,6582,6585,6606,6647,6648,6649,6650,6651,6652,6668,6733,6788,6789,6846,6909,6927,7011,7012,7015,7016,7017,7022,7023,7025,7026,7027,7028,7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043,7044,7045,7046,7047,7048,7049,7053,7055,7076,7077,7078,7079,7086,7092,7093,7097,7098,7099,7100,7101,7105,7106,7107,7109,7110,7111,7112,7113,7114,7115,7118,7120,7125,7126,7132,7136,7138,7139,7149,7153,7154,7155,7156,7157,7158,7175,7206,7234,7235,7246,7247,7268,7269,7274,7290,7309,7318,7319,7320,7321,7327,7328,7329,7332,7333,7334,7335,7337,7341,7342,7344,7345,7346,7347,7348,7352,7353,7354,7357,7358,7369,7371,7372,7376,7379,7396,7397,7404,7405,7430,7431,7432,7433,7434,7438,7439,7440,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7523,7524,7584,7603,7668,7669,7670,7671,7725,7726,7727,7728,7847,7855,7856,7857,7858,7864,7872,7873,7874,7883,7885,7886,7895,7977,7995,7996,8095,8120,8136,8201,8202,8203,8204,8205,8207,8208,8210,8211,8212,8213,8214,8216,8218,8219,8236,8277,8278,8279,8280,8281,8283,8296,8297,8298,8299,8300,8301,8302,8303,8304,8311,8318,8319,8384,8400,8408,8409,8419,8447,8503,8518,8519,8520,8521,8522,8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8534,8535,8538,8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8550,8551,8553,8555,8556,8557,8558,8560,8561,8562,8563,8564,8565,8566,8596,8597,8598,8600,8601,8602,8603,8605,8606,8607,8636,8637,8660,8667,8675,8759,8760,8761,8762,8763,8764,8766,8837,8886,8891,8892,8893,8894,8895,8896,8897,8898,8899,8900,8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,8915,8916,8917,8920,8921,8922,8923,8924,8956,8957,8958,8959,8960,8961,8977,8978,8979,8981,9024,9041,9042,9043,9044,9045,9046,9096,9097,9098,9162,9163,9164,9165,9166,9167,9176,9197,9198,9199,9200,9201,9216,9217,9218,9219,9239,9240,9241,9257,9258,9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9318,9336,9377,9396,9397,9416,9454,9462,9464,9517,9518,9545,9547,9554,9583,9596,9602,9604,9622,9690,9691,9692,9693,9694,9695,9696,9697,9698,9701,9716,9717,9718,9816,9817,9818,9819,9860,9861,9862,9877,9878,9879,9916,10077,10078,10080,10081,10082,10083,10157,10158,10159,10160,10177,10197,10199,10200,10221,10263,10316,10317,10318,10319,10323,10356,10357,10358,10359,10366,10371,10372,10374,10375,10376,10381,10382,10384,10385,10390,10391,10393,10398,10399,10400,10405,10406,10407,10408,10409,10411,10412,10413,10414,10416,10417,10418,10419,10420,10421,10422,10423,10424,10425,10426,10442,10447,10463,10464,10469,10470,10471,10472,10475,10476,10477,10478,10480,10481,10485,10486,10487,10488,10489,10491,10495,10498,10499,10500,10509,10558,10559,10580,10605,10608,10617,10639,10640,10641,10642,10643,10644,10647,10648,10659,10660,10661,10678,10738,10756,10757,10758,10759,10760,10761,10762,10801,10802,10806,10807,10809,10814,10816,10817,10821,10822,10823,10824,10825,10826,10827,10896,10899,10916,11043,11257,11290,11291,11318,11319,11320,11321,11322,11323,11324,11338,11339,11340,11350,11351,11352,11353,11356,11357,11359,11360,11361,11365,11368,11370,11371,11372,11373,11387,11388,11390,11391,11440,11441,11442,11443,11444,11445,11448,11450,11451,11452,11453,11454,11455,11456,11457,11458,11459,11461,11462,11464,11465,11467,11469,11470,11471,11472,11473,11475,11476,11477,11480,11483,11484,11516,11551,11552,11559,11561,11562,11563,11576,11577,11578,11582,11611,11613,11656,11658,11661,11662,11665,11666,11667,11668,11673,11680,11681,11682,11683,11684,11685,11686,11687,11688,11697,11698,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,11731,11732,11733,11734,11735,11736,11737,11738,11739,11740,11741,11744,11745,11746,11747,11777,11778,11781,11782,11784,11785,11786,11787,11788,11789,11790,11791,11792,11793,11794,11830,11831,11858,11873,11880,11881,11882,11883,11896,11897,11910,11911,11912,11913,11914,11915,11917,11918,11921,12037,12046,12076,12100,12101,12119,12178,12179,12199,12206,12216,12217,12218,12219,12220,12221,12222,12223,12224,12237,12248,12250,12262,12263,12322,12347,12387,12418,12431,12432,12433,12457,12459,12461,12463,12464,12465,12467,12468,12579,12676,12677,12678,12759,12856,12865,12896,12897,12902,13019,13021,13022,13036,13141,13142,13157,13160,13196,13197,13276,13285,13323,13533,13599,13996,14123,14221,14222,14223,14224,14225,14226,14227,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14266,14268,14269,14270,14271,14272,14273,14276,14277,14278,14279,14280,14281,14303,14339,14340,14342,14343,14344,14345,14356,14398,14399,14400,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14446,14447,14448,14455,14458,14460,14462,14472,14476,14477,14478,14479,14487,14488,14490,14491,14492,14523,14532,14661,14750,14821,14825,14880,14882,14883,15043,15067,15111,15168,15201,15202,15213,15229,15230,15233,15235,15236,15240,15247,15249,15250,15262,15264,15277,15312,15318,15319,15320,15323,15324,15325,15327,15333,15335,15336,15338,15343,15355,15407,15408,15409,15461,15462,15505,15542,15635,15636,15637,15638,15641,15642,15643,15645,15647,15648,15649,15650,15651,15652,15654,15655,15656,15657,15658,15668,15670,15685,15692,15937,15949,15965,15966,15967,15968,16162,16247,16248,16249,16250,16294,16300,16301,16302,16303,16304,16305,16307,16308,16309,16310,16311,16313,16314,16315,16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327,16328,16330,16331,16332,16333,16334,16335,16337,16339,16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351,16352,16353,16354,16355,16402,16403,16404,16405,16469,17115,17183,17184,17185,17186,17187,17188,17189,17190,17191,17192,17193,17194,17195,17196,17197,17199,17200,17201,17202,17203,17210,17216,17217,17235,17236,17278,17279,17298,17300,17320,17321,17322,17323,17324,17325,17326,17327,17328,17329,17330,17331,17333,17334,17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347,17348,17349,17350,17352,17353,17358,17372,17373,17374,17447,17448,17475,17494,17496,17522,17523,17524,17525,17527,17528,17550,17556,17588,17589,17591,17604,17606,17607,17608,17661,17673,17683,17701,17702,17713,17714,17878,18241,23554,23555,23589,23590,23591,23592,23593,23594,23595,23620,23637,23714,23841,23873,24477,24818,24819,37214,37917,37984,38006,38016,38023 +Total: 3090 + +All Base References: +1000105,1000610,1001115,1001620,1002125,1002630,1003140,1004150,1005163,1010708,1010809,1010910,1011011,1011112,1011213,1011314,1011415,1011822,1011923,1012024,1012125,1020812,1021014,1021115,1021216,1021317,1021418,1021519,1021620,1021721,1021822,1021923,1022024,1022125,1022226,1022327,1022428,1022529,1022630,1022731,1022832,1022933,1023034,1023135,1023236,1023337,1023438,1023539,1023640,1023741,1023842,1023943,1024044,1024145,1024246,1024347,1024448,1024549,1024650,1024751,1024852,1024953,1025054,1025155,1025256,1025357,1025458,1025559,1025660,1025761,1025862,1025963,1026063,1026163,1026263,1031922,1032023,1032124,1032225,1032326,1032427,1032528,1032629,1032730,1032831,1032932,1033033,1033134,1033235,1033336,1033437,1033538,1033639,1033740,1033841,1033942,1034043,1034144,1034245,1034346,1034447,1034548,1034649,1034750,1034851,1034952,1035053,1035154,1035255,1035356,1035457,1035558,1035659,1035760,1035861,1035963,1044046,1044248,1044450,1044652,1044854,1045056,1045258,1045460,1045662,1045863,1046063,1050614,1051525,1052635,1053650,1055163,1060610,1061120,1062130,1063140,1064150,1065155,1065663,1070610,1071114,1071519,1072025,1072627,1072830,1073135,1073640,1074145,1074650,1075061,1075063,1075155,1075660,1076163,1080620,1081225,1081630,1082035,1082640,1083045,1083650,1084055,1084660,1085063,1086163,1090110,1091120,1092130,1093140,1094150,1095162,1100105,1105865,1106672,1125860,1125961,1126062,1126163,1126264,1126365,1126466,1126567,1126668,1126769,1126870,1126971,1127072,1127173,1135861,1135962,1136063,1136164,1136265,1136366,1136467,1136568,1136669,1136770,1136873,1146773,1155873,1165864,1166573,1176571,1176573,1186165,1186673 +Total: 206 + +All Affected Items: +118,647,720,727,754,766,767,768,774,789,790,791,804,805,809,810,811,812,818,828,833,856,857,858,863,864,865,866,867,868,869,870,871,873,890,929,934,935,936,937,940,942,943,944,954,955,1121,1168,1169,1180,1181,1203,1204,1206,1207,1210,1263,1265,1315,1364,1366,1367,1368,1369,1370,1372,1374,1376,1377,1378,1380,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1425,1427,1429,1430,1431,1433,1438,1443,1447,1465,1477,1478,1495,1497,1498,1499,1501,1502,1503,1504,1505,1506,1507,1509,1510,1511,1512,1513,1514,1515,1516,1529,1607,1608,1613,1625,1639,1640,1685,1705,1710,1711,1712,1713,1714,1715,1716,1717,1718,1720,1721,1722,1725,1726,1730,1731,1732,1733,1734,1735,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1764,1766,1767,1768,1769,1770,1772,1774,1775,1776,1777,1778,1780,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1973,1979,1980,1981,1982,1988,1990,1994,2011,2059,2072,2073,2075,2077,2078,2079,2080,2098,2099,2100,2112,2138,2140,2163,2164,2194,2210,2211,2212,2213,2214,2215,2216,2217,2219,2220,2221,2222,2236,2243,2244,2245,2246,2256,2276,2277,2278,2289,2290,2291,2299,2406,2407,2408,2409,2455,2553,2555,2564,2565,2598,2601,2632,2635,2642,2643,2644,2645,2646,2648,2649,2650,2651,2652,2653,2654,2656,2657,2721,2763,2764,2765,2766,2773,2774,2777,2778,2780,2781,2782,2783,2785,2786,2800,2801,2802,2815,2819,2824,2825,2877,2878,2879,2881,2882,2883,2911,2912,2915,2951,2957,2958,2959,2960,2961,2962,2963,2964,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992,3012,3013,3020,3021,3036,3037,3039,3040,3041,3042,3045,3047,3048,3049,3055,3056,3057,3058,3065,3066,3067,3069,3075,3184,3185,3186,3187,3189,3190,3192,3193,3195,3196,3197,3198,3199,3200,3201,3202,3203,3205,3206,3207,3208,3210,3211,3212,3213,3214,3279,3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3302,3303,3304,3305,3306,3307,3308,3309,3310,3312,3313,3314,3315,3331,3363,3365,3370,3373,3374,3375,3376,3377,3378,3379,3380,3381,3385,3395,3396,3430,3608,3609,3610,3611,3612,3641,3642,3643,3644,3645,3647,3649,3650,3651,3652,3653,3654,3655,3656,3740,3778,3779,3780,3781,3782,3783,3784,3785,3786,3787,3792,3793,3794,3795,3796,3797,3798,3799,3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815,3816,3817,3827,3831,3832,3864,3866,3867,3868,3869,3870,3872,3873,3874,3914,3928,3936,3937,3938,3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3949,3950,3951,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975,3976,3986,3987,3989,3990,3992,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4035,4036,4037,4038,4039,4040,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4054,4055,4057,4058,4059,4060,4061,4062,4063,4064,4065,4066,4067,4068,4069,4070,4071,4072,4073,4074,4075,4076,4077,4078,4079,4080,4082,4083,4084,4087,4088,4089,4090,4091,4292,4293,4294,4296,4297,4299,4300,4345,4346,4347,4348,4349,4350,4351,4352,4353,4356,4408,4409,4410,4412,4414,4416,4417,4419,4421,4422,4424,4425,4426,4496,4500,4560,4561,4562,4563,4564,4565,4566,4567,4568,4569,4570,4571,4575,4576,4577,4632,4633,4634,4636,4637,4638,4658,4659,4661,4662,4663,4665,4666,4668,4669,4671,4672,4674,4675,4677,4678,4680,4681,4683,4684,4686,4687,4689,4690,4692,4693,4694,4695,4696,4697,4698,4699,4700,4701,4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718,4719,4720,4721,4722,4725,4726,4727,4729,4731,4732,4733,4734,4735,4736,4737,4738,4998,4999,5001,5002,5003,5007,5009,5011,5069,5071,5093,5207,5212,5213,5214,5215,5216,5266,5267,5543,5571,5572,5573,5574,5575,5576,5578,5758,5759,5760,5774,5972,5974,6044,6045,6046,6149,6266,6267,6268,6269,6271,6336,6337,6342,6344,6347,6348,6375,6378,6379,6380,6381,6382,6383,6386,6387,6388,6389,6390,6391,6393,6394,6395,6396,6397,6398,6399,6400,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428,6429,6430,6431,6432,6433,6454,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6517,6518,6519,6520,6521,6527,6528,6531,6536,6537,6538,6539,6540,6541,6542,6543,6545,6546,6547,6548,6549,6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,6565,6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605,6607,6608,6609,6610,6611,6612,6613,6614,6615,6616,6617,6622,6660,6663,6716,7084,7085,7086,7090,7091,7092,7108,7109,7110,7111,7112,7113,7288,7330,7331,7332,7350,7351,7353,7354,7355,7356,7357,7360,7363,7364,7366,7367,7368,7369,7370,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,7418,7419,7420,7421,7422,7423,7424,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439,7440,7441,7443,7444,7445,7446,7447,7448,7449,7450,7453,7454,7455,7456,7457,7458,7459,7460,7461,7462,7463,7465,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492,7493,7494,7495,7496,7517,7518,7519,7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7552,7553,7554,7555,7556,7557,7558,7608,7609,7610,7611,7734,7909,7910,7975,7989,7990,7992,7993,8006,8029,8080,8081,8082,8083,8084,8085,8086,8106,8107,8108,8109,8110,8111,8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127,8128,8129,8130,8131,8132,8133,8134,8135,8137,8138,8139,8140,8141,8142,8143,8144,8156,8157,8158,8159,8160,8161,8162,8163,8177,8178,8179,8180,8182,8183,8184,8186,8188,8190,8194,8196,8199,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255,8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271,8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,8315,8316,8317,8318,8319,8320,8386,8387,8389,8390,8746,8747,8748,8749,8750,8751,8752,8753,8754,8755,9285,9286,9287,9288,9289,9290,9291,9292,9293,9295,9297,9298,9359,9385,9395,9402,9405,9433,9434,9435,9742,9743,9744,9745,9746,9747,9748,9749,9750,9751,9752,9753,9754,9755,9756,9757,9758,9759,9760,9761,9762,9763,9764,9765,9766,9767,9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,9778,9779,9780,9781,9782,9783,9784,9785,9786,9787,9788,9789,9790,9791,9792,9793,9794,9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,9810,9811,9812,9813,9814,9815,9816,9817,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,9833,9834,9835,9836,9837,9838,9839,9840,9841,9842,9843,9844,9845,9846,9847,9848,9849,9850,9851,9852,9853,9854,9855,9856,9857,9858,9859,9860,9861,9862,9863,9864,9865,9866,9867,9868,9869,9870,9871,9872,9873,9874,9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885,9886,9887,9889,9890,9891,9892,9893,9894,9895,9896,9897,9898,9899,9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,9915,9916,9917,9918,9919,9920,9921,9922,9923,9924,9925,9926,9927,9928,9929,9930,9931,9932,9933,9934,9935,9936,9937,9938,9939,9940,9941,9942,9943,9944,9945,9946,9947,9948,9949,9950,9951,9952,9953,9954,9955,9956,9957,9958,9959,9960,9961,9962,9963,9964,9965,9966,9967,9968,9969,9970,9971,9972,9973,9974,10057,10058,10059,10060,10061,10062,10063,10064,10065,10066,10067,10068,10069,10070,10071,10072,10073,10074,10075,10076,10077,10078,10079,10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090,10091,10092,10093,10094,10095,10096,10097,10098,10099,10100,10101,10102,10103,10104,10105,10106,10107,10108,10109,10110,10111,10112,10113,10118,10119,10120,10121,10122,10123,10124,10125,10126,10127,10128,10129,10130,10131,10132,10133,10134,10135,10136,10137,10138,10139,10140,10141,10142,10143,10144,10145,10146,10147,10148,10149,10150,10151,10152,10153,10154,10155,10156,10157,10158,10159,10160,10161,10162,10163,10164,10165,10166,10167,10168,10169,10170,10171,10172,10173,10174,10175,10176,10177,10178,10179,10180,10181,10182,10183,10184,10185,10186,10187,10188,10189,10190,10191,10192,10193,10194,10195,10196,10197,10198,10199,10200,10201,10202,10203,10204,10205,10206,10207,10208,10209,10210,10211,10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10225,10226,10227,10228,10229,10230,10231,10232,10233,10234,10235,10236,10237,10238,10239,10240,10241,10242,10243,10244,10245,10246,10247,10248,10249,10250,10251,10252,10253,10254,10255,10256,10257,10258,10259,10260,10261,10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,10272,10273,10274,10275,10276,10277,10278,10279,10280,10281,10282,10287,10288,10289,10300,10301,10302,10305,10306,10307,10308,10309,10310,10312,10315,10316,10320,10362,10363,10364,10365,10366,10367,10368,10369,10370,10371,10372,10373,10374,10375,10376,10377,10378,10379,10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391,10404,10405,10406,10407,10408,10409,10424,10601,10603,10604,10606,11038,11039,11081,11098,11164,11165,11167,11168,11202,11204,11208,11224,11225,11226,11302,11732,11733,11734,11736,11737,11965,11967,11968,11969,11970,11971,11972,11973,11974,11975,11976,11977,11978,11979,11980,11981,11982,11983,11984,11985,11986,11987,11988,11989,11990,11991,11992,11993,11994,11995,11996,11997,11998,11999,12001,12002,12004,12005,12006,12007,12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12019,12020,12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,12032,12034,12035,12036,12039,12040,12042,12043,12044,12045,12046,12047,12048,12052,12053,12054,12055,12056,12057,12058,12261,12682,12683,12684,12685,12689,12691,12692,12974,12975,12976,12977,12978,12979,12982,12983,12984,12985,12987,12988,12989,12990,12992,12994,12996,12997,12998,12999,13000,13001,13002,13003,13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015,13016,13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,13028,13029,13030,13031,13032,13033,13034,13035,13036,13037,13038,13039,13040,13041,13042,13043,13044,13045,13046,13047,13048,13049,13051,13052,13053,13054,13055,13056,13057,13058,13059,13060,13062,13063,13064,13065,13066,13067,13068,13070,13071,13072,13073,13074,13075,13076,13077,13079,13081,13082,13083,13084,13085,13087,13088,13089,13091,13093,13094,13095,13096,13097,13099,13100,13101,13102,13103,13105,13106,13107,13108,13109,13110,13111,13112,13113,13114,13115,13116,13117,13118,13119,13120,13121,13122,13123,13124,13125,13126,13127,13128,13129,13130,13131,13132,13133,13134,13135,13136,13137,13138,13139,13144,13145,13146,13199,13443,13444,13446,13486,13487,13488,13489,13816,13817,13818,13819,13820,13821,13822,13823,13824,13825,14025,14086,14087,14088,14089,14090,14091,14093,14094,14095,14096,14097,14098,14099,14102,14109,14110,14113,14114,14115,14116,14117,14119,14120,14121,14122,14123,14124,14125,14126,14127,14129,14131,14133,14157,14158,14159,14160,14161,14162,14163,14164,14165,14166,14167,14168,14169,14170,14171,14172,14173,14174,14175,14176,14177,14178,14179,14180,14181,14182,14183,14184,14185,14186,14187,14188,14189,14190,14191,14192,14193,14194,14195,14196,14197,14198,14199,14200,14201,14202,14203,14204,14205,14206,14207,14208,14209,14210,14211,14212,14213,14214,14215,14216,14217,14218,14219,14220,14221,14222,14223,14224,14225,14226,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14238,14239,14240,14241,14242,14243,14244,14245,14246,14247,14248,14249,14250,14251,14252,14253,14254,14255,14257,14258,14259,14260,14261,14262,14263,14264,14265,14266,14267,14268,14269,14270,14271,14272,14273,14274,14275,14276,14277,14278,14279,14280,14281,14282,14283,14284,14285,14286,14287,14288,14289,14290,14291,14292,14293,14294,14295,14296,14297,14298,14299,14300,14301,14302,14303,14304,14305,14306,14307,14308,14309,14310,14311,14312,14313,14314,14315,14316,14317,14318,14319,14320,14321,14322,14323,14324,14325,14326,14327,14328,14329,14330,14331,14332,14333,14334,14335,14336,14337,14364,14365,14366,14367,14368,14369,14370,14371,14372,14373,14374,14375,14376,14377,14378,14379,14380,14397,14398,14399,14400,14401,14402,14403,14404,14405,14406,14407,14408,14409,14410,14411,14412,14413,14414,14415,14416,14417,14418,14419,14420,14421,14422,14423,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14434,14435,14436,14437,14438,14439,14440,14441,14442,14443,14444,14445,14446,14447,14448,14449,14450,14451,14452,14453,14454,14455,14456,14457,14458,14459,14460,14461,14462,14463,14464,14465,14466,14467,14470,14474,14478,14479,14484,14549,14551,14552,14553,14554,14555,14557,14558,14559,14560,14561,14562,14563,14564,14565,14566,14567,14568,14569,14570,14571,14572,14573,14574,14578,14579,14580,14581,14582,14583,14584,14585,14587,14588,14589,14590,14591,14592,14593,14594,14595,14596,14598,14599,14600,14601,14602,14603,14604,14605,14606,14607,14608,14652,14653,14654,14655,14656,14657,14658,14659,14660,14661,14662,14663,14664,14665,14666,14667,14668,14669,14670,14671,14672,14673,14674,14675,14676,14677,14678,14680,14681,14682,14683,14684,14685,14686,14687,14688,14722,14723,14724,14725,14726,14727,14728,14729,14730,14742,14743,14744,14745,14746,14747,14748,14749,14750,14751,14752,14753,14754,14755,14756,14757,14758,14759,14760,14761,14762,14763,14764,14765,14766,14767,14768,14769,14770,14771,14772,14773,14774,14775,14776,14777,14778,14779,14780,14781,14782,14783,14784,14785,14786,14787,14788,14789,14790,14791,14792,14793,14794,14795,14796,14797,14798,14799,14800,14801,14802,14803,14804,14805,14806,14807,14808,14809,14810,14811,14812,14813,14814,14815,14816,14817,14821,14825,14826,14827,14828,14829,14830,14831,14832,14833,14834,14835,14838,14839,14840,14841,14842,14843,14844,14846,14847,14848,14849,14850,14851,14852,14853,14854,14855,14856,14857,14858,14859,14860,14861,14862,14863,14864,14865,14866,14867,14868,14869,14895,14896,14897,14898,14899,14900,14901,14902,14903,14904,14905,14906,14907,14908,14909,14910,14911,14912,14913,14914,14915,14916,14917,14918,14919,14920,14921,14922,14923,14924,14925,14926,14927,14928,14929,14930,14931,14932,14933,14934,14935,14936,14937,14938,14939,14940,14941,14942,14943,14944,14945,14946,14947,14948,14949,14950,14951,14952,14953,14954,14955,14956,14957,14958,14959,14960,14961,14962,14963,14964,14965,14966,14967,14968,14969,14970,14971,14972,14973,14974,14975,14976,14977,14978,14979,14980,14981,14982,14983,15003,15004,15005,15006,15007,15008,15009,15010,15011,15012,15013,15014,15015,15016,15017,15018,15019,15110,15111,15112,15113,15114,15115,15116,15117,15118,15119,15120,15121,15122,15123,15124,15125,15126,15127,15128,15129,15130,15131,15132,15133,15134,15135,15136,15137,15139,15140,15142,15143,15144,15145,15146,15147,15148,15149,15150,15151,15152,15153,15154,15155,15156,15157,15158,15159,15160,15161,15162,15163,15164,15165,15166,15167,15168,15169,15170,15171,15172,15173,15174,15175,15176,15177,15178,15179,15180,15181,15182,15183,15184,15185,15186,15187,15188,15189,15190,15191,15192,15193,15194,15195,15210,15211,15212,15213,15214,15215,15216,15217,15218,15219,15220,15221,15222,15223,15224,15225,15226,15227,15228,15229,15230,15231,15232,15233,15234,15235,15236,15237,15238,15239,15240,15241,15242,15243,15244,15245,15246,15247,15248,15249,15250,15251,15252,15253,15254,15255,15256,15257,15258,15259,15260,15261,15262,15263,15264,15265,15266,15267,15268,15269,15270,15271,15272,15273,15274,15275,15276,15278,15279,15280,15281,15282,15283,15284,15285,15286,15287,15288,15289,15291,15294,15295,15296,15297,15298,15299,15300,15301,15302,15303,15304,15305,15306,15307,15308,15309,15310,15311,15312,15313,15322,15323,15324,15325,15329,15330,15331,15332,15333,15334,15336,15337,15338,15339,15340,15341,15342,15343,15344,15345,15346,15347,15348,15349,15350,15351,15352,15353,15354,15355,15356,15357,15358,15359,15360,15361,15362,15363,15364,15365,15366,15367,15368,15369,15370,15371,15372,15373,15374,15375,15376,15377,15378,15379,15380,15381,15382,15383,15384,15385,15386,15387,15388,15389,15390,15391,15392,15393,15394,15395,15425,15426,15427,15428,15429,15430,15431,15432,15433,15434,15435,15436,15437,15438,15439,15440,15441,15442,15472,15473,15474,15475,15476,15477,15478,15479,15480,15481,15482,15483,15484,15485,15486,15487,15488,15489,15490,15491,15492,15493,15494,15495,15496,15497,15498,15499,15500,15501,15502,15503,15504,15505,15506,15507,15508,15509,15510,15511,15512,15513,15514,15515,15516,15517,15518,15519,15520,15521,15522,15523,15524,15525,15526,15527,15528,15529,15530,15531,15532,15533,15534,15535,15536,15537,15538,15539,15540,15541,15542,15543,15544,15545,15546,15547,15548,15549,15550,15551,15552,15553,15554,15555,15556,15557,15558,15559,15560,15561,15562,15563,15565,15566,15567,15568,15569,15570,15571,15572,15573,15574,15575,15576,15577,15578,15579,15580,15581,15582,15583,15584,15589,15590,15591,15592,15593,15594,15595,15596,15597,15598,15599,15600,15601,15602,15603,15604,15605,15606,15607,15608,15609,15610,15611,15612,15613,15614,15615,15616,15617,15618,15619,15620,15621,15622,15623,15624,15625,15626,15627,15628,15629,15630,15631,15632,15633,15634,15635,15636,15637,15638,15639,15640,15641,15642,15643,15644,15645,15646,15647,15648,15649,15650,15651,15652,15653,15654,15655,15656,15657,15658,15659,15660,15661,15662,15663,15664,15665,15666,15667,15668,15669,15670,15671,15672,15673,15674,15675,15676,15677,15678,15679,15680,15681,15682,15683,15684,15685,15686,15687,15693,15694,15731,15737,15887,15890,15891,15892,15893,15894,15895,15912,15918,15925,15926,15927,15928,15929,15930,15931,15932,15933,15934,15935,15936,15937,15938,15939,15940,15941,15942,15943,15944,15945,15946,15947,15962,15963,15964,15965,15966,15967,15968,15969,15970,15971,15972,15973,15974,15975,15976,15977,15978,15979,15980,15981,15982,15983,15984,15985,15986,15987,15988,15989,15990,15991,16043,16044,16215,16218,16220,16253,17007,17413,17414,17682,17683,18600,19230,19231,19232,19233,19234,19235,19236,19259,19260,19261,19262,19263,19264,19265,19269,19270,19271,19272,19273,19274,19275,19278,19279,19280,19281,19282,19283,19284,20974,20976,21002,21003,21004,21005,21006,21007,21008,21009,21010,21011,21012,21013,21014,21015,21016,21017,21018,21019,21020,21021,21022,21940,21944,21945,21947,21949,22146,22153,22393,22532,22540,22541,22542,22548,22553,22557,22558,22829,22832,22890,22891,22903,22904,22912,22913,22914,22919,22926,23154,23197,23199,23203,23620,23621,23622,23623,23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635,23636,23637,23802,23804,23810,23883,23884,24163,24164,24165,24166,24167,24168,24169,24170,24171,24192,24193,24194,24195,24196,24197,24198,24199,24200,24201,24202,24203,24204,24205,24206,24207,24209,24210,24211,24212,24213,24214,24215,24216,24217,24218,24219,24220,24222,24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307,24575,24576,24577,24578,24580,24582,24583,24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595,24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607,24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619,24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631,24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643,24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655,24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667,24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679,24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691,24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703,24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715,24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727,24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739,24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751,24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763,24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775,24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787,24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799,24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811,24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823,24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835,24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847,24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859,24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871,24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895,24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907,24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919,24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931,24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943,24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979,24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991,24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003,25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015,25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027,25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039,25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087,25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099,25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111,25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123,25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135,25136,25137,25138,25139,25140,25141,25142,25143,25144,25146,25147,25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171,25172,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183,25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195,25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207,25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219,25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231,25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243,25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255,25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267,25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279,25280,25281,25282,25283,25284,25286,25287,25288,25289,25290,25291,25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303,25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315,25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327,25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339,25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351,25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363,25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375,25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387,25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399,25400,25401,25402,25403,25404,25405,25406,25887,25905,25906,25907,25909,27498,27499,27500,27501,27502,27503,28270,28279,28280,28531,28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543,28544,29549,29550,29714,29723,29724,29725,29726,29727,29728,29729,29730,29731,29732,29733,29734,31125,31126,31127,31131,31133,31134,31136,31137,31138,31139,31140,31142,31143,31145,31147,31148,31149,31150,31151,31152,31153,31173,31175,31178,31180,31186,31187,31190,31193,31196,31200,31202,31204,31222,31226,31230,31234,31237,31240,31255,31258,31272,31275,31276,31277,31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291,31292,31293,31294,31295,31297,31298,31299,31303,31304,31305,31306,31308,31318,31319,31320,31321,31322,31323,31326,31328,31329,31330,31331,31332,31333,31334,31335,31336,31338,31339,31340,31342,31343,31501,31557,31565,31573,31581,31837,31875,31876,31877,31878,31879,31883,31884,31885,31886,31887,31888,31889,31893,31894,31895,31896,31898,31899,31900,31902,31903,31904,31905,31906,31908,31909,31911,31912,31913,31915,31916,31917,31918,31925,31926,31927,31928,31929,31935,31936,31937,31938,31939,31940,31943,31952,32411,32520,33186,33457,33458,33459,33460,33461,33462,33954,15742,12684,14467,14466,12685,14470,16043,16215,21949,16044,14474,12689,12691,16218,15731,14478,14479,12692,13486,15737,13488,14484,13489,16220,13487,12693,12694,15746,15745,15743,13490,14489,12695,14492,16051,13492,13493,14491,12697,15755,14494,15757,14498,12702,16245,13518,15765,12704,16055,14499,16251,12713,14504,14506,14508,16253,12703,12711,14501,14507,12716,14509,14510,12717,22388,14511,12720,12728,22390,22389 +Total: 4470 + +All Root References: +BETWEEN 1000001 AND 1000062; +BETWEEN 1000105 AND 1000162; +BETWEEN 1000201 AND 1000263; +BETWEEN 1000305 AND 1000363; + +*/ +-- Loose Items +DELETE FROM `creature_loot_template` WHERE +`Entry` IN (3,30,36,40,43,46,48,60,61,79,92,94,95,97,98,99,100,113,114,115,116,117,118,119,121,122,123,124,125,126,127,154,157,171,199,202,203,205,206,210,212,213,215,217,218,232,285,300,315,327,330,345,390,391,397,422,423,424,426,428,429,430,431,432,433,434,435,436,437,440,441,442,445,446,449,452,453,454,456,458,462,471,472,473,474,475,476,478,480,481,485,500,501,502,503,504,505,506,507,511,513,515,517,518,519,520,521,524,525,533,534,539,544,545,547,548,550,565,568,569,570,572,573,574,578,579,580,584,587,588,589,590,594,595,596,597,598,599,604,615,616,619,622,623,624,625,626,628,634,636,641,657,660,667,669,670,671,672,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,694,696,697,699,701,702,703,709,710,711,712,723,728,729,730,732,735,736,740,741,742,743,744,745,746,747,750,751,752,754,755,757,759,760,761,762,763,764,765,766,767,768,769,771,772,780,781,782,783,784,785,787,813,814,818,819,822,824,830,831,832,833,834,846,854,855,856,858,861,862,863,864,865,868,871,873,875,877,879,880,881,889,891,892,898,905,909,910,920,921,922,923,930,937,938,939,940,941,942,943,947,948,949,950,976,977,978,979,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1051,1052,1053,1054,1057,1059,1061,1062,1063,1065,1069,1081,1082,1083,1084,1085,1087,1088,1094,1095,1096,1097,1106,1108,1109,1110,1111,1112,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1137,1138,1140,1142,1144,1150,1151,1152,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1169,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1183,1184,1185,1186,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1199,1201,1202,1205,1206,1207,1211,1216,1222,1224,1225,1236,1251,1258,1259,1260,1270,1353,1364,1388,1393,1397,1398,1399,1400,1417,1418,1424,1425,1426,1487,1488,1489,1490,1491,1520,1522,1523,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1543,1544,1545,1547,1548,1549,1550,1551,1552,1553,1554,1555,1557,1558,1559,1561,1562,1563,1564,1565,1653,1654,1655,1656,1657,1658,1660,1662,1664,1665,1674,1675,1689,1693,1706,1707,1708,1711,1713,1715,1720,1725,1726,1727,1729,1731,1732,1753,1754,1765,1766,1767,1768,1769,1770,1772,1773,1778,1779,1780,1781,1782,1783,1784,1785,1787,1788,1789,1791,1793,1794,1795,1796,1797,1802,1804,1806,1808,1809,1812,1813,1815,1816,1817,1821,1822,1824,1826,1827,1831,1832,1833,1834,1835,1837,1844,1845,1847,1848,1851,1865,1866,1867,1868,1869,1870,1883,1884,1885,1888,1889,1891,1894,1895,1907,1908,1909,1910,1911,1912,1913,1914,1915,1920,1922,1923,1924,1934,1935,1936,1939,1940,1941,1942,1943,1944,1947,1948,1953,1954,1955,1956,1957,1958,1961,1971,1972,1973,1974,1983,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2017,2018,2019,2020,2021,2022,2025,2027,2029,2030,2033,2034,2038,2039,2042,2043,2053,2054,2069,2070,2071,2089,2090,2091,2102,2103,2106,2108,2120,2152,2156,2157,2162,2163,2164,2165,2166,2167,2168,2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,2185,2186,2187,2189,2190,2191,2192,2201,2202,2203,2204,2205,2206,2207,2208,2212,2231,2232,2233,2234,2235,2236,2237,2240,2241,2242,2243,2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,2260,2261,2264,2265,2266,2267,2268,2269,2270,2271,2272,2283,2287,2304,2305,2306,2318,2319,2320,2321,2322,2323,2324,2332,2335,2336,2337,2338,2339,2344,2345,2346,2347,2348,2349,2350,2351,2354,2356,2358,2359,2360,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2384,2385,2387,2403,2404,2406,2407,2408,2411,2412,2413,2414,2415,2416,2420,2421,2422,2423,2427,2428,2431,2440,2448,2449,2450,2451,2452,2453,2473,2474,2476,2503,2505,2521,2522,2529,2530,2534,2535,2536,2537,2541,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2569,2570,2571,2572,2573,2574,2575,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,2589,2590,2591,2592,2595,2596,2597,2599,2600,2603,2604,2605,2606,2607,2609,2611,2612,2618,2619,2628,2635,2636,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2680,2681,2686,2691,2692,2693,2694,2701,2714,2715,2716,2717,2718,2719,2720,2723,2725,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2738,2739,2740,2742,2743,2744,2751,2752,2753,2760,2761,2762,2764,2765,2773,2779,2780,2781,2782,2783,2791,2793,2817,2829,2830,2831,2850,2892,2893,2894,2906,2907,2923,2924,2925,2926,2927,2928,2929,2932,2944,2945,2949,2950,2951,2956,2957,2958,2959,2960,2962,2963,2964,2965,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,2989,2990,3035,3051,3056,3058,3068,3094,3099,3100,3103,3104,3105,3106,3107,3108,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3125,3126,3127,3128,3129,3130,3131,3141,3192,3195,3196,3197,3198,3199,3203,3204,3205,3206,3207,3225,3226,3227,3228,3231,3232,3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,3249,3250,3251,3252,3253,3254,3255,3256,3258,3260,3261,3263,3265,3266,3267,3268,3269,3271,3272,3273,3274,3275,3276,3277,3278,3279,3280,3282,3283,3284,3285,3286,3295,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3392,3393,3394,3396,3397,3414,3415,3416,3424,3425,3426,3434,3435,3436,3438,3445,3452,3454,3455,3456,3457,3458,3459,3461,3463,3465,3466,3467,3470,3471,3472,3473,3474,3476,3503,3528,3530,3532,3535,3566,3577,3578,3586,3630,3631,3632,3633,3634,3636,3637,3638,3640,3641,3652,3655,3660,3662,3664,3667,3672,3696,3711,3712,3713,3715,3717,3721,3725,3727,3728,3730,3732,3733,3734,3735,3736,3737,3739,3740,3742,3743,3745,3746,3748,3749,3750,3752,3754,3755,3757,3758,3759,3762,3763,3765,3767,3770,3771,3772,3773,3774,3780,3781,3782,3783,3784,3789,3791,3792,3797,3801,3802,3803,3804,3806,3807,3808,3809,3810,3811,3812,3814,3815,3816,3817,3818,3819,3820,3821,3823,3824,3825,3833,3834,3840,3851,3853,3854,3855,3857,3859,3861,3862,3863,3864,3866,3868,3872,3873,3875,3877,3917,3919,3921,3922,3923,3924,3925,3926,3928,3931,3932,3940,3941,3942,3943,3944,3947,3986,3987,3988,3989,3991,3992,3993,3999,4003,4004,4005,4006,4007,4008,4009,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4034,4035,4036,4037,4038,4040,4041,4042,4044,4050,4051,4052,4053,4054,4056,4057,4061,4062,4063,4064,4065,4066,4067,4070,4073,4074,4093,4094,4095,4096,4097,4099,4100,4101,4104,4107,4109,4110,4111,4112,4114,4116,4117,4118,4119,4120,4124,4126,4127,4128,4129,4130,4131,4132,4133,4139,4140,4142,4143,4144,4147,4150,4151,4154,4158,4202,4248,4249,4250,4260,4273,4280,4281,4282,4283,4284,4285,4286,4287,4288,4289,4290,4291,4292,4294,4295,4296,4297,4298,4299,4300,4301,4302,4303,4304,4306,4308,4316,4323,4324,4328,4329,4331,4334,4341,4343,4344,4345,4346,4347,4348,4351,4352,4356,4357,4359,4361,4362,4363,4376,4378,4379,4380,4382,4385,4387,4388,4389,4390,4393,4394,4397,4401,4403,4404,4409,4412,4414,4415,4416,4417,4418,4425,4427,4435,4436,4437,4438,4440,4442,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,4467,4468,4469,4472,4474,4475,4479,4480,4481,4493,4494,4499,4505,4506,4512,4514,4515,4516,4517,4518,4519,4520,4522,4523,4525,4530,4531,4532,4538,4539,4540,4541,4548,4619,4623,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,4644,4645,4646,4647,4648,4649,4651,4652,4653,4654,4655,4656,4657,4658,4659,4662,4663,4664,4665,4666,4667,4668,4670,4671,4672,4673,4674,4675,4676,4677,4678,4679,4680,4681,4682,4684,4685,4692,4693,4694,4695,4696,4697,4699,4700,4701,4702,4705,4711,4712,4713,4714,4715,4716,4718,4719,4723,4726,4727,4728,4729,4787,4788,4789,4798,4799,4802,4803,4805,4807,4809,4810,4811,4812,4813,4814,4815,4818,4819,4820,4821,4822,4823,4824,4825,4827,4834,4841,4842,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,4855,4856,4857,4860,4861,4863,4872,5048,5053,5055,5056,5057,5085,5086,5184,5224,5225,5226,5228,5229,5232,5234,5235,5236,5237,5238,5239,5240,5241,5243,5244,5245,5246,5247,5249,5251,5253,5254,5255,5256,5258,5259,5260,5261,5262,5263,5267,5268,5269,5270,5271,5272,5273,5274,5277,5278,5280,5283,5286,5287,5288,5291,5292,5293,5295,5296,5297,5299,5300,5304,5305,5306,5307,5308,5327,5328,5331,5332,5333,5334,5335,5336,5337,5343,5345,5346,5347,5349,5350,5352,5354,5356,5362,5363,5364,5366,5399,5400,5401,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430,5431,5441,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461,5462,5465,5471,5472,5473,5474,5475,5477,5481,5485,5490,5600,5601,5602,5615,5616,5617,5618,5622,5643,5645,5646,5647,5648,5649,5650,5682,5683,5708,5755,5756,5761,5771,5786,5787,5807,5808,5809,5823,5826,5829,5832,5833,5834,5835,5836,5837,5838,5839,5840,5843,5844,5846,5847,5848,5849,5850,5852,5853,5854,5855,5856,5857,5858,5860,5861,5862,5863,5865,5881,5912,5928,5933,5974,5975,5976,5977,5978,5979,5982,5983,5984,5985,5988,5990,5991,5992,5993,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6020,6033,6035,6068,6072,6073,6093,6113,6115,6116,6117,6118,6123,6124,6125,6126,6127,6128,6132,6133,6135,6136,6137,6138,6140,6167,6170,6184,6185,6186,6187,6188,6189,6190,6193,6194,6195,6196,6198,6199,6200,6201,6202,6206,6207,6208,6210,6211,6212,6213,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6230,6231,6232,6233,6234,6329,6347,6348,6349,6350,6351,6352,6369,6370,6371,6372,6375,6377,6378,6379,6380,6391,6392,6407,6466,6488,6489,6490,6494,6497,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6516,6517,6518,6519,6520,6521,6523,6527,6547,6551,6552,6553,6554,6555,6556,6557,6559,6570,6581,6582,6585,6606,6647,6648,6649,6650,6651,6652,6668,6733,6788,6789,6846,6909,6927,7011,7012,7015,7016,7017,7022,7023,7025,7026,7027,7028,7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043,7044,7045,7046,7047,7048,7049,7053,7055,7076,7077,7078,7079,7086,7092,7093,7097,7098,7099,7100,7101,7105,7106,7107,7109,7110,7111,7112,7113,7114,7115,7118,7120,7125,7126,7132,7136,7138,7139,7149,7153,7154,7155,7156,7157,7158,7175,7206,7234,7235,7246,7247,7268,7269,7274,7290,7309,7318,7319,7320,7321,7327,7328,7329,7332,7333,7334,7335,7337,7341,7342,7344,7345,7346,7347,7348,7352,7353,7354,7357,7358,7369,7371,7372,7376,7379,7396,7397,7404,7405,7430,7431,7432,7433,7434,7438,7439,7440,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7523,7524,7584,7603,7668,7669,7670,7671,7725,7726,7727,7728,7847,7855,7856,7857,7858,7864,7872,7873,7874,7883,7885,7886,7895,7977,7995,7996,8095,8120,8136,8201,8202,8203,8204,8205,8207,8208,8210,8211,8212,8213,8214,8216,8218,8219,8236,8277,8278,8279,8280,8281,8283,8296,8297,8298,8299,8300,8301,8302,8303,8304,8311,8318,8319,8384,8400,8408,8409,8419,8447,8503,8518,8519,8520,8521,8522,8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8534,8535,8538,8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8550,8551,8553,8555,8556,8557,8558,8560,8561,8562,8563,8564,8565,8566,8596,8597,8598,8600,8601,8602,8603,8605,8606,8607,8636,8637,8660,8667,8675,8759,8760,8761,8762,8763,8764,8766,8837,8886,8891,8892,8893,8894,8895,8896,8897,8898,8899,8900,8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,8915,8916,8917,8920,8921,8922,8923,8924,8956,8957,8958,8959,8960,8961,8977,8978,8979,8981,9024,9041,9042,9043,9044,9045,9046,9096,9097,9098,9162,9163,9164,9165,9166,9167,9176,9197,9198,9199,9200,9201,9216,9217,9218,9219,9239,9240,9241,9257,9258,9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9318,9336,9377,9396,9397,9416,9454,9462,9464,9517,9518,9545,9547,9554,9583,9596,9602,9604,9622,9690,9691,9692,9693,9694,9695,9696,9697,9698,9701,9716,9717,9718,9816,9817,9818,9819,9860,9861,9862,9877,9878,9879,9916,10077,10078,10080,10081,10082,10083,10157,10158,10159,10160,10177,10197,10199,10200,10221,10263,10316,10317,10318,10319,10323,10356,10357,10358,10359,10366,10371,10372,10374,10375,10376,10381,10382,10384,10385,10390,10391,10393,10398,10399,10400,10405,10406,10407,10408,10409,10411,10412,10413,10414,10416,10417,10418,10419,10420,10421,10422,10423,10424,10425,10426,10442,10447,10463,10464,10469,10470,10471,10472,10475,10476,10477,10478,10480,10481,10485,10486,10487,10488,10489,10491,10495,10498,10499,10500,10509,10558,10559,10580,10605,10608,10617,10639,10640,10641,10642,10643,10644,10647,10648,10659,10660,10661,10678,10738,10756,10757,10758,10759,10760,10761,10762,10801,10802,10806,10807,10809,10814,10816,10817,10821,10822,10823,10824,10825,10826,10827,10896,10899,10916,11043,11257,11290,11291,11318,11319,11320,11321,11322,11323,11324,11338,11339,11340,11350,11351,11352,11353,11356,11357,11359,11360,11361,11365,11368,11370,11371,11372,11373,11387,11388,11390,11391,11440,11441,11442,11443,11444,11445,11448,11450,11451,11452,11453,11454,11455,11456,11457,11458,11459,11461,11462,11464,11465,11467,11469,11470,11471,11472,11473,11475,11476,11477,11480,11483,11484,11516,11551,11552,11559,11561,11562,11563,11576,11577,11578,11582,11611,11613,11656,11658,11661,11662,11665,11666,11667,11668,11673,11680,11681,11682,11683,11684,11685,11686,11687,11688,11697,11698,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,11731,11732,11733,11734,11735,11736,11737,11738,11739,11740,11741,11744,11745,11746,11747,11777,11778,11781,11782,11784,11785,11786,11787,11788,11789,11790,11791,11792,11793,11794,11830,11831,11858,11873,11880,11881,11882,11883,11896,11897,11910,11911,11912,11913,11914,11915,11917,11918,11921,12037,12046,12076,12100,12101,12119,12178,12179,12199,12206,12216,12217,12218,12219,12220,12221,12222,12223,12224,12237,12248,12250,12262,12263,12322,12347,12387,12418,12431,12432,12433,12457,12459,12461,12463,12464,12465,12467,12468,12579,12676,12677,12678,12759,12856,12865,12896,12897,12902,13019,13021,13022,13036,13141,13142,13157,13160,13196,13197,13276,13285,13323,13533,13599,13996,14123,14221,14222,14223,14224,14225,14226,14227,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14266,14268,14269,14270,14271,14272,14273,14276,14277,14278,14279,14280,14281,14303,14339,14340,14342,14343,14344,14345,14356,14398,14399,14400,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14446,14447,14448,14455,14458,14460,14462,14472,14476,14477,14478,14479,14487,14488,14490,14491,14492,14523,14532,14661,14750,14821,14825,14880,14882,14883,15043,15067,15111,15168,15201,15202,15213,15229,15230,15233,15235,15236,15240,15247,15249,15250,15262,15264,15277,15312,15318,15319,15320,15323,15324,15325,15327,15333,15335,15336,15338,15343,15355,15407,15408,15409,15461,15462,15505,15542,15635,15636,15637,15638,15641,15642,15643,15645,15647,15648,15649,15650,15651,15652,15654,15655,15656,15657,15658,15668,15670,15685,15692,15937,15949,15965,15966,15967,15968,16162,16247,16248,16249,16250,16294,16300,16301,16302,16303,16304,16305,16307,16308,16309,16310,16311,16313,16314,16315,16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327,16328,16330,16331,16332,16333,16334,16335,16337,16339,16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351,16352,16353,16354,16355,16402,16403,16404,16405,16469,17115,17183,17184,17185,17186,17187,17188,17189,17190,17191,17192,17193,17194,17195,17196,17197,17199,17200,17201,17202,17203,17210,17216,17217,17235,17236,17278,17279,17298,17300,17320,17321,17322,17323,17324,17325,17326,17327,17328,17329,17330,17331,17333,17334,17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347,17348,17349,17350,17352,17353,17358,17372,17373,17374,17447,17448,17475,17494,17496,17522,17523,17524,17525,17527,17528,17550,17556,17588,17589,17591,17604,17606,17607,17608,17661,17673,17683,17701,17702,17713,17714,17878,18241,23554,23555,23589,23590,23591,23592,23593,23594,23595,23620,23637,23714,23841,23873,24477,24818,24819,37214,37917,37984,38006,38016,38023) +AND `Item` IN (118,647,720,727,754,766,767,768,774,789,790,791,804,805,809,810,811,812,818,828,833,856,857,858,863,864,865,866,867,868,869,870,871,873,890,929,934,935,936,937,940,942,943,944,954,955,1121,1168,1169,1180,1181,1203,1204,1206,1207,1210,1263,1265,1315,1364,1366,1367,1368,1369,1370,1372,1374,1376,1377,1378,1380,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1425,1427,1429,1430,1431,1433,1438,1443,1447,1465,1477,1478,1495,1497,1498,1499,1501,1502,1503,1504,1505,1506,1507,1509,1510,1511,1512,1513,1514,1515,1516,1529,1607,1608,1613,1625,1639,1640,1685,1705,1710,1711,1712,1713,1714,1715,1716,1717,1718,1720,1721,1722,1725,1726,1730,1731,1732,1733,1734,1735,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1764,1766,1767,1768,1769,1770,1772,1774,1775,1776,1777,1778,1780,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1973,1979,1980,1981,1982,1988,1990,1994,2011,2059,2072,2073,2075,2077,2078,2079,2080,2098,2099,2100,2112,2138,2140,2163,2164,2194,2210,2211,2212,2213,2214,2215,2216,2217,2219,2220,2221,2222,2236,2243,2244,2245,2246,2256,2276,2277,2278,2289,2290,2291,2299,2406,2407,2408,2409,2455,2553,2555,2564,2565,2598,2601,2632,2635,2642,2643,2644,2645,2646,2648,2649,2650,2651,2652,2653,2654,2656,2657,2721,2763,2764,2765,2766,2773,2774,2777,2778,2780,2781,2782,2783,2785,2786,2800,2801,2802,2815,2819,2824,2825,2877,2878,2879,2881,2882,2883,2911,2912,2915,2951,2957,2958,2959,2960,2961,2962,2963,2964,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992,3012,3013,3020,3021,3036,3037,3039,3040,3041,3042,3045,3047,3048,3049,3055,3056,3057,3058,3065,3066,3067,3069,3075,3184,3185,3186,3187,3189,3190,3192,3193,3195,3196,3197,3198,3199,3200,3201,3202,3203,3205,3206,3207,3208,3210,3211,3212,3213,3214,3279,3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3302,3303,3304,3305,3306,3307,3308,3309,3310,3312,3313,3314,3315,3331,3363,3365,3370,3373,3374,3375,3376,3377,3378,3379,3380,3381,3385,3395,3396,3430,3608,3609,3610,3611,3612,3641,3642,3643,3644,3645,3647,3649,3650,3651,3652,3653,3654,3655,3656,3740,3778,3779,3780,3781,3782,3783,3784,3785,3786,3787,3792,3793,3794,3795,3796,3797,3798,3799,3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815,3816,3817,3827,3831,3832,3864,3866,3867,3868,3869,3870,3872,3873,3874,3914,3928,3936,3937,3938,3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3949,3950,3951,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975,3976,3986,3987,3989,3990,3992,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4035,4036,4037,4038,4039,4040,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4054,4055,4057,4058,4059,4060,4061,4062,4063,4064,4065,4066,4067,4068,4069,4070,4071,4072,4073,4074,4075,4076,4077,4078,4079,4080,4082,4083,4084,4087,4088,4089,4090,4091,4292,4293,4294,4296,4297,4299,4300,4345,4346,4347,4348,4349,4350,4351,4352,4353,4356,4408,4409,4410,4412,4414,4416,4417,4419,4421,4422,4424,4425,4426,4496,4500,4560,4561,4562,4563,4564,4565,4566,4567,4568,4569,4570,4571,4575,4576,4577,4632,4633,4634,4636,4637,4638,4658,4659,4661,4662,4663,4665,4666,4668,4669,4671,4672,4674,4675,4677,4678,4680,4681,4683,4684,4686,4687,4689,4690,4692,4693,4694,4695,4696,4697,4698,4699,4700,4701,4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718,4719,4720,4721,4722,4725,4726,4727,4729,4731,4732,4733,4734,4735,4736,4737,4738,4998,4999,5001,5002,5003,5007,5009,5011,5069,5071,5093,5207,5212,5213,5214,5215,5216,5266,5267,5543,5571,5572,5573,5574,5575,5576,5578,5758,5759,5760,5774,5972,5974,6044,6045,6046,6149,6266,6267,6268,6269,6271,6336,6337,6342,6344,6347,6348,6375,6378,6379,6380,6381,6382,6383,6386,6387,6388,6389,6390,6391,6393,6394,6395,6396,6397,6398,6399,6400,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428,6429,6430,6431,6432,6433,6454,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6517,6518,6519,6520,6521,6527,6528,6531,6536,6537,6538,6539,6540,6541,6542,6543,6545,6546,6547,6548,6549,6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,6565,6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605,6607,6608,6609,6610,6611,6612,6613,6614,6615,6616,6617,6622,6660,6663,6716,7084,7085,7086,7090,7091,7092,7108,7109,7110,7111,7112,7113,7288,7330,7331,7332,7350,7351,7353,7354,7355,7356,7357,7360,7363,7364,7366,7367,7368,7369,7370,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,7418,7419,7420,7421,7422,7423,7424,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439,7440,7441,7443,7444,7445,7446,7447,7448,7449,7450,7453,7454,7455,7456,7457,7458,7459,7460,7461,7462,7463,7465,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492,7493,7494,7495,7496,7517,7518,7519,7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7552,7553,7554,7555,7556,7557,7558,7608,7609,7610,7611,7734,7909,7910,7975,7989,7990,7992,7993,8006,8029,8080,8081,8082,8083,8084,8085,8086,8106,8107,8108,8109,8110,8111,8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127,8128,8129,8130,8131,8132,8133,8134,8135,8137,8138,8139,8140,8141,8142,8143,8144,8156,8157,8158,8159,8160,8161,8162,8163,8177,8178,8179,8180,8182,8183,8184,8186,8188,8190,8194,8196,8199,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255,8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271,8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,8315,8316,8317,8318,8319,8320,8386,8387,8389,8390,8746,8747,8748,8749,8750,8751,8752,8753,8754,8755,9285,9286,9287,9288,9289,9290,9291,9292,9293,9295,9297,9298,9359,9385,9395,9402,9405,9433,9434,9435,9742,9743,9744,9745,9746,9747,9748,9749,9750,9751,9752,9753,9754,9755,9756,9757,9758,9759,9760,9761,9762,9763,9764,9765,9766,9767,9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,9778,9779,9780,9781,9782,9783,9784,9785,9786,9787,9788,9789,9790,9791,9792,9793,9794,9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,9810,9811,9812,9813,9814,9815,9816,9817,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,9833,9834,9835,9836,9837,9838,9839,9840,9841,9842,9843,9844,9845,9846,9847,9848,9849,9850,9851,9852,9853,9854,9855,9856,9857,9858,9859,9860,9861,9862,9863,9864,9865,9866,9867,9868,9869,9870,9871,9872,9873,9874,9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885,9886,9887,9889,9890,9891,9892,9893,9894,9895,9896,9897,9898,9899,9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,9915,9916,9917,9918,9919,9920,9921,9922,9923,9924,9925,9926,9927,9928,9929,9930,9931,9932,9933,9934,9935,9936,9937,9938,9939,9940,9941,9942,9943,9944,9945,9946,9947,9948,9949,9950,9951,9952,9953,9954,9955,9956,9957,9958,9959,9960,9961,9962,9963,9964,9965,9966,9967,9968,9969,9970,9971,9972,9973,9974,10057,10058,10059,10060,10061,10062,10063,10064,10065,10066,10067,10068,10069,10070,10071,10072,10073,10074,10075,10076,10077,10078,10079,10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090,10091,10092,10093,10094,10095,10096,10097,10098,10099,10100,10101,10102,10103,10104,10105,10106,10107,10108,10109,10110,10111,10112,10113,10118,10119,10120,10121,10122,10123,10124,10125,10126,10127,10128,10129,10130,10131,10132,10133,10134,10135,10136,10137,10138,10139,10140,10141,10142,10143,10144,10145,10146,10147,10148,10149,10150,10151,10152,10153,10154,10155,10156,10157,10158,10159,10160,10161,10162,10163,10164,10165,10166,10167,10168,10169,10170,10171,10172,10173,10174,10175,10176,10177,10178,10179,10180,10181,10182,10183,10184,10185,10186,10187,10188,10189,10190,10191,10192,10193,10194,10195,10196,10197,10198,10199,10200,10201,10202,10203,10204,10205,10206,10207,10208,10209,10210,10211,10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10225,10226,10227,10228,10229,10230,10231,10232,10233,10234,10235,10236,10237,10238,10239,10240,10241,10242,10243,10244,10245,10246,10247,10248,10249,10250,10251,10252,10253,10254,10255,10256,10257,10258,10259,10260,10261,10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,10272,10273,10274,10275,10276,10277,10278,10279,10280,10281,10282,10287,10288,10289,10300,10301,10302,10305,10306,10307,10308,10309,10310,10312,10315,10316,10320,10362,10363,10364,10365,10366,10367,10368,10369,10370,10371,10372,10373,10374,10375,10376,10377,10378,10379,10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391,10404,10405,10406,10407,10408,10409,10424,10601,10603,10604,10606,11038,11039,11081,11098,11164,11165,11167,11168,11202,11204,11208,11224,11225,11226,11302,11732,11733,11734,11736,11737,11965,11967,11968,11969,11970,11971,11972,11973,11974,11975,11976,11977,11978,11979,11980,11981,11982,11983,11984,11985,11986,11987,11988,11989,11990,11991,11992,11993,11994,11995,11996,11997,11998,11999,12001,12002,12004,12005,12006,12007,12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12019,12020,12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,12032,12034,12035,12036,12039,12040,12042,12043,12044,12045,12046,12047,12048,12052,12053,12054,12055,12056,12057,12058,12261,12682,12683,12684,12685,12689,12691,12692,12974,12975,12976,12977,12978,12979,12982,12983,12984,12985,12987,12988,12989,12990,12992,12994,12996,12997,12998,12999,13000,13001,13002,13003,13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015,13016,13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,13028,13029,13030,13031,13032,13033,13034,13035,13036,13037,13038,13039,13040,13041,13042,13043,13044,13045,13046,13047,13048,13049,13051,13052,13053,13054,13055,13056,13057,13058,13059,13060,13062,13063,13064,13065,13066,13067,13068,13070,13071,13072,13073,13074,13075,13076,13077,13079,13081,13082,13083,13084,13085,13087,13088,13089,13091,13093,13094,13095,13096,13097,13099,13100,13101,13102,13103,13105,13106,13107,13108,13109,13110,13111,13112,13113,13114,13115,13116,13117,13118,13119,13120,13121,13122,13123,13124,13125,13126,13127,13128,13129,13130,13131,13132,13133,13134,13135,13136,13137,13138,13139,13144,13145,13146,13199,13443,13444,13446,13486,13487,13488,13489,13816,13817,13818,13819,13820,13821,13822,13823,13824,13825,14025,14086,14087,14088,14089,14090,14091,14093,14094,14095,14096,14097,14098,14099,14102,14109,14110,14113,14114,14115,14116,14117,14119,14120,14121,14122,14123,14124,14125,14126,14127,14129,14131,14133,14157,14158,14159,14160,14161,14162,14163,14164,14165,14166,14167,14168,14169,14170,14171,14172,14173,14174,14175,14176,14177,14178,14179,14180,14181,14182,14183,14184,14185,14186,14187,14188,14189,14190,14191,14192,14193,14194,14195,14196,14197,14198,14199,14200,14201,14202,14203,14204,14205,14206,14207,14208,14209,14210,14211,14212,14213,14214,14215,14216,14217,14218,14219,14220,14221,14222,14223,14224,14225,14226,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14238,14239,14240,14241,14242,14243,14244,14245,14246,14247,14248,14249,14250,14251,14252,14253,14254,14255,14257,14258,14259,14260,14261,14262,14263,14264,14265,14266,14267,14268,14269,14270,14271,14272,14273,14274,14275,14276,14277,14278,14279,14280,14281,14282,14283,14284,14285,14286,14287,14288,14289,14290,14291,14292,14293,14294,14295,14296,14297,14298,14299,14300,14301,14302,14303,14304,14305,14306,14307,14308,14309,14310,14311,14312,14313,14314,14315,14316,14317,14318,14319,14320,14321,14322,14323,14324,14325,14326,14327,14328,14329,14330,14331,14332,14333,14334,14335,14336,14337,14364,14365,14366,14367,14368,14369,14370,14371,14372,14373,14374,14375,14376,14377,14378,14379,14380,14397,14398,14399,14400,14401,14402,14403,14404,14405,14406,14407,14408,14409,14410,14411,14412,14413,14414,14415,14416,14417,14418,14419,14420,14421,14422,14423,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14434,14435,14436,14437,14438,14439,14440,14441,14442,14443,14444,14445,14446,14447,14448,14449,14450,14451,14452,14453,14454,14455,14456,14457,14458,14459,14460,14461,14462,14463,14464,14465,14466,14467,14470,14474,14478,14479,14484,14549,14551,14552,14553,14554,14555,14557,14558,14559,14560,14561,14562,14563,14564,14565,14566,14567,14568,14569,14570,14571,14572,14573,14574,14578,14579,14580,14581,14582,14583,14584,14585,14587,14588,14589,14590,14591,14592,14593,14594,14595,14596,14598,14599,14600,14601,14602,14603,14604,14605,14606,14607,14608,14652,14653,14654,14655,14656,14657,14658,14659,14660,14661,14662,14663,14664,14665,14666,14667,14668,14669,14670,14671,14672,14673,14674,14675,14676,14677,14678,14680,14681,14682,14683,14684,14685,14686,14687,14688,14722,14723,14724,14725,14726,14727,14728,14729,14730,14742,14743,14744,14745,14746,14747,14748,14749,14750,14751,14752,14753,14754,14755,14756,14757,14758,14759,14760,14761,14762,14763,14764,14765,14766,14767,14768,14769,14770,14771,14772,14773,14774,14775,14776,14777,14778,14779,14780,14781,14782,14783,14784,14785,14786,14787,14788,14789,14790,14791,14792,14793,14794,14795,14796,14797,14798,14799,14800,14801,14802,14803,14804,14805,14806,14807,14808,14809,14810,14811,14812,14813,14814,14815,14816,14817,14821,14825,14826,14827,14828,14829,14830,14831,14832,14833,14834,14835,14838,14839,14840,14841,14842,14843,14844,14846,14847,14848,14849,14850,14851,14852,14853,14854,14855,14856,14857,14858,14859,14860,14861,14862,14863,14864,14865,14866,14867,14868,14869,14895,14896,14897,14898,14899,14900,14901,14902,14903,14904,14905,14906,14907,14908,14909,14910,14911,14912,14913,14914,14915,14916,14917,14918,14919,14920,14921,14922,14923,14924,14925,14926,14927,14928,14929,14930,14931,14932,14933,14934,14935,14936,14937,14938,14939,14940,14941,14942,14943,14944,14945,14946,14947,14948,14949,14950,14951,14952,14953,14954,14955,14956,14957,14958,14959,14960,14961,14962,14963,14964,14965,14966,14967,14968,14969,14970,14971,14972,14973,14974,14975,14976,14977,14978,14979,14980,14981,14982,14983,15003,15004,15005,15006,15007,15008,15009,15010,15011,15012,15013,15014,15015,15016,15017,15018,15019,15110,15111,15112,15113,15114,15115,15116,15117,15118,15119,15120,15121,15122,15123,15124,15125,15126,15127,15128,15129,15130,15131,15132,15133,15134,15135,15136,15137,15139,15140,15142,15143,15144,15145,15146,15147,15148,15149,15150,15151,15152,15153,15154,15155,15156,15157,15158,15159,15160,15161,15162,15163,15164,15165,15166,15167,15168,15169,15170,15171,15172,15173,15174,15175,15176,15177,15178,15179,15180,15181,15182,15183,15184,15185,15186,15187,15188,15189,15190,15191,15192,15193,15194,15195,15210,15211,15212,15213,15214,15215,15216,15217,15218,15219,15220,15221,15222,15223,15224,15225,15226,15227,15228,15229,15230,15231,15232,15233,15234,15235,15236,15237,15238,15239,15240,15241,15242,15243,15244,15245,15246,15247,15248,15249,15250,15251,15252,15253,15254,15255,15256,15257,15258,15259,15260,15261,15262,15263,15264,15265,15266,15267,15268,15269,15270,15271,15272,15273,15274,15275,15276,15278,15279,15280,15281,15282,15283,15284,15285,15286,15287,15288,15289,15291,15294,15295,15296,15297,15298,15299,15300,15301,15302,15303,15304,15305,15306,15307,15308,15309,15310,15311,15312,15313,15322,15323,15324,15325,15329,15330,15331,15332,15333,15334,15336,15337,15338,15339,15340,15341,15342,15343,15344,15345,15346,15347,15348,15349,15350,15351,15352,15353,15354,15355,15356,15357,15358,15359,15360,15361,15362,15363,15364,15365,15366,15367,15368,15369,15370,15371,15372,15373,15374,15375,15376,15377,15378,15379,15380,15381,15382,15383,15384,15385,15386,15387,15388,15389,15390,15391,15392,15393,15394,15395,15425,15426,15427,15428,15429,15430,15431,15432,15433,15434,15435,15436,15437,15438,15439,15440,15441,15442,15472,15473,15474,15475,15476,15477,15478,15479,15480,15481,15482,15483,15484,15485,15486,15487,15488,15489,15490,15491,15492,15493,15494,15495,15496,15497,15498,15499,15500,15501,15502,15503,15504,15505,15506,15507,15508,15509,15510,15511,15512,15513,15514,15515,15516,15517,15518,15519,15520,15521,15522,15523,15524,15525,15526,15527,15528,15529,15530,15531,15532,15533,15534,15535,15536,15537,15538,15539,15540,15541,15542,15543,15544,15545,15546,15547,15548,15549,15550,15551,15552,15553,15554,15555,15556,15557,15558,15559,15560,15561,15562,15563,15565,15566,15567,15568,15569,15570,15571,15572,15573,15574,15575,15576,15577,15578,15579,15580,15581,15582,15583,15584,15589,15590,15591,15592,15593,15594,15595,15596,15597,15598,15599,15600,15601,15602,15603,15604,15605,15606,15607,15608,15609,15610,15611,15612,15613,15614,15615,15616,15617,15618,15619,15620,15621,15622,15623,15624,15625,15626,15627,15628,15629,15630,15631,15632,15633,15634,15635,15636,15637,15638,15639,15640,15641,15642,15643,15644,15645,15646,15647,15648,15649,15650,15651,15652,15653,15654,15655,15656,15657,15658,15659,15660,15661,15662,15663,15664,15665,15666,15667,15668,15669,15670,15671,15672,15673,15674,15675,15676,15677,15678,15679,15680,15681,15682,15683,15684,15685,15686,15687,15693,15694,15731,15737,15887,15890,15891,15892,15893,15894,15895,15912,15918,15925,15926,15927,15928,15929,15930,15931,15932,15933,15934,15935,15936,15937,15938,15939,15940,15941,15942,15943,15944,15945,15946,15947,15962,15963,15964,15965,15966,15967,15968,15969,15970,15971,15972,15973,15974,15975,15976,15977,15978,15979,15980,15981,15982,15983,15984,15985,15986,15987,15988,15989,15990,15991,16043,16044,16215,16218,16220,16253,17007,17413,17414,17682,17683,18600,19230,19231,19232,19233,19234,19235,19236,19259,19260,19261,19262,19263,19264,19265,19269,19270,19271,19272,19273,19274,19275,19278,19279,19280,19281,19282,19283,19284,20974,20976,21002,21003,21004,21005,21006,21007,21008,21009,21010,21011,21012,21013,21014,21015,21016,21017,21018,21019,21020,21021,21022,21940,21944,21945,21947,21949,22146,22153,22393,22532,22540,22541,22542,22548,22553,22557,22558,22829,22832,22890,22891,22903,22904,22912,22913,22914,22919,22926,23154,23197,23199,23203,23620,23621,23622,23623,23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635,23636,23637,23802,23804,23810,23883,23884,24163,24164,24165,24166,24167,24168,24169,24170,24171,24192,24193,24194,24195,24196,24197,24198,24199,24200,24201,24202,24203,24204,24205,24206,24207,24209,24210,24211,24212,24213,24214,24215,24216,24217,24218,24219,24220,24222,24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307,24575,24576,24577,24578,24580,24582,24583,24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595,24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607,24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619,24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631,24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643,24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655,24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667,24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679,24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691,24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703,24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715,24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727,24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739,24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751,24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763,24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775,24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787,24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799,24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811,24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823,24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835,24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847,24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859,24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871,24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895,24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907,24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919,24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931,24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943,24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979,24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991,24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003,25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015,25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027,25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039,25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087,25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099,25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111,25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123,25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135,25136,25137,25138,25139,25140,25141,25142,25143,25144,25146,25147,25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171,25172,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183,25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195,25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207,25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219,25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231,25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243,25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255,25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267,25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279,25280,25281,25282,25283,25284,25286,25287,25288,25289,25290,25291,25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303,25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315,25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327,25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339,25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351,25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363,25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375,25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387,25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399,25400,25401,25402,25403,25404,25405,25406,25887,25905,25906,25907,25909,27498,27499,27500,27501,27502,27503,28270,28279,28280,28531,28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543,28544,29549,29550,29714,29723,29724,29725,29726,29727,29728,29729,29730,29731,29732,29733,29734,31125,31126,31127,31131,31133,31134,31136,31137,31138,31139,31140,31142,31143,31145,31147,31148,31149,31150,31151,31152,31153,31173,31175,31178,31180,31186,31187,31190,31193,31196,31200,31202,31204,31222,31226,31230,31234,31237,31240,31255,31258,31272,31275,31276,31277,31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291,31292,31293,31294,31295,31297,31298,31299,31303,31304,31305,31306,31308,31318,31319,31320,31321,31322,31323,31326,31328,31329,31330,31331,31332,31333,31334,31335,31336,31338,31339,31340,31342,31343,31501,31557,31565,31573,31581,31837,31875,31876,31877,31878,31879,31883,31884,31885,31886,31887,31888,31889,31893,31894,31895,31896,31898,31899,31900,31902,31903,31904,31905,31906,31908,31909,31911,31912,31913,31915,31916,31917,31918,31925,31926,31927,31928,31929,31935,31936,31937,31938,31939,31940,31943,31952,32411,32520,33186,33457,33458,33459,33460,33461,33462,33954,15742,12684,14467,14466,12685,14470,16043,16215,21949,16044,14474,12689,12691,16218,15731,14478,14479,12692,13486,15737,13488,14484,13489,16220,13487,12693,12694,15746,15745,15743,13490,14489,12695,14492,16051,13492,13493,14491,12697,15755,14494,15757,14498,12702,16245,13518,15765,12704,16055,14499,16251,12713,14504,14506,14508,16253,12703,12711,14501,14507,12716,14509,14510,12717,22388,14511,12720,12728,22390,22389,4415,7452,4301,8384,10608,8028,21953,12698,14497) +AND `Reference` = 0; + +-- References +-- SELECT +-- `Reference`, +-- COUNT(*) AS `Occurrences`, +-- MIN(`Chance`) AS `MinChance`, +-- MAX(`Chance`) AS `MaxChance`, +-- -- Optional: If your core has comments in this table, show one to help ID it +-- MAX(`Comment`) AS `SampleComment` +-- FROM +-- `creature_loot_template` +-- WHERE +-- `Entry` IN ( /* ... */ ) +-- AND `Reference` < 1000000 +-- GROUP BY +-- `Reference` +-- ORDER BY +-- `Occurrences` DESC; +DELETE FROM `creature_loot_template` WHERE +`Entry` IN (3,30,36,40,43,46,48,60,61,79,92,94,95,97,98,99,100,113,114,115,116,117,118,119,121,122,123,124,125,126,127,154,157,171,199,202,203,205,206,210,212,213,215,217,218,232,285,300,315,327,330,345,390,391,397,422,423,424,426,428,429,430,431,432,433,434,435,436,437,440,441,442,445,446,449,452,453,454,456,458,462,471,472,473,474,475,476,478,480,481,485,500,501,502,503,504,505,506,507,511,513,515,517,518,519,520,521,524,525,533,534,539,544,545,547,548,550,565,568,569,570,572,573,574,578,579,580,584,587,588,589,590,594,595,596,597,598,599,604,615,616,619,622,623,624,625,626,628,634,636,641,657,660,667,669,670,671,672,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,694,696,697,699,701,702,703,709,710,711,712,723,728,729,730,732,735,736,740,741,742,743,744,745,746,747,750,751,752,754,755,757,759,760,761,762,763,764,765,766,767,768,769,771,772,780,781,782,783,784,785,787,813,814,818,819,822,824,830,831,832,833,834,846,854,855,856,858,861,862,863,864,865,868,871,873,875,877,879,880,881,889,891,892,898,905,909,910,920,921,922,923,930,937,938,939,940,941,942,943,947,948,949,950,976,977,978,979,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1051,1052,1053,1054,1057,1059,1061,1062,1063,1065,1069,1081,1082,1083,1084,1085,1087,1088,1094,1095,1096,1097,1106,1108,1109,1110,1111,1112,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1137,1138,1140,1142,1144,1150,1151,1152,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1169,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1183,1184,1185,1186,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1199,1201,1202,1205,1206,1207,1211,1216,1222,1224,1225,1236,1251,1258,1259,1260,1270,1353,1364,1388,1393,1397,1398,1399,1400,1417,1418,1424,1425,1426,1487,1488,1489,1490,1491,1520,1522,1523,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1543,1544,1545,1547,1548,1549,1550,1551,1552,1553,1554,1555,1557,1558,1559,1561,1562,1563,1564,1565,1653,1654,1655,1656,1657,1658,1660,1662,1664,1665,1674,1675,1689,1693,1706,1707,1708,1711,1713,1715,1720,1725,1726,1727,1729,1731,1732,1753,1754,1765,1766,1767,1768,1769,1770,1772,1773,1778,1779,1780,1781,1782,1783,1784,1785,1787,1788,1789,1791,1793,1794,1795,1796,1797,1802,1804,1806,1808,1809,1812,1813,1815,1816,1817,1821,1822,1824,1826,1827,1831,1832,1833,1834,1835,1837,1844,1845,1847,1848,1851,1865,1866,1867,1868,1869,1870,1883,1884,1885,1888,1889,1891,1894,1895,1907,1908,1909,1910,1911,1912,1913,1914,1915,1920,1922,1923,1924,1934,1935,1936,1939,1940,1941,1942,1943,1944,1947,1948,1953,1954,1955,1956,1957,1958,1961,1971,1972,1973,1974,1983,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2017,2018,2019,2020,2021,2022,2025,2027,2029,2030,2033,2034,2038,2039,2042,2043,2053,2054,2069,2070,2071,2089,2090,2091,2102,2103,2106,2108,2120,2152,2156,2157,2162,2163,2164,2165,2166,2167,2168,2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,2185,2186,2187,2189,2190,2191,2192,2201,2202,2203,2204,2205,2206,2207,2208,2212,2231,2232,2233,2234,2235,2236,2237,2240,2241,2242,2243,2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,2260,2261,2264,2265,2266,2267,2268,2269,2270,2271,2272,2283,2287,2304,2305,2306,2318,2319,2320,2321,2322,2323,2324,2332,2335,2336,2337,2338,2339,2344,2345,2346,2347,2348,2349,2350,2351,2354,2356,2358,2359,2360,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2384,2385,2387,2403,2404,2406,2407,2408,2411,2412,2413,2414,2415,2416,2420,2421,2422,2423,2427,2428,2431,2440,2448,2449,2450,2451,2452,2453,2473,2474,2476,2503,2505,2521,2522,2529,2530,2534,2535,2536,2537,2541,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2569,2570,2571,2572,2573,2574,2575,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,2589,2590,2591,2592,2595,2596,2597,2599,2600,2603,2604,2605,2606,2607,2609,2611,2612,2618,2619,2628,2635,2636,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2680,2681,2686,2691,2692,2693,2694,2701,2714,2715,2716,2717,2718,2719,2720,2723,2725,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2738,2739,2740,2742,2743,2744,2751,2752,2753,2760,2761,2762,2764,2765,2773,2779,2780,2781,2782,2783,2791,2793,2817,2829,2830,2831,2850,2892,2893,2894,2906,2907,2923,2924,2925,2926,2927,2928,2929,2932,2944,2945,2949,2950,2951,2956,2957,2958,2959,2960,2962,2963,2964,2965,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,2989,2990,3035,3051,3056,3058,3068,3094,3099,3100,3103,3104,3105,3106,3107,3108,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3125,3126,3127,3128,3129,3130,3131,3141,3192,3195,3196,3197,3198,3199,3203,3204,3205,3206,3207,3225,3226,3227,3228,3231,3232,3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,3249,3250,3251,3252,3253,3254,3255,3256,3258,3260,3261,3263,3265,3266,3267,3268,3269,3271,3272,3273,3274,3275,3276,3277,3278,3279,3280,3282,3283,3284,3285,3286,3295,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3392,3393,3394,3396,3397,3414,3415,3416,3424,3425,3426,3434,3435,3436,3438,3445,3452,3454,3455,3456,3457,3458,3459,3461,3463,3465,3466,3467,3470,3471,3472,3473,3474,3476,3503,3528,3530,3532,3535,3566,3577,3578,3586,3630,3631,3632,3633,3634,3636,3637,3638,3640,3641,3652,3655,3660,3662,3664,3667,3672,3696,3711,3712,3713,3715,3717,3721,3725,3727,3728,3730,3732,3733,3734,3735,3736,3737,3739,3740,3742,3743,3745,3746,3748,3749,3750,3752,3754,3755,3757,3758,3759,3762,3763,3765,3767,3770,3771,3772,3773,3774,3780,3781,3782,3783,3784,3789,3791,3792,3797,3801,3802,3803,3804,3806,3807,3808,3809,3810,3811,3812,3814,3815,3816,3817,3818,3819,3820,3821,3823,3824,3825,3833,3834,3840,3851,3853,3854,3855,3857,3859,3861,3862,3863,3864,3866,3868,3872,3873,3875,3877,3917,3919,3921,3922,3923,3924,3925,3926,3928,3931,3932,3940,3941,3942,3943,3944,3947,3986,3987,3988,3989,3991,3992,3993,3999,4003,4004,4005,4006,4007,4008,4009,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4034,4035,4036,4037,4038,4040,4041,4042,4044,4050,4051,4052,4053,4054,4056,4057,4061,4062,4063,4064,4065,4066,4067,4070,4073,4074,4093,4094,4095,4096,4097,4099,4100,4101,4104,4107,4109,4110,4111,4112,4114,4116,4117,4118,4119,4120,4124,4126,4127,4128,4129,4130,4131,4132,4133,4139,4140,4142,4143,4144,4147,4150,4151,4154,4158,4202,4248,4249,4250,4260,4273,4280,4281,4282,4283,4284,4285,4286,4287,4288,4289,4290,4291,4292,4294,4295,4296,4297,4298,4299,4300,4301,4302,4303,4304,4306,4308,4316,4323,4324,4328,4329,4331,4334,4341,4343,4344,4345,4346,4347,4348,4351,4352,4356,4357,4359,4361,4362,4363,4376,4378,4379,4380,4382,4385,4387,4388,4389,4390,4393,4394,4397,4401,4403,4404,4409,4412,4414,4415,4416,4417,4418,4425,4427,4435,4436,4437,4438,4440,4442,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,4467,4468,4469,4472,4474,4475,4479,4480,4481,4493,4494,4499,4505,4506,4512,4514,4515,4516,4517,4518,4519,4520,4522,4523,4525,4530,4531,4532,4538,4539,4540,4541,4548,4619,4623,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,4644,4645,4646,4647,4648,4649,4651,4652,4653,4654,4655,4656,4657,4658,4659,4662,4663,4664,4665,4666,4667,4668,4670,4671,4672,4673,4674,4675,4676,4677,4678,4679,4680,4681,4682,4684,4685,4692,4693,4694,4695,4696,4697,4699,4700,4701,4702,4705,4711,4712,4713,4714,4715,4716,4718,4719,4723,4726,4727,4728,4729,4787,4788,4789,4798,4799,4802,4803,4805,4807,4809,4810,4811,4812,4813,4814,4815,4818,4819,4820,4821,4822,4823,4824,4825,4827,4834,4841,4842,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,4855,4856,4857,4860,4861,4863,4872,5048,5053,5055,5056,5057,5085,5086,5184,5224,5225,5226,5228,5229,5232,5234,5235,5236,5237,5238,5239,5240,5241,5243,5244,5245,5246,5247,5249,5251,5253,5254,5255,5256,5258,5259,5260,5261,5262,5263,5267,5268,5269,5270,5271,5272,5273,5274,5277,5278,5280,5283,5286,5287,5288,5291,5292,5293,5295,5296,5297,5299,5300,5304,5305,5306,5307,5308,5327,5328,5331,5332,5333,5334,5335,5336,5337,5343,5345,5346,5347,5349,5350,5352,5354,5356,5362,5363,5364,5366,5399,5400,5401,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430,5431,5441,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461,5462,5465,5471,5472,5473,5474,5475,5477,5481,5485,5490,5600,5601,5602,5615,5616,5617,5618,5622,5643,5645,5646,5647,5648,5649,5650,5682,5683,5708,5755,5756,5761,5771,5786,5787,5807,5808,5809,5823,5826,5829,5832,5833,5834,5835,5836,5837,5838,5839,5840,5843,5844,5846,5847,5848,5849,5850,5852,5853,5854,5855,5856,5857,5858,5860,5861,5862,5863,5865,5881,5912,5928,5933,5974,5975,5976,5977,5978,5979,5982,5983,5984,5985,5988,5990,5991,5992,5993,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6020,6033,6035,6068,6072,6073,6093,6113,6115,6116,6117,6118,6123,6124,6125,6126,6127,6128,6132,6133,6135,6136,6137,6138,6140,6167,6170,6184,6185,6186,6187,6188,6189,6190,6193,6194,6195,6196,6198,6199,6200,6201,6202,6206,6207,6208,6210,6211,6212,6213,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6230,6231,6232,6233,6234,6329,6347,6348,6349,6350,6351,6352,6369,6370,6371,6372,6375,6377,6378,6379,6380,6391,6392,6407,6466,6488,6489,6490,6494,6497,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6516,6517,6518,6519,6520,6521,6523,6527,6547,6551,6552,6553,6554,6555,6556,6557,6559,6570,6581,6582,6585,6606,6647,6648,6649,6650,6651,6652,6668,6733,6788,6789,6846,6909,6927,7011,7012,7015,7016,7017,7022,7023,7025,7026,7027,7028,7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043,7044,7045,7046,7047,7048,7049,7053,7055,7076,7077,7078,7079,7086,7092,7093,7097,7098,7099,7100,7101,7105,7106,7107,7109,7110,7111,7112,7113,7114,7115,7118,7120,7125,7126,7132,7136,7138,7139,7149,7153,7154,7155,7156,7157,7158,7175,7206,7234,7235,7246,7247,7268,7269,7274,7290,7309,7318,7319,7320,7321,7327,7328,7329,7332,7333,7334,7335,7337,7341,7342,7344,7345,7346,7347,7348,7352,7353,7354,7357,7358,7369,7371,7372,7376,7379,7396,7397,7404,7405,7430,7431,7432,7433,7434,7438,7439,7440,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7523,7524,7584,7603,7668,7669,7670,7671,7725,7726,7727,7728,7847,7855,7856,7857,7858,7864,7872,7873,7874,7883,7885,7886,7895,7977,7995,7996,8095,8120,8136,8201,8202,8203,8204,8205,8207,8208,8210,8211,8212,8213,8214,8216,8218,8219,8236,8277,8278,8279,8280,8281,8283,8296,8297,8298,8299,8300,8301,8302,8303,8304,8311,8318,8319,8384,8400,8408,8409,8419,8447,8503,8518,8519,8520,8521,8522,8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8534,8535,8538,8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8550,8551,8553,8555,8556,8557,8558,8560,8561,8562,8563,8564,8565,8566,8596,8597,8598,8600,8601,8602,8603,8605,8606,8607,8636,8637,8660,8667,8675,8759,8760,8761,8762,8763,8764,8766,8837,8886,8891,8892,8893,8894,8895,8896,8897,8898,8899,8900,8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,8915,8916,8917,8920,8921,8922,8923,8924,8956,8957,8958,8959,8960,8961,8977,8978,8979,8981,9024,9041,9042,9043,9044,9045,9046,9096,9097,9098,9162,9163,9164,9165,9166,9167,9176,9197,9198,9199,9200,9201,9216,9217,9218,9219,9239,9240,9241,9257,9258,9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9318,9336,9377,9396,9397,9416,9454,9462,9464,9517,9518,9545,9547,9554,9583,9596,9602,9604,9622,9690,9691,9692,9693,9694,9695,9696,9697,9698,9701,9716,9717,9718,9816,9817,9818,9819,9860,9861,9862,9877,9878,9879,9916,10077,10078,10080,10081,10082,10083,10157,10158,10159,10160,10177,10197,10199,10200,10221,10263,10316,10317,10318,10319,10323,10356,10357,10358,10359,10366,10371,10372,10374,10375,10376,10381,10382,10384,10385,10390,10391,10393,10398,10399,10400,10405,10406,10407,10408,10409,10411,10412,10413,10414,10416,10417,10418,10419,10420,10421,10422,10423,10424,10425,10426,10442,10447,10463,10464,10469,10470,10471,10472,10475,10476,10477,10478,10480,10481,10485,10486,10487,10488,10489,10491,10495,10498,10499,10500,10509,10558,10559,10580,10605,10608,10617,10639,10640,10641,10642,10643,10644,10647,10648,10659,10660,10661,10678,10738,10756,10757,10758,10759,10760,10761,10762,10801,10802,10806,10807,10809,10814,10816,10817,10821,10822,10823,10824,10825,10826,10827,10896,10899,10916,11043,11257,11290,11291,11318,11319,11320,11321,11322,11323,11324,11338,11339,11340,11350,11351,11352,11353,11356,11357,11359,11360,11361,11365,11368,11370,11371,11372,11373,11387,11388,11390,11391,11440,11441,11442,11443,11444,11445,11448,11450,11451,11452,11453,11454,11455,11456,11457,11458,11459,11461,11462,11464,11465,11467,11469,11470,11471,11472,11473,11475,11476,11477,11480,11483,11484,11516,11551,11552,11559,11561,11562,11563,11576,11577,11578,11582,11611,11613,11656,11658,11661,11662,11665,11666,11667,11668,11673,11680,11681,11682,11683,11684,11685,11686,11687,11688,11697,11698,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,11731,11732,11733,11734,11735,11736,11737,11738,11739,11740,11741,11744,11745,11746,11747,11777,11778,11781,11782,11784,11785,11786,11787,11788,11789,11790,11791,11792,11793,11794,11830,11831,11858,11873,11880,11881,11882,11883,11896,11897,11910,11911,11912,11913,11914,11915,11917,11918,11921,12037,12046,12076,12100,12101,12119,12178,12179,12199,12206,12216,12217,12218,12219,12220,12221,12222,12223,12224,12237,12248,12250,12262,12263,12322,12347,12387,12418,12431,12432,12433,12457,12459,12461,12463,12464,12465,12467,12468,12579,12676,12677,12678,12759,12856,12865,12896,12897,12902,13019,13021,13022,13036,13141,13142,13157,13160,13196,13197,13276,13285,13323,13533,13599,13996,14123,14221,14222,14223,14224,14225,14226,14227,14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14266,14268,14269,14270,14271,14272,14273,14276,14277,14278,14279,14280,14281,14303,14339,14340,14342,14343,14344,14345,14356,14398,14399,14400,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14446,14447,14448,14455,14458,14460,14462,14472,14476,14477,14478,14479,14487,14488,14490,14491,14492,14523,14532,14661,14750,14821,14825,14880,14882,14883,15043,15067,15111,15168,15201,15202,15213,15229,15230,15233,15235,15236,15240,15247,15249,15250,15262,15264,15277,15312,15318,15319,15320,15323,15324,15325,15327,15333,15335,15336,15338,15343,15355,15407,15408,15409,15461,15462,15505,15542,15635,15636,15637,15638,15641,15642,15643,15645,15647,15648,15649,15650,15651,15652,15654,15655,15656,15657,15658,15668,15670,15685,15692,15937,15949,15965,15966,15967,15968,16162,16247,16248,16249,16250,16294,16300,16301,16302,16303,16304,16305,16307,16308,16309,16310,16311,16313,16314,16315,16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327,16328,16330,16331,16332,16333,16334,16335,16337,16339,16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351,16352,16353,16354,16355,16402,16403,16404,16405,16469,17115,17183,17184,17185,17186,17187,17188,17189,17190,17191,17192,17193,17194,17195,17196,17197,17199,17200,17201,17202,17203,17210,17216,17217,17235,17236,17278,17279,17298,17300,17320,17321,17322,17323,17324,17325,17326,17327,17328,17329,17330,17331,17333,17334,17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347,17348,17349,17350,17352,17353,17358,17372,17373,17374,17447,17448,17475,17494,17496,17522,17523,17524,17525,17527,17528,17550,17556,17588,17589,17591,17604,17606,17607,17608,17661,17673,17683,17701,17702,17713,17714,17878,18241,23554,23555,23589,23590,23591,23592,23593,23594,23595,23620,23637,23714,23841,23873,24477,24818,24819,37214,37917,37984,38006,38016,38023) +AND `Reference` IN ( +24016, -- Occurrences: 232, Greens +24033, -- Occurrences: 225, Greens +24036, -- Occurrences: 214, Greys +24034, -- Occurrences: 184, Blues +24018, -- Occurrences: 180, Greens +24031, -- Occurrences: 179, Greens +24017, -- Occurrences: 176, Blues +24024, -- Occurrences: 165, Greys +24088, -- Occurrences: 159, Purples +24029, -- Occurrences: 150, Mess +24089, -- Occurrences: 149, Purples +24032, -- Occurrences: 134, Rares +24087, -- Occurrences: 133, Purples +24019, -- Occurrences: 126, Blues +24058, -- Occurrences: 102, Trash +24021, -- Occurrences: 100, Blues (Totem, Idol, Libram) +24090, -- Occurrences: 97, Purples +24086, -- Occurrences: 90, Purples +24030, -- Occurrences: 90, Blues +24064, -- Occurrences: 89, Greens +24027, -- Occurrences: 83, Greens +24045, -- Occurrences: 82, Greens +24039, -- Occurrences: 81, Greens +24066, -- Occurrences: 77, Greens +24041, -- Occurrences: 76, Greens +24043, -- Occurrences: 74, Greens +24068, -- Occurrences: 71, Greens +24062, -- Occurrences: 68, Greens +24025, -- Occurrences: 66, Greens +24020, -- Occurrences: 66, Greens +24037, -- Occurrences: 59, Mess +24060, -- Occurrences: 58, Mess +24054, -- Occurrences: 58, Greens +24085, -- Occurrences: 57, Purples +24050, -- Occurrences: 52, Greens +24078, -- Occurrences: 52, Greens +24047, -- Occurrences: 51, Mess +24082, -- Occurrences: 48, Purples +24052, -- Occurrences: 47, Mess o' Stuff +24056, -- Occurrences: 45, Greens +24028, -- Occurrences: 44, Rares +24065, -- Occurrences: 44, Rares +24044, -- Occurrences: 43, Rares +24077, -- Occurrences: 42, Greens +24081, -- Occurrences: 41, Purples +24042, -- Occurrences: 40, Rares +24063, -- Occurrences: 40, Rares +24083, -- Occurrences: 39, Purples +24059, -- Occurrences: 37, Greys +24084, -- Occurrences: 37, Purples +24046, -- Occurrences: 36, Rares +24080, -- Occurrences: 36, Purples +24067, -- Occurrences: 33, Rares +24069, -- Occurrences: 31, Rares +24070, -- Occurrences: 31, Greys + Tigerseye +24061, -- Occurrences: 30, Rares +24026, -- Occurrences: 27, Rares +24040, -- Occurrences: 26, Rares +24049, -- Occurrences: 21, Rares +24051, -- Occurrences: 19, Rares +24091, -- Occurrences: 19, Purples +24055, -- Occurrences: 17, Rares +24057, -- Occurrences: 16, Rares +24079, -- Occurrences: 13, Purples +24038, -- Occurrences: 12, Blues +24053, -- Occurrences: 12, Blues +24074, -- Occurrences: 8, Low-Level Greens +24075, -- Occurrences: 7, Low-Level Greens + Malachite +24076, -- Occurrences: 7, Whites +24071 -- Occurrences: 5, Greys + Malachite +); + +/* TBC: +Creatures to Edit: 1410,5355,7370,11980,12377,12378,12379,15547,15548,15551,16170,16171,16173,16174,16175,16176,16177,16178,16389,16406,16407,16408,16409,16410,16411,16412,16414,16415,16424,16425,16459,16460,16461,16468,16470,16471,16472,16473,16481,16482,16485,16488,16489,16491,16492,16504,16507,16519,16523,16525,16526,16529,16530,16539,16540,16544,16545,16595,16596,16769,16772,16805,16810,16943,16944,16945,16948,16949,16952,16992,17088,17128,17129,17130,17131,17132,17133,17134,17135,17136,17137,17138,17139,17141,17142,17143,17146,17147,17148,17149,17150,17151,17152,17153,17154,17155,17156,17157,17158,17159,17160,17356,17370,17400,17401,17724,17725,17726,17727,17728,17729,17730,17731,17732,17734,17735,17771,17799,17814,17815,17816,17817,17840,17895,17897,17898,17899,17905,17906,17907,17908,17916,17938,17940,17952,17957,17958,17959,17960,17961,17962,17963,17964,17981,17993,17994,18033,18037,18043,18062,18064,18065,18145,18155,18182,18202,18203,18204,18205,18211,18220,18226,18238,18257,18258,18259,18260,18289,18290,18298,18309,18311,18312,18313,18315,18318,18319,18320,18321,18323,18325,18326,18327,18328,18331,18334,18352,18391,18404,18405,18411,18413,18419,18420,18421,18423,18437,18438,18440,18449,18450,18451,18452,18453,18454,18455,18456,18457,18460,18461,18463,18464,18465,18466,18467,18468,18469,18470,18476,18477,18493,18495,18498,18499,18500,18501,18503,18524,18533,18535,18536,18539,18540,18541,18548,18554,18556,18557,18558,18559,18567,18583,18585,18586,18587,18588,18595,18608,18631,18632,18633,18634,18635,18636,18637,18638,18639,18640,18641,18642,18647,18648,18658,18660,18661,18663,18670,18702,18707,18718,18720,18750,18794,18796,18848,18850,18852,18853,18855,18856,18857,18858,18859,18860,18864,18865,18866,18867,18869,18870,18872,18873,18875,18877,18879,18880,18881,18882,18883,18884,18885,18886,18963,18964,18974,18976,18982,18983,18996,19055,19166,19167,19183,19191,19201,19208,19209,19231,19307,19389,19428,19429,19453,19486,19494,19505,19507,19508,19509,19510,19511,19512,19513,19543,19544,19545,19546,19554,19557,19593,19595,19598,19608,19632,19633,19635,19641,19642,19643,19657,19705,19707,19712,19713,19716,19735,19738,19740,19744,19747,19754,19755,19756,19757,19759,19760,19762,19765,19767,19768,19779,19784,19788,19789,19792,19795,19796,19799,19800,19801,19802,19806,19823,19824,19825,19826,19827,19830,19831,19843,19847,19852,19853,19865,19881,19884,19885,19886,19887,19888,19889,19890,19891,19892,19902,19903,19904,19926,19940,19943,19944,19945,19948,19952,19957,19960,19961,19963,19973,19978,19979,19980,19982,19983,19984,19985,19986,19987,19988,19989,19990,19991,19992,19993,19994,19995,19996,19997,19998,20021,20031,20032,20033,20034,20035,20036,20037,20038,20039,20040,20041,20042,20043,20044,20045,20046,20048,20049,20050,20052,20058,20059,20095,20113,20132,20134,20135,20136,20138,20139,20140,20141,20161,20177,20179,20180,20181,20191,20192,20193,20202,20207,20210,20211,20215,20216,20221,20248,20255,20256,20258,20259,20260,20261,20265,20285,20326,20329,20330,20332,20334,20340,20394,20397,20404,20409,20410,20416,20427,20435,20452,20453,20454,20456,20458,20459,20474,20480,20483,20495,20496,20501,20502,20512,20514,20516,20554,20557,20600,20601,20606,20607,20609,20610,20611,20614,20634,20668,20671,20673,20680,20683,20684,20685,20713,20714,20723,20726,20727,20728,20729,20730,20731,20732,20747,20748,20749,20751,20753,20756,20757,20765,20766,20768,20770,20772,20773,20774,20775,20777,20778,20779,20783,20795,20800,20801,20803,20854,20857,20859,20864,20865,20866,20867,20868,20872,20873,20875,20878,20879,20881,20882,20883,20887,20888,20896,20897,20901,20902,20905,20906,20908,20909,20910,20911,20924,20925,20927,20928,20929,20930,20931,20934,20983,20987,20988,20990,20998,21004,21021,21022,21023,21032,21033,21042,21046,21047,21048,21050,21057,21058,21059,21060,21061,21065,21089,21102,21108,21123,21124,21126,21127,21164,21168,21171,21178,21179,21180,21181,21189,21196,21198,21200,21205,21218,21220,21221,21224,21225,21226,21227,21229,21230,21231,21232,21238,21242,21246,21249,21251,21254,21263,21284,21285,21287,21296,21298,21299,21300,21301,21302,21305,21309,21314,21315,21324,21325,21326,21337,21339,21350,21368,21370,21373,21380,21381,21382,21383,21384,21385,21386,21387,21389,21405,21408,21409,21416,21425,21450,21453,21454,21455,21462,21477,21478,21492,21499,21500,21501,21503,21505,21506,21516,21519,21520,21636,21637,21640,21644,21648,21649,21650,21651,21652,21656,21660,21661,21662,21663,21695,21696,21702,21709,21710,21711,21717,21718,21719,21720,21721,21722,21723,21724,21728,21730,21742,21743,21763,21767,21784,21787,21788,21795,21801,21802,21803,21804,21808,21809,21810,21815,21816,21817,21820,21821,21827,21839,21842,21843,21844,21849,21854,21863,21864,21878,21879,21891,21897,21901,21902,21904,21907,21911,21912,21923,21941,21956,21963,21979,21985,22011,22012,22016,22017,22018,22038,22044,22045,22052,22072,22076,22081,22082,22084,22093,22095,22099,22100,22105,22123,22132,22143,22144,22148,22160,22175,22180,22181,22182,22187,22194,22195,22199,22201,22202,22204,22217,22221,22241,22242,22243,22244,22252,22253,22254,22255,22257,22261,22262,22263,22265,22275,22281,22286,22287,22289,22291,22295,22297,22298,22303,22304,22305,22307,22308,22309,22310,22311,22313,22325,22327,22341,22342,22343,22357,22363,22378,22384,22387,22388,22392,22393,22394,22466,22482,22807,22825,22826,22827,22828,22844,22845,22846,22847,22853,22855,22869,22873,22874,22875,22876,22877,22878,22879,22880,22881,22882,22883,22884,22885,22939,22945,22946,22953,22954,22955,22956,22957,22959,22960,22962,22963,22964,22965,23008,23018,23020,23022,23026,23028,23029,23030,23047,23049,23061,23066,23067,23068,23153,23154,23161,23162,23163,23165,23169,23172,23174,23188,23196,23219,23222,23223,23232,23235,23236,23237,23239,23261,23264,23267,23269,23281,23282,23285,23286,23290,23305,23311,23324,23326,23330,23337,23339,23353,23354,23355,23374,23386,23390,23394,23400,23402,23403,23501,23542,23580,23581,23582,23584,23586,23596,23597,23774,23834,24043,24047,24059,24064,24065,24179,24180,24374,24530,24549,24684,24689,24696,24698,24762,24777,24922,24955,24960,24976,25001,25060,25073,25593,25595,25599,25867,38030 +1/4 Chance: 18212,21264,18207 + +Normal Non-Humanoid: 17128,17129,17130,17131,17132,17133,17952,18033,18205,18212,18220,18226,18289,18334,18437,18438,18461,18463,18464,18465,18466,18467,18468,18469,18470,18476,18477,18670,18750,18879,18880,18883,18884,18963,18964,18982,18983,18996,19183,19595,19598,19784,20058,20330,20502,20607,20610,20611,20634,20671,20673,20714,20728,20747,20748,20749,20751,20773,20775,20777,20783,20924,20925,20931,20987,20998,21022,21033,21042,21108,21123,21124,21373,21408,21462,21723,21802,21804,21816,21839,21854,21864,21879,21891,21897,21901,21956,22044,22052,22100,22105,22123,22132,22181,22182,22187,22255,22257,22265,22287,22807,22946,23020,23026,23169,23219,23264,23326,23501,24047,24064,24922,18877,20021,20332,20713,21004,21032,21387,21721,21722,21817,21820,21821,17153,17154,17155,17156,17157,17158,17159,17160,18062,18145,18587,18864,18865,18866,18867,18881,18882,19494,19557,19608,20514,20516,20774,20983,21023,21050,21059,21060,21061,21326,21696,21728,22095,22244,22286,22298,22307,22309,22310,22311,22313,20340,20501,20554,20668,20778,20865,21264,21305,21380,21381,21849,22194,22466,22482,23285,23286,23290 +Normal Humanoid: 21389,21492,16943,16944,16948,16949,16952,16992,17151,17401,17981,18641,18642,18660,18661,18663,18858,18859,18860,18869,18870,18974,18976,19716,19738,19740,19744,19754,19755,19756,19757,19759,19760,19799,19800,19801,19802,19852,19853,19960,19961,19973,19978,19979,19980,20141,20215,20285,20326,20394,20404,20427,20557,20680,20683,20685,20803,20887,20927,20928,20929,20930,21021,21287,21309,21314,21337,21499,21516,21519,21520,21656,21808,21827,21878,21923,21963,22180,22195,22201,22202,22204,22221,22289,22291,22304,22327,22392,22394,23174,23386,25001,7370,12377,12378,12379,16409,16468,16805,18043,18460,18498,18499,18500,18501,18503,18556,18557,18558,18559,18872,18873,19543,19544,19545,19546,19825,19826,19827,19881,20409,20410,20480,20495,20496,20512,20934,21058,21065,21198,21200,21324,21384,21385,21386,21450,21636,21651,21763,21784,21787,21788,21795,21815,21941,22045,23066,23067,23068,1410,5355,16519,16769,16772,16810,17088,17134,17135,17136,17137,17138,17139,17141,17142,17143,17146,17147,17148,17149,17150,17963,17964,18037,18064,18065,18202,18203,18204,18207,18211,18238,18260,18298,18352,18391,18413,18449,18450,18451,18452,18453,18454,18455,18456,18457,18539,18540,18541,18548,18554,18583,18595,18658,18718,18720,18850,18852,18853,18855,18857,18875,19453,19593,19635,19641,19642,19643,19657,19705,19707,19762,19765,19767,19768,19779,19788,19789,19792,19795,19796,19806,19830,19831,19902,19904,19926,19943,19944,19945,19948,19952,19957,19982,19983,19984,19985,19986,19987,19988,19989,19990,19991,19992,19993,19994,19995,19998,20095,20113,20134,20135,20136,20139,20140,20161,20207,20210,20211,20221,20248,20284,20329,20334,20397,20416,20435,20452,20453,20456,20458,20459,20474,20601,20606,20609,20614,20684,20723,20726,20727,20730,20731,20732,20753,20765,20766,20768,20770,20795,20854,20872,20878,21046,21047,21048,21057,21089,21179,21180,21189,21196,21238,21242,21254,21284,21285,21296,21300,21302,21368,21370,21382,21383,21405,21409,21416,21453,21454,21455,21477,21478,21503,21505,21637,21640,21644,21649,21650,21652,21660,21661,21662,21663,21709,21710,21711,21717,21718,21719,21720,21742,21743,21767,21803,21809,21810,21902,21907,21911,21912,21985,22016,22017,22018,22081,22082,22084,22099,22143,22144,22148,22160,22175,22217,22241,22242,22243,22252,22254,22261,22262,22263,22305,22308,22341,22342,22343,22363,22378,22384,22387,22388,23008,23153,23154,23188,23305,23311,23324,23586,24955,24960,24976,25060,25073,38030 + +Elite Non-Humanoid: 16170,16171,16173,16174,16175,16491,16492,17724,17731,17732,17840,18155,18257,18258,18259,18290,18647,18648,18707,19055,19428,19429,19513,19632,19865,20038,20039,20729,20906,21102,21246,21724,21904,22884,22885,23162,23163,23232,23267,23269,23584,23834,24043,24530,25867,21648,23061,23261,23281,23282,16488,16489,16529,16530,17725,18182,18856,20908,21181,21325,21695,21730,21863,22878,22881,22883,23029,17734,18885,18886,19823,19824,19940,20202,20772,21251,21844,22011,22275,23165,16485,16504,18405,19166,19735,20040,20041,22295,23394,24777,16595,16596,17356,20779,20864,22038 +Elite Humanoid: 20910,20911,22072,22253,16176,16177,16178,16461,16539,16945,17152,17400,17908,17916,18535,18536,18567,18796,18848,19191,19231,19307,19511,19512,19554,19712,19713,19747,19843,19847,19963,20052,20132,20138,20265,20800,20801,20866,20867,20868,20873,20875,20879,20881,20882,20883,20888,20901,20902,20905,21249,21500,21501,21506,22281,22297,22303,22325,22357,22825,22827,22828,22853,22855,22869,22954,22956,22957,22962,22964,23230,23337,23339,23353,23354,23355,25593,25595,25599,15547,15548,15551,16389,16406,16407,16408,16410,16411,16412,16414,16415,16424,16425,16459,16460,16470,16471,16472,16473,16481,16482,16525,16526,17895,17897,17898,17905,17906,17907,18319,18320,18327,18524,18588,20483,21801,21838,22953,23161,11980,16507,16523,16540,16544,16545,17370,17726,17727,17728,17729,17730,17735,17771,17799,17814,17815,17816,17817,17899,17938,17940,17957,17958,17959,17960,17961,17962,17993,17994,18309,18311,18312,18313,18315,18318,18321,18323,18325,18326,18328,18331,18404,18411,18419,18420,18421,18423,18440,18493,18495,18533,18585,18586,18608,18631,18632,18633,18634,18635,18636,18637,18638,18639,18640,18702,18794,19167,19201,19208,19209,19389,19486,19505,19507,19508,19509,19510,19633,19884,19885,19886,19887,19888,19889,19890,19891,19892,19903,19996,19997,20031,20032,20033,20034,20035,20036,20037,20042,20043,20044,20045,20046,20048,20049,20050,20059,20177,20179,20180,20181,20191,20192,20193,20216,20255,20256,20258,20259,20260,20261,20454,20600,20756,20757,20857,20859,20896,20897,20909,20988,20990,21126,21127,21164,21168,21171,21178,21205,21218,21220,21221,21224,21225,21226,21227,21229,21230,21231,21232,21263,21298,21299,21301,21315,21339,21350,21425,21702,21842,21843,21979,22012,22076,22093,22199,22393,22826,22844,22845,22846,22847,22873,22874,22875,22876,22877,22879,22880,22882,22939,22945,22955,22959,22960,22963,22965,23018,23022,23028,23030,23047,23049,23172,23196,23222,23223,23235,23236,23237,23239,23330,23374,23390,23400,23402,23403,23542,23580,23581,23582,23596,23597,23774,24059,24065,24179,24180,24374,24549,24684,24689,24696,24698,24762 + +Items Affected: 5760,13444,13446,16253,22146,22153,22532,22540,22541,22542,22548,22553,22557,22558,22829,22832,22903,22904,22912,22913,22914,22919,22926,23154,23620,23621,23622,23623,23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635,23636,23637,23802,23804,23810,23883,23884,24163,24164,24165,24166,24167,24168,24169,24170,24171,24192,24193,24194,24195,24196,24197,24198,24199,24200,24201,24202,24203,24204,24205,24206,24207,24209,24210,24211,24212,24213,24214,24215,24216,24217,24218,24219,24220,24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307,24575,24576,24577,24578,24580,24582,24583,24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595,24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607,24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619,24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631,24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643,24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655,24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667,24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679,24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691,24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703,24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715,24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727,24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739,24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751,24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763,24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775,24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787,24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799,24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811,24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823,24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835,24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847,24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859,24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871,24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895,24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907,24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919,24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931,24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943,24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979,24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991,24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003,25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015,25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027,25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039,25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087,25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099,25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111,25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123,25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135,25136,25137,25138,25139,25140,25141,25142,25143,25144,25146,25147,25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171,25172,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183,25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195,25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207,25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219,25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231,25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243,25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255,25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267,25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279,25280,25281,25282,25283,25284,25286,25287,25288,25289,25290,25291,25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303,25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315,25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327,25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339,25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351,25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363,25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375,25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387,25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399,25400,25401,25402,25403,25404,25405,25406,25887,25905,25906,25907,25909,27498,27499,27500,27501,27502,27503,28270,28279,28280,28531,28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543,28544,29549,29550,29714,29723,29724,29725,29726,29727,29728,29729,29730,29731,29732,29733,29734,31125,31126,31127,31131,31133,31134,31136,31137,31138,31139,31140,31142,31143,31145,31147,31148,31149,31150,31151,31152,31153,31173,31175,31178,31180,31186,31187,31190,31193,31196,31200,31202,31204,31222,31226,31230,31234,31237,31240,31255,31258,31272,31275,31276,31277,31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291,31292,31293,31294,31295,31297,31298,31299,31303,31304,31305,31306,31308,31318,31319,31320,31321,31322,31323,31326,31328,31329,31330,31331,31332,31333,31334,31335,31336,31338,31339,31340,31342,31343,31501,31557,31565,31573,31581,31837,31875,31876,31877,31878,31879,31883,31884,31885,31886,31887,31888,31889,31893,31894,31895,31896,31898,31899,31900,31902,31903,31904,31905,31906,31908,31909,31911,31912,31913,31915,31916,31917,31918,31925,31926,31927,31928,31929,31935,31936,31937,31938,31939,31940,31943,31952,32411,32520,33186,33457,33458,33459,33460,33461,33462,33954 +Total: 1117 +*/ +DELETE FROM `creature_loot_template` WHERE `Entry` IN (18212,21264,18207,1410,5355,7370,11980,12377,12378,12379,15547,15548,15551,16170,16171,16173,16174,16175,16176,16177,16178,16389,16406,16407,16408,16409,16410,16411,16412,16414,16415,16424,16425,16459,16460,16461,16468,16470,16471,16472,16473,16481,16482,16485,16488,16489,16491,16492,16504,16507,16519,16523,16525,16526,16529,16530,16539,16540,16544,16545,16595,16596,16769,16772,16805,16810,16943,16944,16945,16948,16949,16952,16992,17088,17128,17129,17130,17131,17132,17133,17134,17135,17136,17137,17138,17139,17141,17142,17143,17146,17147,17148,17149,17150,17151,17152,17153,17154,17155,17156,17157,17158,17159,17160,17356,17370,17400,17401,17724,17725,17726,17727,17728,17729,17730,17731,17732,17734,17735,17771,17799,17814,17815,17816,17817,17840,17895,17897,17898,17899,17905,17906,17907,17908,17916,17938,17940,17952,17957,17958,17959,17960,17961,17962,17963,17964,17981,17993,17994,18033,18037,18043,18062,18064,18065,18145,18155,18182,18202,18203,18204,18205,18211,18220,18226,18238,18257,18258,18259,18260,18289,18290,18298,18309,18311,18312,18313,18315,18318,18319,18320,18321,18323,18325,18326,18327,18328,18331,18334,18352,18391,18404,18405,18411,18413,18419,18420,18421,18423,18437,18438,18440,18449,18450,18451,18452,18453,18454,18455,18456,18457,18460,18461,18463,18464,18465,18466,18467,18468,18469,18470,18476,18477,18493,18495,18498,18499,18500,18501,18503,18524,18533,18535,18536,18539,18540,18541,18548,18554,18556,18557,18558,18559,18567,18583,18585,18586,18587,18588,18595,18608,18631,18632,18633,18634,18635,18636,18637,18638,18639,18640,18641,18642,18647,18648,18658,18660,18661,18663,18670,18702,18707,18718,18720,18750,18794,18796,18848,18850,18852,18853,18855,18856,18857,18858,18859,18860,18864,18865,18866,18867,18869,18870,18872,18873,18875,18877,18879,18880,18881,18882,18883,18884,18885,18886,18963,18964,18974,18976,18982,18983,18996,19055,19166,19167,19183,19191,19201,19208,19209,19231,19307,19389,19428,19429,19453,19486,19494,19505,19507,19508,19509,19510,19511,19512,19513,19543,19544,19545,19546,19554,19557,19593,19595,19598,19608,19632,19633,19635,19641,19642,19643,19657,19705,19707,19712,19713,19716,19735,19738,19740,19744,19747,19754,19755,19756,19757,19759,19760,19762,19765,19767,19768,19779,19784,19788,19789,19792,19795,19796,19799,19800,19801,19802,19806,19823,19824,19825,19826,19827,19830,19831,19843,19847,19852,19853,19865,19881,19884,19885,19886,19887,19888,19889,19890,19891,19892,19902,19903,19904,19926,19940,19943,19944,19945,19948,19952,19957,19960,19961,19963,19973,19978,19979,19980,19982,19983,19984,19985,19986,19987,19988,19989,19990,19991,19992,19993,19994,19995,19996,19997,19998,20021,20031,20032,20033,20034,20035,20036,20037,20038,20039,20040,20041,20042,20043,20044,20045,20046,20048,20049,20050,20052,20058,20059,20095,20113,20132,20134,20135,20136,20138,20139,20140,20141,20161,20177,20179,20180,20181,20191,20192,20193,20202,20207,20210,20211,20215,20216,20221,20248,20255,20256,20258,20259,20260,20261,20265,20285,20326,20329,20330,20332,20334,20340,20394,20397,20404,20409,20410,20416,20427,20435,20452,20453,20454,20456,20458,20459,20474,20480,20483,20495,20496,20501,20502,20512,20514,20516,20554,20557,20600,20601,20606,20607,20609,20610,20611,20614,20634,20668,20671,20673,20680,20683,20684,20685,20713,20714,20723,20726,20727,20728,20729,20730,20731,20732,20747,20748,20749,20751,20753,20756,20757,20765,20766,20768,20770,20772,20773,20774,20775,20777,20778,20779,20783,20795,20800,20801,20803,20854,20857,20859,20864,20865,20866,20867,20868,20872,20873,20875,20878,20879,20881,20882,20883,20887,20888,20896,20897,20901,20902,20905,20906,20908,20909,20910,20911,20924,20925,20927,20928,20929,20930,20931,20934,20983,20987,20988,20990,20998,21004,21021,21022,21023,21032,21033,21042,21046,21047,21048,21050,21057,21058,21059,21060,21061,21065,21089,21102,21108,21123,21124,21126,21127,21164,21168,21171,21178,21179,21180,21181,21189,21196,21198,21200,21205,21218,21220,21221,21224,21225,21226,21227,21229,21230,21231,21232,21238,21242,21246,21249,21251,21254,21263,21284,21285,21287,21296,21298,21299,21300,21301,21302,21305,21309,21314,21315,21324,21325,21326,21337,21339,21350,21368,21370,21373,21380,21381,21382,21383,21384,21385,21386,21387,21389,21405,21408,21409,21416,21425,21450,21453,21454,21455,21462,21477,21478,21492,21499,21500,21501,21503,21505,21506,21516,21519,21520,21636,21637,21640,21644,21648,21649,21650,21651,21652,21656,21660,21661,21662,21663,21695,21696,21702,21709,21710,21711,21717,21718,21719,21720,21721,21722,21723,21724,21728,21730,21742,21743,21763,21767,21784,21787,21788,21795,21801,21802,21803,21804,21808,21809,21810,21815,21816,21817,21820,21821,21827,21839,21842,21843,21844,21849,21854,21863,21864,21878,21879,21891,21897,21901,21902,21904,21907,21911,21912,21923,21941,21956,21963,21979,21985,22011,22012,22016,22017,22018,22038,22044,22045,22052,22072,22076,22081,22082,22084,22093,22095,22099,22100,22105,22123,22132,22143,22144,22148,22160,22175,22180,22181,22182,22187,22194,22195,22199,22201,22202,22204,22217,22221,22241,22242,22243,22244,22252,22253,22254,22255,22257,22261,22262,22263,22265,22275,22281,22286,22287,22289,22291,22295,22297,22298,22303,22304,22305,22307,22308,22309,22310,22311,22313,22325,22327,22341,22342,22343,22357,22363,22378,22384,22387,22388,22392,22393,22394,22466,22482,22807,22825,22826,22827,22828,22844,22845,22846,22847,22853,22855,22869,22873,22874,22875,22876,22877,22878,22879,22880,22881,22882,22883,22884,22885,22939,22945,22946,22953,22954,22955,22956,22957,22959,22960,22962,22963,22964,22965,23008,23018,23020,23022,23026,23028,23029,23030,23047,23049,23061,23066,23067,23068,23153,23154,23161,23162,23163,23165,23169,23172,23174,23188,23196,23219,23222,23223,23232,23235,23236,23237,23239,23261,23264,23267,23269,23281,23282,23285,23286,23290,23305,23311,23324,23326,23330,23337,23339,23353,23354,23355,23374,23386,23390,23394,23400,23402,23403,23501,23542,23580,23581,23582,23584,23586,23596,23597,23774,23834,24043,24047,24059,24064,24065,24179,24180,24374,24530,24549,24684,24689,24696,24698,24762,24777,24922,24955,24960,24976,25001,25060,25073,25593,25595,25599,25867,38030) +AND `Reference` BETWEEN 1100000 AND 1100400; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(1410, 1, 1100163, 0, 5, 'Firewing Bloodwarder - World Loot Level 63'), +(1410, 2, 1100164, 0, 5, 'Firewing Bloodwarder - World Loot Level 64'), +(5355, 1, 1100163, 0, 5, 'Firewing Defender - World Loot Level 63'), +(5355, 2, 1100164, 0, 5, 'Firewing Defender - World Loot Level 64'), +(7370, 1, 1100168, 0, 5, 'Restless Shade - World Loot Level 68'), +(7370, 2, 1100169, 0, 5, 'Restless Shade - World Loot Level 69'), +(11980, 1, 1100372, 0, 5, 'Zuluhed the Whacked - World Loot Level 72'), +(12377, 1, 1100169, 0, 5, 'Wailing Spectre - World Loot Level 69'), +(12377, 2, 1100170, 0, 5, 'Wailing Spectre - World Loot Level 70'), +(12378, 1, 1100168, 0, 5, 'Damned Soul - World Loot Level 68'), +(12378, 2, 1100169, 0, 5, 'Damned Soul - World Loot Level 69'), +(12379, 1, 1100169, 0, 5, 'Unliving Caretaker - World Loot Level 69'), +(12379, 2, 1100170, 0, 5, 'Unliving Caretaker - World Loot Level 70'), +(15547, 1, 1100271, 0, 5, 'Spectral Charger - World Loot Level 71'), +(15548, 1, 1100271, 0, 5, 'Spectral Stallion - World Loot Level 71'), +(15551, 1, 1100370, 0, 5, 'Spectral Stable Hand - World Loot Level 70'), +(16170, 1, 1100270, 0, 5, 'Coldmist Stalker - World Loot Level 70'), +(16171, 1, 1100271, 0, 5, 'Coldmist Widow - World Loot Level 71'), +(16173, 1, 1100269, 0, 5, 'Shadowbat - World Loot Level 69'), +(16173, 2, 1100270, 0, 5, 'Shadowbat - World Loot Level 70'), +(16174, 1, 1100271, 0, 5, 'Greater Shadowbat - World Loot Level 71'), +(16175, 1, 1100271, 0, 5, 'Vampiric Shadowbat - World Loot Level 71'), +(16176, 1, 1100269, 0, 5, 'Shadowbeast - World Loot Level 69'), +(16176, 2, 1100270, 0, 5, 'Shadowbeast - World Loot Level 70'), +(16177, 1, 1100271, 0, 5, 'Dreadbeast - World Loot Level 71'), +(16178, 1, 1100270, 0, 5, 'Phase Hound - World Loot Level 70'), +(16389, 1, 1100370, 0, 5, 'Spectral Apprentice - World Loot Level 70'), +(16406, 1, 1100371, 0, 5, 'Phantom Attendant - World Loot Level 71'), +(16407, 1, 1100369, 0, 5, 'Spectral Servant - World Loot Level 69'), +(16408, 1, 1100372, 0, 5, 'Phantom Valet - World Loot Level 72'), +(16409, 1, 1100170, 0, 5, 'Phantom Guest - World Loot Level 70'), +(16410, 1, 1100372, 0, 5, 'Spectral Retainer - World Loot Level 72'), +(16411, 1, 1100371, 0, 5, 'Spectral Chef - World Loot Level 71'), +(16412, 1, 1100371, 0, 5, 'Ghostly Baker - World Loot Level 71'), +(16414, 1, 1100371, 0, 5, 'Ghostly Steward - World Loot Level 71'), +(16415, 1, 1100371, 0, 5, 'Skeletal Waiter - World Loot Level 71'), +(16424, 1, 1100371, 0, 5, 'Spectral Sentry - World Loot Level 71'), +(16425, 1, 1100371, 0, 5, 'Phantom Guardsman - World Loot Level 71'), +(16459, 1, 1100371, 0, 5, 'Wanton Hostess - World Loot Level 71'), +(16460, 1, 1100371, 0, 5, 'Night Mistress - World Loot Level 71'), +(16461, 1, 1100371, 0, 5, 'Concubine - World Loot Level 71'), +(16468, 1, 1100170, 0, 5, 'Spectral Patron - World Loot Level 70'), +(16470, 1, 1100372, 0, 5, 'Ghostly Philanthropist - World Loot Level 72'), +(16471, 1, 1100372, 0, 5, 'Skeletal Usher - World Loot Level 72'), +(16472, 1, 1100371, 0, 5, 'Phantom Stagehand - World Loot Level 71'), +(16473, 1, 1100371, 0, 5, 'Spectral Performer - World Loot Level 71'), +(16481, 1, 1100372, 0, 5, 'Ghastly Haunt - World Loot Level 72'), +(16482, 1, 1100372, 0, 5, 'Trapped Soul - World Loot Level 72'), +(16485, 1, 1100272, 0, 5, 'Arcane Watchman - World Loot Level 72'), +(16488, 1, 1100271, 0, 5, 'Arcane Anomaly - World Loot Level 71'), +(16489, 1, 1100270, 0, 5, 'Chaotic Sentience - World Loot Level 70'), +(16489, 2, 1100271, 0, 5, 'Chaotic Sentience - World Loot Level 71'), +(16491, 1, 1100270, 0, 5, 'Mana Feeder - World Loot Level 70'), +(16492, 1, 1100270, 0, 5, 'Syphoner - World Loot Level 70'), +(16504, 1, 1100272, 0, 5, 'Arcane Protector - World Loot Level 72'), +(16507, 1, 1100369, 0, 5, 'Shattered Hand Sentry - World Loot Level 69'), +(16519, 1, 1100163, 0, 5, 'Shadowy Executioner - World Loot Level 63'), +(16519, 2, 1100164, 0, 5, 'Shadowy Executioner - World Loot Level 64'), +(16523, 1, 1100369, 0, 5, 'Shattered Hand Savage - World Loot Level 69'), +(16525, 1, 1100271, 0, 5, 'Spell Shade - World Loot Level 71'), +(16526, 1, 1100272, 0, 5, 'Sorcerous Shade - World Loot Level 72'), +(16529, 1, 1100271, 0, 5, 'Magical Horror - World Loot Level 71'), +(16530, 1, 1100270, 0, 5, 'Mana Warp - World Loot Level 70'), +(16539, 1, 1100370, 0, 5, 'Homunculus - World Loot Level 70'), +(16540, 1, 1100372, 0, 5, 'Shadow Pillager - World Loot Level 72'), +(16544, 1, 1100372, 0, 5, 'Ethereal Thief - World Loot Level 72'), +(16545, 1, 1100372, 0, 5, 'Ethereal Spellfilcher - World Loot Level 72'), +(16595, 1, 1100272, 0, 5, 'Fleshbeast - World Loot Level 72'), +(16596, 1, 1100272, 0, 5, 'Greater Fleshbeast - World Loot Level 72'), +(16769, 1, 1100163, 0, 5, 'Firewing Warlock - World Loot Level 63'), +(16769, 2, 1100164, 0, 5, 'Firewing Warlock - World Loot Level 64'), +(16772, 1, 1100163, 0, 5, 'Bonechewer Devastator - World Loot Level 63'), +(16772, 2, 1100164, 0, 5, 'Bonechewer Devastator - World Loot Level 64'), +(16805, 1, 1100164, 0, 5, 'Broken Skeleton - World Loot Level 64'), +(16805, 2, 1100165, 0, 5, 'Broken Skeleton - World Loot Level 65'), +(16810, 1, 1100163, 0, 5, 'Bonechewer Backbreaker - World Loot Level 63'), +(16810, 2, 1100164, 0, 5, 'Bonechewer Backbreaker - World Loot Level 64'), +(16943, 1, 1100168, 0, 5, 'Cyber-Rage Forgelord - World Loot Level 68'), +(16943, 2, 1100169, 0, 5, 'Cyber-Rage Forgelord - World Loot Level 69'), +(16944, 1, 1100168, 0, 5, 'Mo\'arg Doomsmith - World Loot Level 68'), +(16944, 2, 1100169, 0, 5, 'Mo\'arg Doomsmith - World Loot Level 69'), +(16945, 1, 1100367, 0, 5, 'Mo\'arg Engineer - World Loot Level 67'), +(16945, 2, 1100368, 0, 5, 'Mo\'arg Engineer - World Loot Level 68'), +(16948, 1, 1100168, 0, 5, 'Gan\'arg Engineer - World Loot Level 68'), +(16948, 2, 1100169, 0, 5, 'Gan\'arg Engineer - World Loot Level 69'), +(16949, 1, 1100168, 0, 5, 'Gan\'arg Mekgineer - World Loot Level 68'), +(16949, 2, 1100169, 0, 5, 'Gan\'arg Mekgineer - World Loot Level 69'), +(16952, 1, 1100167, 0, 5, 'Anger Guard - World Loot Level 67'), +(16952, 2, 1100168, 0, 5, 'Anger Guard - World Loot Level 68'), +(16992, 1, 1100061, 0, 5, 'Dreadtusk - World Loot Level 61'), +(16992, 2, 1100062, 0, 5, 'Dreadtusk - World Loot Level 62'), +(17088, 1, 1100163, 0, 5, 'Shadowy Summoner - World Loot Level 63'), +(17088, 2, 1100164, 0, 5, 'Shadowy Summoner - World Loot Level 64'), +(17128, 1, 1100064, 0, 5, 'Windroc - World Loot Level 64'), +(17128, 2, 1100065, 0, 5, 'Windroc - World Loot Level 65'), +(17129, 1, 1100066, 0, 5, 'Greater Windroc - World Loot Level 66'), +(17129, 2, 1100067, 0, 5, 'Greater Windroc - World Loot Level 67'), +(17130, 1, 1100064, 0, 5, 'Talbuk Stag - World Loot Level 64'), +(17130, 2, 1100065, 0, 5, 'Talbuk Stag - World Loot Level 65'), +(17131, 1, 1100065, 0, 5, 'Talbuk Thorngrazer - World Loot Level 65'), +(17131, 2, 1100066, 0, 5, 'Talbuk Thorngrazer - World Loot Level 66'), +(17132, 1, 1100065, 0, 5, 'Clefthoof Bull - World Loot Level 65'), +(17132, 2, 1100066, 0, 5, 'Clefthoof Bull - World Loot Level 66'), +(17133, 1, 1100066, 0, 5, 'Aged Clefthoof - World Loot Level 66'), +(17133, 2, 1100067, 0, 5, 'Aged Clefthoof - World Loot Level 67'), +(17134, 1, 1100164, 0, 5, 'Boulderfist Crusher - World Loot Level 64'), +(17134, 2, 1100165, 0, 5, 'Boulderfist Crusher - World Loot Level 65'), +(17135, 1, 1100164, 0, 5, 'Boulderfist Mystic - World Loot Level 64'), +(17135, 2, 1100165, 0, 5, 'Boulderfist Mystic - World Loot Level 65'), +(17136, 1, 1100165, 0, 5, 'Boulderfist Warrior - World Loot Level 65'), +(17136, 2, 1100166, 0, 5, 'Boulderfist Warrior - World Loot Level 66'), +(17137, 1, 1100165, 0, 5, 'Boulderfist Mage - World Loot Level 65'), +(17137, 2, 1100166, 0, 5, 'Boulderfist Mage - World Loot Level 66'), +(17138, 1, 1100165, 0, 5, 'Warmaul Reaver - World Loot Level 65'), +(17138, 2, 1100166, 0, 5, 'Warmaul Reaver - World Loot Level 66'), +(17139, 1, 1100164, 0, 5, 'Windyreed Scavenger - World Loot Level 64'), +(17139, 2, 1100165, 0, 5, 'Windyreed Scavenger - World Loot Level 65'), +(17141, 1, 1100164, 0, 5, 'Windyreed Wretch - World Loot Level 64'), +(17141, 2, 1100165, 0, 5, 'Windyreed Wretch - World Loot Level 65'), +(17142, 1, 1100164, 0, 5, 'Wrekt Warrior - World Loot Level 64'), +(17142, 2, 1100165, 0, 5, 'Wrekt Warrior - World Loot Level 65'), +(17143, 1, 1100163, 0, 5, 'Wrekt Seer - World Loot Level 63'), +(17146, 1, 1100166, 0, 5, 'Kil\'sorrow Spellbinder - World Loot Level 66'), +(17146, 2, 1100167, 0, 5, 'Kil\'sorrow Spellbinder - World Loot Level 67'), +(17147, 1, 1100165, 0, 5, 'Kil\'sorrow Cultist - World Loot Level 65'), +(17147, 2, 1100166, 0, 5, 'Kil\'sorrow Cultist - World Loot Level 66'), +(17148, 1, 1100165, 0, 5, 'Kil\'sorrow Deathsworn - World Loot Level 65'), +(17148, 2, 1100166, 0, 5, 'Kil\'sorrow Deathsworn - World Loot Level 66'), +(17149, 1, 1100165, 0, 5, 'Vir\'aani Raider - World Loot Level 65'), +(17149, 2, 1100166, 0, 5, 'Vir\'aani Raider - World Loot Level 66'), +(17150, 1, 1100166, 0, 5, 'Vir\'aani Arcanist - World Loot Level 66'), +(17150, 2, 1100167, 0, 5, 'Vir\'aani Arcanist - World Loot Level 67'), +(17151, 1, 1100166, 0, 5, 'Gan\'arg Tinkerer - World Loot Level 66'), +(17151, 2, 1100167, 0, 5, 'Gan\'arg Tinkerer - World Loot Level 67'), +(17151, 3, 1100168, 0, 5, 'Gan\'arg Tinkerer - World Loot Level 68'), +(17152, 1, 1100367, 0, 5, 'Felguard Legionnaire - World Loot Level 67'), +(17152, 2, 1100368, 0, 5, 'Felguard Legionnaire - World Loot Level 68'), +(17153, 1, 1100064, 0, 5, 'Lake Spirit - World Loot Level 64'), +(17153, 2, 1100065, 0, 5, 'Lake Spirit - World Loot Level 65'), +(17154, 1, 1100064, 0, 5, 'Muck Spawn - World Loot Level 64'), +(17154, 2, 1100065, 0, 5, 'Muck Spawn - World Loot Level 65'), +(17154, 3, 1100066, 0, 5, 'Muck Spawn - World Loot Level 66'), +(17155, 1, 1100065, 0, 5, 'Lake Surger - World Loot Level 65'), +(17155, 2, 1100066, 0, 5, 'Lake Surger - World Loot Level 66'), +(17156, 1, 1100064, 0, 5, 'Tortured Earth Spirit - World Loot Level 64'), +(17156, 2, 1100065, 0, 5, 'Tortured Earth Spirit - World Loot Level 65'), +(17157, 1, 1100066, 0, 5, 'Shattered Rumbler - World Loot Level 66'), +(17157, 2, 1100067, 0, 5, 'Shattered Rumbler - World Loot Level 67'), +(17158, 1, 1100064, 0, 5, 'Dust Howler - World Loot Level 64'), +(17158, 2, 1100065, 0, 5, 'Dust Howler - World Loot Level 65'), +(17159, 1, 1100065, 0, 5, 'Storm Rager - World Loot Level 65'), +(17159, 2, 1100066, 0, 5, 'Storm Rager - World Loot Level 66'), +(17160, 1, 1100066, 0, 5, 'Living Cyclone - World Loot Level 66'), +(17356, 1, 1100269, 0, 5, 'Creeping Ooze - World Loot Level 69'), +(17370, 1, 1100361, 0, 5, 'Laughing Skull Enforcer - World Loot Level 61'), +(17400, 1, 1100362, 0, 5, 'Felguard Annihilator - World Loot Level 62'), +(17401, 1, 1100060, 0, 5, 'Felhound Manastalker - World Loot Level 60'), +(17401, 2, 1100061, 0, 5, 'Felhound Manastalker - World Loot Level 61'), +(17724, 1, 1100262, 0, 5, 'Underbat - World Loot Level 62'), +(17725, 1, 1100262, 0, 5, 'Underbog Lurker - World Loot Level 62'), +(17725, 2, 1100263, 0, 5, 'Underbog Lurker - World Loot Level 63'), +(17726, 1, 1100364, 0, 5, 'Wrathfin Myrmidon - World Loot Level 64'), +(17727, 1, 1100364, 0, 5, 'Wrathfin Sentry - World Loot Level 64'), +(17728, 1, 1100363, 0, 5, 'Murkblood Tribesman - World Loot Level 63'), +(17728, 2, 1100364, 0, 5, 'Murkblood Tribesman - World Loot Level 64'), +(17729, 1, 1100363, 0, 5, 'Murkblood Spearman - World Loot Level 63'), +(17729, 2, 1100364, 0, 5, 'Murkblood Spearman - World Loot Level 64'), +(17730, 1, 1100363, 0, 5, 'Murkblood Healer - World Loot Level 63'), +(17730, 2, 1100364, 0, 5, 'Murkblood Healer - World Loot Level 64'), +(17731, 1, 1100264, 0, 5, 'Fen Ray - World Loot Level 64'), +(17732, 1, 1100263, 0, 5, 'Lykul Wasp - World Loot Level 63'), +(17734, 1, 1100264, 0, 5, 'Underbog Lord - World Loot Level 64'), +(17735, 1, 1100364, 0, 5, 'Wrathfin Warrior - World Loot Level 64'), +(17771, 1, 1100363, 0, 5, 'Murkblood Oracle - World Loot Level 63'), +(17771, 2, 1100364, 0, 5, 'Murkblood Oracle - World Loot Level 64'), +(17799, 1, 1100370, 0, 5, 'Dreghood Slave - World Loot Level 70'), +(17814, 1, 1100365, 0, 5, 'Lordaeron Watchman - World Loot Level 65'), +(17815, 1, 1100365, 0, 5, 'Lordaeron Sentry - World Loot Level 65'), +(17816, 1, 1100362, 0, 5, 'Bogstrok - World Loot Level 62'), +(17817, 1, 1100362, 0, 5, 'Greater Bogstrok - World Loot Level 62'), +(17840, 1, 1100265, 0, 5, 'Durnholde Tracking Hound - World Loot Level 65'), +(17895, 1, 1100370, 0, 5, 'Ghoul - World Loot Level 70'), +(17897, 1, 1100270, 0, 5, 'Crypt Fiend - World Loot Level 70'), +(17898, 1, 1100371, 0, 5, 'Abomination - World Loot Level 71'), +(17899, 1, 1100370, 0, 5, 'Shadowy Necromancer - World Loot Level 70'), +(17905, 1, 1100370, 0, 5, 'Banshee - World Loot Level 70'), +(17906, 1, 1100270, 0, 5, 'Gargoyle - World Loot Level 70'), +(17907, 1, 1100272, 0, 5, 'Frost Wyrm - World Loot Level 72'), +(17908, 1, 1100271, 0, 5, 'Giant Infernal - World Loot Level 71'), +(17916, 1, 1100270, 0, 5, 'Fel Stalker - World Loot Level 70'), +(17938, 1, 1100362, 0, 5, 'Coilfang Observer - World Loot Level 62'), +(17940, 1, 1100363, 0, 5, 'Coilfang Technician - World Loot Level 63'), +(17952, 1, 1100067, 0, 5, 'Darkwater Crocolisk - World Loot Level 67'), +(17952, 2, 1100068, 0, 5, 'Darkwater Crocolisk - World Loot Level 68'), +(17957, 1, 1100363, 0, 5, 'Coilfang Champion - World Loot Level 63'), +(17958, 1, 1100363, 0, 5, 'Coilfang Defender - World Loot Level 63'), +(17959, 1, 1100362, 0, 5, 'Coilfang Slavehandler - World Loot Level 62'), +(17959, 2, 1100363, 0, 5, 'Coilfang Slavehandler - World Loot Level 63'), +(17960, 1, 1100362, 0, 5, 'Coilfang Soothsayer - World Loot Level 62'), +(17961, 1, 1100362, 0, 5, 'Coilfang Enchantress - World Loot Level 62'), +(17962, 1, 1100361, 0, 5, 'Coilfang Collaborator - World Loot Level 61'), +(17962, 2, 1100362, 0, 5, 'Coilfang Collaborator - World Loot Level 62'), +(17963, 1, 1100162, 0, 5, 'Wastewalker Slave - World Loot Level 62'), +(17963, 2, 1100163, 0, 5, 'Wastewalker Slave - World Loot Level 63'), +(17964, 1, 1100162, 0, 5, 'Wastewalker Worker - World Loot Level 62'), +(17964, 2, 1100163, 0, 5, 'Wastewalker Worker - World Loot Level 63'), +(17981, 1, 1100165, 0, 5, 'Voidspawn - World Loot Level 65'), +(17981, 2, 1100166, 0, 5, 'Voidspawn - World Loot Level 66'), +(17993, 1, 1100369, 0, 5, 'Bloodwarder Protector - World Loot Level 69'), +(17993, 2, 1100370, 0, 5, 'Bloodwarder Protector - World Loot Level 70'), +(17994, 1, 1100370, 0, 5, 'Bloodwarder Falconer - World Loot Level 70'), +(18033, 1, 1100064, 0, 5, 'Dark Worg - World Loot Level 64'), +(18033, 2, 1100065, 0, 5, 'Dark Worg - World Loot Level 65'), +(18037, 1, 1100166, 0, 5, 'Warmaul Warlock - World Loot Level 66'), +(18037, 2, 1100167, 0, 5, 'Warmaul Warlock - World Loot Level 67'), +(18043, 1, 1100166, 0, 5, 'Agitated Orc Spirit - World Loot Level 66'), +(18043, 2, 1100167, 0, 5, 'Agitated Orc Spirit - World Loot Level 67'), +(18062, 1, 1100065, 0, 5, 'Enraged Crusher - World Loot Level 65'), +(18062, 2, 1100066, 0, 5, 'Enraged Crusher - World Loot Level 66'), +(18064, 1, 1100165, 0, 5, 'Warmaul Shaman - World Loot Level 65'), +(18064, 2, 1100166, 0, 5, 'Warmaul Shaman - World Loot Level 66'), +(18065, 1, 1100166, 0, 5, 'Warmaul Brute - World Loot Level 66'), +(18065, 2, 1100167, 0, 5, 'Warmaul Brute - World Loot Level 67'), +(18145, 1, 1100066, 0, 5, 'Watoosun\'s Polluted Essence - World Loot Level 66'), +(18155, 1, 1100269, 0, 5, 'Bloodfalcon - World Loot Level 69'), +(18182, 1, 1100267, 0, 5, 'Gurok the Usurper - World Loot Level 67'), +(18202, 1, 1100165, 0, 5, 'Murkblood Putrifier - World Loot Level 65'), +(18202, 2, 1100166, 0, 5, 'Murkblood Putrifier - World Loot Level 66'), +(18203, 1, 1100166, 0, 5, 'Murkblood Raider - World Loot Level 66'), +(18203, 2, 1100167, 0, 5, 'Murkblood Raider - World Loot Level 67'), +(18204, 1, 1100167, 0, 5, 'Ortor of Murkblood - World Loot Level 67'), +(18205, 1, 1100064, 0, 5, 'Clefthoof - World Loot Level 64'), +(18205, 2, 1100065, 0, 5, 'Clefthoof - World Loot Level 65'), +(18207, 1, 1100164, 25, 5, 'Murkblood Scavenger - World Loot Level 64'), +(18211, 1, 1100167, 0, 5, 'Murkblood Brute - World Loot Level 67'), +(18212, 1, 1100062, 12.5, 5, 'Mudfin Frenzy - World Loot Level 62'), +(18212, 2, 1100063, 12.5, 5, 'Mudfin Frenzy - World Loot Level 63'), +(18220, 1, 1100065, 0, 5, 'Ravenous Windroc - World Loot Level 65'), +(18220, 2, 1100066, 0, 5, 'Ravenous Windroc - World Loot Level 66'), +(18226, 1, 1100066, 0, 5, 'Talbuk Patriarch - World Loot Level 66'), +(18226, 2, 1100067, 0, 5, 'Talbuk Patriarch - World Loot Level 67'), +(18238, 1, 1100167, 0, 5, 'Murkblood Invader - World Loot Level 67'), +(18257, 1, 1100267, 0, 5, 'Gutripper - World Loot Level 67'), +(18258, 1, 1100267, 0, 5, 'Bach\'lor - World Loot Level 67'), +(18259, 1, 1100267, 0, 5, 'Banthar - World Loot Level 67'), +(18260, 1, 1100164, 0, 5, 'Boulderfist Invader - World Loot Level 64'), +(18260, 2, 1100165, 0, 5, 'Boulderfist Invader - World Loot Level 65'), +(18289, 1, 1100066, 0, 5, 'Bull Elekk - World Loot Level 66'), +(18289, 2, 1100067, 0, 5, 'Bull Elekk - World Loot Level 67'), +(18290, 1, 1100268, 0, 5, 'Tusker - World Loot Level 68'), +(18298, 1, 1100167, 0, 5, 'Gava\'xi - World Loot Level 67'), +(18309, 1, 1100364, 0, 5, 'Ethereal Scavenger - World Loot Level 64'), +(18311, 1, 1100364, 0, 5, 'Ethereal Crypt Raider - World Loot Level 64'), +(18312, 1, 1100365, 0, 5, 'Ethereal Spellbinder - World Loot Level 65'), +(18312, 2, 1100366, 0, 5, 'Ethereal Spellbinder - World Loot Level 66'), +(18313, 1, 1100364, 0, 5, 'Ethereal Sorcerer - World Loot Level 64'), +(18313, 2, 1100365, 0, 5, 'Ethereal Sorcerer - World Loot Level 65'), +(18315, 1, 1100366, 0, 5, 'Ethereal Theurgist - World Loot Level 66'), +(18318, 1, 1100367, 0, 5, 'Sethekk Initiate - World Loot Level 67'), +(18319, 1, 1100367, 0, 5, 'Time-Lost Scryer - World Loot Level 67'), +(18320, 1, 1100369, 0, 5, 'Time-Lost Shadowmage - World Loot Level 69'), +(18321, 1, 1100368, 0, 5, 'Sethekk Talon Lord - World Loot Level 68'), +(18321, 2, 1100369, 0, 5, 'Sethekk Talon Lord - World Loot Level 69'), +(18323, 1, 1100367, 0, 5, 'Sethekk Guard - World Loot Level 67'), +(18325, 1, 1100368, 0, 5, 'Sethekk Prophet - World Loot Level 68'), +(18326, 1, 1100369, 0, 5, 'Sethekk Shaman - World Loot Level 69'), +(18327, 1, 1100367, 0, 5, 'Time-Lost Controller - World Loot Level 67'), +(18328, 1, 1100367, 0, 5, 'Sethekk Oracle - World Loot Level 67'), +(18331, 1, 1100365, 0, 5, 'Ethereal Darkcaster - World Loot Level 65'), +(18334, 1, 1100066, 0, 5, 'Wild Elekk - World Loot Level 66'), +(18352, 1, 1100164, 0, 5, 'Boulderfist Hunter - World Loot Level 64'), +(18352, 2, 1100165, 0, 5, 'Boulderfist Hunter - World Loot Level 65'), +(18391, 1, 1100167, 0, 5, 'Giselda the Crone - World Loot Level 67'), +(18404, 1, 1100369, 0, 5, 'Bloodwarder Steward - World Loot Level 69'), +(18404, 2, 1100370, 0, 5, 'Bloodwarder Steward - World Loot Level 70'), +(18405, 1, 1100270, 0, 5, 'Tempest-Forge Peacekeeper - World Loot Level 70'), +(18411, 1, 1100367, 0, 5, 'Durn the Hungerer - World Loot Level 67'), +(18413, 1, 1100166, 0, 5, 'Zorbo the Advisor - World Loot Level 66'), +(18419, 1, 1100369, 0, 5, 'Bloodwarder Greenkeeper - World Loot Level 69'), +(18419, 2, 1100370, 0, 5, 'Bloodwarder Greenkeeper - World Loot Level 70'), +(18420, 1, 1100371, 0, 5, 'Sunseeker Geomancer - World Loot Level 71'), +(18421, 1, 1100370, 0, 5, 'Sunseeker Researcher - World Loot Level 70'), +(18423, 1, 1100367, 0, 5, 'Cho\'war the Pillager - World Loot Level 67'), +(18437, 1, 1100062, 0, 5, 'Vicious Teromoth - World Loot Level 62'), +(18437, 2, 1100063, 0, 5, 'Vicious Teromoth - World Loot Level 63'), +(18438, 1, 1100064, 0, 5, 'Naphthal\'ar - World Loot Level 64'), +(18440, 1, 1100365, 0, 5, 'Warmaul Chef Bufferlo - World Loot Level 65'), +(18440, 2, 1100366, 0, 5, 'Warmaul Chef Bufferlo - World Loot Level 66'), +(18449, 1, 1100162, 0, 5, 'Shienor Talonite - World Loot Level 62'), +(18449, 2, 1100163, 0, 5, 'Shienor Talonite - World Loot Level 63'), +(18450, 1, 1100162, 0, 5, 'Shienor Sorcerer - World Loot Level 62'), +(18450, 2, 1100163, 0, 5, 'Shienor Sorcerer - World Loot Level 63'), +(18451, 1, 1100162, 0, 5, 'Shienor Wing Guard - World Loot Level 62'), +(18451, 2, 1100163, 0, 5, 'Shienor Wing Guard - World Loot Level 63'), +(18452, 1, 1100163, 0, 5, 'Skithian Dreadhawk - World Loot Level 63'), +(18452, 2, 1100164, 0, 5, 'Skithian Dreadhawk - World Loot Level 64'), +(18453, 1, 1100163, 0, 5, 'Skithian Windripper - World Loot Level 63'), +(18453, 2, 1100164, 0, 5, 'Skithian Windripper - World Loot Level 64'), +(18454, 1, 1100164, 0, 5, 'Shalassi Talonguard - World Loot Level 64'), +(18455, 1, 1100164, 0, 5, 'Shalassi Oracle - World Loot Level 64'), +(18455, 2, 1100165, 0, 5, 'Shalassi Oracle - World Loot Level 65'), +(18456, 1, 1100162, 0, 5, 'Tuurem Scavenger - World Loot Level 62'), +(18456, 2, 1100163, 0, 5, 'Tuurem Scavenger - World Loot Level 63'), +(18457, 1, 1100162, 0, 5, 'Tuurem Hunter - World Loot Level 62'), +(18457, 2, 1100163, 0, 5, 'Tuurem Hunter - World Loot Level 63'), +(18460, 1, 1100164, 0, 5, 'Lost Spirit - World Loot Level 64'), +(18460, 2, 1100165, 0, 5, 'Lost Spirit - World Loot Level 65'), +(18461, 1, 1100062, 0, 5, 'Dampscale Basilisk - World Loot Level 62'), +(18461, 2, 1100063, 0, 5, 'Dampscale Basilisk - World Loot Level 63'), +(18463, 1, 1100063, 0, 5, 'Dampscale Devourer - World Loot Level 63'), +(18463, 2, 1100064, 0, 5, 'Dampscale Devourer - World Loot Level 64'), +(18464, 1, 1100063, 0, 5, 'Warp Stalker - World Loot Level 63'), +(18464, 2, 1100064, 0, 5, 'Warp Stalker - World Loot Level 64'), +(18465, 1, 1100064, 0, 5, 'Warp Hunter - World Loot Level 64'), +(18465, 2, 1100065, 0, 5, 'Warp Hunter - World Loot Level 65'), +(18466, 1, 1100063, 0, 5, 'Dreadfang Lurker - World Loot Level 63'), +(18466, 2, 1100064, 0, 5, 'Dreadfang Lurker - World Loot Level 64'), +(18467, 1, 1100064, 0, 5, 'Dreadfang Widow - World Loot Level 64'), +(18467, 2, 1100065, 0, 5, 'Dreadfang Widow - World Loot Level 65'), +(18468, 1, 1100062, 0, 5, 'Teromoth - World Loot Level 62'), +(18468, 2, 1100063, 0, 5, 'Teromoth - World Loot Level 63'), +(18469, 1, 1100063, 0, 5, 'Royal Teromoth - World Loot Level 63'), +(18469, 2, 1100064, 0, 5, 'Royal Teromoth - World Loot Level 64'), +(18470, 1, 1100064, 0, 5, 'Bonelasher - World Loot Level 64'), +(18470, 2, 1100065, 0, 5, 'Bonelasher - World Loot Level 65'), +(18476, 1, 1100062, 0, 5, 'Timber Worg - World Loot Level 62'), +(18476, 2, 1100063, 0, 5, 'Timber Worg - World Loot Level 63'), +(18477, 1, 1100063, 0, 5, 'Timber Worg Alpha - World Loot Level 63'), +(18477, 2, 1100064, 0, 5, 'Timber Worg Alpha - World Loot Level 64'), +(18493, 1, 1100365, 0, 5, 'Auchenai Soulpriest - World Loot Level 65'), +(18493, 2, 1100366, 0, 5, 'Auchenai Soulpriest - World Loot Level 66'), +(18495, 1, 1100365, 0, 5, 'Auchenai Vindicator - World Loot Level 65'), +(18495, 2, 1100366, 0, 5, 'Auchenai Vindicator - World Loot Level 66'), +(18498, 1, 1100165, 0, 5, 'Unliving Soldier - World Loot Level 65'), +(18499, 1, 1100165, 0, 5, 'Unliving Sorcerer - World Loot Level 65'), +(18500, 1, 1100165, 0, 5, 'Unliving Cleric - World Loot Level 65'), +(18501, 1, 1100165, 0, 5, 'Unliving Stalker - World Loot Level 65'), +(18503, 1, 1100165, 30, 5, 'Phantasmal Possessor - World Loot Level 65'), +(18524, 1, 1100366, 0, 5, 'Angered Skeleton - World Loot Level 66'), +(18533, 1, 1100365, 0, 5, 'Luanga the Imprisoner - World Loot Level 65'), +(18535, 1, 1100368, 0, 5, 'Demos, Overseer of Hate - World Loot Level 68'), +(18536, 1, 1100368, 0, 5, 'Xirkos, Overseer of Fear - World Loot Level 68'), +(18539, 1, 1100163, 0, 5, 'Ashkaz - World Loot Level 63'), +(18540, 1, 1100163, 0, 5, 'Ayit - World Loot Level 63'), +(18541, 1, 1100163, 0, 5, 'Urdak - World Loot Level 63'), +(18541, 2, 1100164, 0, 5, 'Urdak - World Loot Level 64'), +(18548, 1, 1100164, 0, 5, 'Firewing Courier - World Loot Level 64'), +(18554, 1, 1100165, 0, 5, 'Sharth Voldoun - World Loot Level 65'), +(18556, 1, 1100165, 0, 5, 'Phasing Soldier - World Loot Level 65'), +(18556, 2, 1100166, 0, 5, 'Phasing Soldier - World Loot Level 66'), +(18557, 1, 1100165, 0, 5, 'Phasing Cleric - World Loot Level 65'), +(18557, 2, 1100166, 0, 5, 'Phasing Cleric - World Loot Level 66'), +(18558, 1, 1100165, 0, 5, 'Phasing Sorcerer - World Loot Level 65'), +(18558, 2, 1100166, 0, 5, 'Phasing Sorcerer - World Loot Level 66'), +(18559, 1, 1100165, 0, 5, 'Phasing Stalker - World Loot Level 65'), +(18559, 2, 1100166, 0, 5, 'Phasing Stalker - World Loot Level 66'), +(18567, 1, 1100368, 0, 5, 'Mo\'arg Master Planner - World Loot Level 68'), +(18583, 1, 1100164, 0, 5, 'Lisaile Fireweaver - World Loot Level 64'), +(18585, 1, 1100368, 0, 5, 'Raliq the Drunk - World Loot Level 68'), +(18586, 1, 1100368, 0, 5, 'Coosh\'coosh - World Loot Level 68'), +(18587, 1, 1100068, 0, 5, 'Frayer - World Loot Level 68'), +(18587, 2, 1100069, 0, 5, 'Frayer - World Loot Level 69'), +(18588, 1, 1100368, 0, 5, 'Floon - World Loot Level 68'), +(18595, 1, 1100162, 0, 5, 'Warped Peon - World Loot Level 62'), +(18595, 2, 1100163, 0, 5, 'Warped Peon - World Loot Level 63'), +(18608, 1, 1100370, 0, 5, 'Laughing Skull Enforcer (1) - World Loot Level 70'), +(18631, 1, 1100369, 0, 5, 'Cabal Cultist - World Loot Level 69'), +(18631, 2, 1100370, 0, 5, 'Cabal Cultist - World Loot Level 70'), +(18632, 1, 1100371, 0, 5, 'Cabal Executioner - World Loot Level 71'), +(18633, 1, 1100369, 0, 5, 'Cabal Acolyte - World Loot Level 69'), +(18634, 1, 1100370, 0, 5, 'Cabal Summoner - World Loot Level 70'), +(18634, 2, 1100371, 0, 5, 'Cabal Summoner - World Loot Level 71'), +(18635, 1, 1100369, 0, 5, 'Cabal Deathsworn - World Loot Level 69'), +(18635, 2, 1100370, 0, 5, 'Cabal Deathsworn - World Loot Level 70'), +(18636, 1, 1100370, 0, 5, 'Cabal Assassin - World Loot Level 70'), +(18637, 1, 1100369, 0, 5, 'Cabal Shadow Priest - World Loot Level 69'), +(18637, 2, 1100370, 0, 5, 'Cabal Shadow Priest - World Loot Level 70'), +(18638, 1, 1100370, 0, 5, 'Cabal Zealot - World Loot Level 70'), +(18639, 1, 1100370, 0, 5, 'Cabal Spellbinder - World Loot Level 70'), +(18639, 2, 1100371, 0, 5, 'Cabal Spellbinder - World Loot Level 71'), +(18640, 1, 1100369, 0, 5, 'Cabal Warlock - World Loot Level 69'), +(18641, 1, 1100169, 0, 5, 'Cabal Familiar - World Loot Level 69'), +(18642, 1, 1100069, 0, 5, 'Fel Guardhound - World Loot Level 69'), +(18647, 1, 1100264, 0, 5, 'Deathskitter - World Loot Level 64'), +(18648, 1, 1100264, 0, 5, 'Stonegazer - World Loot Level 64'), +(18658, 1, 1100167, 0, 5, 'Kil\'sorrow Ritualist - World Loot Level 67'), +(18658, 2, 1100168, 0, 5, 'Kil\'sorrow Ritualist - World Loot Level 68'), +(18660, 1, 1100168, 0, 5, 'Subjugator Vaz\'shir - World Loot Level 68'), +(18661, 1, 1100167, 0, 5, 'Terrorguard - World Loot Level 67'), +(18661, 2, 1100168, 0, 5, 'Terrorguard - World Loot Level 68'), +(18663, 1, 1100170, 0, 5, 'Maiden of Discipline - World Loot Level 70'), +(18670, 1, 1100063, 0, 5, 'Ironjaw - World Loot Level 63'), +(18670, 2, 1100064, 0, 5, 'Ironjaw - World Loot Level 64'), +(18702, 1, 1100366, 0, 5, 'Auchenai Necromancer - World Loot Level 66'), +(18707, 1, 1100265, 0, 5, 'Torgos - World Loot Level 65'), +(18718, 1, 1100165, 0, 5, 'Shadowy Hunter - World Loot Level 65'), +(18720, 1, 1100165, 0, 5, 'Shadowmaster Grieve - World Loot Level 65'), +(18750, 1, 1100062, 0, 5, 'Shimmerscale Eel - World Loot Level 62'), +(18750, 2, 1100063, 0, 5, 'Shimmerscale Eel - World Loot Level 63'), +(18794, 1, 1100369, 0, 5, 'Cabal Ritualist - World Loot Level 69'), +(18796, 1, 1100370, 0, 5, 'Fel Overseer - World Loot Level 70'), +(18848, 1, 1100370, 0, 5, 'Malicious Instructor - World Loot Level 70'), +(18848, 2, 1100371, 0, 5, 'Malicious Instructor - World Loot Level 71'), +(18850, 1, 1100167, 0, 5, 'Sunfury Guardsman - World Loot Level 67'), +(18850, 2, 1100168, 0, 5, 'Sunfury Guardsman - World Loot Level 68'), +(18852, 1, 1100167, 0, 5, 'Sunfury Warp-Engineer - World Loot Level 67'), +(18852, 2, 1100168, 0, 5, 'Sunfury Warp-Engineer - World Loot Level 68'), +(18853, 1, 1100167, 0, 5, 'Sunfury Bloodwarder - World Loot Level 67'), +(18853, 2, 1100168, 0, 5, 'Sunfury Bloodwarder - World Loot Level 68'), +(18855, 1, 1100167, 0, 5, 'Sunfury Magister - World Loot Level 67'), +(18855, 2, 1100168, 0, 5, 'Sunfury Magister - World Loot Level 68'), +(18856, 1, 1100268, 0, 5, 'Arcane Annihilator - World Loot Level 68'), +(18857, 1, 1100168, 0, 5, 'Sunfury Warp-Master - World Loot Level 68'), +(18858, 1, 1100168, 0, 5, 'Wrathbringer - World Loot Level 68'), +(18858, 2, 1100169, 0, 5, 'Wrathbringer - World Loot Level 69'), +(18859, 1, 1100168, 0, 5, 'Wrath Priestess - World Loot Level 68'), +(18859, 2, 1100169, 0, 5, 'Wrath Priestess - World Loot Level 69'), +(18860, 1, 1100170, 0, 5, 'Daughter of Destiny - World Loot Level 70'), +(18864, 1, 1100067, 0, 5, 'Mana Wraith - World Loot Level 67'), +(18864, 2, 1100068, 0, 5, 'Mana Wraith - World Loot Level 68'), +(18865, 1, 1100067, 0, 5, 'Warp Aberration - World Loot Level 67'), +(18865, 2, 1100068, 0, 5, 'Warp Aberration - World Loot Level 68'), +(18866, 1, 1100068, 0, 5, 'Mageslayer - World Loot Level 68'), +(18866, 2, 1100069, 0, 5, 'Mageslayer - World Loot Level 69'), +(18867, 1, 1100068, 0, 5, 'Mana Seeker - World Loot Level 68'), +(18867, 2, 1100069, 0, 5, 'Mana Seeker - World Loot Level 69'), +(18869, 1, 1100068, 0, 5, 'Unstable Voidwraith - World Loot Level 68'), +(18869, 2, 1100069, 0, 5, 'Unstable Voidwraith - World Loot Level 69'), +(18870, 1, 1100068, 0, 5, 'Voidshrieker - World Loot Level 68'), +(18870, 2, 1100069, 0, 5, 'Voidshrieker - World Loot Level 69'), +(18872, 1, 1100167, 0, 5, 'Disembodied Vindicator - World Loot Level 67'), +(18872, 2, 1100168, 0, 5, 'Disembodied Vindicator - World Loot Level 68'), +(18873, 1, 1100167, 0, 5, 'Disembodied Protector - World Loot Level 67'), +(18873, 2, 1100168, 0, 5, 'Disembodied Protector - World Loot Level 68'), +(18875, 1, 1100167, 0, 5, 'Zaxxis Raider - World Loot Level 67'), +(18875, 2, 1100168, 0, 5, 'Zaxxis Raider - World Loot Level 68'), +(18877, 1, 1100068, 0, 5, 'Nether Drake - World Loot Level 68'), +(18877, 2, 1100069, 0, 5, 'Nether Drake - World Loot Level 69'), +(18879, 1, 1100067, 0, 5, 'Phase Hunter - World Loot Level 67'), +(18879, 2, 1100068, 0, 5, 'Phase Hunter - World Loot Level 68'), +(18880, 1, 1100067, 0, 5, 'Nether Ray - World Loot Level 67'), +(18880, 2, 1100068, 0, 5, 'Nether Ray - World Loot Level 68'), +(18881, 1, 1100067, 0, 5, 'Sundered Rumbler - World Loot Level 67'), +(18881, 2, 1100068, 0, 5, 'Sundered Rumbler - World Loot Level 68'), +(18882, 1, 1100069, 0, 5, 'Sundered Thunderer - World Loot Level 69'), +(18883, 1, 1100067, 0, 5, 'Mana Snapper - World Loot Level 67'), +(18883, 2, 1100068, 0, 5, 'Mana Snapper - World Loot Level 68'), +(18884, 1, 1100067, 0, 5, 'Warp Chaser - World Loot Level 67'), +(18884, 2, 1100068, 0, 5, 'Warp Chaser - World Loot Level 68'), +(18885, 1, 1100267, 0, 5, 'Farahlon Giant - World Loot Level 67'), +(18885, 2, 1100268, 0, 5, 'Farahlon Giant - World Loot Level 68'), +(18886, 1, 1100269, 0, 5, 'Farahlon Breaker - World Loot Level 69'), +(18886, 2, 1100270, 0, 5, 'Farahlon Breaker - World Loot Level 70'), +(18963, 1, 1100066, 0, 5, 'Windroc Huntress - World Loot Level 66'), +(18964, 1, 1100064, 0, 5, 'Injured Talbuk - World Loot Level 64'), +(18974, 1, 1100162, 0, 5, 'Z\'kral - World Loot Level 62'), +(18976, 1, 1100162, 0, 5, 'Urga\'zz - World Loot Level 62'), +(18982, 1, 1100067, 0, 5, 'Sable Jaguar - World Loot Level 67'), +(18982, 2, 1100068, 0, 5, 'Sable Jaguar - World Loot Level 68'), +(18983, 1, 1100067, 0, 5, 'Blackfang Tarantula - World Loot Level 67'), +(18983, 2, 1100068, 0, 5, 'Blackfang Tarantula - World Loot Level 68'), +(18996, 1, 1100064, 0, 5, 'Windroc Hunter - World Loot Level 64'), +(18996, 2, 1100065, 0, 5, 'Windroc Hunter - World Loot Level 65'), +(19055, 1, 1100266, 0, 5, 'Windroc Matriarch - World Loot Level 66'), +(19166, 1, 1100271, 0, 5, 'Tempest-Forge Patroller - World Loot Level 71'), +(19167, 1, 1100370, 0, 5, 'Bloodwarder Slayer - World Loot Level 70'), +(19183, 1, 1100062, 0, 5, 'Clefthoof Calf - World Loot Level 62'), +(19183, 2, 1100063, 0, 5, 'Clefthoof Calf - World Loot Level 63'), +(19191, 1, 1100363, 0, 5, 'Arazzius the Cruel - World Loot Level 63'), +(19201, 1, 1100366, 0, 5, 'Mountain Gronn - World Loot Level 66'), +(19208, 1, 1100369, 0, 5, 'Summoned Cabal Acolyte - World Loot Level 69'), +(19209, 1, 1100369, 0, 5, 'Summoned Cabal Deathsworn - World Loot Level 69'), +(19231, 1, 1100370, 0, 5, 'Mechanar Crusher - World Loot Level 70'), +(19307, 1, 1100264, 0, 5, 'Nexus Terror - World Loot Level 64'), +(19389, 1, 1100372, 0, 5, 'Lair Brute - World Loot Level 72'), +(19428, 1, 1100268, 0, 5, 'Cobalt Serpent - World Loot Level 68'), +(19429, 1, 1100266, 0, 5, 'Avian Darkhawk - World Loot Level 66'), +(19453, 1, 1100168, 0, 5, 'Sunfury Captain - World Loot Level 68'), +(19486, 1, 1100370, 0, 5, 'Sunseeker Chemist - World Loot Level 70'), +(19494, 1, 1100068, 0, 5, 'Ar\'kelos - World Loot Level 68'), +(19505, 1, 1100370, 0, 5, 'Sunseeker Channeler - World Loot Level 70'), +(19507, 1, 1100370, 0, 5, 'Sunseeker Gene-Splicer - World Loot Level 70'), +(19508, 1, 1100370, 0, 5, 'Sunseeker Herbalist - World Loot Level 70'), +(19509, 1, 1100370, 0, 5, 'Sunseeker Harvester - World Loot Level 70'), +(19510, 1, 1100370, 0, 5, 'Bloodwarder Centurion - World Loot Level 70'), +(19511, 1, 1100370, 0, 5, 'Nethervine Inciter - World Loot Level 70'), +(19512, 1, 1100370, 0, 5, 'Nethervine Reaper - World Loot Level 70'), +(19513, 1, 1100270, 0, 5, 'Mutate Fear-Shrieker - World Loot Level 70'), +(19543, 1, 1100168, 0, 5, 'Battle-Mage Dathric - World Loot Level 68'), +(19544, 1, 1100168, 0, 5, 'Conjurer Luminrath - World Loot Level 68'), +(19545, 1, 1100168, 0, 5, 'Cohlien Frostweaver - World Loot Level 68'), +(19546, 1, 1100168, 0, 5, 'Abjurist Belmara - World Loot Level 68'), +(19554, 1, 1100270, 0, 5, 'Dimensius the All-Devouring - World Loot Level 70'), +(19557, 1, 1100069, 0, 5, 'Greater Frayer - World Loot Level 69'), +(19593, 1, 1100168, 0, 5, 'Spellbinder Maryana - World Loot Level 68'), +(19595, 1, 1100067, 0, 5, 'Drained Phase Hunter - World Loot Level 67'), +(19595, 2, 1100068, 0, 5, 'Drained Phase Hunter - World Loot Level 68'), +(19598, 1, 1100070, 0, 5, 'Mutate Fleshlasher - World Loot Level 70'), +(19608, 1, 1100070, 0, 5, 'Frayer Wildling - World Loot Level 70'), +(19632, 1, 1100264, 0, 5, 'Lykul Stinger - World Loot Level 64'), +(19633, 1, 1100369, 0, 5, 'Bloodwarder Mender - World Loot Level 69'), +(19635, 1, 1100168, 0, 5, 'Captain Arathyn - World Loot Level 68'), +(19641, 1, 1100169, 0, 5, 'Warp-Raider Nesaad - World Loot Level 69'), +(19642, 1, 1100168, 0, 5, 'Zaxxis Stalker - World Loot Level 68'), +(19643, 1, 1100168, 0, 5, 'Sunfury Astromancer - World Loot Level 68'), +(19657, 1, 1100169, 0, 5, 'Summoner Kanthin - World Loot Level 69'), +(19705, 1, 1100169, 0, 5, 'Master Daellis Dawnstrike - World Loot Level 69'), +(19707, 1, 1100167, 0, 5, 'Sunfury Archer - World Loot Level 67'), +(19707, 2, 1100168, 0, 5, 'Sunfury Archer - World Loot Level 68'), +(19712, 1, 1100370, 0, 5, 'Mechanar Driller - World Loot Level 70'), +(19713, 1, 1100370, 0, 5, 'Mechanar Wrecker - World Loot Level 70'), +(19716, 1, 1100169, 0, 5, 'Mechanar Tinkerer - World Loot Level 69'), +(19735, 1, 1100271, 0, 5, 'Tempest-Forge Destroyer - World Loot Level 71'), +(19738, 1, 1100169, 0, 5, 'Doomclaw - World Loot Level 69'), +(19740, 1, 1100167, 0, 5, 'Wrathwalker - World Loot Level 67'), +(19740, 2, 1100168, 0, 5, 'Wrathwalker - World Loot Level 68'), +(19744, 1, 1100170, 0, 5, 'Dreadwarden - World Loot Level 70'), +(19747, 1, 1100368, 0, 5, 'Baelmon the Hound-Master - World Loot Level 68'), +(19754, 1, 1100168, 0, 5, 'Deathforge Tinkerer - World Loot Level 68'), +(19754, 2, 1100169, 0, 5, 'Deathforge Tinkerer - World Loot Level 69'), +(19755, 1, 1100166, 0, 5, 'Mo\'arg Weaponsmith - World Loot Level 66'), +(19755, 2, 1100167, 0, 5, 'Mo\'arg Weaponsmith - World Loot Level 67'), +(19756, 1, 1100168, 0, 5, 'Deathforge Smith - World Loot Level 68'), +(19756, 2, 1100169, 0, 5, 'Deathforge Smith - World Loot Level 69'), +(19757, 1, 1100068, 0, 5, 'Infernal Soul - World Loot Level 68'), +(19757, 2, 1100069, 0, 5, 'Infernal Soul - World Loot Level 69'), +(19760, 1, 1100068, 0, 5, 'Cooling Infernal - World Loot Level 68'), +(19760, 2, 1100069, 0, 5, 'Cooling Infernal - World Loot Level 69'), +(19762, 1, 1100168, 0, 5, 'Coilskar Defender - World Loot Level 68'), +(19765, 1, 1100169, 0, 5, 'Coilskar Myrmidon - World Loot Level 69'), +(19765, 2, 1100170, 0, 5, 'Coilskar Myrmidon - World Loot Level 70'), +(19767, 1, 1100169, 0, 5, 'Coilskar Sorceress - World Loot Level 69'), +(19767, 2, 1100170, 0, 5, 'Coilskar Sorceress - World Loot Level 70'), +(19768, 1, 1100168, 0, 5, 'Coilskar Siren - World Loot Level 68'), +(19768, 2, 1100169, 0, 5, 'Coilskar Siren - World Loot Level 69'), +(19779, 1, 1100167, 0, 5, 'Sunfury Geologist - World Loot Level 67'), +(19779, 2, 1100168, 0, 5, 'Sunfury Geologist - World Loot Level 68'), +(19784, 1, 1100068, 0, 5, 'Coilskar Cobra - World Loot Level 68'), +(19788, 1, 1100170, 0, 5, 'Coilskar Muckwatcher - World Loot Level 70'), +(19789, 1, 1100169, 0, 5, 'Coilskar Waterkeeper - World Loot Level 69'), +(19792, 1, 1100168, 0, 5, 'Eclipsion Centurion - World Loot Level 68'), +(19792, 2, 1100169, 0, 5, 'Eclipsion Centurion - World Loot Level 69'), +(19795, 1, 1100169, 0, 5, 'Eclipsion Blood Knight - World Loot Level 69'), +(19796, 1, 1100168, 0, 5, 'Eclipsion Archmage - World Loot Level 68'), +(19796, 2, 1100169, 0, 5, 'Eclipsion Archmage - World Loot Level 69'), +(19799, 1, 1100169, 0, 5, 'Illidari Dreadbringer - World Loot Level 69'), +(19800, 1, 1100168, 0, 5, 'Illidari Painlasher - World Loot Level 68'), +(19800, 2, 1100169, 0, 5, 'Illidari Painlasher - World Loot Level 69'), +(19801, 1, 1100167, 30, 5, 'Illidari Agonizer - World Loot Level 67'), +(19802, 1, 1100168, 0, 5, 'Illidari Shocktrooper - World Loot Level 68'), +(19802, 2, 1100169, 0, 5, 'Illidari Shocktrooper - World Loot Level 69'), +(19806, 1, 1100170, 0, 5, 'Eclipsion Bloodwarder - World Loot Level 70'), +(19823, 1, 1100269, 0, 5, 'Crazed Colossus - World Loot Level 69'), +(19823, 2, 1100270, 0, 5, 'Crazed Colossus - World Loot Level 70'), +(19824, 1, 1100268, 0, 5, 'Son of Corok - World Loot Level 68'), +(19824, 2, 1100269, 0, 5, 'Son of Corok - World Loot Level 69'), +(19825, 1, 1100167, 0, 5, 'Dark Conclave Talonite - World Loot Level 67'), +(19826, 1, 1100167, 0, 5, 'Dark Conclave Shadowmancer - World Loot Level 67'), +(19826, 2, 1100168, 0, 5, 'Dark Conclave Shadowmancer - World Loot Level 68'), +(19827, 1, 1100168, 0, 5, 'Dark Conclave Ravenguard - World Loot Level 68'), +(19830, 1, 1100167, 0, 5, 'Arcanist Ardonis - World Loot Level 67'), +(19831, 1, 1100168, 0, 5, 'Commander Dawnforge - World Loot Level 68'), +(19843, 1, 1100370, 0, 5, 'Nethervine Trickster - World Loot Level 70'), +(19847, 1, 1100366, 0, 5, 'Levixus - World Loot Level 66'), +(19852, 1, 1100167, 0, 5, 'Artifact Seeker - World Loot Level 67'), +(19852, 2, 1100168, 0, 5, 'Artifact Seeker - World Loot Level 68'), +(19853, 1, 1100167, 0, 5, 'Felblade Doomguard - World Loot Level 67'), +(19853, 2, 1100168, 0, 5, 'Felblade Doomguard - World Loot Level 68'), +(19865, 1, 1100270, 0, 5, 'Mutate Horror - World Loot Level 70'), +(19881, 1, 1100168, 0, 5, 'Severed Spirit - World Loot Level 68'), +(19884, 1, 1100370, 0, 5, 'Bogstrok (1) - World Loot Level 70'), +(19885, 1, 1100371, 0, 5, 'Coilfang Champion (1) - World Loot Level 71'), +(19886, 1, 1100371, 0, 5, 'Coilfang Defender (1) - World Loot Level 71'), +(19887, 1, 1100370, 0, 5, 'Coilfang Enchantress (1) - World Loot Level 70'), +(19888, 1, 1100370, 0, 5, 'Coilfang Observer (1) - World Loot Level 70'), +(19889, 1, 1100371, 0, 5, 'Coilfang Slavehandler (1) - World Loot Level 71'), +(19890, 1, 1100370, 0, 5, 'Coilfang Soothsayer (1) - World Loot Level 70'), +(19891, 1, 1100371, 0, 5, 'Coilfang Technician (1) - World Loot Level 71'), +(19892, 1, 1100370, 0, 5, 'Greater Bogstrok (1) - World Loot Level 70'), +(19902, 1, 1100171, 0, 5, 'Wastewalker Slave (1) - World Loot Level 71'), +(19903, 1, 1100370, 0, 5, 'Coilfang Collaborator (1) - World Loot Level 70'), +(19904, 1, 1100171, 0, 5, 'Wastewalker Worker (1) - World Loot Level 71'), +(19926, 1, 1100168, 0, 5, 'Spellreaver Marathelle - World Loot Level 68'), +(19940, 1, 1100267, 0, 5, 'Apex - World Loot Level 67'), +(19940, 2, 1100268, 0, 5, 'Apex - World Loot Level 68'), +(19943, 1, 1100165, 0, 5, 'Lashh\'an Talonite - World Loot Level 65'), +(19943, 2, 1100166, 0, 5, 'Lashh\'an Talonite - World Loot Level 66'), +(19944, 1, 1100165, 0, 5, 'Lashh\'an Wing Guard - World Loot Level 65'), +(19944, 2, 1100166, 0, 5, 'Lashh\'an Wing Guard - World Loot Level 66'), +(19945, 1, 1100165, 0, 5, 'Lashh\'an Windwalker - World Loot Level 65'), +(19945, 2, 1100166, 0, 5, 'Lashh\'an Windwalker - World Loot Level 66'), +(19948, 1, 1100165, 0, 5, 'Bloodmaul Skirmisher - World Loot Level 65'), +(19948, 2, 1100166, 0, 5, 'Bloodmaul Skirmisher - World Loot Level 66'), +(19952, 1, 1100165, 0, 5, 'Bloodmaul Geomancer - World Loot Level 65'), +(19952, 2, 1100166, 0, 5, 'Bloodmaul Geomancer - World Loot Level 66'), +(19957, 1, 1100165, 0, 5, 'Bloodmaul Brewmaster - World Loot Level 65'), +(19957, 2, 1100166, 0, 5, 'Bloodmaul Brewmaster - World Loot Level 66'), +(19960, 1, 1100168, 0, 5, 'Doomforge Engineer - World Loot Level 68'), +(19961, 1, 1100168, 0, 5, 'Doomforge Attendant - World Loot Level 68'), +(19963, 1, 1100368, 0, 5, 'Doomcryer - World Loot Level 68'), +(19973, 1, 1100170, 0, 5, 'Abyssal Flamebringer - World Loot Level 70'), +(19973, 2, 1100171, 0, 5, 'Abyssal Flamebringer - World Loot Level 71'), +(19978, 1, 1100168, 0, 5, 'Deathforge Over-Smith - World Loot Level 68'), +(19979, 1, 1100167, 0, 5, 'Deathforge Technician - World Loot Level 67'), +(19979, 2, 1100168, 0, 5, 'Deathforge Technician - World Loot Level 68'), +(19980, 1, 1100067, 0, 5, 'Void Terror - World Loot Level 67'), +(19980, 2, 1100068, 0, 5, 'Void Terror - World Loot Level 68'), +(19982, 1, 1100165, 0, 5, 'Vekh\'nir Keeneye - World Loot Level 65'), +(19982, 2, 1100166, 0, 5, 'Vekh\'nir Keeneye - World Loot Level 66'), +(19983, 1, 1100165, 0, 5, 'Vekh\'nir Stormcaller - World Loot Level 65'), +(19983, 2, 1100166, 0, 5, 'Vekh\'nir Stormcaller - World Loot Level 66'), +(19984, 1, 1100165, 0, 5, 'Vekh\'nir Dreadhawk - World Loot Level 65'), +(19984, 2, 1100166, 0, 5, 'Vekh\'nir Dreadhawk - World Loot Level 66'), +(19985, 1, 1100166, 0, 5, 'Ruuan\'ok Cloudgazer - World Loot Level 66'), +(19985, 2, 1100167, 0, 5, 'Ruuan\'ok Cloudgazer - World Loot Level 67'), +(19986, 1, 1100166, 0, 5, 'Ruuan\'ok Skyfury - World Loot Level 66'), +(19986, 2, 1100167, 0, 5, 'Ruuan\'ok Skyfury - World Loot Level 67'), +(19987, 1, 1100166, 0, 5, 'Ruuan\'ok Ravenguard - World Loot Level 66'), +(19987, 2, 1100167, 0, 5, 'Ruuan\'ok Ravenguard - World Loot Level 67'), +(19988, 1, 1100167, 0, 5, 'Grishna Falconwing - World Loot Level 67'), +(19988, 2, 1100168, 0, 5, 'Grishna Falconwing - World Loot Level 68'), +(19989, 1, 1100167, 0, 5, 'Grishna Harbinger - World Loot Level 67'), +(19989, 2, 1100168, 0, 5, 'Grishna Harbinger - World Loot Level 68'), +(19990, 1, 1100167, 0, 5, 'Grishna Scorncrow - World Loot Level 67'), +(19990, 2, 1100168, 0, 5, 'Grishna Scorncrow - World Loot Level 68'), +(19991, 1, 1100165, 0, 5, 'Bloodmaul Brute - World Loot Level 65'), +(19991, 2, 1100166, 0, 5, 'Bloodmaul Brute - World Loot Level 66'), +(19992, 1, 1100165, 0, 5, 'Bloodmaul Shaman - World Loot Level 65'), +(19993, 1, 1100166, 0, 5, 'Bloodmaul Mauler - World Loot Level 66'), +(19993, 2, 1100167, 0, 5, 'Bloodmaul Mauler - World Loot Level 67'), +(19994, 1, 1100166, 0, 5, 'Bloodmaul Warlock - World Loot Level 66'), +(19994, 2, 1100167, 0, 5, 'Bloodmaul Warlock - World Loot Level 67'), +(19995, 1, 1100165, 0, 5, 'Bladespire Brute - World Loot Level 65'), +(19995, 2, 1100166, 0, 5, 'Bladespire Brute - World Loot Level 66'), +(19996, 1, 1100367, 0, 5, 'Bladespire Battlemage - World Loot Level 67'), +(19997, 1, 1100367, 0, 5, 'Bladespire Enforcer - World Loot Level 67'), +(19998, 1, 1100165, 0, 5, 'Bladespire Shaman - World Loot Level 65'), +(19998, 2, 1100166, 0, 5, 'Bladespire Shaman - World Loot Level 66'), +(20021, 1, 1100067, 0, 5, 'Nether Whelp - World Loot Level 67'), +(20031, 1, 1100371, 0, 5, 'Bloodwarder Legionnaire - World Loot Level 71'), +(20032, 1, 1100371, 0, 5, 'Bloodwarder Vindicator - World Loot Level 71'), +(20033, 1, 1100371, 0, 5, 'Astromancer - World Loot Level 71'), +(20034, 1, 1100371, 0, 5, 'Star Scryer - World Loot Level 71'), +(20035, 1, 1100372, 0, 5, 'Bloodwarder Marshal - World Loot Level 72'), +(20036, 1, 1100371, 0, 5, 'Bloodwarder Squire - World Loot Level 71'), +(20037, 1, 1100371, 0, 5, 'Tempest Falconer - World Loot Level 71'), +(20038, 1, 1100270, 0, 5, 'Phoenix-Hawk Hatchling - World Loot Level 70'), +(20039, 1, 1100272, 0, 5, 'Phoenix-Hawk - World Loot Level 72'), +(20040, 1, 1100272, 0, 5, 'Crystalcore Devastator - World Loot Level 72'), +(20041, 1, 1100272, 0, 5, 'Crystalcore Sentinel - World Loot Level 72'), +(20042, 1, 1100371, 0, 5, 'Tempest-Smith - World Loot Level 71'), +(20043, 1, 1100370, 0, 5, 'Apprentice Star Scryer - World Loot Level 70'), +(20044, 1, 1100370, 0, 5, 'Novice Astromancer - World Loot Level 70'), +(20045, 1, 1100372, 0, 5, 'Nether Scryer - World Loot Level 72'), +(20046, 1, 1100372, 0, 5, 'Astromancer Lord - World Loot Level 72'), +(20048, 1, 1100371, 0, 5, 'Crimson Hand Centurion - World Loot Level 71'), +(20049, 1, 1100371, 0, 5, 'Crimson Hand Blood Knight - World Loot Level 71'), +(20050, 1, 1100372, 0, 5, 'Crimson Hand Inquisitor - World Loot Level 72'), +(20052, 1, 1100371, 0, 5, 'Crystalcore Mechanic - World Loot Level 71'), +(20058, 1, 1100065, 0, 5, 'Bloodmaul Dire Wolf - World Loot Level 65'), +(20059, 1, 1100370, 0, 5, 'Sunseeker Netherbinder - World Loot Level 70'), +(20095, 1, 1100167, 0, 5, 'Grimnok Battleborn - World Loot Level 67'), +(20113, 1, 1100166, 0, 5, 'Lashh\'an Matriarch - World Loot Level 66'), +(20132, 1, 1100372, 0, 5, 'Socrethar - World Loot Level 72'), +(20134, 1, 1100167, 0, 5, 'Sunfury Arcanist - World Loot Level 67'), +(20134, 2, 1100168, 0, 5, 'Sunfury Arcanist - World Loot Level 68'), +(20135, 1, 1100168, 0, 5, 'Sunfury Arch Mage - World Loot Level 68'), +(20136, 1, 1100167, 0, 5, 'Sunfury Researcher - World Loot Level 67'), +(20136, 2, 1100168, 0, 5, 'Sunfury Researcher - World Loot Level 68'), +(20138, 1, 1100370, 0, 5, 'Culuthas - World Loot Level 70'), +(20139, 1, 1100168, 0, 5, 'Sunfury Conjurer - World Loot Level 68'), +(20139, 2, 1100169, 0, 5, 'Sunfury Conjurer - World Loot Level 69'), +(20140, 1, 1100168, 0, 5, 'Sunfury Centurion - World Loot Level 68'), +(20140, 2, 1100169, 0, 5, 'Sunfury Centurion - World Loot Level 69'), +(20141, 1, 1100069, 0, 5, 'Hound of Culuthas - World Loot Level 69'), +(20141, 2, 1100070, 0, 5, 'Hound of Culuthas - World Loot Level 70'), +(20161, 1, 1100166, 0, 5, 'Vekh\'nir Matriarch - World Loot Level 66'), +(20177, 1, 1100371, 0, 5, 'Murkblood Healer (1) - World Loot Level 71'), +(20179, 1, 1100370, 0, 5, 'Murkblood Oracle (1) - World Loot Level 70'), +(20180, 1, 1100371, 0, 5, 'Murkblood Spearman (1) - World Loot Level 71'), +(20181, 1, 1100371, 0, 5, 'Murkblood Tribesman (1) - World Loot Level 71'), +(20191, 1, 1100371, 0, 5, 'Wrathfin Myrmidon (1) - World Loot Level 71'), +(20192, 1, 1100371, 0, 5, 'Wrathfin Sentry (1) - World Loot Level 71'), +(20193, 1, 1100371, 0, 5, 'Wrathfin Warrior (1) - World Loot Level 71'), +(20202, 1, 1100269, 0, 5, 'Cragskaar - World Loot Level 69'), +(20207, 1, 1100168, 0, 5, 'Sunfury Bowman - World Loot Level 68'), +(20207, 2, 1100169, 0, 5, 'Sunfury Bowman - World Loot Level 69'), +(20210, 1, 1100167, 0, 5, 'Shaleskin Flayer - World Loot Level 67'), +(20210, 2, 1100168, 0, 5, 'Shaleskin Flayer - World Loot Level 68'), +(20211, 1, 1100167, 0, 5, 'Ruuan\'ok Matriarch - World Loot Level 67'), +(20215, 1, 1100169, 0, 5, 'Pentatharon - World Loot Level 69'), +(20216, 1, 1100370, 0, 5, 'Grulloc - World Loot Level 70'), +(20221, 1, 1100168, 0, 5, 'Sunfury Flamekeeper - World Loot Level 68'), +(20248, 1, 1100169, 0, 5, 'Sunfury Nethermancer - World Loot Level 69'), +(20248, 2, 1100170, 0, 5, 'Sunfury Nethermancer - World Loot Level 70'), +(20255, 1, 1100370, 0, 5, 'Ethereal Crypt Raider (1) - World Loot Level 70'), +(20256, 1, 1100371, 0, 5, 'Ethereal Darkcaster (1) - World Loot Level 71'), +(20258, 1, 1100370, 0, 5, 'Ethereal Scavenger (1) - World Loot Level 70'), +(20259, 1, 1100371, 0, 5, 'Ethereal Sorcerer (1) - World Loot Level 71'), +(20260, 1, 1100372, 0, 5, 'Ethereal Spellbinder (1) - World Loot Level 72'), +(20261, 1, 1100372, 0, 5, 'Ethereal Theurgist (1) - World Loot Level 72'), +(20265, 1, 1100270, 0, 5, 'Nexus Terror (1) - World Loot Level 70'), +(20285, 1, 1100168, 0, 5, 'Gan\'arg Warp-Tinker - World Loot Level 68'), +(20285, 2, 1100169, 0, 5, 'Gan\'arg Warp-Tinker - World Loot Level 69'), +(20326, 1, 1100170, 0, 5, 'Mo\'arg Warp-Master - World Loot Level 70'), +(20329, 1, 1100168, 0, 5, 'Grishna Matriarch - World Loot Level 68'), +(20330, 1, 1100066, 0, 5, 'Bloodmaul Battle Worg - World Loot Level 66'), +(20330, 2, 1100067, 0, 5, 'Bloodmaul Battle Worg - World Loot Level 67'), +(20332, 1, 1100070, 0, 5, 'Nether Dragon - World Loot Level 70'), +(20334, 1, 1100165, 0, 5, 'Bladespire Cook - World Loot Level 65'), +(20334, 2, 1100166, 0, 5, 'Bladespire Cook - World Loot Level 66'), +(20340, 1, 1100069, 0, 5, 'Fleshfiend - World Loot Level 69'), +(20340, 2, 1100070, 0, 5, 'Fleshfiend - World Loot Level 70'), +(20394, 1, 1100069, 0, 5, 'Eye of Culuthas - World Loot Level 69'), +(20394, 2, 1100070, 0, 5, 'Eye of Culuthas - World Loot Level 70'), +(20397, 1, 1100168, 0, 5, 'Overseer Seylanna - World Loot Level 68'), +(20404, 1, 1100168, 0, 5, 'Warp-Gate Engineer - World Loot Level 68'), +(20404, 2, 1100169, 0, 5, 'Warp-Gate Engineer - World Loot Level 69'), +(20409, 1, 1100169, 0, 5, 'Kirin\'Var Apprentice - World Loot Level 69'), +(20410, 1, 1100169, 0, 5, 'Rhonsus - World Loot Level 69'), +(20416, 1, 1100168, 0, 5, 'Overseer Theredis - World Loot Level 68'), +(20427, 1, 1100170, 0, 5, 'Veneratus the Many - World Loot Level 70'), +(20435, 1, 1100168, 0, 5, 'Overseer Athanel - World Loot Level 68'), +(20452, 1, 1100168, 0, 5, 'Ethereum Assassin - World Loot Level 68'), +(20452, 2, 1100169, 0, 5, 'Ethereum Assassin - World Loot Level 69'), +(20453, 1, 1100168, 0, 5, 'Ethereum Shocktrooper - World Loot Level 68'), +(20453, 2, 1100169, 0, 5, 'Ethereum Shocktrooper - World Loot Level 69'), +(20454, 1, 1100372, 0, 5, 'Nexus-King Salhadaar - World Loot Level 72'), +(20456, 1, 1100169, 0, 5, 'Ethereum Researcher - World Loot Level 69'), +(20456, 2, 1100170, 0, 5, 'Ethereum Researcher - World Loot Level 70'), +(20458, 1, 1100169, 0, 5, 'Ethereum Archon - World Loot Level 69'), +(20458, 2, 1100170, 0, 5, 'Ethereum Archon - World Loot Level 70'), +(20459, 1, 1100169, 0, 5, 'Ethereum Overlord - World Loot Level 69'), +(20459, 2, 1100170, 0, 5, 'Ethereum Overlord - World Loot Level 70'), +(20474, 1, 1100169, 0, 5, 'Ethereum Nexus-Stalker - World Loot Level 69'), +(20474, 2, 1100170, 0, 5, 'Ethereum Nexus-Stalker - World Loot Level 70'), +(20480, 1, 1100168, 0, 5, 'Kirin\'Var Ghost - World Loot Level 68'), +(20483, 1, 1100369, 0, 5, 'Naberius - World Loot Level 69'), +(20495, 1, 1100068, 0, 5, 'Skeletal Stallion - World Loot Level 68'), +(20496, 1, 1100160, 0, 5, 'Kirin\'Var Spectre - World Loot Level 60'), +(20501, 1, 1100069, 0, 5, 'Seeping Sludge - World Loot Level 69'), +(20501, 2, 1100070, 0, 5, 'Seeping Sludge - World Loot Level 70'), +(20502, 1, 1100067, 0, 5, 'Eclipsion Dragonhawk - World Loot Level 67'), +(20502, 2, 1100068, 0, 5, 'Eclipsion Dragonhawk - World Loot Level 68'), +(20512, 1, 1100168, 0, 5, 'Tormented Soul - World Loot Level 68'), +(20514, 1, 1100067, 0, 5, 'Searing Elemental - World Loot Level 67'), +(20514, 2, 1100068, 0, 5, 'Searing Elemental - World Loot Level 68'), +(20516, 1, 1100068, 0, 5, 'Warp Monstrosity - World Loot Level 68'), +(20516, 2, 1100069, 0, 5, 'Warp Monstrosity - World Loot Level 69'), +(20554, 1, 1100070, 0, 5, 'Arconus the Insatiable - World Loot Level 70'), +(20557, 1, 1100069, 0, 5, 'Wrath Hound - World Loot Level 69'), +(20557, 2, 1100070, 0, 5, 'Wrath Hound - World Loot Level 70'), +(20557, 3, 1100071, 0, 5, 'Wrath Hound - World Loot Level 71'), +(20600, 1, 1100370, 0, 5, 'Maggoc - World Loot Level 70'), +(20601, 1, 1100167, 0, 5, 'Razaani Raider - World Loot Level 67'), +(20601, 2, 1100168, 0, 5, 'Razaani Raider - World Loot Level 68'), +(20606, 1, 1100168, 0, 5, 'Shaleskin Ripper - World Loot Level 68'), +(20606, 2, 1100169, 0, 5, 'Shaleskin Ripper - World Loot Level 69'), +(20607, 1, 1100068, 0, 5, 'Craghide Basilisk - World Loot Level 68'), +(20607, 2, 1100069, 0, 5, 'Craghide Basilisk - World Loot Level 69'), +(20609, 1, 1100167, 0, 5, 'Razaani Nexus Stalker - World Loot Level 67'), +(20609, 2, 1100168, 0, 5, 'Razaani Nexus Stalker - World Loot Level 68'), +(20610, 1, 1100068, 0, 5, 'Talbuk Doe - World Loot Level 68'), +(20610, 2, 1100069, 0, 5, 'Talbuk Doe - World Loot Level 69'), +(20611, 1, 1100068, 0, 5, 'Shimmerwing Moth - World Loot Level 68'), +(20611, 2, 1100069, 0, 5, 'Shimmerwing Moth - World Loot Level 69'), +(20614, 1, 1100167, 0, 5, 'Razaani Spell-Thief - World Loot Level 67'), +(20614, 2, 1100168, 0, 5, 'Razaani Spell-Thief - World Loot Level 68'), +(20634, 1, 1100068, 0, 5, 'Scythetooth Raptor - World Loot Level 68'), +(20634, 2, 1100069, 0, 5, 'Scythetooth Raptor - World Loot Level 69'), +(20668, 1, 1100067, 0, 5, 'Fiendling Flesh Beast - World Loot Level 67'), +(20671, 1, 1100068, 0, 5, 'Ripfang Lynx - World Loot Level 68'), +(20671, 2, 1100069, 0, 5, 'Ripfang Lynx - World Loot Level 69'), +(20673, 1, 1100068, 0, 5, 'Swiftwing Shredder - World Loot Level 68'), +(20673, 2, 1100069, 0, 5, 'Swiftwing Shredder - World Loot Level 69'), +(20680, 1, 1100163, 0, 5, 'Arzeth the Powerless - World Loot Level 63'), +(20683, 1, 1100168, 0, 5, 'Prophetess Cavrylin - World Loot Level 68'), +(20683, 2, 1100169, 0, 5, 'Prophetess Cavrylin - World Loot Level 69'), +(20684, 1, 1100168, 0, 5, 'Lady Shav\'rar - World Loot Level 68'), +(20684, 2, 1100169, 0, 5, 'Lady Shav\'rar - World Loot Level 69'), +(20685, 1, 1100170, 0, 5, 'Overseer Azarad - World Loot Level 70'), +(20713, 1, 1100065, 0, 5, 'Fey Drake - World Loot Level 65'), +(20713, 2, 1100066, 0, 5, 'Fey Drake - World Loot Level 66'), +(20714, 1, 1100066, 0, 5, 'Ridgespine Stalker - World Loot Level 66'), +(20714, 2, 1100067, 0, 5, 'Ridgespine Stalker - World Loot Level 67'), +(20723, 1, 1100167, 0, 5, 'Korgaah - World Loot Level 67'), +(20726, 1, 1100166, 0, 5, 'Mugdorg - World Loot Level 66'), +(20727, 1, 1100170, 0, 5, 'Captain Zovax - World Loot Level 70'), +(20728, 1, 1100065, 0, 5, 'Bladespire Raptor - World Loot Level 65'), +(20728, 2, 1100066, 0, 5, 'Bladespire Raptor - World Loot Level 66'), +(20729, 1, 1100267, 0, 5, 'Bladespire Ravager - World Loot Level 67'), +(20730, 1, 1100166, 0, 5, 'Glumdor - World Loot Level 66'), +(20731, 1, 1100166, 0, 5, 'Droggam - World Loot Level 66'), +(20732, 1, 1100167, 0, 5, 'Gorr\'Dim - World Loot Level 67'), +(20747, 1, 1100065, 0, 5, 'Silkwing Larva - World Loot Level 65'), +(20747, 2, 1100066, 0, 5, 'Silkwing Larva - World Loot Level 66'), +(20748, 1, 1100065, 0, 5, 'Thunderlord Dire Wolf - World Loot Level 65'), +(20748, 2, 1100066, 0, 5, 'Thunderlord Dire Wolf - World Loot Level 66'), +(20749, 1, 1100066, 0, 5, 'Scalewing Serpent - World Loot Level 66'), +(20749, 2, 1100067, 0, 5, 'Scalewing Serpent - World Loot Level 67'), +(20751, 1, 1100066, 0, 5, 'Daggermaw Lashtail - World Loot Level 66'), +(20751, 2, 1100067, 0, 5, 'Daggermaw Lashtail - World Loot Level 67'), +(20753, 1, 1100167, 0, 5, 'Dorgok - World Loot Level 67'), +(20756, 1, 1100367, 0, 5, 'Bladespire Chef - World Loot Level 67'), +(20757, 1, 1100367, 0, 5, 'Fingrom - World Loot Level 67'), +(20765, 1, 1100167, 0, 5, 'Bladespire Crusher - World Loot Level 67'), +(20766, 1, 1100167, 0, 5, 'Bladespire Mystic - World Loot Level 67'), +(20768, 1, 1100167, 0, 5, 'Gnosh Brognat - World Loot Level 67'), +(20770, 1, 1100170, 0, 5, 'Warden Icoshock - World Loot Level 70'), +(20772, 1, 1100268, 0, 5, 'Netherock - World Loot Level 68'), +(20773, 1, 1100068, 0, 5, 'Barbscale Crocolisk - World Loot Level 68'), +(20773, 2, 1100069, 0, 5, 'Barbscale Crocolisk - World Loot Level 69'), +(20774, 1, 1100068, 0, 5, 'Farahlon Lasher - World Loot Level 68'), +(20774, 2, 1100069, 0, 5, 'Farahlon Lasher - World Loot Level 69'), +(20775, 1, 1100068, 0, 5, 'Markaru - World Loot Level 68'), +(20777, 1, 1100068, 0, 5, 'Talbuk Sire - World Loot Level 68'), +(20777, 2, 1100069, 0, 5, 'Talbuk Sire - World Loot Level 69'), +(20778, 1, 1100068, 0, 5, 'Void Waste - World Loot Level 68'), +(20778, 2, 1100069, 0, 5, 'Void Waste - World Loot Level 69'), +(20779, 1, 1100270, 0, 5, 'Congealed Void Horror - World Loot Level 70'), +(20783, 1, 1100071, 0, 5, 'Porfus the Gem Gorger - World Loot Level 71'), +(20795, 1, 1100168, 0, 5, 'Keeper of the Cistern - World Loot Level 68'), +(20795, 2, 1100169, 0, 5, 'Keeper of the Cistern - World Loot Level 69'), +(20800, 1, 1100368, 0, 5, 'Forgemaster Morug - World Loot Level 68'), +(20800, 2, 1100369, 0, 5, 'Forgemaster Morug - World Loot Level 69'), +(20801, 1, 1100368, 0, 5, 'Silroth - World Loot Level 68'), +(20801, 2, 1100369, 0, 5, 'Silroth - World Loot Level 69'), +(20803, 1, 1100170, 0, 5, 'Overmaster Grindgarr - World Loot Level 70'), +(20854, 1, 1100170, 0, 5, 'Ethereum Gladiator - World Loot Level 70'), +(20857, 1, 1100368, 0, 5, 'Arcatraz Defender - World Loot Level 68'), +(20857, 2, 1100369, 0, 5, 'Arcatraz Defender - World Loot Level 69'), +(20859, 1, 1100368, 0, 5, 'Arcatraz Warder - World Loot Level 68'), +(20859, 2, 1100369, 0, 5, 'Arcatraz Warder - World Loot Level 69'), +(20864, 1, 1100271, 0, 5, 'Protean Nightmare - World Loot Level 71'), +(20865, 1, 1100068, 0, 5, 'Protean Horror - World Loot Level 68'), +(20865, 2, 1100069, 0, 5, 'Protean Horror - World Loot Level 69'), +(20866, 1, 1100270, 0, 5, 'Soul Devourer - World Loot Level 70'), +(20867, 1, 1100270, 0, 5, 'Death Watcher - World Loot Level 70'), +(20868, 1, 1100270, 0, 5, 'Entropic Eye - World Loot Level 70'), +(20872, 1, 1100168, 0, 5, 'Deathforge Summoner - World Loot Level 68'), +(20872, 2, 1100169, 0, 5, 'Deathforge Summoner - World Loot Level 69'), +(20873, 1, 1100370, 0, 5, 'Negaton Warp-Master - World Loot Level 70'), +(20875, 1, 1100370, 0, 5, 'Negaton Screamer - World Loot Level 70'), +(20878, 1, 1100168, 0, 5, 'Deathforge Guardian - World Loot Level 68'), +(20878, 2, 1100169, 0, 5, 'Deathforge Guardian - World Loot Level 69'), +(20879, 1, 1100370, 0, 5, 'Eredar Soul-Eater - World Loot Level 70'), +(20881, 1, 1100370, 0, 5, 'Unbound Devastator - World Loot Level 70'), +(20882, 1, 1100370, 0, 5, 'Skulking Witch - World Loot Level 70'), +(20883, 1, 1100370, 0, 5, 'Spiteful Temptress - World Loot Level 70'), +(20887, 1, 1100167, 30, 5, 'Deathforge Imp - World Loot Level 67'), +(20888, 1, 1100372, 0, 5, 'Solus the Eternal - World Loot Level 72'), +(20896, 1, 1100370, 0, 5, 'Ethereum Slayer - World Loot Level 70'), +(20897, 1, 1100370, 0, 5, 'Ethereum Wave-Caster - World Loot Level 70'), +(20901, 1, 1100370, 0, 5, 'Sargeron Archer - World Loot Level 70'), +(20902, 1, 1100370, 0, 5, 'Sargeron Hellcaller - World Loot Level 70'), +(20905, 1, 1100370, 0, 5, 'Blazing Trickster - World Loot Level 70'), +(20906, 1, 1100272, 0, 5, 'Phase-Hunter - World Loot Level 72'), +(20908, 1, 1100272, 0, 5, 'Akkiris Lightning-Waker - World Loot Level 72'), +(20909, 1, 1100372, 0, 5, 'Sulfuron Magma-Thrower - World Loot Level 72'), +(20910, 1, 1100372, 0, 5, 'Twilight Drakonaar - World Loot Level 72'), +(20911, 1, 1100372, 0, 5, 'Blackwing Drakonaar - World Loot Level 72'), +(20924, 1, 1100067, 0, 5, 'Grishnath Basilisk - World Loot Level 67'), +(20925, 1, 1100067, 0, 5, 'Scalded Basilisk - World Loot Level 67'), +(20925, 2, 1100068, 0, 5, 'Scalded Basilisk - World Loot Level 68'), +(20927, 1, 1100168, 0, 5, 'Gan\'arg Technomancer - World Loot Level 68'), +(20927, 2, 1100169, 0, 5, 'Gan\'arg Technomancer - World Loot Level 69'), +(20928, 1, 1100169, 0, 5, 'Ironspine Forgelord - World Loot Level 69'), +(20929, 1, 1100170, 0, 5, 'Wrath Lord - World Loot Level 70'), +(20930, 1, 1100170, 0, 5, 'Hatecryer - World Loot Level 70'), +(20931, 1, 1100071, 0, 5, 'Tyrantus - World Loot Level 71'), +(20934, 1, 1100168, 0, 5, 'Severed Defender - World Loot Level 68'), +(20983, 1, 1100068, 0, 5, 'Mutated Farahlon Lasher - World Loot Level 68'), +(20983, 2, 1100069, 0, 5, 'Mutated Farahlon Lasher - World Loot Level 69'), +(20987, 1, 1100066, 0, 5, 'Ruuan Weald Basilisk - World Loot Level 66'), +(20988, 1, 1100369, 0, 5, 'Sunseeker Engineer - World Loot Level 69'), +(20990, 1, 1100369, 0, 5, 'Bloodwarder Physician - World Loot Level 69'), +(20998, 1, 1100068, 0, 5, 'Ridgespine Horror - World Loot Level 68'), +(21004, 1, 1100066, 0, 5, 'Lesser Nether Drake - World Loot Level 66'), +(21004, 2, 1100067, 0, 5, 'Lesser Nether Drake - World Loot Level 67'), +(21021, 1, 1100167, 0, 5, 'Scorch Imp - World Loot Level 67'), +(21021, 2, 1100168, 0, 5, 'Scorch Imp - World Loot Level 68'), +(21022, 1, 1100065, 0, 5, 'Grovestalker Lynx - World Loot Level 65'), +(21022, 2, 1100066, 0, 5, 'Grovestalker Lynx - World Loot Level 66'), +(21023, 1, 1100066, 0, 5, 'Stronglimb Deeproot - World Loot Level 66'), +(21032, 1, 1100068, 0, 5, 'Dreadwing - World Loot Level 68'), +(21033, 1, 1100065, 0, 5, 'Bladewing Bloodletter - World Loot Level 65'), +(21033, 2, 1100066, 0, 5, 'Bladewing Bloodletter - World Loot Level 66'), +(21042, 1, 1100067, 0, 5, 'Dire Raven - World Loot Level 67'), +(21042, 2, 1100068, 0, 5, 'Dire Raven - World Loot Level 68'), +(21046, 1, 1100167, 0, 5, 'Boulder\'mok Brute - World Loot Level 67'), +(21046, 2, 1100168, 0, 5, 'Boulder\'mok Brute - World Loot Level 68'), +(21047, 1, 1100167, 0, 5, 'Boulder\'mok Shaman - World Loot Level 67'), +(21047, 2, 1100168, 0, 5, 'Boulder\'mok Shaman - World Loot Level 68'), +(21048, 1, 1100168, 0, 5, 'Boulder\'mok Chieftain - World Loot Level 68'), +(21050, 1, 1100068, 0, 5, 'Enraged Earth Spirit - World Loot Level 68'), +(21050, 2, 1100069, 0, 5, 'Enraged Earth Spirit - World Loot Level 69'), +(21057, 1, 1100168, 0, 5, 'Nexus-Prince Razaan - World Loot Level 68'), +(21058, 1, 1100167, 0, 5, 'Disembodied Exarch - World Loot Level 67'), +(21058, 2, 1100168, 0, 5, 'Disembodied Exarch - World Loot Level 68'), +(21059, 1, 1100068, 0, 5, 'Enraged Water Spirit - World Loot Level 68'), +(21059, 2, 1100069, 0, 5, 'Enraged Water Spirit - World Loot Level 69'), +(21060, 1, 1100069, 0, 5, 'Enraged Air Spirit - World Loot Level 69'), +(21060, 2, 1100070, 0, 5, 'Enraged Air Spirit - World Loot Level 70'), +(21061, 1, 1100068, 0, 5, 'Enraged Fire Spirit - World Loot Level 68'), +(21061, 2, 1100069, 0, 5, 'Enraged Fire Spirit - World Loot Level 69'), +(21065, 1, 1100168, 0, 5, 'Tormented Citizen - World Loot Level 68'), +(21089, 1, 1100170, 0, 5, 'Sunfury Blood Knight - World Loot Level 70'), +(21102, 1, 1100270, 0, 5, 'Uvuros - World Loot Level 70'), +(21108, 1, 1100069, 0, 5, 'Spawn of Uvuros - World Loot Level 69'), +(21123, 1, 1100066, 0, 5, 'Felsworn Scalewing - World Loot Level 66'), +(21123, 2, 1100067, 0, 5, 'Felsworn Scalewing - World Loot Level 67'), +(21124, 1, 1100067, 0, 5, 'Felsworn Daggermaw - World Loot Level 67'), +(21124, 2, 1100068, 0, 5, 'Felsworn Daggermaw - World Loot Level 68'), +(21126, 1, 1100362, 0, 5, 'Coilfang Scale-Healer - World Loot Level 62'), +(21127, 1, 1100363, 0, 5, 'Coilfang Tempest - World Loot Level 63'), +(21164, 1, 1100370, 0, 5, 'Netharel - World Loot Level 70'), +(21168, 1, 1100370, 0, 5, 'Theras - World Loot Level 70'), +(21171, 1, 1100370, 0, 5, 'Alandien - World Loot Level 70'), +(21178, 1, 1100370, 0, 5, 'Varedis - World Loot Level 70'), +(21179, 1, 1100170, 0, 5, 'Demon Hunter Supplicant - World Loot Level 70'), +(21180, 1, 1100170, 0, 5, 'Demon Hunter Initiate - World Loot Level 70'), +(21181, 1, 1100272, 0, 5, 'Cyrukh the Firelord - World Loot Level 72'), +(21189, 1, 1100166, 0, 5, 'Crystal Flayer - World Loot Level 66'), +(21189, 2, 1100167, 0, 5, 'Crystal Flayer - World Loot Level 67'), +(21196, 1, 1100169, 0, 5, 'Ravenous Flayer - World Loot Level 69'), +(21196, 2, 1100170, 0, 5, 'Ravenous Flayer - World Loot Level 70'), +(21198, 1, 1100164, 0, 5, 'Deathtalon Spirit - World Loot Level 64'), +(21200, 1, 1100163, 0, 5, 'Screeching Spirit - World Loot Level 63'), +(21200, 2, 1100164, 0, 5, 'Screeching Spirit - World Loot Level 64'), +(21205, 1, 1100370, 0, 5, 'Ravenous Flayer Matriarch - World Loot Level 70'), +(21218, 1, 1100371, 0, 5, 'Vashj\'ir Honor Guard - World Loot Level 71'), +(21220, 1, 1100371, 0, 5, 'Coilfang Priestess - World Loot Level 71'), +(21221, 1, 1100371, 0, 5, 'Coilfang Beast-Tamer - World Loot Level 71'), +(21224, 1, 1100371, 0, 5, 'Tidewalker Depth-Seer - World Loot Level 71'), +(21225, 1, 1100371, 0, 5, 'Tidewalker Warrior - World Loot Level 71'), +(21226, 1, 1100371, 0, 5, 'Tidewalker Shaman - World Loot Level 71'), +(21227, 1, 1100371, 0, 5, 'Tidewalker Harpooner - World Loot Level 71'), +(21229, 1, 1100371, 0, 5, 'Greyheart Tidecaller - World Loot Level 71'), +(21230, 1, 1100371, 0, 5, 'Greyheart Nether-Mage - World Loot Level 71'), +(21231, 1, 1100371, 0, 5, 'Greyheart Shield-Bearer - World Loot Level 71'), +(21232, 1, 1100371, 0, 5, 'Greyheart Skulker - World Loot Level 71'), +(21238, 1, 1100165, 0, 5, 'Bloodmaul Drudger - World Loot Level 65'), +(21238, 2, 1100166, 0, 5, 'Bloodmaul Drudger - World Loot Level 66'), +(21242, 1, 1100164, 0, 5, 'Auchenai Death-Speaker - World Loot Level 64'), +(21246, 1, 1100271, 0, 5, 'Serpentshrine Sporebat - World Loot Level 71'), +(21249, 1, 1100368, 0, 5, 'Wrathstalker - World Loot Level 68'), +(21251, 1, 1100272, 0, 5, 'Underbog Colossus - World Loot Level 72'), +(21254, 1, 1100165, 0, 5, 'Dullgrom Dredger - World Loot Level 65'), +(21254, 2, 1100166, 0, 5, 'Dullgrom Dredger - World Loot Level 66'), +(21263, 1, 1100371, 0, 5, 'Greyheart Technician - World Loot Level 71'), +(21264, 1, 1100069, 12.5, 5, 'Seeping Ooze - World Loot Level 69'), +(21264, 2, 1100070, 12.5, 5, 'Seeping Ooze - World Loot Level 70'), +(21284, 1, 1100165, 0, 5, 'Auchenai Initiate - World Loot Level 65'), +(21284, 2, 1100166, 0, 5, 'Auchenai Initiate - World Loot Level 66'), +(21285, 1, 1100164, 0, 5, 'Auchenai Doomsayer - World Loot Level 64'), +(21285, 2, 1100165, 0, 5, 'Auchenai Doomsayer - World Loot Level 65'), +(21287, 1, 1100169, 0, 5, 'Warbringer Razuun - World Loot Level 69'), +(21296, 1, 1100166, 0, 5, 'Bladespire Champion - World Loot Level 66'), +(21298, 1, 1100371, 0, 5, 'Coilfang Serpentguard - World Loot Level 71'), +(21299, 1, 1100371, 0, 5, 'Coilfang Fathom-Witch - World Loot Level 71'), +(21300, 1, 1100166, 0, 5, 'Fel Corrupter - World Loot Level 66'), +(21300, 2, 1100167, 0, 5, 'Fel Corrupter - World Loot Level 67'), +(21301, 1, 1100371, 0, 5, 'Coilfang Shatterer - World Loot Level 71'), +(21302, 1, 1100167, 0, 5, 'Shadow Council Warlock - World Loot Level 67'), +(21305, 1, 1100067, 0, 5, 'Mutant Horror - World Loot Level 67'), +(21305, 2, 1100068, 0, 5, 'Mutant Horror - World Loot Level 68'), +(21309, 1, 1100170, 0, 5, 'Painmistress Gabrissa - World Loot Level 70'), +(21314, 1, 1100167, 0, 5, 'Terrormaster - World Loot Level 67'), +(21314, 2, 1100168, 0, 5, 'Terrormaster - World Loot Level 68'), +(21315, 1, 1100371, 0, 5, 'Ruul the Darkener - World Loot Level 71'), +(21324, 1, 1100063, 0, 5, 'Spirit Raven - World Loot Level 63'), +(21324, 2, 1100064, 0, 5, 'Spirit Raven - World Loot Level 64'), +(21325, 1, 1100267, 0, 5, 'Raven\'s Wood Stonebark - World Loot Level 67'), +(21325, 2, 1100268, 0, 5, 'Raven\'s Wood Stonebark - World Loot Level 68'), +(21326, 1, 1100067, 0, 5, 'Raven\'s Wood Leafbeard - World Loot Level 67'), +(21326, 2, 1100068, 0, 5, 'Raven\'s Wood Leafbeard - World Loot Level 68'), +(21337, 1, 1100169, 0, 5, 'Illidari Shadowstalker - World Loot Level 69'), +(21339, 1, 1100371, 0, 5, 'Coilfang Hate-Screamer - World Loot Level 71'), +(21350, 1, 1100372, 0, 5, 'Gronn-Priest - World Loot Level 72'), +(21368, 1, 1100164, 0, 5, 'Ethereal Plunderer - World Loot Level 64'), +(21368, 2, 1100165, 0, 5, 'Ethereal Plunderer - World Loot Level 65'), +(21370, 1, 1100164, 0, 5, 'Ethereal Nethermancer - World Loot Level 64'), +(21370, 2, 1100165, 0, 5, 'Ethereal Nethermancer - World Loot Level 65'), +(21373, 1, 1100065, 0, 5, 'Silkwing - World Loot Level 65'), +(21373, 2, 1100066, 0, 5, 'Silkwing - World Loot Level 66'), +(21380, 1, 1100067, 0, 5, 'Greater Crust Burster - World Loot Level 67'), +(21381, 1, 1100066, 0, 5, 'Young Crust Burster - World Loot Level 66'), +(21381, 2, 1100067, 0, 5, 'Young Crust Burster - World Loot Level 67'), +(21382, 1, 1100167, 0, 5, 'Wyrmcult Zealot - World Loot Level 67'), +(21382, 2, 1100168, 0, 5, 'Wyrmcult Zealot - World Loot Level 68'), +(21383, 1, 1100167, 0, 5, 'Wyrmcult Acolyte - World Loot Level 67'), +(21383, 2, 1100168, 0, 5, 'Wyrmcult Acolyte - World Loot Level 68'), +(21384, 1, 1100168, 0, 5, 'Dark Conclave Harbinger - World Loot Level 68'), +(21385, 1, 1100167, 0, 5, 'Dark Conclave Scorncrow - World Loot Level 67'), +(21385, 2, 1100168, 0, 5, 'Dark Conclave Scorncrow - World Loot Level 68'), +(21386, 1, 1100167, 0, 5, 'Dark Conclave Hawkeye - World Loot Level 67'), +(21387, 1, 1100067, 0, 5, 'Wyrmcult Blackwhelp - World Loot Level 67'), +(21387, 2, 1100068, 0, 5, 'Wyrmcult Blackwhelp - World Loot Level 68'), +(21389, 1, 1100168, 0, 5, 'Maxnar the Ashmaw - World Loot Level 68'), +(21405, 1, 1100164, 0, 5, 'Ethereal Arcanist - World Loot Level 64'), +(21405, 2, 1100165, 0, 5, 'Ethereal Arcanist - World Loot Level 65'), +(21408, 1, 1100067, 0, 5, 'Felfire Diemetradon - World Loot Level 67'), +(21408, 2, 1100068, 0, 5, 'Felfire Diemetradon - World Loot Level 68'), +(21409, 1, 1100170, 0, 5, 'Envoy Icarius - World Loot Level 70'), +(21416, 1, 1100170, 0, 5, 'Lakaan - World Loot Level 70'), +(21425, 1, 1100372, 0, 5, 'Nexus-King Salhadaar - World Loot Level 72'), +(21450, 1, 1100068, 0, 5, 'Skethyl Owl - World Loot Level 68'), +(21450, 2, 1100069, 0, 5, 'Skethyl Owl - World Loot Level 69'), +(21453, 1, 1100169, 0, 5, 'Ashtongue Shaman - World Loot Level 69'), +(21453, 2, 1100170, 0, 5, 'Ashtongue Shaman - World Loot Level 70'), +(21454, 1, 1100169, 0, 5, 'Ashtongue Warrior - World Loot Level 69'), +(21454, 2, 1100170, 0, 5, 'Ashtongue Warrior - World Loot Level 70'), +(21455, 1, 1100169, 0, 5, 'Ashtongue Worker - World Loot Level 69'), +(21462, 1, 1100068, 0, 5, 'Greater Felfire Diemetradon - World Loot Level 68'), +(21462, 2, 1100069, 0, 5, 'Greater Felfire Diemetradon - World Loot Level 69'), +(21477, 1, 1100169, 0, 5, 'Rocknail Flayer - World Loot Level 69'), +(21478, 1, 1100168, 0, 5, 'Rocknail Ripper - World Loot Level 68'), +(21478, 2, 1100169, 0, 5, 'Rocknail Ripper - World Loot Level 69'), +(21492, 1, 1100167, 0, 5, 'Wyrmcult Blessed - World Loot Level 67'), +(21492, 2, 1100168, 0, 5, 'Wyrmcult Blessed - World Loot Level 68'), +(21499, 1, 1100169, 0, 5, 'Overseer Ripsaw - World Loot Level 69'), +(21500, 1, 1100368, 0, 5, 'Morgroron - World Loot Level 68'), +(21500, 2, 1100369, 0, 5, 'Morgroron - World Loot Level 69'), +(21501, 1, 1100368, 0, 5, 'Makazradon - World Loot Level 68'), +(21501, 2, 1100369, 0, 5, 'Makazradon - World Loot Level 69'), +(21503, 1, 1100170, 0, 5, 'Sunfury Warlock - World Loot Level 70'), +(21505, 1, 1100170, 0, 5, 'Sunfury Summoner - World Loot Level 70'), +(21506, 1, 1100370, 0, 5, 'Azaloth - World Loot Level 70'), +(21516, 1, 1100168, 0, 5, 'Death\'s Watch - World Loot Level 68'), +(21519, 1, 1100168, 0, 5, 'Death\'s Might - World Loot Level 68'), +(21520, 1, 1100170, 0, 5, 'Illidari Jailor - World Loot Level 70'), +(21636, 1, 1100165, 0, 5, 'Vengeful Draenei - World Loot Level 65'), +(21637, 1, 1100167, 0, 5, 'Wyrmcult Scout - World Loot Level 67'), +(21637, 2, 1100168, 0, 5, 'Wyrmcult Scout - World Loot Level 68'), +(21640, 1, 1100165, 0, 5, 'Trogma - World Loot Level 65'), +(21640, 2, 1100166, 0, 5, 'Trogma - World Loot Level 66'), +(21644, 1, 1100170, 0, 5, 'Skettis Wing Guard - World Loot Level 70'), +(21644, 2, 1100171, 0, 5, 'Skettis Wing Guard - World Loot Level 71'), +(21648, 1, 1100269, 0, 5, 'Mature Netherwing Drake - World Loot Level 69'), +(21649, 1, 1100170, 0, 5, 'Skettis Windwalker - World Loot Level 70'), +(21649, 2, 1100171, 0, 5, 'Skettis Windwalker - World Loot Level 71'), +(21650, 1, 1100170, 0, 5, 'Skettis Talonite - World Loot Level 70'), +(21651, 1, 1100170, 0, 5, 'Time-Lost Skettis Reaver - World Loot Level 70'), +(21651, 2, 1100171, 0, 5, 'Time-Lost Skettis Reaver - World Loot Level 71'), +(21652, 1, 1100171, 0, 5, 'Skettis Time-Shifter - World Loot Level 71'), +(21652, 2, 1100172, 0, 5, 'Skettis Time-Shifter - World Loot Level 72'), +(21656, 1, 1100169, 0, 5, 'Illidari Satyr - World Loot Level 69'), +(21660, 1, 1100163, 0, 5, 'Cabal Abjurist - World Loot Level 63'), +(21660, 2, 1100164, 0, 5, 'Cabal Abjurist - World Loot Level 64'), +(21661, 1, 1100163, 0, 5, 'Cabal Skirmisher - World Loot Level 63'), +(21662, 1, 1100163, 0, 5, 'Cabal Tomb-Raider - World Loot Level 63'), +(21662, 2, 1100164, 0, 5, 'Cabal Tomb-Raider - World Loot Level 64'), +(21663, 1, 1100170, 0, 5, 'Oronu the Elder - World Loot Level 70'), +(21695, 1, 1100270, 0, 5, 'Tidal Surger - World Loot Level 70'), +(21696, 1, 1100070, 0, 5, 'Steam Surger - World Loot Level 70'), +(21702, 1, 1100370, 0, 5, 'Ethereum Life-Binder - World Loot Level 70'), +(21709, 1, 1100170, 0, 5, 'Eykenen - World Loot Level 70'), +(21710, 1, 1100170, 0, 5, 'Uylaru - World Loot Level 70'), +(21711, 1, 1100170, 0, 5, 'Haalum - World Loot Level 70'), +(21717, 1, 1100168, 0, 5, 'Dragonmaw Wrangler - World Loot Level 68'), +(21717, 2, 1100169, 0, 5, 'Dragonmaw Wrangler - World Loot Level 69'), +(21718, 1, 1100169, 0, 5, 'Dragonmaw Subjugator - World Loot Level 69'), +(21718, 2, 1100170, 0, 5, 'Dragonmaw Subjugator - World Loot Level 70'), +(21719, 1, 1100170, 0, 5, 'Dragonmaw Drake-Rider - World Loot Level 70'), +(21720, 1, 1100169, 0, 5, 'Dragonmaw Shaman - World Loot Level 69'), +(21720, 2, 1100170, 0, 5, 'Dragonmaw Shaman - World Loot Level 70'), +(21721, 1, 1100069, 0, 5, 'Enslaved Netherwing Whelp - World Loot Level 69'), +(21722, 1, 1100069, 0, 5, 'Enslaved Netherwing Drake - World Loot Level 69'), +(21723, 1, 1100070, 0, 5, 'Blackwind Sabercat - World Loot Level 70'), +(21723, 2, 1100071, 0, 5, 'Blackwind Sabercat - World Loot Level 71'), +(21724, 1, 1100270, 0, 5, 'Hawkbane - World Loot Level 70'), +(21728, 1, 1100070, 0, 5, 'Skettis Surger - World Loot Level 70'), +(21728, 2, 1100071, 0, 5, 'Skettis Surger - World Loot Level 71'), +(21730, 1, 1100272, 0, 5, 'Alluvion - World Loot Level 72'), +(21742, 1, 1100167, 0, 5, 'Sunfury Eradicator - World Loot Level 67'), +(21742, 2, 1100168, 0, 5, 'Sunfury Eradicator - World Loot Level 68'), +(21743, 1, 1100168, 0, 5, 'Sunfury Blood Lord - World Loot Level 68'), +(21763, 1, 1100171, 0, 5, 'Time-Lost Skettis Worshipper - World Loot Level 71'), +(21767, 1, 1100168, 0, 5, 'Harbinger of the Raven - World Loot Level 68'), +(21784, 1, 1100170, 0, 5, 'Ghostrider of Karabor - World Loot Level 70'), +(21787, 1, 1100171, 0, 5, 'Time-Lost Skettis High Priest - World Loot Level 71'), +(21788, 1, 1100168, 0, 5, 'Shadowmoon Zealot - World Loot Level 68'), +(21788, 2, 1100169, 0, 5, 'Shadowmoon Zealot - World Loot Level 69'), +(21795, 1, 1100168, 0, 5, 'Shadowmoon Harbinger - World Loot Level 68'), +(21795, 2, 1100169, 0, 5, 'Shadowmoon Harbinger - World Loot Level 69'), +(21801, 1, 1100370, 0, 5, 'Vhel\'kur - World Loot Level 70'), +(21802, 1, 1100069, 0, 5, 'Elekk Demolisher - World Loot Level 69'), +(21803, 1, 1100169, 0, 5, 'Ashtongue Handler - World Loot Level 69'), +(21804, 1, 1100070, 0, 5, 'Skettis Kaliri - World Loot Level 70'), +(21808, 1, 1100169, 0, 5, 'Illidari Overseer - World Loot Level 69'), +(21809, 1, 1100166, 0, 5, 'Wyrmcult Poacher - World Loot Level 66'), +(21809, 2, 1100167, 0, 5, 'Wyrmcult Poacher - World Loot Level 67'), +(21810, 1, 1100166, 0, 5, 'Wyrmcult Hewer - World Loot Level 66'), +(21810, 2, 1100167, 0, 5, 'Wyrmcult Hewer - World Loot Level 67'), +(21815, 1, 1100169, 0, 5, 'Cleric of Karabor - World Loot Level 69'), +(21815, 2, 1100170, 0, 5, 'Cleric of Karabor - World Loot Level 70'), +(21816, 1, 1100063, 0, 5, 'Ironspine Chomper - World Loot Level 63'), +(21816, 2, 1100064, 0, 5, 'Ironspine Chomper - World Loot Level 64'), +(21817, 1, 1100067, 0, 5, 'Adolescent Nether Drake - World Loot Level 67'), +(21820, 1, 1100067, 0, 5, 'Mature Nether Drake - World Loot Level 67'), +(21821, 1, 1100067, 0, 5, 'Proto-Nether Drake - World Loot Level 67'), +(21827, 1, 1100170, 0, 5, 'Zandras - World Loot Level 70'), +(21839, 1, 1100065, 0, 5, 'Mature Silkwing - World Loot Level 65'), +(21839, 2, 1100066, 0, 5, 'Mature Silkwing - World Loot Level 66'), +(21842, 1, 1100370, 0, 5, 'Coilfang Scale-Healer (1) - World Loot Level 70'), +(21843, 1, 1100370, 0, 5, 'Coilfang Tempest (1) - World Loot Level 70'), +(21844, 1, 1100271, 0, 5, 'Mountain Colossus - World Loot Level 71'), +(21844, 2, 1100272, 0, 5, 'Mountain Colossus - World Loot Level 72'), +(21849, 1, 1100064, 0, 5, 'Bone Crawler - World Loot Level 64'), +(21849, 2, 1100065, 0, 5, 'Bone Crawler - World Loot Level 65'), +(21854, 1, 1100062, 0, 5, 'Ironspine Petrifier - World Loot Level 62'), +(21854, 2, 1100063, 0, 5, 'Ironspine Petrifier - World Loot Level 63'), +(21863, 1, 1100270, 0, 5, 'Serpentshrine Lurker - World Loot Level 70'), +(21864, 1, 1100068, 0, 5, 'Scorchshell Pincer - World Loot Level 68'), +(21864, 2, 1100069, 0, 5, 'Scorchshell Pincer - World Loot Level 69'), +(21878, 1, 1100067, 0, 5, 'Felboar - World Loot Level 67'), +(21878, 2, 1100068, 0, 5, 'Felboar - World Loot Level 68'), +(21879, 1, 1100068, 0, 5, 'Vilewing Chimaera - World Loot Level 68'), +(21891, 1, 1100067, 0, 5, 'Avian Ripper - World Loot Level 67'), +(21897, 1, 1100070, 0, 5, 'Felspine the Greater - World Loot Level 70'), +(21901, 1, 1100069, 0, 5, 'Netherskate - World Loot Level 69'), +(21901, 2, 1100070, 0, 5, 'Netherskate - World Loot Level 70'), +(21902, 1, 1100162, 0, 5, 'Cabal Spell-weaver - World Loot Level 62'), +(21902, 2, 1100163, 0, 5, 'Cabal Spell-weaver - World Loot Level 63'), +(21904, 1, 1100268, 0, 5, 'Avian Warhawk - World Loot Level 68'), +(21907, 1, 1100162, 0, 5, 'Cabal Initiate - World Loot Level 62'), +(21907, 2, 1100163, 0, 5, 'Cabal Initiate - World Loot Level 63'), +(21911, 1, 1100170, 0, 5, 'Skettis Soulcaller - World Loot Level 70'), +(21911, 2, 1100171, 0, 5, 'Skettis Soulcaller - World Loot Level 71'), +(21912, 1, 1100171, 0, 5, 'Skettis Sentinel - World Loot Level 71'), +(21912, 2, 1100172, 0, 5, 'Skettis Sentinel - World Loot Level 72'), +(21923, 1, 1100168, 0, 5, 'Terrorguard Protector - World Loot Level 68'), +(21923, 2, 1100169, 0, 5, 'Terrorguard Protector - World Loot Level 69'), +(21941, 1, 1100164, 0, 5, 'Accursed Apparition - World Loot Level 64'), +(21941, 2, 1100165, 0, 5, 'Accursed Apparition - World Loot Level 65'), +(21956, 1, 1100066, 0, 5, 'Rema - World Loot Level 66'), +(21963, 1, 1100164, 0, 5, 'Enslaved Doomguard - World Loot Level 64'), +(21979, 1, 1100370, 0, 5, 'Val\'zareq the Conqueror - World Loot Level 70'), +(21985, 1, 1100171, 0, 5, 'Skettis Eviscerator - World Loot Level 71'), +(21985, 2, 1100172, 0, 5, 'Skettis Eviscerator - World Loot Level 72'), +(22011, 1, 1100270, 0, 5, 'Corok the Mighty - World Loot Level 70'), +(22012, 1, 1100370, 0, 5, 'Chancellor Bloodleaf - World Loot Level 70'), +(22016, 1, 1100168, 0, 5, 'Eclipsion Soldier - World Loot Level 68'), +(22016, 2, 1100169, 0, 5, 'Eclipsion Soldier - World Loot Level 69'), +(22017, 1, 1100168, 0, 5, 'Eclipsion Spellbinder - World Loot Level 68'), +(22017, 2, 1100169, 0, 5, 'Eclipsion Spellbinder - World Loot Level 69'), +(22018, 1, 1100169, 0, 5, 'Eclipsion Cavalier - World Loot Level 69'), +(22038, 1, 1100265, 0, 5, 'Hai\'shulud - World Loot Level 65'), +(22038, 2, 1100266, 0, 5, 'Hai\'shulud - World Loot Level 66'), +(22044, 1, 1100065, 0, 5, 'Cavern Crawler - World Loot Level 65'), +(22045, 1, 1100165, 0, 5, 'Vengeful Husk - World Loot Level 65'), +(22045, 2, 1100166, 0, 5, 'Vengeful Husk - World Loot Level 66'), +(22052, 1, 1100065, 0, 5, 'Daggermaw Blackhide - World Loot Level 65'), +(22052, 2, 1100066, 0, 5, 'Daggermaw Blackhide - World Loot Level 66'), +(22072, 1, 1100370, 0, 5, 'Shadowsworn Drakonid - World Loot Level 70'), +(22076, 1, 1100372, 0, 5, 'Torloth the Magnificent - World Loot Level 72'), +(22081, 1, 1100169, 0, 5, 'Shadowmoon Darkweaver - World Loot Level 69'), +(22081, 2, 1100170, 0, 5, 'Shadowmoon Darkweaver - World Loot Level 70'), +(22082, 1, 1100168, 0, 5, 'Shadowmoon Slayer - World Loot Level 68'), +(22082, 2, 1100169, 0, 5, 'Shadowmoon Slayer - World Loot Level 69'), +(22084, 1, 1100170, 0, 5, 'Shadowmoon Chosen - World Loot Level 70'), +(22093, 1, 1100370, 0, 5, 'Illidari Watcher - World Loot Level 70'), +(22095, 1, 1100064, 0, 5, 'Infested Root-Walker - World Loot Level 64'), +(22095, 2, 1100065, 0, 5, 'Infested Root-Walker - World Loot Level 65'), +(22099, 1, 1100167, 0, 5, 'Wyrmcult Provisioner - World Loot Level 67'), +(22099, 2, 1100168, 0, 5, 'Wyrmcult Provisioner - World Loot Level 68'), +(22100, 1, 1100064, 0, 5, 'Scorpid Bonecrawler - World Loot Level 64'), +(22100, 2, 1100065, 0, 5, 'Scorpid Bonecrawler - World Loot Level 65'), +(22105, 1, 1100064, 0, 5, 'Decrepit Clefthoof - World Loot Level 64'), +(22105, 2, 1100065, 0, 5, 'Decrepit Clefthoof - World Loot Level 65'), +(22123, 1, 1100063, 0, 5, 'Rip-Blade Ravager - World Loot Level 63'), +(22132, 1, 1100065, 0, 5, 'Mature Cavern Crawler - World Loot Level 65'), +(22143, 1, 1100171, 0, 5, 'Gordunni Back-Breaker - World Loot Level 71'), +(22143, 2, 1100172, 0, 5, 'Gordunni Back-Breaker - World Loot Level 72'), +(22144, 1, 1100170, 0, 5, 'Gordunni Elementalist - World Loot Level 70'), +(22144, 2, 1100171, 0, 5, 'Gordunni Elementalist - World Loot Level 71'), +(22148, 1, 1100171, 0, 5, 'Gordunni Head-Splitter - World Loot Level 71'), +(22148, 2, 1100172, 0, 5, 'Gordunni Head-Splitter - World Loot Level 72'), +(22160, 1, 1100166, 0, 5, 'Bloodmaul Taskmaster - World Loot Level 66'), +(22160, 2, 1100167, 0, 5, 'Bloodmaul Taskmaster - World Loot Level 67'), +(22175, 1, 1100171, 0, 5, 'Apexis Flayer - World Loot Level 71'), +(22175, 2, 1100172, 0, 5, 'Apexis Flayer - World Loot Level 72'), +(22180, 1, 1100070, 0, 5, 'Shard-Hide Boar - World Loot Level 70'), +(22180, 2, 1100071, 0, 5, 'Shard-Hide Boar - World Loot Level 71'), +(22181, 1, 1100070, 0, 5, 'Aether Ray - World Loot Level 70'), +(22181, 2, 1100071, 0, 5, 'Aether Ray - World Loot Level 71'), +(22182, 1, 1100070, 0, 5, 'Lightning Wasp - World Loot Level 70'), +(22182, 2, 1100071, 0, 5, 'Lightning Wasp - World Loot Level 71'), +(22187, 1, 1100071, 0, 5, 'Bladespine Basilisk - World Loot Level 71'), +(22187, 2, 1100072, 0, 5, 'Bladespine Basilisk - World Loot Level 72'), +(22194, 1, 1100070, 0, 5, 'Spire Needler - World Loot Level 70'), +(22194, 2, 1100071, 0, 5, 'Spire Needler - World Loot Level 71'), +(22194, 3, 1100072, 0, 5, 'Spire Needler - World Loot Level 72'), +(22195, 1, 1100170, 0, 5, 'Wrath Speaker - World Loot Level 70'), +(22195, 2, 1100171, 0, 5, 'Wrath Speaker - World Loot Level 71'), +(22199, 1, 1100370, 0, 5, 'Slaag - World Loot Level 70'), +(22201, 1, 1100170, 0, 5, 'Fear Whisperer - World Loot Level 70'), +(22201, 2, 1100171, 0, 5, 'Fear Whisperer - World Loot Level 71'), +(22202, 1, 1100170, 0, 5, 'Nightmare Imp - World Loot Level 70'), +(22204, 1, 1100171, 0, 5, 'Fear Fiend - World Loot Level 71'), +(22217, 1, 1100166, 0, 5, 'Felstorm Corruptor - World Loot Level 66'), +(22217, 2, 1100167, 0, 5, 'Felstorm Corruptor - World Loot Level 67'), +(22221, 1, 1100171, 0, 5, 'Felstorm Overseer - World Loot Level 71'), +(22241, 1, 1100170, 0, 5, 'Bash\'ir Raider - World Loot Level 70'), +(22241, 2, 1100171, 0, 5, 'Bash\'ir Raider - World Loot Level 71'), +(22242, 1, 1100170, 0, 5, 'Bash\'ir Spell-Thief - World Loot Level 70'), +(22242, 2, 1100171, 0, 5, 'Bash\'ir Spell-Thief - World Loot Level 71'), +(22243, 1, 1100171, 0, 5, 'Bash\'ir Arcanist - World Loot Level 71'), +(22243, 2, 1100172, 0, 5, 'Bash\'ir Arcanist - World Loot Level 72'), +(22244, 1, 1100070, 0, 5, 'Unbound Ethereal - World Loot Level 70'), +(22244, 2, 1100071, 0, 5, 'Unbound Ethereal - World Loot Level 71'), +(22252, 1, 1100168, 0, 5, 'Dragonmaw Peon - World Loot Level 68'), +(22252, 2, 1100169, 0, 5, 'Dragonmaw Peon - World Loot Level 69'), +(22253, 1, 1100372, 0, 5, 'Dragonmaw Ascendant - World Loot Level 72'), +(22254, 1, 1100170, 0, 5, 'Wrath Corruptor - World Loot Level 70'), +(22254, 2, 1100171, 0, 5, 'Wrath Corruptor - World Loot Level 71'), +(22254, 3, 1100172, 0, 5, 'Wrath Corruptor - World Loot Level 72'), +-- Removed from the game +-- (22255, 1, 1100071, 0, 5, 'Daggertail Lizard - World Loot Level 71'), +-- (22255, 2, 1100072, 0, 5, 'Daggertail Lizard - World Loot Level 72'), +-- (22255, 3, 1100073, 0, 5, 'Daggertail Lizard - World Loot Level 73'), +-- (22257, 1, 1100071, 0, 5, 'Deathlash Stinger - World Loot Level 71'), +-- (22257, 2, 1100072, 0, 5, 'Deathlash Stinger - World Loot Level 72'), +-- (22257, 3, 1100073, 0, 5, 'Deathlash Stinger - World Loot Level 73'), +-- (22261, 1, 1100171, 0, 5, 'Bladespire Guardian - World Loot Level 71'), +-- (22261, 2, 1100172, 0, 5, 'Bladespire Guardian - World Loot Level 72'), +-- (22261, 3, 1100173, 0, 5, 'Bladespire Guardian - World Loot Level 73'), +-- (22262, 1, 1100171, 0, 5, 'Bladespire Elder - World Loot Level 71'), +-- (22262, 2, 1100172, 0, 5, 'Bladespire Elder - World Loot Level 72'), +-- (22262, 3, 1100173, 0, 5, 'Bladespire Elder - World Loot Level 73'), +-- (22263, 1, 1100171, 0, 5, 'Bladespire Keg King - World Loot Level 71'), +-- (22263, 2, 1100172, 0, 5, 'Bladespire Keg King - World Loot Level 72'), +-- (22263, 3, 1100173, 0, 5, 'Bladespire Keg King - World Loot Level 73'), +(22265, 1, 1100066, 0, 5, 'Shadowwing Owl - World Loot Level 66'), +(22265, 2, 1100067, 0, 5, 'Shadowwing Owl - World Loot Level 67'), +(22275, 1, 1100272, 0, 5, 'Apexis Guardian - World Loot Level 72'), +(22281, 1, 1100372, 0, 5, 'Galvanoth - World Loot Level 72'), +(22286, 1, 1100070, 0, 5, 'Fel Rager - World Loot Level 70'), +(22286, 2, 1100071, 0, 5, 'Fel Rager - World Loot Level 71'), +(22287, 1, 1100071, 0, 5, 'Amberpelt Clefthoof - World Loot Level 71'), +(22287, 2, 1100072, 0, 5, 'Amberpelt Clefthoof - World Loot Level 72'), +(22289, 1, 1100070, 0, 5, 'Darkflame Infernal - World Loot Level 70'), +(22289, 2, 1100071, 0, 5, 'Darkflame Infernal - World Loot Level 71'), +(22291, 1, 1100170, 0, 5, 'Furnace Guard - World Loot Level 70'), +(22291, 2, 1100171, 0, 5, 'Furnace Guard - World Loot Level 71'), +(22291, 3, 1100172, 0, 5, 'Furnace Guard - World Loot Level 72'), +(22295, 1, 1100271, 0, 5, 'Deathforge Automaton - World Loot Level 71'), +(22295, 2, 1100272, 0, 5, 'Deathforge Automaton - World Loot Level 72'), +(22297, 1, 1100372, 0, 5, 'Throne-Guard Highlord - World Loot Level 72'), +(22298, 1, 1100071, 0, 5, 'Vile Fire-Soul - World Loot Level 71'), +(22303, 1, 1100270, 0, 5, 'Throne Hound - World Loot Level 70'), +(22303, 2, 1100271, 0, 5, 'Throne Hound - World Loot Level 71'), +(22304, 1, 1100171, 0, 5, 'Mo\'arg Extractor - World Loot Level 71'), +(22305, 1, 1100167, 0, 5, 'Vekh - World Loot Level 67'), +(22307, 1, 1100065, 0, 5, 'Rotting Forest-Rager - World Loot Level 65'), +(22308, 1, 1100166, 0, 5, 'Wyrmcult Hunter - World Loot Level 66'), +(22308, 2, 1100167, 0, 5, 'Wyrmcult Hunter - World Loot Level 67'), +(22309, 1, 1100070, 0, 5, 'Crashing Wave-Spirit - World Loot Level 70'), +(22309, 2, 1100071, 0, 5, 'Crashing Wave-Spirit - World Loot Level 71'), +(22310, 1, 1100070, 0, 5, 'Storming Wind-Ripper - World Loot Level 70'), +(22310, 2, 1100071, 0, 5, 'Storming Wind-Ripper - World Loot Level 71'), +(22311, 1, 1100070, 0, 5, 'Raging Fire-Soul - World Loot Level 70'), +(22311, 2, 1100071, 0, 5, 'Raging Fire-Soul - World Loot Level 71'), +(22313, 1, 1100070, 0, 5, 'Rumbling Earth-Heart - World Loot Level 70'), +(22313, 2, 1100071, 0, 5, 'Rumbling Earth-Heart - World Loot Level 71'), +(22325, 1, 1100370, 0, 5, 'Nightmare Weaver - World Loot Level 70'), +(22325, 2, 1100371, 0, 5, 'Nightmare Weaver - World Loot Level 71'), +(22327, 1, 1100171, 0, 5, 'Terror-Fire Guardian - World Loot Level 71'), +(22327, 2, 1100172, 0, 5, 'Terror-Fire Guardian - World Loot Level 72'), +(22341, 1, 1100170, 0, 5, 'Deathshadow Acolyte - World Loot Level 70'), +(22341, 2, 1100171, 0, 5, 'Deathshadow Acolyte - World Loot Level 71'), +(22342, 1, 1100170, 0, 5, 'Deathshadow Spellbinder - World Loot Level 70'), +(22342, 2, 1100171, 0, 5, 'Deathshadow Spellbinder - World Loot Level 71'), +(22343, 1, 1100170, 0, 5, 'Deathshadow Archon - World Loot Level 70'), +(22343, 2, 1100171, 0, 5, 'Deathshadow Archon - World Loot Level 71'), +-- (22357, 1, 1100373, 0, 5, 'Reth\'hedron the Subduer - World Loot Level 73'), -- This is wrong +(22363, 1, 1100170, 0, 5, 'Deathshadow Warlock - World Loot Level 70'), +(22363, 2, 1100171, 0, 5, 'Deathshadow Warlock - World Loot Level 71'), +(22378, 1, 1100164, 0, 5, 'Cabal Interrogator - World Loot Level 64'), +(22378, 2, 1100165, 0, 5, 'Cabal Interrogator - World Loot Level 65'), +(22384, 1, 1100166, 0, 5, 'Bloodmaul Soothsayer - World Loot Level 66'), +(22384, 2, 1100167, 0, 5, 'Bloodmaul Soothsayer - World Loot Level 67'), +(22387, 1, 1100164, 0, 5, 'Lithic Oracle - World Loot Level 64'), +(22387, 2, 1100165, 0, 5, 'Lithic Oracle - World Loot Level 65'), +(22388, 1, 1100163, 0, 5, 'Lithic Talonguard - World Loot Level 63'), +(22388, 2, 1100164, 0, 5, 'Lithic Talonguard - World Loot Level 64'), +(22392, 1, 1100171, 0, 5, 'Wrath Fiend - World Loot Level 71'), +(22392, 2, 1100172, 0, 5, 'Wrath Fiend - World Loot Level 72'), +(22393, 1, 1100370, 0, 5, 'Deathshadow Overlord - World Loot Level 70'), +(22393, 2, 1100371, 0, 5, 'Deathshadow Overlord - World Loot Level 71'), +(22394, 1, 1100070, 0, 5, 'Deathshadow Hound - World Loot Level 70'), +(22394, 2, 1100071, 0, 5, 'Deathshadow Hound - World Loot Level 71'), +(22466, 1, 1100064, 0, 5, 'Bone Sifter - World Loot Level 64'), +(22466, 2, 1100065, 0, 5, 'Bone Sifter - World Loot Level 65'), +(22482, 1, 1100064, 0, 5, 'Mature Bone Sifter - World Loot Level 64'), +(22482, 2, 1100065, 0, 5, 'Mature Bone Sifter - World Loot Level 65'), +(22807, 1, 1100070, 0, 5, 'Lost Torranche - World Loot Level 70'), +(22825, 1, 1100372, 0, 5, 'Matron Li-sahar - World Loot Level 72'), +(22826, 1, 1100372, 0, 5, 'King Dorfbruiser - World Loot Level 72'), +(22827, 1, 1100372, 0, 5, 'Gorgolon the All-seeing - World Loot Level 72'), +(22828, 1, 1100372, 0, 5, 'Trelopades - World Loot Level 72'), +(22844, 1, 1100372, 0, 5, 'Ashtongue Battlelord - World Loot Level 72'), +(22845, 1, 1100371, 0, 5, 'Ashtongue Mystic - World Loot Level 71'), +(22846, 1, 1100371, 0, 5, 'Ashtongue Stormcaller - World Loot Level 71'), +(22847, 1, 1100372, 0, 5, 'Ashtongue Primalist - World Loot Level 72'), +(22853, 1, 1100371, 0, 5, 'Illidari Defiler - World Loot Level 71'), +(22855, 1, 1100372, 0, 5, 'Illidari Nightlord - World Loot Level 72'), +(22869, 1, 1100371, 0, 5, 'Illidari Boneslicer - World Loot Level 71'), +(22873, 1, 1100371, 0, 5, 'Coilskar General - World Loot Level 71'), +(22874, 1, 1100371, 0, 5, 'Coilskar Harpooner - World Loot Level 71'), +(22875, 1, 1100371, 0, 5, 'Coilskar Sea-Caller - World Loot Level 71'), +(22876, 1, 1100371, 0, 5, 'Coilskar Soothsayer - World Loot Level 71'), +(22877, 1, 1100371, 0, 5, 'Coilskar Wrangler - World Loot Level 71'), +(22878, 1, 1100272, 0, 5, 'Aqueous Lord - World Loot Level 72'), +(22879, 1, 1100372, 0, 5, 'Shadowmoon Reaver - World Loot Level 72'), +(22880, 1, 1100372, 0, 5, 'Shadowmoon Champion - World Loot Level 72'), +(22881, 1, 1100270, 0, 5, 'Aqueous Surger - World Loot Level 70'), +(22882, 1, 1100372, 0, 5, 'Shadowmoon Deathshaper - World Loot Level 72'), +(22883, 1, 1100270, 0, 5, 'Aqueous Spawn - World Loot Level 70'), +(22883, 2, 1100271, 0, 5, 'Aqueous Spawn - World Loot Level 71'), +(22883, 3, 1100272, 0, 5, 'Aqueous Spawn - World Loot Level 72'), +(22884, 1, 1100272, 0, 5, 'Leviathan - World Loot Level 72'), +(22885, 1, 1100270, 0, 5, 'Dragon Turtle - World Loot Level 70'), +(22939, 1, 1100370, 0, 5, 'Temple Concubine - World Loot Level 70'), +(22945, 1, 1100372, 0, 5, 'Shadowmoon Blood Mage - World Loot Level 72'), +(22946, 1, 1100071, 0, 5, 'Shadowmoon War Hound - World Loot Level 71'), +(22953, 1, 1100371, 0, 5, 'Wrathbone Flayer - World Loot Level 71'), +(22954, 1, 1100372, 0, 5, 'Illidari Fearbringer - World Loot Level 72'), +(22955, 1, 1100370, 0, 5, 'Charming Courtesan - World Loot Level 70'), +(22956, 1, 1100372, 0, 5, 'Sister of Pain - World Loot Level 72'), +(22957, 1, 1100372, 0, 5, 'Priestess of Dementia - World Loot Level 72'), +(22959, 1, 1100370, 0, 5, 'Spellbound Attendant - World Loot Level 70'), +(22960, 1, 1100371, 0, 5, 'Dragonmaw Wyrmcaller - World Loot Level 71'), +(22962, 1, 1100372, 0, 5, 'Priestess of Delight - World Loot Level 72'), +(22963, 1, 1100370, 0, 5, 'Bonechewer Worker - World Loot Level 70'), +(22964, 1, 1100372, 0, 5, 'Sister of Pleasure - World Loot Level 72'), +(22965, 1, 1100371, 0, 5, 'Enslaved Servant - World Loot Level 71'), +(23008, 1, 1100171, 0, 5, 'Ethereum Jailor - World Loot Level 71'), +(23018, 1, 1100371, 0, 5, 'Shadowmoon Houndmaster - World Loot Level 71'), +(23020, 1, 1100069, 0, 5, 'Shadow Serpent - World Loot Level 69'), +(23020, 2, 1100070, 0, 5, 'Shadow Serpent - World Loot Level 70'), +(23022, 1, 1100370, 0, 5, 'Gordunni Soulreaper - World Loot Level 70'), +(23022, 2, 1100371, 0, 5, 'Gordunni Soulreaper - World Loot Level 71'), +(23026, 1, 1100069, 0, 5, 'Twilight Serpent - World Loot Level 69'), +(23026, 2, 1100070, 0, 5, 'Twilight Serpent - World Loot Level 70'), +(23028, 1, 1100371, 0, 5, 'Bonechewer Taskmaster - World Loot Level 71'), +(23029, 1, 1100271, 0, 5, 'Talonsworn Forest-Rager - World Loot Level 71'), +(23029, 2, 1100272, 0, 5, 'Talonsworn Forest-Rager - World Loot Level 72'), +(23030, 1, 1100371, 0, 5, 'Dragonmaw Sky Stalker - World Loot Level 71'), +(23047, 1, 1100372, 0, 5, 'Shadowmoon Soldier - World Loot Level 72'), +(23049, 1, 1100372, 0, 5, 'Shadowmoon Weapon Master - World Loot Level 72'), +(23061, 1, 1100272, 0, 5, 'Rivendark - World Loot Level 72'), +(23066, 1, 1100171, 0, 5, 'Talonpriest Ishaal - World Loot Level 71'), +(23067, 1, 1100171, 0, 5, 'Talonpriest Skizzik - World Loot Level 71'), +(23068, 1, 1100171, 0, 5, 'Talonpriest Zellek - World Loot Level 71'), +(23153, 1, 1100172, 0, 5, 'Bash\'ir Surveyor - World Loot Level 72'), +(23154, 1, 1100170, 0, 5, 'Mana-debt Slave - World Loot Level 70'), +(23161, 1, 1100372, 0, 5, 'Darkscreecher Akkarai - World Loot Level 72'), +(23162, 1, 1100272, 0, 5, 'Vakkiz the Windrager - World Loot Level 72'), +(23163, 1, 1100272, 0, 5, 'Gezzarak the Huntress - World Loot Level 72'), +(23165, 1, 1100272, 0, 5, 'Karrog - World Loot Level 72'), +(23169, 1, 1100070, 0, 5, 'Nethermine Flayer - World Loot Level 70'), +(23169, 2, 1100071, 0, 5, 'Nethermine Flayer - World Loot Level 71'), +(23172, 1, 1100372, 0, 5, 'Hand of Gorefiend - World Loot Level 72'), +(23174, 1, 1100170, 0, 5, 'Crystalfused Miner - World Loot Level 70'), +(23188, 1, 1100170, 0, 5, 'Dragonmaw Transporter - World Loot Level 70'), +(23196, 1, 1100372, 0, 5, 'Bonechewer Behemoth - World Loot Level 72'), +(23219, 1, 1100069, 0, 5, 'Blackwind Warp Chaser - World Loot Level 69'), +(23219, 2, 1100070, 0, 5, 'Blackwind Warp Chaser - World Loot Level 70'), +(23222, 1, 1100371, 0, 5, 'Bonechewer Brawler - World Loot Level 71'), +(23223, 1, 1100371, 0, 5, 'Bonechewer Spectator - World Loot Level 71'), +(23232, 1, 1100271, 0, 5, 'Mutant War Hound - World Loot Level 71'), +(23235, 1, 1100372, 0, 5, 'Bonechewer Blade Fury - World Loot Level 72'), +(23236, 1, 1100371, 0, 5, 'Bonechewer Shield Disciple - World Loot Level 71'), +(23237, 1, 1100371, 0, 5, 'Bonechewer Blood Prophet - World Loot Level 71'), +(23239, 1, 1100371, 0, 5, 'Bonechewer Combatant - World Loot Level 71'), +(23261, 1, 1100272, 0, 5, 'Furywing - World Loot Level 72'), +(23264, 1, 1100070, 0, 5, 'Overmine Flayer - World Loot Level 70'), +(23264, 2, 1100071, 0, 5, 'Overmine Flayer - World Loot Level 71'), +(23267, 1, 1100272, 0, 5, 'Arvoar the Rapacious - World Loot Level 72'), +(23269, 1, 1100272, 0, 5, 'Barash the Den Mother - World Loot Level 72'), +(23281, 1, 1100272, 0, 5, 'Insidion - World Loot Level 72'), +(23282, 1, 1100271, 0, 5, 'Obsidia - World Loot Level 71'), +(23282, 2, 1100272, 0, 5, 'Obsidia - World Loot Level 72'), +(23285, 1, 1100070, 0, 5, 'Nethermine Burster - World Loot Level 70'), +(23285, 2, 1100071, 0, 5, 'Nethermine Burster - World Loot Level 71'), +(23286, 1, 1100070, 0, 5, 'Black Blood of Draenor - World Loot Level 70'), +(23290, 1, 1100069, 0, 5, 'Draenor Blood Terror - World Loot Level 69'), +(23290, 2, 1100070, 0, 5, 'Draenor Blood Terror - World Loot Level 70'), +(23305, 1, 1100171, 0, 5, 'Crazed Murkblood Foreman - World Loot Level 71'), +(23311, 1, 1100168, 0, 5, 'Disobedient Dragonmaw Peon - World Loot Level 68'), +(23311, 2, 1100169, 0, 5, 'Disobedient Dragonmaw Peon - World Loot Level 69'), +(23324, 1, 1100170, 0, 5, 'Crazed Murkblood Miner - World Loot Level 70'), +(23326, 1, 1100070, 0, 5, 'Nethermine Ravager - World Loot Level 70'), +(23330, 1, 1100371, 0, 5, 'Dragonmaw Wind Reaver - World Loot Level 71'), +(23337, 1, 1100372, 0, 5, 'Illidari Centurion - World Loot Level 72'), +(23339, 1, 1100371, 0, 5, 'Illidari Heartseeker - World Loot Level 71'), +(23353, 1, 1100372, 0, 5, 'Braxxus - World Loot Level 72'), +(23354, 1, 1100372, 0, 5, 'Mo\'arg Incinerator - World Loot Level 72'), +(23355, 1, 1100372, 0, 5, 'Zarcsin - World Loot Level 72'), +(23374, 1, 1100371, 0, 5, 'Ashtongue Stalker - World Loot Level 71'), +(23386, 1, 1100170, 0, 5, 'Gan\'arg Analyzer - World Loot Level 70'), +(23390, 1, 1100372, 0, 5, 'Bash\'ir\'s Harbinger - World Loot Level 72'), +(23394, 1, 1100272, 0, 5, 'Promenade Sentinel - World Loot Level 72'), +(23400, 1, 1100372, 0, 5, 'Illidari Archon - World Loot Level 72'), +(23402, 1, 1100372, 0, 5, 'Illidari Battle-mage - World Loot Level 72'), +(23403, 1, 1100372, 0, 5, 'Illidari Assassin - World Loot Level 72'), +(23501, 1, 1100069, 0, 5, 'Netherwing Ray - World Loot Level 69'), +(23501, 2, 1100070, 0, 5, 'Netherwing Ray - World Loot Level 70'), +(23542, 1, 1100371, 0, 5, 'Amani\'shi Axe Thrower - World Loot Level 71'), +(23580, 1, 1100371, 0, 5, 'Amani\'shi Warbringer - World Loot Level 71'), +(23581, 1, 1100371, 0, 5, 'Amani\'shi Medicine Man - World Loot Level 71'), +(23582, 1, 1100371, 0, 5, 'Amani\'shi Tribesman - World Loot Level 71'), +(23584, 1, 1100270, 0, 5, 'Amani Bear - World Loot Level 70'), +(23586, 1, 1100170, 0, 5, 'Amani\'shi Scout - World Loot Level 70'), +(23596, 1, 1100371, 0, 5, 'Amani\'shi Flame Caster - World Loot Level 71'), +(23597, 1, 1100371, 0, 5, 'Amani\'shi Guardian - World Loot Level 71'), +(23774, 1, 1100370, 0, 5, 'Amani\'shi Trainer - World Loot Level 70'), +(23834, 1, 1100270, 0, 5, 'Amani Dragonhawk - World Loot Level 70'), +(24043, 1, 1100270, 0, 5, 'Amani Lynx - World Loot Level 70'), +(24047, 1, 1100070, 0, 5, 'Amani Crocolisk - World Loot Level 70'), +(24059, 1, 1100371, 0, 5, 'Amani\'shi Beast Tamer - World Loot Level 71'), +(24064, 1, 1100070, 0, 5, 'Amani Lynx Cub - World Loot Level 70'), +(24065, 1, 1100371, 0, 5, 'Amani\'shi Handler - World Loot Level 71'), +(24179, 1, 1100371, 0, 5, 'Amani\'shi Wind Walker - World Loot Level 71'), +(24180, 1, 1100371, 0, 5, 'Amani\'shi Protector - World Loot Level 71'), +(24374, 1, 1100370, 0, 5, 'Amani\'shi Berserker - World Loot Level 70'), +(24530, 1, 1100270, 0, 5, 'Amani Elder Lynx - World Loot Level 70'), +(24549, 1, 1100371, 0, 5, 'Amani\'shi Tempest - World Loot Level 71'), +(24684, 1, 1100370, 0, 5, 'Sunblade Blood Knight - World Loot Level 70'), +(24689, 1, 1100369, 0, 5, 'Wretched Bruiser - World Loot Level 69'), +(24696, 1, 1100371, 0, 5, 'Coilskar Witch - World Loot Level 71'), +(24698, 1, 1100371, 0, 5, 'Ethereum Smuggler - World Loot Level 71'), +(24762, 1, 1100369, 0, 5, 'Sunblade Keeper - World Loot Level 69'), +(24762, 2, 1100370, 0, 5, 'Sunblade Keeper - World Loot Level 70'), +(24777, 1, 1100271, 0, 5, 'Sunblade Sentinel - World Loot Level 71'), +(24922, 1, 1100070, 0, 5, 'Razorthorn Ravager - World Loot Level 70'), +(24955, 1, 1100070, 0, 5, 'Emaciated Felblood - World Loot Level 70'), +(24960, 1, 1100169, 0, 5, 'Wretched Devourer - World Loot Level 69'), +(24976, 1, 1100170, 0, 5, 'Dawnblade Blood Knight - World Loot Level 70'), +(25001, 1, 1100070, 0, 5, 'Abyssal Flamewalker - World Loot Level 70'), +(25001, 2, 1100071, 0, 5, 'Abyssal Flamewalker - World Loot Level 71'), +(25060, 1, 1100170, 0, 5, 'Darkspine Myrmidon - World Loot Level 70'), +(25060, 2, 1100171, 0, 5, 'Darkspine Myrmidon - World Loot Level 71'), +(25073, 1, 1100170, 0, 5, 'Darkspine Siren - World Loot Level 70'), +(25073, 2, 1100171, 0, 5, 'Darkspine Siren - World Loot Level 71'), +(25593, 1, 1100371, 0, 5, 'Apocalypse Guard - World Loot Level 71'), +(25595, 1, 1100271, 0, 5, 'Chaos Gazer - World Loot Level 71'), +(25599, 1, 1100271, 0, 5, 'Cataclysm Hound - World Loot Level 71'), +(25867, 1, 1100270, 0, 5, 'Sunblade Dragonhawk - World Loot Level 70'), +(38030, 1, 1100163, 0, 5, 'Crown Underling - World Loot Level 63'), +(38030, 2, 1100164, 0, 5, 'Crown Underling - World Loot Level 64'); + +-- Loose Items +DELETE FROM `creature_loot_template` WHERE +`Entry` IN (1410,5355,7370,11980,12377,12378,12379,15547,15548,15551,16170,16171,16173,16174,16175,16176,16177,16178,16389,16406,16407,16408,16409,16410,16411,16412,16414,16415,16424,16425,16459,16460,16461,16468,16470,16471,16472,16473,16481,16482,16485,16488,16489,16491,16492,16504,16507,16519,16523,16525,16526,16529,16530,16539,16540,16544,16545,16595,16596,16769,16772,16805,16810,16943,16944,16945,16948,16949,16952,16992,17088,17128,17129,17130,17131,17132,17133,17134,17135,17136,17137,17138,17139,17141,17142,17143,17146,17147,17148,17149,17150,17151,17152,17153,17154,17155,17156,17157,17158,17159,17160,17356,17370,17400,17401,17724,17725,17726,17727,17728,17729,17730,17731,17732,17734,17735,17771,17799,17814,17815,17816,17817,17840,17895,17897,17898,17899,17905,17906,17907,17908,17916,17938,17940,17952,17957,17958,17959,17960,17961,17962,17963,17964,17981,17993,17994,18033,18037,18043,18062,18064,18065,18145,18155,18182,18202,18203,18204,18205,18211,18220,18226,18238,18257,18258,18259,18260,18289,18290,18298,18309,18311,18312,18313,18315,18318,18319,18320,18321,18323,18325,18326,18327,18328,18331,18334,18352,18391,18404,18405,18411,18413,18419,18420,18421,18423,18437,18438,18440,18449,18450,18451,18452,18453,18454,18455,18456,18457,18460,18461,18463,18464,18465,18466,18467,18468,18469,18470,18476,18477,18493,18495,18498,18499,18500,18501,18503,18524,18533,18535,18536,18539,18540,18541,18548,18554,18556,18557,18558,18559,18567,18583,18585,18586,18587,18588,18595,18608,18631,18632,18633,18634,18635,18636,18637,18638,18639,18640,18641,18642,18647,18648,18658,18660,18661,18663,18670,18702,18707,18718,18720,18750,18794,18796,18848,18850,18852,18853,18855,18856,18857,18858,18859,18860,18864,18865,18866,18867,18869,18870,18872,18873,18875,18877,18879,18880,18881,18882,18883,18884,18885,18886,18963,18964,18974,18976,18982,18983,18996,19055,19166,19167,19183,19191,19201,19208,19209,19231,19307,19389,19428,19429,19453,19486,19494,19505,19507,19508,19509,19510,19511,19512,19513,19543,19544,19545,19546,19554,19557,19593,19595,19598,19608,19632,19633,19635,19641,19642,19643,19657,19705,19707,19712,19713,19716,19735,19738,19740,19744,19747,19754,19755,19756,19757,19759,19760,19762,19765,19767,19768,19779,19784,19788,19789,19792,19795,19796,19799,19800,19801,19802,19806,19823,19824,19825,19826,19827,19830,19831,19843,19847,19852,19853,19865,19881,19884,19885,19886,19887,19888,19889,19890,19891,19892,19902,19903,19904,19926,19940,19943,19944,19945,19948,19952,19957,19960,19961,19963,19973,19978,19979,19980,19982,19983,19984,19985,19986,19987,19988,19989,19990,19991,19992,19993,19994,19995,19996,19997,19998,20021,20031,20032,20033,20034,20035,20036,20037,20038,20039,20040,20041,20042,20043,20044,20045,20046,20048,20049,20050,20052,20058,20059,20095,20113,20132,20134,20135,20136,20138,20139,20140,20141,20161,20177,20179,20180,20181,20191,20192,20193,20202,20207,20210,20211,20215,20216,20221,20248,20255,20256,20258,20259,20260,20261,20265,20285,20326,20329,20330,20332,20334,20340,20394,20397,20404,20409,20410,20416,20427,20435,20452,20453,20454,20456,20458,20459,20474,20480,20483,20495,20496,20501,20502,20512,20514,20516,20554,20557,20600,20601,20606,20607,20609,20610,20611,20614,20634,20668,20671,20673,20680,20683,20684,20685,20713,20714,20723,20726,20727,20728,20729,20730,20731,20732,20747,20748,20749,20751,20753,20756,20757,20765,20766,20768,20770,20772,20773,20774,20775,20777,20778,20779,20783,20795,20800,20801,20803,20854,20857,20859,20864,20865,20866,20867,20868,20872,20873,20875,20878,20879,20881,20882,20883,20887,20888,20896,20897,20901,20902,20905,20906,20908,20909,20910,20911,20924,20925,20927,20928,20929,20930,20931,20934,20983,20987,20988,20990,20998,21004,21021,21022,21023,21032,21033,21042,21046,21047,21048,21050,21057,21058,21059,21060,21061,21065,21089,21102,21108,21123,21124,21126,21127,21164,21168,21171,21178,21179,21180,21181,21189,21196,21198,21200,21205,21218,21220,21221,21224,21225,21226,21227,21229,21230,21231,21232,21238,21242,21246,21249,21251,21254,21263,21284,21285,21287,21296,21298,21299,21300,21301,21302,21305,21309,21314,21315,21324,21325,21326,21337,21339,21350,21368,21370,21373,21380,21381,21382,21383,21384,21385,21386,21387,21389,21405,21408,21409,21416,21425,21450,21453,21454,21455,21462,21477,21478,21492,21499,21500,21501,21503,21505,21506,21516,21519,21520,21636,21637,21640,21644,21648,21649,21650,21651,21652,21656,21660,21661,21662,21663,21695,21696,21702,21709,21710,21711,21717,21718,21719,21720,21721,21722,21723,21724,21728,21730,21742,21743,21763,21767,21784,21787,21788,21795,21801,21802,21803,21804,21808,21809,21810,21815,21816,21817,21820,21821,21827,21839,21842,21843,21844,21849,21854,21863,21864,21878,21879,21891,21897,21901,21902,21904,21907,21911,21912,21923,21941,21956,21963,21979,21985,22011,22012,22016,22017,22018,22038,22044,22045,22052,22072,22076,22081,22082,22084,22093,22095,22099,22100,22105,22123,22132,22143,22144,22148,22160,22175,22180,22181,22182,22187,22194,22195,22199,22201,22202,22204,22217,22221,22241,22242,22243,22244,22252,22253,22254,22255,22257,22261,22262,22263,22265,22275,22281,22286,22287,22289,22291,22295,22297,22298,22303,22304,22305,22307,22308,22309,22310,22311,22313,22325,22327,22341,22342,22343,22357,22363,22378,22384,22387,22388,22392,22393,22394,22466,22482,22807,22825,22826,22827,22828,22844,22845,22846,22847,22853,22855,22869,22873,22874,22875,22876,22877,22878,22879,22880,22881,22882,22883,22884,22885,22939,22945,22946,22953,22954,22955,22956,22957,22959,22960,22962,22963,22964,22965,23008,23018,23020,23022,23026,23028,23029,23030,23047,23049,23061,23066,23067,23068,23153,23154,23161,23162,23163,23165,23169,23172,23174,23188,23196,23219,23222,23223,23232,23235,23236,23237,23239,23261,23264,23267,23269,23281,23282,23285,23286,23290,23305,23311,23324,23326,23330,23337,23339,23353,23354,23355,23374,23386,23390,23394,23400,23402,23403,23501,23542,23580,23581,23582,23584,23586,23596,23597,23774,23834,24043,24047,24059,24064,24065,24179,24180,24374,24530,24549,24684,24689,24696,24698,24762,24777,24922,24955,24960,24976,25001,25060,25073,25593,25595,25599,25867,38030) +AND `Item` IN (5760,13444,13446,16253,22146,22153,22532,22540,22541,22542,22548,22553,22557,22558,22829,22832,22903,22904,22912,22913,22914,22919,22926,23154,23620,23621,23622,23623,23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635,23636,23637,23802,23804,23810,23883,23884,24163,24164,24165,24166,24167,24168,24169,24170,24171,24192,24193,24194,24195,24196,24197,24198,24199,24200,24201,24202,24203,24204,24205,24206,24207,24209,24210,24211,24212,24213,24214,24215,24216,24217,24218,24219,24220,24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307,24575,24576,24577,24578,24580,24582,24583,24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595,24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607,24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619,24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631,24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643,24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655,24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667,24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679,24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691,24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703,24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715,24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727,24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739,24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751,24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763,24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775,24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787,24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799,24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811,24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823,24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835,24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847,24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859,24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871,24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895,24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907,24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919,24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931,24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943,24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979,24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991,24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003,25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015,25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027,25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039,25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087,25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099,25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111,25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123,25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135,25136,25137,25138,25139,25140,25141,25142,25143,25144,25146,25147,25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171,25172,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183,25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195,25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207,25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219,25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231,25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243,25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255,25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267,25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279,25280,25281,25282,25283,25284,25286,25287,25288,25289,25290,25291,25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303,25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315,25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327,25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339,25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351,25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363,25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375,25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387,25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399,25400,25401,25402,25403,25404,25405,25406,25887,25905,25906,25907,25909,27498,27499,27500,27501,27502,27503,28270,28279,28280,28531,28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543,28544,29549,29550,29714,29723,29724,29725,29726,29727,29728,29729,29730,29731,29732,29733,29734,31125,31126,31127,31131,31133,31134,31136,31137,31138,31139,31140,31142,31143,31145,31147,31148,31149,31150,31151,31152,31153,31173,31175,31178,31180,31186,31187,31190,31193,31196,31200,31202,31204,31222,31226,31230,31234,31237,31240,31255,31258,31272,31275,31276,31277,31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291,31292,31293,31294,31295,31297,31298,31299,31303,31304,31305,31306,31308,31318,31319,31320,31321,31322,31323,31326,31328,31329,31330,31331,31332,31333,31334,31335,31336,31338,31339,31340,31342,31343,31501,31557,31565,31573,31581,31837,31875,31876,31877,31878,31879,31883,31884,31885,31886,31887,31888,31889,31893,31894,31895,31896,31898,31899,31900,31902,31903,31904,31905,31906,31908,31909,31911,31912,31913,31915,31916,31917,31918,31925,31926,31927,31928,31929,31935,31936,31937,31938,31939,31940,31943,31952,32411,32520,33186,33457,33458,33459,33460,33461,33462,33954,15742,12684,14467,14466,12685,14470,16043,16215,21949,16044,14474,12689,12691,16218,15731,14478,14479,12692,13486,15737,13488,14484,13489,16220,13487,12693,12694,15746,15745,15743,13490,14489,12695,14492,16051,13492,13493,14491,12697,15755,14494,15757,14498,12702,16245,13518,15765,12704,16055,14499,16251,12713,14504,14506,14508,16253,12703,12711,14501,14507,12716,14509,14510,12717,22388,14511,12720,12728,22390,22389,4415,7452,4301,8384,10608,8028,21953,12698,14497) +AND `Reference` = 0; + +-- References +DELETE FROM `creature_loot_template` WHERE +`Entry` IN (1410,5355,7370,11980,12377,12378,12379,15547,15548,15551,16170,16171,16173,16174,16175,16176,16177,16178,16389,16406,16407,16408,16409,16410,16411,16412,16414,16415,16424,16425,16459,16460,16461,16468,16470,16471,16472,16473,16481,16482,16485,16488,16489,16491,16492,16504,16507,16519,16523,16525,16526,16529,16530,16539,16540,16544,16545,16595,16596,16769,16772,16805,16810,16943,16944,16945,16948,16949,16952,16992,17088,17128,17129,17130,17131,17132,17133,17134,17135,17136,17137,17138,17139,17141,17142,17143,17146,17147,17148,17149,17150,17151,17152,17153,17154,17155,17156,17157,17158,17159,17160,17356,17370,17400,17401,17724,17725,17726,17727,17728,17729,17730,17731,17732,17734,17735,17771,17799,17814,17815,17816,17817,17840,17895,17897,17898,17899,17905,17906,17907,17908,17916,17938,17940,17952,17957,17958,17959,17960,17961,17962,17963,17964,17981,17993,17994,18033,18037,18043,18062,18064,18065,18145,18155,18182,18202,18203,18204,18205,18211,18220,18226,18238,18257,18258,18259,18260,18289,18290,18298,18309,18311,18312,18313,18315,18318,18319,18320,18321,18323,18325,18326,18327,18328,18331,18334,18352,18391,18404,18405,18411,18413,18419,18420,18421,18423,18437,18438,18440,18449,18450,18451,18452,18453,18454,18455,18456,18457,18460,18461,18463,18464,18465,18466,18467,18468,18469,18470,18476,18477,18493,18495,18498,18499,18500,18501,18503,18524,18533,18535,18536,18539,18540,18541,18548,18554,18556,18557,18558,18559,18567,18583,18585,18586,18587,18588,18595,18608,18631,18632,18633,18634,18635,18636,18637,18638,18639,18640,18641,18642,18647,18648,18658,18660,18661,18663,18670,18702,18707,18718,18720,18750,18794,18796,18848,18850,18852,18853,18855,18856,18857,18858,18859,18860,18864,18865,18866,18867,18869,18870,18872,18873,18875,18877,18879,18880,18881,18882,18883,18884,18885,18886,18963,18964,18974,18976,18982,18983,18996,19055,19166,19167,19183,19191,19201,19208,19209,19231,19307,19389,19428,19429,19453,19486,19494,19505,19507,19508,19509,19510,19511,19512,19513,19543,19544,19545,19546,19554,19557,19593,19595,19598,19608,19632,19633,19635,19641,19642,19643,19657,19705,19707,19712,19713,19716,19735,19738,19740,19744,19747,19754,19755,19756,19757,19759,19760,19762,19765,19767,19768,19779,19784,19788,19789,19792,19795,19796,19799,19800,19801,19802,19806,19823,19824,19825,19826,19827,19830,19831,19843,19847,19852,19853,19865,19881,19884,19885,19886,19887,19888,19889,19890,19891,19892,19902,19903,19904,19926,19940,19943,19944,19945,19948,19952,19957,19960,19961,19963,19973,19978,19979,19980,19982,19983,19984,19985,19986,19987,19988,19989,19990,19991,19992,19993,19994,19995,19996,19997,19998,20021,20031,20032,20033,20034,20035,20036,20037,20038,20039,20040,20041,20042,20043,20044,20045,20046,20048,20049,20050,20052,20058,20059,20095,20113,20132,20134,20135,20136,20138,20139,20140,20141,20161,20177,20179,20180,20181,20191,20192,20193,20202,20207,20210,20211,20215,20216,20221,20248,20255,20256,20258,20259,20260,20261,20265,20285,20326,20329,20330,20332,20334,20340,20394,20397,20404,20409,20410,20416,20427,20435,20452,20453,20454,20456,20458,20459,20474,20480,20483,20495,20496,20501,20502,20512,20514,20516,20554,20557,20600,20601,20606,20607,20609,20610,20611,20614,20634,20668,20671,20673,20680,20683,20684,20685,20713,20714,20723,20726,20727,20728,20729,20730,20731,20732,20747,20748,20749,20751,20753,20756,20757,20765,20766,20768,20770,20772,20773,20774,20775,20777,20778,20779,20783,20795,20800,20801,20803,20854,20857,20859,20864,20865,20866,20867,20868,20872,20873,20875,20878,20879,20881,20882,20883,20887,20888,20896,20897,20901,20902,20905,20906,20908,20909,20910,20911,20924,20925,20927,20928,20929,20930,20931,20934,20983,20987,20988,20990,20998,21004,21021,21022,21023,21032,21033,21042,21046,21047,21048,21050,21057,21058,21059,21060,21061,21065,21089,21102,21108,21123,21124,21126,21127,21164,21168,21171,21178,21179,21180,21181,21189,21196,21198,21200,21205,21218,21220,21221,21224,21225,21226,21227,21229,21230,21231,21232,21238,21242,21246,21249,21251,21254,21263,21284,21285,21287,21296,21298,21299,21300,21301,21302,21305,21309,21314,21315,21324,21325,21326,21337,21339,21350,21368,21370,21373,21380,21381,21382,21383,21384,21385,21386,21387,21389,21405,21408,21409,21416,21425,21450,21453,21454,21455,21462,21477,21478,21492,21499,21500,21501,21503,21505,21506,21516,21519,21520,21636,21637,21640,21644,21648,21649,21650,21651,21652,21656,21660,21661,21662,21663,21695,21696,21702,21709,21710,21711,21717,21718,21719,21720,21721,21722,21723,21724,21728,21730,21742,21743,21763,21767,21784,21787,21788,21795,21801,21802,21803,21804,21808,21809,21810,21815,21816,21817,21820,21821,21827,21839,21842,21843,21844,21849,21854,21863,21864,21878,21879,21891,21897,21901,21902,21904,21907,21911,21912,21923,21941,21956,21963,21979,21985,22011,22012,22016,22017,22018,22038,22044,22045,22052,22072,22076,22081,22082,22084,22093,22095,22099,22100,22105,22123,22132,22143,22144,22148,22160,22175,22180,22181,22182,22187,22194,22195,22199,22201,22202,22204,22217,22221,22241,22242,22243,22244,22252,22253,22254,22255,22257,22261,22262,22263,22265,22275,22281,22286,22287,22289,22291,22295,22297,22298,22303,22304,22305,22307,22308,22309,22310,22311,22313,22325,22327,22341,22342,22343,22357,22363,22378,22384,22387,22388,22392,22393,22394,22466,22482,22807,22825,22826,22827,22828,22844,22845,22846,22847,22853,22855,22869,22873,22874,22875,22876,22877,22878,22879,22880,22881,22882,22883,22884,22885,22939,22945,22946,22953,22954,22955,22956,22957,22959,22960,22962,22963,22964,22965,23008,23018,23020,23022,23026,23028,23029,23030,23047,23049,23061,23066,23067,23068,23153,23154,23161,23162,23163,23165,23169,23172,23174,23188,23196,23219,23222,23223,23232,23235,23236,23237,23239,23261,23264,23267,23269,23281,23282,23285,23286,23290,23305,23311,23324,23326,23330,23337,23339,23353,23354,23355,23374,23386,23390,23394,23400,23402,23403,23501,23542,23580,23581,23582,23584,23586,23596,23597,23774,23834,24043,24047,24059,24064,24065,24179,24180,24374,24530,24549,24684,24689,24696,24698,24762,24777,24922,24955,24960,24976,25001,25060,25073,25593,25595,25599,25867,38030) +AND `Reference` IN ( +24002, -- Occurrences: 912, Trash +24001, -- Occurrences: 666, Trash +24009, -- Occurrences: 603, Greens +24011, -- Occurrences: 600, Greens +24035, -- Occurrences: 419, Potions, Scrolls +24007, -- Occurrences: 408, Greens +24012, -- Occurrences: 374, Blues +24014, -- Occurrences: 316, Blues +24013, -- Occurrences: 292, Greens +24092, -- Occurrences: 260, Patterns +24005, -- Occurrences: 258, Greens +24000, -- Occurrences: 224, Trash +24010, -- Occurrences: 203, Blues +24003, -- Occurrences: 148, Greens +24093, -- Occurrences: 143, Patterns +24008, -- Occurrences: 105, Blues +24015, -- Occurrences: 89, Blues +24006, -- Occurrences: 53, Blues +24023, -- Occurrences: 40, Greens +24004, -- Occurrences: 14, Blues +24024, -- Occurrences: 6, Trash +24036, -- Occurrences: 5, Trash +24016, -- Occurrences: 5, Greens +24088, -- Occurrences: 4, Vanilla Purples +24034, -- Occurrences: 4, Vanilla Blues +24022, -- Occurrences: 4, Greens +24033, -- Occurrences: 4, Greens +24019, -- Occurrences: 4, Vanilla Blues +24018, -- Occurrences: 4, Greens +24017, -- Occurrences: 4, Vanilla Blues +24089, -- Occurrences: 3, Vanilla Purples +24724, -- Occurrences: 3, Scrolls +24090, -- Occurrences: 2, Vanilla Purples +24031, -- Occurrences: 2, Greens +24127, -- Occurrences: 1, Nested Reference for Greens +10001, -- Occurrences: 1, Scrolls +24726, -- Occurrences: 1, Scrolls +24029, -- Occurrences: 1, Greens +24032, -- Occurrences: 1, Blues +24021, -- Occurrences: 1, Blues +4000, -- Occurrences: 1, Trash +4001, -- Occurrences: 1, Trash +4104, -- Occurrences: 1, Greens +4105, -- Occurrences: 1, Greens +4201, -- Occurrences: 1, Blues +4202, -- Occurrences: 1, Blues +4203, -- Occurrences: 1, Blues +4204, -- Occurrences: 1, Blues +4103, -- Occurrences: 1, Greens +14501, -- Occurrences: 1, Blues +24020 -- Occurrences: 1, Greens +); + +-- Low-Level TBC Creatures missed in first pass +-- Entries: 16972,16973,17034,17035,17039,17053,18128,18130,18131,18132,18133,18138,18213,18214,18280,19423,19458,19459,19706,20196,20279,20280,20283,20290,20324,20387,16863,16879,16880,16946,16947,16950,16954,16960,16974,16975,17014,18827,18975,18981,19190,19261,19282,19298,19335,19408,19434,19527,20798,18136,18137,18124,19402,16904,16905,16906,16978,16846,16847,16867,16870,16871,16873,16876,16878,16907,16911,16912,16925,16927,16928,16929,16964,16966,16967,18077,18079,18080,18113,18114,18123,18340,18952,19263,19295,19410,19411,19413,19414,19415,19422,19424,19442,19457,19701,20115,16844,16857,16901,16903,16968,18977,19299,19264,19312,19443 +DELETE FROM `creature_loot_template` WHERE `Entry` IN (16972,16973,17034,17035,17039,17053,18128,18130,18131,18132,18133,18138,18213,18214,18280,19423,19458,19459,19706,20196,20279,20280,20283,20290,20324,20387,16863,16879,16880,16946,16947,16950,16954,16960,16974,16975,17014,18827,18975,18981,19190,19261,19282,19298,19335,19408,19434,19527,20798,18136,18137,18124,19402,16904,16905,16906,16978,16846,16847,16867,16870,16871,16873,16876,16878,16907,16911,16912,16925,16927,16928,16929,16964,16966,16967,18077,18079,18080,18113,18114,18123,18340,18952,19263,19295,19410,19411,19413,19414,19415,19422,19424,19442,19457,19701,20115,16844,16857,16901,16903,16968,18977,19299,19264,19312,19443) +AND `Reference` BETWEEN 1100000 AND 1100400; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(16844, 1, 1100059, 0, 5, 'Crust Burster - World Loot Level 59'), +(16844, 2, 1100060, 0, 5, 'Crust Burster - World Loot Level 60'), +(16846, 1, 1100161, 0, 5, 'Mag\'har Grunt - World Loot Level 61'), +(16847, 1, 1100158, 0, 5, 'Debilitated Mag\'har Grunt - World Loot Level 58'), +(16857, 1, 1100059, 0, 5, 'Marauding Crust Burster - World Loot Level 59'), +(16857, 2, 1100060, 0, 5, 'Marauding Crust Burster - World Loot Level 60'), +(16863, 1, 1100060, 0, 5, 'Deranged Helboar - World Loot Level 60'), +(16863, 2, 1100061, 0, 5, 'Deranged Helboar - World Loot Level 61'), +(16867, 1, 1100162, 0, 5, 'Shattered Hand Grunt - World Loot Level 62'), +(16867, 2, 1100163, 0, 5, 'Shattered Hand Grunt - World Loot Level 63'), +(16870, 1, 1100162, 0, 5, 'Shattered Hand Captain - World Loot Level 62'), +(16870, 2, 1100163, 0, 5, 'Shattered Hand Captain - World Loot Level 63'), +(16871, 1, 1100160, 0, 5, 'Bleeding Hollow Grunt - World Loot Level 60'), +(16871, 2, 1100161, 0, 5, 'Bleeding Hollow Grunt - World Loot Level 61'), +(16873, 1, 1100160, 0, 5, 'Bleeding Hollow Dark Shaman - World Loot Level 60'), +(16873, 2, 1100161, 0, 5, 'Bleeding Hollow Dark Shaman - World Loot Level 61'), +(16876, 1, 1100158, 0, 5, 'Bonechewer Mutant - World Loot Level 58'), +(16876, 2, 1100159, 0, 5, 'Bonechewer Mutant - World Loot Level 59'), +(16878, 1, 1100161, 0, 5, 'Shattered Hand Berserker - World Loot Level 61'), +(16878, 2, 1100162, 0, 5, 'Shattered Hand Berserker - World Loot Level 62'), +(16879, 1, 1100058, 0, 5, 'Starving Helboar - World Loot Level 58'), +(16879, 2, 1100059, 0, 5, 'Starving Helboar - World Loot Level 59'), +(16880, 1, 1100061, 0, 5, 'Hulking Helboar - World Loot Level 61'), +(16880, 2, 1100062, 0, 5, 'Hulking Helboar - World Loot Level 62'), +(16901, 1, 1100061, 0, 5, 'Blistering Rot - World Loot Level 61'), +(16901, 2, 1100062, 0, 5, 'Blistering Rot - World Loot Level 62'), +(16903, 1, 1100061, 2.5, 5, 'Blistering Oozeling - World Loot Level 61'), +(16903, 2, 1100062, 2.5, 5, 'Blistering Oozeling - World Loot Level 62'), +(16904, 1, 1100159, 0, 5, 'Unyielding Footman - World Loot Level 59'), +(16904, 2, 1100160, 0, 5, 'Unyielding Footman - World Loot Level 60'), +(16905, 1, 1100159, 0, 5, 'Unyielding Sorcerer - World Loot Level 59'), +(16905, 2, 1100160, 0, 5, 'Unyielding Sorcerer - World Loot Level 60'), +(16906, 1, 1100159, 0, 5, 'Unyielding Knight - World Loot Level 59'), +(16906, 2, 1100160, 0, 5, 'Unyielding Knight - World Loot Level 60'), +(16907, 1, 1100159, 0, 5, 'Bleeding Hollow Peon - World Loot Level 59'), +(16911, 1, 1100162, 0, 5, 'Mag\'har Watcher - World Loot Level 62'), +(16911, 2, 1100163, 0, 5, 'Mag\'har Watcher - World Loot Level 63'), +(16912, 1, 1100162, 0, 5, 'Mag\'har Hunter - World Loot Level 62'), +(16912, 2, 1100163, 0, 5, 'Mag\'har Hunter - World Loot Level 63'), +(16925, 1, 1100158, 0, 5, 'Bonechewer Raider - World Loot Level 58'), +(16925, 2, 1100159, 0, 5, 'Bonechewer Raider - World Loot Level 59'), +(16927, 1, 1100160, 0, 5, 'Stonescythe Whelp - World Loot Level 60'), +(16927, 2, 1100161, 0, 5, 'Stonescythe Whelp - World Loot Level 61'), +(16928, 1, 1100161, 0, 5, 'Stonescythe Ambusher - World Loot Level 61'), +(16929, 1, 1100161, 0, 5, 'Stonescythe Alpha - World Loot Level 61'), +(16929, 2, 1100162, 0, 5, 'Stonescythe Alpha - World Loot Level 62'), +(16946, 1, 1100161, 0, 5, 'Mo\'arg Forgefiend - World Loot Level 61'), +(16946, 2, 1100162, 0, 5, 'Mo\'arg Forgefiend - World Loot Level 62'), +(16947, 1, 1100160, 0, 5, 'Gan\'arg Servant - World Loot Level 60'), +(16947, 2, 1100161, 0, 5, 'Gan\'arg Servant - World Loot Level 61'), +(16950, 1, 1100058, 0, 5, 'Netherhound - World Loot Level 58'), +(16954, 1, 1100160, 0, 5, 'Forge Camp Legionnaire - World Loot Level 60'), +(16954, 2, 1100161, 0, 5, 'Forge Camp Legionnaire - World Loot Level 61'), +(16960, 1, 1100160, 0, 5, 'Sister of Grief - World Loot Level 60'), +(16960, 2, 1100161, 0, 5, 'Sister of Grief - World Loot Level 61'), +(16964, 1, 1100161, 0, 5, 'Warlord Morkh - World Loot Level 61'), +(16966, 1, 1100162, 0, 5, 'Haal\'eshi Windwalker - World Loot Level 62'), +(16966, 2, 1100163, 0, 5, 'Haal\'eshi Windwalker - World Loot Level 63'), +(16967, 1, 1100162, 0, 5, 'Haal\'eshi Talonguard - World Loot Level 62'), +(16967, 2, 1100163, 0, 5, 'Haal\'eshi Talonguard - World Loot Level 63'), +(16968, 1, 1100061, 0, 5, 'Tunneler - World Loot Level 61'), +(16968, 2, 1100062, 0, 5, 'Tunneler - World Loot Level 62'), +(16972, 1, 1100058, 0, 5, 'Bonestripper Buzzard - World Loot Level 58'), +(16972, 2, 1100059, 0, 5, 'Bonestripper Buzzard - World Loot Level 59'), +(16973, 1, 1100061, 0, 5, 'Bonestripper Vulture - World Loot Level 61'), +(16973, 2, 1100062, 0, 5, 'Bonestripper Vulture - World Loot Level 62'), +(16974, 1, 1100060, 0, 5, 'Rogue Voidwalker - World Loot Level 60'), +(16974, 2, 1100061, 0, 5, 'Rogue Voidwalker - World Loot Level 61'), +(16975, 1, 1100060, 0, 5, 'Uncontrolled Voidwalker - World Loot Level 60'), +(16975, 2, 1100061, 0, 5, 'Uncontrolled Voidwalker - World Loot Level 61'), +(16978, 1, 1100161, 0, 5, 'Lieutenant Commander Thalvos - World Loot Level 61'), +(17014, 1, 1100061, 0, 5, 'Collapsing Voidwalker - World Loot Level 61'), +(17014, 2, 1100062, 0, 5, 'Collapsing Voidwalker - World Loot Level 62'), +(17034, 1, 1100062, 0, 5, 'Female Kaliri Hatchling - World Loot Level 62'), +(17035, 1, 1100063, 0, 5, 'Kaliri Matriarch - World Loot Level 63'), +(17039, 1, 1100061, 0, 5, 'Male Kaliri Hatchling - World Loot Level 61'), +(17053, 1, 1100060, 0, 5, 'Kaliri Swooper - World Loot Level 60'), +(17053, 2, 1100061, 0, 5, 'Kaliri Swooper - World Loot Level 61'), +(18077, 1, 1100160, 0, 5, 'Umbrafen Oracle - World Loot Level 60'), +(18077, 2, 1100161, 0, 5, 'Umbrafen Oracle - World Loot Level 61'), +(18079, 1, 1100160, 0, 5, 'Umbrafen Seer - World Loot Level 60'), +(18079, 2, 1100161, 0, 5, 'Umbrafen Seer - World Loot Level 61'), +(18080, 1, 1100162, 0, 5, 'Kataru - World Loot Level 62'), +(18113, 1, 1100161, 0, 5, 'Feralfen Hunter - World Loot Level 61'), +(18113, 2, 1100162, 0, 5, 'Feralfen Hunter - World Loot Level 62'), +(18114, 1, 1100161, 0, 5, 'Feralfen Mystic - World Loot Level 61'), +(18114, 2, 1100162, 0, 5, 'Feralfen Mystic - World Loot Level 62'), +(18123, 1, 1100162, 0, 5, 'Wrekt Slave - World Loot Level 62'), +(18124, 1, 1100161, 0, 5, 'Withered Giant - World Loot Level 61'), +(18124, 2, 1100162, 0, 5, 'Withered Giant - World Loot Level 62'), +(18128, 1, 1100061, 0, 5, 'Sporebat - World Loot Level 61'), +(18128, 2, 1100062, 0, 5, 'Sporebat - World Loot Level 62'), +(18130, 1, 1100060, 0, 5, 'Marshfang Ripper - World Loot Level 60'), +(18130, 2, 1100061, 0, 5, 'Marshfang Ripper - World Loot Level 61'), +(18131, 1, 1100062, 0, 5, 'Marshfang Slicer - World Loot Level 62'), +(18131, 2, 1100063, 0, 5, 'Marshfang Slicer - World Loot Level 63'), +(18132, 1, 1100060, 0, 5, 'Umbraglow Stinger - World Loot Level 60'), +(18132, 2, 1100061, 0, 5, 'Umbraglow Stinger - World Loot Level 61'), +(18133, 1, 1100062, 0, 5, 'Marshlight Bleeder - World Loot Level 62'), +(18133, 2, 1100063, 0, 5, 'Marshlight Bleeder - World Loot Level 63'), +(18136, 1, 1100161, 0, 5, 'Marsh Lurker - World Loot Level 61'), +(18136, 2, 1100162, 0, 5, 'Marsh Lurker - World Loot Level 62'), +(18137, 1, 1100161, 0, 5, 'Marsh Dredger - World Loot Level 61'), +(18137, 2, 1100162, 0, 5, 'Marsh Dredger - World Loot Level 62'), +(18138, 1, 1100060, 0, 5, 'Umbrafen Eel - World Loot Level 60'), +(18138, 2, 1100061, 0, 5, 'Umbrafen Eel - World Loot Level 61'), +(18213, 1, 1100060, 0, 5, 'Mire Hydra - World Loot Level 60'), +(18213, 2, 1100061, 0, 5, 'Mire Hydra - World Loot Level 61'), +(18214, 1, 1100062, 0, 5, 'Fenclaw Thrasher - World Loot Level 62'), +(18214, 2, 1100063, 0, 5, 'Fenclaw Thrasher - World Loot Level 63'), +(18280, 1, 1100062, 0, 5, 'Sporewing - World Loot Level 62'), +(18340, 1, 1100162, 0, 5, 'Steam Pump Overseer - World Loot Level 62'), +(18340, 2, 1100163, 0, 5, 'Steam Pump Overseer - World Loot Level 63'), +(18827, 1, 1100159, 0, 5, 'Gan\'arg Sapper - World Loot Level 59'), +(18827, 2, 1100160, 0, 5, 'Gan\'arg Sapper - World Loot Level 60'), +(18952, 1, 1100158, 0, 5, 'Bonechewer Scavenger - World Loot Level 58'), +(18952, 2, 1100159, 0, 5, 'Bonechewer Scavenger - World Loot Level 59'), +(18975, 1, 1100158, 0, 5, 'Wrathguard - World Loot Level 58'), +(18975, 2, 1100159, 0, 5, 'Wrathguard - World Loot Level 59'), +(18977, 1, 1100360, 0, 5, 'Felguard Destroyer - World Loot Level 60'), +(18981, 1, 1100159, 0, 5, 'Doomwhisperer - World Loot Level 59'), +(19190, 1, 1100158, 0, 5, 'Fel Handler - World Loot Level 58'), +(19190, 2, 1100159, 0, 5, 'Fel Handler - World Loot Level 59'), +(19261, 1, 1100058, 0, 5, 'Infernal Warbringer - World Loot Level 58'), +(19261, 2, 1100059, 0, 5, 'Infernal Warbringer - World Loot Level 59'), +(19263, 1, 1100161, 0, 5, 'Warboss Nekrogg - World Loot Level 61'), +(19264, 1, 1100363, 0, 5, 'Force-Commander Gorax - World Loot Level 63'), +(19282, 1, 1100162, 0, 5, 'Subjugator Shi\'aziv - World Loot Level 62'), +(19295, 1, 1100161, 0, 5, 'Shattered Hand Grenadier - World Loot Level 61'), +(19298, 1, 1100162, 0, 5, 'Warbringer Arix\'Amal - World Loot Level 62'), +(19299, 1, 1100369, 0, 5, 'Deathwhisperer - World Loot Level 69'), +(19299, 2, 1100170, 0, 5, 'Deathwhisperer - World Loot Level 70'), +(19312, 1, 1100362, 0, 5, 'Drillmaster Zurok - World Loot Level 62'), +(19335, 1, 1100162, 0, 5, 'Subjugator Yalqiz - World Loot Level 62'), +(19402, 1, 1100162, 0, 5, 'Withered Bog Lord - World Loot Level 62'), +(19408, 1, 1100161, 0, 5, 'Maiden of Pain - World Loot Level 61'), +(19410, 1, 1100162, 0, 5, 'Shattered Hand Neophyte - World Loot Level 62'), +(19410, 2, 1100163, 0, 5, 'Shattered Hand Neophyte - World Loot Level 63'), +(19411, 1, 1100162, 0, 5, 'Shattered Hand Warlock - World Loot Level 62'), +(19411, 2, 1100163, 0, 5, 'Shattered Hand Warlock - World Loot Level 63'), +(19413, 1, 1100161, 0, 5, 'Shattered Hand Mage - World Loot Level 61'), +(19413, 2, 1100162, 0, 5, 'Shattered Hand Mage - World Loot Level 62'), +(19414, 1, 1100161, 0, 5, 'Shattered Hand Guard - World Loot Level 61'), +(19414, 2, 1100162, 0, 5, 'Shattered Hand Guard - World Loot Level 62'), +(19415, 1, 1100161, 0, 5, 'Shattered Hand Acolyte - World Loot Level 61'), +(19415, 2, 1100162, 0, 5, 'Shattered Hand Acolyte - World Loot Level 62'), +(19422, 1, 1100160, 0, 5, 'Bleeding Hollow Necrolyte - World Loot Level 60'), +(19422, 2, 1100161, 0, 5, 'Bleeding Hollow Necrolyte - World Loot Level 61'), +(19423, 1, 1100060, 0, 5, 'Bleeding Hollow Worg - World Loot Level 60'), +(19424, 1, 1100160, 0, 5, 'Bleeding Hollow Tormentor - World Loot Level 60'), +(19424, 2, 1100161, 0, 5, 'Bleeding Hollow Tormentor - World Loot Level 61'), +(19434, 1, 1100159, 0, 5, 'Dreadcaller - World Loot Level 59'), +(19442, 1, 1100160, 0, 5, 'Worg Master Kruush - World Loot Level 60'), +(19443, 1, 1100361, 0, 5, 'Tagar Spinebreaker - World Loot Level 61'), +(19457, 1, 1100161, 0, 5, 'Grillok "Darkeye" - World Loot Level 61'), +(19458, 1, 1100058, 0, 5, 'Ripp - World Loot Level 58'), +(19458, 2, 1100059, 0, 5, 'Ripp - World Loot Level 59'), +(19459, 1, 1100060, 0, 5, 'Feng - World Loot Level 60'), +(19527, 1, 1100061, 0, 5, 'Vacillating Voidcaller - World Loot Level 61'), +(19527, 2, 1100062, 0, 5, 'Vacillating Voidcaller - World Loot Level 62'), +(19701, 1, 1100158, 0, 5, 'Bonechewer Evoker - World Loot Level 58'), +(19701, 2, 1100159, 0, 5, 'Bonechewer Evoker - World Loot Level 59'), +(19706, 1, 1100061, 0, 5, 'Marshrock Threshalisk - World Loot Level 61'), +(19706, 2, 1100062, 0, 5, 'Marshrock Threshalisk - World Loot Level 62'), +(20115, 1, 1100160, 0, 5, 'Umbrafen Witchdoctor - World Loot Level 60'), +(20115, 2, 1100161, 0, 5, 'Umbrafen Witchdoctor - World Loot Level 61'), +(20196, 1, 1100061, 0, 5, 'Bloodthirsty Marshfang - World Loot Level 61'), +(20196, 2, 1100062, 0, 5, 'Bloodthirsty Marshfang - World Loot Level 62'), +(20279, 1, 1100062, 0, 5, 'Ragestone Threshalisk - World Loot Level 62'), +(20279, 2, 1100063, 0, 5, 'Ragestone Threshalisk - World Loot Level 63'), +(20280, 1, 1100062, 0, 5, 'Ragestone Trampler - World Loot Level 62'), +(20280, 2, 1100063, 0, 5, 'Ragestone Trampler - World Loot Level 63'), +(20283, 1, 1100061, 0, 5, 'Marshrock Stomper - World Loot Level 61'), +(20283, 2, 1100062, 0, 5, 'Marshrock Stomper - World Loot Level 62'), +(20290, 1, 1100061, 0, 5, 'Lagoon Eel - World Loot Level 61'), +(20290, 2, 1100062, 0, 5, 'Lagoon Eel - World Loot Level 62'), +(20324, 1, 1100061, 0, 5, 'Parched Hydra - World Loot Level 61'), +(20387, 1, 1100060, 0, 5, 'Young Sporebat - World Loot Level 60'), +(20387, 2, 1100061, 0, 5, 'Young Sporebat - World Loot Level 61'), +(20798, 1, 1100161, 0, 5, 'Razorsaw - World Loot Level 61'), +(20798, 2, 1100162, 0, 5, 'Razorsaw - World Loot Level 62'); +DELETE FROM `creature_loot_template` WHERE +`Entry` IN (16972,16973,17034,17035,17039,17053,18128,18130,18131,18132,18133,18138,18213,18214,18280,19423,19458,19459,19706,20196,20279,20280,20283,20290,20324,20387,16863,16879,16880,16946,16947,16950,16954,16960,16974,16975,17014,18827,18975,18981,19190,19261,19282,19298,19335,19408,19434,19527,20798,18136,18137,18124,19402,16904,16905,16906,16978,16846,16847,16867,16870,16871,16873,16876,16878,16907,16911,16912,16925,16927,16928,16929,16964,16966,16967,18077,18079,18080,18113,18114,18123,18340,18952,19263,19295,19410,19411,19413,19414,19415,19422,19424,19442,19457,19701,20115,16844,16857,16901,16903,16968,18977,19299,19264,19312,19443) +AND `Item` IN (5760,13444,13446,16253,22146,22153,22532,22540,22541,22542,22548,22553,22557,22558,22829,22832,22903,22904,22912,22913,22914,22919,22926,23154,23620,23621,23622,23623,23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635,23636,23637,23802,23804,23810,23883,23884,24163,24164,24165,24166,24167,24168,24169,24170,24171,24192,24193,24194,24195,24196,24197,24198,24199,24200,24201,24202,24203,24204,24205,24206,24207,24209,24210,24211,24212,24213,24214,24215,24216,24217,24218,24219,24220,24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307,24575,24576,24577,24578,24580,24582,24583,24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595,24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607,24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619,24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631,24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643,24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655,24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667,24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679,24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691,24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703,24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715,24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727,24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739,24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751,24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763,24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775,24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787,24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799,24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811,24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823,24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835,24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847,24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859,24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871,24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895,24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907,24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919,24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931,24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943,24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979,24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991,24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003,25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015,25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027,25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039,25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087,25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099,25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111,25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123,25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135,25136,25137,25138,25139,25140,25141,25142,25143,25144,25146,25147,25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171,25172,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183,25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195,25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207,25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219,25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231,25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243,25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255,25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267,25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279,25280,25281,25282,25283,25284,25286,25287,25288,25289,25290,25291,25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303,25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315,25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327,25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339,25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351,25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363,25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375,25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387,25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399,25400,25401,25402,25403,25404,25405,25406,25887,25905,25906,25907,25909,27498,27499,27500,27501,27502,27503,28270,28279,28280,28531,28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543,28544,29549,29550,29714,29723,29724,29725,29726,29727,29728,29729,29730,29731,29732,29733,29734,31125,31126,31127,31131,31133,31134,31136,31137,31138,31139,31140,31142,31143,31145,31147,31148,31149,31150,31151,31152,31153,31173,31175,31178,31180,31186,31187,31190,31193,31196,31200,31202,31204,31222,31226,31230,31234,31237,31240,31255,31258,31272,31275,31276,31277,31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291,31292,31293,31294,31295,31297,31298,31299,31303,31304,31305,31306,31308,31318,31319,31320,31321,31322,31323,31326,31328,31329,31330,31331,31332,31333,31334,31335,31336,31338,31339,31340,31342,31343,31501,31557,31565,31573,31581,31837,31875,31876,31877,31878,31879,31883,31884,31885,31886,31887,31888,31889,31893,31894,31895,31896,31898,31899,31900,31902,31903,31904,31905,31906,31908,31909,31911,31912,31913,31915,31916,31917,31918,31925,31926,31927,31928,31929,31935,31936,31937,31938,31939,31940,31943,31952,32411,32520,33186,33457,33458,33459,33460,33461,33462,33954) +AND `Reference` = 0; +DELETE FROM `creature_loot_template` WHERE +`Entry` IN (16972,16973,17034,17035,17039,17053,18128,18130,18131,18132,18133,18138,18213,18214,18280,19423,19458,19459,19706,20196,20279,20280,20283,20290,20324,20387,16863,16879,16880,16946,16947,16950,16954,16960,16974,16975,17014,18827,18975,18981,19190,19261,19282,19298,19335,19408,19434,19527,20798,18136,18137,18124,19402,16904,16905,16906,16978,16846,16847,16867,16870,16871,16873,16876,16878,16907,16911,16912,16925,16927,16928,16929,16964,16966,16967,18077,18079,18080,18113,18114,18123,18340,18952,19263,19295,19410,19411,19413,19414,19415,19422,19424,19442,19457,19701,20115,16844,16857,16901,16903,16968,18977,19299,19264,19312,19443) +AND `Reference` IN ( +6000, -- Occurrences: 106, Bundle +6003, -- Occurrences: 44, Scrolls +6001 -- Occurrences: 1, Bundle +); + +-- Fixes: These both pointed to the same lootid +UPDATE `creature_template` SET `lootid` = 8889 WHERE (`entry` = 8889); +UPDATE `creature_template` SET `lootid` = 8890 WHERE (`entry` = 8890); + +-- Deprecated +DELETE FROM `reference_loot_template` WHERE `Entry` IN (24004,24006,24008,24012,24014,24015,24022,24023,24127,24726,6000,4100,4101,4102); diff --git a/data/sql/updates/pending_db_world/wotlk.sql b/data/sql/updates/pending_db_world/wotlk.sql new file mode 100644 index 000000000..b2723781b --- /dev/null +++ b/data/sql/updates/pending_db_world/wotlk.sql @@ -0,0 +1,4510 @@ +-- +DELETE FROM `reference_loot_template` WHERE `Entry` IN (1206874,1207583,1226870,1226971,1227072,1227173,1227274,1227375,1227476,1227577,1227678,1227779,1227880,1227981,1228082,1228183,1236871,1237072,1237173,1237274,1237375,1237476,1237577,1237678,1237779,1237981,1238083,1248083,1256875,1256883,1257683,1266870,1267174,1267579,1268083,1270000,1270001,1270002); +INSERT INTO `reference_loot_template` (`Entry`, `Chance`, `GroupId`, `Item`, `Comment`) VALUES +-- ItemId, ItemName, ItemLevel, RequiredLevel, Quality, +-- Greys (5%) +-- 68-74 +(1206874, 0, 1, 33372, 'Fur-Lined Armor'), -- 118, 71, 0, +(1206874, 0, 1, 33373, 'Fur-Lined Belt'), -- 118, 71, 0, +(1206874, 0, 1, 33374, 'Fur-Lined Boots'), -- 118, 71, 0, +(1206874, 0, 1, 33375, 'Fur-Lined Bracers'), -- 118, 71, 0, +(1206874, 0, 1, 33376, 'Fur-Lined Gloves'), -- 118, 71, 0, +(1206874, 0, 1, 33439, 'Fur-Lined Leather Helmet'), -- 118, 71, 0, +(1206874, 0, 1, 33377, 'Fur-Lined Pants'), -- 118, 71, 0, +(1206874, 0, 1, 33378, 'Fur-Lined Shoulderpads'), -- 118, 71, 0, +(1206874, 0, 1, 33404, 'Ice-Bound Plate Belt'), -- 118, 71, 0, +(1206874, 0, 1, 33405, 'Ice-Bound Plate Boots'), -- 118, 71, 0, +(1206874, 0, 1, 33406, 'Ice-Bound Plate Bracers'), -- 118, 71, 0, +(1206874, 0, 1, 33407, 'Ice-Bound Plate Chestpiece'), -- 118, 71, 0, +(1206874, 0, 1, 33408, 'Ice-Bound Plate Gloves'), -- 118, 71, 0, +(1206874, 0, 1, 33440, 'Ice-Bound Plate Helmet'), -- 118, 71, 0, +(1206874, 0, 1, 33409, 'Ice-Bound Plate Pants'), -- 118, 71, 0, +(1206874, 0, 1, 33410, 'Ice-Bound Plate Shoulderpads'), -- 118, 71, 0, +(1206874, 0, 1, 33390, 'Icy Mail Armor'), -- 118, 71, 0, +(1206874, 0, 1, 33391, 'Icy Mail Belt'), -- 118, 71, 0, +(1206874, 0, 1, 33392, 'Icy Mail Boots'), -- 118, 71, 0, +(1206874, 0, 1, 33393, 'Icy Mail Bracers'), -- 118, 71, 0, +(1206874, 0, 1, 33437, 'Icy Mail Circlet'), -- 118, 71, 0, +(1206874, 0, 1, 33394, 'Icy Mail Gloves'), -- 118, 71, 0, +(1206874, 0, 1, 33395, 'Icy Mail Pants'), -- 118, 71, 0, +(1206874, 0, 1, 33396, 'Icy Mail Shoulderpads'), -- 118, 71, 0, +(1206874, 0, 1, 33358, 'Thread-Bare Cloth Belt'), -- 118, 71, 0, +(1206874, 0, 1, 33359, 'Thread-Bare Cloth Boots'), -- 118, 71, 0, +(1206874, 0, 1, 33360, 'Thread-Bare Cloth Bracers'), -- 118, 71, 0, +(1206874, 0, 1, 33361, 'Thread-Bare Cloth Gloves'), -- 118, 71, 0, +(1206874, 0, 1, 33362, 'Thread-Bare Cloth Pants'), -- 118, 71, 0, +(1206874, 0, 1, 33363, 'Thread-Bare Cloth Shoulderpads'), -- 118, 71, 0, +(1206874, 0, 1, 33364, 'Thread-Bare Cloth Vest'), -- 118, 71, 0, +(1206874, 0, 1, 33438, 'Thread-Bare Hat'), -- 118, 71, 0, +(1206874, 0, 1, 33430, 'Abandoned Greatsword'), -- 125, 74, 0, +(1206874, 0, 1, 33426, 'Chipped Timber Axe'), -- 125, 74, 0, +(1206874, 0, 1, 33424, 'Cracked Iron Staff'), -- 125, 74, 0, +(1206874, 0, 1, 33428, 'Dulled Shiv'), -- 125, 74, 0, +(1206874, 0, 1, 33427, 'Frost-Encrusted Rifle'), -- 125, 74, 0, +(1206874, 0, 1, 33429, 'Ice Cleaver'), -- 125, 74, 0, +(1206874, 0, 1, 33425, 'Ice-Pitted Blade'), -- 125, 74, 0, +(1206874, 0, 1, 33431, 'Icesmashing Mace'), -- 125, 74, 0, +(1206874, 0, 1, 33423, 'Rime-Covered Mace'), -- 125, 74, 0, +(1206874, 0, 1, 33422, 'Shattered Bow'), -- 125, 74, 0, +-- 75-80 +(1207583, 0, 1, 33430, 'Abandoned Greatsword'), -- 125, 74, 0, +(1207583, 0, 1, 33426, 'Chipped Timber Axe'), -- 125, 74, 0, +(1207583, 0, 1, 33424, 'Cracked Iron Staff'), -- 125, 74, 0, +(1207583, 0, 1, 33428, 'Dulled Shiv'), -- 125, 74, 0, +(1207583, 0, 1, 33427, 'Frost-Encrusted Rifle'), -- 125, 74, 0, +(1207583, 0, 1, 33429, 'Ice Cleaver'), -- 125, 74, 0, +(1207583, 0, 1, 33425, 'Ice-Pitted Blade'), -- 125, 74, 0, +(1207583, 0, 1, 33431, 'Icesmashing Mace'), -- 125, 74, 0, +(1207583, 0, 1, 33423, 'Rime-Covered Mace'), -- 125, 74, 0, +(1207583, 0, 1, 33422, 'Shattered Bow'), -- 125, 74, 0, +(1207583, 0, 1, 33397, 'Frigid Mail Armor'), -- 132, 77, 0, +(1207583, 0, 1, 33398, 'Frigid Mail Belt'), -- 132, 77, 0, +(1207583, 0, 1, 33399, 'Frigid Mail Boots'), -- 132, 77, 0, +(1207583, 0, 1, 33400, 'Frigid Mail Bracers'), -- 132, 77, 0, +(1207583, 0, 1, 33433, 'Frigid Mail Circlet'), -- 132, 77, 0, +(1207583, 0, 1, 33401, 'Frigid Mail Gloves'), -- 132, 77, 0, +(1207583, 0, 1, 33402, 'Frigid Mail Pants'), -- 132, 77, 0, +(1207583, 0, 1, 33403, 'Frigid Mail Shoulderpads'), -- 132, 77, 0, +(1207583, 0, 1, 33365, 'Frost-Rimed Cloth Belt'), -- 132, 77, 0, +(1207583, 0, 1, 33366, 'Frost-Rimed Cloth Boots'), -- 132, 77, 0, +(1207583, 0, 1, 33367, 'Frost-Rimed Cloth Bracers'), -- 132, 77, 0, +(1207583, 0, 1, 33368, 'Frost-Rimed Cloth Gloves'), -- 132, 77, 0, +(1207583, 0, 1, 33436, 'Frost-Rimed Cloth Hat'), -- 132, 77, 0, +(1207583, 0, 1, 33369, 'Frost-Rimed Cloth Pants'), -- 132, 77, 0, +(1207583, 0, 1, 33370, 'Frost-Rimed Cloth Shoulderpads'), -- 132, 77, 0, +(1207583, 0, 1, 33371, 'Frost-Rimed Cloth Vest'), -- 132, 77, 0, +(1207583, 0, 1, 33412, 'Frost-Worn Plate Belt'), -- 132, 77, 0, +(1207583, 0, 1, 33413, 'Frost-Worn Plate Boots'), -- 132, 77, 0, +(1207583, 0, 1, 33414, 'Frost-Worn Plate Bracers'), -- 132, 77, 0, +(1207583, 0, 1, 33415, 'Frost-Worn Plate Chestpiece'), -- 132, 77, 0, +(1207583, 0, 1, 33416, 'Frost-Worn Plate Gloves'), -- 132, 77, 0, +(1207583, 0, 1, 33435, 'Frost-Worn Plate Helmet'), -- 132, 77, 0, +(1207583, 0, 1, 33417, 'Frost-Worn Plate Pants'), -- 132, 77, 0, +(1207583, 0, 1, 33419, 'Frost-Worn Plate Shoulderpads'), -- 132, 77, 0, +(1207583, 0, 1, 33379, 'Frozen Armor'), -- 132, 77, 0, +(1207583, 0, 1, 33380, 'Frozen Belt'), -- 132, 77, 0, +(1207583, 0, 1, 33381, 'Frozen Boots'), -- 132, 77, 0, +(1207583, 0, 1, 33382, 'Frozen Bracers'), -- 132, 77, 0, +(1207583, 0, 1, 33383, 'Frozen Gloves'), -- 132, 77, 0, +(1207583, 0, 1, 33434, 'Frozen Leather Helmet'), -- 132, 77, 0, +(1207583, 0, 1, 33384, 'Frozen Pants'), -- 132, 77, 0, +(1207583, 0, 1, 33385, 'Frozen Shoulderpads'), -- 132, 77, 0, +-- Greens (2%) +-- 68-70 +(1226870, 0, 1, 36697, 'Aquatic Greatstaff'), -- 130, 67, 2, +(1226870, 0, 1, 36641, 'Bound Musket'), -- 130, 67, 2, +(1226870, 0, 1, 36627, 'Composite Crossbow'), -- 130, 67, 2, +(1226870, 0, 1, 36068, 'Daggercap Boots'), -- 130, 67, 2, +(1226870, 0, 1, 36074, 'Daggercap Bracers'), -- 130, 67, 2, +(1226870, 0, 1, 36071, 'Daggercap Cover'), -- 130, 67, 2, +(1226870, 0, 1, 36070, 'Daggercap Gloves'), -- 130, 67, 2, +(1226870, 0, 1, 36069, 'Daggercap Jerkin'), -- 130, 67, 2, +(1226870, 0, 1, 36073, 'Daggercap Spaulders'), -- 130, 67, 2, +(1226870, 0, 1, 36072, 'Daggercap Trousers'), -- 130, 67, 2, +(1226870, 0, 1, 36067, 'Daggercap Waistband'), -- 130, 67, 2, +(1226870, 0, 1, 36669, 'Eccentric Dagger'), -- 130, 67, 2, +(1226870, 0, 1, 36683, 'Enshrined Mace'), -- 130, 67, 2, +(1226870, 0, 1, 35955, 'Farshire Belt'), -- 130, 67, 2, +(1226870, 0, 1, 35962, 'Farshire Cuffs'), -- 130, 67, 2, +(1226870, 0, 1, 35956, 'Farshire Footpads'), -- 130, 67, 2, +(1226870, 0, 1, 35958, 'Farshire Gloves'), -- 130, 67, 2, +(1226870, 0, 1, 35959, 'Farshire Hood'), -- 130, 67, 2, +(1226870, 0, 1, 35960, 'Farshire Pants'), -- 130, 67, 2, +(1226870, 0, 1, 35957, 'Farshire Robe'), -- 130, 67, 2, +(1226870, 0, 1, 35961, 'Farshire Shoulderpads'), -- 130, 67, 2, +(1226870, 0, 1, 36585, 'Finned Battleaxe'), -- 130, 67, 2, +(1226870, 0, 1, 36711, 'Forsaken Edge'), -- 130, 67, 2, +(1226870, 0, 1, 36186, 'Garmaul Bracers'), -- 130, 67, 2, +(1226870, 0, 1, 36181, 'Garmaul Chestpiece'), -- 130, 67, 2, +(1226870, 0, 1, 36182, 'Garmaul Fists'), -- 130, 67, 2, +(1226870, 0, 1, 36180, 'Garmaul Footwraps'), -- 130, 67, 2, +(1226870, 0, 1, 36183, 'Garmaul Helmet'), -- 130, 67, 2, +(1226870, 0, 1, 36184, 'Garmaul Legguards'), -- 130, 67, 2, +(1226870, 0, 1, 36185, 'Garmaul Shoulderguards'), -- 130, 67, 2, +(1226870, 0, 1, 36179, 'Garmaul Waistband'), -- 130, 67, 2, +(1226870, 0, 1, 36501, 'Granite Maul'), -- 130, 67, 2, +(1226870, 0, 1, 36613, 'Honorable Longbow'), -- 130, 67, 2, +(1226870, 0, 1, 36459, 'Icy Orb'), -- 130, 67, 2, +(1226870, 0, 1, 36557, 'Meat Ripper'), -- 130, 67, 2, +(1226870, 0, 1, 36599, 'Ocean Trident'), -- 130, 67, 2, +(1226870, 0, 1, 36417, 'Oval Ring'), -- 130, 67, 2, +(1226870, 0, 1, 36431, 'Painted Wooden Beads'), -- 130, 67, 2, +(1226870, 0, 1, 36655, 'Pearled Wand'), -- 130, 67, 2, +(1226870, 0, 1, 36473, 'Pioneer\'s Dagger'), -- 130, 67, 2, +(1226870, 0, 1, 36515, 'Raider\'s Cutlass'), -- 130, 67, 2, +(1226870, 0, 1, 36403, 'Riding Cloak'), -- 130, 67, 2, +(1226870, 0, 1, 36445, 'Riveted Shield'), -- 130, 67, 2, +(1226870, 0, 1, 36571, 'Splicing Axe'), -- 130, 67, 2, +(1226870, 0, 1, 36487, 'Stone-Headed Gavel'), -- 130, 67, 2, +(1226870, 0, 1, 36543, 'Survival Stick'), -- 130, 67, 2, +(1226870, 0, 1, 36529, 'Unearthed Broadsword'), -- 130, 67, 2, +(1226870, 0, 1, 36293, 'Westguard Armor'), -- 130, 67, 2, +(1226870, 0, 1, 36291, 'Westguard Belt'), -- 130, 67, 2, +(1226870, 0, 1, 36298, 'Westguard Bracers'), -- 130, 67, 2, +(1226870, 0, 1, 36297, 'Westguard Epaulets'), -- 130, 67, 2, +(1226870, 0, 1, 36294, 'Westguard Gloves'), -- 130, 67, 2, +(1226870, 0, 1, 36292, 'Westguard Greaves'), -- 130, 67, 2, +(1226870, 0, 1, 36295, 'Westguard Helm'), -- 130, 67, 2, +(1226870, 0, 1, 36296, 'Westguard Legplates'), -- 130, 67, 2, +-- 69-71 +(1226971, 0, 1, 36684, 'Ambrosial Hammer'), -- 134, 68, 2, +(1226971, 0, 1, 35970, 'Bloodspore Bracelets'), -- 134, 68, 2, +(1226971, 0, 1, 35966, 'Bloodspore Gloves'), -- 134, 68, 2, +(1226971, 0, 1, 35967, 'Bloodspore Hood'), -- 134, 68, 2, +(1226971, 0, 1, 35968, 'Bloodspore Leggings'), -- 134, 68, 2, +(1226971, 0, 1, 35969, 'Bloodspore Mantle'), -- 134, 68, 2, +(1226971, 0, 1, 35965, 'Bloodspore Robe'), -- 134, 68, 2, +(1226971, 0, 1, 35964, 'Bloodspore Sandals'), -- 134, 68, 2, +(1226971, 0, 1, 35963, 'Bloodspore Sash'), -- 134, 68, 2, +(1226971, 0, 1, 36306, 'Coldrock Bracers'), -- 134, 68, 2, +(1226971, 0, 1, 36301, 'Coldrock Breastplate'), -- 134, 68, 2, +(1226971, 0, 1, 36302, 'Coldrock Gauntlets'), -- 134, 68, 2, +(1226971, 0, 1, 36299, 'Coldrock Girdle'), -- 134, 68, 2, +(1226971, 0, 1, 36303, 'Coldrock Helmet'), -- 134, 68, 2, +(1226971, 0, 1, 36304, 'Coldrock Legplates'), -- 134, 68, 2, +(1226971, 0, 1, 36305, 'Coldrock Pauldrons'), -- 134, 68, 2, +(1226971, 0, 1, 36300, 'Coldrock Sabatons'), -- 134, 68, 2, +(1226971, 0, 1, 36488, 'Conifer Club'), -- 134, 68, 2, +(1226971, 0, 1, 36698, 'Conifer Cone Staff'), -- 134, 68, 2, +(1226971, 0, 1, 36558, 'Curved Scratcher'), -- 134, 68, 2, +(1226971, 0, 1, 36656, 'Darkened Wand'), -- 134, 68, 2, +(1226971, 0, 1, 36572, 'Dinged Cleaver'), -- 134, 68, 2, +(1226971, 0, 1, 36474, 'Engraved Dagger'), -- 134, 68, 2, +(1226971, 0, 1, 36642, 'Flintlock Gun'), -- 134, 68, 2, +(1226971, 0, 1, 36418, 'Floral Loop'), -- 134, 68, 2, +(1226971, 0, 1, 36446, 'Forged-Iron Shield'), -- 134, 68, 2, +(1226971, 0, 1, 36670, 'Gypsy Blade'), -- 134, 68, 2, +(1226971, 0, 1, 36712, 'Howling Throwing Knives'), -- 134, 68, 2, +(1226971, 0, 1, 36544, 'Journeyed Staff'), -- 134, 68, 2, +(1226971, 0, 1, 36187, 'Njord Belt'), -- 134, 68, 2, +(1226971, 0, 1, 36188, 'Njord Boots'), -- 134, 68, 2, +(1226971, 0, 1, 36194, 'Njord Bracers'), -- 134, 68, 2, +(1226971, 0, 1, 36189, 'Njord Chain Vest'), -- 134, 68, 2, +(1226971, 0, 1, 36190, 'Njord Gauntlets'), -- 134, 68, 2, +(1226971, 0, 1, 36191, 'Njord Helm'), -- 134, 68, 2, +(1226971, 0, 1, 36192, 'Njord Leggings'), -- 134, 68, 2, +(1226971, 0, 1, 36193, 'Njord Shoulderguards'), -- 134, 68, 2, +(1226971, 0, 1, 36460, 'Northern Star'), -- 134, 68, 2, +(1226971, 0, 1, 36432, 'Silver Rope Chain'), -- 134, 68, 2, +(1226971, 0, 1, 36404, 'Suede Cloak'), -- 134, 68, 2, +(1226971, 0, 1, 36516, 'Tribal Blade'), -- 134, 68, 2, +(1226971, 0, 1, 36628, 'Under-Arm Crossbow'), -- 134, 68, 2, +(1226971, 0, 1, 36502, 'Ungainly Mace'), -- 134, 68, 2, +(1226971, 0, 1, 36600, 'Village Scythe'), -- 134, 68, 2, +(1226971, 0, 1, 36530, 'Whetted Ironblade'), -- 134, 68, 2, +(1226971, 0, 1, 36082, 'Winterfin Bindings'), -- 134, 68, 2, +(1226971, 0, 1, 36076, 'Winterfin Boots'), -- 134, 68, 2, +(1226971, 0, 1, 36077, 'Winterfin Chestpiece'), -- 134, 68, 2, +(1226971, 0, 1, 36075, 'Winterfin Cord'), -- 134, 68, 2, +(1226971, 0, 1, 36079, 'Winterfin Cowl'), -- 134, 68, 2, +(1226971, 0, 1, 36078, 'Winterfin Gloves'), -- 134, 68, 2, +(1226971, 0, 1, 36080, 'Winterfin Legguards'), -- 134, 68, 2, +(1226971, 0, 1, 36081, 'Winterfin Shoulderguards'), -- 134, 68, 2, +(1226971, 0, 1, 36586, 'Wreaking Battleaxe'), -- 134, 68, 2, +(1226971, 0, 1, 36614, 'Yew Bow'), -- 134, 68, 2, +-- 70-72 +(1227072, 0, 1, 36309, 'Baleheim Armor'), -- 138, 69, 2, +(1227072, 0, 1, 36307, 'Baleheim Belt'), -- 138, 69, 2, +(1227072, 0, 1, 36313, 'Baleheim Epaulets'), -- 138, 69, 2, +(1227072, 0, 1, 36310, 'Baleheim Gloves'), -- 138, 69, 2, +(1227072, 0, 1, 36308, 'Baleheim Greaves'), -- 138, 69, 2, +(1227072, 0, 1, 36311, 'Baleheim Helmet'), -- 138, 69, 2, +(1227072, 0, 1, 36312, 'Baleheim Legguards'), -- 138, 69, 2, +(1227072, 0, 1, 36314, 'Baleheim Vambraces'), -- 138, 69, 2, +(1227072, 0, 1, 36545, 'Branched Stick'), -- 138, 69, 2, +(1227072, 0, 1, 36461, 'Demon-Skull Orb'), -- 138, 69, 2, +(1227072, 0, 1, 36405, 'Double Cape'), -- 138, 69, 2, +(1227072, 0, 1, 36615, 'Expert\'s Longbow'), -- 138, 69, 2, +(1227072, 0, 1, 36629, 'Ferocious Crossbow'), -- 138, 69, 2, +(1227072, 0, 1, 36419, 'Glass Ring'), -- 138, 69, 2, +(1227072, 0, 1, 36699, 'Iceberg Staff'), -- 138, 69, 2, +(1227072, 0, 1, 36489, 'Iron Flanged Scepter'), -- 138, 69, 2, +(1227072, 0, 1, 36517, 'Iron-Grip Shortsword'), -- 138, 69, 2, +(1227072, 0, 1, 36447, 'Kaskala Buckler'), -- 138, 69, 2, +(1227072, 0, 1, 35972, 'Mur\'ghoul Boots'), -- 138, 69, 2, +(1227072, 0, 1, 35975, 'Mur\'ghoul Cap'), -- 138, 69, 2, +(1227072, 0, 1, 35971, 'Mur\'ghoul Girdle'), -- 138, 69, 2, +(1227072, 0, 1, 35974, 'Mur\'ghoul Handwraps'), -- 138, 69, 2, +(1227072, 0, 1, 35976, 'Mur\'ghoul Leggings'), -- 138, 69, 2, +(1227072, 0, 1, 35973, 'Mur\'ghoul Robe'), -- 138, 69, 2, +(1227072, 0, 1, 35977, 'Mur\'ghoul Shoulderpads'), -- 138, 69, 2, +(1227072, 0, 1, 35978, 'Mur\'ghoul Wristwraps'), -- 138, 69, 2, +(1227072, 0, 1, 36671, 'Ominous Dagger'), -- 138, 69, 2, +(1227072, 0, 1, 36601, 'Patient Harpoon'), -- 138, 69, 2, +(1227072, 0, 1, 36685, 'Placid Lightmace'), -- 138, 69, 2, +(1227072, 0, 1, 36573, 'Primeval Adze'), -- 138, 69, 2, +(1227072, 0, 1, 36559, 'Prized Handscythes'), -- 138, 69, 2, +(1227072, 0, 1, 36713, 'Reaching Star'), -- 138, 69, 2, +(1227072, 0, 1, 36083, 'Riplash Belt'), -- 138, 69, 2, +(1227072, 0, 1, 36084, 'Riplash Boots'), -- 138, 69, 2, +(1227072, 0, 1, 36087, 'Riplash Cover'), -- 138, 69, 2, +(1227072, 0, 1, 36086, 'Riplash Gloves'), -- 138, 69, 2, +(1227072, 0, 1, 36085, 'Riplash Jerkin'), -- 138, 69, 2, +(1227072, 0, 1, 36088, 'Riplash Leggings'), -- 138, 69, 2, +(1227072, 0, 1, 36089, 'Riplash Pauldrons'), -- 138, 69, 2, +(1227072, 0, 1, 36090, 'Riplash Wristguards'), -- 138, 69, 2, +(1227072, 0, 1, 36531, 'Sawtooth Greatsword'), -- 138, 69, 2, +(1227072, 0, 1, 36475, 'Seal Shortblade'), -- 138, 69, 2, +(1227072, 0, 1, 36202, 'Skom Bracers'), -- 138, 69, 2, +(1227072, 0, 1, 36197, 'Skom Chain Vest'), -- 138, 69, 2, +(1227072, 0, 1, 36198, 'Skom Gloves'), -- 138, 69, 2, +(1227072, 0, 1, 36196, 'Skom Greaves'), -- 138, 69, 2, +(1227072, 0, 1, 36199, 'Skom Helm'), -- 138, 69, 2, +(1227072, 0, 1, 36200, 'Skom Leggings'), -- 138, 69, 2, +(1227072, 0, 1, 36201, 'Skom Spaulders'), -- 138, 69, 2, +(1227072, 0, 1, 36195, 'Skom Stitched-Belt'), -- 138, 69, 2, +(1227072, 0, 1, 36433, 'Snake Entwined Necklace'), -- 138, 69, 2, +(1227072, 0, 1, 36587, 'Taunka Axe'), -- 138, 69, 2, +(1227072, 0, 1, 36503, 'Toothless Bludgeon'), -- 138, 69, 2, +(1227072, 0, 1, 36643, 'Tracker\'s Musket'), -- 138, 69, 2, +(1227072, 0, 1, 36657, 'Vicious Wand'), -- 138, 69, 2, +-- 71-73 +(1227173, 0, 1, 36574, 'Bone Cleaver'), -- 142, 70, 2, +(1227173, 0, 1, 36588, 'Burning Battleaxe'), -- 142, 70, 2, +(1227173, 0, 1, 36504, 'Cleft-Edged Hammer'), -- 142, 70, 2, +(1227173, 0, 1, 36462, 'Coldarra Crystal'), -- 142, 70, 2, +(1227173, 0, 1, 36616, 'Dutiful Longbow'), -- 142, 70, 2, +(1227173, 0, 1, 36658, 'Extinguished Spark'), -- 142, 70, 2, +(1227173, 0, 1, 36560, 'Fighter\'s Grip'), -- 142, 70, 2, +(1227173, 0, 1, 35979, 'Foothold Belt'), -- 142, 70, 2, +(1227173, 0, 1, 35980, 'Foothold Boots'), -- 142, 70, 2, +(1227173, 0, 1, 35986, 'Foothold Cuffs'), -- 142, 70, 2, +(1227173, 0, 1, 35982, 'Foothold Gloves'), -- 142, 70, 2, +(1227173, 0, 1, 35983, 'Foothold Hood'), -- 142, 70, 2, +(1227173, 0, 1, 35984, 'Foothold Pants'), -- 142, 70, 2, +(1227173, 0, 1, 35981, 'Foothold Robe'), -- 142, 70, 2, +(1227173, 0, 1, 35985, 'Foothold Shoulderpads'), -- 142, 70, 2, +(1227173, 0, 1, 36420, 'Gemstone Ring'), -- 142, 70, 2, +(1227173, 0, 1, 36434, 'Gold Mesh Collar'), -- 142, 70, 2, +(1227173, 0, 1, 36686, 'Harmonious Scepter'), -- 142, 70, 2, +(1227173, 0, 1, 36644, 'Inelegant Musket'), -- 142, 70, 2, +(1227173, 0, 1, 36210, 'Nifflevar Bindings'), -- 142, 70, 2, +(1227173, 0, 1, 36204, 'Nifflevar Boots'), -- 142, 70, 2, +(1227173, 0, 1, 36205, 'Nifflevar Chestpiece'), -- 142, 70, 2, +(1227173, 0, 1, 36203, 'Nifflevar Girdle'), -- 142, 70, 2, +(1227173, 0, 1, 36206, 'Nifflevar Gloves'), -- 142, 70, 2, +(1227173, 0, 1, 36207, 'Nifflevar Helmet'), -- 142, 70, 2, +(1227173, 0, 1, 36208, 'Nifflevar Legguards'), -- 142, 70, 2, +(1227173, 0, 1, 36209, 'Nifflevar Shoulderguards'), -- 142, 70, 2, +(1227173, 0, 1, 36700, 'Peat Greatstaff'), -- 142, 70, 2, +(1227173, 0, 1, 36602, 'Rust-Covered Polearm'), -- 142, 70, 2, +(1227173, 0, 1, 36532, 'Shark Fin Blade'), -- 142, 70, 2, +(1227173, 0, 1, 36630, 'Sinewed Crossbow'), -- 142, 70, 2, +(1227173, 0, 1, 36448, 'Spiked Targe'), -- 142, 70, 2, +(1227173, 0, 1, 36672, 'Strange Dagger'), -- 142, 70, 2, +(1227173, 0, 1, 36518, 'Tundra\'s Edge'), -- 142, 70, 2, +(1227173, 0, 1, 36490, 'Tuskarr Cudgel'), -- 142, 70, 2, +(1227173, 0, 1, 36714, 'Tuskarr\'s Piercers'), -- 142, 70, 2, +(1227173, 0, 1, 36546, 'Unusual Staff'), -- 142, 70, 2, +(1227173, 0, 1, 36406, 'Wayfarer\'s Cloak'), -- 142, 70, 2, +(1227173, 0, 1, 36476, 'Whale Ripper'), -- 142, 70, 2, +(1227173, 0, 1, 36098, 'Wildevar Armguards'), -- 142, 70, 2, +(1227173, 0, 1, 36091, 'Wildevar Belt'), -- 142, 70, 2, +(1227173, 0, 1, 36092, 'Wildevar Boots'), -- 142, 70, 2, +(1227173, 0, 1, 36095, 'Wildevar Cap'), -- 142, 70, 2, +(1227173, 0, 1, 36094, 'Wildevar Gloves'), -- 142, 70, 2, +(1227173, 0, 1, 36096, 'Wildevar Pants'), -- 142, 70, 2, +(1227173, 0, 1, 36097, 'Wildevar Shoulderguards'), -- 142, 70, 2, +(1227173, 0, 1, 36093, 'Wildevar Tunic'), -- 142, 70, 2, +(1227173, 0, 1, 36322, 'Wyrmskull Bracers'), -- 142, 70, 2, +(1227173, 0, 1, 36317, 'Wyrmskull Breastplate'), -- 142, 70, 2, +(1227173, 0, 1, 36321, 'Wyrmskull Epaulets'), -- 142, 70, 2, +(1227173, 0, 1, 36318, 'Wyrmskull Gauntlets'), -- 142, 70, 2, +(1227173, 0, 1, 36315, 'Wyrmskull Girdle'), -- 142, 70, 2, +(1227173, 0, 1, 36319, 'Wyrmskull Helm'), -- 142, 70, 2, +(1227173, 0, 1, 36320, 'Wyrmskull Legplates'), -- 142, 70, 2, +(1227173, 0, 1, 36316, 'Wyrmskull Sabatons'), -- 142, 70, 2, +-- 72-74 +(1227274, 0, 1, 35994, 'Bristlepine Bracers'), -- 146, 71, 2, +(1227274, 0, 1, 35987, 'Bristlepine Cord'), -- 146, 71, 2, +(1227274, 0, 1, 35990, 'Bristlepine Handwraps'), -- 146, 71, 2, +(1227274, 0, 1, 35991, 'Bristlepine Headpiece'), -- 146, 71, 2, +(1227274, 0, 1, 35992, 'Bristlepine Leggings'), -- 146, 71, 2, +(1227274, 0, 1, 35989, 'Bristlepine Robe'), -- 146, 71, 2, +(1227274, 0, 1, 35988, 'Bristlepine Sandals'), -- 146, 71, 2, +(1227274, 0, 1, 35993, 'Bristlepine Shoulderpads'), -- 146, 71, 2, +(1227274, 0, 1, 36106, 'Caribou Bands'), -- 146, 71, 2, +(1227274, 0, 1, 36100, 'Caribou Boots'), -- 146, 71, 2, +(1227274, 0, 1, 36104, 'Caribou Britches'), -- 146, 71, 2, +(1227274, 0, 1, 36103, 'Caribou Cowl'), -- 146, 71, 2, +(1227274, 0, 1, 36102, 'Caribou Gloves'), -- 146, 71, 2, +(1227274, 0, 1, 36105, 'Caribou Shoulders'), -- 146, 71, 2, +(1227274, 0, 1, 36101, 'Caribou Vest'), -- 146, 71, 2, +(1227274, 0, 1, 36099, 'Caribou Waistband'), -- 146, 71, 2, +(1227274, 0, 1, 36421, 'Devotional Band'), -- 146, 71, 2, +(1227274, 0, 1, 36435, 'Embroidered Pendant'), -- 146, 71, 2, +(1227274, 0, 1, 36323, 'Halgrind Belt'), -- 146, 71, 2, +(1227274, 0, 1, 36330, 'Halgrind Bracers'), -- 146, 71, 2, +(1227274, 0, 1, 36325, 'Halgrind Carapace'), -- 146, 71, 2, +(1227274, 0, 1, 36329, 'Halgrind Epaulets'), -- 146, 71, 2, +(1227274, 0, 1, 36326, 'Halgrind Gloves'), -- 146, 71, 2, +(1227274, 0, 1, 36324, 'Halgrind Greaves'), -- 146, 71, 2, +(1227274, 0, 1, 36327, 'Halgrind Helmet'), -- 146, 71, 2, +(1227274, 0, 1, 36328, 'Halgrind Legplates'), -- 146, 71, 2, +(1227274, 0, 1, 36407, 'Lace-Trimmed Cloak'), -- 146, 71, 2, +(1227274, 0, 1, 36213, 'Orca Armor'), -- 146, 71, 2, +(1227274, 0, 1, 36211, 'Orca Belt'), -- 146, 71, 2, +(1227274, 0, 1, 36218, 'Orca Bindings'), -- 146, 71, 2, +(1227274, 0, 1, 36214, 'Orca Fists'), -- 146, 71, 2, +(1227274, 0, 1, 36212, 'Orca Footwraps'), -- 146, 71, 2, +(1227274, 0, 1, 36215, 'Orca Helmet'), -- 146, 71, 2, +(1227274, 0, 1, 36216, 'Orca Legwraps'), -- 146, 71, 2, +(1227274, 0, 1, 36217, 'Orca Spaulders'), -- 146, 71, 2, +(1227274, 0, 1, 36463, 'Polished Orb'), -- 146, 71, 2, +(1227274, 0, 1, 36449, 'Vrykul Shield'), -- 146, 71, 2, +-- Did you know my first pass missed several items? All weapons within this range. Apparently they never dropped prior to this. +(1227274, 0, 1, 36533, 'Adorned Broadsword'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36603, 'Archaic Longspear'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36575, 'Dragonflayer Hatchet'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36505, 'Frosted Steel Mallet'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36631, 'Horned Crossbow'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36687, 'Illuminated Scepter'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36547, 'Jester\'s Stick'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36519, 'Moonlit Katana'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36701, 'Pine Needle Staff'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36715, 'Runed Shuriken, 146'), -- 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36589, 'Segmenting Broadaxe'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36491, 'Serrated Maul'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36659, 'Shivery Wand'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36645, 'Tuskarr Boomstick'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36477, 'Twin-Edged Stiletto'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36673, 'Wise Dagger'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +(1227274, 0, 1, 36617, 'Yielding Bow'), -- 146, 71, 2 -- Random Green: Missing from Loot Table 72+ +-- 73-75 +(1227375, 0, 1, 36226, 'Amberpine Bracers'), -- 150, 72, 2, +(1227375, 0, 1, 36221, 'Amberpine Chain Vest'), -- 150, 72, 2, +(1227375, 0, 1, 36222, 'Amberpine Gauntlets'), -- 150, 72, 2, +(1227375, 0, 1, 36219, 'Amberpine Girdle'), -- 150, 72, 2, +(1227375, 0, 1, 36220, 'Amberpine Greaves'), -- 150, 72, 2, +(1227375, 0, 1, 36223, 'Amberpine Helmet'), -- 150, 72, 2, +(1227375, 0, 1, 36224, 'Amberpine Legguards'), -- 150, 72, 2, +(1227375, 0, 1, 36225, 'Amberpine Spaulders'), -- 150, 72, 2, +(1227375, 0, 1, 36576, 'Beaked Axe'), -- 150, 72, 2, +(1227375, 0, 1, 36562, 'Blue-Nailed Claws'), -- 150, 72, 2, +(1227375, 0, 1, 36590, 'Bone Plate Axe'), -- 150, 72, 2, +(1227375, 0, 1, 36520, 'Chopping Wideblade'), -- 150, 72, 2, +(1227375, 0, 1, 36464, 'Darkened Scepter'), -- 150, 72, 2, +(1227375, 0, 1, 36422, 'Filigree Ring'), -- 150, 72, 2, +(1227375, 0, 1, 36478, 'Frosty Talon'), -- 150, 72, 2, +(1227375, 0, 1, 36333, 'Grizzlemaw Armor'), -- 150, 72, 2, +(1227375, 0, 1, 36331, 'Grizzlemaw Belt'), -- 150, 72, 2, +(1227375, 0, 1, 36337, 'Grizzlemaw Epaulets'), -- 150, 72, 2, +(1227375, 0, 1, 36334, 'Grizzlemaw Gauntlets'), -- 150, 72, 2, +(1227375, 0, 1, 36335, 'Grizzlemaw Helm'), -- 150, 72, 2, +(1227375, 0, 1, 36336, 'Grizzlemaw Legplates'), -- 150, 72, 2, +(1227375, 0, 1, 36332, 'Grizzlemaw Sabatons'), -- 150, 72, 2, +(1227375, 0, 1, 36338, 'Grizzlemaw Vambraces'), -- 150, 72, 2, +(1227375, 0, 1, 36604, 'Grizzly Glaive'), -- 150, 72, 2, +(1227375, 0, 1, 36646, 'Haggard Gun'), -- 150, 72, 2, +(1227375, 0, 1, 36436, 'Jasper Bead Necklace'), -- 150, 72, 2, +(1227375, 0, 1, 36660, 'Melted Wand'), -- 150, 72, 2, +(1227375, 0, 1, 36702, 'Melting Icestaff'), -- 150, 72, 2, +(1227375, 0, 1, 36674, 'Old Tooth'), -- 150, 72, 2, +(1227375, 0, 1, 36492, 'Peaked Club'), -- 150, 72, 2, +(1227375, 0, 1, 36548, 'Promised Staff'), -- 150, 72, 2, +(1227375, 0, 1, 36408, 'Reversible Wool Cape'), -- 150, 72, 2, +(1227375, 0, 1, 36688, 'Sacrosanct Mace'), -- 150, 72, 2, +(1227375, 0, 1, 36632, 'Slingshot Crossbow'), -- 150, 72, 2, +(1227375, 0, 1, 36450, 'Strapped Heater Shield'), -- 150, 72, 2, +(1227375, 0, 1, 36534, 'Tempered-Steel Blade'), -- 150, 72, 2, +(1227375, 0, 1, 36716, 'Threatening Darts'), -- 150, 72, 2, +(1227375, 0, 1, 36618, 'Twisted Longbow'), -- 150, 72, 2, +(1227375, 0, 1, 36506, 'Vaulted Mace'), -- 150, 72, 2, +(1227375, 0, 1, 36109, 'Vileprey Armor'), -- 150, 72, 2, +(1227375, 0, 1, 36108, 'Vileprey Boots'), -- 150, 72, 2, +(1227375, 0, 1, 36114, 'Vileprey Bracers'), -- 150, 72, 2, +(1227375, 0, 1, 36107, 'Vileprey Cord'), -- 150, 72, 2, +(1227375, 0, 1, 36110, 'Vileprey Gloves'), -- 150, 72, 2, +(1227375, 0, 1, 36111, 'Vileprey Hood'), -- 150, 72, 2, +(1227375, 0, 1, 36112, 'Vileprey Leggings'), -- 150, 72, 2, +(1227375, 0, 1, 36113, 'Vileprey Pauldrons'), -- 150, 72, 2, +(1227375, 0, 1, 36002, 'Voldrune Bracelets'), -- 150, 72, 2, +(1227375, 0, 1, 35999, 'Voldrune Crown'), -- 150, 72, 2, +(1227375, 0, 1, 35998, 'Voldrune Gloves'), -- 150, 72, 2, +(1227375, 0, 1, 36000, 'Voldrune Legs'), -- 150, 72, 2, +(1227375, 0, 1, 36001, 'Voldrune Mantle'), -- 150, 72, 2, +(1227375, 0, 1, 35997, 'Voldrune Robe'), -- 150, 72, 2, +(1227375, 0, 1, 35995, 'Voldrune Sash'), -- 150, 72, 2, +(1227375, 0, 1, 35996, 'Voldrune Slippers'), -- 150, 72, 2, +-- 74-76 +(1227476, 0, 1, 36619, 'Astral Light Bow'), -- 154, 73, 2, +(1227476, 0, 1, 36341, 'Bloodmar Breastplate'), -- 154, 73, 2, +(1227476, 0, 1, 36342, 'Bloodmar Gauntlets'), -- 154, 73, 2, +(1227476, 0, 1, 36339, 'Bloodmar Girdle'), -- 154, 73, 2, +(1227476, 0, 1, 36343, 'Bloodmar Helm'), -- 154, 73, 2, +(1227476, 0, 1, 36344, 'Bloodmar Legplates'), -- 154, 73, 2, +(1227476, 0, 1, 36345, 'Bloodmar Pauldrons'), -- 154, 73, 2, +(1227476, 0, 1, 36340, 'Bloodmar Sabatons'), -- 154, 73, 2, +(1227476, 0, 1, 36346, 'Bloodmar Vambraces'), -- 154, 73, 2, +(1227476, 0, 1, 36409, 'Crushed Velvet Cloak'), -- 154, 73, 2, +(1227476, 0, 1, 36577, 'Disk Axe'), -- 154, 73, 2, +(1227476, 0, 1, 36535, 'Dragon\'s Rib Sword'), -- 154, 73, 2, +(1227476, 0, 1, 36661, 'Enigmatic Wand'), -- 154, 73, 2, +(1227476, 0, 1, 36465, 'Evergreen Branch'), -- 154, 73, 2, +(1227476, 0, 1, 36437, 'Figaro Chain'), -- 154, 73, 2, +(1227476, 0, 1, 36493, 'Furbolg Truncheon'), -- 154, 73, 2, +(1227476, 0, 1, 36563, 'Gloved Talons'), -- 154, 73, 2, +(1227476, 0, 1, 36010, 'Icemist Bracelets'), -- 154, 73, 2, +(1227476, 0, 1, 36007, 'Icemist Circlet'), -- 154, 73, 2, +(1227476, 0, 1, 36006, 'Icemist Gloves'), -- 154, 73, 2, +(1227476, 0, 1, 36009, 'Icemist Mantle'), -- 154, 73, 2, +(1227476, 0, 1, 36008, 'Icemist Pants'), -- 154, 73, 2, +(1227476, 0, 1, 36005, 'Icemist Robe'), -- 154, 73, 2, +(1227476, 0, 1, 36003, 'Icemist Sash'), -- 154, 73, 2, +(1227476, 0, 1, 36004, 'Icemist Slippers'), -- 154, 73, 2, +(1227476, 0, 1, 36507, 'Iron-Molded Fist'), -- 154, 73, 2, +(1227476, 0, 1, 36451, 'Kamagua Shield'), -- 154, 73, 2, +(1227476, 0, 1, 36647, 'Noisy Blaster'), -- 154, 73, 2, +(1227476, 0, 1, 36633, 'Palisade Crossbow'), -- 154, 73, 2, +(1227476, 0, 1, 36423, 'Posy Ring'), -- 154, 73, 2, +(1227476, 0, 1, 36549, 'Pulsing Quarterstaff'), -- 154, 73, 2, +(1227476, 0, 1, 36689, 'Refreshing Hammer'), -- 154, 73, 2, +(1227476, 0, 1, 36521, 'Shimmering Sabre'), -- 154, 73, 2, +(1227476, 0, 1, 36479, 'Snobold Ripper'), -- 154, 73, 2, +(1227476, 0, 1, 36675, 'Sockeye Dagger'), -- 154, 73, 2, +(1227476, 0, 1, 36122, 'Taunka Armguards'), -- 154, 73, 2, +(1227476, 0, 1, 36115, 'Taunka Belt'), -- 154, 73, 2, +(1227476, 0, 1, 36116, 'Taunka Boots'), -- 154, 73, 2, +(1227476, 0, 1, 36118, 'Taunka Gloves'), -- 154, 73, 2, +(1227476, 0, 1, 36119, 'Taunka Hat'), -- 154, 73, 2, +(1227476, 0, 1, 36120, 'Taunka Legguards'), -- 154, 73, 2, +(1227476, 0, 1, 36121, 'Taunka Spaulders'), -- 154, 73, 2, +(1227476, 0, 1, 36117, 'Taunka Tunic'), -- 154, 73, 2, +(1227476, 0, 1, 36227, 'Trapper Belt'), -- 154, 73, 2, +(1227476, 0, 1, 36234, 'Trapper Bracers'), -- 154, 73, 2, +(1227476, 0, 1, 36229, 'Trapper Chain Vest'), -- 154, 73, 2, +(1227476, 0, 1, 36228, 'Trapper Footwraps'), -- 154, 73, 2, +(1227476, 0, 1, 36230, 'Trapper Gloves'), -- 154, 73, 2, +(1227476, 0, 1, 36231, 'Trapper Helm'), -- 154, 73, 2, +(1227476, 0, 1, 36232, 'Trapper Leggings'), -- 154, 73, 2, +(1227476, 0, 1, 36233, 'Trapper Shoulderguards'), -- 154, 73, 2, +(1227476, 0, 1, 36703, 'Tusked Greatstaff'), -- 154, 73, 2, +(1227476, 0, 1, 36717, 'Venture Co. Throwing Axe'), -- 154, 73, 2, +(1227476, 0, 1, 36605, 'Wind Scythe'), -- 154, 73, 2, +(1227476, 0, 1, 36591, 'Winged Axe'), -- 154, 73, 2, +-- 75-77 +(1227577, 0, 1, 36494, 'Barbed Star'), -- 158, 74, 2, +(1227577, 0, 1, 36424, 'Cameo Ring'), -- 158, 74, 2, +(1227577, 0, 1, 36410, 'Caribou Skin Cloak'), -- 158, 74, 2, +(1227577, 0, 1, 36508, 'Cumbersome Sledgehammer'), -- 158, 74, 2, +(1227577, 0, 1, 36592, 'Deforester Axe'), -- 158, 74, 2, +(1227577, 0, 1, 36480, 'Ebony Dagger'), -- 158, 74, 2, +(1227577, 0, 1, 36466, 'Facetted Orb'), -- 158, 74, 2, +(1227577, 0, 1, 36704, 'Hive Comb Staff'), -- 158, 74, 2, +(1227577, 0, 1, 36536, 'Inlaid Greatsword'), -- 158, 74, 2, +(1227577, 0, 1, 36354, 'Jormungar Bracers'), -- 158, 74, 2, +(1227577, 0, 1, 36349, 'Jormungar Breastplate'), -- 158, 74, 2, +(1227577, 0, 1, 36350, 'Jormungar Gauntlets'), -- 158, 74, 2, +(1227577, 0, 1, 36347, 'Jormungar Girdle'), -- 158, 74, 2, +(1227577, 0, 1, 36351, 'Jormungar Helmet'), -- 158, 74, 2, +(1227577, 0, 1, 36352, 'Jormungar Legplates'), -- 158, 74, 2, +(1227577, 0, 1, 36353, 'Jormungar Pauldrons'), -- 158, 74, 2, +(1227577, 0, 1, 36348, 'Jormungar Sabatons'), -- 158, 74, 2, +(1227577, 0, 1, 36123, 'Muradin Belt'), -- 158, 74, 2, +(1227577, 0, 1, 36130, 'Muradin Bindings'), -- 158, 74, 2, +(1227577, 0, 1, 36124, 'Muradin Boots'), -- 158, 74, 2, +(1227577, 0, 1, 36125, 'Muradin Chestpiece'), -- 158, 74, 2, +(1227577, 0, 1, 36126, 'Muradin Gloves'), -- 158, 74, 2, +(1227577, 0, 1, 36127, 'Muradin Hood'), -- 158, 74, 2, +(1227577, 0, 1, 36128, 'Muradin Pants'), -- 158, 74, 2, +(1227577, 0, 1, 36129, 'Muradin Shoulders'), -- 158, 74, 2, +(1227577, 0, 1, 36718, 'Nexus Shrike'), -- 158, 74, 2, +(1227577, 0, 1, 36634, 'Pain Repeater'), -- 158, 74, 2, +(1227577, 0, 1, 36550, 'Refulgent Staff'), -- 158, 74, 2, +(1227577, 0, 1, 36606, 'Rugged Polearm'), -- 158, 74, 2, +(1227577, 0, 1, 36522, 'Scored Blade'), -- 158, 74, 2, +(1227577, 0, 1, 36438, 'Shark-Toothed Necklace'), -- 158, 74, 2, +(1227577, 0, 1, 36242, 'Shoveltusk Bindings'), -- 158, 74, 2, +(1227577, 0, 1, 36237, 'Shoveltusk Breastplate'), -- 158, 74, 2, +(1227577, 0, 1, 36238, 'Shoveltusk Gauntlets'), -- 158, 74, 2, +(1227577, 0, 1, 36236, 'Shoveltusk Greaves'), -- 158, 74, 2, +(1227577, 0, 1, 36239, 'Shoveltusk Helmet'), -- 158, 74, 2, +(1227577, 0, 1, 36240, 'Shoveltusk Legguards'), -- 158, 74, 2, +(1227577, 0, 1, 36241, 'Shoveltusk Mantle'), -- 158, 74, 2, +(1227577, 0, 1, 36235, 'Shoveltusk Waistband'), -- 158, 74, 2, +(1227577, 0, 1, 36564, 'Spider Claw'), -- 158, 74, 2, +(1227577, 0, 1, 36452, 'Spoke Shield'), -- 158, 74, 2, +(1227577, 0, 1, 36018, 'Tethys Bracelets'), -- 158, 74, 2, +(1227577, 0, 1, 36014, 'Tethys Gloves'), -- 158, 74, 2, +(1227577, 0, 1, 36015, 'Tethys Hood'), -- 158, 74, 2, +(1227577, 0, 1, 36016, 'Tethys Leggings'), -- 158, 74, 2, +(1227577, 0, 1, 36017, 'Tethys Mantle'), -- 158, 74, 2, +(1227577, 0, 1, 36013, 'Tethys Robe'), -- 158, 74, 2, +(1227577, 0, 1, 36011, 'Tethys Sash'), -- 158, 74, 2, +(1227577, 0, 1, 36012, 'Tethys Slippers'), -- 158, 74, 2, +(1227577, 0, 1, 36620, 'Tracking Bow'), -- 158, 74, 2, +(1227577, 0, 1, 36648, 'Trapper\'s Rifle'), -- 158, 74, 2, +(1227577, 0, 1, 36578, 'Troll Chopper'), -- 158, 74, 2, +(1227577, 0, 1, 36690, 'Unearthly Scepter'), -- 158, 74, 2, +(1227577, 0, 1, 36662, 'Voodoo Wand'), -- 158, 74, 2, +(1227577, 0, 1, 36676, 'Water Blade'), -- 158, 74, 2, +-- 76-78 +(1227678, 0, 1, 36621, 'Advanced Flatbow'), -- 162, 75, 2, +(1227678, 0, 1, 36019, 'Aerie Belt'), -- 162, 75, 2, +(1227678, 0, 1, 36020, 'Aerie Boots'), -- 162, 75, 2, +(1227678, 0, 1, 36026, 'Aerie Bracers'), -- 162, 75, 2, +(1227678, 0, 1, 36022, 'Aerie Gloves'), -- 162, 75, 2, +(1227678, 0, 1, 36023, 'Aerie Headpiece'), -- 162, 75, 2, +(1227678, 0, 1, 36024, 'Aerie Pants'), -- 162, 75, 2, +(1227678, 0, 1, 36021, 'Aerie Robe'), -- 162, 75, 2, +(1227678, 0, 1, 36025, 'Aerie Shoulderpads'), -- 162, 75, 2, +(1227678, 0, 1, 36663, 'Ancient Wand'), -- 162, 75, 2, +(1227678, 0, 1, 36579, 'Boreal Woodchopper'), -- 162, 75, 2, +(1227678, 0, 1, 36411, 'Brawler\'s Cape'), -- 162, 75, 2, +(1227678, 0, 1, 36691, 'Dignified Hammer'), -- 162, 75, 2, +(1227678, 0, 1, 36607, 'Dwarven Halberd'), -- 162, 75, 2, +(1227678, 0, 1, 36453, 'Embossed Brazen Shield'), -- 162, 75, 2, +(1227678, 0, 1, 36509, 'Femur-Shafted Mace'), -- 162, 75, 2, +(1227678, 0, 1, 36495, 'Ferrous Hammer'), -- 162, 75, 2, +(1227678, 0, 1, 36357, 'Frostpaw Armor'), -- 162, 75, 2, +(1227678, 0, 1, 36355, 'Frostpaw Belt'), -- 162, 75, 2, +(1227678, 0, 1, 36361, 'Frostpaw Epaulets'), -- 162, 75, 2, +(1227678, 0, 1, 36358, 'Frostpaw Gauntlets'), -- 162, 75, 2, +(1227678, 0, 1, 36356, 'Frostpaw Greaves'), -- 162, 75, 2, +(1227678, 0, 1, 36359, 'Frostpaw Helmet'), -- 162, 75, 2, +(1227678, 0, 1, 36360, 'Frostpaw Legguards'), -- 162, 75, 2, +(1227678, 0, 1, 36362, 'Frostpaw Vambraces'), -- 162, 75, 2, +(1227678, 0, 1, 36537, 'Fur-Grip Broadsword'), -- 162, 75, 2, +(1227678, 0, 1, 36705, 'Geyser Staff'), -- 162, 75, 2, +(1227678, 0, 1, 36425, 'Gold Twisted Ring'), -- 162, 75, 2, +(1227678, 0, 1, 36565, 'Hero\'s Knuckles'), -- 162, 75, 2, +(1227678, 0, 1, 36719, 'Hunter\'s Scout'), -- 162, 75, 2, +(1227678, 0, 1, 36677, 'Levitating Dagger'), -- 162, 75, 2, +(1227678, 0, 1, 36250, 'Mammoth Bindings'), -- 162, 75, 2, +(1227678, 0, 1, 36244, 'Mammoth Boots'), -- 162, 75, 2, +(1227678, 0, 1, 36245, 'Mammoth Chestpiece'), -- 162, 75, 2, +(1227678, 0, 1, 36246, 'Mammoth Fists'), -- 162, 75, 2, +(1227678, 0, 1, 36243, 'Mammoth Girdle'), -- 162, 75, 2, +(1227678, 0, 1, 36247, 'Mammoth Helm'), -- 162, 75, 2, +(1227678, 0, 1, 36248, 'Mammoth Legwraps'), -- 162, 75, 2, +(1227678, 0, 1, 36249, 'Mammoth Spaulders'), -- 162, 75, 2, +(1227678, 0, 1, 36635, 'Marvelous Crossbow'), -- 162, 75, 2, +(1227678, 0, 1, 36467, 'Reflecting Sphere'), -- 162, 75, 2, +(1227678, 0, 1, 36551, 'Ritual Greatstaff'), -- 162, 75, 2, +(1227678, 0, 1, 36439, 'Serpentine Chain'), -- 162, 75, 2, +(1227678, 0, 1, 36481, 'Trapper Knife'), -- 162, 75, 2, +(1227678, 0, 1, 36593, 'Troll Decollator'), -- 162, 75, 2, +(1227678, 0, 1, 36523, 'Trollish Slicer'), -- 162, 75, 2, +(1227678, 0, 1, 36649, 'Tundra Rifle'), -- 162, 75, 2, +(1227678, 0, 1, 36138, 'Wolverine Armguards'), -- 162, 75, 2, +(1227678, 0, 1, 36132, 'Wolverine Boots'), -- 162, 75, 2, +(1227678, 0, 1, 36135, 'Wolverine Cap'), -- 162, 75, 2, +(1227678, 0, 1, 36131, 'Wolverine Girdle'), -- 162, 75, 2, +(1227678, 0, 1, 36134, 'Wolverine Gloves'), -- 162, 75, 2, +(1227678, 0, 1, 36133, 'Wolverine Jerkin'), -- 162, 75, 2, +(1227678, 0, 1, 36136, 'Wolverine Leggings'), -- 162, 75, 2, +(1227678, 0, 1, 36137, 'Wolverine Shoulderguards'), -- 162, 75, 2, +-- 77-79 +(1227779, 0, 1, 36622, 'Acute Shortbow'), -- 166, 76, 2, +(1227779, 0, 1, 36636, 'Arbalest Crossbow'), -- 166, 76, 2, +(1227779, 0, 1, 36496, 'Brass-Bound Cudgel'), -- 166, 76, 2, +(1227779, 0, 1, 36664, 'Chilled Wand'), -- 166, 76, 2, +(1227779, 0, 1, 36580, 'Dire Axe'), -- 166, 76, 2, +(1227779, 0, 1, 36412, 'Fleece Cloak'), -- 166, 76, 2, +(1227779, 0, 1, 36720, 'Flying Knives'), -- 166, 76, 2, +(1227779, 0, 1, 36594, 'Fracturing Battleaxe'), -- 166, 76, 2, +(1227779, 0, 1, 36139, 'Ghrino Belt'), -- 166, 76, 2, +(1227779, 0, 1, 36140, 'Ghrino Boots'), -- 166, 76, 2, +(1227779, 0, 1, 36146, 'Ghrino Bracers'), -- 166, 76, 2, +(1227779, 0, 1, 36144, 'Ghrino Britches'), -- 166, 76, 2, +(1227779, 0, 1, 36143, 'Ghrino Cover'), -- 166, 76, 2, +(1227779, 0, 1, 36142, 'Ghrino Gloves'), -- 166, 76, 2, +(1227779, 0, 1, 36145, 'Ghrino Pauldrons'), -- 166, 76, 2, +(1227779, 0, 1, 36141, 'Ghrino Vest'), -- 166, 76, 2, +(1227779, 0, 1, 36566, 'Gilded Fangs'), -- 166, 76, 2, +(1227779, 0, 1, 36468, 'Glistening Star'), -- 166, 76, 2, +(1227779, 0, 1, 36440, 'Gold Clasped Chain'), -- 166, 76, 2, +(1227779, 0, 1, 36510, 'Lumbering Bludgeon'), -- 166, 76, 2, +(1227779, 0, 1, 36370, 'Magnataur Bracers'), -- 166, 76, 2, +(1227779, 0, 1, 36365, 'Magnataur Breastplate'), -- 166, 76, 2, +(1227779, 0, 1, 36366, 'Magnataur Gauntlets'), -- 166, 76, 2, +(1227779, 0, 1, 36363, 'Magnataur Girdle'), -- 166, 76, 2, +(1227779, 0, 1, 36367, 'Magnataur Helm'), -- 166, 76, 2, +(1227779, 0, 1, 36368, 'Magnataur Legplates'), -- 166, 76, 2, +(1227779, 0, 1, 36369, 'Magnataur Pauldrons'), -- 166, 76, 2, +(1227779, 0, 1, 36364, 'Magnataur Sabatons'), -- 166, 76, 2, +(1227779, 0, 1, 36650, 'Mammoth Gun'), -- 166, 76, 2, +(1227779, 0, 1, 36027, 'Oracle Belt'), -- 166, 76, 2, +(1227779, 0, 1, 36034, 'Oracle Bracelets'), -- 166, 76, 2, +(1227779, 0, 1, 36031, 'Oracle Circlet'), -- 166, 76, 2, +(1227779, 0, 1, 36030, 'Oracle Gloves'), -- 166, 76, 2, +(1227779, 0, 1, 36032, 'Oracle Leggings'), -- 166, 76, 2, +(1227779, 0, 1, 36033, 'Oracle Mantle'), -- 166, 76, 2, +(1227779, 0, 1, 36029, 'Oracle Robe'), -- 166, 76, 2, +(1227779, 0, 1, 36028, 'Oracle Slippers'), -- 166, 76, 2, +(1227779, 0, 1, 36482, 'Parrying Dagger'), -- 166, 76, 2, +(1227779, 0, 1, 36608, 'Piercing Glaive'), -- 166, 76, 2, +(1227779, 0, 1, 36524, 'Primitive Scimitar'), -- 166, 76, 2, +(1227779, 0, 1, 36692, 'Remedial Mace'), -- 166, 76, 2, +(1227779, 0, 1, 36678, 'Runed Talon'), -- 166, 76, 2, +(1227779, 0, 1, 36552, 'Spiked Greatstaff'), -- 166, 76, 2, +(1227779, 0, 1, 36426, 'Stirrup Ring'), -- 166, 76, 2, +(1227779, 0, 1, 36706, 'Tenacious Vine Staff'), -- 166, 76, 2, +(1227779, 0, 1, 36538, 'Trollish Destroyer'), -- 166, 76, 2, +(1227779, 0, 1, 36253, 'Wolvar Armor'), -- 166, 76, 2, +(1227779, 0, 1, 36251, 'Wolvar Belt'), -- 166, 76, 2, +(1227779, 0, 1, 36258, 'Wolvar Bindings'), -- 166, 76, 2, +(1227779, 0, 1, 36254, 'Wolvar Fists'), -- 166, 76, 2, +(1227779, 0, 1, 36252, 'Wolvar Greaves'), -- 166, 76, 2, +(1227779, 0, 1, 36255, 'Wolvar Helmet'), -- 166, 76, 2, +(1227779, 0, 1, 36256, 'Wolvar Legguards'), -- 166, 76, 2, +(1227779, 0, 1, 36257, 'Wolvar Shoulderguards'), -- 166, 76, 2, +-- 78-80 +(1227880, 0, 1, 36609, 'Abandoned Spear'), -- 170, 77, 2, +(1227880, 0, 1, 36497, 'Adamant Mallet'), -- 170, 77, 2, +(1227880, 0, 1, 36511, 'Arctic War Hammer'), -- 170, 77, 2, +(1227880, 0, 1, 36707, 'Cascading Water Staff'), -- 170, 77, 2, +(1227880, 0, 1, 36539, 'Chilled Warblade'), -- 170, 77, 2, +(1227880, 0, 1, 36035, 'Condor Belt'), -- 170, 77, 2, +(1227880, 0, 1, 36042, 'Condor Bindings'), -- 170, 77, 2, +(1227880, 0, 1, 36038, 'Condor Gloves'), -- 170, 77, 2, +(1227880, 0, 1, 36039, 'Condor Headpiece'), -- 170, 77, 2, +(1227880, 0, 1, 36040, 'Condor Pants'), -- 170, 77, 2, +(1227880, 0, 1, 36037, 'Condor Robe'), -- 170, 77, 2, +(1227880, 0, 1, 36036, 'Condor Sandals'), -- 170, 77, 2, +(1227880, 0, 1, 36041, 'Condor Shoulderpads'), -- 170, 77, 2, +(1227880, 0, 1, 36266, 'Cormorant Bracelets'), -- 170, 77, 2, +(1227880, 0, 1, 36261, 'Cormorant Chain Vest'), -- 170, 77, 2, +(1227880, 0, 1, 36260, 'Cormorant Footwraps'), -- 170, 77, 2, +(1227880, 0, 1, 36262, 'Cormorant Gloves'), -- 170, 77, 2, +(1227880, 0, 1, 36263, 'Cormorant Helm'), -- 170, 77, 2, +(1227880, 0, 1, 36264, 'Cormorant Leggings'), -- 170, 77, 2, +(1227880, 0, 1, 36265, 'Cormorant Mantle'), -- 170, 77, 2, +(1227880, 0, 1, 36259, 'Cormorant Waistband'), -- 170, 77, 2, +(1227880, 0, 1, 36525, 'Craggy Machete'), -- 170, 77, 2, +(1227880, 0, 1, 36553, 'Desecrated Staff'), -- 170, 77, 2, +(1227880, 0, 1, 36721, 'Dragon\'s Teeth'), -- 170, 77, 2, +(1227880, 0, 1, 36413, 'Dyed Taffeta Cape'), -- 170, 77, 2, +(1227880, 0, 1, 36427, 'Engraved Ring'), -- 170, 77, 2, +(1227880, 0, 1, 36623, 'Harnessed Longbow'), -- 170, 77, 2, +(1227880, 0, 1, 36637, 'Horrific Crossbow'), -- 170, 77, 2, +(1227880, 0, 1, 36373, 'Kraken Breastplate'), -- 170, 77, 2, +(1227880, 0, 1, 36377, 'Kraken Epaulets'), -- 170, 77, 2, +(1227880, 0, 1, 36374, 'Kraken Gauntlets'), -- 170, 77, 2, +(1227880, 0, 1, 36371, 'Kraken Girdle'), -- 170, 77, 2, +(1227880, 0, 1, 36372, 'Kraken Greaves'), -- 170, 77, 2, +(1227880, 0, 1, 36375, 'Kraken Helm'), -- 170, 77, 2, +(1227880, 0, 1, 36376, 'Kraken Legplates'), -- 170, 77, 2, +(1227880, 0, 1, 36378, 'Kraken Vambraces'), -- 170, 77, 2, +(1227880, 0, 1, 36469, 'Lidless Orb'), -- 170, 77, 2, +(1227880, 0, 1, 36483, 'Mandible Edge'), -- 170, 77, 2, +(1227880, 0, 1, 36651, 'Muzzled Musket'), -- 170, 77, 2, +(1227880, 0, 1, 36441, 'Pearl Woven Choker'), -- 170, 77, 2, +(1227880, 0, 1, 36595, 'Planate Broadaxe'), -- 170, 77, 2, +(1227880, 0, 1, 36455, 'Plated Bulwark'), -- 170, 77, 2, +(1227880, 0, 1, 36147, 'Pygmy Belt'), -- 170, 77, 2, +(1227880, 0, 1, 36154, 'Pygmy Bindings'), -- 170, 77, 2, +(1227880, 0, 1, 36148, 'Pygmy Boots'), -- 170, 77, 2, +(1227880, 0, 1, 36150, 'Pygmy Gloves'), -- 170, 77, 2, +(1227880, 0, 1, 36151, 'Pygmy Helmet'), -- 170, 77, 2, +(1227880, 0, 1, 36152, 'Pygmy Pants'), -- 170, 77, 2, +(1227880, 0, 1, 36153, 'Pygmy Shoulders'), -- 170, 77, 2, +(1227880, 0, 1, 36149, 'Pygmy Tunic'), -- 170, 77, 2, +(1227880, 0, 1, 36693, 'Serene Hammer'), -- 170, 77, 2, +(1227880, 0, 1, 36679, 'Singing Dagger'), -- 170, 77, 2, +(1227880, 0, 1, 36567, 'Six-Fingered Claws'), -- 170, 77, 2, +(1227880, 0, 1, 36665, 'Wasteland Wand'), -- 170, 77, 2, +(1227880, 0, 1, 36581, 'Wolvar Handaxe'), -- 170, 77, 2, +-- 79-81 +(1227981, 0, 1, 36694, 'Beatific Mace'), -- 174, 78, 2, +(1227981, 0, 1, 36638, 'Bloody Crossbow'), -- 174, 78, 2, +(1227981, 0, 1, 36428, 'Bouquet Ring'), -- 174, 78, 2, +(1227981, 0, 1, 36050, 'Crystalsong Bracelets'), -- 174, 78, 2, +(1227981, 0, 1, 36047, 'Crystalsong Crown'), -- 174, 78, 2, +(1227981, 0, 1, 36046, 'Crystalsong Gloves'), -- 174, 78, 2, +(1227981, 0, 1, 36048, 'Crystalsong Leggings'), -- 174, 78, 2, +(1227981, 0, 1, 36049, 'Crystalsong Mantle'), -- 174, 78, 2, +(1227981, 0, 1, 36045, 'Crystalsong Robe'), -- 174, 78, 2, +(1227981, 0, 1, 36043, 'Crystalsong Sash'), -- 174, 78, 2, +(1227981, 0, 1, 36044, 'Crystalsong Slippers'), -- 174, 78, 2, +(1227981, 0, 1, 36554, 'Cursed Staff'), -- 174, 78, 2, +(1227981, 0, 1, 36484, 'Etched Dagger'), -- 174, 78, 2, +(1227981, 0, 1, 36470, 'Gilded Scepter'), -- 174, 78, 2, +(1227981, 0, 1, 36381, 'Golem Breastplate'), -- 174, 78, 2, +(1227981, 0, 1, 36382, 'Golem Gauntlets'), -- 174, 78, 2, +(1227981, 0, 1, 36379, 'Golem Girdle'), -- 174, 78, 2, +(1227981, 0, 1, 36383, 'Golem Helmet'), -- 174, 78, 2, +(1227981, 0, 1, 36384, 'Golem Legplates'), -- 174, 78, 2, +(1227981, 0, 1, 36385, 'Golem Pauldrons'), -- 174, 78, 2, +(1227981, 0, 1, 36380, 'Golem Sabatons'), -- 174, 78, 2, +(1227981, 0, 1, 36386, 'Golem Vambraces'), -- 174, 78, 2, +(1227981, 0, 1, 36568, 'Hollowed Bone Knuckles'), -- 174, 78, 2, +(1227981, 0, 1, 36582, 'Ice Pick'), -- 174, 78, 2, +(1227981, 0, 1, 36456, 'Icy Kite Shield'), -- 174, 78, 2, +(1227981, 0, 1, 36414, 'Mammoth Fur Cloak'), -- 174, 78, 2, +(1227981, 0, 1, 36680, 'Mystic Fang'), -- 174, 78, 2, +(1227981, 0, 1, 36498, 'Nerubian Mace'), -- 174, 78, 2, +(1227981, 0, 1, 36512, 'Onerous Mallet'), -- 174, 78, 2, +(1227981, 0, 1, 36540, 'Petrified Sword'), -- 174, 78, 2, +(1227981, 0, 1, 36610, 'Plagued Pike'), -- 174, 78, 2, +(1227981, 0, 1, 36666, 'Polar Wand'), -- 174, 78, 2, +(1227981, 0, 1, 36722, 'Pyramid Throwing Star'), -- 174, 78, 2, +(1227981, 0, 1, 36596, 'Rupturing Axe'), -- 174, 78, 2, +(1227981, 0, 1, 36624, 'Shrieking Bow'), -- 174, 78, 2, +(1227981, 0, 1, 36442, 'Silken Cord Amulet'), -- 174, 78, 2, +(1227981, 0, 1, 36526, 'Sleeted Longsword'), -- 174, 78, 2, +(1227981, 0, 1, 36708, 'Snow Blossom Staff'), -- 174, 78, 2, +(1227981, 0, 1, 36652, 'Stocky Shotgun'), -- 174, 78, 2, +(1227981, 0, 1, 36274, 'Ulduar Bracers'), -- 174, 78, 2, +(1227981, 0, 1, 36269, 'Ulduar Breastplate'), -- 174, 78, 2, +(1227981, 0, 1, 36270, 'Ulduar Gauntlets'), -- 174, 78, 2, +(1227981, 0, 1, 36267, 'Ulduar Girdle'), -- 174, 78, 2, +(1227981, 0, 1, 36268, 'Ulduar Greaves'), -- 174, 78, 2, +(1227981, 0, 1, 36271, 'Ulduar Helm'), -- 174, 78, 2, +(1227981, 0, 1, 36272, 'Ulduar Legguards'), -- 174, 78, 2, +(1227981, 0, 1, 36273, 'Ulduar Shoulderguards'), -- 174, 78, 2, +(1227981, 0, 1, 36162, 'Wendigo Bands'), -- 174, 78, 2, +(1227981, 0, 1, 36156, 'Wendigo Boots'), -- 174, 78, 2, +(1227981, 0, 1, 36157, 'Wendigo Chestpiece'), -- 174, 78, 2, +(1227981, 0, 1, 36155, 'Wendigo Girdle'), -- 174, 78, 2, +(1227981, 0, 1, 36158, 'Wendigo Gloves'), -- 174, 78, 2, +(1227981, 0, 1, 36159, 'Wendigo Hood'), -- 174, 78, 2, +(1227981, 0, 1, 36160, 'Wendigo Legguards'), -- 174, 78, 2, +(1227981, 0, 1, 36161, 'Wendigo Pauldrons'), -- 174, 78, 2, +-- 80-82 +(1228082, 0, 1, 36527, 'Blackened Blade'), -- 178, 79, 2, +(1228082, 0, 1, 36611, 'Bleak Scythe'), -- 178, 79, 2, +(1228082, 0, 1, 36639, 'Brutal Ballista'), -- 178, 79, 2, +(1228082, 0, 1, 36723, 'Clawed Shuriken'), -- 178, 79, 2, +(1228082, 0, 1, 36709, 'Crystal Woodstaff'), -- 178, 79, 2, +(1228082, 0, 1, 36695, 'Dogmatic Scepter'), -- 178, 79, 2, +(1228082, 0, 1, 36499, 'Frigid War-Mace'), -- 178, 79, 2, +(1228082, 0, 1, 36471, 'Ice Crystal'), -- 178, 79, 2, +(1228082, 0, 1, 36597, 'Ice-Splintering Axe'), -- 178, 79, 2, +(1228082, 0, 1, 36457, 'Ivory Shield'), -- 178, 79, 2, +(1228082, 0, 1, 36513, 'Lode-Headed Hammer'), -- 178, 79, 2, +(1228082, 0, 1, 36625, 'Massive Recurved Bow'), -- 178, 79, 2, +(1228082, 0, 1, 36555, 'Minion Staff'), -- 178, 79, 2, +(1228082, 0, 1, 36443, 'Platinum Medallion'), -- 178, 79, 2, +(1228082, 0, 1, 36653, 'Precipice Longrifle'), -- 178, 79, 2, +(1228082, 0, 1, 36389, 'Revenant Armor'), -- 178, 79, 2, +(1228082, 0, 1, 36387, 'Revenant Belt'), -- 178, 79, 2, +(1228082, 0, 1, 36394, 'Revenant Bracers'), -- 178, 79, 2, +(1228082, 0, 1, 36393, 'Revenant Epaulets'), -- 178, 79, 2, +(1228082, 0, 1, 36390, 'Revenant Gauntlets'), -- 178, 79, 2, +(1228082, 0, 1, 36388, 'Revenant Greaves'), -- 178, 79, 2, +(1228082, 0, 1, 36391, 'Revenant Helmet'), -- 178, 79, 2, +(1228082, 0, 1, 36392, 'Revenant Legguards'), -- 178, 79, 2, +(1228082, 0, 1, 36569, 'Savage Talons'), -- 178, 79, 2, +(1228082, 0, 1, 36485, 'Sinuous Keris'), -- 178, 79, 2, +(1228082, 0, 1, 36583, 'Skeletal Hacker'), -- 178, 79, 2, +(1228082, 0, 1, 36667, 'Solid Ice Wand'), -- 178, 79, 2, +(1228082, 0, 1, 36275, 'Spiderlord Belt'), -- 178, 79, 2, +(1228082, 0, 1, 36276, 'Spiderlord Boots'), -- 178, 79, 2, +(1228082, 0, 1, 36282, 'Spiderlord Bracers'), -- 178, 79, 2, +(1228082, 0, 1, 36277, 'Spiderlord Chestpiece'), -- 178, 79, 2, +(1228082, 0, 1, 36278, 'Spiderlord Gauntlets'), -- 178, 79, 2, +(1228082, 0, 1, 36279, 'Spiderlord Helm'), -- 178, 79, 2, +(1228082, 0, 1, 36280, 'Spiderlord Legguards'), -- 178, 79, 2, +(1228082, 0, 1, 36281, 'Spiderlord Spaulders'), -- 178, 79, 2, +(1228082, 0, 1, 36429, 'Spur Ring'), -- 178, 79, 2, +(1228082, 0, 1, 36415, 'Vintage Satin Cloak'), -- 178, 79, 2, +(1228082, 0, 1, 36058, 'Vizier Bracelets'), -- 178, 79, 2, +(1228082, 0, 1, 36054, 'Vizier Gloves'), -- 178, 79, 2, +(1228082, 0, 1, 36055, 'Vizier Hood'), -- 178, 79, 2, +(1228082, 0, 1, 36056, 'Vizier Leggings'), -- 178, 79, 2, +(1228082, 0, 1, 36057, 'Vizier Mantle'), -- 178, 79, 2, +(1228082, 0, 1, 36053, 'Vizier Robe'), -- 178, 79, 2, +(1228082, 0, 1, 36051, 'Vizier Sash'), -- 178, 79, 2, +(1228082, 0, 1, 36052, 'Vizier Slippers'), -- 178, 79, 2, +(1228082, 0, 1, 36170, 'Webspinner Bindings'), -- 178, 79, 2, +(1228082, 0, 1, 36164, 'Webspinner Boots'), -- 178, 79, 2, +(1228082, 0, 1, 36163, 'Webspinner Cord'), -- 178, 79, 2, +(1228082, 0, 1, 36166, 'Webspinner Gloves'), -- 178, 79, 2, +(1228082, 0, 1, 36167, 'Webspinner Hood'), -- 178, 79, 2, +(1228082, 0, 1, 36168, 'Webspinner Leggings'), -- 178, 79, 2, +(1228082, 0, 1, 36169, 'Webspinner Shoulderguards'), -- 178, 79, 2, +(1228082, 0, 1, 36165, 'Webspinner Vest'), -- 178, 79, 2, +(1228082, 0, 1, 36541, 'Wintry Claymore'), -- 178, 79, 2, +(1228082, 0, 1, 36681, 'Wisdom Carver'), -- 178, 79, 2, +-- 81-83 +(1228183, 0, 1, 36556, 'Apocalyptic Staff'), -- 182, 80, 2, +(1228183, 0, 1, 36710, 'Avalanche Staff'), -- 182, 80, 2, +(1228183, 0, 1, 36472, 'Carved Rod'), -- 182, 80, 2, +(1228183, 0, 1, 36066, 'Coldwraith Bindings'), -- 182, 80, 2, +(1228183, 0, 1, 36060, 'Coldwraith Boots'), -- 182, 80, 2, +(1228183, 0, 1, 36063, 'Coldwraith Cowl'), -- 182, 80, 2, +(1228183, 0, 1, 36062, 'Coldwraith Handwraps'), -- 182, 80, 2, +(1228183, 0, 1, 36065, 'Coldwraith Mantle'), -- 182, 80, 2, +(1228183, 0, 1, 36064, 'Coldwraith Pants'), -- 182, 80, 2, +(1228183, 0, 1, 36061, 'Coldwraith Robe'), -- 182, 80, 2, +(1228183, 0, 1, 36059, 'Coldwraith Sash'), -- 182, 80, 2, +(1228183, 0, 1, 36570, 'Corrupted Scythes'), -- 182, 80, 2, +(1228183, 0, 1, 36458, 'Frozen Shield'), -- 182, 80, 2, +(1228183, 0, 1, 36724, 'Frozen Throwing Blades'), -- 182, 80, 2, +(1228183, 0, 1, 36500, 'Gargoyle\'s Mace'), -- 182, 80, 2, +(1228183, 0, 1, 36171, 'Geist Belt'), -- 182, 80, 2, +(1228183, 0, 1, 36172, 'Geist Boots'), -- 182, 80, 2, +(1228183, 0, 1, 36174, 'Geist Gloves'), -- 182, 80, 2, +(1228183, 0, 1, 36175, 'Geist Hood'), -- 182, 80, 2, +(1228183, 0, 1, 36176, 'Geist Legguards'), -- 182, 80, 2, +(1228183, 0, 1, 36177, 'Geist Shoulders'), -- 182, 80, 2, +(1228183, 0, 1, 36173, 'Geist Tunic'), -- 182, 80, 2, +(1228183, 0, 1, 36178, 'Geist Wristguards'), -- 182, 80, 2, +(1228183, 0, 1, 36696, 'Graced Scepter'), -- 182, 80, 2, +(1228183, 0, 1, 36654, 'Harsh-Winter Rifle'), -- 182, 80, 2, +(1228183, 0, 1, 36444, 'Ice Encrusted Amulet'), -- 182, 80, 2, +(1228183, 0, 1, 36542, 'Invasion Blade'), -- 182, 80, 2, +(1228183, 0, 1, 36514, 'Kingly Battlehammer'), -- 182, 80, 2, +(1228183, 0, 1, 36626, 'Military Compound Bow'), -- 182, 80, 2, +(1228183, 0, 1, 36668, 'Mindless Wand'), -- 182, 80, 2, +(1228183, 0, 1, 36397, 'Necropolis Breastplate'), -- 182, 80, 2, +(1228183, 0, 1, 36401, 'Necropolis Epaulets'), -- 182, 80, 2, +(1228183, 0, 1, 36395, 'Necropolis Girdle'), -- 182, 80, 2, +(1228183, 0, 1, 36398, 'Necropolis Gloves'), -- 182, 80, 2, +(1228183, 0, 1, 36399, 'Necropolis Helm'), -- 182, 80, 2, +(1228183, 0, 1, 36400, 'Necropolis Legplates'), -- 182, 80, 2, +(1228183, 0, 1, 36396, 'Necropolis Sabatons'), -- 182, 80, 2, +(1228183, 0, 1, 36402, 'Necropolis Vambraces'), -- 182, 80, 2, +(1228183, 0, 1, 36486, 'Ornate Pugio'), -- 182, 80, 2, +(1228183, 0, 1, 36430, 'Puzzle Ring'), -- 182, 80, 2, +(1228183, 0, 1, 36416, 'Regal Cloak'), -- 182, 80, 2, +(1228183, 0, 1, 36598, 'Scarlet Battle Axe'), -- 182, 80, 2, +(1228183, 0, 1, 36640, 'Scourge Crossbow'), -- 182, 80, 2, +(1228183, 0, 1, 36612, 'Scourge War Spear'), -- 182, 80, 2, +(1228183, 0, 1, 36682, 'Seduced Blade'), -- 182, 80, 2, +(1228183, 0, 1, 36528, 'Skeleton\'s Sword'), -- 182, 80, 2, +(1228183, 0, 1, 36584, 'Snowy Edge'), -- 182, 80, 2, +(1228183, 0, 1, 36285, 'Spectral Armor'), -- 182, 80, 2, +(1228183, 0, 1, 36290, 'Spectral Bracelets'), -- 182, 80, 2, +(1228183, 0, 1, 36286, 'Spectral Gauntlets'), -- 182, 80, 2, +(1228183, 0, 1, 36284, 'Spectral Greaves'), -- 182, 80, 2, +(1228183, 0, 1, 36287, 'Spectral Helmet'), -- 182, 80, 2, +(1228183, 0, 1, 36288, 'Spectral Legwraps'), -- 182, 80, 2, +(1228183, 0, 1, 36289, 'Spectral Mantle'), -- 182, 80, 2, +(1228183, 0, 1, 36283, 'Spectral Waistband'), -- 182, 80, 2, +-- Rares +-- 68-71 +(1236871, 0, 1, 37747, 'Beneficent Bulwark'), -- 130, 69, 3, +(1236871, 0, 1, 37745, 'Greenhealer\'s Garb'), -- 130, 69, 3, +(1236871, 0, 1, 37746, 'Helm of the Burning Soul'), -- 130, 69, 3, +(1236871, 0, 1, 37744, 'Horrorblood Treads'), -- 130, 69, 3, +(1236871, 0, 1, 37743, 'Legguards of Brutalization'), -- 130, 69, 3, +(1236871, 0, 1, 37748, 'Winterfall\'s Frozen Necklace'), -- 130, 69, 3, +(1236871, 0, 1, 37782, 'Gauntlets of the Cheerful Hearth'), -- 134, 70, 3, +(1236871, 0, 1, 37762, 'Many-Pocketed Belt'), -- 134, 70, 3, +(1236871, 0, 1, 37752, 'Sandals of Broken Dreams'), -- 134, 70, 3, +(1236871, 0, 1, 37749, 'Shocking Claws'), -- 134, 70, 3, +(1236871, 0, 1, 37751, 'Tooga\'s Lost Toenail'), -- 134, 70, 3, +(1236871, 0, 1, 37772, 'Wub\'s Electrospike Spaulders'), -- 134, 70, 3, +-- 70-72 +(1237072, 0, 1, 37783, 'Blood-Tempered Spaulders'), -- 138, 71, 3, +(1237072, 0, 1, 37803, 'Lola\'s Lifegiving Branch'), -- 138, 71, 3, +(1237072, 0, 1, 37753, 'Mendicant\'s Robe of Mendacity'), -- 138, 71, 3, +(1237072, 0, 1, 37819, 'Milan\'s Mastercraft Band'), -- 138, 71, 3, +(1237072, 0, 1, 37773, 'Shock-Inducing Girdle'), -- 138, 71, 3, +(1237072, 0, 1, 37763, 'Treads of the Purifier'), -- 138, 71, 3, +-- 71-73 +(1237173, 0, 1, 37764, 'Corehound Fang Shoulderpads'), -- 142, 72, 3, +(1237173, 0, 1, 37796, 'Earthbound Cape'), -- 142, 72, 3, +(1237173, 0, 1, 37795, 'Grips of the Valiant Champion'), -- 142, 72, 3, +(1237173, 0, 1, 37774, 'Leggings of Aqueous Dissolution'), -- 142, 72, 3, +(1237173, 0, 1, 37754, 'Shimmersteel Hood'), -- 142, 72, 3, +(1237173, 0, 1, 37820, 'Worgen\'s Ring of Revitalization'), -- 142, 72, 3, +-- 72-74 +(1237274, 0, 1, 37817, 'Branch of Sinful Reprieve'), -- 146, 73, 3, +(1237274, 0, 1, 37811, 'Captain Carver\'s Persuader'), -- 146, 73, 3, +(1237274, 0, 1, 37802, 'Elanor\'s Edge'), -- 146, 73, 3, +(1237274, 0, 1, 37785, 'Girdle of the Howling Berserker'), -- 146, 73, 3, +(1237274, 0, 1, 37775, 'Helm of the Broken Ram'), -- 146, 73, 3, +(1237274, 0, 1, 37755, 'Leggings of the Icy Heart'), -- 146, 73, 3, +-- 73-75 +(1237375, 0, 1, 37776, 'Bracers of Accurate Fire'), -- 150, 74, 3, +(1237375, 0, 1, 37765, 'Leggings of the Water Moccasin'), -- 150, 74, 3, +(1237375, 0, 1, 37786, 'Legguards of the Forlorn Seas'), -- 150, 74, 3, +(1237375, 0, 1, 37807, 'Lydia\'s Sharpened Swordbreaker'), -- 150, 74, 3, +(1237375, 0, 1, 37821, 'Raine\'s Signet of Blasting'), -- 150, 74, 3, +(1237375, 0, 1, 37756, 'Zoe\'s Comforting Cape'), -- 150, 74, 3, +-- 74-76 +(1237476, 0, 1, 37813, 'Banner Slicer'), -- 154, 75, 3, +(1237476, 0, 1, 37777, 'Bracers of Sizzling Heat'), -- 154, 75, 3, +(1237476, 0, 1, 37766, 'Bracers of Unmitigated Larceny'), -- 154, 75, 3, +(1237476, 0, 1, 37757, 'Charlotte\'s Chastizing Pauldrons'), -- 154, 75, 3, +(1237476, 0, 1, 37787, 'Greathelm of the Unyielding Bull'), -- 154, 75, 3, +(1237476, 0, 1, 37805, 'Melia\'s Magnificent Scepter'), -- 154, 75, 3, +-- 75-77 +(1237577, 0, 1, 37810, 'Blade-Binding Bulwark'), -- 158, 76, 3, +(1237577, 0, 1, 37804, 'Bloodwood Greatstaff'), -- 158, 76, 3, +(1237577, 0, 1, 37789, 'Gauntlets of Disembowelment'), -- 158, 76, 3, +(1237577, 0, 1, 37778, 'Girdle of Unerring Flight'), -- 158, 76, 3, +(1237577, 0, 1, 37812, 'Petrified Ironwood Smasher'), -- 158, 76, 3, +(1237577, 0, 1, 37758, 'Raine\'s Choker of Combustion'), -- 158, 76, 3, +(1237577, 0, 1, 37767, 'Ryft\'s Deathgaze'), -- 158, 76, 3, +-- 76-78 +(1237678, 0, 1, 37790, 'Belt of Crystalline Tears'), -- 162, 77, 3, +(1237678, 0, 1, 37808, 'Dragonjaw Mauler'), -- 162, 77, 3, +(1237678, 0, 1, 37768, 'Leggings of Violent Exsanguination'), -- 162, 77, 3, +(1237678, 0, 1, 37759, 'Rhie-ay\'s Clutching Gauntlets'), -- 162, 77, 3, +(1237678, 0, 1, 37809, 'Roc-Feather Longbow'), -- 162, 77, 3, +(1237678, 0, 1, 37806, 'Zabra\'s Misplaced Staff'), -- 162, 77, 3, +-- 77-79 +(1237779, 0, 1, 37792, 'Agin\'s Crushing Carapace'), -- 166, 77, 3, +(1237779, 0, 1, 37797, 'Cloak of the Agile Mind'), -- 166, 77, 3, +(1237779, 0, 1, 37823, 'Draconic Choker of Ferocity'), -- 166, 77, 3, +(1237779, 0, 1, 37769, 'Gnarled Shovelhorn Spaulders'), -- 166, 77, 3, +(1237779, 0, 1, 37779, 'Nixod\'s Chain-Threshed Spaulders'), -- 166, 77, 3, +-- 79-81 +(1237981, 0, 1, 37770, 'Bulge-Concealing Breastplate'), -- 170, 77, 3, +(1237981, 0, 1, 37780, 'Condor-Bone Chestguard'), -- 170, 77, 3, +(1237981, 0, 1, 37760, 'Cracklefire Wristguards'), -- 170, 77, 3, +(1237981, 0, 1, 37793, 'Skullcage of Eternal Terror'), -- 170, 77, 3, +(1237981, 0, 1, 37822, 'Twisted Puzzle-Ring'), -- 170, 77, 3, +-- 80-83 +(1238083, 0, 1, 37781, 'Grips of the Warming Heart'), -- 174, 78, 3, +(1238083, 0, 1, 37824, 'Gwyneth\'s Runed Dragonwand'), -- 174, 78, 3, +(1238083, 0, 1, 37761, 'Shimmerthread Girdle'), -- 174, 78, 3, +(1238083, 0, 1, 37794, 'Torta\'s Oversized Choker'), -- 174, 78, 3, +(1238083, 0, 1, 37771, 'Wristguards of Verdant Recovery'), -- 174, 78, 3, +-- Epics +-- 80+ +(1248083, 0, 1, 44311, 'Avool\'s Sword of Jin'), -- 200, 80, 4, +(1248083, 0, 1, 37835, 'Je\'Tze\'s Bell'), -- 200, 80, 4, +(1248083, 0, 1, 44308, 'Signet of Edward the Odd'), -- 200, 80, 4, +(1248083, 0, 1, 44309, 'Sash of Jordan'), -- 200, 80, 4, +(1248083, 0, 1, 44310, 'Namlak\'s Supernumerary Sticker'), -- 200, 80, 4, +(1248083, 0, 1, 43573, 'Tears of Bitter Anguish'), -- 200, 80, 4, +(1248083, 0, 1, 37254, 'Super Simian Sphere'), -- 200, 80, 4, +(1248083, 0, 1, 44313, 'Zom\'s Crackling Bulwark'), -- 200, 80, 4, +(1248083, 0, 1, 44312, 'Wapach\'s Spaulders of Solidarity'), -- 200, 80, 4, +-- Potions (3%) +-- 68-75 +(1256875, 67, 1, 22829, 'Super Healing Potion'), -- 80, 70, 1, +(1256875, 33, 1, 22832, 'Super Mana Potion'), -- 80, 70, 1, +-- 76-83 +(1257683, 67, 1, 33447, 'Runic Healing Potion'), -- 80, 70, 1, +(1257683, 33, 1, 33448, 'Runic Mana Potion'), -- 80, 70, 1, +-- Scrolls (1%) +(1256883, 0, 1, 43463, 'Scroll of Agility VII'), -- 80, 70, 1, +(1256883, 0, 1, 37091, 'Scroll of Intellect VII'), -- 80, 70, 1, +(1256883, 0, 1, 43467, 'Scroll of Protection VII'), -- 80, 70, 1, +(1256883, 0, 1, 37097, 'Scroll of Spirit VII'), -- 80, 70, 1, +(1256883, 0, 1, 37093, 'Scroll of Stamina VII'), -- 80, 70, 1, +(1256883, 0, 1, 43465, 'Scroll of Strength VII'); -- 80, 70, 1, + +DELETE FROM `reference_loot_template` WHERE `Entry` IN (1266870,1267174,1267579,1268083,1260001,1260002,1260003); +INSERT INTO `reference_loot_template` (`Entry`, `Reference`, `Chance`, `GroupId`, `Item`, `Comment`) VALUES +-- Professions +-- 68-70 +(1266870, 1260001, 2, 1, 1, 'Cooking Recipes'), +(1266870, 0, 0.1, 7, 31952, 'Khorium Lockbox'), +(1266870, 0, 1, 8, 43876, 'A Guide to Northern Cloth Scavenging'), +-- 71-74 +(1267174, 1260001, 2, 1, 1, 'Cooking Recipes'), +(1267174, 0, 0.1, 7, 43622, 'Froststeel Lockbox'), +(1267174, 0, 1, 8, 43876, 'A Guide to Northern Cloth Scavenging'), +-- 75+ +(1267579, 1260001, 2, 1, 1, 'Cooking Recipes'), +(1267579, 1260002, 0.5, 2, 2, 'Tailoring Patterns'), +(1267579, 0, 0.1, 3, 43297, 'Damaged Necklace'), -- 80, 77, 2, +(1267579, 0, 2, 4, 39152, 'Manual: Heavy Frostweave Bandage'), -- 80, 0, 2, +(1267579, 1260003, 0.2, 5, 3, 'Jewelcrafting Designs'), +(1267579, 0, 0.1, 7, 43624, 'Titanium Lockbox'), -- 80, 0, 3, +(1267579, 0, 1, 8, 43876, 'A Guide to Northern Cloth Scavenging'), +-- 80+ +(1268083, 1260001, 2, 1, 1, 'Cooking Recipes'), +(1268083, 1260002, 0.5, 2, 2, 'Tailoring Patterns'), +(1268083, 0, 0.1, 3, 43297, 'Damaged Necklace'), -- 80, 77, 2, +(1268083, 0, 2, 4, 39152, 'Manual: Heavy Frostweave Bandage'), -- 80, 0, 2, +(1268083, 1260003, 0.2, 5, 3, 'Jewelcrafting Designs'), +(1268083, 0, 0.1, 6, 45912, 'Book of Glyph Mastery'), -- 80, 0, 2 +(1268083, 0, 0.1, 7, 43624, 'Titanium Lockbox'), -- 80, 0, 3, +(1268083, 0, 1, 8, 43876, 'A Guide to Northern Cloth Scavenging'), +-- Cooking Recipes +(1260001, 0, 0, 1, 43509, 'Recipe: Bad Clams'), -- 75, 0, 2, +(1260001, 0, 0, 1, 43510, 'Recipe: Haunted Herring'), -- 75, 0, 2, +(1260001, 0, 0, 1, 43508, 'Recipe: Last Week\'s Mammoth'), -- 75, 0, 2, +(1260001, 0, 0, 1, 43507, 'Recipe: Tasty Cupcake'), -- 75, 0, 2, +-- Tailoring Patterns +(1260002, 0, 0, 2, 42173, 'Pattern: Blue Lumberjack Shirt'), -- 72, 0, 2, +(1260002, 0, 0, 2, 42176, 'Pattern: Blue Workman\'s Shirt'), -- 72, 0, 2, +(1260002, 0, 0, 2, 42175, 'Pattern: Green Lumberjack Shirt'), -- 72, 0, 2, +(1260002, 0, 0, 2, 42172, 'Pattern: Red Lumberjack Shirt'), -- 72, 0, 2, +(1260002, 0, 0, 2, 42177, 'Pattern: Red Workman\'s Shirt'), -- 72, 0, 2, +(1260002, 0, 0, 2, 42178, 'Pattern: Rustic Workman\'s Shirt'), -- 72, 0, 2, +-- Jewelcrafting Designs +(1260003, 0, 0, 5, 41788, 'Design: Beaming Earthsiege Diamond'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41780, 'Design: Champion\'s Monarch Topaz'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41786, 'Design: Destructive Skyflare Diamond'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41777, 'Design: Etched Monarch Topaz'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41789, 'Design: Inscribed Monarch Topaz'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41781, 'Design: Misty Forest Emerald'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41783, 'Design: Purified Twilight Opal'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41778, 'Design: Resolute Monarch Topaz'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41782, 'Design: Shining Forest Emerald'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41784, 'Design: Sovereign Twilight Opal'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41779, 'Design: Stalwart Monarch Topaz'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41785, 'Design: Tenuous Twilight Opal'), -- 80, 0, 3, +(1260003, 0, 0, 5, 41787, 'Design: Thundering Skyflare Diamond'); -- 80, 0, 3, + +DELETE FROM `reference_loot_template` WHERE (`Entry` IN (1270000, 1270001, 1270002)); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +-- Normal +(1270001, 33470, 0, 100, 0, 1, 0, 1, 1, 'Frostweave Cloth'), +(1270001, 1, 1270000, 50, 0, 1, 0, 1, 1, 'Tailoring Bonus Cloth'), +-- Elite +(1270002, 33470, 0, 100, 0, 1, 0, 2, 4, 'Frostweave Cloth'), +(1270002, 1, 1270000, 50, 0, 1, 0, 1, 1, 'Tailoring Bonus Cloth'), +-- Tailoring Bonus +(1270000, 33470, 0, 100, 0, 1, 0, 1, 3, 'Bonus Frostweave Cloth'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 10 AND `SourceGroup` IN (1270000, 1267174, 1266870, 1267579, 1268083, 1260001, 1260002, 1260003); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(10, 1270000, 33470, 0, 0, 1, 0, 59390, 0, 0, 0, 0, 0, '', 'Player must know Northern Cloth Scavenging (59390) to loot bonus cloth'), +(10, 1266870, 43876, 0, 0, 1, 0, 59390, 0, 0, 1, 0, 0, '', 'Player must not know Northern Cloth Scavenging (59390) to loot A Guide to Northern Cloth Scavenging'), +(10, 1267174, 43876, 0, 0, 1, 0, 59390, 0, 0, 1, 0, 0, '', 'Player must not know Northern Cloth Scavenging (59390) to loot A Guide to Northern Cloth Scavenging'), +(10, 1267579, 43876, 0, 0, 1, 0, 59390, 0, 0, 1, 0, 0, '', 'Player must not know Northern Cloth Scavenging (59390) to loot A Guide to Northern Cloth Scavenging'), +(10, 1268083, 43876, 0, 0, 1, 0, 59390, 0, 0, 1, 0, 0, '', 'Player must not know Northern Cloth Scavenging (59390) to loot A Guide to Northern Cloth Scavenging'), + +(10, 1260001, 43507, 0, 0, 7, 0, 185, 1, 0, 0, 0, 0, '', 'Player must have Cooking Skill to loot recipe'), +(10, 1260001, 43508, 0, 0, 7, 0, 185, 1, 0, 0, 0, 0, '', 'Player must have Cooking Skill to loot recipe'), +(10, 1260001, 43509, 0, 0, 7, 0, 185, 1, 0, 0, 0, 0, '', 'Player must have Cooking Skill to loot recipe'), +(10, 1260001, 43510, 0, 0, 7, 0, 185, 1, 0, 0, 0, 0, '', 'Player must have Cooking Skill to loot recipe'), +(10, 1260001, 43507, 0, 0, 25, 0, 58512, 0, 0, 1, 0, 0, '', 'Player must not know cooking recipe already'), +(10, 1260001, 43508, 0, 0, 25, 0, 58521, 0, 0, 1, 0, 0, '', 'Player must not know cooking recipe already'), +(10, 1260001, 43509, 0, 0, 25, 0, 58523, 0, 0, 1, 0, 0, '', 'Player must not know cooking recipe already'), +(10, 1260001, 43510, 0, 0, 25, 0, 58525, 0, 0, 1, 0, 0, '', 'Player must not know cooking recipe already'), + +(10, 1267579, 39152, 0, 0, 7, 0, 129, 390, 0, 0, 0, 0, '', 'Player must have First Aid Skill (390) to loot recipe'), +(10, 1267579, 39152, 0, 0, 25, 0, 45546, 0, 0, 1, 0, 0, '', 'Player must not know Heavy Frostweave Bandage recipe already'), +(10, 1268083, 39152, 0, 0, 7, 0, 129, 390, 0, 0, 0, 0, '', 'Player must have First Aid Skill (390) to loot recipe'), +(10, 1268083, 39152, 0, 0, 25, 0, 45546, 0, 0, 1, 0, 0, '', 'Player must not know Heavy Frostweave Bandage recipe already'), + +(10, 1260002, 42172, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring Skill to loot pattern'), +(10, 1260002, 42173, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring Skill to loot pattern'), +(10, 1260002, 42175, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring Skill to loot pattern'), +(10, 1260002, 42176, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring Skill to loot pattern'), +(10, 1260002, 42177, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring Skill to loot pattern'), +(10, 1260002, 42178, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring Skill to loot pattern'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` IN (1200068, 1200168, 1200069, 1200169, 1200070, 1200170, 1200071, 1200171, 1200072, 1200172, 1200073, 1200173, 1200074, 1200174, 1200075, 1200175, 1200076, 1200176, 1200077, 1200177, 1200078, 1200178, 1200079, 1200179, 1200080, 1200180, 1200081, 1200181, 1200082, 1200182, 1200268, 1200368, 1200269, 1200369, 1200270, 1200370, 1200271, 1200371, 1200272, 1200372, 1200273, 1200373, 1200274, 1200374, 1200275, 1200375, 1200276, 1200376, 1200277, 1200377, 1200278, 1200378, 1200279, 1200379, 1200280, 1200380, 1200281, 1200381, 1200282, 1200382)); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +-- Packages +-- Humanoids, Undead: +Potions, +Scrolls, +Cloth +-- 1 + [Exp] + 00 + [Counter] + [Level] +-- 0: No Scrolls/Cloth/Potions, Normal +-- 1: With, Normal +-- 2: No Scrolls/Cloth/Potions, Elite +-- 3: With, Elite +-- e.g. 1200068, Level 68 Beast +-- For simplicity sake, we will be rewarding the highest level loot available. +-- 68-68 +(1200068, 1, 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200068, 2, 1226870, 2, 0, 1, 0, 1, 1, 'WotLK Greens 68-70 Level Range'), +(1200068, 3, 1236871, 0.1, 0, 1, 0, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200068, 4, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), + +(1200168, 1, 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200168, 2, 1226870, 2, 0, 1, 0, 1, 1, 'WotLK Greens 68-70 Level Range'), +(1200168, 3, 1236871, 0.1, 0, 1, 0, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200168, 4, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), +(1200168, 5, 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200168, 6, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200069, 1, 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200069, 2, 1226870, 1, 0, 1, 1, 1, 1, 'WotLK Greens 68-70 Level Range'), +(1200069, 3, 1226971, 1, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +(1200069, 4, 1236871, 0.1, 0, 1, 0, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200069, 5, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), + +(1200169, 1, 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200169, 2, 1226870, 1, 0, 1, 1, 1, 1, 'WotLK Greens 68-70 Level Range'), +(1200169, 3, 1226971, 1, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +(1200169, 4, 1236871, 0.1, 0, 1, 0, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200169, 5, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), +(1200169, 6, 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200169, 7, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200070, 1, 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200070, 2, 1226870, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 68-70 Level Range'), +(1200070, 3, 1226971, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +(1200070, 4, 1227072, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200070, 5, 1236871, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200070, 6, 1237072, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200070, 7, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), + +(1200170, 1, 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200170, 2, 1226870, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 68-70 Level Range'), +(1200170, 3, 1226971, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +(1200170, 4, 1227072, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200170, 5, 1236871, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200170, 6, 1237072, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200170, 7, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), +(1200170, 8, 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200170, 9, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200071, 1, 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200071, 2, 1226971, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +(1200071, 3, 1227072, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200071, 4, 1227173, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200071, 5, 1236871, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200071, 6, 1237072, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200071, 7, 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200071, 8, 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), + +(1200171, 1 , 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200171, 2 , 1226971, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +(1200171, 3 , 1227072, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200171, 4 , 1227173, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200171, 5 , 1236871, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200171, 6 , 1237072, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200171, 7 , 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200171, 8 , 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), +(1200171, 9 , 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200171, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200072, 1, 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200072, 2, 1227072, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200072, 3, 1227173, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200072, 4, 1227274, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200072, 5, 1237072, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200072, 6, 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200072, 7, 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200072, 8, 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), + +(1200172, 1 , 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200172, 2 , 1227072, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200172, 3 , 1227173, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200172, 4 , 1227274, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200172, 5 , 1237072, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200172, 6 , 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200172, 7 , 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200172, 8 , 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), +(1200172, 9 , 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200172, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200073, 1, 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200073, 2, 1227173, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200073, 3, 1227274, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200073, 4, 1227375, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200073, 5, 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200073, 6, 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200073, 7, 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200073, 8, 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), + +(1200173, 1 , 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200173, 2 , 1227173, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200173, 3 , 1227274, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200173, 4 , 1227375, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200173, 5 , 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200173, 6 , 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200173, 7 , 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200173, 8 , 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), +(1200173, 9 , 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200173, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200074, 1, 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200074, 2, 1227274, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200074, 3, 1227375, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200074, 4, 1227476, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200074, 5, 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200074, 6, 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200074, 7, 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200074, 8, 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), + +(1200174, 1 , 1206874, 5, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200174, 2 , 1227274, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200174, 3 , 1227375, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200174, 4 , 1227476, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200174, 5 , 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200174, 6 , 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200174, 7 , 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200174, 8 , 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), +(1200174, 9 , 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200174, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200075, 1, 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200075, 2, 1227375, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200075, 3, 1227476, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200075, 4, 1227577, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200075, 5, 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200075, 6, 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200075, 7, 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200075, 8, 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), + +(1200175, 1 , 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200175, 2 , 1227375, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200175, 3 , 1227476, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200175, 4 , 1227577, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200175, 5 , 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200175, 6 , 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200175, 7 , 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200175, 8 , 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), +(1200175, 9 , 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200175, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200076, 1, 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200076, 2, 1227476, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200076, 3, 1227577, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200076, 4, 1227678, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200076, 5, 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200076, 6, 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200076, 7, 1237678, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200076, 8, 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), + +(1200176, 1 , 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200176, 2 , 1227476, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200176, 3 , 1227577, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200176, 4 , 1227678, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200176, 5 , 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200176, 6 , 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200176, 7 , 1237678, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200176, 8 , 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), +(1200176, 9 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200176, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200077, 1, 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200077, 2, 1227577, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200077, 3, 1227678, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200077, 4, 1227779, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200077, 5, 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200077, 6, 1237678, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200077, 7, 1237779, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 77-79 Level Range'), +(1200077, 8, 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), + +(1200177, 1 , 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200177, 2 , 1227577, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200177, 3 , 1227678, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200177, 4 , 1227779, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200177, 5 , 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200177, 6 , 1237678, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200177, 7 , 1237779, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 77-79 Level Range'), +(1200177, 8 , 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), +(1200177, 9 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200177, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200078, 1, 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200078, 2, 1227678, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200078, 3, 1227779, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200078, 4, 1227880, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200078, 5, 1237678, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200078, 6, 1237779, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 77-79 Level Range'), +(1200078, 8, 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), + +(1200178, 1 , 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200178, 2 , 1227678, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200178, 3 , 1227779, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200178, 4 , 1227880, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200178, 5 , 1237678, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200178, 6 , 1237779, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 77-79 Level Range'), +(1200178, 8 , 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), +(1200178, 9 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200178, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200079, 1, 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200079, 2, 1227779, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200079, 3, 1227880, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200079, 4, 1227981, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200079, 5, 1237779, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200079, 6, 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200079, 7, 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), + +(1200179, 1 , 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200179, 2 , 1227779, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200179, 3 , 1227880, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200179, 4 , 1227981, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200179, 5 , 1237779, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 77-79 Level Range'), +(1200179, 6 , 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200179, 7 , 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), +(1200179, 8 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200179, 9 , 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200080, 1, 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200080, 2, 1227880, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200080, 3, 1227981, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200080, 4, 1228082, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +(1200080, 5, 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200080, 6, 1238083, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +(1200080, 7, 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +(1200080, 8, 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), + +(1200180, 1 , 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200180, 2 , 1227880, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200180, 3 , 1227981, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200180, 4 , 1228082, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +(1200180, 5 , 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200180, 6 , 1238083, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +(1200180, 7 , 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +(1200180, 8 , 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), +(1200180, 9 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200180, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200081, 1, 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200081, 2, 1227981, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200081, 3, 1228082, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +(1200081, 4, 1228183, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 81-83 Level Range'), +(1200081, 5, 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200081, 6, 1238083, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +(1200081, 7, 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +(1200081, 8, 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), + +(1200181, 1 , 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200181, 2 , 1227981, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200181, 3 , 1228082, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +(1200181, 4 , 1228183, 0.67, 0, 1, 1, 1, 1, 'WotLK Greens 81-83 Level Range'), +(1200181, 5 , 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200181, 6 , 1238083, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +(1200181, 7 , 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +(1200181, 8 , 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), +(1200181, 9 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200181, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +-- (1200082, 1, 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +-- (1200082, 2, 1228082, 1, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +-- (1200082, 3, 1228183, 1, 0, 1, 1, 1, 1, 'WotLK Greens 81-83 Level Range'), +-- (1200082, 4, 1238083, 0.1, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +-- (1200082, 5, 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +-- (1200082, 6, 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), + +-- (1200182, 1, 1207583, 5, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +-- (1200182, 2, 1228082, 1, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +-- (1200182, 3, 1228183, 1, 0, 1, 1, 1, 1, 'WotLK Greens 81-83 Level Range'), +-- (1200182, 4, 1238083, 0.1, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +-- (1200182, 5, 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +-- (1200182, 6, 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), +-- (1200182, 7, 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +-- (1200182, 8, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +-- Elites +-- (1200268, 1, 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +-- (1200268, 2, 1226870, 10, 0, 1, 0, 1, 1, 'WotLK Greens 68-70 Level Range'), +-- (1200268, 3, 1236871, 0.1, 0, 1, 0, 1, 1, 'WotLK Blues 68-71 Level Range'), +-- (1200268, 4, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), + +-- (1200368, 1, 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +-- (1200368, 2, 1226870, 10, 0, 1, 0, 1, 1, 'WotLK Greens 68-70 Level Range'), +-- (1200368, 3, 1236871, 0.1, 0, 1, 0, 1, 1, 'WotLK Blues 68-71 Level Range'), +-- (1200368, 4, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), +-- (1200368, 5, 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +-- (1200368, 6, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +-- (1200269, 1, 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +-- (1200269, 2, 1226870, 5, 0, 1, 1, 1, 1, 'WotLK Greens 68-70 Level Range'), +-- (1200269, 3, 1226971, 5, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +-- (1200269, 4, 1236871, 0.1, 0, 1, 0, 1, 1, 'WotLK Blues 68-71 Level Range'), +-- (1200269, 5, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), + +-- (1200369, 1, 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +-- (1200369, 2, 1226870, 5, 0, 1, 1, 1, 1, 'WotLK Greens 68-70 Level Range'), +-- (1200369, 3, 1226971, 5, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +-- (1200369, 4, 1236871, 0.1, 0, 1, 0, 1, 1, 'WotLK Blues 68-71 Level Range'), +-- (1200369, 5, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), +-- (1200369, 6, 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +-- (1200369, 7, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200270, 1, 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200270, 2, 1226870, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 68-70 Level Range'), +(1200270, 3, 1226971, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +(1200270, 4, 1227072, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200270, 5, 1236871, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200270, 6, 1237072, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200270, 7, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), + +(1200370, 1, 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200370, 2, 1226870, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 68-70 Level Range'), +(1200370, 3, 1226971, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +(1200370, 4, 1227072, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200370, 5, 1236871, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200370, 6, 1237072, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200370, 7, 1266870, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 68-70 Level Range'), +(1200370, 8, 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200370, 9, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200271, 1, 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200271, 2, 1226971, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +(1200271, 3, 1227072, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200271, 4, 1227173, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200271, 5, 1236871, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200271, 6, 1237072, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200271, 7, 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200271, 8, 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), + +(1200371, 1 , 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200371, 2 , 1226971, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +(1200371, 3 , 1227072, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200371, 4 , 1227173, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200371, 5 , 1236871, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200371, 6 , 1237072, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200371, 7 , 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200371, 8 , 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), +(1200371, 9 , 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200371, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200272, 1, 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200272, 2, 1227072, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200272, 3, 1227173, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200272, 4, 1227274, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200272, 5, 1237072, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200272, 6, 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200272, 7, 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200272, 8, 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), + +(1200372, 1 , 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200372, 2 , 1227072, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 70-72 Level Range'), +(1200372, 3 , 1227173, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200372, 4 , 1227274, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200372, 5 , 1237072, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 70-72 Level Range'), +(1200372, 6 , 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200372, 7 , 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200372, 8 , 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), +(1200372, 9 , 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200372, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200273, 1, 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200273, 2, 1227173, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200273, 3, 1227274, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200273, 4, 1227375, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200273, 5, 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200273, 6, 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200273, 7, 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200273, 8, 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), + +(1200373, 1 , 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200373, 2 , 1227173, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 71-73 Level Range'), +(1200373, 3 , 1227274, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200373, 4 , 1227375, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200373, 5 , 1237173, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 71-73 Level Range'), +(1200373, 6 , 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200373, 7 , 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200373, 8 , 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), +(1200373, 9 , 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200373, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200274, 1, 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200274, 2, 1227274, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200274, 3, 1227375, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200274, 4, 1227476, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200274, 5, 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200274, 6, 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200274, 7, 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200274, 8, 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), + +(1200374, 1 , 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200374, 2 , 1227274, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 72-74 Level Range'), +(1200374, 3 , 1227375, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200374, 4 , 1227476, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200374, 5 , 1237274, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 72-74 Level Range'), +(1200374, 6 , 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200374, 7 , 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200374, 8 , 1267174, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 71-74 Level Range'), +(1200374, 9 , 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200374, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +-- (1200275, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +-- (1200275, 2, 1227375, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +-- (1200275, 3, 1227476, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +-- (1200275, 4, 1227577, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +-- (1200275, 5, 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +-- (1200275, 6, 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +-- (1200275, 7, 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +-- (1200275, 8, 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), + +(1200375, 1 , 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200375, 2 , 1227375, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200375, 3 , 1227476, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200375, 4 , 1227577, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200375, 5 , 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200375, 6 , 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200375, 7 , 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200375, 8 , 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), +(1200375, 9 , 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200375, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200276, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200276, 2, 1227476, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200276, 3, 1227577, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200276, 4, 1227678, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200276, 5, 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200276, 6, 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200276, 7, 1237678, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200276, 8, 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), + +(1200376, 1 , 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200376, 2 , 1227476, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200376, 3 , 1227577, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200376, 4 , 1227678, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200376, 5 , 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200376, 6 , 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200376, 7 , 1237678, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200376, 8 , 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), +(1200376, 9 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200376, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200277, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200277, 2, 1227577, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200277, 3, 1227678, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200277, 4, 1227779, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200277, 5, 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200277, 6, 1237678, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200277, 7, 1237779, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 77-79 Level Range'), +(1200277, 8, 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), + +(1200377, 1 , 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200377, 2 , 1227577, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200377, 3 , 1227678, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200377, 4 , 1227779, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200377, 5 , 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200377, 6 , 1237678, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200377, 7 , 1237779, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 77-79 Level Range'), +(1200377, 8 , 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), +(1200377, 9 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200377, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200278, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200278, 2, 1227678, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200278, 3, 1227779, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200278, 4, 1227880, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200278, 5, 1237678, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200278, 6, 1237779, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 77-79 Level Range'), +(1200278, 8, 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), + +(1200378, 1 , 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200378, 2 , 1227678, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 76-78 Level Range'), +(1200378, 3 , 1227779, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200378, 4 , 1227880, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200378, 5 , 1237678, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 76-78 Level Range'), +(1200378, 6 , 1237779, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 77-79 Level Range'), +(1200378, 8 , 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), +(1200378, 9 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200378, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200279, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200279, 2, 1227779, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200279, 3, 1227880, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200279, 4, 1227981, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200279, 5, 1237779, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200279, 6, 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200279, 7, 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), + +(1200379, 1 , 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200379, 2 , 1227779, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 77-79 Level Range'), +(1200379, 3 , 1227880, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200379, 4 , 1227981, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200379, 5 , 1237779, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 77-79 Level Range'), +(1200379, 6 , 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200379, 7 , 1267579, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 75-79 Level Range'), +(1200379, 8 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200379, 9 , 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200280, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200280, 2, 1227880, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200280, 3, 1227981, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200280, 4, 1228082, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +(1200280, 5, 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200280, 6, 1238083, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +(1200280, 7, 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +(1200280, 8, 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), + +(1200380, 1 , 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200380, 2 , 1227880, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 78-80 Level Range'), +(1200380, 3 , 1227981, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200380, 4 , 1228082, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +(1200380, 5 , 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200380, 6 , 1238083, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +(1200380, 7 , 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +(1200380, 8 , 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), +(1200380, 9 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200380, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200281, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200281, 2, 1227981, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200281, 3, 1228082, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +(1200281, 4, 1228183, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 81-83 Level Range'), +(1200281, 5, 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200281, 6, 1238083, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +(1200281, 7, 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +(1200281, 8, 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), + +(1200381, 1 , 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200381, 2 , 1227981, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 79-81 Level Range'), +(1200381, 3 , 1228082, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +(1200381, 4 , 1228183, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 81-83 Level Range'), +(1200381, 5 , 1237981, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 79-81 Level Range'), +(1200381, 6 , 1238083, 0.05, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +(1200381, 7 , 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +(1200381, 8 , 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), +(1200381, 9 , 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200381, 10, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'); + +-- (1200282, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +-- (1200282, 2, 1228082, 5, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +-- (1200282, 3, 1228183, 5, 0, 1, 1, 1, 1, 'WotLK Greens 81-83 Level Range'), +-- (1200282, 4, 1238083, 0.1, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +-- (1200282, 5, 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +-- (1200282, 6, 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), + +-- (1200382, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +-- (1200382, 2, 1228082, 5, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +-- (1200382, 3, 1228183, 5, 0, 1, 1, 1, 1, 'WotLK Greens 81-83 Level Range'), +-- (1200382, 4, 1238083, 0.1, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +-- (1200382, 5, 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +-- (1200382, 6, 1268083, 100, 0, 1, 0, 1, 1, 'WoLK Profession Drops 80+ Level Range'), +-- (1200382, 7, 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +-- (1200382, 8, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'); + +-- INSERT INTO `creature_loot_template` +-- (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) +-- SELECT +-- T.LootId, +-- +-- -- ITEM ID INCREMENTER +-- -- n is 0, 1, 2... so we add 1 to make it 1, 2, 3... +-- numbers.n + 1, +-- +-- -- REFERENCE ID ([BASE_ID] + Level) +-- -- REPLACE [BASE_ID] BELOW with 1200100 or 1200000 +-- [BASE_ID] + (GREATEST(1, T.MinLvl) + numbers.n), +-- +-- -- CHANCE (0 = Equal distribution) +-- 0, +-- +-- 0, 1, 5, 1, 1, +-- +-- -- CLEAN COMMENT +-- CONCAT(T.CreatureName, ' - World Loot Level ', (GREATEST(1, T.MinLvl) + numbers.n)) +-- FROM +-- ( +-- SELECT +-- `lootid` AS LootId, +-- MAX(`name`) AS CreatureName, +-- MAX(`minlevel`) AS MinLvl, +-- MAX(`maxlevel`) AS MaxLvl +-- FROM `creature_template` +-- WHERE +-- -- Paste the creature list here +-- `entry` IN ( ... ) +-- +-- GROUP BY `lootid` +-- ) T +-- CROSS JOIN +-- (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) AS numbers +-- WHERE +-- (GREATEST(1, T.MinLvl) + numbers.n) <= LEAST(82, T.MaxLvl); + +DELETE FROM `creature_loot_template` WHERE `Reference` IN (1200068, 1200168, 1200069, 1200169, 1200070, 1200170, 1200071, 1200171, 1200072, 1200172, 1200073, 1200173, 1200074, 1200174, 1200075, 1200175, 1200076, 1200176, 1200077, 1200177, 1200078, 1200178, 1200079, 1200179, 1200080, 1200180, 1200081, 1200181, 1200082, 1200182) AND `Entry` IN (5936,23643,23644,23645,23651,23652,23653,23654,23655,23656,23657,23658,23660,23661,23662,23663,23664,23665,23666,23667,23668,23669,23670,23672,23673,23674,23675,23676,23677,23678,23680,23688,23689,23690,23691,23711,23740,23744,23750,23760,23772,23785,23793,23794,23796,23809,23866,23871,23874,23875,23883,23886,23887,23919,23929,23931,23932,23934,23940,23945,23946,23958,23959,23963,23964,23967,23983,23989,23990,23991,23992,23994,24013,24014,24015,24016,24026,24030,24073,24076,24116,24128,24160,24161,24162,24169,24173,24178,24206,24212,24213,24214,24215,24216,24228,24229,24249,24250,24262,24271,24277,24285,24286,24287,24316,24334,24340,24459,24460,24461,24475,24478,24485,24516,24517,24533,24540,24546,24562,24563,24566,24567,24601,24613,24614,24628,24633,24635,24637,24638,24642,24644,24673,24676,24677,24681,24713,24747,24779,24785,24786,24787,24788,24789,24791,24797,24846,24863,24871,24872,24899,24901,24957,25026,25203,25204,25209,25211,25215,25216,25217,25224,25226,25227,25294,25316,25350,25351,25353,25355,25378,25383,25386,25387,25392,25393,25396,25415,25417,25419,25427,25428,25429,25430,25432,25433,25434,25445,25448,25449,25452,25454,25464,25467,25468,25470,25479,25481,25482,25487,25489,25496,25498,25501,25514,25520,25521,25522,25523,25582,25585,25600,25605,25609,25611,25613,25615,25619,25622,25623,25650,25651,25660,25668,25675,25680,25684,25685,25686,25687,25699,25700,25701,25707,25709,25713,25715,25717,25718,25719,25721,25722,25728,25743,25748,25750,25752,25753,25758,25760,25788,25791,25792,25793,25800,25803,25806,25814,25817,25836,25839,25843,25880,25968,25979,25981,26073,26076,26103,26115,26126,26165,26174,26196,26197,26198,26199,26201,26202,26252,26257,26266,26268,26270,26271,26272,26273,26280,26281,26283,26284,26295,26316,26319,26322,26334,26336,26343,26344,26347,26348,26349,26356,26357,26358,26359,26363,26366,26369,26370,26389,26402,26405,26407,26408,26409,26410,26411,26413,26414,26416,26418,26421,26425,26426,26428,26434,26436,26446,26447,26449,26451,26455,26457,26461,26467,26472,26480,26481,26482,26483,26492,26493,26496,26511,26521,26522,26536,26544,26575,26577,26586,26592,26605,26606,26613,26615,26616,26643,26644,26646,26655,26658,26663,26667,26679,26681,26704,26705,26706,26708,26762,26769,26770,26771,26786,26795,26797,26806,26811,26812,26815,26816,26820,26823,26825,26827,26872,26891,26919,26920,26921,26922,26923,26926,26942,26943,26946,26948,26965,27004,27005,27020,27024,27117,27118,27131,27177,27202,27203,27206,27207,27209,27211,27220,27224,27225,27226,27229,27230,27233,27234,27235,27236,27237,27238,27244,27246,27254,27259,27260,27272,27278,27279,27283,27284,27286,27287,27288,27289,27294,27329,27330,27332,27333,27340,27342,27343,27355,27356,27357,27358,27360,27362,27363,27367,27370,27371,27382,27401,27408,27410,27416,27421,27424,27470,27493,27508,27523,27533,27534,27539,27545,27546,27547,27551,27552,27554,27555,27570,27615,27617,27627,27676,27680,27699,27701,27797,27799,27800,27805,27823,27824,27826,27830,27835,27836,27926,27927,27941,28001,28002,28003,28004,28009,28010,28011,28022,28023,28026,28034,28035,28036,28069,28080,28081,28083,28085,28086,28087,28096,28097,28098,28101,28108,28109,28110,28118,28123,28124,28129,28145,28158,28186,28188,28213,28221,28233,28246,28257,28258,28268,28288,28297,28303,28323,28345,28373,28378,28379,28380,28381,28388,28402,28403,28404,28411,28412,28414,28417,28418,28442,28465,28494,28495,28496,28504,28519,28538,28564,28565,28575,28600,28602,28603,28641,28750,28759,28779,28802,28803,28843,28847,28848,28851,28858,28861,28862,28877,28882,28916,28917,28918,28988,29013,29036,29123,29124,29129,29133,29211,29235,29236,29237,29319,29323,29327,29329,29330,29331,29332,29333,29334,29338,29369,29370,29374,29376,29377,29380,29382,29389,29390,29392,29402,29404,29407,29409,29411,29412,29413,29426,29427,29436,29449,29450,29451,29452,29453,29461,29469,29479,29486,29487,29498,29504,29518,29554,29559,29562,29569,29570,29586,29590,29592,29605,29622,29623,29624,29646,29652,29654,29656,29693,29695,29697,29698,29699,29717,29719,29720,29722,29724,29738,29755,29792,29793,29808,29834,29843,29844,29861,29862,29874,29875,29880,29958,30003,30037,30040,30046,30135,30146,30147,30148,30164,30167,30184,30202,30204,30205,30206,30243,30250,30333,30387,30430,30445,30447,30448,30450,30482,30541,30543,30597,30632,30687,30689,30701,30725,30746,30751,30842,30845,30846,30847,30848,30849,30856,30860,30862,30863,30864,30865,30868,30872,30873,30875,30876,30877,30894,30920,30921,30922,30931,30949,30951,30952,30957,30958,30960,30988,31037,31039,31041,31042,31043,31123,31140,31145,31147,31150,31152,31155,31228,31231,31233,31236,31258,31263,31265,31267,31396,31401,31402,31403,31404,31411,31554,31718,31731,31738,31746,31754,31779,31783,31787,31843,31847,31853,31900,32149,32164,32236,32238,32250,32255,32257,32259,32260,32262,32263,32268,32276,32279,32284,32285,32289,32290,32291,32297,32349,32507,32572,34838,34839); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(5936, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Orca - World Loot Level 70'), +(5936, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Orca - World Loot Level 71'), +(23643, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Unstable Mur\'ghoul - World Loot Level 70'), +(23644, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Mur\'ghoul Flesheater - World Loot Level 71'), +(23645, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Mur\'ghoul Corrupter - World Loot Level 71'), +(23651, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Dragonflayer Tribesman - World Loot Level 68'), +(23651, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Tribesman - World Loot Level 69'), +(23652, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Dragonflayer Vrykul - World Loot Level 68'), +(23652, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Vrykul - World Loot Level 69'), +(23653, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Winterskorn Spearman - World Loot Level 68'), +(23653, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Winterskorn Spearman - World Loot Level 69'), +(23654, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Dragonflayer Warrior - World Loot Level 68'), +(23654, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Warrior - World Loot Level 69'), +(23655, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Winterskorn Bonegrinder - World Loot Level 68'), +(23655, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Winterskorn Bonegrinder - World Loot Level 69'), +(23656, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Dragonflayer Rune-Seer - World Loot Level 68'), +(23656, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Rune-Seer - World Loot Level 69'), +(23657, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Winterskorn Skald - World Loot Level 68'), +(23657, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Winterskorn Skald - World Loot Level 69'), +(23658, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Dragonflayer Death Weaver - World Loot Level 68'), +(23658, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Death Weaver - World Loot Level 69'), +(23660, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Dragonflayer Thane - World Loot Level 68'), +(23660, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Thane - World Loot Level 69'), +(23661, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Winterskorn Tribesman - World Loot Level 70'), +(23662, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Winterskorn Woodsman - World Loot Level 70'), +(23663, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Winterskorn Shield-Maiden - World Loot Level 70'), +(23663, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Winterskorn Shield-Maiden - World Loot Level 71'), +(23664, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Winterskorn Warrior - World Loot Level 70'), +(23664, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Winterskorn Warrior - World Loot Level 71'), +(23665, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Winterskorn Raider - World Loot Level 70'), +(23665, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Winterskorn Raider - World Loot Level 71'), +(23666, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Winterskorn Berserker - World Loot Level 70'), +(23666, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Winterskorn Berserker - World Loot Level 71'), +(23667, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Winterskorn Rune-Seer - World Loot Level 70'), +(23667, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Winterskorn Rune-Seer - World Loot Level 71'), +(23668, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Winterskorn Rune-Caster - World Loot Level 70'), +(23668, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Winterskorn Rune-Caster - World Loot Level 71'), +(23669, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Winterskorn Oracle - World Loot Level 70'), +(23669, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Winterskorn Oracle - World Loot Level 71'), +(23670, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Winterskorn Elder - World Loot Level 71'), +(23672, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Iron Rune Worker - World Loot Level 69'), +(23673, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Iron Rune Steelguard - World Loot Level 69'), +(23673, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Iron Rune Steelguard - World Loot Level 70'), +(23674, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Iron Rune Sage - World Loot Level 69'), +(23674, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Iron Rune Sage - World Loot Level 70'), +(23675, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Iron Rune Runemaster - World Loot Level 69'), +(23675, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Iron Rune Runemaster - World Loot Level 70'), +(23676, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Iron Rune Destroyer - World Loot Level 69'), +(23676, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Iron Rune Destroyer - World Loot Level 70'), +(23677, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Frost Nymph - World Loot Level 70'), +(23678, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Chill Nymph - World Loot Level 70'), +(23680, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Plagued Proto-Dragon - World Loot Level 70'), +(23688, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Proto-Whelp - World Loot Level 69'), +(23689, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Proto-Drake - World Loot Level 70'), +(23689, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Proto-Drake - World Loot Level 71'), +(23690, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Shoveltusk - World Loot Level 68'), +(23691, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Shoveltusk Stag - World Loot Level 69'), +(23711, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Iron Rune Laborer - World Loot Level 69'), +(23740, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Frosthorn Ram - World Loot Level 70'), +(23740, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Frosthorn Ram - World Loot Level 71'), +(23744, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Icehollow Behemoth - World Loot Level 71'), +(23750, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Proto-Whelp Hatchling - World Loot Level 70'), +(23750, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Proto-Whelp Hatchling - World Loot Level 71'), +(23760, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Forsaken Plaguebringer - World Loot Level 70'), +(23772, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Spotted Hippogryph - World Loot Level 69'), +(23772, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Spotted Hippogryph - World Loot Level 70'), +(23785, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Daggercap Hammerhead - World Loot Level 68'), +(23785, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Daggercap Hammerhead - World Loot Level 69'), +(23793, 1, 1200168, 0, 0, 1, 5, 1, 1, 'North Fleet Soldier - World Loot Level 68'), +(23793, 2, 1200169, 0, 0, 1, 5, 1, 1, 'North Fleet Soldier - World Loot Level 69'), +(23794, 1, 1200168, 0, 0, 1, 5, 1, 1, 'North Fleet Medic - World Loot Level 68'), +(23794, 2, 1200169, 0, 0, 1, 5, 1, 1, 'North Fleet Medic - World Loot Level 69'), +(23796, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Iron Rune Binder - World Loot Level 69'), +(23796, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Iron Rune Binder - World Loot Level 70'), +(23809, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Vengeance Landing Cannoneer - World Loot Level 72'), +(23809, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Vengeance Landing Cannoneer - World Loot Level 73'), +(23866, 1, 1200168, 0, 0, 1, 5, 1, 1, 'North Fleet Sailor - World Loot Level 68'), +(23866, 2, 1200169, 0, 0, 1, 5, 1, 1, 'North Fleet Sailor - World Loot Level 69'), +(23871, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Handler - World Loot Level 69'), +(23871, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Dragonflayer Handler - World Loot Level 70'), +(23874, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Thornvine Creeper - World Loot Level 69'), +(23874, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Thornvine Creeper - World Loot Level 70'), +(23875, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Blacksouled Keeper - World Loot Level 71'), +(23883, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Forsaken Crossbowman - World Loot Level 68'), +(23883, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Forsaken Crossbowman - World Loot Level 69'), +(23886, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Bull Lion Seal - World Loot Level 70'), +(23887, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Lion Seal - World Loot Level 68'), +(23887, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Lion Seal - World Loot Level 69'), +(23919, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Ice Elemental - World Loot Level 69'), +(23929, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Giant Tidecrawler - World Loot Level 68'), +(23929, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Giant Tidecrawler - World Loot Level 69'), +(23931, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Oluf the Violent - World Loot Level 69'), +(23932, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Yanis the Mystic - World Loot Level 71'), +(23934, 1, 1200168, 0, 0, 1, 5, 1, 1, 'North Fleet Salvager - World Loot Level 68'), +(23934, 2, 1200169, 0, 0, 1, 5, 1, 1, 'North Fleet Salvager - World Loot Level 69'), +(23940, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Skeld Drakeson - World Loot Level 70'), +(23945, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Fjord Crow - World Loot Level 68'), +(23946, 1, 1200168, 0, 0, 1, 5, 1, 1, 'North Fleet Marksman - World Loot Level 68'), +(23946, 2, 1200169, 0, 0, 1, 5, 1, 1, 'North Fleet Marksman - World Loot Level 69'), +(23958, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Riven Widow - World Loot Level 70'), +(23958, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Riven Widow - World Loot Level 71'), +(23959, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Darkclaw Bat - World Loot Level 70'), +(23959, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Darkclaw Bat - World Loot Level 71'), +(23963, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Sergeant Lorric - World Loot Level 69'), +(23964, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Lieutenant Celeyne - World Loot Level 69'), +(23967, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Deranged Explorer - World Loot Level 70'), +(23967, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Deranged Explorer - World Loot Level 71'), +(23983, 1, 1200068, 0, 0, 1, 5, 1, 1, 'North Fleet Marine - World Loot Level 68'), +(23983, 2, 1200069, 0, 0, 1, 5, 1, 1, 'North Fleet Marine - World Loot Level 69'), +(23989, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Gjalerbron Sleep-Watcher - World Loot Level 70'), +(23989, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Gjalerbron Sleep-Watcher - World Loot Level 71'), +(23990, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Gjalerbron Rune-Caster - World Loot Level 70'), +(23990, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Gjalerbron Rune-Caster - World Loot Level 71'), +(23991, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Gjalerbron Warrior - World Loot Level 70'), +(23991, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Gjalerbron Warrior - World Loot Level 71'), +(23992, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Putrid Wight - World Loot Level 70'), +(23992, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Putrid Wight - World Loot Level 71'), +(23994, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Dragonflayer Hunting Hound - World Loot Level 68'), +(24013, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Deathless Watcher - World Loot Level 70'), +(24013, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Deathless Watcher - World Loot Level 71'), +(24014, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Necrolord - World Loot Level 70'), +(24014, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Necrolord - World Loot Level 71'), +(24015, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Winterskorn Defender - World Loot Level 68'), +(24015, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Winterskorn Defender - World Loot Level 69'), +(24016, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Ulf the Bloodletter - World Loot Level 69'), +(24026, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Fanggore Worg - World Loot Level 70'), +(24026, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Fanggore Worg - World Loot Level 71'), +(24030, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Iron Rune Stonecaller - World Loot Level 70'), +(24073, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Fearsome Horror - World Loot Level 70'), +(24073, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Fearsome Horror - World Loot Level 71'), +(24076, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Winterskorn Worg - World Loot Level 68'), +(24076, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Winterskorn Worg - World Loot Level 69'), +(24116, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Winterskorn Scout - World Loot Level 69'), +(24128, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Wild Worg - World Loot Level 68'), +(24128, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Wild Worg - World Loot Level 69'), +(24160, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Plagued Proto-Whelp - World Loot Level 69'), +(24161, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Oric the Baleful - World Loot Level 69'), +(24162, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Gunnar Thorvardsson - World Loot Level 69'), +(24169, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Lieutenant - World Loot Level 69'), +(24173, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Frostgore - World Loot Level 71'), +(24178, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Shatterhorn - World Loot Level 71'), +(24206, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Prowling Worg - World Loot Level 70'), +(24206, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Prowling Worg - World Loot Level 71'), +(24212, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Iron Rune Guardian - World Loot Level 69'), +(24212, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Iron Rune Guardian - World Loot Level 70'), +(24213, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Firjus the Soul Crusher - World Loot Level 69'), +(24214, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Yorus the Flesh Harvester - World Loot Level 69'), +(24215, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Jlarborn the Strategist - World Loot Level 69'), +(24216, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Dragonflayer Berserker - World Loot Level 68'), +(24216, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Berserker - World Loot Level 69'), +(24228, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Iceshard Elemental - World Loot Level 70'), +(24228, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Iceshard Elemental - World Loot Level 71'), +(24229, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Howling Cyclone - World Loot Level 70'), +(24229, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Howling Cyclone - World Loot Level 71'), +(24249, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Dragonflayer Soulreaver - World Loot Level 68'), +(24249, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Soulreaver - World Loot Level 69'), +(24250, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Dragonflayer Fleshripper - World Loot Level 68'), +(24250, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Fleshripper - World Loot Level 69'), +(24262, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Vrykul Soul - World Loot Level 70'), +(24262, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Vrykul Soul - World Loot Level 71'), +(24271, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Iron Rune Golem - World Loot Level 70'), +(24277, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Garwal - World Loot Level 71'), +(24285, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Northern Barbfish - World Loot Level 70'), +(24286, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Forsaken Spy - World Loot Level 70'), +(24287, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Caldemere Snapper - World Loot Level 69'), +(24287, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Caldemere Snapper - World Loot Level 70'), +(24316, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Iron Rune Sentinel - World Loot Level 70'), +(24334, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Binder Murdis - World Loot Level 70'), +(24340, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Rampaging Earth Elemental - World Loot Level 69'), +(24340, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Rampaging Earth Elemental - World Loot Level 70'), +(24459, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Chillmere Coastrunner - World Loot Level 70'), +(24459, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Chillmere Coastrunner - World Loot Level 71'), +(24460, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Chillmere Tidehunter - World Loot Level 70'), +(24460, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Chillmere Tidehunter - World Loot Level 71'), +(24461, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Chillmere Oracle - World Loot Level 70'), +(24461, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Chillmere Oracle - World Loot Level 71'), +(24475, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Bloodthirsty Worg - World Loot Level 68'), +(24475, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Bloodthirsty Worg - World Loot Level 69'), +(24478, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Fjord Crawler - World Loot Level 70'), +(24485, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Servitor Shade - World Loot Level 70'), +(24516, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Bjomolf - World Loot Level 72'), +(24517, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Varg - World Loot Level 71'), +(24533, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Defender - World Loot Level 69'), +(24540, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Necrotech - World Loot Level 71'), +(24546, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Rotgill - World Loot Level 71'), +(24562, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Invader - World Loot Level 68'), +(24562, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Invader - World Loot Level 69'), +(24563, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Venomspitter - World Loot Level 70'), +(24563, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Venomspitter - World Loot Level 71'), +(24566, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Skitterer - World Loot Level 68'), +(24566, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Skitterer - World Loot Level 69'), +(24567, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Den Vermin - World Loot Level 68'), +(24567, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Den Vermin - World Loot Level 69'), +(24601, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Steam Rager - World Loot Level 70'), +(24601, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Steam Rager - World Loot Level 71'), +(24613, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Mammoth Calf - World Loot Level 68'), +(24614, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Wooly Mammoth - World Loot Level 69'), +(24628, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Northsea Duelist - World Loot Level 70'), +(24633, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Rabid Brown Bear - World Loot Level 70'), +(24633, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Rabid Brown Bear - World Loot Level 71'), +(24635, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Dragonflayer Harpooner - World Loot Level 68'), +(24635, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Harpooner - World Loot Level 69'), +(24637, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Great Reef Shark - World Loot Level 70'), +(24637, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Great Reef Shark - World Loot Level 71'), +(24638, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Keeper Witherleaf - World Loot Level 71'), +(24642, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Drunken Northsea Pirate - World Loot Level 70'), +(24644, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Harpoon Master Yavus - World Loot Level 70'), +(24673, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Frostwing Chimaera - World Loot Level 70'), +(24673, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Frostwing Chimaera - World Loot Level 71'), +(24676, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Crazed Northsea Slaver - World Loot Level 70'), +(24677, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Spearfang Worg - World Loot Level 70'), +(24677, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Spearfang Worg - World Loot Level 71'), +(24681, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Island Shoveltusk - World Loot Level 70'), +(24681, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Island Shoveltusk - World Loot Level 71'), +(24713, 1, 1200170, 0, 0, 1, 5, 1, 1, '"Crowleg" Dan - World Loot Level 70'), +(24747, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Fjord Hawk - World Loot Level 68'), +(24747, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Fjord Hawk - World Loot Level 69'), +(24747, 3, 1200070, 0, 0, 1, 5, 1, 1, 'Fjord Hawk - World Loot Level 70'), +(24779, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Ambusher - World Loot Level 69'), +(24779, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Dragonflayer Ambusher - World Loot Level 70'), +(24779, 3, 1200171, 0, 0, 1, 5, 1, 1, 'Dragonflayer Ambusher - World Loot Level 71'), +(24785, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Big Roy - World Loot Level 71'), +(24786, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Reef Bull - World Loot Level 70'), +(24787, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Fjord Hawk Matriarch - World Loot Level 71'), +(24788, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Jack Adams - World Loot Level 70'), +(24789, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Forlorn Soul - World Loot Level 70'), +(24789, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Forlorn Soul - World Loot Level 71'), +(24791, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Shoveltusk Calf - World Loot Level 68'), +(24797, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Reef Cow - World Loot Level 70'), +(24846, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Iron Dwarf - World Loot Level 69'), +(24863, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Frosthorn Kid - World Loot Level 70'), +(24871, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Risen Vrykul Ancestor - World Loot Level 69'), +(24871, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Risen Vrykul Ancestor - World Loot Level 70'), +(24872, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Blood Shade - World Loot Level 69'), +(24872, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Blood Shade - World Loot Level 70'), +(24899, 1, 1200071, 0, 0, 1, 5, 1, 1, '"Scoodles" - World Loot Level 71'), +(24901, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Maddened Frosthorn - World Loot Level 70'), +(24901, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Maddened Frosthorn - World Loot Level 71'), +(24957, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Cult Plaguebringer - World Loot Level 70'), +(24957, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Cult Plaguebringer - World Loot Level 71'), +(25026, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Mutinous Sea Dog - World Loot Level 69'), +(25026, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Mutinous Sea Dog - World Loot Level 70'), +(25203, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Glrggl - World Loot Level 71'), +(25204, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Glimmer Bay Orca - World Loot Level 70'), +(25204, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Glimmer Bay Orca - World Loot Level 71'), +(25209, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Claximus - World Loot Level 72'), +(25211, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Cleaver Bmurglbrm - World Loot Level 69'), +(25215, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Winterfin Shorestriker - World Loot Level 69'), +(25215, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Winterfin Shorestriker - World Loot Level 70'), +(25216, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Winterfin Oracle - World Loot Level 69'), +(25216, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Winterfin Oracle - World Loot Level 70'), +(25217, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Winterfin Warrior - World Loot Level 69'), +(25217, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Winterfin Warrior - World Loot Level 70'), +(25224, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Vengeful Kvaldir Spirit - World Loot Level 70'), +(25224, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Vengeful Kvaldir Spirit - World Loot Level 71'), +(25226, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Scalder - World Loot Level 71'), +(25227, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Crypt Crawler - World Loot Level 68'), +(25227, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Crypt Crawler - World Loot Level 69'), +(25294, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Web Lord - World Loot Level 69'), +(25316, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Beryl Sorcerer - World Loot Level 69'), +(25316, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Beryl Sorcerer - World Loot Level 70'), +(25350, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Risen Longrunner - World Loot Level 69'), +(25350, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Risen Longrunner - World Loot Level 70'), +(25351, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Ghostly Sage - World Loot Level 69'), +(25351, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Ghostly Sage - World Loot Level 70'), +(25353, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Beryl Treasure Hunter - World Loot Level 69'), +(25353, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Beryl Treasure Hunter - World Loot Level 70'), +(25355, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Beryl Hound - World Loot Level 69'), +(25355, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Beryl Hound - World Loot Level 70'), +(25378, 1, 1200171, 0, 0, 1, 5, 1, 1, 'En\'kilah Necromancer - World Loot Level 71'), +(25378, 2, 1200172, 0, 0, 1, 5, 1, 1, 'En\'kilah Necromancer - World Loot Level 72'), +(25383, 1, 1200171, 0, 0, 1, 5, 1, 1, 'En\'kilah Abomination - World Loot Level 71'), +(25386, 1, 1200170, 0, 0, 1, 5, 1, 1, 'En\'kilah Crypt Fiend - World Loot Level 70'), +(25386, 2, 1200171, 0, 0, 1, 5, 1, 1, 'En\'kilah Crypt Fiend - World Loot Level 71'), +(25387, 1, 1200071, 0, 0, 1, 5, 1, 1, 'En\'kilah Gargoyle - World Loot Level 71'), +(25392, 1, 1200172, 0, 0, 1, 5, 1, 1, 'High Priest Andorath - World Loot Level 72'), +(25393, 1, 1200170, 0, 0, 1, 5, 1, 1, 'En\'kilah Ghoul - World Loot Level 70'), +(25396, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Naxxanar Skeletal Mage - World Loot Level 72'), +(25415, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Enraged Tempest - World Loot Level 70'), +(25415, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Enraged Tempest - World Loot Level 71'), +(25417, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Raging Boiler - World Loot Level 69'), +(25417, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Raging Boiler - World Loot Level 70'), +(25419, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Boiling Spirit - World Loot Level 69'), +(25419, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Boiling Spirit - World Loot Level 70'), +(25427, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Kaganishu - World Loot Level 71'), +(25428, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Magmoth Shaman - World Loot Level 69'), +(25428, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Magmoth Shaman - World Loot Level 70'), +(25429, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Magmoth Forager - World Loot Level 70'), +(25429, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Magmoth Forager - World Loot Level 71'), +(25430, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Magmothregar - World Loot Level 72'), +(25432, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Mate of Magmothregar - World Loot Level 70'), +(25433, 1, 1200169, 12.5, 0, 1, 5, 1, 1, 'Offspring of Magmothregar - World Loot Level 69'), +(25433, 2, 1200170, 12.5, 0, 1, 5, 1, 1, 'Offspring of Magmothregar - World Loot Level 70'), +(25434, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Magmoth Crusher - World Loot Level 70'), +(25445, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Corpse Harvester - World Loot Level 68'), +(25445, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Corpse Harvester - World Loot Level 69'), +(25448, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Curator Insivius - World Loot Level 72'), +(25449, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Beryl Reclaimer - World Loot Level 69'), +(25449, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Beryl Reclaimer - World Loot Level 70'), +(25452, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Scourged Mammoth - World Loot Level 70'), +(25452, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Scourged Mammoth - World Loot Level 71'), +(25454, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Tundra Crawler - World Loot Level 70'), +(25464, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Bloodspore Moth - World Loot Level 68'), +(25464, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Bloodspore Moth - World Loot Level 69'), +(25467, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Bloodspore Harvester - World Loot Level 68'), +(25467, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Bloodspore Harvester - World Loot Level 69'), +(25468, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Bloodspore Roaster - World Loot Level 68'), +(25468, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Bloodspore Roaster - World Loot Level 69'), +(25470, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Bloodspore Firestarter - World Loot Level 68'), +(25470, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Bloodspore Firestarter - World Loot Level 69'), +(25479, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Kvaldir Mistweaver - World Loot Level 68'), +(25479, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Kvaldir Mistweaver - World Loot Level 69'), +(25481, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Landing Crawler - World Loot Level 68'), +(25481, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Landing Crawler - World Loot Level 69'), +(25482, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Sand Turtle - World Loot Level 70'), +(25487, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Wooly Rhino Matriarch - World Loot Level 68'), +(25489, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Wooly Rhino Bull - World Loot Level 69'), +(25496, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Kvaldir Mist Lord - World Loot Level 68'), +(25496, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Kvaldir Mist Lord - World Loot Level 69'), +(25498, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Aspatha the Broodmother - World Loot Level 71'), +(25501, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Gammoth Tender - World Loot Level 70'), +(25514, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Rocknar - World Loot Level 71'), +(25520, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Skadir Runecaster - World Loot Level 68'), +(25520, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Skadir Runecaster - World Loot Level 69'), +(25521, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Skadir Longboatsman - World Loot Level 68'), +(25521, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Skadir Longboatsman - World Loot Level 69'), +(25522, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Skadir Raider - World Loot Level 68'), +(25522, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Skadir Raider - World Loot Level 69'), +(25523, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Skadir Mariner - World Loot Level 68'), +(25523, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Skadir Mariner - World Loot Level 69'), +(25582, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Scourged Flamespitter - World Loot Level 68'), +(25582, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Scourged Flamespitter - World Loot Level 69'), +(25585, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Beryl Mage Hunter - World Loot Level 69'), +(25585, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Beryl Mage Hunter - World Loot Level 70'), +(25600, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Unliving Swine - World Loot Level 68'), +(25600, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Unliving Swine - World Loot Level 69'), +(25605, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Clandestine Cultist - World Loot Level 68'), +(25605, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Clandestine Cultist - World Loot Level 69'), +(25609, 1, 1200169, 0, 0, 1, 5, 1, 1, 'En\'kilah Necrolord - World Loot Level 69'), +(25611, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Warsong Aberration - World Loot Level 69'), +(25613, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Skadir Mistweaver - World Loot Level 68'), +(25613, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Skadir Mistweaver - World Loot Level 69'), +(25615, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Plagued Magnataur - World Loot Level 70'), +(25615, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Plagued Magnataur - World Loot Level 71'), +(25619, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Warrior - World Loot Level 70'), +(25619, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Warrior - World Loot Level 71'), +(25622, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Tunneler - World Loot Level 70'), +(25622, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Nerub\'ar Tunneler - World Loot Level 71'), +(25623, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Harvest Collector - World Loot Level 68'), +(25650, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Plagued Scavenger - World Loot Level 68'), +(25650, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Plagued Scavenger - World Loot Level 69'), +(25651, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Cultist Necrolyte - World Loot Level 68'), +(25651, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Cultist Necrolyte - World Loot Level 69'), +(25660, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Festering Ghoul - World Loot Level 70'), +(25660, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Festering Ghoul - World Loot Level 71'), +(25668, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Vengeful Taunka Spirit - World Loot Level 70'), +(25668, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Vengeful Taunka Spirit - World Loot Level 71'), +(25675, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Tundra Wolf - World Loot Level 68'), +(25680, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Marsh Caribou - World Loot Level 70'), +(25680, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Marsh Caribou - World Loot Level 71'), +(25684, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Talramas Abomination - World Loot Level 71'), +(25685, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Gorloc Waddler - World Loot Level 70'), +(25685, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Gorloc Waddler - World Loot Level 71'), +(25686, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Gorloc Gibberer - World Loot Level 70'), +(25686, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Gorloc Gibberer - World Loot Level 71'), +(25687, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Gorloc Steam Belcher - World Loot Level 70'), +(25687, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Gorloc Steam Belcher - World Loot Level 71'), +(25699, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Gorloc Mud Splasher - World Loot Level 70'), +(25699, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Gorloc Mud Splasher - World Loot Level 71'), +(25700, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Gorloc Hunter - World Loot Level 70'), +(25700, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Gorloc Hunter - World Loot Level 71'), +(25701, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Gorloc Dredger - World Loot Level 70'), +(25701, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Gorloc Dredger - World Loot Level 71'), +(25707, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Magic-bound Ancient - World Loot Level 71'), +(25707, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Magic-bound Ancient - World Loot Level 72'), +(25709, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Glacial Ancient - World Loot Level 71'), +(25709, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Glacial Ancient - World Loot Level 72'), +(25713, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Blue Drakonid Supplicant - World Loot Level 71'), +(25713, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Blue Drakonid Supplicant - World Loot Level 72'), +(25715, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Frozen Elemental - World Loot Level 70'), +(25715, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Frozen Elemental - World Loot Level 71'), +(25717, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Coldarra Scalesworn - World Loot Level 71'), +(25717, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Coldarra Scalesworn - World Loot Level 72'), +(25718, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Coldarra Mage Slayer - World Loot Level 69'), +(25719, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Coldarra Spellbinder - World Loot Level 71'), +(25719, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Coldarra Spellbinder - World Loot Level 72'), +(25721, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Arcane Serpent - World Loot Level 71'), +(25721, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Arcane Serpent - World Loot Level 72'), +(25722, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Coldarra Spellweaver - World Loot Level 71'), +(25722, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Coldarra Spellweaver - World Loot Level 72'), +(25728, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Coldarra Wyrmkin - World Loot Level 71'), +(25728, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Coldarra Wyrmkin - World Loot Level 72'), +(25743, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Wooly Mammoth Bull - World Loot Level 70'), +(25748, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Oil-covered Hawk - World Loot Level 70'), +(25750, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Oil-soaked Caribou - World Loot Level 70'), +(25752, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Scavenge-bot 004-A8 - World Loot Level 70'), +(25752, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Scavenge-bot 004-A8 - World Loot Level 71'), +(25753, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Sentry-bot 57-K - World Loot Level 70'), +(25758, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Defendo-tank 66D - World Loot Level 70'), +(25758, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Defendo-tank 66D - World Loot Level 71'), +(25760, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Kvaldir Raider - World Loot Level 68'), +(25760, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Kvaldir Raider - World Loot Level 69'), +(25788, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Weakened Magnataur Huntress - World Loot Level 69'), +(25791, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Oil-stained Wolf - World Loot Level 70'), +(25791, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Oil-stained Wolf - World Loot Level 71'), +(25792, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Scavenge-bot 005-B6 - World Loot Level 70'), +(25792, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Scavenge-bot 005-B6 - World Loot Level 71'), +(25793, 1, 1200070, 0, 0, 1, 5, 1, 1, '55-D Collect-a-tron - World Loot Level 70'), +(25793, 2, 1200071, 0, 0, 1, 5, 1, 1, '55-D Collect-a-tron - World Loot Level 71'), +(25800, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Clam Master K - World Loot Level 72'), +(25803, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Karen "I Don\'t Caribou" the Culler - World Loot Level 72'), +(25806, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Loot Crazed Poacher - World Loot Level 69'), +(25806, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Loot Crazed Poacher - World Loot Level 70'), +(25814, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Fizzcrank Mechagnome - World Loot Level 71'), +(25817, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Oiled Fledgeling - World Loot Level 69'), +(25836, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Loot Crazed Diver - World Loot Level 69'), +(25836, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Loot Crazed Diver - World Loot Level 70'), +(25839, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Northsea Mercenary - World Loot Level 69'), +(25839, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Northsea Mercenary - World Loot Level 70'), +(25843, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Northsea Thug - World Loot Level 69'), +(25843, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Northsea Thug - World Loot Level 70'), +(25880, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Minion of Kaw - World Loot Level 69'), +(25880, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Minion of Kaw - World Loot Level 70'), +(25880, 3, 1200171, 0, 0, 1, 5, 1, 1, 'Minion of Kaw - World Loot Level 71'), +(25968, 1, 1200071, 0, 0, 1, 5, 1, 1, '"Lunchbox" - World Loot Level 71'), +(25979, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Loot Crazed Hunter - World Loot Level 70'), +(25979, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Loot Crazed Hunter - World Loot Level 71'), +(25981, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Scourged Footman - World Loot Level 68'), +(25981, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Scourged Footman - World Loot Level 69'), +(26073, 1, 1200172, 0, 0, 1, 5, 1, 1, 'High Priest Talet-Kha - World Loot Level 72'), +(26076, 1, 1200172, 0, 0, 1, 5, 1, 1, 'High Priest Naferset - World Loot Level 72'), +(26103, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Darkfallen Deathblade - World Loot Level 72'), +(26115, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Darkfallen Bloodbearer - World Loot Level 72'), +(26126, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Bone Warrior - World Loot Level 70'), +(26126, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Bone Warrior - World Loot Level 71'), +(26165, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Damned Taunka Spirit - World Loot Level 70'), +(26174, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Carrion Condor - World Loot Level 70'), +(26174, 2, 1200071, 0, 0, 1, 5, 1, 1, 'Carrion Condor - World Loot Level 71'), +(26196, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Loguhn - World Loot Level 73'), +(26197, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Snowfall Glade Reaver - World Loot Level 71'), +(26197, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Snowfall Glade Reaver - World Loot Level 72'), +(26198, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Snowfall Glade Wolvar - World Loot Level 71'), +(26198, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Snowfall Glade Wolvar - World Loot Level 72'), +(26199, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Snowfall Glade Den Mother - World Loot Level 71'), +(26199, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Snowfall Glade Den Mother - World Loot Level 72'), +(26201, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Snowfall Glade Shaman - World Loot Level 71'), +(26201, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Snowfall Glade Shaman - World Loot Level 72'), +(26202, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Ziggurat Defender - World Loot Level 70'), +(26202, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Ziggurat Defender - World Loot Level 71'), +(26252, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Captain Jacobs - World Loot Level 69'), +(26257, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Surge Needle Sorcerer - World Loot Level 71'), +(26257, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Surge Needle Sorcerer - World Loot Level 72'), +(26266, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Heigarr the Horrible - World Loot Level 70'), +(26268, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Rune Reaver - World Loot Level 74'), +(26268, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Rune Reaver - World Loot Level 75'), +(26270, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Iron Rune-Shaper - World Loot Level 73'), +(26270, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Iron Rune-Shaper - World Loot Level 74'), +(26271, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Emaciated Mammoth Bull - World Loot Level 73'), +(26272, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Emaciated Mammoth - World Loot Level 71'), +(26273, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Emaciated Mammoth Calf - World Loot Level 70'), +(26280, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Dragonblight Mage Hunter - World Loot Level 71'), +(26280, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Dragonblight Mage Hunter - World Loot Level 72'), +(26281, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Moonrest Stalker - World Loot Level 71'), +(26281, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Moonrest Stalker - World Loot Level 72'), +(26283, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Ice Revenant - World Loot Level 72'), +(26283, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Ice Revenant - World Loot Level 73'), +(26284, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Runic Battle Golem - World Loot Level 73'), +(26284, 2, 1200074, 0, 0, 1, 5, 1, 1, 'Runic Battle Golem - World Loot Level 74'), +(26295, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Magnataur Patriarch - World Loot Level 72'), +(26316, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Crystalline Ice Elemental - World Loot Level 73'), +(26316, 2, 1200074, 0, 0, 1, 5, 1, 1, 'Crystalline Ice Elemental - World Loot Level 74'), +(26319, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Anub\'ar Cultist - World Loot Level 71'), +(26319, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Anub\'ar Cultist - World Loot Level 72'), +(26322, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Arcane Wyrm - World Loot Level 71'), +(26322, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Arcane Wyrm - World Loot Level 72'), +(26334, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Forgemaster Damrath - World Loot Level 74'), +(26336, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Indu\'le Mystic - World Loot Level 71'), +(26336, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Indu\'le Mystic - World Loot Level 72'), +(26343, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Indu\'le Fisherman - World Loot Level 71'), +(26343, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Indu\'le Fisherman - World Loot Level 72'), +(26344, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Indu\'le Warrior - World Loot Level 71'), +(26344, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Indu\'le Warrior - World Loot Level 72'), +(26347, 1, 1200074, 0, 0, 1, 5, 1, 1, 'Runic War Golem - World Loot Level 74'), +(26347, 2, 1200075, 0, 0, 1, 5, 1, 1, 'Runic War Golem - World Loot Level 75'), +(26348, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Iron Thane Argrum - World Loot Level 74'), +(26349, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Goramosh - World Loot Level 73'), +(26356, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Redfang Hunter - World Loot Level 74'), +(26356, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Redfang Hunter - World Loot Level 75'), +(26357, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Frostpaw Warrior - World Loot Level 75'), +(26358, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Ice Heart Jormungar Feeder - World Loot Level 72'), +(26359, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Ice Heart Jormungar Spawn - World Loot Level 72'), +(26363, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Tallhorn Stag - World Loot Level 72'), +(26363, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Tallhorn Stag - World Loot Level 73'), +(26366, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Entropic Ooze - World Loot Level 72'), +(26366, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Entropic Ooze - World Loot Level 73'), +(26369, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Imperial Eagle - World Loot Level 72'), +(26369, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Imperial Eagle - World Loot Level 73'), +(26370, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Arcanimus - World Loot Level 73'), +(26389, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Solstice Hunter - World Loot Level 73'), +(26389, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Solstice Hunter - World Loot Level 74'), +(26402, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Anub\'ar Ambusher - World Loot Level 71'), +(26402, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Anub\'ar Ambusher - World Loot Level 72'), +(26405, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Iron Thane Furyhammer - World Loot Level 75'), +(26407, 1, 1200074, 0, 0, 1, 5, 1, 1, 'Lightning Sentry - World Loot Level 74'), +(26407, 2, 1200075, 0, 0, 1, 5, 1, 1, 'Lightning Sentry - World Loot Level 75'), +(26408, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Iron Rune-Smith - World Loot Level 74'), +(26408, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Iron Rune-Smith - World Loot Level 75'), +(26409, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Rune-Smith Durar - World Loot Level 74'), +(26409, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Rune-Smith Durar - World Loot Level 75'), +(26410, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Rune-Smith Kathorn - World Loot Level 74'), +(26410, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Rune-Smith Kathorn - World Loot Level 75'), +(26411, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Deranged Indu\'le Villager - World Loot Level 71'), +(26411, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Deranged Indu\'le Villager - World Loot Level 72'), +(26413, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Anub\'ar Dreadweaver - World Loot Level 71'), +(26413, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Anub\'ar Dreadweaver - World Loot Level 72'), +(26414, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Runic Lightning Gunner - World Loot Level 74'), +(26414, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Runic Lightning Gunner - World Loot Level 75'), +(26416, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Wolfcult Initiate - World Loot Level 73'), +(26416, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Wolfcult Initiate - World Loot Level 74'), +(26418, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Longhoof Grazer - World Loot Level 73'), +(26418, 2, 1200074, 0, 0, 1, 5, 1, 1, 'Longhoof Grazer - World Loot Level 74'), +(26421, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Woodlands Walker - World Loot Level 71'), +(26421, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Woodlands Walker - World Loot Level 72'), +(26425, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Drakkari Warrior - World Loot Level 73'), +(26426, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Arctic Ram - World Loot Level 72'), +(26426, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Arctic Ram - World Loot Level 73'), +(26428, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Frostpaw Shaman - World Loot Level 75'), +(26434, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Frostpaw Trapper - World Loot Level 75'), +(26436, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Redfang Elder - World Loot Level 75'), +(26446, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Ice Serpent - World Loot Level 72'), +(26446, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Ice Serpent - World Loot Level 73'), +(26447, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Drakkari Shaman - World Loot Level 73'), +(26449, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Gamel the Cruel - World Loot Level 70'), +(26451, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Ragnar Drakkarlund - World Loot Level 70'), +(26455, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Moonrest Highborne - World Loot Level 71'), +(26455, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Moonrest Highborne - World Loot Level 72'), +(26457, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Diseased Drakkari - World Loot Level 73'), +(26461, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Scourge Corpserender - World Loot Level 73'), +(26467, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Jormungar Tunneler - World Loot Level 73'), +(26467, 2, 1200074, 0, 0, 1, 5, 1, 1, 'Jormungar Tunneler - World Loot Level 74'), +(26472, 1, 1200074, 0, 0, 1, 5, 1, 1, 'Highland Mustang - World Loot Level 74'), +(26472, 2, 1200075, 0, 0, 1, 5, 1, 1, 'Highland Mustang - World Loot Level 75'), +(26480, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Magnataur Youngling - World Loot Level 72'), +(26481, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Magnataur Alpha - World Loot Level 73'), +(26482, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Arctic Grizzly - World Loot Level 72'), +(26482, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Arctic Grizzly - World Loot Level 73'), +(26483, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Dragonbone Condor - World Loot Level 71'), +(26483, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Dragonbone Condor - World Loot Level 72'), +(26492, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Wastes Digger - World Loot Level 72'), +(26492, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Wastes Digger - World Loot Level 73'), +(26493, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Wastes Taskmaster - World Loot Level 73'), +(26496, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Wind Trader Mu\'fah - World Loot Level 72'), +(26511, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Moa\'ki Bottom Thresher - World Loot Level 71'), +(26511, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Moa\'ki Bottom Thresher - World Loot Level 72'), +(26521, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Kili\'ua - World Loot Level 72'), +(26522, 1, 1200074, 0, 0, 1, 5, 1, 1, 'Subterranean Thresher - World Loot Level 74'), +(26536, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Mindless Servant - World Loot Level 78'), +(26544, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Warlord Zim\'bo - World Loot Level 73'), +(26575, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Coldwind Waste Huntress - World Loot Level 73'), +(26575, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Coldwind Waste Huntress - World Loot Level 74'), +(26577, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Coldwind Witch - World Loot Level 73'), +(26577, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Coldwind Witch - World Loot Level 74'), +(26586, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Hungry Worg - World Loot Level 72'), +(26586, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Hungry Worg - World Loot Level 73'), +(26592, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Graymist Hunter - World Loot Level 73'), +(26592, 2, 1200074, 0, 0, 1, 5, 1, 1, 'Graymist Hunter - World Loot Level 74'), +(26605, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Anub\'ar Underlord - World Loot Level 71'), +(26605, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Anub\'ar Underlord - World Loot Level 72'), +(26606, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Anub\'ar Slayer - World Loot Level 71'), +(26606, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Anub\'ar Slayer - World Loot Level 72'), +(26613, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Arctic Grizzly Cub - World Loot Level 69'), +(26613, 2, 1200070, 0, 0, 1, 5, 1, 1, 'Arctic Grizzly Cub - World Loot Level 70'), +(26615, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Snowfall Elk - World Loot Level 71'), +(26615, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Snowfall Elk - World Loot Level 72'), +(26616, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Blighted Elk - World Loot Level 71'), +(26616, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Blighted Elk - World Loot Level 72'), +(26643, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Rabid Grizzly - World Loot Level 68'), +(26643, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Rabid Grizzly - World Loot Level 69'), +(26643, 3, 1200070, 0, 0, 1, 5, 1, 1, 'Rabid Grizzly - World Loot Level 70'), +(26643, 4, 1200071, 0, 0, 1, 5, 1, 1, 'Rabid Grizzly - World Loot Level 71'), +(26643, 5, 1200072, 0, 0, 1, 5, 1, 1, 'Rabid Grizzly - World Loot Level 72'), +(26644, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Ursus Mauler - World Loot Level 72'), +(26644, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Ursus Mauler - World Loot Level 73'), +(26646, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Saronite Horror - World Loot Level 73'), +(26646, 2, 1200074, 0, 0, 1, 5, 1, 1, 'Saronite Horror - World Loot Level 74'), +(26655, 1, 1200172, 0, 0, 1, 5, 1, 1, 'High Cultist Zangus - World Loot Level 72'), +(26658, 1, 1200168, 0, 0, 1, 5, 1, 1, 'Reckless Scavenger - World Loot Level 68'), +(26658, 2, 1200169, 0, 0, 1, 5, 1, 1, 'Reckless Scavenger - World Loot Level 69'), +(26663, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Winterskorn Hunter - World Loot Level 69'), +(26663, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Winterskorn Hunter - World Loot Level 70'), +(26667, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Dragonflayer Spectator - World Loot Level 79'), +(26679, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Silverbrook Trapper - World Loot Level 73'), +(26679, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Silverbrook Trapper - World Loot Level 74'), +(26681, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Grumbald One-Eye - World Loot Level 75'), +(26704, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Drakkari Defender - World Loot Level 74'), +(26705, 1, 1200172, 7.5, 0, 1, 5, 1, 1, 'Snowplain Disciple - World Loot Level 72'), +(26705, 2, 1200173, 7.5, 0, 1, 5, 1, 1, 'Snowplain Disciple - World Loot Level 73'), +(26706, 1, 1200074, 0, 0, 1, 5, 1, 1, 'Infected Grizzly Bear - World Loot Level 74'), +(26708, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Silverbrook Villager - World Loot Level 73'), +(26708, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Silverbrook Villager - World Loot Level 74'), +(26762, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Captain Emmy Malin - World Loot Level 72'), +(26769, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Anok\'ra the Manipulator - World Loot Level 72'), +(26770, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Tivax the Breaker - World Loot Level 72'), +(26771, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Sinok the Shadowrager - World Loot Level 72'), +(26786, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Iron Rune Avenger - World Loot Level 74'), +(26786, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Iron Rune Avenger - World Loot Level 75'), +(26795, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Drakkari Oracle - World Loot Level 73'), +(26797, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Drakkari Protector - World Loot Level 73'), +(26806, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Guardian Serpent - World Loot Level 72'), +(26811, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Ancient Drakkari Warmonger - World Loot Level 73'), +(26812, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Ancient Drakkari Soothsayer - World Loot Level 73'), +(26815, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Lieutenant Ta\'zinni - World Loot Level 72'), +(26816, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Focus Wizard - World Loot Level 71'), +(26816, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Focus Wizard - World Loot Level 72'), +(26820, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Iron Rune-Weaver - World Loot Level 75'), +(26823, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Howling Wolvar Trainer - World Loot Level 70'), +(26825, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Howling Wolvar Shaman - World Loot Level 69'), +(26827, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Howling Wolvar Lookout - World Loot Level 69'), +(26872, 1, 1200074, 0, 0, 1, 5, 1, 1, 'Weakened Giant - World Loot Level 74'), +(26891, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Undead Miner - World Loot Level 74'), +(26891, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Undead Miner - World Loot Level 75'), +(26919, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Drak\'aguul - World Loot Level 73'), +(26920, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Overseer Durval - World Loot Level 75'), +(26921, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Overseer Korgan - World Loot Level 75'), +(26922, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Overseer Lochli - World Loot Level 75'), +(26923, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Overseer Brunon - World Loot Level 75'), +(26926, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Duke Vallenhal - World Loot Level 73'), +(26942, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Decrepit Necromancer - World Loot Level 73'), +(26942, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Decrepit Necromancer - World Loot Level 74'), +(26943, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Battered Drakkari Berserker - World Loot Level 74'), +(26946, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Reanimated Drakkari Tribesman - World Loot Level 73'), +(26946, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Reanimated Drakkari Tribesman - World Loot Level 74'), +(26948, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Hulking Atrocity - World Loot Level 74'), +(26965, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Tormented Drakkari - World Loot Level 73'), +(26965, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Tormented Drakkari - World Loot Level 74'), +(27004, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Icefist - World Loot Level 73'), +(27005, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Chilltusk - World Loot Level 73'), +(27020, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Bloodmoon Worgen - World Loot Level 73'), +(27020, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Bloodmoon Worgen - World Loot Level 74'), +(27024, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Bloodmoon Cultist - World Loot Level 73'), +(27024, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Bloodmoon Cultist - World Loot Level 74'), +(27117, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Amberpine Scout - World Loot Level 73'), +(27117, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Amberpine Scout - World Loot Level 74'), +(27118, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Conquest Hold Raider - World Loot Level 73'), +(27118, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Conquest Hold Raider - World Loot Level 74'), +(27131, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Grizzly Bear - World Loot Level 73'), +(27131, 2, 1200074, 0, 0, 1, 5, 1, 1, 'Grizzly Bear - World Loot Level 74'), +(27177, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Iron Rune Overseer - World Loot Level 74'), +(27177, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Iron Rune Overseer - World Loot Level 75'), +(27202, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Onslaught Raven Priest - World Loot Level 71'), +(27202, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Onslaught Raven Priest - World Loot Level 72'), +(27203, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Onslaught Footman - World Loot Level 71'), +(27203, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Onslaught Footman - World Loot Level 72'), +(27206, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Onslaught Knight - World Loot Level 71'), +(27206, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Onslaught Knight - World Loot Level 72'), +(27207, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Onslaught Workman - World Loot Level 71'), +(27207, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Onslaught Workman - World Loot Level 72'), +(27209, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Torturer LeCraft - World Loot Level 72'), +(27211, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Onslaught Executioner - World Loot Level 72'), +(27220, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Forgotten Captain - World Loot Level 72'), +(27220, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Forgotten Captain - World Loot Level 73'), +(27224, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Forgotten Knight - World Loot Level 71'), +(27224, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Forgotten Knight - World Loot Level 72'), +(27225, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Forgotten Rifleman - World Loot Level 71'), +(27225, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Forgotten Rifleman - World Loot Level 72'), +(27226, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Forgotten Peasant - World Loot Level 71'), +(27229, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Forgotten Footman - World Loot Level 71'), +(27229, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Forgotten Footman - World Loot Level 72'), +(27230, 1, 1200074, 0, 0, 1, 5, 1, 1, 'Silvercoat Stag - World Loot Level 74'), +(27230, 2, 1200075, 0, 0, 1, 5, 1, 1, 'Silvercoat Stag - World Loot Level 75'), +(27233, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Onslaught Deckhand - World Loot Level 71'), +(27233, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Onslaught Deckhand - World Loot Level 72'), +(27234, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Blacksmith Goodman - World Loot Level 73'), +(27235, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Lead Cannoneer Zierhut - World Loot Level 73'), +(27236, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Stable Master Mercer - World Loot Level 72'), +(27237, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Commander Jordan - World Loot Level 73'), +(27238, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Foreman Kaleiki - World Loot Level 72'), +(27244, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Emerald Skytalon - World Loot Level 73'), +(27244, 2, 1200074, 0, 0, 1, 5, 1, 1, 'Emerald Skytalon - World Loot Level 74'), +(27246, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Bishop Street - World Loot Level 72'), +(27254, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Emerald Lasher - World Loot Level 73'), +(27254, 2, 1200074, 0, 0, 1, 5, 1, 1, 'Emerald Lasher - World Loot Level 74'), +(27259, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Dragonflayer Flamebinder - World Loot Level 73'), +(27259, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Dragonflayer Flamebinder - World Loot Level 74'), +(27260, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Dragonflayer Huscarl - World Loot Level 73'), +(27260, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Dragonflayer Huscarl - World Loot Level 74'), +(27272, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Risen Villager - World Loot Level 70'), +(27272, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Risen Villager - World Loot Level 71'), +(27278, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Snowplain Zealot - World Loot Level 72'), +(27278, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Snowplain Zealot - World Loot Level 73'), +(27279, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Snowplain Shaman - World Loot Level 72'), +(27279, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Snowplain Shaman - World Loot Level 73'), +(27283, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Risen Wintergarde Mage - World Loot Level 71'), +(27283, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Risen Wintergarde Mage - World Loot Level 72'), +(27284, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Risen Wintergarde Defender - World Loot Level 71'), +(27284, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Risen Wintergarde Defender - World Loot Level 72'), +(27286, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Dreadbone Invader - World Loot Level 72'), +(27287, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Mindless Wight - World Loot Level 72'), +(27288, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Death Knight Champion - World Loot Level 72'), +(27289, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Naxxramas Necrolord - World Loot Level 72'), +(27294, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Tundra Scavenger - World Loot Level 72'), +(27294, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Tundra Scavenger - World Loot Level 73'), +(27329, 1, 1200071, 0, 0, 1, 5, 1, 1, 'Onslaught Bloodhound - World Loot Level 71'), +(27329, 2, 1200072, 0, 0, 1, 5, 1, 1, 'Onslaught Bloodhound - World Loot Level 72'), +(27330, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Onslaught Infantry - World Loot Level 72'), +(27330, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Onslaught Infantry - World Loot Level 73'), +(27332, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Onslaught Scout - World Loot Level 71'), +(27332, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Onslaught Scout - World Loot Level 72'), +(27333, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Onslaught Mason - World Loot Level 72'), +(27333, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Onslaught Mason - World Loot Level 73'), +(27340, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Bloodpaw Marauder - World Loot Level 71'), +(27340, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Bloodpaw Marauder - World Loot Level 72'), +(27342, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Bloodpaw Warrior - World Loot Level 71'), +(27342, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Bloodpaw Warrior - World Loot Level 72'), +(27343, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Bloodpaw Shaman - World Loot Level 71'), +(27343, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Bloodpaw Shaman - World Loot Level 72'), +(27355, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Rothin the Decaying - World Loot Level 75'), +(27356, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Burning Depths Necrolyte - World Loot Level 73'), +(27356, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Burning Depths Necrolyte - World Loot Level 74'), +(27357, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Onslaught Raven Archon - World Loot Level 73'), +(27357, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Onslaught Raven Archon - World Loot Level 74'), +(27358, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Burning Depths Necromancer - World Loot Level 73'), +(27358, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Burning Depths Necromancer - World Loot Level 74'), +(27360, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Smoldering Skeleton - World Loot Level 73'), +(27360, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Smoldering Skeleton - World Loot Level 74'), +(27362, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Smoldering Construct - World Loot Level 73'), +(27362, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Smoldering Construct - World Loot Level 74'), +(27363, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Smoldering Geist - World Loot Level 73'), +(27363, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Smoldering Geist - World Loot Level 74'), +(27367, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Onslaught Death Knight - World Loot Level 73'), +(27367, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Onslaught Death Knight - World Loot Level 74'), +(27370, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Vengeful Geist - World Loot Level 71'), +(27370, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Vengeful Geist - World Loot Level 72'), +(27371, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Synipus - World Loot Level 72'), +(27382, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Deathbringer Revenant - World Loot Level 72'), +(27382, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Deathbringer Revenant - World Loot Level 73'), +(27401, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Risen Wintergarde Miner - World Loot Level 71'), +(27401, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Risen Wintergarde Miner - World Loot Level 72'), +(27408, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Duskhowl Prowler - World Loot Level 72'), +(27408, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Duskhowl Prowler - World Loot Level 73'), +(27410, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Scourge Siegesmith - World Loot Level 72'), +(27416, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Pipthwack - World Loot Level 72'), +(27421, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Fern Feeder Moth - World Loot Level 73'), +(27424, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Conquest Hold Marauder - World Loot Level 73'), +(27424, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Conquest Hold Marauder - World Loot Level 74'), +(27470, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Conquest Hold Grunt - World Loot Level 73'), +(27470, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Conquest Hold Grunt - World Loot Level 74'), +(27493, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Sergeant Bonesnap - World Loot Level 74'), +(27508, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Necrolord Amarion - World Loot Level 72'), +(27523, 1, 1200073, 0, 0, 1, 5, 1, 1, 'Grizzlesnout - World Loot Level 73'), +(27533, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Frigid Geist - World Loot Level 72'), +(27533, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Frigid Geist - World Loot Level 73'), +(27534, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Frigid Ghoul - World Loot Level 71'), +(27534, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Frigid Ghoul - World Loot Level 72'), +(27539, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Frigid Necromancer - World Loot Level 73'), +(27539, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Frigid Necromancer - World Loot Level 74'), +(27545, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Katja - World Loot Level 74'), +(27546, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Silverbrook Hunter - World Loot Level 73'), +(27546, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Silverbrook Hunter - World Loot Level 74'), +(27547, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Vladek - World Loot Level 74'), +(27551, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Enraged Apparition - World Loot Level 71'), +(27551, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Enraged Apparition - World Loot Level 72'), +(27552, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Reanimated Noble - World Loot Level 71'), +(27552, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Reanimated Noble - World Loot Level 72'), +(27554, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Injured Drakkari Refugee - World Loot Level 74'), +(27555, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Drakkari Witch Doctor - World Loot Level 73'), +(27570, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Venture Co. Straggler - World Loot Level 73'), +(27615, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Scourge Deathspeaker - World Loot Level 72'), +(27615, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Scourge Deathspeaker - World Loot Level 73'), +(27617, 1, 1200074, 0, 0, 1, 5, 1, 1, 'River Thresher - World Loot Level 74'), +(27627, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Tatjana - World Loot Level 74'), +(27676, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Silverbrook Defender - World Loot Level 73'), +(27676, 2, 1200174, 0, 0, 1, 5, 1, 1, 'Silverbrook Defender - World Loot Level 74'), +(27680, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Dahlia Suntouch - World Loot Level 75'), +(27699, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Gjalerhorn Scavenger - World Loot Level 70'), +(27699, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Gjalerhorn Scavenger - World Loot Level 71'), +(27701, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Gjalerhorn Worker - World Loot Level 70'), +(27701, 2, 1200171, 0, 0, 1, 5, 1, 1, 'Gjalerhorn Worker - World Loot Level 71'), +(27797, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Tattered Abomination - World Loot Level 73'), +(27799, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Scourge Technician - World Loot Level 72'), +(27799, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Scourge Technician - World Loot Level 73'), +(27800, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Leprous Servant - World Loot Level 71'), +(27805, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Necrolord Horus - World Loot Level 73'), +(27823, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Naxxramas Dreadguard - World Loot Level 72'), +(27823, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Naxxramas Dreadguard - World Loot Level 73'), +(27824, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Naxxramas Shade - World Loot Level 72'), +(27824, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Naxxramas Shade - World Loot Level 73'), +(27826, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Necrolord X\'avius - World Loot Level 73'), +(27830, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Venture Co. Evacuee - World Loot Level 73'), +(27835, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Dreadbone Construct - World Loot Level 72'), +(27835, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Dreadbone Construct - World Loot Level 73'), +(27836, 1, 1200172, 0, 0, 1, 5, 1, 1, 'Wailing Soul - World Loot Level 72'), +(27836, 2, 1200173, 0, 0, 1, 5, 1, 1, 'Wailing Soul - World Loot Level 73'), +(27926, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Thorvald - World Loot Level 70'), +(27927, 1, 1200169, 0, 0, 1, 5, 1, 1, 'Dragonflayer Guardian - World Loot Level 69'), +(27927, 2, 1200170, 0, 0, 1, 5, 1, 1, 'Dragonflayer Guardian - World Loot Level 70'), +(27941, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Drakkari Plague Spreader - World Loot Level 73'), +(28001, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Dreadsaber - World Loot Level 75'), +(28001, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Dreadsaber - World Loot Level 76'), +(28002, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Mangal Crocolisk - World Loot Level 75'), +(28002, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Mangal Crocolisk - World Loot Level 76'), +(28003, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Bittertide Hydra - World Loot Level 75'), +(28003, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Bittertide Hydra - World Loot Level 76'), +(28004, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Goretalon Roc - World Loot Level 75'), +(28004, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Goretalon Roc - World Loot Level 76'), +(28009, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Shardhorn Rhino - World Loot Level 75'), +(28009, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Shardhorn Rhino - World Loot Level 76'), +(28010, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Stranded Thresher - World Loot Level 75'), +(28010, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Stranded Thresher - World Loot Level 76'), +(28011, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Emperor Cobra - World Loot Level 75'), +(28011, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Emperor Cobra - World Loot Level 76'), +(28022, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Carrion Eater - World Loot Level 75'), +(28022, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Carrion Eater - World Loot Level 76'), +(28023, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Rotting Abomination - World Loot Level 75'), +(28023, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Rotting Abomination - World Loot Level 76'), +(28026, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Rampaging Geist - World Loot Level 75'), +(28026, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Rampaging Geist - World Loot Level 76'), +(28034, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Drakkari Snake Handler - World Loot Level 75'), +(28034, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Drakkari Snake Handler - World Loot Level 76'), +(28035, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Priest of Sseratus - World Loot Level 75'), +(28035, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Priest of Sseratus - World Loot Level 76'), +(28036, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Champion of Sseratus - World Loot Level 75'), +(28036, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Champion of Sseratus - World Loot Level 76'), +(28069, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Sholazar Guardian - World Loot Level 77'), +(28069, 2, 1200078, 0, 0, 1, 5, 1, 1, 'Sholazar Guardian - World Loot Level 78'), +(28080, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Frenzyheart Spearbearer - World Loot Level 76'), +(28080, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Frenzyheart Spearbearer - World Loot Level 77'), +(28081, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Frenzyheart Scavenger - World Loot Level 76'), +(28081, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Frenzyheart Scavenger - World Loot Level 77'), +(28083, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Serfex the Reaver - World Loot Level 78'), +(28085, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Sapphire Hive Drone - World Loot Level 75'), +(28085, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Sapphire Hive Drone - World Loot Level 76'), +(28085, 3, 1200077, 0, 0, 1, 5, 1, 1, 'Sapphire Hive Drone - World Loot Level 77'), +(28086, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Sapphire Hive Wasp - World Loot Level 76'), +(28086, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Sapphire Hive Wasp - World Loot Level 77'), +(28087, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Sapphire Hive Queen - World Loot Level 78'), +(28096, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Hardknuckle Charger - World Loot Level 76'), +(28096, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Hardknuckle Charger - World Loot Level 77'), +(28097, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Pitch - World Loot Level 76'), +(28098, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Hardknuckle Forager - World Loot Level 76'), +(28101, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Blighted Corpse - World Loot Level 76'), +(28101, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Blighted Corpse - World Loot Level 77'), +(28108, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Bonescythe Ravager - World Loot Level 75'), +(28108, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Bonescythe Ravager - World Loot Level 76'), +(28109, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Mistwhisper Warrior - World Loot Level 76'), +(28109, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Mistwhisper Warrior - World Loot Level 77'), +(28110, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Mistwhisper Oracle - World Loot Level 76'), +(28110, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Mistwhisper Oracle - World Loot Level 77'), +(28118, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Watery Lord - World Loot Level 76'), +(28123, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Venture Co. Excavator - World Loot Level 75'), +(28123, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Venture Co. Excavator - World Loot Level 76'), +(28124, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Venture Co. Ruffian - World Loot Level 75'), +(28124, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Venture Co. Ruffian - World Loot Level 76'), +(28129, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Longneck Grazer - World Loot Level 75'), +(28129, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Longneck Grazer - World Loot Level 76'), +(28145, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Lurking Basilisk - World Loot Level 75'), +(28145, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Lurking Basilisk - World Loot Level 76'), +(28158, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Withered Argent Footman - World Loot Level 75'), +(28158, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Withered Argent Footman - World Loot Level 76'), +(28186, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Foreman Swindlegrin - World Loot Level 76'), +(28188, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Meatpie - World Loot Level 76'), +(28213, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Hardknuckle Matriarch - World Loot Level 77'), +(28221, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Trapdoor Crawler - World Loot Level 75'), +(28221, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Trapdoor Crawler - World Loot Level 76'), +(28233, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Zul\'Drak Bat - World Loot Level 75'), +(28233, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Zul\'Drak Bat - World Loot Level 76'), +(28246, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Sky Terror - World Loot Level 75'), +(28246, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Sky Terror - World Loot Level 76'), +(28257, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Hath\'ar Necromagus - World Loot Level 75'), +(28257, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Hath\'ar Necromagus - World Loot Level 76'), +(28258, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Hath\'ar Skimmer - World Loot Level 75'), +(28258, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Hath\'ar Skimmer - World Loot Level 76'), +(28268, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Scourged Argent Footman - World Loot Level 75'), +(28268, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Scourged Argent Footman - World Loot Level 76'), +(28288, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Farunn - World Loot Level 76'), +(28297, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Shango - World Loot Level 76'), +(28303, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Drakkari Water Binder - World Loot Level 75'), +(28303, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Drakkari Water Binder - World Loot Level 76'), +(28323, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Mossy Rampager - World Loot Level 75'), +(28323, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Mossy Rampager - World Loot Level 76'), +(28345, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Drakkari Spirit - World Loot Level 75'), +(28345, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Drakkari Spirit - World Loot Level 76'), +(28373, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Cultist Infiltrator - World Loot Level 76'), +(28373, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Cultist Infiltrator - World Loot Level 77'), +(28378, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Primordial Drake - World Loot Level 76'), +(28378, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Primordial Drake - World Loot Level 77'), +(28379, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Shattertusk Mammoth - World Loot Level 76'), +(28379, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Shattertusk Mammoth - World Loot Level 77'), +(28380, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Shattertusk Bull - World Loot Level 76'), +(28380, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Shattertusk Bull - World Loot Level 77'), +(28381, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Shattertusk Calf - World Loot Level 76'), +(28388, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Jin\'Alai Warrior - World Loot Level 76'), +(28388, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Jin\'Alai Warrior - World Loot Level 77'), +(28402, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Claw of Har\'koa - World Loot Level 76'), +(28402, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Claw of Har\'koa - World Loot Level 77'), +(28403, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Har\'koan Subduer - World Loot Level 76'), +(28403, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Har\'koan Subduer - World Loot Level 77'), +(28404, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Cursed Offspring of Har\'koa - World Loot Level 76'), +(28404, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Cursed Offspring of Har\'koa - World Loot Level 77'), +(28411, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Frozen Earth - World Loot Level 76'), +(28411, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Frozen Earth - World Loot Level 77'), +(28412, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Hath\'ar Broodmaster - World Loot Level 75'), +(28412, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Hath\'ar Broodmaster - World Loot Level 76'), +(28414, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Drakkari Captive - World Loot Level 75'), +(28414, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Drakkari Captive - World Loot Level 76'), +(28417, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Priest of Rhunok - World Loot Level 76'), +(28417, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Priest of Rhunok - World Loot Level 77'), +(28418, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Drakkari Bear Trapper - World Loot Level 76'), +(28418, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Drakkari Bear Trapper - World Loot Level 77'), +(28442, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Prophet of Rhunok - World Loot Level 77'), +(28465, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Heb\'Drakkar Striker - World Loot Level 76'), +(28465, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Heb\'Drakkar Striker - World Loot Level 77'), +(28494, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Kutube\'sa - World Loot Level 77'), +(28495, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Gawanil - World Loot Level 77'), +(28496, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Chulo the Mad - World Loot Level 77'), +(28504, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Jin\'Alai Medicine Man - World Loot Level 76'), +(28504, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Jin\'Alai Medicine Man - World Loot Level 77'), +(28519, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Withered Troll - World Loot Level 74'), +(28519, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Withered Troll - World Loot Level 75'), +(28538, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Cultist Saboteur - World Loot Level 76'), +(28538, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Cultist Saboteur - World Loot Level 77'), +(28564, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Putrid Abomination - World Loot Level 74'), +(28564, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Putrid Abomination - World Loot Level 75'), +(28565, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Decaying Ghoul - World Loot Level 75'), +(28565, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Decaying Ghoul - World Loot Level 76'), +(28575, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Rhunok\'s Tormentor - World Loot Level 77'), +(28600, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Heb\'Drakkar Headhunter - World Loot Level 76'), +(28600, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Heb\'Drakkar Headhunter - World Loot Level 77'), +(28602, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Death\'s Hand Acolyte - World Loot Level 77'), +(28602, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Death\'s Hand Acolyte - World Loot Level 78'), +(28603, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Blightguard - World Loot Level 74'), +(28603, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Blightguard - World Loot Level 75'), +(28641, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Blighted Corpse - World Loot Level 76'), +(28641, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Blighted Corpse - World Loot Level 77'), +(28750, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Blight Geist - World Loot Level 74'), +(28750, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Blight Geist - World Loot Level 75'), +(28759, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Flying Fiend - World Loot Level 75'), +(28759, 2, 1200076, 0, 0, 1, 5, 1, 1, 'Flying Fiend - World Loot Level 76'), +(28779, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Blood of Mam\'toth - World Loot Level 76'), +(28779, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Blood of Mam\'toth - World Loot Level 77'), +(28802, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Servant of Drakuru - World Loot Level 75'), +(28802, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Servant of Drakuru - World Loot Level 76'), +(28803, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Drakuru\'s Guard - World Loot Level 75'), +(28803, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Drakuru\'s Guard - World Loot Level 76'), +(28843, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Bloated Abomination - World Loot Level 75'), +(28843, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Bloated Abomination - World Loot Level 76'), +(28847, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Siltslither Eel - World Loot Level 76'), +(28847, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Siltslither Eel - World Loot Level 77'), +(28848, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Prophet of Har\'koa - World Loot Level 77'), +(28851, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Enraged Mammoth - World Loot Level 76'), +(28851, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Enraged Mammoth - World Loot Level 77'), +(28858, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Storm Revenant - World Loot Level 79'), +(28858, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Storm Revenant - World Loot Level 80'), +(28861, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Mam\'toth Disciple - World Loot Level 76'), +(28861, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Mam\'toth Disciple - World Loot Level 77'), +(28862, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Aqueous Spirit - World Loot Level 79'), +(28862, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Aqueous Spirit - World Loot Level 80'), +(28877, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Stormwatcher - World Loot Level 80'), +(28882, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Enchanted Tiki Warrior - World Loot Level 76'), +(28882, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Enchanted Tiki Warrior - World Loot Level 77'), +(28916, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Tiri - World Loot Level 77'), +(28917, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Yara - World Loot Level 77'), +(28918, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Drek\'Maz - World Loot Level 77'), +(28988, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Akali Subduer - World Loot Level 76'), +(28988, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Akali Subduer - World Loot Level 77'), +(29013, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Perch Guardian - World Loot Level 77'), +(29013, 2, 1200078, 0, 0, 1, 5, 1, 1, 'Perch Guardian - World Loot Level 78'), +(29036, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Servant of Freya - World Loot Level 76'), +(29036, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Servant of Freya - World Loot Level 77'), +(29123, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Monstrous Wight - World Loot Level 75'), +(29123, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Monstrous Wight - World Loot Level 76'), +(29124, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Lifeblood Elemental - World Loot Level 76'), +(29129, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Lost Drakkari Spirit - World Loot Level 75'), +(29129, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Lost Drakkari Spirit - World Loot Level 76'), +(29133, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Disturbed Soul - World Loot Level 75'), +(29133, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Disturbed Soul - World Loot Level 76'), +(29211, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Drakkari Native - World Loot Level 75'), +(29211, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Drakkari Native - World Loot Level 76'), +(29235, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Gundrak Savage - World Loot Level 76'), +(29235, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Gundrak Savage - World Loot Level 77'), +(29236, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Gundrak Brute - World Loot Level 76'), +(29236, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Gundrak Brute - World Loot Level 77'), +(29237, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Gundrak Fire-eater - World Loot Level 76'), +(29237, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Gundrak Fire-eater - World Loot Level 77'), +(29319, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Icepaw Bear - World Loot Level 76'), +(29319, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Icepaw Bear - World Loot Level 77'), +(29323, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Sifreldar Storm Maiden - World Loot Level 78'), +(29323, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Sifreldar Storm Maiden - World Loot Level 79'), +(29327, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Frost Leopard - World Loot Level 76'), +(29327, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Frost Leopard - World Loot Level 77'), +(29329, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Onslaught Paladin - World Loot Level 79'), +(29329, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Onslaught Paladin - World Loot Level 80'), +(29330, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Onslaught Harbor Guard - World Loot Level 79'), +(29330, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Onslaught Harbor Guard - World Loot Level 80'), +(29331, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Sifreldar Runekeeper - World Loot Level 79'), +(29331, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Sifreldar Runekeeper - World Loot Level 80'), +(29332, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Gundrak Bat Rider - World Loot Level 76'), +(29332, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Gundrak Bat Rider - World Loot Level 77'), +(29333, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Onslaught Gryphon Rider - World Loot Level 79'), +(29333, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Onslaught Gryphon Rider - World Loot Level 80'), +(29334, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Gundrak Raptor - World Loot Level 76'), +(29334, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Gundrak Raptor - World Loot Level 77'), +(29338, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Onslaught Raven Bishop - World Loot Level 79'), +(29338, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Onslaught Raven Bishop - World Loot Level 80'), +(29369, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Stormforged Taskmaster - World Loot Level 78'), +(29369, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Stormforged Taskmaster - World Loot Level 79'), +(29370, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Stormforged Champion - World Loot Level 79'), +(29374, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Stormforged Magus - World Loot Level 78'), +(29374, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Stormforged Magus - World Loot Level 79'), +(29376, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Stormforged Artificer - World Loot Level 78'), +(29376, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Stormforged Artificer - World Loot Level 79'), +(29377, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Stormforged Raider - World Loot Level 78'), +(29377, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Stormforged Raider - World Loot Level 79'), +(29380, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Stormforged War Golem - World Loot Level 79'), +(29380, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Stormforged War Golem - World Loot Level 80'), +(29382, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Stormforged Reaver - World Loot Level 79'), +(29382, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Stormforged Reaver - World Loot Level 80'), +(29389, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Mechagnome Laborer - World Loot Level 78'), +(29389, 2, 1200079, 0, 0, 1, 5, 1, 1, 'Mechagnome Laborer - World Loot Level 79'), +(29390, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Snowdrift Jormungar - World Loot Level 79'), +(29390, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Snowdrift Jormungar - World Loot Level 80'), +(29392, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Ravenous Jaws - World Loot Level 79'), +(29392, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Ravenous Jaws - World Loot Level 80'), +(29402, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Ironwool Mammoth - World Loot Level 77'), +(29402, 2, 1200078, 0, 0, 1, 5, 1, 1, 'Ironwool Mammoth - World Loot Level 78'), +(29404, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Savage Hill Scavenger - World Loot Level 77'), +(29404, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Savage Hill Scavenger - World Loot Level 78'), +(29407, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Snowblind Devotee - World Loot Level 76'), +(29407, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Snowblind Devotee - World Loot Level 77'), +(29409, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Garm Watcher - World Loot Level 77'), +(29409, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Garm Watcher - World Loot Level 78'), +(29411, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Crystalweb Weaver - World Loot Level 77'), +(29411, 2, 1200078, 0, 0, 1, 5, 1, 1, 'Crystalweb Weaver - World Loot Level 78'), +(29412, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Crystalweb Spitter - World Loot Level 77'), +(29412, 2, 1200078, 0, 0, 1, 5, 1, 1, 'Crystalweb Spitter - World Loot Level 78'), +(29413, 1, 1200176, 0, 0, 1, 5, 1, 1, 'Snowblind Digger - World Loot Level 76'), +(29413, 2, 1200177, 0, 0, 1, 5, 1, 1, 'Snowblind Digger - World Loot Level 77'), +(29426, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Hyldnir Overseer - World Loot Level 79'), +(29426, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Hyldnir Overseer - World Loot Level 80'), +(29427, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Captive Vrykul - World Loot Level 79'), +(29427, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Captive Vrykul - World Loot Level 80'), +(29436, 1, 1200074, 0, 0, 1, 5, 1, 1, 'Icetouched Earthrager - World Loot Level 74'), +(29436, 2, 1200075, 0, 0, 1, 5, 1, 1, 'Icetouched Earthrager - World Loot Level 75'), +(29449, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Vargul Deathwaker - World Loot Level 75'), +(29449, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Vargul Deathwaker - World Loot Level 76'), +(29450, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Vargul Runelord - World Loot Level 75'), +(29450, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Vargul Runelord - World Loot Level 76'), +(29451, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Vargul Slayer - World Loot Level 75'), +(29451, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Vargul Slayer - World Loot Level 76'), +(29452, 1, 1200074, 0, 0, 1, 5, 1, 1, 'Vargul Blighthound - World Loot Level 74'), +(29452, 2, 1200075, 0, 0, 1, 5, 1, 1, 'Vargul Blighthound - World Loot Level 75'), +(29453, 1, 1200074, 0, 0, 1, 5, 1, 1, 'Vargul Plaguetalon - World Loot Level 74'), +(29453, 2, 1200075, 0, 0, 1, 5, 1, 1, 'Vargul Plaguetalon - World Loot Level 75'), +(29461, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Icetip Crawler - World Loot Level 78'), +(29469, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Ice Steppe Rhino - World Loot Level 78'), +(29469, 2, 1200079, 0, 0, 1, 5, 1, 1, 'Ice Steppe Rhino - World Loot Level 79'), +(29479, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Shoveltusk Forager - World Loot Level 69'), +(29486, 1, 1200069, 0, 0, 1, 5, 1, 1, 'Tamed Shoveltusk - World Loot Level 69'), +(29487, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Wild Shoveltusk - World Loot Level 68'), +(29498, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Brunnhildar Warmaiden - World Loot Level 80'), +(29504, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Seething Revenant - World Loot Level 80'), +(29518, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Overseer Syra - World Loot Level 79'), +(29554, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Snowblind Devotee - World Loot Level 76'), +(29554, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Snowblind Devotee - World Loot Level 77'), +(29559, 1, 1200068, 0, 0, 1, 5, 1, 1, 'Lion Seal Whelp - World Loot Level 68'), +(29559, 2, 1200069, 0, 0, 1, 5, 1, 1, 'Lion Seal Whelp - World Loot Level 69'), +(29562, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Icemaw Bear - World Loot Level 79'), +(29562, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Icemaw Bear - World Loot Level 80'), +(29569, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Valkyrion Aspirant - World Loot Level 79'), +(29569, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Valkyrion Aspirant - World Loot Level 80'), +(29570, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Nascent Val\'kyr - World Loot Level 79'), +(29570, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Nascent Val\'kyr - World Loot Level 80'), +(29586, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Stormforged Pillager - World Loot Level 78'), +(29586, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Stormforged Pillager - World Loot Level 79'), +(29590, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Blighted Proto-Drake - World Loot Level 80'), +(29592, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Brijana - World Loot Level 80'), +(29605, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Ravenous Jormungar - World Loot Level 79'), +(29605, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Ravenous Jormungar - World Loot Level 80'), +(29622, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Savage Hill Mystic - World Loot Level 77'), +(29622, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Savage Hill Mystic - World Loot Level 78'), +(29623, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Savage Hill Brute - World Loot Level 77'), +(29623, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Savage Hill Brute - World Loot Level 78'), +(29624, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Stormrider - World Loot Level 79'), +(29624, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Stormrider - World Loot Level 80'), +(29646, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Banshee Soulclaimer - World Loot Level 75'), +(29646, 2, 1200176, 0, 0, 1, 5, 1, 1, 'Banshee Soulclaimer - World Loot Level 76'), +(29652, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Stormforged Tracker - World Loot Level 78'), +(29652, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Stormforged Tracker - World Loot Level 79'), +(29654, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Drakuru Blood Drinker - World Loot Level 74'), +(29654, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Drakuru Blood Drinker - World Loot Level 75'), +(29656, 1, 1200175, 0, 0, 1, 5, 1, 1, 'Drakuru Berserker - World Loot Level 75'), +(29693, 1, 1200072, 0, 0, 1, 5, 1, 1, 'Serpent Defender - World Loot Level 72'), +(29693, 2, 1200073, 0, 0, 1, 5, 1, 1, 'Serpent Defender - World Loot Level 73'), +(29695, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Tracker Thulin - World Loot Level 79'), +(29697, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Drakuru Prophet - World Loot Level 74'), +(29697, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Drakuru Prophet - World Loot Level 75'), +(29698, 1, 1200074, 0, 0, 1, 5, 1, 1, 'Drakuru Raptor - World Loot Level 74'), +(29698, 2, 1200075, 0, 0, 1, 5, 1, 1, 'Drakuru Raptor - World Loot Level 75'), +(29699, 1, 1200174, 0, 0, 1, 5, 1, 1, 'Drakuru Raptor Rider - World Loot Level 74'), +(29699, 2, 1200175, 0, 0, 1, 5, 1, 1, 'Drakuru Raptor Rider - World Loot Level 75'), +(29717, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Shadow Cultist - World Loot Level 79'), +(29717, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Shadow Cultist - World Loot Level 80'), +(29719, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Morbid Carcass - World Loot Level 79'), +(29719, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Morbid Carcass - World Loot Level 80'), +(29720, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Vault Geist - World Loot Level 79'), +(29720, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Vault Geist - World Loot Level 80'), +(29722, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Rabid Cannibal - World Loot Level 79'), +(29722, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Rabid Cannibal - World Loot Level 80'), +(29724, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Library Guardian - World Loot Level 78'), +(29724, 2, 1200079, 0, 0, 1, 5, 1, 1, 'Library Guardian - World Loot Level 79'), +(29738, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Death Knight Master - World Loot Level 79'), +(29738, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Death Knight Master - World Loot Level 80'), +(29755, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Stormpeak Hatchling - World Loot Level 80'), +(29792, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Frostfeather Screecher - World Loot Level 78'), +(29792, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Frostfeather Screecher - World Loot Level 79'), +(29793, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Frostfeather Witch - World Loot Level 78'), +(29793, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Frostfeather Witch - World Loot Level 79'), +(29808, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Stormcrest Hatchling - World Loot Level 77'), +(29834, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Drakkari Frenzy - World Loot Level 77'), +(29843, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Stormforged Loreseeker - World Loot Level 78'), +(29843, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Stormforged Loreseeker - World Loot Level 79'), +(29844, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Icebound Revenant - World Loot Level 78'), +(29844, 2, 1200079, 0, 0, 1, 5, 1, 1, 'Icebound Revenant - World Loot Level 79'), +(29844, 3, 1200080, 0, 0, 1, 5, 1, 1, 'Icebound Revenant - World Loot Level 80'), +(29861, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Stormforged Eradicator - World Loot Level 79'), +(29862, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Stormforged Monitor - World Loot Level 78'), +(29862, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Stormforged Monitor - World Loot Level 79'), +(29874, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Drakkari Inciter - World Loot Level 77'), +(29875, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Icemane Yeti - World Loot Level 79'), +(29875, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Icemane Yeti - World Loot Level 80'), +(29880, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Jotunheim Warrior - World Loot Level 79'), +(29880, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Jotunheim Warrior - World Loot Level 80'), +(29958, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Tundra Ram - World Loot Level 79'), +(29958, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Tundra Ram - World Loot Level 80'), +(30003, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Gnarlhide - World Loot Level 77'), +(30003, 2, 1200078, 0, 0, 1, 5, 1, 1, 'Gnarlhide - World Loot Level 78'), +(30037, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Mjordin Combatant - World Loot Level 79'), +(30037, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Mjordin Combatant - World Loot Level 80'), +(30040, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Eternal Watcher - World Loot Level 80'), +(30046, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Yulda the Stormspeaker - World Loot Level 80'), +(30135, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Restless Frostborn Warrior - World Loot Level 78'), +(30135, 2, 1200079, 0, 0, 1, 5, 1, 1, 'Restless Frostborn Warrior - World Loot Level 79'), +(30146, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Exhausted Vrykul - World Loot Level 78'), +(30146, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Exhausted Vrykul - World Loot Level 79'), +(30146, 3, 1200180, 0, 0, 1, 5, 1, 1, 'Exhausted Vrykul - World Loot Level 80'), +(30147, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Garhal - World Loot Level 79'), +(30147, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Garhal - World Loot Level 80'), +(30148, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Infesting Jormungar - World Loot Level 80'), +(30164, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Cavedweller Worg - World Loot Level 79'), +(30164, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Cavedweller Worg - World Loot Level 80'), +(30167, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Gimorak - World Loot Level 79'), +(30167, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Gimorak - World Loot Level 80'), +(30184, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Scion of Storm - World Loot Level 79'), +(30184, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Scion of Storm - World Loot Level 80'), +(30202, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Reanimated Crusader - World Loot Level 77'), +(30202, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Reanimated Crusader - World Loot Level 78'), +(30204, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Forgotten Depths Ambusher - World Loot Level 77'), +(30204, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Forgotten Depths Ambusher - World Loot Level 78'), +(30205, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Forgotten Depths Acolyte - World Loot Level 77'), +(30205, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Forgotten Depths Acolyte - World Loot Level 78'), +(30206, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Carrion Fleshstripper - World Loot Level 76'), +(30206, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Carrion Fleshstripper - World Loot Level 77'), +(30243, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Njorndar Spear-Sister - World Loot Level 79'), +(30243, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Njorndar Spear-Sister - World Loot Level 80'), +(30250, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Valhalas Vargul - World Loot Level 79'), +(30250, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Valhalas Vargul - World Loot Level 80'), +(30333, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Forgotten Depths Slayer - World Loot Level 77'), +(30333, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Forgotten Depths Slayer - World Loot Level 78'), +(30387, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Seething Revenant - World Loot Level 80'), +(30430, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Sentry Worg - World Loot Level 77'), +(30430, 2, 1200078, 0, 0, 1, 5, 1, 1, 'Sentry Worg - World Loot Level 78'), +(30445, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Ice Steppe Bull - World Loot Level 78'), +(30445, 2, 1200079, 0, 0, 1, 5, 1, 1, 'Ice Steppe Bull - World Loot Level 79'), +(30447, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Romping Rhino - World Loot Level 78'), +(30447, 2, 1200079, 0, 0, 1, 5, 1, 1, 'Romping Rhino - World Loot Level 79'), +(30448, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Plains Mammoth - World Loot Level 77'), +(30448, 2, 1200078, 0, 0, 1, 5, 1, 1, 'Plains Mammoth - World Loot Level 78'), +(30450, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Wailing Winds - World Loot Level 79'), +(30450, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Wailing Winds - World Loot Level 80'), +(30482, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Wrathstrike Gargoyle - World Loot Level 77'), +(30482, 2, 1200078, 0, 0, 1, 5, 1, 1, 'Wrathstrike Gargoyle - World Loot Level 78'), +(30541, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Forgotten Depths Underking - World Loot Level 78'), +(30543, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Forgotten Depths High Priest - World Loot Level 77'), +(30543, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Forgotten Depths High Priest - World Loot Level 78'), +(30597, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Spiked Ghoul - World Loot Level 80'), +(30632, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Mjordin Water Magus - World Loot Level 79'), +(30632, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Mjordin Water Magus - World Loot Level 80'), +(30687, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Skeletal Constructor - World Loot Level 80'), +(30689, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Chained Abomination - World Loot Level 80'), +(30701, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Vile Creeper - World Loot Level 79'), +(30725, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Jotunheim Sleep-Watcher - World Loot Level 79'), +(30725, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Jotunheim Sleep-Watcher - World Loot Level 80'), +(30746, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Master Summoner Zarod - World Loot Level 80'), +(30751, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Kul\'galar Oracle - World Loot Level 79'), +(30751, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Kul\'galar Oracle - World Loot Level 80'), +(30842, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Wandering Shadow - World Loot Level 80'), +(30845, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Living Lasher - World Loot Level 80'), +(30846, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Glacial Spirit - World Loot Level 80'), +(30847, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Raging Flame - World Loot Level 80'), +(30848, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Whispering Wind - World Loot Level 80'), +(30849, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Chilled Earth Elemental - World Loot Level 80'), +(30856, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Unbound Trickster - World Loot Level 78'), +(30856, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Unbound Trickster - World Loot Level 79'), +(30860, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Unbound Dryad - World Loot Level 78'), +(30860, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Unbound Dryad - World Loot Level 79'), +(30862, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Unbound Ent - World Loot Level 77'), +(30862, 2, 1200078, 0, 0, 1, 5, 1, 1, 'Unbound Ent - World Loot Level 78'), +(30863, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Shandaral Druid Spirit - World Loot Level 78'), +(30863, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Shandaral Druid Spirit - World Loot Level 79'), +(30864, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Shandaral Hunter Spirit - World Loot Level 78'), +(30864, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Shandaral Hunter Spirit - World Loot Level 79'), +(30865, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Shandaral Warrior Spirit - World Loot Level 78'), +(30865, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Shandaral Warrior Spirit - World Loot Level 79'), +(30868, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Unbound Corrupter - World Loot Level 78'), +(30868, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Unbound Corrupter - World Loot Level 79'), +(30872, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Shadow Revenant - World Loot Level 80'), +(30873, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Flame Revenant - World Loot Level 80'), +(30875, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Tempest Revenant - World Loot Level 80'), +(30876, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Earthbound Revenant - World Loot Level 80'), +(30877, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Water Revenant - World Loot Level 80'), +(30894, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Lithe Stalker - World Loot Level 80'), +(30920, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Lumbering Atrocity - World Loot Level 80'), +(30921, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Skeletal Runesmith - World Loot Level 80'), +(30922, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Umbral Brute - World Loot Level 80'), +(30931, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Drakkari Inciter (1) - World Loot Level 80'), +(30931, 2, 1200181, 0, 0, 1, 5, 1, 1, 'Drakkari Inciter (1) - World Loot Level 81'), +(30949, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Risen Laborer - World Loot Level 80'), +(30951, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Restless Lookout - World Loot Level 80'), +(30952, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Hungering Plaguehound - World Loot Level 80'), +(30957, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Death Knight Initiate - World Loot Level 80'), +(30958, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Death Knight Initiate - World Loot Level 80'), +-- (30960, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Risen Soldier - World Loot Level 80'), +(30988, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Scourgebeak Fleshripper - World Loot Level 80'), +(31037, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Forgotten Depths High Priest - World Loot Level 77'), +(31037, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Forgotten Depths High Priest - World Loot Level 78'), +(31039, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Forgotten Depths Underking - World Loot Level 78'), +(31041, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Dispirited Ent - World Loot Level 76'), +(31041, 2, 1200077, 0, 0, 1, 5, 1, 1, 'Dispirited Ent - World Loot Level 77'), +(31042, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Death Knight Adept - World Loot Level 80'), +(31043, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Reanimated Crusader - World Loot Level 77'), +(31043, 2, 1200178, 0, 0, 1, 5, 1, 1, 'Reanimated Crusader - World Loot Level 78'), +(31123, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Shandaral Spirit Wolf - World Loot Level 78'), +(31123, 2, 1200079, 0, 0, 1, 5, 1, 1, 'Shandaral Spirit Wolf - World Loot Level 79'), +(31140, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Hulking Abomination - World Loot Level 80'), +(31145, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Shadow Adept - World Loot Level 80'), +(31147, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Vicious Geist - World Loot Level 80'), +(31150, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Plagued Fiend - World Loot Level 80'), +(31152, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Undying Minion - World Loot Level 80'), +(31155, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Malefic Necromancer - World Loot Level 80'), +(31228, 1, 1200077, 0, 0, 1, 5, 1, 1, 'Grove Walker - World Loot Level 77'), +(31228, 2, 1200078, 0, 0, 1, 5, 1, 1, 'Grove Walker - World Loot Level 78'), +(31231, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Lost Shandaral Spirit - World Loot Level 78'), +(31231, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Lost Shandaral Spirit - World Loot Level 79'), +(31233, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Sinewy Wolf - World Loot Level 78'), +(31236, 1, 1200076, 0, 0, 1, 5, 1, 1, 'Dappled Stag - World Loot Level 76'), +(31258, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Ymirheim Chosen Warrior - World Loot Level 80'), +(31263, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Carrion Hunter - World Loot Level 80'), +(31265, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Savage Proto-Drake - World Loot Level 80'), +(31267, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Ymirjar Element Shaper - World Loot Level 80'), +(31396, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Val\'kyr Taskmistress - World Loot Level 80'), +(31401, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Azure Manashaper - World Loot Level 79'), +(31401, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Azure Manashaper - World Loot Level 80'), +(31402, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Azure Scalebane - World Loot Level 79'), +(31402, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Azure Scalebane - World Loot Level 80'), +(31403, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Azure Spellweaver - World Loot Level 79'), +(31403, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Azure Spellweaver - World Loot Level 80'), +(31404, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Azure Manabeast - World Loot Level 78'), +(31404, 2, 1200079, 0, 0, 1, 5, 1, 1, 'Azure Manabeast - World Loot Level 79'), +(31411, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Hulking Horror - World Loot Level 79'), +(31411, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Hulking Horror - World Loot Level 80'), +(31554, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Restless Lookout - World Loot Level 80'), +(31718, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Frostbrood Whelp - World Loot Level 80'), +(31731, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Wyrm Reanimator - World Loot Level 80'), +(31738, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Cultist Corrupter - World Loot Level 80'), +(31746, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Ymirheim Defender - World Loot Level 80'), +(31754, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Glacial Bonelord - World Loot Level 80'), +(31779, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Skeletal Archmage - World Loot Level 80'), +(31783, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Vrykul Necrolord - World Loot Level 80'), +(31787, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Citadel Watcher - World Loot Level 79'), +(31787, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Citadel Watcher - World Loot Level 80'), +(31843, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Reanimated Miner - World Loot Level 78'), +(31843, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Reanimated Miner - World Loot Level 79'), +(31847, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Scavenging Geist - World Loot Level 79'), +(31847, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Scavenging Geist - World Loot Level 80'), +(31853, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Cruel Overseer - World Loot Level 80'), +(31900, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Scourge Banner-Bearer - World Loot Level 80'), +(32149, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Fallen Hero\'s Spirit - World Loot Level 79'), +(32164, 1, 1200178, 0, 0, 1, 5, 1, 1, 'Skeletal Craftsman - World Loot Level 78'), +(32164, 2, 1200179, 0, 0, 1, 5, 1, 1, 'Skeletal Craftsman - World Loot Level 79'), +(32236, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Dark Subjugator - World Loot Level 80'), +(32238, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Bitter Initiate - World Loot Level 80'), +(32250, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Overseer Faedris - World Loot Level 80'), +(32255, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Converted Hero - World Loot Level 80'), +(32257, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Scourge Converter - World Loot Level 80'), +(32259, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Void Summoner - World Loot Level 79'), +(32259, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Void Summoner - World Loot Level 80'), +(32260, 1, 1200078, 0, 0, 1, 5, 1, 1, 'Enslaved Minion - World Loot Level 78'), +(32260, 2, 1200079, 0, 0, 1, 5, 1, 1, 'Enslaved Minion - World Loot Level 79'), +(32262, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Shadow Channeler - World Loot Level 79'), +(32262, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Shadow Channeler - World Loot Level 80'), +(32263, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Overseer Veraj - World Loot Level 80'), +(32268, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Cult Taskmaster - World Loot Level 79'), +(32268, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Cult Taskmaster - World Loot Level 80'), +(32276, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Cult Blackguard - World Loot Level 79'), +(32276, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Cult Blackguard - World Loot Level 80'), +(32279, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Vile Torturer - World Loot Level 79'), +(32279, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Vile Torturer - World Loot Level 80'), +(32284, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Scourge Soulbinder - World Loot Level 80'), +(32285, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Overseer Jhaeqon - World Loot Level 79'), +(32285, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Overseer Jhaeqon - World Loot Level 80'), +(32289, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Damned Apothecary - World Loot Level 79'), +(32289, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Damned Apothecary - World Loot Level 80'), +(32290, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Cult Alchemist - World Loot Level 79'), +(32290, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Cult Alchemist - World Loot Level 80'), +(32291, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Overseer Savryn - World Loot Level 80'), +(32297, 1, 1200179, 0, 0, 1, 5, 1, 1, 'Cult Researcher - World Loot Level 79'), +(32297, 2, 1200180, 0, 0, 1, 5, 1, 1, 'Cult Researcher - World Loot Level 80'), +(32349, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Cultist Shard Watcher - World Loot Level 80'), +(32507, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Cultist Acolyte - World Loot Level 80'), +(32572, 1, 1200171, 0, 0, 1, 5, 1, 1, 'Dragonblight Mage Hunter - World Loot Level 71'), +(32572, 2, 1200172, 0, 0, 1, 5, 1, 1, 'Dragonblight Mage Hunter - World Loot Level 72'), +(34838, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Kvaldir Reaver - World Loot Level 79'), +(34838, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Kvaldir Reaver - World Loot Level 80'), +(34839, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Kvaldir Mist Binder - World Loot Level 79'), +(34839, 2, 1200080, 0, 0, 1, 5, 1, 1, 'Kvaldir Mist Binder - World Loot Level 80'); + +-- SELECT +-- `Reference`, +-- COUNT(*) AS `Occurrences`, +-- MIN(`Chance`) AS `MinChance`, +-- MAX(`Chance`) AS `MaxChance`, +-- -- Optional: If your core has comments in this table, show one to help ID it +-- MAX(`Comment`) AS `SampleComment` +-- FROM +-- `creature_loot_template` +-- WHERE +-- `Entry` IN ( /* ... */ ) +-- AND `Reference` < 1000000 +-- GROUP BY +-- `Reference` +-- ORDER BY +-- `Occurrences` DESC; + +-- Now for the cleanup +-- Loose Items +DELETE FROM `creature_loot_template` +WHERE `Item` IN (33358,33359,33360,33361,33362,33363,33364,33372,33373,33374,33375,33376,33377,33378,33390,33391,33392,33393,33394,33395,33396,33404,33405,33406,33407,33408,33409,33410,33422,33423,33424,33425,33426,33427,33428,33429,33430,33431,33437,33438,33439,33440,33365,33366,33367,33368,33369,33370,33371,33379,33380,33381,33382,33383,33384,33385,33397,33398,33399,33400,33401,33402,33403,33412,33413,33414,33415,33416,33417,33419,33433,33434,33435,33436,35955,35956,35957,35958,35959,35960,35961,35962,36067,36068,36069,36070,36071,36072,36073,36074,36179,36180,36181,36182,36183,36184,36185,36186,36291,36292,36293,36294,36295,36296,36297,36298,36403,36417,36431,36445,36459,36473,36487,36501,36515,36529,36543,36557,36571,36585,36599,36613,36627,36641,36655,36669,36683,36697,36711,35963,35964,35965,35966,35967,35968,35969,35970,36075,36076,36077,36078,36079,36080,36081,36082,36187,36188,36189,36190,36191,36192,36193,36194,36299,36300,36301,36302,36303,36304,36305,36306,36404,36418,36432,36446,36460,36474,36488,36502,36516,36530,36544,36558,36572,36586,36600,36614,36628,36642,36656,36670,36684,36698,36712,35971,35972,35973,35974,35975,35976,35977,35978,36083,36084,36085,36086,36087,36088,36089,36090,36195,36196,36197,36198,36199,36200,36201,36202,36307,36308,36309,36310,36311,36312,36313,36314,36405,36419,36433,36447,36461,36475,36489,36503,36517,36531,36545,36559,36573,36587,36601,36615,36629,36643,36657,36671,36685,36699,36713,35979,35980,35981,35982,35983,35984,35985,35986,36091,36092,36093,36094,36095,36096,36097,36098,36203,36204,36205,36206,36207,36208,36209,36210,36315,36316,36317,36318,36319,36320,36321,36322,36406,36420,36434,36448,36462,36476,36490,36504,36518,36532,36546,36560,36574,36588,36602,36616,36630,36644,36658,36672,36686,36700,36714,35987,35988,35989,35990,35991,35992,35993,35994,36099,36100,36101,36102,36103,36104,36105,36106,36211,36212,36213,36214,36215,36216,36217,36218,36323,36324,36325,36326,36327,36328,36329,36330,36407,36421,36435,36449,36463,35995,35996,35997,35998,35999,36000,36001,36002,36107,36108,36109,36110,36111,36112,36113,36114,36219,36220,36221,36222,36223,36224,36225,36226,36331,36332,36333,36334,36335,36336,36337,36338,36408,36422,36436,36450,36464,36478,36492,36506,36520,36534,36548,36562,36576,36590,36604,36618,36632,36646,36660,36674,36688,36702,36716,36003,36004,36005,36006,36007,36008,36009,36010,36115,36116,36117,36118,36119,36120,36121,36122,36227,36228,36229,36230,36231,36232,36233,36234,36339,36340,36341,36342,36343,36344,36345,36346,36409,36423,36437,36451,36465,36479,36493,36507,36521,36535,36549,36563,36577,36591,36605,36619,36633,36647,36661,36675,36689,36703,36717,36011,36012,36013,36014,36015,36016,36017,36018,36123,36124,36125,36126,36127,36128,36129,36130,36235,36236,36237,36238,36239,36240,36241,36242,36347,36348,36349,36350,36351,36352,36353,36354,36410,36424,36438,36452,36466,36480,36494,36508,36522,36536,36550,36564,36578,36592,36606,36620,36634,36648,36662,36676,36690,36704,36718,36019,36020,36021,36022,36023,36024,36025,36026,36131,36132,36133,36134,36135,36136,36137,36138,36243,36244,36245,36246,36247,36248,36249,36250,36355,36356,36357,36358,36359,36360,36361,36362,36411,36425,36439,36453,36467,36481,36495,36509,36523,36537,36551,36565,36579,36593,36607,36621,36635,36649,36663,36677,36691,36705,36719,36027,36028,36029,36030,36031,36032,36033,36034,36139,36140,36141,36142,36143,36144,36145,36146,36251,36252,36253,36254,36255,36256,36257,36258,36363,36364,36365,36366,36367,36368,36369,36370,36412,36426,36440,36468,36482,36496,36510,36524,36538,36552,36566,36580,36594,36608,36622,36636,36650,36664,36678,36692,36706,36720,36035,36036,36037,36038,36039,36040,36041,36042,36147,36148,36149,36150,36151,36152,36153,36154,36259,36260,36261,36262,36263,36264,36265,36266,36371,36372,36373,36374,36375,36376,36377,36378,36413,36427,36441,36455,36469,36483,36497,36511,36525,36539,36553,36567,36581,36595,36609,36623,36637,36651,36665,36679,36693,36707,36721,36043,36044,36045,36046,36047,36048,36049,36050,36155,36156,36157,36158,36159,36160,36161,36162,36267,36268,36269,36270,36271,36272,36273,36274,36379,36380,36381,36382,36383,36384,36385,36386,36414,36428,36442,36456,36470,36484,36498,36512,36526,36540,36554,36568,36582,36596,36610,36624,36638,36652,36666,36680,36694,36708,36722,36051,36052,36053,36054,36055,36056,36057,36058,36163,36164,36165,36166,36167,36168,36169,36170,36275,36276,36277,36278,36279,36280,36281,36282,36387,36388,36389,36390,36391,36392,36393,36394,36415,36429,36443,36457,36471,36485,36499,36513,36527,36541,36555,36569,36583,36597,36611,36625,36639,36653,36667,36681,36695,36709,36723,36059,36060,36061,36062,36063,36064,36065,36066,36171,36172,36173,36174,36175,36176,36177,36178,36283,36284,36285,36286,36287,36288,36289,36290,36395,36396,36397,36398,36399,36400,36401,36402,36416,36430,36444,36458,36472,36486,36500,36514,36528,36542,36556,36570,36584,36598,36612,36626,36640,36654,36668,36682,36696,36710,36724,37743,37744,37745,37746,37747,37748,37749,37751,37752,37762,37772,37782,37753,37763,37773,37783,37803,37819,37754,37764,37774,37795,37796,37820,37755,37775,37785,37802,37811,37817,37756,37765,37776,37786,37807,37821,37757,37766,37777,37787,37805,37813,37758,37767,37778,37789,37804,37810,37812,37759,37768,37790,37806,37808,37809,37769,37779,37792,37797,37823,37760,37770,37780,37793,37822,37761,37771,37781,37794,37824,37254,37835,43573,44308,44309,44310,44311,44312,44313,22829,22832,37091,37093,37097,43463,43465,43467,33447,33448,43507,43508,43509,43510,43622,43876,39152,41777,41778,41779,41780,41781,41782,41783,41784,41785,41786,41787,41788,41789,42172,42173,42175,42176,42177,42178,43297,43624,45912,33470) +AND `Entry` IN (5936,23643,23644,23645,23651,23652,23653,23654,23655,23656,23657,23658,23660,23661,23662,23663,23664,23665,23666,23667,23668,23669,23670,23672,23673,23674,23675,23676,23677,23678,23680,23688,23689,23690,23691,23711,23740,23744,23750,23760,23772,23785,23793,23794,23796,23809,23866,23871,23874,23875,23883,23886,23887,23919,23929,23931,23932,23934,23940,23945,23946,23958,23959,23963,23964,23967,23983,23989,23990,23991,23992,23994,24013,24014,24015,24016,24026,24030,24073,24076,24116,24128,24160,24161,24162,24169,24173,24178,24206,24212,24213,24214,24215,24216,24228,24229,24249,24250,24262,24271,24277,24285,24286,24287,24316,24334,24340,24459,24460,24461,24475,24478,24485,24516,24517,24533,24540,24546,24562,24563,24566,24567,24601,24613,24614,24628,24633,24635,24637,24638,24642,24644,24673,24676,24677,24681,24713,24747,24779,24785,24786,24787,24788,24789,24791,24797,24846,24863,24871,24872,24899,24901,24957,25026,25203,25204,25209,25211,25215,25216,25217,25224,25226,25227,25294,25316,25350,25351,25353,25355,25378,25383,25386,25387,25392,25393,25396,25415,25417,25419,25427,25428,25429,25430,25432,25433,25434,25445,25448,25449,25452,25454,25464,25467,25468,25470,25479,25481,25482,25487,25489,25496,25498,25501,25514,25520,25521,25522,25523,25582,25585,25600,25605,25609,25611,25613,25615,25619,25622,25623,25650,25651,25660,25668,25675,25680,25684,25685,25686,25687,25699,25700,25701,25707,25709,25713,25715,25717,25718,25719,25721,25722,25728,25743,25748,25750,25752,25753,25758,25760,25788,25791,25792,25793,25800,25803,25806,25814,25817,25836,25839,25843,25880,25968,25979,25981,26073,26076,26103,26115,26126,26165,26174,26196,26197,26198,26199,26201,26202,26252,26257,26266,26268,26270,26271,26272,26273,26280,26281,26283,26284,26295,26316,26319,26322,26334,26336,26343,26344,26347,26348,26349,26356,26357,26358,26359,26363,26366,26369,26370,26389,26402,26405,26407,26408,26409,26410,26411,26413,26414,26416,26418,26421,26425,26426,26428,26434,26436,26446,26447,26449,26451,26455,26457,26461,26467,26472,26480,26481,26482,26483,26492,26493,26496,26511,26521,26522,26536,26544,26575,26577,26586,26592,26605,26606,26613,26615,26616,26643,26644,26646,26655,26658,26663,26667,26679,26681,26704,26705,26706,26708,26762,26769,26770,26771,26786,26795,26797,26806,26811,26812,26815,26816,26820,26823,26825,26827,26872,26891,26919,26920,26921,26922,26923,26926,26942,26943,26946,26948,26965,27004,27005,27020,27024,27117,27118,27131,27177,27202,27203,27206,27207,27209,27211,27220,27224,27225,27226,27229,27230,27233,27234,27235,27236,27237,27238,27244,27246,27254,27259,27260,27272,27278,27279,27283,27284,27286,27287,27288,27289,27294,27329,27330,27332,27333,27340,27342,27343,27355,27356,27357,27358,27360,27362,27363,27367,27370,27371,27382,27401,27408,27410,27416,27421,27424,27470,27493,27508,27523,27533,27534,27539,27545,27546,27547,27551,27552,27554,27555,27570,27615,27617,27627,27676,27680,27699,27701,27797,27799,27800,27805,27823,27824,27826,27830,27835,27836,27926,27927,27941,28001,28002,28003,28004,28009,28010,28011,28022,28023,28026,28034,28035,28036,28069,28080,28081,28083,28085,28086,28087,28096,28097,28098,28101,28108,28109,28110,28118,28123,28124,28129,28145,28158,28186,28188,28213,28221,28233,28246,28257,28258,28268,28288,28297,28303,28323,28345,28373,28378,28379,28380,28381,28388,28402,28403,28404,28411,28412,28414,28417,28418,28442,28465,28494,28495,28496,28504,28519,28538,28564,28565,28575,28600,28602,28603,28641,28750,28759,28779,28802,28803,28843,28847,28848,28851,28858,28861,28862,28877,28882,28916,28917,28918,28988,29013,29036,29123,29124,29129,29133,29211,29235,29236,29237,29319,29323,29327,29329,29330,29331,29332,29333,29334,29338,29369,29370,29374,29376,29377,29380,29382,29389,29390,29392,29402,29404,29407,29409,29411,29412,29413,29426,29427,29436,29449,29450,29451,29452,29453,29461,29469,29479,29486,29487,29498,29504,29518,29554,29559,29562,29569,29570,29586,29590,29592,29605,29622,29623,29624,29646,29652,29654,29656,29693,29695,29697,29698,29699,29717,29719,29720,29722,29724,29738,29755,29792,29793,29808,29834,29843,29844,29861,29862,29874,29875,29880,29958,30003,30037,30040,30046,30135,30146,30147,30148,30164,30167,30184,30202,30204,30205,30206,30243,30250,30333,30387,30430,30445,30447,30448,30450,30482,30541,30543,30597,30632,30687,30689,30701,30725,30746,30751,30842,30845,30846,30847,30848,30849,30856,30860,30862,30863,30864,30865,30868,30872,30873,30875,30876,30877,30894,30920,30921,30922,30931,30949,30951,30952,30957,30958,30960,30988,31037,31039,31041,31042,31043,31123,31140,31145,31147,31150,31152,31155,31228,31231,31233,31236,31258,31263,31265,31267,31396,31401,31402,31403,31404,31411,31554,31718,31731,31738,31746,31754,31779,31783,31787,31843,31847,31853,31900,32149,32164,32236,32238,32250,32255,32257,32259,32260,32262,32263,32268,32276,32279,32284,32285,32289,32290,32291,32297,32349,32507,32572,34838,34839); +-- Delete Legacy References +DELETE FROM `creature_loot_template` WHERE +`Entry` IN (5936,23643,23644,23645,23651,23652,23653,23654,23655,23656,23657,23658,23660,23661,23662,23663,23664,23665,23666,23667,23668,23669,23670,23672,23673,23674,23675,23676,23677,23678,23680,23688,23689,23690,23691,23711,23740,23744,23750,23760,23772,23785,23793,23794,23796,23809,23866,23871,23874,23875,23883,23886,23887,23919,23929,23931,23932,23934,23940,23945,23946,23958,23959,23963,23964,23967,23983,23989,23990,23991,23992,23994,24013,24014,24015,24016,24026,24030,24073,24076,24116,24128,24160,24161,24162,24169,24173,24178,24206,24212,24213,24214,24215,24216,24228,24229,24249,24250,24262,24271,24277,24285,24286,24287,24316,24334,24340,24459,24460,24461,24475,24478,24485,24516,24517,24533,24540,24546,24562,24563,24566,24567,24601,24613,24614,24628,24633,24635,24637,24638,24642,24644,24673,24676,24677,24681,24713,24747,24779,24785,24786,24787,24788,24789,24791,24797,24846,24863,24871,24872,24899,24901,24957,25026,25203,25204,25209,25211,25215,25216,25217,25224,25226,25227,25294,25316,25350,25351,25353,25355,25378,25383,25386,25387,25392,25393,25396,25415,25417,25419,25427,25428,25429,25430,25432,25433,25434,25445,25448,25449,25452,25454,25464,25467,25468,25470,25479,25481,25482,25487,25489,25496,25498,25501,25514,25520,25521,25522,25523,25582,25585,25600,25605,25609,25611,25613,25615,25619,25622,25623,25650,25651,25660,25668,25675,25680,25684,25685,25686,25687,25699,25700,25701,25707,25709,25713,25715,25717,25718,25719,25721,25722,25728,25743,25748,25750,25752,25753,25758,25760,25788,25791,25792,25793,25800,25803,25806,25814,25817,25836,25839,25843,25880,25968,25979,25981,26073,26076,26103,26115,26126,26165,26174,26196,26197,26198,26199,26201,26202,26252,26257,26266,26268,26270,26271,26272,26273,26280,26281,26283,26284,26295,26316,26319,26322,26334,26336,26343,26344,26347,26348,26349,26356,26357,26358,26359,26363,26366,26369,26370,26389,26402,26405,26407,26408,26409,26410,26411,26413,26414,26416,26418,26421,26425,26426,26428,26434,26436,26446,26447,26449,26451,26455,26457,26461,26467,26472,26480,26481,26482,26483,26492,26493,26496,26511,26521,26522,26536,26544,26575,26577,26586,26592,26605,26606,26613,26615,26616,26643,26644,26646,26655,26658,26663,26667,26679,26681,26704,26705,26706,26708,26762,26769,26770,26771,26786,26795,26797,26806,26811,26812,26815,26816,26820,26823,26825,26827,26872,26891,26919,26920,26921,26922,26923,26926,26942,26943,26946,26948,26965,27004,27005,27020,27024,27117,27118,27131,27177,27202,27203,27206,27207,27209,27211,27220,27224,27225,27226,27229,27230,27233,27234,27235,27236,27237,27238,27244,27246,27254,27259,27260,27272,27278,27279,27283,27284,27286,27287,27288,27289,27294,27329,27330,27332,27333,27340,27342,27343,27355,27356,27357,27358,27360,27362,27363,27367,27370,27371,27382,27401,27408,27410,27416,27421,27424,27470,27493,27508,27523,27533,27534,27539,27545,27546,27547,27551,27552,27554,27555,27570,27615,27617,27627,27676,27680,27699,27701,27797,27799,27800,27805,27823,27824,27826,27830,27835,27836,27926,27927,27941,28001,28002,28003,28004,28009,28010,28011,28022,28023,28026,28034,28035,28036,28069,28080,28081,28083,28085,28086,28087,28096,28097,28098,28101,28108,28109,28110,28118,28123,28124,28129,28145,28158,28186,28188,28213,28221,28233,28246,28257,28258,28268,28288,28297,28303,28323,28345,28373,28378,28379,28380,28381,28388,28402,28403,28404,28411,28412,28414,28417,28418,28442,28465,28494,28495,28496,28504,28519,28538,28564,28565,28575,28600,28602,28603,28641,28750,28759,28779,28802,28803,28843,28847,28848,28851,28858,28861,28862,28877,28882,28916,28917,28918,28988,29013,29036,29123,29124,29129,29133,29211,29235,29236,29237,29319,29323,29327,29329,29330,29331,29332,29333,29334,29338,29369,29370,29374,29376,29377,29380,29382,29389,29390,29392,29402,29404,29407,29409,29411,29412,29413,29426,29427,29436,29449,29450,29451,29452,29453,29461,29469,29479,29486,29487,29498,29504,29518,29554,29559,29562,29569,29570,29586,29590,29592,29605,29622,29623,29624,29646,29652,29654,29656,29693,29695,29697,29698,29699,29717,29719,29720,29722,29724,29738,29755,29792,29793,29808,29834,29843,29844,29861,29862,29874,29875,29880,29958,30003,30037,30040,30046,30135,30146,30147,30148,30164,30167,30184,30202,30204,30205,30206,30243,30250,30333,30387,30430,30445,30447,30448,30450,30482,30541,30543,30597,30632,30687,30689,30701,30725,30746,30751,30842,30845,30846,30847,30848,30849,30856,30860,30862,30863,30864,30865,30868,30872,30873,30875,30876,30877,30894,30920,30921,30922,30931,30949,30951,30952,30957,30958,30960,30988,31037,31039,31041,31042,31043,31123,31140,31145,31147,31150,31152,31155,31228,31231,31233,31236,31258,31263,31265,31267,31396,31401,31402,31403,31404,31411,31554,31718,31731,31738,31746,31754,31779,31783,31787,31843,31847,31853,31900,32149,32164,32236,32238,32250,32255,32257,32259,32260,32262,32263,32268,32276,32279,32284,32285,32289,32290,32291,32297,32349,32507,32572,34838,34839) +AND `Reference` IN ( +26001, -- Occurrences: 785, Grey Loot +26000, -- Occurrences: 559, Grey Loot +24727, -- Occurrences: 523, Scrolls +26040, -- Occurrences: 521, Frostweave Cloth +26004, -- Occurrences: 312, Green Loot +26002, -- Occurrences: 298, Grey Loot +26005, -- Occurrences: 297, Green Loot +26006, -- Occurrences: 281, Green Loot +26008, -- Occurrences: 268, Green Loot +26003, -- Occurrences: 240, Green Loot +26007, -- Occurrences: 217, Green Loot +26013, -- Occurrences: 191, Green Loot +26009, -- Occurrences: 178, Green Loot +26012, -- Occurrences: 169, Green Loot +26010, -- Occurrences: 162, Green Loot +26011, -- Occurrences: 158, Green Loot +26018, -- Occurrences: 156, Blue Loot +26014, -- Occurrences: 147, Green Loot +26019, -- Occurrences: 139, Blue Loot +26017, -- Occurrences: 131, Blue Loot +26015, -- Occurrences: 111, Green Loot +26020, -- Occurrences: 110, Blue Loot +26021, -- Occurrences: 96, Blue Loot +26023, -- Occurrences: 68, Blue Loot +26022, -- Occurrences: 65, Blue Loot +26024, -- Occurrences: 55, Blue Loot +26028, -- Occurrences: 44, Blue Loot +26025, -- Occurrences: 36, Blue Loot +26027, -- Occurrences: 28, Blue Loot +26026, -- Occurrences: 27, 77-79 Blue Loot +26042, -- Occurrences: 5, Cooking Recipes +35080, -- Occurrences: 2, 78-80 Green Loot +35074 -- Occurrences: 1, Purple Loot +); + +-- Loot not found in new system: +-- 41608 Cloak of Frozen Spirits: Profession Item +-- That's it + +-- Remove now deprecated references +DELETE FROM `reference_loot_template` WHERE `Entry` IN (26026, 26027, 26042); + +-- Delete Conditions that we don't need anymore +DELETE FROM `conditions` +WHERE `SourceGroup` IN (23643,23643,23644,23644,23645,23645,23645,23651,23651,23651,23651,23652,23652,23652,23652,23653,23653,23653,23653,23654,23654,23654,23654,23655,23655,23655,23655,23656,23656,23656,23656,23657,23657,23657,23657,23658,23658,23658,23658,23660,23660,23660,23660,23661,23661,23661,23661,23662,23662,23662,23662,23663,23663,23663,23663,23664,23664,23664,23664,23665,23665,23665,23665,23666,23666,23666,23666,23667,23668,23668,23668,23669,23669,23669,23670,23672,23672,23672,23673,23673,23674,23674,23674,23674,23675,23675,23675,23676,23676,23676,23676,23678,23678,23678,23678,23711,23711,23711,23711,23760,23760,23760,23760,23793,23793,23793,23793,23794,23794,23794,23794,23796,23866,23866,23866,23866,23871,23871,23871,23871,23875,23875,23931,23932,23932,23934,23934,23934,23940,23940,23940,23940,23946,23946,23946,23946,23967,23967,23967,23967,23989,23989,23989,23989,23990,23990,23990,23990,23991,23991,23991,23991,23992,23992,24013,24013,24013,24013,24014,24014,24014,24014,24015,24015,24015,24015,24016,24030,24030,24030,24030,24073,24073,24073,24073,24116,24116,24161,24161,24162,24169,24169,24212,24212,24212,24212,24213,24213,24213,24214,24214,24214,24214,24215,24216,24216,24216,24216,24249,24249,24249,24249,24250,24250,24250,24250,24286,24286,24286,24286,24334,24334,24485,24485,24485,24485,24540,24540,24540,24540,24546,24562,24562,24562,24562,24567,24567,24567,24567,24635,24635,24635,24635,24638,24638,24638,24642,24642,24644,24644,24676,24676,24676,24676,24713,24713,24779,24779,24779,24789,24789,24846,24871,24871,24871,24871,24872,24872,24872,24872,24957,24957,24957,24957,25026,25026,25026,25026,25026,25026,25209,25209,25209,25227,25227,25227,25227,25294,25294,25294,25294,25316,25316,25316,25316,25316,25350,25350,25350,25350,25351,25351,25351,25351,25353,25353,25353,25353,25378,25378,25378,25378,25383,25383,25383,25383,25386,25386,25386,25386,25392,25392,25393,25393,25393,25393,25396,25396,25396,25396,25428,25428,25428,25428,25429,25429,25429,25429,25430,25430,25430,25432,25432,25432,25432,25433,25433,25433,25433,25434,25434,25434,25434,25448,25448,25448,25449,25449,25449,25449,25467,25467,25467,25467,25468,25468,25470,25470,25470,25470,25479,25479,25479,25479,25496,25496,25496,25496,25501,25520,25520,25520,25521,25521,25521,25521,25522,25522,25522,25522,25523,25523,25523,25523,25605,25605,25605,25605,25609,25609,25609,25609,25611,25611,25611,25611,25613,25613,25613,25613,25615,25615,25615,25615,25619,25619,25650,25650,25650,25650,25651,25651,25651,25651,25660,25660,25660,25660,25668,25684,25684,25684,25684,25713,25713,25713,25719,25719,25719,25719,25760,25760,25760,25760,25800,25800,25800,25803,25803,25803,25806,25806,25806,25806,25836,25836,25836,25836,25839,25839,25839,25839,25843,25843,25843,25843,25880,25880,25880,25880,25979,25979,25979,25979,25981,25981,25981,25981,26073,26076,26076,26076,26103,26103,26103,26103,26115,26115,26115,26126,26126,26126,26126,26165,26196,26197,26197,26197,26197,26198,26198,26198,26198,26199,26199,26199,26199,26201,26201,26202,26202,26202,26202,26252,26252,26257,26257,26257,26257,26266,26266,26268,26268,26268,26268,26268,26270,26270,26280,26280,26280,26280,26280,26280,26319,26319,26319,26336,26336,26336,26336,26343,26343,26343,26343,26344,26344,26344,26344,26356,26356,26356,26356,26357,26357,26357,26389,26389,26389,26389,26408,26408,26408,26409,26410,26411,26411,26413,26414,26416,26425,26428,26447,26447,26447,26447,26449,26451,26451,26451,26451,26455,26455,26455,26455,26457,26457,26461,26480,26480,26480,26481,26481,26492,26492,26493,26493,26496,26544,26575,26577,26605,26605,26605,26605,26606,26606,26606,26606,26655,26655,26658,26658,26658,26658,26679,26704,26704,26704,26705,26762,26762,26769,26770,26771,26771,26786,26786,26795,26795,26795,26797,26797,26811,26811,26812,26815,26816,26816,26816,26816,26820,26820,26820,26823,26825,26827,26827,26827,26891,26891,26919,26921,26922,26923,26926,26942,26942,26948,26948,26965,26965,27004,27005,27020,27020,27024,27024,27024,27024,27118,27118,27118,27177,27177,27202,27202,27202,27202,27203,27203,27203,27203,27206,27206,27206,27206,27206,27206,27207,27207,27209,27220,27220,27224,27224,27225,27225,27225,27225,27226,27226,27226,27226,27229,27229,27229,27229,27233,27233,27233,27233,27235,27237,27259,27259,27259,27259,27260,27260,27260,27260,27272,27278,27278,27278,27278,27279,27279,27283,27284,27284,27284,27284,27284,27284,27286,27286,27286,27287,27287,27288,27288,27330,27330,27330,27330,27332,27332,27332,27333,27333,27333,27340,27342,27342,27343,27343,27356,27356,27356,27357,27357,27358,27358,27358,27358,27360,27360,27360,27360,27362,27362,27362,27363,27363,27363,27363,27367,27370,27370,27370,27370,27401,27401,27401,27401,27410,27410,27410,27410,27424,27424,27470,27533,27533,27539,27539,27539,27539,27546,27551,27551,27552,27552,27552,27552,27554,27554,27676,27680,27699,27699,27699,27699,27701,27701,27797,27797,27797,27799,27800,27823,27823,27824,27826,27826,27830,27830,27835,27835,27836,27926,27927,27927,27941,27941,27941,28004,28011,28022,28022,28022,28023,28023,28026,28026,28026,28035,28035,28036,28036,28036,28036,28036,28080,28080,28080,28080,28081,28101,28108,28108,28108,28123,28123,28123,28123,28124,28124,28124,28129,28158,28158,28188,28257,28257,28257,28257,28268,28303,28303,28303,28303,28373,28373,28373,28388,28388,28388,28388,28402,28402,28402,28403,28403,28403,28412,28412,28412,28414,28414,28417,28417,28418,28418,28465,28465,28465,28494,28495,28496,28504,28504,28504,28504,28504,28519,28519,28538,28538,28538,28564,28565,28565,28575,28600,28600,28602,28602,28603,28641,28641,28802,28861,28916,28917,28988,28988,29123,29129,29129,29133,29211,29211,29211,29235,29236,29237,29323,29323,29329,29329,29330,29330,29331,29333,29338,29369,29370,29377,29404,29404,29407,29407,29409,29413,29413,29449,29450,29450,29450,29451,29451,29451,29451,29554,29569,29569,29586,29586,29622,29623,29646,29646,29652,29652,29654,29654,29654,29654,29656,29656,29656,29656,29656,29697,29697,29699,29699,29699,29699,29717,29719,29720,29724,29792,29793,29834,29843,29875,29880,29880,29880,30037,30202,30202,30202,30202,30202,30202,30204,30205,30250,30250,30333,30333,30430,30447,30448,30543,30687,30689,30701,30701,30701,30725,30746,30845,30856,30860,30860,30863,30865,30894,30920,30921,30951,30951,31140,31140,31150,31152,31231,31258,31396,31402,31403,31718,31738,31746,31746,31754,31779,31847,32255,32259,32259,32276,32289,32289,32289,32290,32297,32349,32507,32572,32572,32572) +AND `SourceTypeOrReferenceId` = 1 +AND `SourceEntry` IN (43507, 43508, 43509, 43510, 43876, 42178, 39152, 42176, 42172, 42177, 42173, 42175); + +/* Maps + * 574 Utgarde Keep + * 601 Azjol'Nerub + * 619 Ahn'kahet: The Old Kingdom + * 576 The Nexus + * 600 Drak'Tharon Keep + * 604 Gundrak + * 599 Halls of Stone + * 602 Halls of Lightning + * 578 The Oculus + * 575 Utgarde Pinnacle + * 595 The Culling of Stratholme + * 632 The Forge of Souls + * 658 Pit of Saron + */ + -- These should not have loot + DELETE FROM `creature_loot_template` WHERE (`Entry` IN (26667, 30767, 26536, 30791, 28733, 31605, 29834, 30928)); + UPDATE `creature_template` SET `lootid` = 0 WHERE (`entry` IN (26667, 30767, 26536, 30791, 28733, 31605, 29834, 30928)); + -- Detach Normal and Heroic Loot + -- With Cloth +DELETE FROM `creature_loot_template` WHERE (`Entry` = 24084); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(24084, 33444, 0, 3, 0, 1, 2, 1, 1, 'Tunneling Ghoul - Pungent Seal Whey'), +(24084, 33452, 0, 6, 0, 1, 2, 1, 1, 'Tunneling Ghoul - Honey-Spiced Lichen'), +(24084, 42108, 0, 33, 1, 1, 0, 1, 1, 'Tunneling Ghoul - Scourge Curio'), +(24084, 43851, 0, 15, 0, 1, 0, 1, 1, 'Tunneling Ghoul - Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 31681 WHERE (`entry` = 31681); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 31681); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(31681, 33444, 0, 3, 0, 1, 2, 1, 1, 'Tunneling Ghoul - Pungent Seal Whey'), +(31681, 33452, 0, 6, 0, 1, 2, 1, 1, 'Tunneling Ghoul - Honey-Spiced Lichen'), +(31681, 42108, 0, 33, 1, 1, 0, 1, 1, 'Tunneling Ghoul - Scourge Curio'), +(31681, 43851, 0, 15, 0, 1, 0, 1, 1, 'Tunneling Ghoul - Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26716); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26716, 33444, 0, 3, 0, 1, 1, 1, 1, 'Azure Warder - Pungent Seal Whey'), +(26716, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Warder - Salted Venison'), +(26716, 43852, 0, 10, 0, 1, 0, 1, 1, 'Azure Warder - Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 30459 WHERE (`entry` = 30459); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30459); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30459, 33444, 0, 3, 0, 1, 1, 1, 1, 'Azure Warder - Pungent Seal Whey'), +(30459, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Warder - Salted Venison'), +(30459, 43852, 0, 10, 0, 1, 0, 1, 1, 'Azure Warder - Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26722); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26722, 33444, 0, 3, 0, 1, 1, 1, 1, 'Azure Magus - Pungent Seal Whey'), +(26722, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Magus - Salted Venison'), +(26722, 43852, 0, 10, 0, 1, 0, 1, 1, 'Azure Magus - Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 30457 WHERE (`entry` = 30457); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30457); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30457, 33444, 0, 3, 0, 1, 1, 1, 1, 'Azure Magus - Pungent Seal Whey'), +(30457, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Magus - Salted Venison'), +(30457, 43852, 0, 10, 0, 1, 0, 1, 1, 'Azure Magus - Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26727); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26727, 33444, 0, 3, 0, 1, 1, 1, 1, 'Mage Hunter Ascendant - Pungent Seal Whey'), +(26727, 33454, 0, 6, 0, 1, 1, 1, 1, 'Mage Hunter Ascendant - Salted Venison'), +(26727, 43852, 0, 10, 0, 1, 0, 1, 1, 'Mage Hunter Ascendant - Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 30460 WHERE (`entry` = 30460); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30460); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30460, 33444, 0, 3, 0, 1, 1, 1, 1, 'Mage Hunter Ascendant - Pungent Seal Whey'), +(30460, 33454, 0, 6, 0, 1, 1, 1, 1, 'Mage Hunter Ascendant - Salted Venison'), +(30460, 43852, 0, 10, 0, 1, 0, 1, 1, 'Mage Hunter Ascendant - Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26728); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26728, 33444, 0, 3, 0, 1, 1, 1, 1, 'Mage Hunter Initiate - Pungent Seal Whey'), +(26728, 33454, 0, 6, 0, 1, 1, 1, 1, 'Mage Hunter Initiate - Salted Venison'), +(26728, 43852, 0, 10, 0, 1, 0, 1, 1, 'Mage Hunter Initiate - Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 30478 WHERE (`entry` = 30478); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30478); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30478, 33444, 0, 3, 0, 1, 1, 1, 1, 'Mage Hunter Initiate - Pungent Seal Whey'), +(30478, 33454, 0, 6, 0, 1, 1, 1, 1, 'Mage Hunter Initiate - Salted Venison'), +(30478, 43852, 0, 10, 0, 1, 0, 1, 1, 'Mage Hunter Initiate - Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26729); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26729, 33444, 0, 3, 0, 1, 1, 1, 1, 'Steward - Pungent Seal Whey'), +(26729, 33454, 0, 6, 0, 1, 1, 1, 1, 'Steward - Salted Venison'), +(26729, 43852, 0, 10, 0, 1, 0, 1, 1, 'Steward - Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 30485 WHERE (`entry` = 30485); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30485); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30485, 33444, 0, 3, 0, 1, 1, 1, 1, 'Steward - Pungent Seal Whey'), +(30485, 33454, 0, 6, 0, 1, 1, 1, 1, 'Steward - Salted Venison'), +(30485, 43852, 0, 10, 0, 1, 0, 1, 1, 'Steward - Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26734); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26734, 33444, 0, 3, 0, 1, 1, 1, 1, 'Azure Enforcer - Pungent Seal Whey'), +(26734, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Enforcer - Salted Venison'), +(26734, 43852, 0, 10, 0, 1, 0, 1, 1, 'Azure Enforcer - Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 30516 WHERE (`entry` = 30516); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30516); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30516, 33444, 0, 3, 0, 1, 1, 1, 1, 'Azure Enforcer - Pungent Seal Whey'), +(30516, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Enforcer - Salted Venison'), +(30516, 43852, 0, 10, 0, 1, 0, 1, 1, 'Azure Enforcer - Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26735); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26735, 33444, 0, 3, 0, 1, 1, 1, 1, 'Azure Scale-Binder - Pungent Seal Whey'), +(26735, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Scale-Binder - Salted Venison'), +(26735, 43852, 0, 10, 0, 1, 0, 1, 1, 'Azure Scale-Binder - Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 30517 WHERE (`entry` = 30517); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30517); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30517, 33444, 0, 3, 0, 1, 1, 1, 1, 'Azure Scale-Binder - Pungent Seal Whey'), +(30517, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Scale-Binder - Salted Venison'), +(30517, 43852, 0, 10, 0, 1, 0, 1, 1, 'Azure Scale-Binder - Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26800); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26800, 33454, 0, 6, 0, 1, 1, 1, 1, 'Salted Venison'), +(26800, 33444, 0, 3, 0, 1, 1, 1, 1, 'Pungent Seal Whey'), +(26800, 43852, 0, 10, 0, 1, 0, 1, 1, 'Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 30496 WHERE (`entry` = 30496); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30496); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30496, 33454, 0, 6, 0, 1, 1, 1, 1, 'Salted Venison'), +(30496, 33444, 0, 3, 0, 1, 1, 1, 1, 'Pungent Seal Whey'), +(30496, 43852, 0, 10, 0, 1, 0, 1, 1, 'Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26802); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26802, 33454, 0, 6, 0, 1, 1, 1, 1, 'Salted Venison'), +(26802, 33444, 0, 3, 0, 1, 1, 1, 1, 'Pungent Seal Whey'), +(26802, 43852, 0, 10, 0, 1, 0, 1, 1, 'Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 30509 WHERE (`entry` = 30509); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30509); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30509, 33454, 0, 6, 0, 1, 1, 1, 1, 'Salted Venison'), +(30509, 33444, 0, 3, 0, 1, 1, 1, 1, 'Pungent Seal Whey'), +(30509, 43852, 0, 10, 0, 1, 0, 1, 1, 'Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26805); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26805, 33454, 0, 6, 0, 1, 1, 1, 1, 'Salted Venison'), +(26805, 33444, 0, 3, 0, 1, 1, 1, 1, 'Pungent Seal Whey'), +(26805, 43852, 0, 10, 0, 1, 0, 1, 1, 'Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 30498 WHERE (`entry` = 30498); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30498); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30498, 33454, 0, 6, 0, 1, 1, 1, 1, 'Salted Venison'), +(30498, 33444, 0, 3, 0, 1, 1, 1, 1, 'Pungent Seal Whey'), +(30498, 43852, 0, 10, 0, 1, 0, 1, 1, 'Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 27966); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(27966, 33445, 0, 3, 0, 1, 1, 1, 1, 'Dark Rune Controller - Honeymint Tea'), +(27966, 33454, 0, 6, 0, 1, 1, 1, 1, 'Dark Rune Controller - Salted Venison'), +(27966, 43852, 0, 15, 0, 1, 0, 1, 1, 'Dark Rune Controller - Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 31371 WHERE (`entry` = 31371); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 31371); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(31371, 33445, 0, 3, 0, 1, 1, 1, 1, 'Dark Rune Controller - Honeymint Tea'), +(31371, 33454, 0, 6, 0, 1, 1, 1, 1, 'Dark Rune Controller - Salted Venison'), +(31371, 43852, 0, 15, 0, 1, 0, 1, 1, 'Dark Rune Controller - Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 28419); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(28419, 33444, 0, 3, 0, 1, 1, 1, 1, 'Frenzied Geist - Pungent Seal Whey'), +(28419, 33452, 0, 6, 0, 1, 1, 1, 1, 'Frenzied Geist - Honey-Spiced Lichen'), +(28419, 42108, 0, 33, 1, 1, 0, 1, 1, 'Frenzied Geist - Scourge Curio'), +(28419, 43851, 0, 50, 0, 1, 0, 1, 1, 'Frenzied Geist - Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 31671 WHERE (`entry` = 31671); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 31671); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(31671, 33444, 0, 3, 0, 1, 1, 1, 1, 'Frenzied Geist - Pungent Seal Whey'), +(31671, 33452, 0, 6, 0, 1, 1, 1, 1, 'Frenzied Geist - Honey-Spiced Lichen'), +(31671, 42108, 0, 33, 1, 1, 0, 1, 1, 'Frenzied Geist - Scourge Curio'), +(31671, 43851, 0, 50, 0, 1, 0, 1, 1, 'Frenzied Geist - Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 29920); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(29920, 33454, 0, 6, 0, 1, 1, 1, 1, 'Salted Venison'), +(29920, 33445, 0, 3, 0, 1, 1, 1, 1, 'Honeymint Tea'), +(29920, 43852, 0, 10, 0, 1, 0, 1, 1, 'Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 30939 WHERE (`entry` = 30939); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30939); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30939, 33454, 0, 6, 0, 1, 1, 1, 1, 'Salted Venison'), +(30939, 33445, 0, 3, 0, 1, 1, 1, 1, 'Honeymint Tea'), +(30939, 43852, 0, 10, 0, 1, 0, 1, 1, 'Thick Fur Clothing Scraps'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30111); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30111, 33444, 0, 3, 0, 1, 1, 1, 1, 'Twilight Worshipper - Pungent Seal Whey'), +(30111, 33454, 0, 6, 0, 1, 1, 1, 1, 'Twilight Worshipper - Salted Venison'), +(30111, 43852, 0, 10, 0, 1, 0, 1, 1, 'Twilight Worshipper - Thick Fur Clothing Scraps'); +UPDATE `creature_template` SET `lootid` = 31475 WHERE (`entry` = 31475); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 31475); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(31475, 33444, 0, 3, 0, 1, 1, 1, 1, 'Twilight Worshipper - Pungent Seal Whey'), +(31475, 33454, 0, 6, 0, 1, 1, 1, 1, 'Twilight Worshipper - Salted Venison'), +(31475, 43852, 0, 10, 0, 1, 0, 1, 1, 'Twilight Worshipper - Thick Fur Clothing Scraps'); + +-- No Cloth +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26730); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26730, 33546, 0, 75, 0, 1, 1, 1, 4, 'Mage Slayer - Vicious Fang'), +(26730, 33547, 0, 15, 0, 1, 1, 1, 1, 'Mage Slayer - Hardened Claw'); +UPDATE `creature_template` SET `lootid` = 30473 WHERE (`entry` = 30473); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30473); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30473, 33546, 0, 75, 0, 1, 1, 1, 4, 'Mage Slayer - Vicious Fang'), +(30473, 33547, 0, 15, 0, 1, 1, 1, 1, 'Mage Slayer - Hardened Claw'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26737); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26737, 36809, 0, 15, 0, 1, 1, 1, 1, 'Crazed Mana-Surge - Elemental Husk'), +(26737, 36810, 0, 75, 0, 1, 1, 2, 4, 'Crazed Mana-Surge - Primordial Infusion'); +UPDATE `creature_template` SET `lootid` = 30519 WHERE (`entry` = 30519); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30519); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30519, 36809, 0, 15, 0, 1, 1, 1, 1, 'Crazed Mana-Surge - Elemental Husk'), +(30519, 36810, 0, 75, 0, 1, 1, 2, 4, 'Crazed Mana-Surge - Primordial Infusion'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26782); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26782, 33452, 0, 3, 0, 1, 1, 1, 1, 'Crystalline Keeper - Honey-Spiced Lichen'), +(26782, 39516, 0, 6, 0, 1, 1, 1, 1, 'Crystalline Keeper - Frosty Mushroom'); +UPDATE `creature_template` SET `lootid` = 30526 WHERE (`entry` = 30526); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30526); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30526, 33452, 0, 3, 0, 1, 1, 1, 1, 'Crystalline Keeper - Honey-Spiced Lichen'), +(30526, 39516, 0, 6, 0, 1, 1, 1, 1, 'Crystalline Keeper - Frosty Mushroom'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 26792); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(26792, 35490, 0, 100, 1, 1, 0, 1, 2, 'Crystalline Protector - Arcane Splinter'); +UPDATE `creature_template` SET `lootid` = 30524 WHERE (`entry` = 30524); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30524); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30524, 35490, 0, 100, 1, 1, 0, 1, 2, 'Crystalline Protector - Arcane Splinter'); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 28231); +UPDATE `creature_template` SET `lootid` = 30525 WHERE (`entry` = 30525); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 29774); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(29774, 33445, 0, 3, 0, 1, 2, 1, 1, 'Spitting Cobra - Honeymint Tea'), +(29774, 33454, 0, 6, 0, 1, 2, 1, 1, 'Spitting Cobra - Salted Venison'), +(29774, 39567, 0, 75, 0, 1, 1, 3, 5, 'Spitting Cobra - Rubicund Scale'), +(29774, 39568, 0, 15, 0, 1, 1, 2, 4, 'Spitting Cobra - Hollow Fang'); +UPDATE `creature_template` SET `lootid` = 30941 WHERE (`entry` = 30941); +DELETE FROM `creature_loot_template` WHERE (`Entry` = 30941); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30941, 33445, 0, 3, 0, 1, 2, 1, 1, 'Spitting Cobra - Honeymint Tea'), +(30941, 33454, 0, 6, 0, 1, 2, 1, 1, 'Spitting Cobra - Salted Venison'), +(30941, 39567, 0, 75, 0, 1, 1, 3, 5, 'Spitting Cobra - Rubicund Scale'), +(30941, 39568, 0, 15, 0, 1, 1, 2, 4, 'Spitting Cobra - Hollow Fang'); + +DELETE FROM `creature_loot_template` WHERE `Reference` IN (1200068, 1200168, 1200069, 1200169, 1200070, 1200170, 1200071, 1200171, 1200072, 1200172, 1200073, 1200173, 1200074, 1200174, 1200075, 1200175, 1200076, 1200176, 1200077, 1200177, 1200078, 1200178, 1200079, 1200179, 1200080, 1200180, 1200081, 1200181, 1200082, 1200182, 1200268, 1200368, 1200269, 1200369, 1200270, 1200370, 1200271, 1200371, 1200272, 1200372, 1200273, 1200373, 1200274, 1200374, 1200275, 1200375, 1200276, 1200376, 1200277, 1200377, 1200278, 1200378, 1200279, 1200379, 1200280, 1200380, 1200281, 1200381, 1200282, 1200382) +AND `Entry` IN (23956,23960,23961,24069,24071,24078,24079,24080,24082,24083,24084,24085,24849,26550,26553,26554,26555,26620,26621,26622,26623,26624,26625,26626,26628,26635,26636,26637,26638,26639,26641,26669,26670,26672,26694,26696,26716,26722,26727,26728,26729,26730,26734,26735,26737,26782,26792,26800,26802,26805,26830,27431,27633,27635,27636,27639,27640,27641,27729,27731,27734,27736,27871,27960,27961,27962,27963,27964,27965,27966,27969,27970,27971,27972,28201,28231,28249,28368,28410,28419,28547,28578,28579,28580,28581,28582,28583,28584,28732,28734,28826,28835,28836,28837,28838,28920,28961,28965,29128,29335,29735,29768,29774,29819,29820,29822,29826,29829,29830,29832,29838,29874,29920,29931,30111,30179,30276,30277,30278,30279,30283,30284,30285,30286,30287,30319,30329,30414,30457,30459,30460,30473,30478,30485,30496,30498,30509,30516,30517,30519,30524,30525,30526,30747,30762,30764,30765,30766,30806,30816,30817,30818,30820,30821,30901,30902,30904,30905,30915,30916,30926,30927,30929,30930,30931,30932,30933,30935,30936,30938,30939,30941,30942,30964,30966,30967,30968,30971,30972,30974,30975,30976,30977,30978,30979,30980,30981,30982,30983,31104,31178,31179,31187,31199,31200,31201,31336,31337,31338,31339,31340,31342,31343,31345,31347,31351,31352,31354,31355,31357,31359,31363,31371,31372,31373,31374,31375,31376,31377,31378,31383,31385,31387,31442,31443,31449,31450,31451,31455,31457,31459,31460,31466,31468,31470,31471,31472,31475,31604,31606,31608,31609,31658,31659,31660,31661,31662,31663,31665,31666,31667,31669,31671,31675,31676,31678,31681,36886,36891,37626); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(23956, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Dragonflayer Strategist - World Loot Level 70'), +(23960, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Dragonflayer Runecaster - World Loot Level 70'), +(23961, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Dragonflayer Ironhelm - World Loot Level 70'), +(24069, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Dragonflayer Bonecrusher - World Loot Level 70'), +(24071, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Dragonflayer Heartsplitter - World Loot Level 70'), +(24078, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Dragonflayer Metalworker - World Loot Level 70'), +(24079, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Dragonflayer Forge Master - World Loot Level 70'), +(24080, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Dragonflayer Weaponsmith - World Loot Level 70'), +(24082, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Proto-Drake Handler - World Loot Level 70'), +(24083, 1, 1200270, 0, 0, 1, 5, 1, 1, 'Enslaved Proto-Drake - World Loot Level 70'), +(24084, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Tunneling Ghoul - World Loot Level 70'), +(24085, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Dragonflayer Overseer - World Loot Level 70'), +(24849, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Proto-Drake Rider - World Loot Level 70'), +(26550, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Dragonflayer Deathseeker - World Loot Level 77'), +(26553, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Fanatic - World Loot Level 80'), +(26554, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Seer - World Loot Level 80'), +(26555, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Scourge Hulk - World Loot Level 80'), +(26620, 1, 1200376, 0, 0, 1, 5, 1, 1, 'Drakkari Guardian - World Loot Level 76'), +(26621, 1, 1200372, 0, 0, 1, 5, 1, 1, 'Ghoul Tormentor - World Loot Level 72'), +(26622, 1, 1200075, 0, 0, 1, 5, 1, 1, 'Drakkari Bat - World Loot Level 75'), +(26623, 1, 1200376, 0, 0, 1, 5, 1, 1, 'Scourge Brute - World Loot Level 76'), +(26624, 1, 1200374, 0, 0, 1, 5, 1, 1, 'Wretched Belcher - World Loot Level 74'), +(26625, 1, 1200274, 0, 0, 1, 5, 1, 1, 'Darkweb Recluse - World Loot Level 74'), +(26626, 1, 1200374, 0, 0, 1, 5, 1, 1, 'Scourge Reanimator - World Loot Level 74'), +(26628, 1, 1200274, 0, 0, 1, 5, 1, 1, 'Drakkari Scytheclaw - World Loot Level 74'), +(26635, 1, 1200374, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Warrior - World Loot Level 74'), +(26636, 1, 1200374, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Soulmage - World Loot Level 74'), +(26637, 1, 1200375, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Handler - World Loot Level 75'), +(26638, 1, 1200375, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Bat Rider - World Loot Level 75'), +(26639, 1, 1200376, 0, 0, 1, 5, 1, 1, 'Drakkari Shaman - World Loot Level 76'), +(26641, 1, 1200374, 0, 0, 1, 5, 1, 1, 'Drakkari Gutripper - World Loot Level 74'), +(26669, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Ymirjar Savage - World Loot Level 79'), +(26670, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Ymirjar Flesh Hunter - World Loot Level 79'), +(26672, 1, 1200279, 0, 0, 1, 5, 1, 1, 'Bloodthirsty Tundra Wolf - World Loot Level 79'), +(26694, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Ymirjar Dusk Shaman - World Loot Level 79'), +(26696, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Ymirjar Berserker - World Loot Level 80'), +(26716, 1, 1200371, 0, 0, 1, 5, 1, 1, 'Azure Warder - World Loot Level 71'), +(26722, 1, 1200371, 0, 0, 1, 5, 1, 1, 'Azure Magus - World Loot Level 71'), +(26727, 1, 1200371, 0, 0, 1, 5, 1, 1, 'Mage Hunter Ascendant - World Loot Level 71'), +(26728, 1, 1200371, 0, 0, 1, 5, 1, 1, 'Mage Hunter Initiate - World Loot Level 71'), +(26729, 1, 1200371, 0, 0, 1, 5, 1, 1, 'Steward - World Loot Level 71'), +(26730, 1, 1200271, 0, 0, 1, 5, 1, 1, 'Mage Slayer - World Loot Level 71'), +(26734, 1, 1200371, 0, 0, 1, 5, 1, 1, 'Azure Enforcer - World Loot Level 71'), +(26735, 1, 1200371, 0, 0, 1, 5, 1, 1, 'Azure Scale-Binder - World Loot Level 71'), +(26737, 1, 1200271, 0, 0, 1, 5, 1, 1, 'Crazed Mana-Surge - World Loot Level 71'), +(26782, 1, 1200271, 0, 0, 1, 5, 1, 1, 'Crystalline Keeper - World Loot Level 71'), +(26792, 1, 1200271, 0, 0, 1, 5, 1, 1, 'Crystalline Protector - World Loot Level 71'), +(26800, 1, 1200371, 0, 0, 1, 5, 1, 1, 'Alliance Berserker - World Loot Level 71'), +(26802, 1, 1200371, 0, 0, 1, 5, 1, 1, 'Alliance Ranger - World Loot Level 71'), +(26805, 1, 1200371, 0, 0, 1, 5, 1, 1, 'Alliance Cleric - World Loot Level 71'), +(26830, 1, 1200376, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Death Knight - World Loot Level 76'), +(27431, 1, 1200375, 0, 0, 1, 5, 1, 1, 'Drakkari Commander - World Loot Level 75'), +(27633, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Azure Inquisitor - World Loot Level 79'), +(27635, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Azure Spellbinder - World Loot Level 79'), +(27636, 1, 1200079, 0, 0, 1, 5, 1, 1, 'Azure Ley-Whelp - World Loot Level 79'), +(27639, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Ring-Lord Sorceress - World Loot Level 79'), +(27640, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Ring-Lord Conjurer - World Loot Level 79'), +(27641, 1, 1200279, 0, 0, 1, 5, 1, 1, 'Centrifuge Construct - World Loot Level 79'), +(27729, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Enraging Ghoul - World Loot Level 80'), +(27731, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Acolyte - World Loot Level 80'), +(27734, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Crypt Fiend - World Loot Level 80'), +(27736, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Patchwork Construct - World Loot Level 80'), +(27736, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Patchwork Construct - World Loot Level 81'), +(27871, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Flesheating Ghoul (1) - World Loot Level 80'), +(27871, 1, 1200374, 0, 0, 1, 5, 1, 1, 'Flesheating Ghoul - World Loot Level 74'), +(27871, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Flesheating Ghoul (1) - World Loot Level 81'), +(27960, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Dark Rune Warrior - World Loot Level 77'), +(27961, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Dark Rune Worker - World Loot Level 77'), +(27962, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Dark Rune Elementalist - World Loot Level 77'), +(27963, 1, 1200378, 0, 0, 1, 5, 1, 1, 'Dark Rune Theurgist - World Loot Level 78'), +(27964, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Dark Rune Scholar - World Loot Level 77'), +(27965, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Dark Rune Shaper - World Loot Level 77'), +(27966, 1, 1200378, 0, 0, 1, 5, 1, 1, 'Dark Rune Controller - World Loot Level 78'), +(27969, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Dark Rune Giant - World Loot Level 77'), +(27970, 1, 1200278, 0, 0, 1, 5, 1, 1, 'Raging Construct - World Loot Level 78'), +(27971, 1, 1200277, 0, 0, 1, 5, 1, 1, 'Unrelenting Construct - World Loot Level 77'), +(27972, 1, 1200278, 0, 0, 1, 5, 1, 1, 'Lightning Construct - World Loot Level 78'), +(28201, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Bile Golem - World Loot Level 81'), +(28231, 1, 1200271, 0, 0, 1, 5, 1, 1, 'Crystalline Tender - World Loot Level 71'), +(28249, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Devouring Ghoul - World Loot Level 77'), +(28249, 2, 1200378, 0, 0, 1, 5, 1, 1, 'Devouring Ghoul - World Loot Level 78'), +(28249, 3, 1200379, 0, 0, 1, 5, 1, 1, 'Devouring Ghoul - World Loot Level 79'), +(28249, 4, 1200380, 0, 0, 1, 5, 1, 1, 'Devouring Ghoul - World Loot Level 80'), +(28368, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Ymirjar Necromancer - World Loot Level 79'), +(28410, 1, 1200370, 0, 0, 1, 5, 1, 1, 'Dragonflayer Spiritualist - World Loot Level 70'), +(28410, 2, 1200371, 0, 0, 1, 5, 1, 1, 'Dragonflayer Spiritualist - World Loot Level 71'), +(28419, 1, 1200170, 0, 0, 1, 5, 1, 1, 'Frenzied Geist - World Loot Level 70'), +(28547, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Storming Vortex - World Loot Level 80'), +(28578, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Hardened Steel Reaver - World Loot Level 79'), +(28579, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Hardened Steel Berserker - World Loot Level 79'), +(28579, 2, 1200380, 0, 0, 1, 5, 1, 1, 'Hardened Steel Berserker - World Loot Level 80'), +(28580, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Hardened Steel Skycaller - World Loot Level 79'), +(28580, 2, 1200380, 0, 0, 1, 5, 1, 1, 'Hardened Steel Skycaller - World Loot Level 80'), +(28581, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Stormforged Tactician - World Loot Level 79'), +(28581, 2, 1200380, 0, 0, 1, 5, 1, 1, 'Stormforged Tactician - World Loot Level 80'), +(28582, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Stormforged Mender - World Loot Level 79'), +(28582, 2, 1200380, 0, 0, 1, 5, 1, 1, 'Stormforged Mender - World Loot Level 80'), +(28583, 1, 1200279, 0, 0, 1, 5, 1, 1, 'Blistering Steamrager - World Loot Level 79'), +(28583, 2, 1200280, 0, 0, 1, 5, 1, 1, 'Blistering Steamrager - World Loot Level 80'), +(28584, 1, 1200279, 0, 0, 1, 5, 1, 1, 'Unbound Firestorm - World Loot Level 79'), +(28584, 2, 1200280, 0, 0, 1, 5, 1, 1, 'Unbound Firestorm - World Loot Level 80'), +(28732, 1, 1200272, 0, 0, 1, 5, 1, 1, 'Anub\'ar Warrior - World Loot Level 72'), +(28734, 1, 1200272, 0, 0, 1, 5, 1, 1, 'Anub\'ar Skirmisher - World Loot Level 72'), +(28826, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Stormfury Revenant - World Loot Level 80'), +(28835, 1, 1200378, 0, 0, 1, 5, 1, 1, 'Stormforged Construct - World Loot Level 78'), +(28836, 1, 1200378, 0, 0, 1, 5, 1, 1, 'Stormforged Runeshaper - World Loot Level 78'), +(28837, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Stormforged Sentinel - World Loot Level 80'), +(28838, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Titanium Vanguard - World Loot Level 80'), +(28920, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Stormforged Giant - World Loot Level 80'), +(28961, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Titanium Siegebreaker - World Loot Level 79'), +(28965, 1, 1200379, 0, 0, 1, 5, 1, 1, 'Titanium Thunderer - World Loot Level 79'), +(29128, 1, 1200274, 0, 0, 1, 5, 1, 1, 'Anub\'ar Prime Guard - World Loot Level 74'), +(29335, 1, 1200272, 0, 0, 1, 5, 1, 1, 'Anub\'ar Webspinner - World Loot Level 72'), +(29735, 1, 1200070, 0, 0, 1, 5, 1, 1, 'Savage Worg - World Loot Level 70'), +(29768, 1, 1200277, 0, 0, 1, 5, 1, 1, 'Unyielding Constrictor - World Loot Level 77'), +(29774, 1, 1200277, 0, 0, 1, 5, 1, 1, 'Spitting Cobra - World Loot Level 77'), +(29819, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Drakkari Lancer - World Loot Level 77'), +(29820, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Drakkari God Hunter - World Loot Level 77'), +(29822, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Drakkari Fire Weaver - World Loot Level 77'), +(29826, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Drakkari Medicine Man - World Loot Level 77'), +(29829, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Drakkari Earthshaker - World Loot Level 77'), +(29830, 1, 1200276, 0, 0, 1, 5, 1, 1, 'Living Mojo - World Loot Level 76'), +(29832, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Drakkari Golem - World Loot Level 77'), +(29838, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Drakkari Rhino - World Loot Level 77'), +(29874, 1, 1200177, 0, 0, 1, 5, 1, 1, 'Drakkari Inciter - World Loot Level 77'), +(29920, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Ruins Dweller - World Loot Level 80'), +(29931, 1, 1200377, 0, 0, 1, 5, 1, 1, 'Drakkari Rhino - World Loot Level 77'), +(30111, 1, 1200374, 0, 0, 1, 5, 1, 1, 'Twilight Worshipper - World Loot Level 74'), +(30179, 1, 1200375, 0, 0, 1, 5, 1, 1, 'Twilight Apostle - World Loot Level 75'), +(30276, 1, 1200373, 0, 0, 1, 5, 1, 1, 'Ahn\'kahar Web Winder - World Loot Level 73'), +(30277, 1, 1200373, 0, 0, 1, 5, 1, 1, 'Ahn\'kahar Slasher - World Loot Level 73'), +(30278, 1, 1200373, 0, 0, 1, 5, 1, 1, 'Ahn\'kahar Spell Flinger - World Loot Level 73'), +(30279, 1, 1200273, 0, 0, 1, 5, 1, 1, 'Deep Crawler - World Loot Level 73'), +(30283, 1, 1200374, 0, 0, 1, 5, 1, 1, 'Plague Walker - World Loot Level 74'), +(30284, 1, 1200374, 0, 0, 1, 5, 1, 1, 'Bonegrinder - World Loot Level 74'), +(30285, 1, 1200373, 0, 0, 1, 5, 1, 1, 'Eye of Taldaram - World Loot Level 73'), +(30286, 1, 1200373, 0, 0, 1, 5, 1, 1, 'Frostbringer - World Loot Level 73'), +(30287, 1, 1200173, 0, 0, 1, 5, 1, 1, 'Plundering Geist - World Loot Level 73'), +(30319, 1, 1200374, 0, 0, 1, 5, 1, 1, 'Twilight Darkcaster - World Loot Level 74'), +(30329, 1, 1200274, 0, 0, 1, 5, 1, 1, 'Savage Cave Beast - World Loot Level 74'), +(30414, 1, 1200375, 0, 0, 1, 5, 1, 1, 'Forgotten One - World Loot Level 75'), +(30457, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Azure Magus (1) - World Loot Level 81'), +(30459, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Azure Warder (1) - World Loot Level 81'), +(30460, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Mage Hunter Ascendant (1) - World Loot Level 80'), +(30473, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Mage Slayer (1) - World Loot Level 80'), +(30478, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Mage Hunter Initiate (1) - World Loot Level 80'), +(30485, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Steward (1) - World Loot Level 80'), +(30496, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Alliance Berserker (1) - World Loot Level 80'), +(30498, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Alliance Cleric (1) - World Loot Level 80'), +(30509, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Alliance Ranger (1) - World Loot Level 80'), +(30516, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Azure Enforcer (1) - World Loot Level 80'), +(30517, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Azure Scale-Binder (1) - World Loot Level 80'), +(30519, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Crazed Mana-Surge (1) - World Loot Level 80'), +(30524, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Crystalline Protector (1) - World Loot Level 80'), +(30525, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Crystalline Tender (1) - World Loot Level 80'), +(30526, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Crystalline Keeper (1) - World Loot Level 80'), +(30747, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Ironhelm (1) - World Loot Level 80'), +(30747, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Ironhelm (1) - World Loot Level 81'), +(30762, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Bloodthirsty Tundra Wolf (1) - World Loot Level 80'), +(30762, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Bloodthirsty Tundra Wolf (1) - World Loot Level 81'), +(30764, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Deathseeker (1) - World Loot Level 80'), +(30764, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Deathseeker (1) - World Loot Level 81'), +(30765, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Fanatic (1) - World Loot Level 80'), +(30765, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Fanatic (1) - World Loot Level 81'), +(30766, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Seer (1) - World Loot Level 80'), +(30766, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Seer (1) - World Loot Level 81'), +(30806, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Scourge Hulk (1) - World Loot Level 81'), +(30816, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Ymirjar Berserker (1) - World Loot Level 80'), +(30816, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Ymirjar Berserker (1) - World Loot Level 81'), +(30817, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Ymirjar Dusk Shaman (1) - World Loot Level 80'), +(30817, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Ymirjar Dusk Shaman (1) - World Loot Level 81'), +(30818, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Ymirjar Flesh Hunter (1) - World Loot Level 80'), +(30818, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Ymirjar Flesh Hunter (1) - World Loot Level 81'), +(30820, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Ymirjar Necromancer (1) - World Loot Level 80'), +(30820, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Ymirjar Necromancer (1) - World Loot Level 81'), +(30821, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Ymirjar Savage (1) - World Loot Level 80'), +(30821, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Ymirjar Savage (1) - World Loot Level 81'), +(30901, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Azure Inquisitor (1) - World Loot Level 80'), +(30901, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Azure Inquisitor (1) - World Loot Level 81'), +(30902, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Azure Ley-Whelp (1) - World Loot Level 80'), +(30902, 2, 1200081, 0, 0, 1, 5, 1, 1, 'Azure Ley-Whelp (1) - World Loot Level 81'), +(30904, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Azure Spellbinder (1) - World Loot Level 80'), +(30904, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Azure Spellbinder (1) - World Loot Level 81'), +(30905, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Centrifuge Construct (1) - World Loot Level 80'), +(30905, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Centrifuge Construct (1) - World Loot Level 81'), +(30915, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Ring-Lord Conjurer (1) - World Loot Level 80'), +(30915, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Ring-Lord Conjurer (1) - World Loot Level 81'), +(30916, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Ring-Lord Sorceress (1) - World Loot Level 80'), +(30916, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Ring-Lord Sorceress (1) - World Loot Level 81'), +(30926, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Drakkari Earthshaker (1) - World Loot Level 80'), +(30926, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari Earthshaker (1) - World Loot Level 81'), +(30927, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari Fire Weaver (1) - World Loot Level 81'), +(30929, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari God Hunter (1) - World Loot Level 81'), +(30930, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Drakkari Golem (1) - World Loot Level 80'), +(30930, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari Golem (1) - World Loot Level 81'), +(30931, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Drakkari Inciter (1) - World Loot Level 80'), +(30931, 2, 1200181, 0, 0, 1, 5, 1, 1, 'Drakkari Inciter (1) - World Loot Level 81'), +(30932, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari Lancer (1) - World Loot Level 81'), +(30933, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari Medicine Man (1) - World Loot Level 81'), +(30935, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari Rhino (1) - World Loot Level 81'), +(30936, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari Rhino (1) - World Loot Level 81'), +(30938, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Living Mojo (1) - World Loot Level 80'), +(30938, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Living Mojo (1) - World Loot Level 81'), +(30939, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Ruins Dweller (1) - World Loot Level 81'), +(30941, 1, 1200281, 0, 0, 1, 5, 1, 1, 'Spitting Cobra (1) - World Loot Level 81'), +(30942, 1, 1200281, 0, 0, 1, 5, 1, 1, 'Unyielding Constrictor (1) - World Loot Level 81'), +(30964, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Blistering Steamrager (1) - World Loot Level 80'), +(30964, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Blistering Steamrager (1) - World Loot Level 81'), +(30966, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Hardened Steel Berserker (1) - World Loot Level 80'), +(30966, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Hardened Steel Berserker (1) - World Loot Level 81'), +(30967, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Hardened Steel Reaver (1) - World Loot Level 80'), +(30967, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Hardened Steel Reaver (1) - World Loot Level 81'), +(30968, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Hardened Steel Skycaller (1) - World Loot Level 80'), +(30968, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Hardened Steel Skycaller (1) - World Loot Level 81'), +(30971, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Stormforged Construct (1) - World Loot Level 80'), +(30971, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Stormforged Construct (1) - World Loot Level 81'), +(30972, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Stormforged Giant (1) - World Loot Level 80'), +(30974, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Stormforged Mender (1) - World Loot Level 80'), +(30974, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Stormforged Mender (1) - World Loot Level 81'), +(30975, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Stormforged Runeshaper (1) - World Loot Level 80'), +(30975, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Stormforged Runeshaper (1) - World Loot Level 81'), +(30976, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Stormforged Sentinel (1) - World Loot Level 80'), +(30976, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Stormforged Sentinel (1) - World Loot Level 81'), +(30977, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Stormforged Tactician (1) - World Loot Level 80'), +(30977, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Stormforged Tactician (1) - World Loot Level 81'), +(30978, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Stormfury Revenant (1) - World Loot Level 80'), +(30978, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Stormfury Revenant (1) - World Loot Level 81'), +(30979, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Storming Vortex (1) - World Loot Level 80'), +(30979, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Storming Vortex (1) - World Loot Level 81'), +(30980, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Titanium Siegebreaker (1) - World Loot Level 80'), +(30980, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Titanium Siegebreaker (1) - World Loot Level 81'), +(30981, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Titanium Vanguard (1) - World Loot Level 80'), +(30981, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Titanium Vanguard (1) - World Loot Level 81'), +(30982, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Titanium Thunderer (1) - World Loot Level 80'), +(30982, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Titanium Thunderer (1) - World Loot Level 81'), +(30983, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Unbound Firestorm (1) - World Loot Level 80'), +(30983, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Unbound Firestorm (1) - World Loot Level 81'), +(31104, 1, 1200279, 0, 0, 1, 5, 1, 1, 'Ahn\'kahar Watcher - World Loot Level 79'), +(31178, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Enraging Ghoul (1) - World Loot Level 80'), +(31179, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Devouring Ghoul (1) - World Loot Level 80'), +(31187, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Crypt Fiend (1) - World Loot Level 80'), +(31199, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Patchwork Construct (1) - World Loot Level 81'), +(31200, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Bile Golem (1) - World Loot Level 81'), +(31201, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Acolyte (1) - World Loot Level 80'), +(31336, 1, 1200281, 0, 0, 1, 5, 1, 1, 'Darkweb Recluse (1) - World Loot Level 81'), +(31337, 1, 1200080, 0, 0, 1, 5, 1, 1, 'Drakkari Bat (1) - World Loot Level 80'), +(31338, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari Commander (1) - World Loot Level 81'), +(31339, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Drakkari Guardian (1) - World Loot Level 80'), +(31339, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari Guardian (1) - World Loot Level 81'), +(31340, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Drakkari Gutripper (1) - World Loot Level 80'), +(31340, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari Gutripper (1) - World Loot Level 81'), +(31342, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Handler (1) - World Loot Level 81'), +(31343, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Drakkari Scytheclaw (1) - World Loot Level 80'), +(31343, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Drakkari Scytheclaw (1) - World Loot Level 81'), +(31345, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Drakkari Shaman (1) - World Loot Level 80'), +(31345, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Drakkari Shaman (1) - World Loot Level 81'), +(31347, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Ghoul Tormentor (1) - World Loot Level 80'), +(31347, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Ghoul Tormentor (1) - World Loot Level 81'), +(31351, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Bat Rider (1) - World Loot Level 80'), +(31351, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Bat Rider (1) - World Loot Level 81'), +(31352, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Death Knight (1) - World Loot Level 80'), +(31352, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Death Knight (1) - World Loot Level 81'), +(31354, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Soulmage (1) - World Loot Level 80'), +(31354, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Soulmage (1) - World Loot Level 81'), +(31355, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Warrior (1) - World Loot Level 80'), +(31355, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Risen Drakkari Warrior (1) - World Loot Level 81'), +(31357, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Scourge Brute (1) - World Loot Level 80'), +(31357, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Scourge Brute (1) - World Loot Level 81'), +(31359, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Scourge Reanimator (1) - World Loot Level 80'), +(31359, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Scourge Reanimator (1) - World Loot Level 81'), +(31363, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Wretched Belcher (1) - World Loot Level 80'), +(31363, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Wretched Belcher (1) - World Loot Level 81'), +(31371, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dark Rune Controller (1) - World Loot Level 80'), +(31372, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dark Rune Elementalist (1) - World Loot Level 80'), +(31372, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dark Rune Elementalist (1) - World Loot Level 81'), +(31373, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Dark Rune Giant (1) - World Loot Level 81'), +(31374, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Dark Rune Scholar (1) - World Loot Level 81'), +(31375, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dark Rune Shaper (1) - World Loot Level 80'), +(31375, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dark Rune Shaper (1) - World Loot Level 81'), +(31376, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dark Rune Theurgist (1) - World Loot Level 80'), +(31376, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dark Rune Theurgist (1) - World Loot Level 81'), +(31377, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dark Rune Warrior (1) - World Loot Level 80'), +(31377, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dark Rune Warrior (1) - World Loot Level 81'), +(31378, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dark Rune Worker (1) - World Loot Level 80'), +(31383, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Lightning Construct (1) - World Loot Level 80'), +(31383, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Lightning Construct (1) - World Loot Level 81'), +(31385, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Raging Construct (1) - World Loot Level 80'), +(31387, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Unrelenting Construct (1) - World Loot Level 80'), +(31387, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Unrelenting Construct (1) - World Loot Level 81'), +(31442, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Ahn\'kahar Slasher (1) - World Loot Level 81'), +(31443, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Ahn\'kahar Spell Flinger (1) - World Loot Level 81'), +(31449, 1, 1200281, 0, 0, 1, 5, 1, 1, 'Ahn\'kahar Watcher (1) - World Loot Level 81'), +(31450, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Ahn\'kahar Web Winder (1) - World Loot Level 81'), +(31451, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Bonegrinder (1) - World Loot Level 81'), +(31455, 1, 1200281, 0, 0, 1, 5, 1, 1, 'Deep Crawler (1) - World Loot Level 81'), +(31457, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Eye of Taldaram (1) - World Loot Level 81'), +(31459, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Forgotten One (1) - World Loot Level 81'), +(31460, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Frostbringer (1) - World Loot Level 81'), +(31466, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Plague Walker (1) - World Loot Level 81'), +(31468, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Plundering Geist (1) - World Loot Level 80'), +(31470, 1, 1200281, 0, 0, 1, 5, 1, 1, 'Savage Cave Beast (1) - World Loot Level 81'), +(31471, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Twilight Apostle (1) - World Loot Level 81'), +(31472, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Twilight Darkcaster (1) - World Loot Level 81'), +(31475, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Twilight Worshipper (1) - World Loot Level 81'), +(31604, 1, 1200281, 0, 0, 1, 5, 1, 1, 'Anub\'ar Prime Guard (1) - World Loot Level 81'), +(31606, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Anub\'ar Skirmisher (1) - World Loot Level 80'), +(31606, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Anub\'ar Skirmisher (1) - World Loot Level 81'), +(31608, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Anub\'ar Warrior (1) - World Loot Level 80'), +(31608, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Anub\'ar Warrior (1) - World Loot Level 81'), +(31609, 1, 1200281, 0, 0, 1, 5, 1, 1, 'Anub\'ar Webspinner (1) - World Loot Level 81'), +(31658, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Bonecrusher (1) - World Loot Level 80'), +(31658, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Bonecrusher (1) - World Loot Level 81'), +(31659, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Forge Master (1) - World Loot Level 80'), +(31659, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Forge Master (1) - World Loot Level 81'), +(31660, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Heartsplitter (1) - World Loot Level 80'), +(31660, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Heartsplitter (1) - World Loot Level 81'), +(31661, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Metalworker (1) - World Loot Level 80'), +(31661, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Metalworker (1) - World Loot Level 81'), +(31662, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Overseer (1) - World Loot Level 80'), +(31662, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Overseer (1) - World Loot Level 81'), +(31663, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Runecaster (1) - World Loot Level 80'), +(31663, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Runecaster (1) - World Loot Level 81'), +(31665, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Dragonflayer Spiritualist (1) - World Loot Level 80'), +(31665, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Dragonflayer Spiritualist (1) - World Loot Level 81'), +(31666, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Strategist (1) - World Loot Level 80'), +(31666, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Strategist (1) - World Loot Level 81'), +(31667, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Dragonflayer Weaponsmith (1) - World Loot Level 80'), +(31667, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Dragonflayer Weaponsmith (1) - World Loot Level 81'), +(31669, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Enslaved Proto-Drake (1) - World Loot Level 80'), +(31669, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Enslaved Proto-Drake (1) - World Loot Level 81'), +(31671, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Frenzied Geist (1) - World Loot Level 80'), +(31671, 2, 1200181, 0, 0, 1, 5, 1, 1, 'Frenzied Geist (1) - World Loot Level 81'), +(31675, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Proto-Drake Handler (1) - World Loot Level 80'), +(31675, 2, 1200381, 0, 0, 1, 5, 1, 1, 'Proto-Drake Handler (1) - World Loot Level 81'), +(31676, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Proto-Drake Rider (1) - World Loot Level 80'), +(31676, 2, 1200281, 0, 0, 1, 5, 1, 1, 'Proto-Drake Rider (1) - World Loot Level 81'), +(31678, 1, 1200081, 0, 0, 1, 5, 1, 1, 'Savage Worg (1) - World Loot Level 81'), +(31681, 1, 1200180, 0, 0, 1, 5, 1, 1, 'Tunneling Ghoul (1) - World Loot Level 80'), +(31681, 2, 1200181, 0, 0, 1, 5, 1, 1, 'Tunneling Ghoul (1) - World Loot Level 81'), +(36886, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Geist Ambusher - World Loot Level 80'), +(36891, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Iceborn Proto-Drake - World Loot Level 80'), +(37626, 1, 1200280, 0, 0, 1, 5, 1, 1, 'Iceborn Proto-Drake (1) - World Loot Level 80'); + +-- Now for the cleanup +-- Loose Items +DELETE FROM `creature_loot_template` +WHERE `Item` IN (33358,33359,33360,33361,33362,33363,33364,33372,33373,33374,33375,33376,33377,33378,33390,33391,33392,33393,33394,33395,33396,33404,33405,33406,33407,33408,33409,33410,33422,33423,33424,33425,33426,33427,33428,33429,33430,33431,33437,33438,33439,33440,33365,33366,33367,33368,33369,33370,33371,33379,33380,33381,33382,33383,33384,33385,33397,33398,33399,33400,33401,33402,33403,33412,33413,33414,33415,33416,33417,33419,33433,33434,33435,33436,35955,35956,35957,35958,35959,35960,35961,35962,36067,36068,36069,36070,36071,36072,36073,36074,36179,36180,36181,36182,36183,36184,36185,36186,36291,36292,36293,36294,36295,36296,36297,36298,36403,36417,36431,36445,36459,36473,36487,36501,36515,36529,36543,36557,36571,36585,36599,36613,36627,36641,36655,36669,36683,36697,36711,35963,35964,35965,35966,35967,35968,35969,35970,36075,36076,36077,36078,36079,36080,36081,36082,36187,36188,36189,36190,36191,36192,36193,36194,36299,36300,36301,36302,36303,36304,36305,36306,36404,36418,36432,36446,36460,36474,36488,36502,36516,36530,36544,36558,36572,36586,36600,36614,36628,36642,36656,36670,36684,36698,36712,35971,35972,35973,35974,35975,35976,35977,35978,36083,36084,36085,36086,36087,36088,36089,36090,36195,36196,36197,36198,36199,36200,36201,36202,36307,36308,36309,36310,36311,36312,36313,36314,36405,36419,36433,36447,36461,36475,36489,36503,36517,36531,36545,36559,36573,36587,36601,36615,36629,36643,36657,36671,36685,36699,36713,35979,35980,35981,35982,35983,35984,35985,35986,36091,36092,36093,36094,36095,36096,36097,36098,36203,36204,36205,36206,36207,36208,36209,36210,36315,36316,36317,36318,36319,36320,36321,36322,36406,36420,36434,36448,36462,36476,36490,36504,36518,36532,36546,36560,36574,36588,36602,36616,36630,36644,36658,36672,36686,36700,36714,35987,35988,35989,35990,35991,35992,35993,35994,36099,36100,36101,36102,36103,36104,36105,36106,36211,36212,36213,36214,36215,36216,36217,36218,36323,36324,36325,36326,36327,36328,36329,36330,36407,36421,36435,36449,36463,35995,35996,35997,35998,35999,36000,36001,36002,36107,36108,36109,36110,36111,36112,36113,36114,36219,36220,36221,36222,36223,36224,36225,36226,36331,36332,36333,36334,36335,36336,36337,36338,36408,36422,36436,36450,36464,36478,36492,36506,36520,36534,36548,36562,36576,36590,36604,36618,36632,36646,36660,36674,36688,36702,36716,36003,36004,36005,36006,36007,36008,36009,36010,36115,36116,36117,36118,36119,36120,36121,36122,36227,36228,36229,36230,36231,36232,36233,36234,36339,36340,36341,36342,36343,36344,36345,36346,36409,36423,36437,36451,36465,36479,36493,36507,36521,36535,36549,36563,36577,36591,36605,36619,36633,36647,36661,36675,36689,36703,36717,36011,36012,36013,36014,36015,36016,36017,36018,36123,36124,36125,36126,36127,36128,36129,36130,36235,36236,36237,36238,36239,36240,36241,36242,36347,36348,36349,36350,36351,36352,36353,36354,36410,36424,36438,36452,36466,36480,36494,36508,36522,36536,36550,36564,36578,36592,36606,36620,36634,36648,36662,36676,36690,36704,36718,36019,36020,36021,36022,36023,36024,36025,36026,36131,36132,36133,36134,36135,36136,36137,36138,36243,36244,36245,36246,36247,36248,36249,36250,36355,36356,36357,36358,36359,36360,36361,36362,36411,36425,36439,36453,36467,36481,36495,36509,36523,36537,36551,36565,36579,36593,36607,36621,36635,36649,36663,36677,36691,36705,36719,36027,36028,36029,36030,36031,36032,36033,36034,36139,36140,36141,36142,36143,36144,36145,36146,36251,36252,36253,36254,36255,36256,36257,36258,36363,36364,36365,36366,36367,36368,36369,36370,36412,36426,36440,36468,36482,36496,36510,36524,36538,36552,36566,36580,36594,36608,36622,36636,36650,36664,36678,36692,36706,36720,36035,36036,36037,36038,36039,36040,36041,36042,36147,36148,36149,36150,36151,36152,36153,36154,36259,36260,36261,36262,36263,36264,36265,36266,36371,36372,36373,36374,36375,36376,36377,36378,36413,36427,36441,36455,36469,36483,36497,36511,36525,36539,36553,36567,36581,36595,36609,36623,36637,36651,36665,36679,36693,36707,36721,36043,36044,36045,36046,36047,36048,36049,36050,36155,36156,36157,36158,36159,36160,36161,36162,36267,36268,36269,36270,36271,36272,36273,36274,36379,36380,36381,36382,36383,36384,36385,36386,36414,36428,36442,36456,36470,36484,36498,36512,36526,36540,36554,36568,36582,36596,36610,36624,36638,36652,36666,36680,36694,36708,36722,36051,36052,36053,36054,36055,36056,36057,36058,36163,36164,36165,36166,36167,36168,36169,36170,36275,36276,36277,36278,36279,36280,36281,36282,36387,36388,36389,36390,36391,36392,36393,36394,36415,36429,36443,36457,36471,36485,36499,36513,36527,36541,36555,36569,36583,36597,36611,36625,36639,36653,36667,36681,36695,36709,36723,36059,36060,36061,36062,36063,36064,36065,36066,36171,36172,36173,36174,36175,36176,36177,36178,36283,36284,36285,36286,36287,36288,36289,36290,36395,36396,36397,36398,36399,36400,36401,36402,36416,36430,36444,36458,36472,36486,36500,36514,36528,36542,36556,36570,36584,36598,36612,36626,36640,36654,36668,36682,36696,36710,36724,37743,37744,37745,37746,37747,37748,37749,37751,37752,37762,37772,37782,37753,37763,37773,37783,37803,37819,37754,37764,37774,37795,37796,37820,37755,37775,37785,37802,37811,37817,37756,37765,37776,37786,37807,37821,37757,37766,37777,37787,37805,37813,37758,37767,37778,37789,37804,37810,37812,37759,37768,37790,37806,37808,37809,37769,37779,37792,37797,37823,37760,37770,37780,37793,37822,37761,37771,37781,37794,37824,37254,37835,43573,44308,44309,44310,44311,44312,44313,22829,22832,37091,37093,37097,43463,43465,43467,33447,33448,43507,43508,43509,43510,43622,43876,39152,41777,41778,41779,41780,41781,41782,41783,41784,41785,41786,41787,41788,41789,42172,42173,42175,42176,42177,42178,43297,43624,45912,33470) +AND `Entry` IN (23956,23960,23961,24069,24071,24078,24079,24080,24082,24083,24084,24085,24849,26550,26553,26554,26555,26620,26621,26622,26623,26624,26625,26626,26628,26635,26636,26637,26638,26639,26641,26669,26670,26672,26694,26696,26716,26722,26727,26728,26729,26730,26734,26735,26737,26782,26792,26800,26802,26805,26830,27431,27633,27635,27636,27639,27640,27641,27729,27731,27734,27736,27871,27960,27961,27962,27963,27964,27965,27966,27969,27970,27971,27972,28201,28231,28249,28368,28410,28419,28547,28578,28579,28580,28581,28582,28583,28584,28732,28734,28826,28835,28836,28837,28838,28920,28961,28965,29128,29335,29735,29768,29774,29819,29820,29822,29826,29829,29830,29832,29838,29874,29920,29931,30111,30179,30276,30277,30278,30279,30283,30284,30285,30286,30287,30319,30329,30414,30457,30459,30460,30473,30478,30485,30496,30498,30509,30516,30517,30519,30524,30525,30526,30747,30762,30764,30765,30766,30806,30816,30817,30818,30820,30821,30901,30902,30904,30905,30915,30916,30926,30927,30929,30930,30931,30932,30933,30935,30936,30938,30939,30941,30942,30964,30966,30967,30968,30971,30972,30974,30975,30976,30977,30978,30979,30980,30981,30982,30983,31104,31178,31179,31187,31199,31200,31201,31336,31337,31338,31339,31340,31342,31343,31345,31347,31351,31352,31354,31355,31357,31359,31363,31371,31372,31373,31374,31375,31376,31377,31378,31383,31385,31387,31442,31443,31449,31450,31451,31455,31457,31459,31460,31466,31468,31470,31471,31472,31475,31604,31606,31608,31609,31658,31659,31660,31661,31662,31663,31665,31666,31667,31669,31671,31675,31676,31678,31681,36886,36891,37626); +-- Delete Legacy References +DELETE FROM `creature_loot_template` WHERE +`Entry` IN (23956,23960,23961,24069,24071,24078,24079,24080,24082,24083,24084,24085,24849,26550,26553,26554,26555,26620,26621,26622,26623,26624,26625,26626,26628,26635,26636,26637,26638,26639,26641,26669,26670,26672,26694,26696,26716,26722,26727,26728,26729,26730,26734,26735,26737,26782,26792,26800,26802,26805,26830,27431,27633,27635,27636,27639,27640,27641,27729,27731,27734,27736,27871,27960,27961,27962,27963,27964,27965,27966,27969,27970,27971,27972,28201,28231,28249,28368,28410,28419,28547,28578,28579,28580,28581,28582,28583,28584,28732,28734,28826,28835,28836,28837,28838,28920,28961,28965,29128,29335,29735,29768,29774,29819,29820,29822,29826,29829,29830,29832,29838,29874,29920,29931,30111,30179,30276,30277,30278,30279,30283,30284,30285,30286,30287,30319,30329,30414,30457,30459,30460,30473,30478,30485,30496,30498,30509,30516,30517,30519,30524,30525,30526,30747,30762,30764,30765,30766,30806,30816,30817,30818,30820,30821,30901,30902,30904,30905,30915,30916,30926,30927,30929,30930,30931,30932,30933,30935,30936,30938,30939,30941,30942,30964,30966,30967,30968,30971,30972,30974,30975,30976,30977,30978,30979,30980,30981,30982,30983,31104,31178,31179,31187,31199,31200,31201,31336,31337,31338,31339,31340,31342,31343,31345,31347,31351,31352,31354,31355,31357,31359,31363,31371,31372,31373,31374,31375,31376,31377,31378,31383,31385,31387,31442,31443,31449,31450,31451,31455,31457,31459,31460,31466,31468,31470,31471,31472,31475,31604,31606,31608,31609,31658,31659,31660,31661,31662,31663,31665,31666,31667,31669,31671,31675,31676,31678,31681,36886,36891,37626) +AND `Reference` IN ( +26040, -- Occurrences: 165, Frostweave Cloth +26001, -- Occurrences: 62, Grey Loot +26002, -- Occurrences: 22, Grey Loot +26000, -- Occurrences: 20, Grey Loot +26010, -- Occurrences: 14, Green Loot +26009, -- Occurrences: 8, Green Loot +26012, -- Occurrences: 8, Green Loot +26004, -- Occurrences: 6, Green Loot +26011, -- Occurrences: 6, Green Loot +24727, -- Occurrences: 6, Scrolls +26003, -- Occurrences: 4, Green Loot +26008, -- Occurrences: 4, Green Loot +26013, -- Occurrences: 4, Green Loot +26005, -- Occurrences: 2, Green Loot +26006, -- Occurrences: 2, Green Loot +26007, -- Occurrences: 2, Green Loot +26014 -- Occurrences: 2, Green Loot +); + +DELETE FROM `conditions` +WHERE `SourceGroup` IN (30660,30666,30667,30695,30893,32191,30668,23956,23960,23961,24069,24071,24078,24079,24080,24082,24083,24084,24085,24849,26550,26553,26554,26555,26620,26621,26622,26623,26624,26625,26626,26628,26635,26636,26637,26638,26639,26641,26669,26670,26672,26694,26696,26716,26722,26727,26728,26729,26730,26734,26735,26737,26782,26792,26800,26802,26805,26830,27431,27633,27635,27636,27639,27640,27641,27729,27731,27734,27736,27871,27960,27961,27962,27963,27964,27965,27966,27969,27970,27971,27972,28201,28231,28249,28368,28410,28419,28547,28578,28579,28580,28581,28582,28583,28584,28732,28734,28826,28835,28836,28837,28838,28920,28961,28965,29128,29335,29735,29768,29774,29819,29820,29822,29826,29829,29830,29832,29838,29874,29920,29931,30111,30179,30276,30277,30278,30279,30283,30284,30285,30286,30287,30319,30329,30414,30457,30459,30460,30473,30478,30485,30496,30498,30509,30516,30517,30519,30524,30525,30526,30747,30762,30764,30765,30766,30806,30816,30817,30818,30820,30821,30901,30902,30904,30905,30915,30916,30926,30927,30929,30930,30931,30932,30933,30935,30936,30938,30939,30941,30942,30964,30966,30967,30968,30971,30972,30974,30975,30976,30977,30978,30979,30980,30981,30982,30983,31104,31178,31179,31187,31199,31200,31201,31336,31337,31338,31339,31340,31342,31343,31345,31347,31351,31352,31354,31355,31357,31359,31363,31371,31372,31373,31374,31375,31376,31377,31378,31383,31385,31387,31442,31443,31449,31450,31451,31455,31457,31459,31460,31466,31468,31470,31471,31472,31475,31604,31606,31608,31609,31658,31659,31660,31661,31662,31663,31665,31666,31667,31669,31671,31675,31676,31678,31681,36886,36891,37626) +AND `SourceTypeOrReferenceId` = 1 +AND `SourceEntry` IN (43507, 43508, 43509, 43510, 43876, 42178, 39152, 42176, 42172, 42177, 42173, 42175); + +-- Violet Hold +DELETE FROM `creature_loot_template` WHERE `Entry` IN (30660, 31501, 30666, 31486, 30667, 31493, 30668, 31490, 30695, 31503, 30893, 31504, 32191, 32192); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(30660, 1, 1200376, 0, 0, 1, 5, 1, 1, 'Portal Guardian - World Loot Level 76'), +(30660, 33445, 0, 3, 0, 1, 1, 1, 1, 'Portal Guardian - Honeymint Tea'), +(30660, 33454, 0, 6, 0, 1, 1, 1, 1, 'Portal Guardian - Salted Venison'), +(30660, 43852, 0, 15, 0, 1, 0, 1, 1, 'Portal Guardian - Thick Fur Clothing Scraps'), +(30660, 1608000, 1608000, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(30666, 1, 1200375, 0, 0, 1, 5, 1, 1, 'Azure Captain - World Loot Level 75'), +(30666, 33445, 0, 3, 0, 1, 1, 1, 1, 'Azure Captain - Honeymint Tea'), +(30666, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Captain - Salted Venison'), +(30666, 43852, 0, 15, 0, 1, 0, 1, 1, 'Azure Captain - Thick Fur Clothing Scraps'), +(30666, 1608000, 1608000, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(30667, 1, 1200375, 0, 0, 1, 5, 1, 1, 'Azure Sorceror - World Loot Level 75'), +(30667, 33445, 0, 3, 0, 1, 1, 1, 1, 'Azure Sorceror - Honeymint Tea'), +(30667, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Sorceror - Salted Venison'), +(30667, 43852, 0, 15, 0, 1, 0, 1, 1, 'Azure Sorceror - Thick Fur Clothing Scraps'), +(30667, 1608000, 1608000, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(30668, 1, 1200375, 0, 0, 1, 5, 1, 1, 'Azure Raider - World Loot Level 75'), +(30668, 33445, 0, 3, 0, 1, 1, 1, 1, 'Azure Raider - Honeymint Tea'), +(30668, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Raider - Salted Venison'), +(30668, 43852, 0, 15, 0, 1, 0, 1, 1, 'Azure Raider - Thick Fur Clothing Scraps'), +(30668, 1608000, 1608000, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(30695, 1, 1200376, 0, 0, 1, 5, 1, 1, 'Portal Keeper - World Loot Level 76'), +(30695, 33445, 0, 3, 0, 1, 1, 1, 1, 'Portal Keeper - Honeymint Tea'), +(30695, 33454, 0, 6, 0, 1, 1, 1, 1, 'Portal Keeper - Salted Venison'), +(30695, 43852, 0, 15, 0, 1, 0, 1, 1, 'Portal Keeper - Thick Fur Clothing Scraps'), +(30695, 1608000, 1608000, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(30893, 1, 1200376, 0, 0, 1, 5, 1, 1, 'Portal Keeper - World Loot Level 76'), +(30893, 33445, 0, 3, 0, 1, 1, 1, 1, 'Portal Keeper - Honeymint Tea'), +(30893, 33454, 0, 6, 0, 1, 1, 1, 1, 'Portal Keeper - Salted Venison'), +(30893, 43852, 0, 15, 0, 1, 0, 1, 1, 'Portal Keeper - Thick Fur Clothing Scraps'), +(30893, 1608000, 1608000, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(31486, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Azure Captain (1) - World Loot Level 81'), +(31486, 33445, 0, 3, 0, 1, 1, 1, 1, 'Azure Captain - Honeymint Tea'), +(31486, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Captain - Salted Venison'), +(31486, 43852, 0, 15, 0, 1, 0, 1, 1, 'Azure Captain - Thick Fur Clothing Scraps'), +(31486, 1608100, 1608100, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(31490, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Azure Raider (1) - World Loot Level 80'), +(31490, 33445, 0, 3, 0, 1, 1, 1, 1, 'Azure Raider - Honeymint Tea'), +(31490, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Raider - Salted Venison'), +(31490, 43852, 0, 15, 0, 1, 0, 1, 1, 'Azure Raider - Thick Fur Clothing Scraps'), +(31490, 1608100, 1608100, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(31493, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Azure Sorceror (1) - World Loot Level 80'), +(31493, 33445, 0, 3, 0, 1, 1, 1, 1, 'Azure Sorceror - Honeymint Tea'), +(31493, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Sorceror - Salted Venison'), +(31493, 43852, 0, 15, 0, 1, 0, 1, 1, 'Azure Sorceror - Thick Fur Clothing Scraps'), +(31493, 1608100, 1608100, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(31501, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Portal Guardian (1) - World Loot Level 81'), +(31501, 33445, 0, 3, 0, 1, 1, 1, 1, 'Portal Guardian (1) - Honeymint Tea'), +(31501, 33454, 0, 6, 0, 1, 1, 1, 1, 'Portal Guardian (1) - Salted Venison'), +(31501, 43852, 0, 15, 0, 1, 0, 1, 1, 'Portal Guardian (1) - Thick Fur Clothing Scraps'), +(31501, 1608100, 1608100, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(31503, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Portal Keeper (1) - World Loot Level 81'), +(31503, 33445, 0, 3, 0, 1, 1, 1, 1, 'Portal Keeper (1) - Honeymint Tea'), +(31503, 33454, 0, 6, 0, 1, 1, 1, 1, 'Portal Keeper (1) - Salted Venison'), +(31503, 43852, 0, 15, 0, 1, 0, 1, 1, 'Portal Keeper (1) - Thick Fur Clothing Scraps'), +(31503, 1608100, 1608100, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(31504, 1, 1200381, 0, 0, 1, 5, 1, 1, 'Portal Keeper (1) - World Loot Level 81'), +(31504, 33445, 0, 3, 0, 1, 1, 1, 1, 'Portal Keeper - Honeymint Tea'), +(31504, 33454, 0, 6, 0, 1, 1, 1, 1, 'Portal Keeper - Salted Venison'), +(31504, 43852, 0, 15, 0, 1, 0, 1, 1, 'Portal Keeper - Thick Fur Clothing Scraps'), +(31504, 1608100, 1608100, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(32191, 1, 1200375, 0, 0, 1, 5, 1, 1, 'Azure Stalker - World Loot Level 75'), +(32191, 33445, 0, 3, 0, 1, 1, 1, 1, 'Azure Stalker - Honeymint Tea'), +(32191, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Stalker - Salted Venison'), +(32191, 43852, 0, 15, 0, 1, 0, 1, 1, 'Azure Stalker - Thick Fur Clothing Scraps'), +(32191, 1608000, 1608000, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'), +(32192, 1, 1200380, 0, 0, 1, 5, 1, 1, 'Azure Stalker (1) - World Loot Level 80'), +(32192, 33445, 0, 3, 0, 1, 1, 1, 1, 'Azure Stalker - Honeymint Tea'), +(32192, 33454, 0, 6, 0, 1, 1, 1, 1, 'Azure Stalker - Salted Venison'), +(32192, 43852, 0, 15, 0, 1, 0, 1, 1, 'Azure Stalker - Thick Fur Clothing Scraps'), +(32192, 1608100, 1608100, 3, 0, 1, 0, 1, 1, 'Dungeon Trash Rares'); + +-- Add Frostweave Cloth or Detach them from World Loot +DELETE FROM `creature_loot_template` WHERE `Entry` IN (23643,23644,23645,23651,23652,23653,23654,23655,23656,23657,23658,23660,23661,23662,23663,23664,23665,23666,23667,23668,23669,23670,23672,23673,23674,23675,23676,23677,23678,23711,23760,23793,23794,23796,23866,23871,23875,23883,23931,23932,23934,23940,23946,23967,23989,23990,23991,23992,24013,24014,24015,24016,24030,24073,24084,24116,24161,24162,24169,24212,24213,24214,24215,24216,24249,24250,24286,24334,24485,24533,24540,24546,24562,24567,24628,24635,24638,24642,24644,24676,24713,24779,24788,24789,24846,24871,24872,24957,25026,25209,25227,25294,25316,25350,25351,25353,25378,25383,25386,25392,25393,25396,25427,25428,25429,25430,25432,25433,25434,25448,25449,25467,25468,25470,25479,25496,25501,25520,25521,25522,25523,25605,25609,25611,25613,25615,25619,25650,25651,25660,25668,25684,25713,25719,25760,25788,25800,25803,25806,25836,25839,25843,25880,25979,25981,26073,26076,26103,26115,26126,26165,26196,26197,26198,26199,26201,26202,26252,26257,26266,26268,26270,26280,26295,26319,26334,26336,26343,26344,26348,26356,26357,26389,26405,26408,26409,26410,26411,26413,26414,26416,26425,26428,26434,26436,26447,26449,26451,26455,26457,26461,26480,26481,26492,26493,26496,26544,26575,26577,26605,26606,26655,26658,26663,26679,26681,26704,26705,26708,26762,26769,26770,26771,26786,26795,26797,26811,26812,26815,26816,26820,26823,26825,26827,26891,26919,26920,26921,26922,26923,26926,26942,26943,26946,26948,26965,27004,27005,27020,27024,27117,27118,27177,27202,27203,27206,27207,27209,27211,27220,27224,27225,27226,27229,27233,27234,27235,27236,27237,27238,27246,27259,27260,27272,27278,27279,27283,27284,27286,27287,27288,27289,27330,27332,27333,27340,27342,27343,27355,27356,27357,27358,27360,27362,27363,27367,27370,27371,27401,27410,27416,27424,27470,27493,27508,27533,27534,27539,27545,27546,27547,27551,27552,27554,27555,27570,27615,27627,27676,27680,27699,27701,27731,27797,27799,27800,27805,27823,27824,27826,27830,27835,27836,27926,27927,27941,28022,28023,28026,28034,28035,28036,28080,28081,28101,28108,28123,28124,28158,28186,28188,28257,28268,28303,28345,28373,28388,28402,28403,28412,28414,28417,28418,28419,28442,28465,28495,28496,28504,28519,28538,28564,28565,28575,28600,28602,28603,28641,28750,28802,28803,28843,28848,28861,28916,28917,28918,28988,29123,29129,29133,29211,29235,29236,29237,29323,29329,29330,29331,29332,29333,29338,29369,29370,29374,29376,29377,29404,29407,29409,29413,29426,29427,29449,29450,29451,29498,29518,29569,29586,29592,29622,29623,29646,29652,29654,29656,29695,29697,29699,29717,29719,29720,29722,29738,29792,29793,29843,29862,29874,29875,29880,30037,30046,30146,30147,30202,30204,30205,30243,30250,30287,30333,30541,30543,30597,30632,30687,30689,30701,30725,30746,30751,30856,30860,30863,30864,30865,30868,30894,30920,30921,30922,30931,30949,30951,30952,30957,30958,30960,31037,31039,31042,31043,31140,31145,31147,31150,31152,31155,31201,31231,31258,31267,31396,31401,31402,31403,31411,31468,31554,31671,31681,31718,31731,31738,31746,31754,31783,31787,31843,31847,31853,31900,32149,32164,32236,32238,32250,32255,32257,32259,32262,32263,32268,32276,32279,32284,32285,32289,32290,32291,32297,32349,32507,32572,23956,23960,23961,24069,24071,24078,24079,24080,24082,24085,24849,26550,26553,26554,26555,26620,26621,26623,26624,26626,26635,26636,26637,26638,26639,26641,26669,26670,26694,26696,26716,26722,26727,26728,26729,26734,26735,26800,26802,26805,26830,27431,27633,27635,27639,27640,27729,27734,27736,27871,27960,27961,27962,27963,27964,27965,27966,27969,28201,28249,28368,28410,28578,28579,28580,28581,28582,28835,28836,28837,28838,28920,28961,28965,29819,29820,29822,29826,29829,29832,29838,29920,29931,30111,30179,30276,30277,30278,30283,30284,30285,30286,30319,30414,30457,30459,30460,30478,30485,30496,30498,30509,30516,30517,30660,30666,30667,30668,30695,30747,30764,30765,30766,30806,30816,30817,30818,30820,30821,30893,30901,30904,30915,30916,30926,30927,30929,30930,30932,30933,30935,30936,30939,30966,30967,30968,30971,30972,30974,30975,30976,30977,30980,30981,30982,31178,31179,31187,31199,31200,31338,31339,31340,31342,31345,31347,31351,31352,31354,31355,31357,31359,31363,31371,31372,31373,31374,31375,31376,31377,31378,31442,31443,31450,31451,31457,31459,31460,31466,31471,31472,31475,31486,31490,31493,31501,31503,31504,31658,31659,31660,31661,31662,31663,31666,31667,31675,32191,32192) AND +`Item` = 33470 AND `Reference` IN (1270001,1270002); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `Comment`) VALUES +(23643, 33470, 1270001, 25, 'Unstable Mur\'ghoul - Frostweave Cloth Normal'), +(23644, 33470, 1270001, 25, 'Mur\'ghoul Flesheater - Frostweave Cloth Normal'), +(23645, 33470, 1270001, 25, 'Mur\'ghoul Corrupter - Frostweave Cloth Normal'), +(23651, 33470, 1270001, 25, 'Dragonflayer Tribesman - Frostweave Cloth Normal'), +(23652, 33470, 1270001, 25, 'Dragonflayer Vrykul - Frostweave Cloth Normal'), +(23653, 33470, 1270001, 25, 'Winterskorn Spearman - Frostweave Cloth Normal'), +(23654, 33470, 1270001, 25, 'Dragonflayer Warrior - Frostweave Cloth Normal'), +(23655, 33470, 1270001, 25, 'Winterskorn Bonegrinder - Frostweave Cloth Normal'), +(23656, 33470, 1270001, 25, 'Dragonflayer Rune-Seer - Frostweave Cloth Normal'), +(23657, 33470, 1270001, 25, 'Winterskorn Skald - Frostweave Cloth Normal'), +(23658, 33470, 1270001, 25, 'Dragonflayer Death Weaver - Frostweave Cloth Normal'), +(23660, 33470, 1270001, 25, 'Dragonflayer Thane - Frostweave Cloth Normal'), +(23661, 33470, 1270001, 25, 'Winterskorn Tribesman - Frostweave Cloth Normal'), +(23662, 33470, 1270001, 25, 'Winterskorn Woodsman - Frostweave Cloth Normal'), +(23663, 33470, 1270001, 25, 'Winterskorn Shield-Maiden - Frostweave Cloth Normal'), +(23664, 33470, 1270001, 25, 'Winterskorn Warrior - Frostweave Cloth Normal'), +(23665, 33470, 1270001, 25, 'Winterskorn Raider - Frostweave Cloth Normal'), +(23666, 33470, 1270001, 25, 'Winterskorn Berserker - Frostweave Cloth Normal'), +(23667, 33470, 1270001, 25, 'Winterskorn Rune-Seer - Frostweave Cloth Normal'), +(23668, 33470, 1270001, 25, 'Winterskorn Rune-Caster - Frostweave Cloth Normal'), +(23669, 33470, 1270001, 25, 'Winterskorn Oracle - Frostweave Cloth Normal'), +(23670, 33470, 1270001, 25, 'Winterskorn Elder - Frostweave Cloth Normal'), +(23672, 33470, 1270001, 25, 'Iron Rune Worker - Frostweave Cloth Normal'), +(23673, 33470, 1270001, 25, 'Iron Rune Steelguard - Frostweave Cloth Normal'), +(23674, 33470, 1270001, 25, 'Iron Rune Sage - Frostweave Cloth Normal'), +(23675, 33470, 1270001, 25, 'Iron Rune Runemaster - Frostweave Cloth Normal'), +(23676, 33470, 1270001, 25, 'Iron Rune Destroyer - Frostweave Cloth Normal'), +(23677, 33470, 1270001, 25, 'Frost Nymph - Frostweave Cloth Normal'), +(23678, 33470, 1270001, 25, 'Chill Nymph - Frostweave Cloth Normal'), +(23711, 33470, 1270001, 25, 'Iron Rune Laborer - Frostweave Cloth Normal'), +(23760, 33470, 1270001, 25, 'Forsaken Plaguebringer - Frostweave Cloth Normal'), +(23793, 33470, 1270001, 25, 'North Fleet Soldier - Frostweave Cloth Normal'), +(23794, 33470, 1270001, 25, 'North Fleet Medic - Frostweave Cloth Normal'), +(23796, 33470, 1270001, 25, 'Iron Rune Binder - Frostweave Cloth Normal'), +(23866, 33470, 1270001, 25, 'North Fleet Sailor - Frostweave Cloth Normal'), +(23871, 33470, 1270001, 25, 'Dragonflayer Handler - Frostweave Cloth Normal'), +(23875, 33470, 1270001, 25, 'Blacksouled Keeper - Frostweave Cloth Normal'), +(23883, 33470, 1270001, 25, 'Forsaken Crossbowman - Frostweave Cloth Normal'), +(23931, 33470, 1270001, 25, 'Oluf the Violent - Frostweave Cloth Normal'), +(23932, 33470, 1270001, 25, 'Yanis the Mystic - Frostweave Cloth Normal'), +(23934, 33470, 1270001, 25, 'North Fleet Salvager - Frostweave Cloth Normal'), +(23940, 33470, 1270001, 25, 'Skeld Drakeson - Frostweave Cloth Normal'), +(23946, 33470, 1270001, 25, 'North Fleet Marksman - Frostweave Cloth Normal'), +(23967, 33470, 1270001, 25, 'Deranged Explorer - Frostweave Cloth Normal'), +(23989, 33470, 1270001, 25, 'Gjalerbron Sleep-Watcher - Frostweave Cloth Normal'), +(23990, 33470, 1270001, 25, 'Gjalerbron Rune-Caster - Frostweave Cloth Normal'), +(23991, 33470, 1270001, 25, 'Gjalerbron Warrior - Frostweave Cloth Normal'), +(23992, 33470, 1270001, 25, 'Putrid Wight - Frostweave Cloth Normal'), +(24013, 33470, 1270001, 25, 'Deathless Watcher - Frostweave Cloth Normal'), +(24014, 33470, 1270001, 25, 'Necrolord - Frostweave Cloth Normal'), +(24015, 33470, 1270001, 25, 'Winterskorn Defender - Frostweave Cloth Normal'), +(24016, 33470, 1270001, 25, 'Ulf the Bloodletter - Frostweave Cloth Normal'), +(24030, 33470, 1270001, 25, 'Iron Rune Stonecaller - Frostweave Cloth Normal'), +(24073, 33470, 1270001, 25, 'Fearsome Horror - Frostweave Cloth Normal'), +(24084, 33470, 1270001, 25, 'Tunneling Ghoul - Frostweave Cloth Normal'), +(24116, 33470, 1270001, 25, 'Winterskorn Scout - Frostweave Cloth Normal'), +(24161, 33470, 1270001, 25, 'Oric the Baleful - Frostweave Cloth Normal'), +(24162, 33470, 1270001, 25, 'Gunnar Thorvardsson - Frostweave Cloth Normal'), +(24169, 33470, 1270001, 25, 'Dragonflayer Lieutenant - Frostweave Cloth Normal'), +(24212, 33470, 1270001, 25, 'Iron Rune Guardian - Frostweave Cloth Normal'), +(24213, 33470, 1270001, 25, 'Firjus the Soul Crusher - Frostweave Cloth Normal'), +(24214, 33470, 1270001, 25, 'Yorus the Flesh Harvester - Frostweave Cloth Normal'), +(24215, 33470, 1270001, 25, 'Jlarborn the Strategist - Frostweave Cloth Normal'), +(24216, 33470, 1270001, 25, 'Dragonflayer Berserker - Frostweave Cloth Normal'), +(24249, 33470, 1270001, 25, 'Dragonflayer Soulreaver - Frostweave Cloth Normal'), +(24250, 33470, 1270001, 25, 'Dragonflayer Fleshripper - Frostweave Cloth Normal'), +(24286, 33470, 1270001, 25, 'Forsaken Spy - Frostweave Cloth Normal'), +(24334, 33470, 1270001, 25, 'Binder Murdis - Frostweave Cloth Normal'), +(24485, 33470, 1270001, 25, 'Servitor Shade - Frostweave Cloth Normal'), +(24533, 33470, 1270001, 25, 'Dragonflayer Defender - Frostweave Cloth Normal'), +(24540, 33470, 1270001, 25, 'Necrotech - Frostweave Cloth Normal'), +(24546, 33470, 1270001, 25, 'Rotgill - Frostweave Cloth Normal'), +(24562, 33470, 1270001, 25, 'Nerub\'ar Invader - Frostweave Cloth Normal'), +(24567, 33470, 1270001, 25, 'Den Vermin - Frostweave Cloth Normal'), +(24628, 33470, 1270001, 25, 'Northsea Duelist - Frostweave Cloth Normal'), +(24635, 33470, 1270001, 25, 'Dragonflayer Harpooner - Frostweave Cloth Normal'), +(24638, 33470, 1270001, 25, 'Keeper Witherleaf - Frostweave Cloth Normal'), +(24642, 33470, 1270001, 25, 'Drunken Northsea Pirate - Frostweave Cloth Normal'), +(24644, 33470, 1270001, 25, 'Harpoon Master Yavus - Frostweave Cloth Normal'), +(24676, 33470, 1270001, 25, 'Crazed Northsea Slaver - Frostweave Cloth Normal'), +(24713, 33470, 1270001, 25, '"Crowleg" Dan - Frostweave Cloth Normal'), +(24779, 33470, 1270001, 25, 'Dragonflayer Ambusher - Frostweave Cloth Normal'), +(24788, 33470, 1270001, 25, 'Jack Adams - Frostweave Cloth Normal'), +(24789, 33470, 1270001, 25, 'Forlorn Soul - Frostweave Cloth Normal'), +(24846, 33470, 1270001, 25, 'Iron Dwarf - Frostweave Cloth Normal'), +(24871, 33470, 1270001, 25, 'Risen Vrykul Ancestor - Frostweave Cloth Normal'), +(24872, 33470, 1270001, 25, 'Blood Shade - Frostweave Cloth Normal'), +(24957, 33470, 1270001, 25, 'Cult Plaguebringer - Frostweave Cloth Normal'), +(25026, 33470, 1270001, 25, 'Mutinous Sea Dog - Frostweave Cloth Normal'), +(25209, 33470, 1270001, 25, 'Claximus - Frostweave Cloth Normal'), +(25227, 33470, 1270001, 25, 'Crypt Crawler - Frostweave Cloth Normal'), +(25294, 33470, 1270001, 25, 'Nerub\'ar Web Lord - Frostweave Cloth Normal'), +(25316, 33470, 1270001, 25, 'Beryl Sorcerer - Frostweave Cloth Normal'), +(25350, 33470, 1270001, 25, 'Risen Longrunner - Frostweave Cloth Normal'), +(25351, 33470, 1270001, 25, 'Ghostly Sage - Frostweave Cloth Normal'), +(25353, 33470, 1270001, 25, 'Beryl Treasure Hunter - Frostweave Cloth Normal'), +(25378, 33470, 1270001, 25, 'En\'kilah Necromancer - Frostweave Cloth Normal'), +(25383, 33470, 1270001, 25, 'En\'kilah Abomination - Frostweave Cloth Normal'), +(25386, 33470, 1270001, 25, 'En\'kilah Crypt Fiend - Frostweave Cloth Normal'), +(25392, 33470, 1270001, 25, 'High Priest Andorath - Frostweave Cloth Normal'), +(25393, 33470, 1270001, 25, 'En\'kilah Ghoul - Frostweave Cloth Normal'), +(25396, 33470, 1270001, 25, 'Naxxanar Skeletal Mage - Frostweave Cloth Normal'), +(25427, 33470, 1270001, 25, 'Kaganishu - Frostweave Cloth Normal'), +(25428, 33470, 1270001, 25, 'Magmoth Shaman - Frostweave Cloth Normal'), +(25429, 33470, 1270001, 25, 'Magmoth Forager - Frostweave Cloth Normal'), +(25430, 33470, 1270001, 25, 'Magmothregar - Frostweave Cloth Normal'), +(25432, 33470, 1270001, 25, 'Mate of Magmothregar - Frostweave Cloth Normal'), +(25433, 33470, 1270001, 25, 'Offspring of Magmothregar - Frostweave Cloth Normal'), +(25434, 33470, 1270001, 25, 'Magmoth Crusher - Frostweave Cloth Normal'), +(25448, 33470, 1270001, 25, 'Curator Insivius - Frostweave Cloth Normal'), +(25449, 33470, 1270001, 25, 'Beryl Reclaimer - Frostweave Cloth Normal'), +(25467, 33470, 1270001, 25, 'Bloodspore Harvester - Frostweave Cloth Normal'), +(25468, 33470, 1270001, 25, 'Bloodspore Roaster - Frostweave Cloth Normal'), +(25470, 33470, 1270001, 25, 'Bloodspore Firestarter - Frostweave Cloth Normal'), +(25479, 33470, 1270001, 25, 'Kvaldir Mistweaver - Frostweave Cloth Normal'), +(25496, 33470, 1270001, 25, 'Kvaldir Mist Lord - Frostweave Cloth Normal'), +(25501, 33470, 1270001, 25, 'Gammoth Tender - Frostweave Cloth Normal'), +(25520, 33470, 1270001, 25, 'Skadir Runecaster - Frostweave Cloth Normal'), +(25521, 33470, 1270001, 25, 'Skadir Longboatsman - Frostweave Cloth Normal'), +(25522, 33470, 1270001, 25, 'Skadir Raider - Frostweave Cloth Normal'), +(25523, 33470, 1270001, 25, 'Skadir Mariner - Frostweave Cloth Normal'), +(25605, 33470, 1270001, 25, 'Clandestine Cultist - Frostweave Cloth Normal'), +(25609, 33470, 1270001, 25, 'En\'kilah Necrolord - Frostweave Cloth Normal'), +(25611, 33470, 1270001, 25, 'Warsong Aberration - Frostweave Cloth Normal'), +(25613, 33470, 1270001, 25, 'Skadir Mistweaver - Frostweave Cloth Normal'), +(25615, 33470, 1270001, 25, 'Plagued Magnataur - Frostweave Cloth Normal'), +(25619, 33470, 1270001, 25, 'Nerub\'ar Warrior - Frostweave Cloth Normal'), +(25650, 33470, 1270001, 25, 'Plagued Scavenger - Frostweave Cloth Normal'), +(25651, 33470, 1270001, 25, 'Cultist Necrolyte - Frostweave Cloth Normal'), +(25660, 33470, 1270001, 25, 'Festering Ghoul - Frostweave Cloth Normal'), +(25668, 33470, 1270001, 25, 'Vengeful Taunka Spirit - Frostweave Cloth Normal'), +(25684, 33470, 1270001, 25, 'Talramas Abomination - Frostweave Cloth Normal'), +(25713, 33470, 1270001, 25, 'Blue Drakonid Supplicant - Frostweave Cloth Normal'), +(25719, 33470, 1270001, 25, 'Coldarra Spellbinder - Frostweave Cloth Normal'), +(25760, 33470, 1270001, 25, 'Kvaldir Raider - Frostweave Cloth Normal'), +(25788, 33470, 1270001, 25, 'Weakened Magnataur Huntress - Frostweave Cloth Normal'), +(25800, 33470, 1270001, 25, 'Clam Master K - Frostweave Cloth Normal'), +(25803, 33470, 1270001, 25, 'Karen "I Don\'t Caribou" the Culler - Frostweave Cloth Normal'), +(25806, 33470, 1270001, 25, 'Loot Crazed Poacher - Frostweave Cloth Normal'), +(25836, 33470, 1270001, 25, 'Loot Crazed Diver - Frostweave Cloth Normal'), +(25839, 33470, 1270001, 25, 'Northsea Mercenary - Frostweave Cloth Normal'), +(25843, 33470, 1270001, 25, 'Northsea Thug - Frostweave Cloth Normal'), +(25880, 33470, 1270001, 25, 'Minion of Kaw - Frostweave Cloth Normal'), +(25979, 33470, 1270001, 25, 'Loot Crazed Hunter - Frostweave Cloth Normal'), +(25981, 33470, 1270001, 25, 'Scourged Footman - Frostweave Cloth Normal'), +(26073, 33470, 1270001, 25, 'High Priest Talet-Kha - Frostweave Cloth Normal'), +(26076, 33470, 1270001, 25, 'High Priest Naferset - Frostweave Cloth Normal'), +(26103, 33470, 1270001, 25, 'Darkfallen Deathblade - Frostweave Cloth Normal'), +(26115, 33470, 1270001, 25, 'Darkfallen Bloodbearer - Frostweave Cloth Normal'), +(26126, 33470, 1270001, 25, 'Bone Warrior - Frostweave Cloth Normal'), +(26165, 33470, 1270001, 25, 'Damned Taunka Spirit - Frostweave Cloth Normal'), +(26196, 33470, 1270001, 25, 'Loguhn - Frostweave Cloth Normal'), +(26197, 33470, 1270001, 25, 'Snowfall Glade Reaver - Frostweave Cloth Normal'), +(26198, 33470, 1270001, 25, 'Snowfall Glade Wolvar - Frostweave Cloth Normal'), +(26199, 33470, 1270001, 25, 'Snowfall Glade Den Mother - Frostweave Cloth Normal'), +(26201, 33470, 1270001, 25, 'Snowfall Glade Shaman - Frostweave Cloth Normal'), +(26202, 33470, 1270001, 25, 'Ziggurat Defender - Frostweave Cloth Normal'), +(26252, 33470, 1270001, 25, 'Captain Jacobs - Frostweave Cloth Normal'), +(26257, 33470, 1270001, 25, 'Surge Needle Sorcerer - Frostweave Cloth Normal'), +(26266, 33470, 1270001, 25, 'Heigarr the Horrible - Frostweave Cloth Normal'), +(26268, 33470, 1270001, 25, 'Rune Reaver - Frostweave Cloth Normal'), +(26270, 33470, 1270001, 25, 'Iron Rune-Shaper - Frostweave Cloth Normal'), +(26280, 33470, 1270001, 25, 'Dragonblight Mage Hunter - Frostweave Cloth Normal'), +(26295, 33470, 1270001, 25, 'Magnataur Patriarch - Frostweave Cloth Normal'), +(26319, 33470, 1270001, 25, 'Anub\'ar Cultist - Frostweave Cloth Normal'), +(26334, 33470, 1270001, 25, 'Forgemaster Damrath - Frostweave Cloth Normal'), +(26336, 33470, 1270001, 25, 'Indu\'le Mystic - Frostweave Cloth Normal'), +(26343, 33470, 1270001, 25, 'Indu\'le Fisherman - Frostweave Cloth Normal'), +(26344, 33470, 1270001, 25, 'Indu\'le Warrior - Frostweave Cloth Normal'), +(26348, 33470, 1270001, 25, 'Iron Thane Argrum - Frostweave Cloth Normal'), +(26356, 33470, 1270001, 25, 'Redfang Hunter - Frostweave Cloth Normal'), +(26357, 33470, 1270001, 25, 'Frostpaw Warrior - Frostweave Cloth Normal'), +(26389, 33470, 1270001, 25, 'Solstice Hunter - Frostweave Cloth Normal'), +(26405, 33470, 1270001, 25, 'Iron Thane Furyhammer - Frostweave Cloth Normal'), +(26408, 33470, 1270001, 25, 'Iron Rune-Smith - Frostweave Cloth Normal'), +(26409, 33470, 1270001, 25, 'Rune-Smith Durar - Frostweave Cloth Normal'), +(26410, 33470, 1270001, 25, 'Rune-Smith Kathorn - Frostweave Cloth Normal'), +(26411, 33470, 1270001, 25, 'Deranged Indu\'le Villager - Frostweave Cloth Normal'), +(26413, 33470, 1270001, 25, 'Anub\'ar Dreadweaver - Frostweave Cloth Normal'), +(26414, 33470, 1270001, 25, 'Runic Lightning Gunner - Frostweave Cloth Normal'), +(26416, 33470, 1270001, 25, 'Wolfcult Initiate - Frostweave Cloth Normal'), +(26425, 33470, 1270001, 25, 'Drakkari Warrior - Frostweave Cloth Normal'), +(26428, 33470, 1270001, 25, 'Frostpaw Shaman - Frostweave Cloth Normal'), +(26434, 33470, 1270001, 25, 'Frostpaw Trapper - Frostweave Cloth Normal'), +(26436, 33470, 1270001, 25, 'Redfang Elder - Frostweave Cloth Normal'), +(26447, 33470, 1270001, 25, 'Drakkari Shaman - Frostweave Cloth Normal'), +(26449, 33470, 1270001, 25, 'Gamel the Cruel - Frostweave Cloth Normal'), +(26451, 33470, 1270001, 25, 'Ragnar Drakkarlund - Frostweave Cloth Normal'), +(26455, 33470, 1270001, 25, 'Moonrest Highborne - Frostweave Cloth Normal'), +(26457, 33470, 1270001, 25, 'Diseased Drakkari - Frostweave Cloth Normal'), +(26461, 33470, 1270001, 25, 'Scourge Corpserender - Frostweave Cloth Normal'), +(26480, 33470, 1270001, 25, 'Magnataur Youngling - Frostweave Cloth Normal'), +(26481, 33470, 1270001, 25, 'Magnataur Alpha - Frostweave Cloth Normal'), +(26492, 33470, 1270001, 25, 'Wastes Digger - Frostweave Cloth Normal'), +(26493, 33470, 1270001, 25, 'Wastes Taskmaster - Frostweave Cloth Normal'), +(26496, 33470, 1270001, 25, 'Wind Trader Mu\'fah - Frostweave Cloth Normal'), +(26544, 33470, 1270001, 25, 'Warlord Zim\'bo - Frostweave Cloth Normal'), +(26575, 33470, 1270001, 25, 'Coldwind Waste Huntress - Frostweave Cloth Normal'), +(26577, 33470, 1270001, 25, 'Coldwind Witch - Frostweave Cloth Normal'), +(26605, 33470, 1270001, 25, 'Anub\'ar Underlord - Frostweave Cloth Normal'), +(26606, 33470, 1270001, 25, 'Anub\'ar Slayer - Frostweave Cloth Normal'), +(26655, 33470, 1270001, 25, 'High Cultist Zangus - Frostweave Cloth Normal'), +(26658, 33470, 1270001, 25, 'Reckless Scavenger - Frostweave Cloth Normal'), +(26663, 33470, 1270001, 25, 'Winterskorn Hunter - Frostweave Cloth Normal'), +(26679, 33470, 1270001, 25, 'Silverbrook Trapper - Frostweave Cloth Normal'), +(26681, 33470, 1270001, 25, 'Grumbald One-Eye - Frostweave Cloth Normal'), +(26704, 33470, 1270001, 25, 'Drakkari Defender - Frostweave Cloth Normal'), +(26705, 33470, 1270001, 25, 'Snowplain Disciple - Frostweave Cloth Normal'), +(26708, 33470, 1270001, 25, 'Silverbrook Villager - Frostweave Cloth Normal'), +(26762, 33470, 1270001, 25, 'Captain Emmy Malin - Frostweave Cloth Normal'), +(26769, 33470, 1270001, 25, 'Anok\'ra the Manipulator - Frostweave Cloth Normal'), +(26770, 33470, 1270001, 25, 'Tivax the Breaker - Frostweave Cloth Normal'), +(26771, 33470, 1270001, 25, 'Sinok the Shadowrager - Frostweave Cloth Normal'), +(26786, 33470, 1270001, 25, 'Iron Rune Avenger - Frostweave Cloth Normal'), +(26795, 33470, 1270001, 25, 'Drakkari Oracle - Frostweave Cloth Normal'), +(26797, 33470, 1270001, 25, 'Drakkari Protector - Frostweave Cloth Normal'), +(26811, 33470, 1270001, 25, 'Ancient Drakkari Warmonger - Frostweave Cloth Normal'), +(26812, 33470, 1270001, 25, 'Ancient Drakkari Soothsayer - Frostweave Cloth Normal'), +(26815, 33470, 1270001, 25, 'Lieutenant Ta\'zinni - Frostweave Cloth Normal'), +(26816, 33470, 1270001, 25, 'Focus Wizard - Frostweave Cloth Normal'), +(26820, 33470, 1270001, 25, 'Iron Rune-Weaver - Frostweave Cloth Normal'), +(26823, 33470, 1270001, 25, 'Howling Wolvar Trainer - Frostweave Cloth Normal'), +(26825, 33470, 1270001, 25, 'Howling Wolvar Shaman - Frostweave Cloth Normal'), +(26827, 33470, 1270001, 25, 'Howling Wolvar Lookout - Frostweave Cloth Normal'), +(26891, 33470, 1270001, 25, 'Undead Miner - Frostweave Cloth Normal'), +(26919, 33470, 1270001, 25, 'Drak\'aguul - Frostweave Cloth Normal'), +(26920, 33470, 1270001, 25, 'Overseer Durval - Frostweave Cloth Normal'), +(26921, 33470, 1270001, 25, 'Overseer Korgan - Frostweave Cloth Normal'), +(26922, 33470, 1270001, 25, 'Overseer Lochli - Frostweave Cloth Normal'), +(26923, 33470, 1270001, 25, 'Overseer Brunon - Frostweave Cloth Normal'), +(26926, 33470, 1270001, 25, 'Duke Vallenhal - Frostweave Cloth Normal'), +(26942, 33470, 1270001, 25, 'Decrepit Necromancer - Frostweave Cloth Normal'), +(26943, 33470, 1270001, 25, 'Battered Drakkari Berserker - Frostweave Cloth Normal'), +(26946, 33470, 1270001, 25, 'Reanimated Drakkari Tribesman - Frostweave Cloth Normal'), +(26948, 33470, 1270001, 25, 'Hulking Atrocity - Frostweave Cloth Normal'), +(26965, 33470, 1270001, 25, 'Tormented Drakkari - Frostweave Cloth Normal'), +(27004, 33470, 1270001, 25, 'Icefist - Frostweave Cloth Normal'), +(27005, 33470, 1270001, 25, 'Chilltusk - Frostweave Cloth Normal'), +(27020, 33470, 1270001, 25, 'Bloodmoon Worgen - Frostweave Cloth Normal'), +(27024, 33470, 1270001, 25, 'Bloodmoon Cultist - Frostweave Cloth Normal'), +(27117, 33470, 1270001, 25, 'Amberpine Scout - Frostweave Cloth Normal'), +(27118, 33470, 1270001, 25, 'Conquest Hold Raider - Frostweave Cloth Normal'), +(27177, 33470, 1270001, 25, 'Iron Rune Overseer - Frostweave Cloth Normal'), +(27202, 33470, 1270001, 25, 'Onslaught Raven Priest - Frostweave Cloth Normal'), +(27203, 33470, 1270001, 25, 'Onslaught Footman - Frostweave Cloth Normal'), +(27206, 33470, 1270001, 25, 'Onslaught Knight - Frostweave Cloth Normal'), +(27207, 33470, 1270001, 25, 'Onslaught Workman - Frostweave Cloth Normal'), +(27209, 33470, 1270001, 25, 'Torturer LeCraft - Frostweave Cloth Normal'), +(27211, 33470, 1270001, 25, 'Onslaught Executioner - Frostweave Cloth Normal'), +(27220, 33470, 1270001, 25, 'Forgotten Captain - Frostweave Cloth Normal'), +(27224, 33470, 1270001, 25, 'Forgotten Knight - Frostweave Cloth Normal'), +(27225, 33470, 1270001, 25, 'Forgotten Rifleman - Frostweave Cloth Normal'), +(27226, 33470, 1270001, 25, 'Forgotten Peasant - Frostweave Cloth Normal'), +(27229, 33470, 1270001, 25, 'Forgotten Footman - Frostweave Cloth Normal'), +(27233, 33470, 1270001, 25, 'Onslaught Deckhand - Frostweave Cloth Normal'), +(27234, 33470, 1270001, 25, 'Blacksmith Goodman - Frostweave Cloth Normal'), +(27235, 33470, 1270001, 25, 'Lead Cannoneer Zierhut - Frostweave Cloth Normal'), +(27236, 33470, 1270001, 25, 'Stable Master Mercer - Frostweave Cloth Normal'), +(27237, 33470, 1270001, 25, 'Commander Jordan - Frostweave Cloth Normal'), +(27238, 33470, 1270001, 25, 'Foreman Kaleiki - Frostweave Cloth Normal'), +(27246, 33470, 1270001, 25, 'Bishop Street - Frostweave Cloth Normal'), +(27259, 33470, 1270001, 25, 'Dragonflayer Flamebinder - Frostweave Cloth Normal'), +(27260, 33470, 1270001, 25, 'Dragonflayer Huscarl - Frostweave Cloth Normal'), +(27272, 33470, 1270001, 25, 'Risen Villager - Frostweave Cloth Normal'), +(27278, 33470, 1270001, 25, 'Snowplain Zealot - Frostweave Cloth Normal'), +(27279, 33470, 1270001, 25, 'Snowplain Shaman - Frostweave Cloth Normal'), +(27283, 33470, 1270001, 25, 'Risen Wintergarde Mage - Frostweave Cloth Normal'), +(27284, 33470, 1270001, 25, 'Risen Wintergarde Defender - Frostweave Cloth Normal'), +(27286, 33470, 1270001, 25, 'Dreadbone Invader - Frostweave Cloth Normal'), +(27287, 33470, 1270001, 25, 'Mindless Wight - Frostweave Cloth Normal'), +(27288, 33470, 1270001, 25, 'Death Knight Champion - Frostweave Cloth Normal'), +(27289, 33470, 1270001, 25, 'Naxxramas Necrolord - Frostweave Cloth Normal'), +(27330, 33470, 1270001, 25, 'Onslaught Infantry - Frostweave Cloth Normal'), +(27332, 33470, 1270001, 25, 'Onslaught Scout - Frostweave Cloth Normal'), +(27333, 33470, 1270001, 25, 'Onslaught Mason - Frostweave Cloth Normal'), +(27340, 33470, 1270001, 25, 'Bloodpaw Marauder - Frostweave Cloth Normal'), +(27342, 33470, 1270001, 25, 'Bloodpaw Warrior - Frostweave Cloth Normal'), +(27343, 33470, 1270001, 25, 'Bloodpaw Shaman - Frostweave Cloth Normal'), +(27355, 33470, 1270001, 25, 'Rothin the Decaying - Frostweave Cloth Normal'), +(27356, 33470, 1270001, 25, 'Burning Depths Necrolyte - Frostweave Cloth Normal'), +(27357, 33470, 1270001, 25, 'Onslaught Raven Archon - Frostweave Cloth Normal'), +(27358, 33470, 1270001, 25, 'Burning Depths Necromancer - Frostweave Cloth Normal'), +(27360, 33470, 1270001, 25, 'Smoldering Skeleton - Frostweave Cloth Normal'), +(27362, 33470, 1270001, 25, 'Smoldering Construct - Frostweave Cloth Normal'), +(27363, 33470, 1270001, 25, 'Smoldering Geist - Frostweave Cloth Normal'), +(27367, 33470, 1270001, 25, 'Onslaught Death Knight - Frostweave Cloth Normal'), +(27370, 33470, 1270001, 25, 'Vengeful Geist - Frostweave Cloth Normal'), +(27371, 33470, 1270001, 25, 'Synipus - Frostweave Cloth Normal'), +(27401, 33470, 1270001, 25, 'Risen Wintergarde Miner - Frostweave Cloth Normal'), +(27410, 33470, 1270001, 25, 'Scourge Siegesmith - Frostweave Cloth Normal'), +(27416, 33470, 1270001, 25, 'Pipthwack - Frostweave Cloth Normal'), +(27424, 33470, 1270001, 25, 'Conquest Hold Marauder - Frostweave Cloth Normal'), +(27470, 33470, 1270001, 25, 'Conquest Hold Grunt - Frostweave Cloth Normal'), +(27493, 33470, 1270001, 25, 'Sergeant Bonesnap - Frostweave Cloth Normal'), +(27508, 33470, 1270001, 25, 'Necrolord Amarion - Frostweave Cloth Normal'), +(27533, 33470, 1270001, 25, 'Frigid Geist - Frostweave Cloth Normal'), +(27534, 33470, 1270001, 25, 'Frigid Ghoul - Frostweave Cloth Normal'), +(27539, 33470, 1270001, 25, 'Frigid Necromancer - Frostweave Cloth Normal'), +(27545, 33470, 1270001, 25, 'Katja - Frostweave Cloth Normal'), +(27546, 33470, 1270001, 25, 'Silverbrook Hunter - Frostweave Cloth Normal'), +(27547, 33470, 1270001, 25, 'Vladek - Frostweave Cloth Normal'), +(27551, 33470, 1270001, 25, 'Enraged Apparition - Frostweave Cloth Normal'), +(27552, 33470, 1270001, 25, 'Reanimated Noble - Frostweave Cloth Normal'), +(27554, 33470, 1270001, 25, 'Injured Drakkari Refugee - Frostweave Cloth Normal'), +(27555, 33470, 1270001, 25, 'Drakkari Witch Doctor - Frostweave Cloth Normal'), +(27570, 33470, 1270001, 25, 'Venture Co. Straggler - Frostweave Cloth Normal'), +(27615, 33470, 1270001, 25, 'Scourge Deathspeaker - Frostweave Cloth Normal'), +(27627, 33470, 1270001, 25, 'Tatjana - Frostweave Cloth Normal'), +(27676, 33470, 1270001, 25, 'Silverbrook Defender - Frostweave Cloth Normal'), +(27680, 33470, 1270001, 25, 'Dahlia Suntouch - Frostweave Cloth Normal'), +(27699, 33470, 1270001, 25, 'Gjalerhorn Scavenger - Frostweave Cloth Normal'), +(27701, 33470, 1270001, 25, 'Gjalerhorn Worker - Frostweave Cloth Normal'), +(27731, 33470, 1270001, 25, 'Acolyte - Frostweave Cloth Normal'), +(27797, 33470, 1270001, 25, 'Tattered Abomination - Frostweave Cloth Normal'), +(27799, 33470, 1270001, 25, 'Scourge Technician - Frostweave Cloth Normal'), +(27800, 33470, 1270001, 25, 'Leprous Servant - Frostweave Cloth Normal'), +(27805, 33470, 1270001, 25, 'Necrolord Horus - Frostweave Cloth Normal'), +(27823, 33470, 1270001, 25, 'Naxxramas Dreadguard - Frostweave Cloth Normal'), +(27824, 33470, 1270001, 25, 'Naxxramas Shade - Frostweave Cloth Normal'), +(27826, 33470, 1270001, 25, 'Necrolord X\'avius - Frostweave Cloth Normal'), +(27830, 33470, 1270001, 25, 'Venture Co. Evacuee - Frostweave Cloth Normal'), +(27835, 33470, 1270001, 25, 'Dreadbone Construct - Frostweave Cloth Normal'), +(27836, 33470, 1270001, 25, 'Wailing Soul - Frostweave Cloth Normal'), +(27926, 33470, 1270001, 25, 'Thorvald - Frostweave Cloth Normal'), +(27927, 33470, 1270001, 25, 'Dragonflayer Guardian - Frostweave Cloth Normal'), +(27941, 33470, 1270001, 25, 'Drakkari Plague Spreader - Frostweave Cloth Normal'), +(28022, 33470, 1270001, 25, 'Carrion Eater - Frostweave Cloth Normal'), +(28023, 33470, 1270001, 25, 'Rotting Abomination - Frostweave Cloth Normal'), +(28026, 33470, 1270001, 25, 'Rampaging Geist - Frostweave Cloth Normal'), +(28034, 33470, 1270001, 25, 'Drakkari Snake Handler - Frostweave Cloth Normal'), +(28035, 33470, 1270001, 25, 'Priest of Sseratus - Frostweave Cloth Normal'), +(28036, 33470, 1270001, 25, 'Champion of Sseratus - Frostweave Cloth Normal'), +(28080, 33470, 1270001, 25, 'Frenzyheart Spearbearer - Frostweave Cloth Normal'), +(28081, 33470, 1270001, 25, 'Frenzyheart Scavenger - Frostweave Cloth Normal'), +(28101, 33470, 1270001, 25, 'Blighted Corpse - Frostweave Cloth Normal'), +(28108, 33470, 1270001, 25, 'Bonescythe Ravager - Frostweave Cloth Normal'), +(28123, 33470, 1270001, 25, 'Venture Co. Excavator - Frostweave Cloth Normal'), +(28124, 33470, 1270001, 25, 'Venture Co. Ruffian - Frostweave Cloth Normal'), +(28158, 33470, 1270001, 25, 'Withered Argent Footman - Frostweave Cloth Normal'), +(28186, 33470, 1270001, 25, 'Foreman Swindlegrin - Frostweave Cloth Normal'), +(28188, 33470, 1270001, 25, 'Meatpie - Frostweave Cloth Normal'), +(28257, 33470, 1270001, 25, 'Hath\'ar Necromagus - Frostweave Cloth Normal'), +(28268, 33470, 1270001, 25, 'Scourged Argent Footman - Frostweave Cloth Normal'), +(28303, 33470, 1270001, 25, 'Drakkari Water Binder - Frostweave Cloth Normal'), +(28345, 33470, 1270001, 25, 'Drakkari Spirit - Frostweave Cloth Normal'), +(28373, 33470, 1270001, 25, 'Cultist Infiltrator - Frostweave Cloth Normal'), +(28388, 33470, 1270001, 25, 'Jin\'Alai Warrior - Frostweave Cloth Normal'), +(28402, 33470, 1270001, 25, 'Claw of Har\'koa - Frostweave Cloth Normal'), +(28403, 33470, 1270001, 25, 'Har\'koan Subduer - Frostweave Cloth Normal'), +(28412, 33470, 1270001, 25, 'Hath\'ar Broodmaster - Frostweave Cloth Normal'), +(28414, 33470, 1270001, 25, 'Drakkari Captive - Frostweave Cloth Normal'), +(28417, 33470, 1270001, 25, 'Priest of Rhunok - Frostweave Cloth Normal'), +(28418, 33470, 1270001, 25, 'Drakkari Bear Trapper - Frostweave Cloth Normal'), +(28419, 33470, 1270001, 25, 'Frenzied Geist - Frostweave Cloth Normal'), +(28442, 33470, 1270001, 25, 'Prophet of Rhunok - Frostweave Cloth Normal'), +(28465, 33470, 1270001, 25, 'Heb\'Drakkar Striker - Frostweave Cloth Normal'), +(28495, 33470, 1270001, 25, 'Gawanil - Frostweave Cloth Normal'), +(28496, 33470, 1270001, 25, 'Chulo the Mad - Frostweave Cloth Normal'), +(28504, 33470, 1270001, 25, 'Jin\'Alai Medicine Man - Frostweave Cloth Normal'), +(28519, 33470, 1270001, 25, 'Withered Troll - Frostweave Cloth Normal'), +(28538, 33470, 1270001, 25, 'Cultist Saboteur - Frostweave Cloth Normal'), +(28564, 33470, 1270001, 25, 'Putrid Abomination - Frostweave Cloth Normal'), +(28565, 33470, 1270001, 25, 'Decaying Ghoul - Frostweave Cloth Normal'), +(28575, 33470, 1270001, 25, 'Rhunok\'s Tormentor - Frostweave Cloth Normal'), +(28600, 33470, 1270001, 25, 'Heb\'Drakkar Headhunter - Frostweave Cloth Normal'), +(28602, 33470, 1270001, 25, 'Death\'s Hand Acolyte - Frostweave Cloth Normal'), +(28603, 33470, 1270001, 25, 'Blightguard - Frostweave Cloth Normal'), +(28641, 33470, 1270001, 25, 'Blighted Corpse - Frostweave Cloth Normal'), +(28750, 33470, 1270001, 25, 'Blight Geist - Frostweave Cloth Normal'), +(28802, 33470, 1270001, 25, 'Servant of Drakuru - Frostweave Cloth Normal'), +(28803, 33470, 1270001, 25, 'Drakuru\'s Guard - Frostweave Cloth Normal'), +(28843, 33470, 1270001, 25, 'Bloated Abomination - Frostweave Cloth Normal'), +(28848, 33470, 1270001, 25, 'Prophet of Har\'koa - Frostweave Cloth Normal'), +(28861, 33470, 1270001, 25, 'Mam\'toth Disciple - Frostweave Cloth Normal'), +(28916, 33470, 1270001, 25, 'Tiri - Frostweave Cloth Normal'), +(28917, 33470, 1270001, 25, 'Yara - Frostweave Cloth Normal'), +(28918, 33470, 1270001, 25, 'Drek\'Maz - Frostweave Cloth Normal'), +(28988, 33470, 1270001, 25, 'Akali Subduer - Frostweave Cloth Normal'), +(29123, 33470, 1270001, 25, 'Monstrous Wight - Frostweave Cloth Normal'), +(29129, 33470, 1270001, 25, 'Lost Drakkari Spirit - Frostweave Cloth Normal'), +(29133, 33470, 1270001, 25, 'Disturbed Soul - Frostweave Cloth Normal'), +(29211, 33470, 1270001, 25, 'Drakkari Native - Frostweave Cloth Normal'), +(29235, 33470, 1270001, 25, 'Gundrak Savage - Frostweave Cloth Normal'), +(29236, 33470, 1270001, 25, 'Gundrak Brute - Frostweave Cloth Normal'), +(29237, 33470, 1270001, 25, 'Gundrak Fire-eater - Frostweave Cloth Normal'), +(29323, 33470, 1270001, 25, 'Sifreldar Storm Maiden - Frostweave Cloth Normal'), +(29329, 33470, 1270001, 25, 'Onslaught Paladin - Frostweave Cloth Normal'), +(29330, 33470, 1270001, 25, 'Onslaught Harbor Guard - Frostweave Cloth Normal'), +(29331, 33470, 1270001, 25, 'Sifreldar Runekeeper - Frostweave Cloth Normal'), +(29332, 33470, 1270001, 25, 'Gundrak Bat Rider - Frostweave Cloth Normal'), +(29333, 33470, 1270001, 25, 'Onslaught Gryphon Rider - Frostweave Cloth Normal'), +(29338, 33470, 1270001, 25, 'Onslaught Raven Bishop - Frostweave Cloth Normal'), +(29369, 33470, 1270001, 25, 'Stormforged Taskmaster - Frostweave Cloth Normal'), +(29370, 33470, 1270001, 25, 'Stormforged Champion - Frostweave Cloth Normal'), +(29374, 33470, 1270001, 25, 'Stormforged Magus - Frostweave Cloth Normal'), +(29376, 33470, 1270001, 25, 'Stormforged Artificer - Frostweave Cloth Normal'), +(29377, 33470, 1270001, 25, 'Stormforged Raider - Frostweave Cloth Normal'), +(29404, 33470, 1270001, 25, 'Savage Hill Scavenger - Frostweave Cloth Normal'), +(29407, 33470, 1270001, 25, 'Snowblind Devotee - Frostweave Cloth Normal'), +(29409, 33470, 1270001, 25, 'Garm Watcher - Frostweave Cloth Normal'), +(29413, 33470, 1270001, 25, 'Snowblind Digger - Frostweave Cloth Normal'), +(29426, 33470, 1270001, 25, 'Hyldnir Overseer - Frostweave Cloth Normal'), +(29427, 33470, 1270001, 25, 'Captive Vrykul - Frostweave Cloth Normal'), +(29449, 33470, 1270001, 25, 'Vargul Deathwaker - Frostweave Cloth Normal'), +(29450, 33470, 1270001, 25, 'Vargul Runelord - Frostweave Cloth Normal'), +(29451, 33470, 1270001, 25, 'Vargul Slayer - Frostweave Cloth Normal'), +(29498, 33470, 1270001, 25, 'Brunnhildar Warmaiden - Frostweave Cloth Normal'), +(29518, 33470, 1270001, 25, 'Overseer Syra - Frostweave Cloth Normal'), +(29569, 33470, 1270001, 25, 'Valkyrion Aspirant - Frostweave Cloth Normal'), +(29586, 33470, 1270001, 25, 'Stormforged Pillager - Frostweave Cloth Normal'), +(29592, 33470, 1270001, 25, 'Brijana - Frostweave Cloth Normal'), +(29622, 33470, 1270001, 25, 'Savage Hill Mystic - Frostweave Cloth Normal'), +(29623, 33470, 1270001, 25, 'Savage Hill Brute - Frostweave Cloth Normal'), +(29646, 33470, 1270001, 25, 'Banshee Soulclaimer - Frostweave Cloth Normal'), +(29652, 33470, 1270001, 25, 'Stormforged Tracker - Frostweave Cloth Normal'), +(29654, 33470, 1270001, 25, 'Drakuru Blood Drinker - Frostweave Cloth Normal'), +(29656, 33470, 1270001, 25, 'Drakuru Berserker - Frostweave Cloth Normal'), +(29695, 33470, 1270001, 25, 'Tracker Thulin - Frostweave Cloth Normal'), +(29697, 33470, 1270001, 25, 'Drakuru Prophet - Frostweave Cloth Normal'), +(29699, 33470, 1270001, 25, 'Drakuru Raptor Rider - Frostweave Cloth Normal'), +(29717, 33470, 1270001, 25, 'Shadow Cultist - Frostweave Cloth Normal'), +(29719, 33470, 1270001, 25, 'Morbid Carcass - Frostweave Cloth Normal'), +(29720, 33470, 1270001, 25, 'Vault Geist - Frostweave Cloth Normal'), +(29722, 33470, 1270001, 25, 'Rabid Cannibal - Frostweave Cloth Normal'), +(29738, 33470, 1270001, 25, 'Death Knight Master - Frostweave Cloth Normal'), +(29792, 33470, 1270001, 25, 'Frostfeather Screecher - Frostweave Cloth Normal'), +(29793, 33470, 1270001, 25, 'Frostfeather Witch - Frostweave Cloth Normal'), +(29843, 33470, 1270001, 25, 'Stormforged Loreseeker - Frostweave Cloth Normal'), +(29862, 33470, 1270001, 25, 'Stormforged Monitor - Frostweave Cloth Normal'), +(29874, 33470, 1270001, 25, 'Drakkari Inciter - Frostweave Cloth Normal'), +(29875, 33470, 1270001, 25, 'Icemane Yeti - Frostweave Cloth Normal'), +(29880, 33470, 1270001, 25, 'Jotunheim Warrior - Frostweave Cloth Normal'), +(30037, 33470, 1270001, 25, 'Mjordin Combatant - Frostweave Cloth Normal'), +(30046, 33470, 1270001, 25, 'Yulda the Stormspeaker - Frostweave Cloth Normal'), +(30146, 33470, 1270001, 25, 'Exhausted Vrykul - Frostweave Cloth Normal'), +(30147, 33470, 1270001, 25, 'Garhal - Frostweave Cloth Normal'), +(30202, 33470, 1270001, 25, 'Reanimated Crusader - Frostweave Cloth Normal'), +(30204, 33470, 1270001, 25, 'Forgotten Depths Ambusher - Frostweave Cloth Normal'), +(30205, 33470, 1270001, 25, 'Forgotten Depths Acolyte - Frostweave Cloth Normal'), +(30243, 33470, 1270001, 25, 'Njorndar Spear-Sister - Frostweave Cloth Normal'), +(30250, 33470, 1270001, 25, 'Valhalas Vargul - Frostweave Cloth Normal'), +(30287, 33470, 1270001, 25, 'Plundering Geist - Frostweave Cloth Normal'), +(30333, 33470, 1270001, 25, 'Forgotten Depths Slayer - Frostweave Cloth Normal'), +(30541, 33470, 1270001, 25, 'Forgotten Depths Underking - Frostweave Cloth Normal'), +(30543, 33470, 1270001, 25, 'Forgotten Depths High Priest - Frostweave Cloth Normal'), +(30597, 33470, 1270001, 25, 'Spiked Ghoul - Frostweave Cloth Normal'), +(30632, 33470, 1270001, 25, 'Mjordin Water Magus - Frostweave Cloth Normal'), +(30687, 33470, 1270001, 25, 'Skeletal Constructor - Frostweave Cloth Normal'), +(30689, 33470, 1270001, 25, 'Chained Abomination - Frostweave Cloth Normal'), +(30701, 33470, 1270001, 25, 'Vile Creeper - Frostweave Cloth Normal'), +(30725, 33470, 1270001, 25, 'Jotunheim Sleep-Watcher - Frostweave Cloth Normal'), +(30746, 33470, 1270001, 25, 'Master Summoner Zarod - Frostweave Cloth Normal'), +(30751, 33470, 1270001, 25, 'Kul\'galar Oracle - Frostweave Cloth Normal'), +(30856, 33470, 1270001, 25, 'Unbound Trickster - Frostweave Cloth Normal'), +(30860, 33470, 1270001, 25, 'Unbound Dryad - Frostweave Cloth Normal'), +(30863, 33470, 1270001, 25, 'Shandaral Druid Spirit - Frostweave Cloth Normal'), +(30864, 33470, 1270001, 25, 'Shandaral Hunter Spirit - Frostweave Cloth Normal'), +(30865, 33470, 1270001, 25, 'Shandaral Warrior Spirit - Frostweave Cloth Normal'), +(30868, 33470, 1270001, 25, 'Unbound Corrupter - Frostweave Cloth Normal'), +(30894, 33470, 1270001, 25, 'Lithe Stalker - Frostweave Cloth Normal'), +(30920, 33470, 1270001, 25, 'Lumbering Atrocity - Frostweave Cloth Normal'), +(30921, 33470, 1270001, 25, 'Skeletal Runesmith - Frostweave Cloth Normal'), +(30922, 33470, 1270001, 25, 'Umbral Brute - Frostweave Cloth Normal'), +(30931, 33470, 1270001, 25, 'Drakkari Inciter (1) - Frostweave Cloth Normal'), +(30949, 33470, 1270001, 25, 'Risen Laborer - Frostweave Cloth Normal'), +(30951, 33470, 1270001, 25, 'Restless Lookout - Frostweave Cloth Normal'), +(30952, 33470, 1270001, 25, 'Hungering Plaguehound - Frostweave Cloth Normal'), +(30957, 33470, 1270001, 25, 'Death Knight Initiate - Frostweave Cloth Normal'), +(30958, 33470, 1270001, 25, 'Death Knight Initiate - Frostweave Cloth Normal'), +-- (30960, 33470, 1270001, 25, 'Risen Soldier - Frostweave Cloth Normal'), +(31037, 33470, 1270001, 25, 'Forgotten Depths High Priest - Frostweave Cloth Normal'), +(31039, 33470, 1270001, 25, 'Forgotten Depths Underking - Frostweave Cloth Normal'), +(31042, 33470, 1270001, 25, 'Death Knight Adept - Frostweave Cloth Normal'), +(31043, 33470, 1270001, 25, 'Reanimated Crusader - Frostweave Cloth Normal'), +(31140, 33470, 1270001, 25, 'Hulking Abomination - Frostweave Cloth Normal'), +(31145, 33470, 1270001, 25, 'Shadow Adept - Frostweave Cloth Normal'), +(31147, 33470, 1270001, 25, 'Vicious Geist - Frostweave Cloth Normal'), +(31150, 33470, 1270001, 25, 'Plagued Fiend - Frostweave Cloth Normal'), +(31152, 33470, 1270001, 25, 'Undying Minion - Frostweave Cloth Normal'), +(31155, 33470, 1270001, 25, 'Malefic Necromancer - Frostweave Cloth Normal'), +(31201, 33470, 1270001, 25, 'Acolyte (1) - Frostweave Cloth Normal'), +(31231, 33470, 1270001, 25, 'Lost Shandaral Spirit - Frostweave Cloth Normal'), +(31258, 33470, 1270001, 25, 'Ymirheim Chosen Warrior - Frostweave Cloth Normal'), +(31267, 33470, 1270001, 25, 'Ymirjar Element Shaper - Frostweave Cloth Normal'), +(31396, 33470, 1270001, 25, 'Val\'kyr Taskmistress - Frostweave Cloth Normal'), +(31401, 33470, 1270001, 25, 'Azure Manashaper - Frostweave Cloth Normal'), +(31402, 33470, 1270001, 25, 'Azure Scalebane - Frostweave Cloth Normal'), +(31403, 33470, 1270001, 25, 'Azure Spellweaver - Frostweave Cloth Normal'), +(31411, 33470, 1270001, 25, 'Hulking Horror - Frostweave Cloth Normal'), +(31468, 33470, 1270001, 25, 'Plundering Geist (1) - Frostweave Cloth Normal'), +(31554, 33470, 1270001, 25, 'Restless Lookout - Frostweave Cloth Normal'), +(31671, 33470, 1270001, 25, 'Frenzied Geist (1) - Frostweave Cloth Normal'), +(31681, 33470, 1270001, 25, 'Tunneling Ghoul (1) - Frostweave Cloth Normal'), +(31718, 33470, 1270001, 25, 'Frostbrood Whelp - Frostweave Cloth Normal'), +(31731, 33470, 1270001, 25, 'Wyrm Reanimator - Frostweave Cloth Normal'), +(31738, 33470, 1270001, 25, 'Cultist Corrupter - Frostweave Cloth Normal'), +(31746, 33470, 1270001, 25, 'Ymirheim Defender - Frostweave Cloth Normal'), +(31754, 33470, 1270001, 25, 'Glacial Bonelord - Frostweave Cloth Normal'), +(31783, 33470, 1270001, 25, 'Vrykul Necrolord - Frostweave Cloth Normal'), +(31787, 33470, 1270001, 25, 'Citadel Watcher - Frostweave Cloth Normal'), +(31843, 33470, 1270001, 25, 'Reanimated Miner - Frostweave Cloth Normal'), +(31847, 33470, 1270001, 25, 'Scavenging Geist - Frostweave Cloth Normal'), +(31853, 33470, 1270001, 25, 'Cruel Overseer - Frostweave Cloth Normal'), +(31900, 33470, 1270001, 25, 'Scourge Banner-Bearer - Frostweave Cloth Normal'), +(32149, 33470, 1270001, 25, 'Fallen Hero\'s Spirit - Frostweave Cloth Normal'), +(32164, 33470, 1270001, 25, 'Skeletal Craftsman - Frostweave Cloth Normal'), +(32236, 33470, 1270001, 25, 'Dark Subjugator - Frostweave Cloth Normal'), +(32238, 33470, 1270001, 25, 'Bitter Initiate - Frostweave Cloth Normal'), +(32250, 33470, 1270001, 25, 'Overseer Faedris - Frostweave Cloth Normal'), +(32255, 33470, 1270001, 25, 'Converted Hero - Frostweave Cloth Normal'), +(32257, 33470, 1270001, 25, 'Scourge Converter - Frostweave Cloth Normal'), +(32259, 33470, 1270001, 25, 'Void Summoner - Frostweave Cloth Normal'), +(32262, 33470, 1270001, 25, 'Shadow Channeler - Frostweave Cloth Normal'), +(32263, 33470, 1270001, 25, 'Overseer Veraj - Frostweave Cloth Normal'), +(32268, 33470, 1270001, 25, 'Cult Taskmaster - Frostweave Cloth Normal'), +(32276, 33470, 1270001, 25, 'Cult Blackguard - Frostweave Cloth Normal'), +(32279, 33470, 1270001, 25, 'Vile Torturer - Frostweave Cloth Normal'), +(32284, 33470, 1270001, 25, 'Scourge Soulbinder - Frostweave Cloth Normal'), +(32285, 33470, 1270001, 25, 'Overseer Jhaeqon - Frostweave Cloth Normal'), +(32289, 33470, 1270001, 25, 'Damned Apothecary - Frostweave Cloth Normal'), +(32290, 33470, 1270001, 25, 'Cult Alchemist - Frostweave Cloth Normal'), +(32291, 33470, 1270001, 25, 'Overseer Savryn - Frostweave Cloth Normal'), +(32297, 33470, 1270001, 25, 'Cult Researcher - Frostweave Cloth Normal'), +(32349, 33470, 1270001, 25, 'Cultist Shard Watcher - Frostweave Cloth Normal'), +(32507, 33470, 1270001, 25, 'Cultist Acolyte - Frostweave Cloth Normal'), +(32572, 33470, 1270001, 25, 'Dragonblight Mage Hunter - Frostweave Cloth Normal'), +(23956, 33470, 1270002, 25, 'Dragonflayer Strategist - Frostweave Cloth Elite'), +(23960, 33470, 1270002, 25, 'Dragonflayer Runecaster - Frostweave Cloth Elite'), +(23961, 33470, 1270002, 25, 'Dragonflayer Ironhelm - Frostweave Cloth Elite'), +(24069, 33470, 1270002, 25, 'Dragonflayer Bonecrusher - Frostweave Cloth Elite'), +(24071, 33470, 1270002, 25, 'Dragonflayer Heartsplitter - Frostweave Cloth Elite'), +(24078, 33470, 1270002, 25, 'Dragonflayer Metalworker - Frostweave Cloth Elite'), +(24079, 33470, 1270002, 25, 'Dragonflayer Forge Master - Frostweave Cloth Elite'), +(24080, 33470, 1270002, 25, 'Dragonflayer Weaponsmith - Frostweave Cloth Elite'), +(24082, 33470, 1270002, 25, 'Proto-Drake Handler - Frostweave Cloth Elite'), +(24085, 33470, 1270002, 25, 'Dragonflayer Overseer - Frostweave Cloth Elite'), +(24849, 33470, 1270002, 25, 'Proto-Drake Rider - Frostweave Cloth Elite'), +(26550, 33470, 1270002, 25, 'Dragonflayer Deathseeker - Frostweave Cloth Elite'), +(26553, 33470, 1270002, 25, 'Dragonflayer Fanatic - Frostweave Cloth Elite'), +(26554, 33470, 1270002, 25, 'Dragonflayer Seer - Frostweave Cloth Elite'), +(26555, 33470, 1270002, 25, 'Scourge Hulk - Frostweave Cloth Elite'), +(26620, 33470, 1270002, 25, 'Drakkari Guardian - Frostweave Cloth Elite'), +(26621, 33470, 1270002, 25, 'Ghoul Tormentor - Frostweave Cloth Elite'), +(26623, 33470, 1270002, 25, 'Scourge Brute - Frostweave Cloth Elite'), +(26624, 33470, 1270002, 25, 'Wretched Belcher - Frostweave Cloth Elite'), +(26626, 33470, 1270002, 25, 'Scourge Reanimator - Frostweave Cloth Elite'), +(26635, 33470, 1270002, 25, 'Risen Drakkari Warrior - Frostweave Cloth Elite'), +(26636, 33470, 1270002, 25, 'Risen Drakkari Soulmage - Frostweave Cloth Elite'), +(26637, 33470, 1270002, 25, 'Risen Drakkari Handler - Frostweave Cloth Elite'), +(26638, 33470, 1270002, 25, 'Risen Drakkari Bat Rider - Frostweave Cloth Elite'), +(26639, 33470, 1270002, 25, 'Drakkari Shaman - Frostweave Cloth Elite'), +(26641, 33470, 1270002, 25, 'Drakkari Gutripper - Frostweave Cloth Elite'), +(26669, 33470, 1270002, 25, 'Ymirjar Savage - Frostweave Cloth Elite'), +(26670, 33470, 1270002, 25, 'Ymirjar Flesh Hunter - Frostweave Cloth Elite'), +(26694, 33470, 1270002, 25, 'Ymirjar Dusk Shaman - Frostweave Cloth Elite'), +(26696, 33470, 1270002, 25, 'Ymirjar Berserker - Frostweave Cloth Elite'), +(26716, 33470, 1270002, 25, 'Azure Warder - Frostweave Cloth Elite'), +(26722, 33470, 1270002, 25, 'Azure Magus - Frostweave Cloth Elite'), +(26727, 33470, 1270002, 25, 'Mage Hunter Ascendant - Frostweave Cloth Elite'), +(26728, 33470, 1270002, 25, 'Mage Hunter Initiate - Frostweave Cloth Elite'), +(26729, 33470, 1270002, 25, 'Steward - Frostweave Cloth Elite'), +(26734, 33470, 1270002, 25, 'Azure Enforcer - Frostweave Cloth Elite'), +(26735, 33470, 1270002, 25, 'Azure Scale-Binder - Frostweave Cloth Elite'), +(26800, 33470, 1270002, 25, 'Alliance Berserker - Frostweave Cloth Elite'), +(26802, 33470, 1270002, 25, 'Alliance Ranger - Frostweave Cloth Elite'), +(26805, 33470, 1270002, 25, 'Alliance Cleric - Frostweave Cloth Elite'), +(26830, 33470, 1270002, 25, 'Risen Drakkari Death Knight - Frostweave Cloth Elite'), +(27431, 33470, 1270002, 25, 'Drakkari Commander - Frostweave Cloth Elite'), +(27633, 33470, 1270002, 25, 'Azure Inquisitor - Frostweave Cloth Elite'), +(27635, 33470, 1270002, 25, 'Azure Spellbinder - Frostweave Cloth Elite'), +(27639, 33470, 1270002, 25, 'Ring-Lord Sorceress - Frostweave Cloth Elite'), +(27640, 33470, 1270002, 25, 'Ring-Lord Conjurer - Frostweave Cloth Elite'), +(27729, 33470, 1270002, 25, 'Enraging Ghoul - Frostweave Cloth Elite'), +(27734, 33470, 1270002, 25, 'Crypt Fiend - Frostweave Cloth Elite'), +(27736, 33470, 1270002, 25, 'Patchwork Construct - Frostweave Cloth Elite'), +(27871, 33470, 1270002, 25, 'Flesheating Ghoul - Frostweave Cloth Elite'), +(27960, 33470, 1270002, 25, 'Dark Rune Warrior - Frostweave Cloth Elite'), +(27961, 33470, 1270002, 25, 'Dark Rune Worker - Frostweave Cloth Elite'), +(27962, 33470, 1270002, 25, 'Dark Rune Elementalist - Frostweave Cloth Elite'), +(27963, 33470, 1270002, 25, 'Dark Rune Theurgist - Frostweave Cloth Elite'), +(27964, 33470, 1270002, 25, 'Dark Rune Scholar - Frostweave Cloth Elite'), +(27965, 33470, 1270002, 25, 'Dark Rune Shaper - Frostweave Cloth Elite'), +(27966, 33470, 1270002, 25, 'Dark Rune Controller - Frostweave Cloth Elite'), +(27969, 33470, 1270002, 25, 'Dark Rune Giant - Frostweave Cloth Elite'), +(28201, 33470, 1270002, 25, 'Bile Golem - Frostweave Cloth Elite'), +(28249, 33470, 1270002, 25, 'Devouring Ghoul - Frostweave Cloth Elite'), +(28368, 33470, 1270002, 25, 'Ymirjar Necromancer - Frostweave Cloth Elite'), +(28410, 33470, 1270002, 25, 'Dragonflayer Spiritualist - Frostweave Cloth Elite'), +(28578, 33470, 1270002, 25, 'Hardened Steel Reaver - Frostweave Cloth Elite'), +(28579, 33470, 1270002, 25, 'Hardened Steel Berserker - Frostweave Cloth Elite'), +(28580, 33470, 1270002, 25, 'Hardened Steel Skycaller - Frostweave Cloth Elite'), +(28581, 33470, 1270002, 25, 'Stormforged Tactician - Frostweave Cloth Elite'), +(28582, 33470, 1270002, 25, 'Stormforged Mender - Frostweave Cloth Elite'), +(28835, 33470, 1270002, 25, 'Stormforged Construct - Frostweave Cloth Elite'), +(28836, 33470, 1270002, 25, 'Stormforged Runeshaper - Frostweave Cloth Elite'), +(28837, 33470, 1270002, 25, 'Stormforged Sentinel - Frostweave Cloth Elite'), +(28838, 33470, 1270002, 25, 'Titanium Vanguard - Frostweave Cloth Elite'), +(28920, 33470, 1270002, 25, 'Stormforged Giant - Frostweave Cloth Elite'), +(28961, 33470, 1270002, 25, 'Titanium Siegebreaker - Frostweave Cloth Elite'), +(28965, 33470, 1270002, 25, 'Titanium Thunderer - Frostweave Cloth Elite'), +(29819, 33470, 1270002, 25, 'Drakkari Lancer - Frostweave Cloth Elite'), +(29820, 33470, 1270002, 25, 'Drakkari God Hunter - Frostweave Cloth Elite'), +(29822, 33470, 1270002, 25, 'Drakkari Fire Weaver - Frostweave Cloth Elite'), +(29826, 33470, 1270002, 25, 'Drakkari Medicine Man - Frostweave Cloth Elite'), +(29829, 33470, 1270002, 25, 'Drakkari Earthshaker - Frostweave Cloth Elite'), +(29832, 33470, 1270002, 25, 'Drakkari Golem - Frostweave Cloth Elite'), +(29838, 33470, 1270002, 25, 'Drakkari Rhino - Frostweave Cloth Elite'), +(29920, 33470, 1270002, 25, 'Ruins Dweller - Frostweave Cloth Elite'), +(29931, 33470, 1270002, 25, 'Drakkari Rhino - Frostweave Cloth Elite'), +(30111, 33470, 1270002, 25, 'Twilight Worshipper - Frostweave Cloth Elite'), +(30179, 33470, 1270002, 25, 'Twilight Apostle - Frostweave Cloth Elite'), +(30276, 33470, 1270002, 25, 'Ahn\'kahar Web Winder - Frostweave Cloth Elite'), +(30277, 33470, 1270002, 25, 'Ahn\'kahar Slasher - Frostweave Cloth Elite'), +(30278, 33470, 1270002, 25, 'Ahn\'kahar Spell Flinger - Frostweave Cloth Elite'), +(30283, 33470, 1270002, 25, 'Plague Walker - Frostweave Cloth Elite'), +(30284, 33470, 1270002, 25, 'Bonegrinder - Frostweave Cloth Elite'), +(30285, 33470, 1270002, 25, 'Eye of Taldaram - Frostweave Cloth Elite'), +(30286, 33470, 1270002, 25, 'Frostbringer - Frostweave Cloth Elite'), +(30319, 33470, 1270002, 25, 'Twilight Darkcaster - Frostweave Cloth Elite'), +(30414, 33470, 1270002, 25, 'Forgotten One - Frostweave Cloth Elite'), +(30457, 33470, 1270002, 25, 'Azure Magus (1) - Frostweave Cloth Elite'), +(30459, 33470, 1270002, 25, 'Azure Warder (1) - Frostweave Cloth Elite'), +(30460, 33470, 1270002, 25, 'Mage Hunter Ascendant (1) - Frostweave Cloth Elite'), +(30478, 33470, 1270002, 25, 'Mage Hunter Initiate (1) - Frostweave Cloth Elite'), +(30485, 33470, 1270002, 25, 'Steward (1) - Frostweave Cloth Elite'), +(30496, 33470, 1270002, 25, 'Alliance Berserker (1) - Frostweave Cloth Elite'), +(30498, 33470, 1270002, 25, 'Alliance Cleric (1) - Frostweave Cloth Elite'), +(30509, 33470, 1270002, 25, 'Alliance Ranger (1) - Frostweave Cloth Elite'), +(30516, 33470, 1270002, 25, 'Azure Enforcer (1) - Frostweave Cloth Elite'), +(30517, 33470, 1270002, 25, 'Azure Scale-Binder (1) - Frostweave Cloth Elite'), +(30660, 33470, 1270002, 25, 'Portal Guardian - Frostweave Cloth Elite'), +(30666, 33470, 1270002, 25, 'Azure Captain - Frostweave Cloth Elite'), +(30667, 33470, 1270002, 25, 'Azure Sorceror - Frostweave Cloth Elite'), +(30668, 33470, 1270002, 25, 'Azure Raider - Frostweave Cloth Elite'), +(30695, 33470, 1270002, 25, 'Portal Keeper - Frostweave Cloth Elite'), +(30747, 33470, 1270002, 25, 'Dragonflayer Ironhelm (1) - Frostweave Cloth Elite'), +(30764, 33470, 1270002, 25, 'Dragonflayer Deathseeker (1) - Frostweave Cloth Elite'), +(30765, 33470, 1270002, 25, 'Dragonflayer Fanatic (1) - Frostweave Cloth Elite'), +(30766, 33470, 1270002, 25, 'Dragonflayer Seer (1) - Frostweave Cloth Elite'), +(30806, 33470, 1270002, 25, 'Scourge Hulk (1) - Frostweave Cloth Elite'), +(30816, 33470, 1270002, 25, 'Ymirjar Berserker (1) - Frostweave Cloth Elite'), +(30817, 33470, 1270002, 25, 'Ymirjar Dusk Shaman (1) - Frostweave Cloth Elite'), +(30818, 33470, 1270002, 25, 'Ymirjar Flesh Hunter (1) - Frostweave Cloth Elite'), +(30820, 33470, 1270002, 25, 'Ymirjar Necromancer (1) - Frostweave Cloth Elite'), +(30821, 33470, 1270002, 25, 'Ymirjar Savage (1) - Frostweave Cloth Elite'), +(30893, 33470, 1270002, 25, 'Portal Keeper - Frostweave Cloth Elite'), +(30901, 33470, 1270002, 25, 'Azure Inquisitor (1) - Frostweave Cloth Elite'), +(30904, 33470, 1270002, 25, 'Azure Spellbinder (1) - Frostweave Cloth Elite'), +(30915, 33470, 1270002, 25, 'Ring-Lord Conjurer (1) - Frostweave Cloth Elite'), +(30916, 33470, 1270002, 25, 'Ring-Lord Sorceress (1) - Frostweave Cloth Elite'), +(30926, 33470, 1270002, 25, 'Drakkari Earthshaker (1) - Frostweave Cloth Elite'), +(30927, 33470, 1270002, 25, 'Drakkari Fire Weaver (1) - Frostweave Cloth Elite'), +(30929, 33470, 1270002, 25, 'Drakkari God Hunter (1) - Frostweave Cloth Elite'), +(30930, 33470, 1270002, 25, 'Drakkari Golem (1) - Frostweave Cloth Elite'), +(30932, 33470, 1270002, 25, 'Drakkari Lancer (1) - Frostweave Cloth Elite'), +(30933, 33470, 1270002, 25, 'Drakkari Medicine Man (1) - Frostweave Cloth Elite'), +(30935, 33470, 1270002, 25, 'Drakkari Rhino (1) - Frostweave Cloth Elite'), +(30936, 33470, 1270002, 25, 'Drakkari Rhino (1) - Frostweave Cloth Elite'), +(30939, 33470, 1270002, 25, 'Ruins Dweller (1) - Frostweave Cloth Elite'), +(30966, 33470, 1270002, 25, 'Hardened Steel Berserker (1) - Frostweave Cloth Elite'), +(30967, 33470, 1270002, 25, 'Hardened Steel Reaver (1) - Frostweave Cloth Elite'), +(30968, 33470, 1270002, 25, 'Hardened Steel Skycaller (1) - Frostweave Cloth Elite'), +(30971, 33470, 1270002, 25, 'Stormforged Construct (1) - Frostweave Cloth Elite'), +(30972, 33470, 1270002, 25, 'Stormforged Giant (1) - Frostweave Cloth Elite'), +(30974, 33470, 1270002, 25, 'Stormforged Mender (1) - Frostweave Cloth Elite'), +(30975, 33470, 1270002, 25, 'Stormforged Runeshaper (1) - Frostweave Cloth Elite'), +(30976, 33470, 1270002, 25, 'Stormforged Sentinel (1) - Frostweave Cloth Elite'), +(30977, 33470, 1270002, 25, 'Stormforged Tactician (1) - Frostweave Cloth Elite'), +(30980, 33470, 1270002, 25, 'Titanium Siegebreaker (1) - Frostweave Cloth Elite'), +(30981, 33470, 1270002, 25, 'Titanium Vanguard (1) - Frostweave Cloth Elite'), +(30982, 33470, 1270002, 25, 'Titanium Thunderer (1) - Frostweave Cloth Elite'), +(31178, 33470, 1270002, 25, 'Enraging Ghoul (1) - Frostweave Cloth Elite'), +(31179, 33470, 1270002, 25, 'Devouring Ghoul (1) - Frostweave Cloth Elite'), +(31187, 33470, 1270002, 25, 'Crypt Fiend (1) - Frostweave Cloth Elite'), +(31199, 33470, 1270002, 25, 'Patchwork Construct (1) - Frostweave Cloth Elite'), +(31200, 33470, 1270002, 25, 'Bile Golem (1) - Frostweave Cloth Elite'), +(31338, 33470, 1270002, 25, 'Drakkari Commander (1) - Frostweave Cloth Elite'), +(31339, 33470, 1270002, 25, 'Drakkari Guardian (1) - Frostweave Cloth Elite'), +(31340, 33470, 1270002, 25, 'Drakkari Gutripper (1) - Frostweave Cloth Elite'), +(31342, 33470, 1270002, 25, 'Risen Drakkari Handler (1) - Frostweave Cloth Elite'), +(31345, 33470, 1270002, 25, 'Drakkari Shaman (1) - Frostweave Cloth Elite'), +(31347, 33470, 1270002, 25, 'Ghoul Tormentor (1) - Frostweave Cloth Elite'), +(31351, 33470, 1270002, 25, 'Risen Drakkari Bat Rider (1) - Frostweave Cloth Elite'), +(31352, 33470, 1270002, 25, 'Risen Drakkari Death Knight (1) - Frostweave Cloth Elite'), +(31354, 33470, 1270002, 25, 'Risen Drakkari Soulmage (1) - Frostweave Cloth Elite'), +(31355, 33470, 1270002, 25, 'Risen Drakkari Warrior (1) - Frostweave Cloth Elite'), +(31357, 33470, 1270002, 25, 'Scourge Brute (1) - Frostweave Cloth Elite'), +(31359, 33470, 1270002, 25, 'Scourge Reanimator (1) - Frostweave Cloth Elite'), +(31363, 33470, 1270002, 25, 'Wretched Belcher (1) - Frostweave Cloth Elite'), +(31371, 33470, 1270002, 25, 'Dark Rune Controller (1) - Frostweave Cloth Elite'), +(31372, 33470, 1270002, 25, 'Dark Rune Elementalist (1) - Frostweave Cloth Elite'), +(31373, 33470, 1270002, 25, 'Dark Rune Giant (1) - Frostweave Cloth Elite'), +(31374, 33470, 1270002, 25, 'Dark Rune Scholar (1) - Frostweave Cloth Elite'), +(31375, 33470, 1270002, 25, 'Dark Rune Shaper (1) - Frostweave Cloth Elite'), +(31376, 33470, 1270002, 25, 'Dark Rune Theurgist (1) - Frostweave Cloth Elite'), +(31377, 33470, 1270002, 25, 'Dark Rune Warrior (1) - Frostweave Cloth Elite'), +(31378, 33470, 1270002, 25, 'Dark Rune Worker (1) - Frostweave Cloth Elite'), +(31442, 33470, 1270002, 25, 'Ahn\'kahar Slasher (1) - Frostweave Cloth Elite'), +(31443, 33470, 1270002, 25, 'Ahn\'kahar Spell Flinger (1) - Frostweave Cloth Elite'), +(31450, 33470, 1270002, 25, 'Ahn\'kahar Web Winder (1) - Frostweave Cloth Elite'), +(31451, 33470, 1270002, 25, 'Bonegrinder (1) - Frostweave Cloth Elite'), +(31457, 33470, 1270002, 25, 'Eye of Taldaram (1) - Frostweave Cloth Elite'), +(31459, 33470, 1270002, 25, 'Forgotten One (1) - Frostweave Cloth Elite'), +(31460, 33470, 1270002, 25, 'Frostbringer (1) - Frostweave Cloth Elite'), +(31466, 33470, 1270002, 25, 'Plague Walker (1) - Frostweave Cloth Elite'), +(31471, 33470, 1270002, 25, 'Twilight Apostle (1) - Frostweave Cloth Elite'), +(31472, 33470, 1270002, 25, 'Twilight Darkcaster (1) - Frostweave Cloth Elite'), +(31475, 33470, 1270002, 25, 'Twilight Worshipper (1) - Frostweave Cloth Elite'), +(31486, 33470, 1270002, 25, 'Azure Captain (1) - Frostweave Cloth Elite'), +(31490, 33470, 1270002, 25, 'Azure Raider (1) - Frostweave Cloth Elite'), +(31493, 33470, 1270002, 25, 'Azure Sorceror (1) - Frostweave Cloth Elite'), +(31501, 33470, 1270002, 25, 'Portal Guardian (1) - Frostweave Cloth Elite'), +(31503, 33470, 1270002, 25, 'Portal Keeper (1) - Frostweave Cloth Elite'), +(31504, 33470, 1270002, 25, 'Portal Keeper (1) - Frostweave Cloth Elite'), +(31658, 33470, 1270002, 25, 'Dragonflayer Bonecrusher (1) - Frostweave Cloth Elite'), +(31659, 33470, 1270002, 25, 'Dragonflayer Forge Master (1) - Frostweave Cloth Elite'), +(31660, 33470, 1270002, 25, 'Dragonflayer Heartsplitter (1) - Frostweave Cloth Elite'), +(31661, 33470, 1270002, 25, 'Dragonflayer Metalworker (1) - Frostweave Cloth Elite'), +(31662, 33470, 1270002, 25, 'Dragonflayer Overseer (1) - Frostweave Cloth Elite'), +(31663, 33470, 1270002, 25, 'Dragonflayer Runecaster (1) - Frostweave Cloth Elite'), +(31666, 33470, 1270002, 25, 'Dragonflayer Strategist (1) - Frostweave Cloth Elite'), +(31667, 33470, 1270002, 25, 'Dragonflayer Weaponsmith (1) - Frostweave Cloth Elite'), +(31675, 33470, 1270002, 25, 'Proto-Drake Handler (1) - Frostweave Cloth Elite'), +(32191, 33470, 1270002, 25, 'Azure Stalker - Frostweave Cloth Elite'), +(32192, 33470, 1270002, 25, 'Azure Stalker (1) - Frostweave Cloth Elite'); + +DELETE FROM `creature_loot_template` WHERE `Entry` = 30960; +UPDATE `creature_template` SET `lootid` = 0 WHERE `entry` = 30960; From 5a128c69d8194a59ff52cad7e377154983fc261a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 20 Feb 2026 15:26:44 +0000 Subject: [PATCH 181/335] chore(DB): import pending files Referenced commit(s): 4b4fb0f90734bc849a526a55afe5552eb41b9608 --- .../lockboxes.sql => db_world/2026_02_20_02.sql} | 1 + .../vanillaTBC.sql => db_world/2026_02_20_03.sql} | 1 + .../{pending_db_world/wotlk.sql => db_world/2026_02_20_04.sql} | 1 + 3 files changed, 3 insertions(+) rename data/sql/updates/{pending_db_world/lockboxes.sql => db_world/2026_02_20_02.sql} (99%) rename data/sql/updates/{pending_db_world/vanillaTBC.sql => db_world/2026_02_20_03.sql} (99%) rename data/sql/updates/{pending_db_world/wotlk.sql => db_world/2026_02_20_04.sql} (99%) diff --git a/data/sql/updates/pending_db_world/lockboxes.sql b/data/sql/updates/db_world/2026_02_20_02.sql similarity index 99% rename from data/sql/updates/pending_db_world/lockboxes.sql rename to data/sql/updates/db_world/2026_02_20_02.sql index 0656674ca..2c0290cb9 100644 --- a/data/sql/updates/pending_db_world/lockboxes.sql +++ b/data/sql/updates/db_world/2026_02_20_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_20_01 -> 2026_02_20_02 -- Ornate Bronze Lockbox DELETE FROM `item_loot_template` WHERE (`Entry` = 4632); INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES diff --git a/data/sql/updates/pending_db_world/vanillaTBC.sql b/data/sql/updates/db_world/2026_02_20_03.sql similarity index 99% rename from data/sql/updates/pending_db_world/vanillaTBC.sql rename to data/sql/updates/db_world/2026_02_20_03.sql index ab28a55cd..8178c6390 100644 --- a/data/sql/updates/pending_db_world/vanillaTBC.sql +++ b/data/sql/updates/db_world/2026_02_20_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_20_02 -> 2026_02_20_03 -- Remove Old System References DELETE FROM `reference_loot_template` WHERE `Entry` IN (1002125, 1012425, 1022425, 1032425, 1052130, 1062029, 1071930, 1080003, 1080016, 1000610, 1010506, 1050110, 1070518, 1080001, 1080013, 1001115, 1011112, 1021112, 1051120, 1061019, 1080002, 1080014, 1010607, 1020608, 1010809, 1020809, 1010910, 1020910, 1012122, 1022122, 1032122, 1010808, 1011111, 1021111, 1011010, 1021010, 1003140, 1023940, 1033940, 1043840, 1053140, 1064049, 1073545, 1080004, 1080020, 1001620, 1011718, 1021718, 1080015, 1011212, 1021212, 1011415, 1021415, 1011011, 1021011, 1011616, 1021616, 1011414, 1021414, 1011516, 1021516, 1011920, 1021920, 1031820, 1011213, 1021213, 1011819, 1021819, 1011617, 1021617, 1012324, 1022324, 1032324, 1012223, 1022223, 1032223, 1002630, 1022829, 1032829, 1080018, 1023030, 1033030, 1063039, 1022627, 1032627, 1080017, 1022930, 1032930, 1012323, 1022323, 1032323, 1023232, 1033232, 1080019, 1010909, 1020909, 1012424, 1022424, 1032424, 1010707, 1012020, 1022020, 1022626, 1032626, 1012525, 1022526, 1032526, 1010708, 1012021, 1022021, 1032021, 1022929, 1032929, 1011515, 1021515, 1023131, 1033131, 1011818, 1021818, 1011919, 1021919, 1022728, 1032728, 1023434, 1033434, 1022727, 1032727, 1023334, 1033334, 1023435, 1033435, 1011314, 1021314, 1023637, 1033637, 1023737, 1033737, 1004150, 1024142, 1034142, 1044142, 1054162, 1080005, 1080021, 1024444, 1034444, 1044444, 1024041, 1034041, 1044041, 1024242, 1034242, 1044242, 1024344, 1034344, 1044344, 1024545, 1034545, 1044545, 1023031, 1033031, 1023233, 1033233, 1023738, 1033738, 1023536, 1033536, 1023132, 1033132, 1024040, 1034040, 1024343, 1034343, 1044343, 1024141, 1034141, 1044141, 1024243, 1034243, 1044243, 1023939, 1033939, 1023839, 1033839, 1023838, 1033838, 1005163, 1025051, 1035051, 1045051, 1065054, 1075062, 1080007, 1080022, 1025050, 1035050, 1045050, 1025353, 1035353, 1045353, 1023636, 1033636, 1024747, 1034747, 1044747, 1080006, 1011717, 1021717, 1012222, 1022222, 1032222, 1012121, 1022121, 1032121, 1011313, 1021313, 1025152, 1035152, 1045152, 1025455, 1035455, 1045455, 1065562, 1025657, 1035657, 1045657, 1025556, 1035556, 1045556, 1025151, 1035151, 1045151, 1025757, 1035757, 1045757, 1025354, 1035354, 1045354, 1025253, 1035253, 1045253, 1026060, 1036060, 1046060, 1025858, 1035858, 1045858, 1025959, 1035959, 1045959, 1025252, 1035252, 1045252, 1025656, 1035656, 1045656, 1026262, 1036262, 1046262, 1025555, 1035555, 1045555, 1025859, 1035859, 1045859, 1023535, 1033535, 1023333, 1033333, 1022525, 1032525, 1024445, 1034445, 1044445, 1024646, 1034646, 1044646, 1024546, 1034546, 1044546, 1024647, 1034647, 1044647, 1024748, 1034748, 1044748, 1024849, 1034849, 1044849, 1024950, 1034950, 1044950, 1010606, 1022828, 1032828, 1025758, 1035758, 1045758, 1024848, 1034848, 1044848, 1024949, 1034949, 1044949, 1025454, 1035454, 1045454, 1025960, 1035960, 1045960, 1026161, 1036161, 1046161, 1026061, 1036061, 1046061); diff --git a/data/sql/updates/pending_db_world/wotlk.sql b/data/sql/updates/db_world/2026_02_20_04.sql similarity index 99% rename from data/sql/updates/pending_db_world/wotlk.sql rename to data/sql/updates/db_world/2026_02_20_04.sql index b2723781b..33b2fcb1f 100644 --- a/data/sql/updates/pending_db_world/wotlk.sql +++ b/data/sql/updates/db_world/2026_02_20_04.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_20_03 -> 2026_02_20_04 -- DELETE FROM `reference_loot_template` WHERE `Entry` IN (1206874,1207583,1226870,1226971,1227072,1227173,1227274,1227375,1227476,1227577,1227678,1227779,1227880,1227981,1228082,1228183,1236871,1237072,1237173,1237274,1237375,1237476,1237577,1237678,1237779,1237981,1238083,1248083,1256875,1256883,1257683,1266870,1267174,1267579,1268083,1270000,1270001,1270002); INSERT INTO `reference_loot_template` (`Entry`, `Chance`, `GroupId`, `Item`, `Comment`) VALUES From a757e306cfeb268f987a0b29b88e8dcd25abe4b8 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 20 Feb 2026 10:06:43 -0600 Subject: [PATCH 182/335] fix(Core/Spells): Master of Elements mana refund with Living Bomb and base cost calculation (#24775) Co-authored-by: blinkysc --- src/server/scripts/Spells/spell_mage.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index 11b2f4bbf..67cfc1bf1 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -70,7 +70,8 @@ enum MageSpells SPELL_MAGE_CHILLED_R2 = 12485, SPELL_MAGE_CHILLED_R3 = 12486, SPELL_MAGE_MANA_SURGE = 37445, - SPELL_MAGE_FROST_NOVA = 122 + SPELL_MAGE_FROST_NOVA = 122, + SPELL_MAGE_LIVING_BOMB_R1 = 44457 }; enum MageSpellIcons @@ -807,7 +808,7 @@ class spell_mage_master_of_elements : public AuraScript bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE }); + return ValidateSpellInfo({ SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE, SPELL_MAGE_LIVING_BOMB_R1 }); } bool CheckProc(ProcEventInfo& eventInfo) @@ -823,7 +824,23 @@ class spell_mage_master_of_elements : public AuraScript { PreventDefaultAction(); - int32 mana = eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), eventInfo.GetDamageInfo()->GetSchoolMask()); + SpellInfo const* spellInfo = eventInfo.GetDamageInfo()->GetSpellInfo(); + + // Living Bomb explosion has no mana cost, use the aura spell's cost instead + if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE + && spellInfo->SpellIconID == MAGE_ICON_LIVING_BOMB + && !spellInfo->ManaCost && !spellInfo->ManaCostPercentage) + { + uint8 rank = sSpellMgr->GetSpellRank(spellInfo->Id); + spellInfo = sSpellMgr->GetSpellInfo( + sSpellMgr->GetSpellWithRank(SPELL_MAGE_LIVING_BOMB_R1, rank)); + if (!spellInfo) + return; + } + + // Use base mana cost (ManaCost + ManaCostPercentage) without spell mods, + // as the talent refunds based on "base mana cost" + int32 mana = spellInfo->ManaCost + int32(CalculatePct(GetTarget()->GetCreateMana(), spellInfo->ManaCostPercentage)); mana = CalculatePct(mana, aurEff->GetAmount()); if (mana > 0) From 20745b45bad49a606a0a2b38dc9f050a227deb96 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 20 Feb 2026 13:48:54 -0300 Subject: [PATCH 183/335] fix(DB/Creature): Implement Steel Gate Gargoyle Attack Event (#24707) --- .../rev_1771021750451817300.sql | 196 ++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771021750451817300.sql diff --git a/data/sql/updates/pending_db_world/rev_1771021750451817300.sql b/data/sql/updates/pending_db_world/rev_1771021750451817300.sql new file mode 100644 index 000000000..84c335513 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771021750451817300.sql @@ -0,0 +1,196 @@ +-- +DELETE FROM `waypoint_data` WHERE `id` IN (244401, 244402, 244403, 244404, 244411, 244412, 244413, 244414, 244415, 244416, 244417, 244418); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `move_type`) VALUES +-- Spawn Paths +(244401, 1, 2166.0625, -3243.5933, 180.9555, NULL, 1), -- PathType: ExactPathFlying +(244401, 2, 2159.8196, -3250.0044, 180.95552, NULL, 1), +(244401, 3, 2139.9976, -3230.1494, 180.95552, NULL, 1), +(244401, 4, 2119.4285, -3219.818, 180.95552, NULL, 1), +(244401, 5, 2082.4119, -3218.6365, 180.95552, NULL, 1), +(244401, 6, 2057.2395, -3231.4038, 180.95552, NULL, 1), + +(244402, 1, 2181.5571, -3264.775, 181.99797, NULL, 1), -- PathType: ExactPathFlying +(244402, 2, 2137.1206, -3261.2974, 181.99797, NULL, 1), +(244402, 3, 2090.4736, -3263.3528, 181.99797, NULL, 1), + +(244403, 1, 2158.682, -3318.3374, 183.71745, NULL, 1), -- PathType: ExactPathFlying +(244403, 2, 2130.7395, -3310.8962, 183.71745, NULL, 1), +(244403, 3, 2096.0337, -3300.9407, 183.71745, NULL, 1), +(244403, 4, 2076.361, -3320.212, 177.49522, NULL, 1), +(244403, 5, 2044.6697, -3331.9944, 177.49522, NULL, 1), +(244403, 6, 1997.7017, -3316.084, 172.1619, NULL, 1), + +(244404, 1, 2190.6858, -3291.0073, 174.83574, NULL, 1), -- PathType: ExactPathFlying +(244404, 2, 2177.2344, -3270.6223, 174.83574, NULL, 1), +(244404, 3, 2154.7668, -3260.519, 174.83574, NULL, 1), +(244404, 4, 2126.8496, -3260.701, 174.83574, NULL, 1), +(244404, 5, 2093.8542, -3282.568, 174.83574, NULL, 1), +(244404, 6, 2065.487, -3277.9292, 174.83574, NULL, 1), +-- Patrol Paths +-- At any point they may start another +(244411, 1, 2061.6252, -3225.8066, 110.46983, NULL, 1), +(244411, 2, 2068.5293, -3225.4172, 110.46983, NULL, 1), +(244411, 3, 2062.1475, -3222.5796, 110.46983, NULL, 1), +(244411, 4, 2050.0513, -3227.5261, 110.46983, NULL, 1), +(244411, 5, 2063.677, -3224.6401, 110.46983, NULL, 1), +(244411, 6, 2060.198, -3221.9307, 110.46983, NULL, 1), +(244411, 7, 2067.0117, -3220.79, 110.46983, NULL, 1), +(244411, 8, 2059.4438, -3225.3433, 110.46983, NULL, 1), + +(244412, 1, 2046.75, -3261.8188, 113.66396, NULL, 1), +(244412, 2, 2054.3982, -3275.4526, 113.66396, NULL, 1), +(244412, 3, 2042.5363, -3264.9768, 113.66396, NULL, 1), +(244412, 4, 2037.8262, -3249.983, 113.66396, NULL, 1), +(244412, 5, 2048.1287, -3254.4248, 113.66396, NULL, 1), +(244412, 6, 2039.2755, -3256.5334, 113.66396, NULL, 1), +(244412, 7, 2042.3751, -3256.4075, 113.66396, NULL, 1), +(244412, 8, 2041.2069, -3256.7092, 113.66396, NULL, 1), + +(244413, 1 , 2053.6716, -3328.2083, 128.81787, NULL, 1), +(244413, 2 , 2068.5825, -3294.51, 128.81787, NULL, 1), +(244413, 3 , 2067.4263, -3266.633, 128.81787, NULL, 1), +(244413, 4 , 2048.2356, -3230.1907, 128.81787, NULL, 1), +(244413, 5 , 2014.4576, -3245.0356, 128.81787, NULL, 1), +(244413, 6 , 2007.6554, -3291.14, 128.81787, NULL, 1), +(244413, 7 , 2010.0525, -3326.0042, 128.81787, NULL, 1), +(244413, 8 , 2040.7793, -3351.0933, 128.81787, NULL, 1), +(244413, 9 , 2063.7512, -3326.8794, 128.81787, NULL, 1), +(244413, 10, 2064.902, -3291.096, 128.81787, NULL, 1), +(244413, 11, 2025.8376, -3286.761, 128.81787, NULL, 1), + +(244414, 1, 2014.2073, -3245.6626, 130.87953, NULL, 1), +(244414, 2, 2015.9786, -3242.778, 130.87953, NULL, 1), +(244414, 3, 2011.9103, -3246.2632, 130.87953, NULL, 1), +(244414, 4, 2019.221, -3242.3965, 130.87953, NULL, 1), +(244414, 5, 2017.1042, -3237.1711, 130.87953, NULL, 1), +(244414, 6, 2018.7694, -3241.8735, 130.87953, NULL, 1), +(244414, 7, 2014.6066, -3251.7986, 130.87953, NULL, 1), +(244414, 8, 2019.221, -3242.3965, 130.87953, NULL, 1), + +(244415, 1 , 1996.0485, -3290.9797, 131.02751, NULL, 1), +(244415, 2 , 1997.7188, -3289.8953, 131.02751, NULL, 1), +(244415, 3 , 1995.3326, -3291.1948, 131.02751, NULL, 1), +(244415, 4 , 1993.0052, -3293.4604, 131.02751, NULL, 1), +(244415, 5 , 1987.5831, -3280.076, 131.02751, NULL, 1), +(244415, 6 , 1978.2656, -3287.1914, 131.02751, NULL, 1), +(244415, 7 , 1996.1595, -3291.0747, 131.02751, NULL, 1), +(244415, 8 , 1993.7706, -3295.9563, 131.02751, NULL, 1), +(244415, 9 , 1994.4401, -3292.1433, 131.02751, NULL, 1), +(244415, 10, 2012.1808, -3283.8916, 131.02751, NULL, 1), +(244415, 11, 1996.1595, -3291.0747, 131.02751, NULL, 1), +(244415, 12, 2050.22, -3212.1023, 131.7216, NULL, 1), + +(244416, 1 , 1993.8201, -3300.897, 137.54697, NULL, 1), +(244416, 2 , 2028.6237, -3306.248, 137.54697, NULL, 1), +(244416, 3 , 2064.139, -3273.6064, 137.54697, NULL, 1), +(244416, 4 , 2066.9956, -3260.3035, 137.54697, NULL, 1), +(244416, 5 , 2053.7297, -3240.1597, 137.54697, NULL, 1), +(244416, 6 , 2019.7631, -3242.2454, 137.54697, NULL, 1), +(244416, 7 , 2010.2274, -3262.113, 137.54697, NULL, 1), +(244416, 8 , 2027.4445, -3284.7336, 137.54697, NULL, 1), +(244416, 9 , 2047.6554, -3329.7773, 137.54697, NULL, 1), +(244416, 10, 2060.7527, -3327.7354, 137.54697, NULL, 1), +(244416, 11, 2042.2126, -3308.3665, 137.54697, NULL, 1), +(244416, 12, 2029.2096, -3294.3716, 137.54697, NULL, 1), + +(244417, 1 , 2080.1594, -3234.2708, 139.72156, NULL, 1), +(244417, 2 , 2093.6687, -3264.2322, 139.72156, NULL, 1), +(244417, 3 , 2092.5127, -3306.2922, 139.72156, NULL, 1), +(244417, 4 , 2090.3342, -3321.6672, 139.72156, NULL, 1), +(244417, 5 , 2063.0059, -3323.8943, 139.72156, NULL, 1), +(244417, 6 , 2017.7001, -3321.9739, 139.72156, NULL, 1), +(244417, 7 , 2018.8739, -3287.563, 139.72156, NULL, 1), +(244417, 8 , 2025.3499, -3263.1636, 139.72156, NULL, 1), +(244417, 9 , 2040.0791, -3338.9258, 139.72156, NULL, 1), +(244417, 10, 2049.0332, -3324.6628, 139.72156, NULL, 1), + +(244418, 1 , 1990.0845, -3315.2732, 148.92896, NULL, 1), +(244418, 2 , 1970.158, -3320.0554, 170.51852, NULL, 1), +(244418, 3 , 1959.2545, -3302.718, 180.7407, NULL, 1), +(244418, 4 , 1956.6018, -3276.815, 185.21294, NULL, 1), +(244418, 5 , 1926.0784, -3243.9893, 185.21294, NULL, 1), +(244418, 6 , 1922.6814, -3216.9436, 185.21294, NULL, 1), +(244418, 7 , 1960.441, -3208.2822, 185.21294, NULL, 1), +(244418, 8 , 1997.6995, -3188.8447, 185.21294, NULL, 1), +(244418, 9 , 2041.0187, -3193.5137, 185.21294, NULL, 1), +(244418, 10, 2042.536, -3224.5352, 185.21294, NULL, 1), +(244418, 11, 2037.7513, -3262.2507, 185.21294, NULL, 1), +(244418, 12, 2009.8748, -3299.9492, 185.21294, NULL, 1), +(244418, 13, 2005.569, -3320.2559, 185.21294, NULL, 1); + +SET @GUID := 52854; + +DELETE FROM `creature` WHERE `id1` = 24440 AND `guid` IN (107082,107083,107084,107085,107086,107087,107088,107089,107090,107092,107093,107094,107095,107096,107097,107098,107099,107100,107101,107102,107111); +DELETE FROM `creature` WHERE `id1` = 24440 AND `guid` BETWEEN @GUID+0 AND @GUID+19; +INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(@GUID+0 , 24440, 571, 495, 3999, 2159.51, -3194.06, 143.911, 0.645772, 30, 65512, 1, NULL), +(@GUID+1 , 24440, 571, 495, 3999, 2165.4, -3172.17, 192.231, 0.767945, 30, 65512, 1, NULL), +(@GUID+2 , 24440, 571, 495, 3999, 2173.41, -3246.4, 179.519, 1.81514, 30, 65512, 1, NULL), +(@GUID+3 , 24440, 571, 495, 3999, 2227.24, -3340.07, 179.863, 2.21385, 30, 65512, 1, NULL), +(@GUID+4 , 24440, 571, 495, 3999, 2187.9, -3230.13, 197.935, 2.46091, 30, 65512, 1, NULL), +(@GUID+5 , 24440, 571, 495, 3999, 2236.79, -3287.49, 181.61, 2.57286, 30, 65512, 1, NULL), +(@GUID+6 , 24440, 571, 495, 3999, 2181.64, -3305.67, 179.903, 2.58309, 30, 65512, 1, NULL), +(@GUID+7 , 24440, 571, 495, 3999, 2228.49, -3350.64, 181.78, 2.70236, 30, 65512, 1, NULL), +(@GUID+8 , 24440, 571, 495, 3999, 2241.28, -3261.74, 194.289, 2.89489, 30, 65512, 1, NULL), +(@GUID+9 , 24440, 571, 495, 3999, 2233.01, -3313.31, 182.573, 3.22579, 30, 65512, 1, NULL), +(@GUID+10, 24440, 571, 495, 3999, 2233.08, -3313.3, 182.572, 3.22579, 30, 65512, 1, NULL), +(@GUID+11, 24440, 571, 495, 3999, 2246.25, -3261.23, 182.262, 3.36849, 30, 65512, 1, NULL), +(@GUID+12, 24440, 571, 495, 3999, 2272.47, -3310.13, 181.942, 3.45575, 30, 65512, 1, NULL), +(@GUID+13, 24440, 571, 495, 3999, 2242.6, -3271.31, 192.245, 3.55272, 30, 65512, 1, NULL), +(@GUID+14, 24440, 571, 495, 3999, 2239.75, -3238.94, 194.69, 3.99352, 30, 65512, 1, NULL), +(@GUID+15, 24440, 571, 495, 3999, 2234.81, -3215.15, 195.862, 4.09856, 30, 65512, 1, NULL), +(@GUID+16, 24440, 571, 495, 3999, 2234.78, -3215.19, 195.857, 4.09858, 30, 65512, 1, NULL), +(@GUID+17, 24440, 571, 495, 3999, 2223.47, -3241.02, 192.57, 4.90438, 30, 65512, 1, NULL), +(@GUID+18, 24440, 571, 495, 3999, 2198.84, -3173.41, 192.855, 5.09636, 30, 65512, 1, NULL), +(@GUID+19, 24440, 571, 495, 3999, 2206.77, -3329.28, 196.61, 5.63741, 30, 65512, 1, NULL); + +DELETE FROM `game_event` WHERE `eventEntry` = 98; +INSERT INTO `game_event` (`eventEntry`, `start_time`, `end_time`, `occurence`, `length`, `holiday`, `holidayStage`, `description`, `world_event`, `announce`) VALUES +(98, NULL, NULL, 5184000, 15, 0, 0, 'Steel Gate Gargoyle Attack', 0, 2); + +DELETE FROM `game_event_creature` WHERE `eventEntry` = 98 AND `guid` BETWEEN @GUID AND @GUID+19; +INSERT INTO `game_event_creature` (`guid`, `eventEntry`) VALUES +(@GUID+0 , 98), +(@GUID+1 , 98), +(@GUID+2 , 98), +(@GUID+3 , 98), +(@GUID+4 , 98), +(@GUID+5 , 98), +(@GUID+6 , 98), +(@GUID+7 , 98), +(@GUID+8 , 98), +(@GUID+9 , 98), +(@GUID+10, 98), +(@GUID+11, 98), +(@GUID+12, 98), +(@GUID+13, 98), +(@GUID+14, 98), +(@GUID+15, 98), +(@GUID+16, 98), +(@GUID+17, 98), +(@GUID+18, 98), +(@GUID+19, 98); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24440; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24440); +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 +(24440, 0, 0, 0, 0, 0, 100, 0, 0, 0, 2400, 3000, 0, 0, 11, 43803, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Gjalerbron Gargoyle - In Combat - Cast \'Gargoyle Strike\''), +(24440, 0, 1, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 233, 244401, 244404, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Gjalerbron Gargoyle - On Respawn - Start Random Path 244401-244404'), +(24440, 0, 3, 0, 109, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2444000, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Gjalerbron Gargoyle - On Path Finished - Run Script'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2444000); +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 +(2444000, 9, 0, 0, 0, 0, 100, 0, 400, 400, 0, 0, 0, 0, 233, 244411, 244418, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Gjalerbron Gargoyle - Actionlist - Start Random Path 244411-244418'); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 24473); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(24473, 0, 0, 'Gargoyle attack! Grab yer rifles, men!', 14, 7, 100, 0, 0, 0, 23410, 0, 'Lead Archaeologist Malzie - On Quest \'Steel Gate Patrol\' Accepted'); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24473; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24473); +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 +(24473, 0, 0, 0, 68, 0, 100, 0, 98, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Lead Archaeologist Malzie - On Game Event 98 Started - Say Line 0'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 24399) AND (`source_type` = 0) AND (`id` IN (6)); +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 +(24399, 0, 6, 0, 19, 0, 100, 0, 11391, 0, 0, 0, 0, 0, 112, 98, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Steel Gate Chief Archaeologist - On Quest \'Steel Gate Patrol\' Taken - Start \'Steel Gate Gargoyle Attack\' Event'); From 88a604889032df23ea23ede8ccaace64f5b4c75d Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 20 Feb 2026 11:04:41 -0600 Subject: [PATCH 184/335] fix(Core/Spells): Use base mana cost for Illumination and Thrill of the Hunt (#24776) Co-authored-by: blinkysc --- .../updates/pending_db_world/rev_1771519000000000000.sql | 3 +++ src/server/scripts/Spells/spell_hunter.cpp | 7 +++++-- src/server/scripts/Spells/spell_paladin.cpp | 5 +++-- 3 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771519000000000000.sql diff --git a/data/sql/updates/pending_db_world/rev_1771519000000000000.sql b/data/sql/updates/pending_db_world/rev_1771519000000000000.sql new file mode 100644 index 000000000..346e2df6f --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771519000000000000.sql @@ -0,0 +1,3 @@ +-- Fix spell_pal_illumination bound to wrong spell (-20234 = Improved Lay on Hands instead of -20210 = Illumination) +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_pal_illumination'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (-20210, 'spell_pal_illumination'); diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index c116241a8..52537630a 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -1349,10 +1349,13 @@ class spell_hun_thrill_of_the_hunt : public AuraScript return; } if (AuraEffect const* pEff = victim->GetAuraEffect(SPELL_AURA_PERIODIC_DUMMY, SPELLFAMILY_HUNTER, 0x0, 0x80000000, 0x0, caster->GetGUID())) - mana = pEff->GetSpellInfo()->CalcPowerCost(caster, SpellSchoolMask(pEff->GetSpellInfo()->SchoolMask)) * 4 / 10 / 3; + { + SpellInfo const* expSpell = pEff->GetSpellInfo(); + mana = (expSpell->ManaCost + int32(CalculatePct(caster->GetCreateMana(), expSpell->ManaCostPercentage))) * 4 / 10 / 3; + } } else - mana = procSpell->CalcPowerCost(caster, SpellSchoolMask(procSpell->SchoolMask)) * 4 / 10; + mana = (procSpell->ManaCost + int32(CalculatePct(caster->GetCreateMana(), procSpell->ManaCostPercentage))) * 4 / 10; if (spell) caster->ToPlayer()->SetSpellModTakingSpell(spell, true); diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 8dd6e0d59..89a3a571a 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -2063,7 +2063,7 @@ private: bool _isVengeance = true; }; -// -20234 - Illumination +// -20210 - Illumination class spell_pal_illumination : public AuraScript { PrepareAuraScript(spell_pal_illumination); @@ -2095,7 +2095,8 @@ class spell_pal_illumination : public AuraScript if (originalSpell && aurEff->GetSpellInfo()) { Unit* target = eventInfo.GetActor(); // Paladin is the target of the energize - int32 bp = CalculatePct(static_cast(originalSpell->CalcPowerCost(target, originalSpell->GetSchoolMask())), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()); + int32 baseCost = originalSpell->ManaCost + int32(CalculatePct(target->GetCreateMana(), originalSpell->ManaCostPercentage)); + int32 bp = CalculatePct(baseCost, aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()); target->CastCustomSpell(target, SPELL_PALADIN_ILLUMINATION_ENERGIZE, &bp, nullptr, nullptr, true, nullptr, aurEff); } } From 8472334cc6611fd62738c5290cb20d34e89c5274 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 20 Feb 2026 17:06:10 +0000 Subject: [PATCH 185/335] chore(DB): import pending files Referenced commit(s): 20745b45bad49a606a0a2b38dc9f050a227deb96 --- .../rev_1771021750451817300.sql => db_world/2026_02_20_05.sql} | 1 + .../rev_1771519000000000000.sql => db_world/2026_02_20_06.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1771021750451817300.sql => db_world/2026_02_20_05.sql} (99%) rename data/sql/updates/{pending_db_world/rev_1771519000000000000.sql => db_world/2026_02_20_06.sql} (87%) diff --git a/data/sql/updates/pending_db_world/rev_1771021750451817300.sql b/data/sql/updates/db_world/2026_02_20_05.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771021750451817300.sql rename to data/sql/updates/db_world/2026_02_20_05.sql index 84c335513..6cef86455 100644 --- a/data/sql/updates/pending_db_world/rev_1771021750451817300.sql +++ b/data/sql/updates/db_world/2026_02_20_05.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_20_04 -> 2026_02_20_05 -- DELETE FROM `waypoint_data` WHERE `id` IN (244401, 244402, 244403, 244404, 244411, 244412, 244413, 244414, 244415, 244416, 244417, 244418); INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `move_type`) VALUES diff --git a/data/sql/updates/pending_db_world/rev_1771519000000000000.sql b/data/sql/updates/db_world/2026_02_20_06.sql similarity index 87% rename from data/sql/updates/pending_db_world/rev_1771519000000000000.sql rename to data/sql/updates/db_world/2026_02_20_06.sql index 346e2df6f..fa0c064fa 100644 --- a/data/sql/updates/pending_db_world/rev_1771519000000000000.sql +++ b/data/sql/updates/db_world/2026_02_20_06.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_20_05 -> 2026_02_20_06 -- Fix spell_pal_illumination bound to wrong spell (-20234 = Improved Lay on Hands instead of -20210 = Illumination) DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_pal_illumination'; INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (-20210, 'spell_pal_illumination'); From 3e791dfcbdbf88dabb1bf660a9be6ce083c0b18e Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 20 Feb 2026 16:56:22 -0600 Subject: [PATCH 186/335] fix(DB/Spell): Add spell_proc entry for Inner Focus (#24780) --- .../updates/pending_db_world/rev_1771623224005229683.sql | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771623224005229683.sql diff --git a/data/sql/updates/pending_db_world/rev_1771623224005229683.sql b/data/sql/updates/pending_db_world/rev_1771623224005229683.sql new file mode 100644 index 000000000..a51e0ea71 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771623224005229683.sql @@ -0,0 +1,8 @@ +-- Inner Focus (14751) - Add spell_proc entry with PROC_ATTR_REQ_SPELLMOD +-- Without this, the proc system consumes the charge on the spell's own cast +-- because Inner Focus's SpellFamilyFlags overlap with its EffectSpellClassMask. +-- PROC_ATTR_REQ_SPELLMOD (0x8) ensures charges are only consumed when the +-- modifier is actually applied to the triggering spell. +DELETE FROM `spell_proc` WHERE `SpellId` = 14751; +INSERT INTO `spell_proc` (`SpellId`,`SchoolMask`,`SpellFamilyName`,`SpellFamilyMask0`,`SpellFamilyMask1`,`SpellFamilyMask2`,`ProcFlags`,`SpellTypeMask`,`SpellPhaseMask`,`HitMask`,`AttributesMask`,`DisableEffectsMask`,`ProcsPerMinute`,`Chance`,`Cooldown`,`Charges`) VALUES +(14751, 0, 6, 3755474943, 14521847, 8256, 0, 7, 2, 0, 8, 0, 0, 0, 0, 0); From 8459cff6cece6fe4f118ceef2b6550da5825fb0c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 20 Feb 2026 22:57:32 +0000 Subject: [PATCH 187/335] chore(DB): import pending files Referenced commit(s): 3e791dfcbdbf88dabb1bf660a9be6ce083c0b18e --- .../rev_1771623224005229683.sql => db_world/2026_02_20_07.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771623224005229683.sql => db_world/2026_02_20_07.sql} (94%) diff --git a/data/sql/updates/pending_db_world/rev_1771623224005229683.sql b/data/sql/updates/db_world/2026_02_20_07.sql similarity index 94% rename from data/sql/updates/pending_db_world/rev_1771623224005229683.sql rename to data/sql/updates/db_world/2026_02_20_07.sql index a51e0ea71..1255086d7 100644 --- a/data/sql/updates/pending_db_world/rev_1771623224005229683.sql +++ b/data/sql/updates/db_world/2026_02_20_07.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_20_06 -> 2026_02_20_07 -- Inner Focus (14751) - Add spell_proc entry with PROC_ATTR_REQ_SPELLMOD -- Without this, the proc system consumes the charge on the spell's own cast -- because Inner Focus's SpellFamilyFlags overlap with its EffectSpellClassMask. From 5e1fd50776fc1b1908a58a6db900ee9d1d48aa7f Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 20 Feb 2026 18:48:08 -0600 Subject: [PATCH 188/335] fix(Core/Scripts): Prevent Judgement of Light from triggering Beacon of Light (#24781) Co-authored-by: blinkysc --- src/server/scripts/Spells/spell_paladin.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 89a3a571a..d9c228867 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -2218,12 +2218,18 @@ class spell_pal_light_s_beacon : public AuraScript SPELL_PALADIN_BEACON_OF_LIGHT_AURA, SPELL_PALADIN_BEACON_OF_LIGHT_FLASH, SPELL_PALADIN_BEACON_OF_LIGHT_HOLY, - SPELL_PALADIN_HOLY_LIGHT_R1 + SPELL_PALADIN_HOLY_LIGHT_R1, + SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL }); } bool CheckProc(ProcEventInfo& eventInfo) { + // Don't proc from Judgement of Light heals — JoL sets originalCaster to + // the paladin for combat log, but the heal is actually cast by the attacker. + if (eventInfo.GetSpellInfo() && eventInfo.GetSpellInfo()->Id == SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL) + return false; + // Don't proc if the heal target is the beacon target (no double heal) if (GetTarget()->HasAura(SPELL_PALADIN_BEACON_OF_LIGHT_AURA, eventInfo.GetActor()->GetGUID())) return false; From b01e202244e69d09bfb6523d83e19db5574660e3 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 20 Feb 2026 18:48:23 -0600 Subject: [PATCH 189/335] fix(Core/Spells): Fix Avenging Wrath not greying out Divine Protection/Shield (#24778) Co-authored-by: blinkysc --- src/server/game/Spells/Spell.cpp | 4 ++++ src/server/scripts/Spells/spell_paladin.cpp | 7 ++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 856eafe78..e8fe0a346 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3201,6 +3201,10 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask) /// @todo: move this code to scripts if (m_preCastSpell) { + // Avenging Wrath - also apply Immune Shield Marker + if (m_preCastSpell == 61987) + m_caster->CastSpell(unit, 61988, true); + // Fearie Fire (Feral) - damage if (m_preCastSpell == 60089) m_caster->CastSpell(unit, m_preCastSpell, true); diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index d9c228867..a57be2921 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -556,18 +556,15 @@ class spell_pal_avenging_wrath : public AuraScript }); } - void HandleApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); + if (AuraEffect const* sanctifiedWrathAurEff = target->GetAuraEffectOfRankedSpell(SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1, EFFECT_2)) { int32 basepoints = sanctifiedWrathAurEff->GetAmount(); target->CastCustomSpell(target, SPELL_PALADIN_SANCTIFIED_WRATH, &basepoints, &basepoints, nullptr, true, nullptr, sanctifiedWrathAurEff); } - - target->CastSpell(target, SPELL_PALADIN_AVENGING_WRATH_MARKER, true, nullptr, aurEff); - // Blizz seems to just apply aura without bothering to cast - target->AddAura(SPELL_PALADIN_IMMUNE_SHIELD_MARKER, target); } void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) From 4e233cc4aee34434282c882b5adca4925ad56d6b Mon Sep 17 00:00:00 2001 From: sogladev Date: Sat, 21 Feb 2026 13:06:25 +0100 Subject: [PATCH 190/335] fix(Scripts/Spells): Mad Alchemist's Potion and Gluth's Decimate 10m (#24788) Co-authored-by: Gerhood --- .../rev_1771670602673698356.sql | 6 + src/server/scripts/Spells/spell_item.cpp | 110 ++++++++++-------- 2 files changed, 68 insertions(+), 48 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771670602673698356.sql diff --git a/data/sql/updates/pending_db_world/rev_1771670602673698356.sql b/data/sql/updates/pending_db_world/rev_1771670602673698356.sql new file mode 100644 index 000000000..f2d99f9c5 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771670602673698356.sql @@ -0,0 +1,6 @@ +-- +UPDATE `spell_script_names` SET `ScriptName` = 'spell_gluth_decimate' WHERE `spell_id` = 28374 AND `ScriptName` = 'spell_item_mad_alchemists_potion'; + +DELETE FROM `spell_script_names` WHERE `spell_id` = 45051; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(45051, 'spell_item_mad_alchemists_potion'); diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index f2d237eda..b0a801b6e 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -772,32 +772,6 @@ class spell_item_essence_of_life : public AuraScript } }; -const uint32 crazyAlchemistTable[5] = -{ - 53909, // Wild Magic - 53908, // Potion of Speed - 53762, // Indestructible Potion - 43185, // Runic Healing Potion - 43186 // Runic Mana Potion -}; - -class spell_item_crazy_alchemists_potion : public SpellScript -{ - PrepareSpellScript(spell_item_crazy_alchemists_potion); - - void HandleHeal(SpellEffIndex /*effIndex*/) - { - // Xinef: 20% to get additional effect, guessed - if (roll_chance_i(20)) - GetCaster()->CastSpell(GetCaster(), crazyAlchemistTable[urand(0, (GetCaster()->getPowerType() == POWER_MANA ? 4 : 3))], true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_item_crazy_alchemists_potion::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); - } -}; - class spell_item_skull_of_impeding_doom : public AuraScript { PrepareAuraScript(spell_item_skull_of_impeding_doom); @@ -5071,7 +5045,7 @@ class spell_item_darkmoon_card_illusion : public AuraScript } }; -// 28374 - Mad Alchemist's Potion +// 45051 - Mad Alchemist's Potion (34440) class spell_item_mad_alchemists_potion : public SpellScript { PrepareSpellScript(spell_item_mad_alchemists_potion); @@ -5081,32 +5055,32 @@ class spell_item_mad_alchemists_potion : public SpellScript std::vector availableElixirs = { // Battle Elixirs - 33720, // Onslaught Elixir - 54452, // Adept's Elixir - 33726, // Elixir of Mastery - 28490, // Elixir of Major Strength - 28491, // Elixir of Healing Power - 28493, // Elixir of Major Frost Power - 54494, // Elixir of Major Agility - 28501, // Elixir of Major Firepower - 28503, // Elixir of Major Shadow Power - 38954, // Fel Strength Elixir + 33720, // Onslaught Elixir (28102) + 54452, // Adept's Elixir (28103) + 33726, // Elixir of Mastery (28104) + 28490, // Elixir of Major Strength (22824) + 28491, // Elixir of Healing Power (22825) + 28493, // Elixir of Major Frost Power (22827) + 54494, // Elixir of Major Agility (22831) + 28501, // Elixir of Major Firepower (22833) + 28503, // Elixir of Major Shadow Power (22835) + 38954, // Fel Strength Elixir (31679) // Guardian Elixirs - 39625, // Elixir of Major Fortitude - 39626, // Earthen Elixir - 39627, // Elixir of Draenic Wisdom - 39628, // Elixir of Ironskin - 28502, // Elixir of Major Defense - 28514, // Elixir of Empowerment + 39625, // Elixir of Major Fortitude (32062) + 39626, // Earthen Elixir (32063) + 39627, // Elixir of Draenic Wisdom (32067) + 39628, // Elixir of Ironskin (32068) + 28502, // Elixir of Major Defense (22834) + 28514, // Elixir of Empowerment (22848) // Other - 28489, // Elixir of Camouflage - 28496 // Elixir of the Searching Eye + 28489, // Elixir of Camouflage (22823) + 28496 // Elixir of the Searching Eye (22830) }; Unit* target = GetCaster(); if (target->getPowerType() == POWER_MANA) - availableElixirs.push_back(28509); // Elixir of Major Mageblood + availableElixirs.push_back(28509); // Elixir of Major Mageblood (22840) uint32 chosenElixir = Acore::Containers::SelectRandomContainerElement(availableElixirs); @@ -5117,7 +5091,7 @@ class spell_item_mad_alchemists_potion : public SpellScript chosenSpellGroup = SPELL_GROUP_ELIXIR_BATTLE; if (sSpellMgr->IsSpellMemberOfSpellGroup(chosenElixir, SPELL_GROUP_ELIXIR_GUARDIAN)) chosenSpellGroup = SPELL_GROUP_ELIXIR_GUARDIAN; - + // If another spell of the same group is already active the elixir should not be cast if (chosenSpellGroup != SPELL_GROUP_NONE) { Unit::AuraApplicationMap const& auraMap = target->GetAppliedAuras(); @@ -5142,6 +5116,46 @@ class spell_item_mad_alchemists_potion : public SpellScript } }; +// 53750 - Crazy Alchemist's Potion (40077) +class spell_item_crazy_alchemists_potion : public SpellScript +{ + PrepareSpellScript(spell_item_crazy_alchemists_potion); + + void SecondaryEffect() + { + std::vector availableElixirs = + { + 43185, // Runic Healing Potion (33447) + 53750, // Crazy Alchemist's Potion (40077) + 53761, // Powerful Rejuvenation Potion (40087) + 53762, // Indestructible Potion (40093) + 53908, // Potion of Speed (40211) + 53909, // Potion of Wild Magic (40212) + 53910, // Mighty Arcane Protection Potion (40213) + 53911, // Mighty Fire Protection Potion (40214) + 53913, // Mighty Frost Protection Potion (40215) + 53914, // Mighty Nature Protection Potion (40216) + 53915 // Mighty Shadow Protection Potion (40217) + }; + + Unit* target = GetCaster(); + + if (!target->IsInCombat()) + availableElixirs.push_back(53753); // Potion of Nightmares (40081) + if (target->getPowerType() == POWER_MANA) + availableElixirs.push_back(43186); // Runic Mana Potion (33448) + + uint32 chosenElixir = Acore::Containers::SelectRandomContainerElement(availableElixirs); + + target->CastSpell(target, chosenElixir, GetCastItem()); + } + + void Register() override + { + AfterCast += SpellCastFn(spell_item_crazy_alchemists_potion::SecondaryEffect); + } +}; + // 47770 - Roll 'dem Bones class spell_item_decahedral_dwarven_dice : public SpellScript { @@ -6209,7 +6223,6 @@ void AddSC_item_spell_scripts() RegisterSpellScript(spell_item_toxic_wasteling); RegisterSpellScript(spell_item_lil_xt); RegisterSpellScript(spell_item_essence_of_life); - RegisterSpellScript(spell_item_crazy_alchemists_potion); RegisterSpellScript(spell_item_skull_of_impeding_doom); RegisterSpellScript(spell_item_feast); RegisterSpellScript(spell_item_gnomish_universal_remote); @@ -6341,6 +6354,7 @@ void AddSC_item_spell_scripts() RegisterSpellScript(spell_item_drums_of_the_wild); RegisterSpellScript(spell_item_darkmoon_card_illusion); RegisterSpellScript(spell_item_mad_alchemists_potion); + RegisterSpellScript(spell_item_crazy_alchemists_potion); RegisterSpellScript(spell_item_decahedral_dwarven_dice); RegisterSpellScript(spell_item_aura_of_madness); RegisterSpellScript(spell_item_dementia); From 85071c01cc6933fcfec66644bf1fcfaa68b69246 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 21 Feb 2026 12:07:31 +0000 Subject: [PATCH 191/335] chore(DB): import pending files Referenced commit(s): 4e233cc4aee34434282c882b5adca4925ad56d6b --- .../rev_1771670602673698356.sql => db_world/2026_02_21_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771670602673698356.sql => db_world/2026_02_21_00.sql} (88%) diff --git a/data/sql/updates/pending_db_world/rev_1771670602673698356.sql b/data/sql/updates/db_world/2026_02_21_00.sql similarity index 88% rename from data/sql/updates/pending_db_world/rev_1771670602673698356.sql rename to data/sql/updates/db_world/2026_02_21_00.sql index f2d99f9c5..180e90739 100644 --- a/data/sql/updates/pending_db_world/rev_1771670602673698356.sql +++ b/data/sql/updates/db_world/2026_02_21_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_20_07 -> 2026_02_21_00 -- UPDATE `spell_script_names` SET `ScriptName` = 'spell_gluth_decimate' WHERE `spell_id` = 28374 AND `ScriptName` = 'spell_item_mad_alchemists_potion'; From 69bccd0a5689bc2ee2eaa89b6c4cb1002670df1a Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sat, 21 Feb 2026 08:12:52 -0600 Subject: [PATCH 192/335] fix(Core/Scripts): Allow Lock and Load to proc from fire school traps (#24784) Co-authored-by: blinkysc --- src/server/scripts/Spells/spell_hunter.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 52537630a..860415bcf 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -1193,9 +1193,8 @@ class spell_hun_lock_and_load : public AuraScript if (!(eventInfo.GetTypeMask() & PROC_FLAG_DONE_TRAP_ACTIVATION)) return false; - // Do not proc on traps for immolation/explosive trap SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || !(spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST)) + if (!spellInfo || !(spellInfo->GetSchoolMask() & (SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_FIRE))) return false; return roll_chance_i(aurEff->GetAmount()); From 16fd29c78f9d458866e6ce7d72596f78fe917c26 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sat, 21 Feb 2026 08:30:53 -0600 Subject: [PATCH 193/335] fix(DB/Spell): Fix Omen of Clarity not proccing from utility spells (#24783) Co-authored-by: blinkysc --- .../rev_11390035128862920444.sql | 2 ++ src/server/scripts/Spells/spell_druid.cpp | 20 ++++--------------- 2 files changed, 6 insertions(+), 16 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_11390035128862920444.sql diff --git a/data/sql/updates/pending_db_world/rev_11390035128862920444.sql b/data/sql/updates/pending_db_world/rev_11390035128862920444.sql new file mode 100644 index 000000000..34421f28b --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_11390035128862920444.sql @@ -0,0 +1,2 @@ +-- Omen of Clarity: revert SpellTypeMask to 0 to match TrinityCore +UPDATE `spell_proc` SET `SpellTypeMask` = 0 WHERE `SpellId` = 16864; diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 8a677ff57..2bac18112 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -238,44 +238,32 @@ class spell_dru_omen_of_clarity : public AuraScript { SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); if (!spellInfo) - { return true; - } - // Prevent passive spells to proc. (I.e shapeshift passives & passive talents) if (spellInfo->IsPassive()) - { return false; - } - // Don't proc on crafting items. if (spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM)) - { return false; - } + + // Reject energize spells (e.g. Furor) - they are not real casts + if (spellInfo->HasEffect(SPELL_EFFECT_ENERGIZE)) + return false; if (eventInfo.GetTypeMask() & PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS) - { return spellInfo->HasAttribute(SPELL_ATTR0_ON_NEXT_SWING) || spellInfo->HasAttribute(SPELL_ATTR0_ON_NEXT_SWING_NO_DAMAGE); - } // Non-damaged/Non-healing spells - only druid abilities if (!spellInfo->HasAttribute(SpellCustomAttributes(SPELL_ATTR0_CU_DIRECT_DAMAGE | SPELL_ATTR0_CU_NO_INITIAL_THREAT))) { if (spellInfo->SpellFamilyName == SPELLFAMILY_DRUID) - { - // Exclude shapeshifting return !spellInfo->HasAura(SPELL_AURA_MOD_SHAPESHIFT); - } return false; } - // Revitalize if (spellInfo->SpellIconID == SPELL_ICON_REVITALIZE) - { return false; - } return true; } From 33bafc7c8a73c9e99f75bd2656c55ed0a4ba3192 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 21 Feb 2026 14:31:56 +0000 Subject: [PATCH 194/335] chore(DB): import pending files Referenced commit(s): 16fd29c78f9d458866e6ce7d72596f78fe917c26 --- .../rev_11390035128862920444.sql => db_world/2026_02_21_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_11390035128862920444.sql => db_world/2026_02_21_01.sql} (75%) diff --git a/data/sql/updates/pending_db_world/rev_11390035128862920444.sql b/data/sql/updates/db_world/2026_02_21_01.sql similarity index 75% rename from data/sql/updates/pending_db_world/rev_11390035128862920444.sql rename to data/sql/updates/db_world/2026_02_21_01.sql index 34421f28b..e4baba8b5 100644 --- a/data/sql/updates/pending_db_world/rev_11390035128862920444.sql +++ b/data/sql/updates/db_world/2026_02_21_01.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_21_00 -> 2026_02_21_01 -- Omen of Clarity: revert SpellTypeMask to 0 to match TrinityCore UPDATE `spell_proc` SET `SpellTypeMask` = 0 WHERE `SpellId` = 16864; From 1c91f96e0203572a3568ecbecadfb3790f53d190 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sat, 21 Feb 2026 10:42:09 -0600 Subject: [PATCH 195/335] fix(DB/Spells): Fix Soul Preserver trinket proccing from non-healing spells (#24792) Co-authored-by: blinkysc --- data/sql/updates/pending_db_world/rev_1771685416037009585.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771685416037009585.sql diff --git a/data/sql/updates/pending_db_world/rev_1771685416037009585.sql b/data/sql/updates/pending_db_world/rev_1771685416037009585.sql new file mode 100644 index 000000000..f9dfbb9dc --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771685416037009585.sql @@ -0,0 +1 @@ +UPDATE `spell_proc` SET `SpellTypeMask` = 2 WHERE `SpellId` = 60510; From 07e9cef70fdba57878b04f8dc2b23bb66f96d6fe Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sat, 21 Feb 2026 10:42:27 -0600 Subject: [PATCH 196/335] fix(Scripts/Spells): Remove duplicate Sacred Shield script with wrong caster attribution (#24791) Co-authored-by: blinkysc --- .../rev_1771684443067867140.sql | 1 + src/server/scripts/Spells/spell_paladin.cpp | 101 ------------------ 2 files changed, 1 insertion(+), 101 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771684443067867140.sql diff --git a/data/sql/updates/pending_db_world/rev_1771684443067867140.sql b/data/sql/updates/pending_db_world/rev_1771684443067867140.sql new file mode 100644 index 000000000..94cb8b822 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771684443067867140.sql @@ -0,0 +1 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_pal_sacred_shield_base'; diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index a57be2921..163899a46 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -288,106 +288,6 @@ class spell_pal_sacred_shield : public AuraScript } }; -class spell_pal_sacred_shield_base : public AuraScript -{ - PrepareAuraScript(spell_pal_sacred_shield_base); - - static constexpr uint32 SACRED_SHIELD_ICD = 6 * IN_MILLISECONDS; - uint32 _cooldownEnd = 0; - - void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) - { - if (Unit* caster = GetCaster()) - { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell); - amount = spellInfo->Effects[EFFECT_0].CalcValue(); - - // +75.00% from sp bonus - amount += CalculatePct(caster->SpellBaseDamageBonusDone(spellInfo->GetSchoolMask()), 75.0f); - - // Xinef: removed divine guardian because it will affect triggered spell with increased amount - // Arena - Dampening - if (AuraEffect const* dampening = caster->GetAuraEffect(SPELL_GENERIC_ARENA_DAMPENING, EFFECT_0)) - { - AddPct(amount, dampening->GetAmount()); - } - // Battleground - Dampening - else if (AuraEffect const* dampening2 = caster->GetAuraEffect(SPELL_GENERIC_BATTLEGROUND_DAMPENING, EFFECT_0)) - { - AddPct(amount, dampening2->GetAmount()); - } - } - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - HealInfo* healinfo = eventInfo.GetHealInfo(); - DamageInfo* damageinfo = eventInfo.GetDamageInfo(); - return !(eventInfo.GetHitMask() & PROC_EX_INTERNAL_HOT) && ((healinfo && healinfo->GetHeal() > 0) || (damageinfo && damageinfo->GetDamage() > 0)); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - if (eventInfo.GetTypeMask() & PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS) - { - Unit* caster = eventInfo.GetActor(); - - HealInfo* healinfo = eventInfo.GetHealInfo(); - - if (!healinfo || !healinfo->GetHeal()) - { - return; - } - - SpellInfo const* procSpell = healinfo->GetSpellInfo(); - if (!procSpell) - { - return; - } - - if (caster && procSpell->SpellFamilyName == SPELLFAMILY_PALADIN && - procSpell->SpellFamilyFlags.HasFlag(0x40000000) && caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_PALADIN, 3021, 0)) // need infusion of light - { - int32 basepoints = int32(float(healinfo->GetHeal()) / 12.0f); - // Item - Paladin T9 Holy 4P Bonus (Flash of Light) - if (AuraEffect const* aurEffect = caster->GetAuraEffect(67191, EFFECT_0)) - AddPct(basepoints, aurEffect->GetAmount()); - - caster->CastCustomSpell(eventInfo.GetActionTarget(), 66922, &basepoints, nullptr, nullptr, true, nullptr, aurEff, caster->GetGUID()); - return; - } - - return; - } - - uint32 now = GameTime::GetGameTimeMS().count(); - if (_cooldownEnd > now) - return; - - uint32 cooldown = SACRED_SHIELD_ICD; - - // Item - Paladin T8 Holy 4P Bonus - if (Unit* caster = aurEff->GetCaster()) - if (AuraEffect const* aurEffect = caster->GetAuraEffect(64895, 0)) - cooldown = aurEffect->GetAmount() * IN_MILLISECONDS; - - _cooldownEnd = now + cooldown; - - uint32 triggered_spell_id = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; - int32 basepoints = aurEff->GetAmount(); - eventInfo.GetActionTarget()->CastCustomSpell(eventInfo.GetActionTarget(), triggered_spell_id, &basepoints, nullptr, nullptr, true, nullptr, aurEff, eventInfo.GetActionTarget()->GetGUID()); - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_sacred_shield_base::CalculateAmount, EFFECT_0, SPELL_AURA_DUMMY); - DoCheckProc += AuraCheckProcFn(spell_pal_sacred_shield_base::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_pal_sacred_shield_base::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - // 31850 - Ardent Defender class spell_pal_ardent_defender : public AuraScript { @@ -2271,7 +2171,6 @@ void AddSC_paladin_spell_scripts() RegisterSpellScript(spell_pal_divine_purpose); RegisterSpellScript(spell_pal_seal_of_light); RegisterSpellScript(spell_pal_sacred_shield); - RegisterSpellScript(spell_pal_sacred_shield_base); RegisterSpellScript(spell_pal_ardent_defender); RegisterSpellScript(spell_pal_aura_mastery); RegisterSpellScript(spell_pal_aura_mastery_immune); From f7bc41eebec9c214df71adef292f1387a61e76c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Borz=C3=AC?= Date: Sat, 21 Feb 2026 17:42:52 +0100 Subject: [PATCH 197/335] refactor(Core/Entities): clean up vendor item removal and add QuaternionData Euler helpers (#24790) --- src/server/game/Entities/Creature/Creature.cpp | 2 +- src/server/game/Entities/GameObject/GameObject.cpp | 11 +++++++++++ src/server/game/Entities/GameObject/GameObjectData.h | 2 ++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index dd2ab4992..694c19287 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -88,7 +88,7 @@ bool VendorItemData::RemoveItem(uint32 item_id) { if ((*i)->item == item_id) { - i = m_items.erase(i++); + i = m_items.erase(i); found = true; } else diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 7979eeb21..32e450030 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -43,6 +43,17 @@ bool QuaternionData::IsUnit() const return fabs(x * x + y * y + z * z + w * w - 1.0f) < 1e-5f; } +void QuaternionData::ToEulerAnglesZYX(float& Z, float& Y, float& X) const +{ + G3D::Matrix3(G3D::Quat(x, y, z, w)).toEulerAnglesZYX(Z, Y, X); +} + +QuaternionData QuaternionData::FromEulerAnglesZYX(float Z, float Y, float X) +{ + G3D::Quat quat(G3D::Matrix3::fromEulerAnglesZYX(Z, Y, X)); + return QuaternionData(quat.x, quat.y, quat.z, quat.w); +} + GameObject::GameObject() : WorldObject(), MovableMapObject(), m_model(nullptr), m_goValue(), m_AI(nullptr) { diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h index eafe70a9d..39c1a6e28 100644 --- a/src/server/game/Entities/GameObject/GameObjectData.h +++ b/src/server/game/Entities/GameObject/GameObjectData.h @@ -689,6 +689,8 @@ struct AC_GAME_API QuaternionData QuaternionData(float X, float Y, float Z, float W) : x(X), y(Y), z(Z), w(W) { } [[nodiscard]] bool IsUnit() const; + void ToEulerAnglesZYX(float& Z, float& Y, float& X) const; + [[nodiscard]] static QuaternionData FromEulerAnglesZYX(float Z, float Y, float X); }; // `gameobject_addon` table From 34caea42becabe0c6f1f31142ee970ec75ac1e47 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 21 Feb 2026 16:43:14 +0000 Subject: [PATCH 198/335] chore(DB): import pending files Referenced commit(s): 1c91f96e0203572a3568ecbecadfb3790f53d190 --- .../rev_1771684443067867140.sql => db_world/2026_02_21_02.sql} | 1 + .../rev_1771685416037009585.sql => db_world/2026_02_21_03.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1771684443067867140.sql => db_world/2026_02_21_02.sql} (66%) rename data/sql/updates/{pending_db_world/rev_1771685416037009585.sql => db_world/2026_02_21_03.sql} (61%) diff --git a/data/sql/updates/pending_db_world/rev_1771684443067867140.sql b/data/sql/updates/db_world/2026_02_21_02.sql similarity index 66% rename from data/sql/updates/pending_db_world/rev_1771684443067867140.sql rename to data/sql/updates/db_world/2026_02_21_02.sql index 94cb8b822..c410c64b3 100644 --- a/data/sql/updates/pending_db_world/rev_1771684443067867140.sql +++ b/data/sql/updates/db_world/2026_02_21_02.sql @@ -1 +1,2 @@ +-- DB update 2026_02_21_01 -> 2026_02_21_02 DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_pal_sacred_shield_base'; diff --git a/data/sql/updates/pending_db_world/rev_1771685416037009585.sql b/data/sql/updates/db_world/2026_02_21_03.sql similarity index 61% rename from data/sql/updates/pending_db_world/rev_1771685416037009585.sql rename to data/sql/updates/db_world/2026_02_21_03.sql index f9dfbb9dc..c0aaa436a 100644 --- a/data/sql/updates/pending_db_world/rev_1771685416037009585.sql +++ b/data/sql/updates/db_world/2026_02_21_03.sql @@ -1 +1,2 @@ +-- DB update 2026_02_21_02 -> 2026_02_21_03 UPDATE `spell_proc` SET `SpellTypeMask` = 2 WHERE `SpellId` = 60510; From 052c36224abea362a816edf2196a6e7388258018 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sat, 21 Feb 2026 16:01:10 -0600 Subject: [PATCH 199/335] fix(Core/Spells): Port HandleBreakableCCAuraProc from TrinityCore (#24793) Co-authored-by: blinkysc Co-authored-by: joschiwald Co-authored-by: sogladev --- .../game/Spells/Auras/SpellAuraEffects.cpp | 18 + .../game/Spells/Auras/SpellAuraEffects.h | 1 + src/server/game/Spells/SpellMgr.cpp | 1 + .../game/Spells/BreakableCCProcTest.cpp | 369 ++++++++++++++++++ 4 files changed, 389 insertions(+) create mode 100644 src/test/server/game/Spells/BreakableCCProcTest.cpp diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 43f9b3adc..ef713a32d 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1254,6 +1254,14 @@ void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) switch (GetAuraType()) { + case SPELL_AURA_MOD_CONFUSE: + case SPELL_AURA_MOD_FEAR: + case SPELL_AURA_MOD_STUN: + case SPELL_AURA_MOD_ROOT: + case SPELL_AURA_TRANSFORM: + HandleBreakableCCAuraProc(aurApp, eventInfo); + break; + case SPELL_AURA_DUMMY: case SPELL_AURA_PROC_TRIGGER_SPELL: HandleProcTriggerSpellAuraProc(aurApp, eventInfo); break; @@ -7214,6 +7222,16 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con Unit::ProcSkillsAndAuras(caster, damageInfo.target, procAttacker, procVictim, hitMask, damageInfo.damage, BASE_ATTACK, spellProto, nullptr, GetEffIndex(), nullptr, &dmgInfo); } +void AuraEffect::HandleBreakableCCAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) +{ + int32 const damageLeft = GetAmount() - static_cast(eventInfo.GetDamageInfo()->GetDamage()); + + if (damageLeft <= 0) + aurApp->GetTarget()->RemoveAura(aurApp); + else + SetAmount(damageLeft); +} + void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) { Unit* triggerCaster = aurApp->GetTarget(); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index 937195060..960ded1dd 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -334,6 +334,7 @@ public: void HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) const; // aura effect proc handlers + void HandleBreakableCCAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo); void HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo); void HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo); void HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index c18449ec4..4374d9d77 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1822,6 +1822,7 @@ bool InitTriggerAuraData() isTriggerAura[SPELL_AURA_ABILITY_IGNORE_AURASTATE] = true; isAlwaysTriggeredAura[SPELL_AURA_OVERRIDE_CLASS_SCRIPTS] = true; + isAlwaysTriggeredAura[SPELL_AURA_MOD_CONFUSE] = true; isAlwaysTriggeredAura[SPELL_AURA_MOD_FEAR] = true; isAlwaysTriggeredAura[SPELL_AURA_MOD_ROOT] = true; isAlwaysTriggeredAura[SPELL_AURA_MOD_STUN] = true; diff --git a/src/test/server/game/Spells/BreakableCCProcTest.cpp b/src/test/server/game/Spells/BreakableCCProcTest.cpp new file mode 100644 index 000000000..1a81a78f4 --- /dev/null +++ b/src/test/server/game/Spells/BreakableCCProcTest.cpp @@ -0,0 +1,369 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file BreakableCCProcTest.cpp + * @brief Tests for the CC break-on-damage proc mechanism + * + * CC auras (Fear, Polymorph, Stun, Root, Transform) have a damage threshold + * set in CalculateAmount. When damage is taken, HandleBreakableCCAuraProc + * subtracts the damage from the threshold and removes the aura when it + * reaches zero. + * + * The threshold is calculated as: + * BaseHealth(casterLevel, CLASS_WARRIOR) / 4.75 + * + * This gives level 80 a threshold of ~2648 HP (12588 / 4.75). + */ + +#include "AuraStub.h" +#include "ProcChanceTestHelper.h" +#include "ProcEventInfoHelper.h" +#include "SpellMgr.h" +#include "WorldMock.h" +#include "gtest/gtest.h" + +using namespace testing; + +/** + * @brief Simulates HandleBreakableCCAuraProc logic + * + * Mirrors AuraEffect::HandleBreakableCCAuraProc from SpellAuraEffects.cpp: + * damageLeft = GetAmount() - damage + * if (damageLeft <= 0) remove aura + * else SetAmount(damageLeft) + * + * @param effect The CC aura effect stub (amount = damage threshold) + * @param damage Damage dealt to the CC'd target + * @return true if the aura should be removed (threshold exceeded) + */ +static bool SimulateBreakableCCProc(AuraEffectStub* effect, int32_t damage) +{ + int32_t damageLeft = effect->GetAmount() - damage; + if (damageLeft <= 0) + return true; // aura removed + effect->SetAmount(damageLeft); + return false; // aura survives, threshold reduced +} + +/** + * @brief Simulates CalculateAmount for CC auras + * + * Mirrors AuraEffect::CalculateAmount from SpellAuraEffects.cpp for + * MOD_FEAR/MOD_CONFUSE/MOD_STUN/MOD_ROOT/TRANSFORM: + * amount = BaseHealth(casterLevel, CLASS_WARRIOR) / 4.75 + * + * Uses known Warrior base health values from CreatureBaseStats DBC. + */ +static int32_t SimulateCCThreshold(uint8_t casterLevel) +{ + // Warrior base health at key levels (EXPANSION_WRATH_OF_THE_LICH_KING) + // From creature_classlevelstats for CLASS_WARRIOR + struct LevelHealth { uint8_t level; int32_t health; }; + static constexpr LevelHealth table[] = { + {1, 60}, {10, 424}, {20, 1128}, {30, 2078}, {40, 3228}, + {50, 4978}, {60, 7361}, {70, 9940}, {80, 12588}, + }; + + int32_t baseHealth = 12588; // default to level 80 + for (auto const& entry : table) + { + if (entry.level == casterLevel) + { + baseHealth = entry.health; + break; + } + } + + return static_cast(baseHealth / 4.75f); +} + +// ============================================================================= +// Test Fixture +// ============================================================================= + +class BreakableCCProcTest : public ::testing::Test +{ +protected: + void SetUp() override + { + _originalWorld = sWorld.release(); + _worldMock = new NiceMock(); + sWorld.reset(_worldMock); + } + + void TearDown() override + { + IWorld* currentWorld = sWorld.release(); + delete currentWorld; + sWorld.reset(_originalWorld); + } + + /** + * @brief Create a CC aura effect stub with the given threshold + */ + AuraEffectStub CreateCCEffect(int32_t threshold, uint32_t auraType = 7 /* MOD_FEAR */) + { + AuraEffectStub effect(0, threshold, auraType); + return effect; + } + +private: + IWorld* _originalWorld = nullptr; + NiceMock* _worldMock = nullptr; +}; + +// ============================================================================= +// HandleBreakableCCAuraProc Logic Tests +// ============================================================================= + +TEST_F(BreakableCCProcTest, SmallDamage_ReducesThreshold_AuraSurvives) +{ + auto effect = CreateCCEffect(1000); + + bool removed = SimulateBreakableCCProc(&effect, 100); + + EXPECT_FALSE(removed); + EXPECT_EQ(effect.GetAmount(), 900); +} + +TEST_F(BreakableCCProcTest, ExactThresholdDamage_RemovesAura) +{ + auto effect = CreateCCEffect(1000); + + bool removed = SimulateBreakableCCProc(&effect, 1000); + + EXPECT_TRUE(removed); +} + +TEST_F(BreakableCCProcTest, ExceedThresholdDamage_RemovesAura) +{ + auto effect = CreateCCEffect(1000); + + bool removed = SimulateBreakableCCProc(&effect, 5000); + + EXPECT_TRUE(removed); +} + +TEST_F(BreakableCCProcTest, MultipleDamageHits_AccumulateUntilBreak) +{ + auto effect = CreateCCEffect(1000); + + // First hit: 400 damage, 600 remaining + EXPECT_FALSE(SimulateBreakableCCProc(&effect, 400)); + EXPECT_EQ(effect.GetAmount(), 600); + + // Second hit: 300 damage, 300 remaining + EXPECT_FALSE(SimulateBreakableCCProc(&effect, 300)); + EXPECT_EQ(effect.GetAmount(), 300); + + // Third hit: 300 damage, exactly 0 remaining -> remove + EXPECT_TRUE(SimulateBreakableCCProc(&effect, 300)); +} + +TEST_F(BreakableCCProcTest, MultipleDamageHits_OvershootBreak) +{ + auto effect = CreateCCEffect(500); + + // First hit: 200 damage + EXPECT_FALSE(SimulateBreakableCCProc(&effect, 200)); + EXPECT_EQ(effect.GetAmount(), 300); + + // Second hit: 400 damage, exceeds remaining 300 + EXPECT_TRUE(SimulateBreakableCCProc(&effect, 400)); +} + +TEST_F(BreakableCCProcTest, OneDamage_ReducesThreshold) +{ + auto effect = CreateCCEffect(1000); + + EXPECT_FALSE(SimulateBreakableCCProc(&effect, 1)); + EXPECT_EQ(effect.GetAmount(), 999); +} + +// ============================================================================= +// Threshold Calculation Tests (CalculateAmount for CC auras) +// ============================================================================= + +TEST_F(BreakableCCProcTest, Level80Threshold_IsReasonable) +{ + int32_t threshold = SimulateCCThreshold(80); + + // Level 80 warrior base health = 12588 + // Threshold = 12588 / 4.75 ≈ 2650 + EXPECT_GT(threshold, 2600); + EXPECT_LT(threshold, 2700); +} + +TEST_F(BreakableCCProcTest, LowerLevelCaster_LowerThreshold) +{ + int32_t threshold60 = SimulateCCThreshold(60); + int32_t threshold80 = SimulateCCThreshold(80); + + EXPECT_LT(threshold60, threshold80); +} + +TEST_F(BreakableCCProcTest, Level80Fear_BreaksOnModerateDamage) +{ + // Simulate a level 80 warlock's Fear + int32_t threshold = SimulateCCThreshold(80); // ~2650 + auto effect = CreateCCEffect(threshold); + + // A 3000 damage hit should break it + EXPECT_TRUE(SimulateBreakableCCProc(&effect, 3000)); +} + +TEST_F(BreakableCCProcTest, Level80Fear_SurvivesSmallDots) +{ + // Simulate a level 80 warlock's Fear + int32_t threshold = SimulateCCThreshold(80); // ~2650 + auto effect = CreateCCEffect(threshold); + + // Small DoT ticks of 200 each - Fear should survive multiple ticks + for (int i = 0; i < 10; ++i) + { + bool removed = SimulateBreakableCCProc(&effect, 200); + if (i < 12) // Should survive at least 12 ticks (200*13 = 2600 < 2650) + { + // We expect it to survive for ~13 ticks + if (!removed) + continue; + } + if (removed) + { + // Should break around tick 13-14 + EXPECT_GE(i, 12); + return; + } + } + // If we get here, verify remaining threshold + EXPECT_GT(effect.GetAmount(), 0); +} + +// ============================================================================= +// Proc Pipeline Integration Tests (using CanSpellTriggerProcOnEvent) +// ============================================================================= + +TEST_F(BreakableCCProcTest, FearProcEntry_MatchesTakenMeleeDamage) +{ + // Fear's auto-generated proc entry from DBC ProcFlags + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags( + PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | + PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS | + PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK | + PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS | + PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG | + PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | + PROC_FLAG_TAKEN_PERIODIC) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithChance(100.0f) + .Build(); + + // Melee auto attack should trigger + auto meleeEvent = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK) + .WithHitMask(PROC_HIT_NORMAL) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, meleeEvent)); +} + +TEST_F(BreakableCCProcTest, FearProcEntry_MatchesTakenSpellDamage) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags( + PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | + PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS | + PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK | + PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS | + PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG | + PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | + PROC_FLAG_TAKEN_PERIODIC) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithChance(100.0f) + .Build(); + + // Magic damage spell should trigger + auto spellEvent = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG) + .WithHitMask(PROC_HIT_NORMAL) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, spellEvent)); +} + +TEST_F(BreakableCCProcTest, FearProcEntry_DoesNotMatchHealEvent) +{ + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags( + PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | + PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS | + PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK | + PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS | + PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG | + PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | + PROC_FLAG_TAKEN_PERIODIC) + .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .WithChance(100.0f) + .Build(); + + // Heal should NOT trigger Fear's proc + auto healEvent = ProcEventInfoBuilder() + .WithTypeMask(PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS) + .WithHitMask(PROC_HIT_NORMAL) + .WithSpellTypeMask(PROC_SPELL_TYPE_HEAL) + .WithSpellPhaseMask(PROC_SPELL_PHASE_HIT) + .Build(); + + EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, healEvent)); +} + +TEST_F(BreakableCCProcTest, FearProcChance_Is100Percent) +{ + auto procEntry = SpellProcEntryBuilder() + .WithChance(100.0f) + .Build(); + + // Fear has 100% proc chance from DBC - every damage event triggers + float chance = ProcChanceTestHelper::SimulateCalcProcChance(procEntry); + EXPECT_FLOAT_EQ(chance, 100.0f); +} + +// ============================================================================= +// Glyph of Fear Threshold Modifier Test +// ============================================================================= + +TEST_F(BreakableCCProcTest, GlyphOfFear_IncreasesThreshold) +{ + // Glyph of Fear adds +100% to the damage threshold (MiscValue 7801) + int32_t baseThreshold = SimulateCCThreshold(80); // ~2650 + int32_t glyphedThreshold = baseThreshold + (baseThreshold * 100 / 100); // +100% + + auto effect = CreateCCEffect(glyphedThreshold); + + // Should survive hits that would normally break it + EXPECT_FALSE(SimulateBreakableCCProc(&effect, 3000)); + EXPECT_GT(effect.GetAmount(), 0); +} From 0994714bd1cef1364154c353091585bcbac9843d Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 21 Feb 2026 19:50:14 -0300 Subject: [PATCH 200/335] fix(Scripts/EoE): Implement Malygos Vortex (#24726) Co-authored-by: Manuel Carrasco (maanuel) Co-authored-by: Claude Opus 4.6 Co-authored-by: Manuel Carrasco Co-authored-by: Trista --- .../rev_vortex_spell_scripts.sql | 24 ++ .../game/Spells/SpellInfoCorrections.cpp | 6 - .../Nexus/EyeOfEternity/boss_malygos.cpp | 269 ++++++++---------- .../Nexus/EyeOfEternity/eye_of_eternity.h | 8 +- .../instance_eye_of_eternity.cpp | 49 ++++ 5 files changed, 191 insertions(+), 165 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_vortex_spell_scripts.sql diff --git a/data/sql/updates/pending_db_world/rev_vortex_spell_scripts.sql b/data/sql/updates/pending_db_world/rev_vortex_spell_scripts.sql new file mode 100644 index 000000000..1d35e2f20 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_vortex_spell_scripts.sql @@ -0,0 +1,24 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN (56105, 55873); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(56105, 'spell_malygos_vortex_dummy'), +(55873, 'spell_malygos_vortex_visual'); + +DELETE FROM `creature` WHERE `guid` IN (132304, 132305, 132306, 132307, 132308); +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`, `ScriptName`, `VerifiedBuild`) +VALUES +(132304,30090,616,0,0,3,1,0,754.733,1301.51,283.379,5.58505,3600,0,0,12600,0,0,0,0,0,'',0), +(132305,30090,616,0,0,3,1,0,754.521,1301.23,279.524,0.680678,3600,0,0,12600,0,0,0,0,0,'',0), +(132306,30090,616,0,0,3,1,0,754.356,1301.48,285.733,5.96903,3600,0,0,12600,0,0,0,0,0,'',0), +(132307,30090,616,0,0,3,1,0,754.192,1301.18,281.851,5.75959,3600,0,0,12600,0,0,0,0,0,'',0), +(132308,30090,616,0,0,3,1,0,754.688,1301.8,287.295,1.25664,3600,0,0,12600,0,0,0,0,0,'',0); + +UPDATE `creature_template` SET `unit_flags` = `unit_flags`|33554432, `VehicleId` = 214, `flags_extra` = `flags_extra`|2|128, `ScriptName` = '' WHERE `entry` = 30090; + +DELETE FROM `creature_template_addon` WHERE `entry` = 30090; +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(30090, 0, 0, 0, 0, 0, 0, '55883'); diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index 66e77fa95..86bd0acc6 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -1892,12 +1892,6 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST); }); - // Vortex (freeze anim) - ApplySpellFix({ 55883 }, [](SpellInfo* spellInfo) - { - spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP; - }); - // Hurl Pyrite ApplySpellFix({ 62490 }, [](SpellInfo* spellInfo) { diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 67c9af88e..7c68f7a4f 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -19,8 +19,6 @@ #include "CreatureScript.h" #include "GameObjectAI.h" #include "GameObjectScript.h" -#include "MoveSplineInit.h" -#include "Opcodes.h" #include "PassiveAI.h" #include "Player.h" #include "ScriptMgr.h" @@ -61,9 +59,11 @@ enum MalygosSpells SPELL_ARCANE_BREATH = 56272, SPELL_ARCANE_STORM = 61693, + SPELL_VORTEX_1 = 56237, SPELL_VORTEX_VISUAL = 55873, + SPELL_VORTEX_DUMMY = 56105, + SPELL_VORTEX_TELEPORT = 73040, SPELL_VORTEX_CONTROL_VEHICLE = 56263, - SPELL_FREEZE_ANIM = 55883, SPELL_ARCANE_OVERLOAD = 56430, SPELL_ARCANE_OVERLOAD_SUMMON = 56429, @@ -195,6 +195,7 @@ struct boss_malygos : public BossAI uint32 timer1, timer2; uint8 IntroCounter; bool bLockHealthCheck; + bool _executingVortex; void InitializeAI() override { @@ -210,6 +211,7 @@ struct boss_malygos : public BossAI timer2 = INTRO_MOVEMENT_INTERVAL; IntroCounter = 0; bLockHealthCheck = false; + _executingVortex = false; SetInvincibility(true); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); @@ -223,7 +225,7 @@ struct boss_malygos : public BossAI void MovementInform(uint32 type, uint32 id) override { - if (type != POINT_MOTION_TYPE) + if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE) return; switch (id) @@ -245,9 +247,8 @@ struct boss_malygos : public BossAI events.RescheduleEvent(EVENT_INTRO_LAND, 0ms, 1); break; case MI_POINT_VORTEX_CENTER: - if (Creature* trigger = me->SummonCreature(NPC_WORLD_TRIGGER_LAOI, CenterPos, TEMPSUMMON_TIMED_DESPAWN, 15000)) - trigger->CastSpell(trigger, SPELL_VORTEX_VISUAL, true); - events.RescheduleEvent(EVENT_START_VORTEX_REAL, 1s, 1); + me->GetMotionMaster()->MoveIdle(); + events.RescheduleEvent(EVENT_START_VORTEX_REAL, 0ms, 1); break; case MI_POINT_CENTER_GROUND_PH_2: events.RescheduleEvent(EVENT_START_PHASE_2_FLY_UP, 0ms, 1); @@ -384,10 +385,20 @@ struct boss_malygos : public BossAI break; } case EVENT_SPELL_ARCANE_BREATH: + if (_executingVortex) + { + events.Repeat(12s, 15s); + break; + } me->CastSpell(me->GetVictim(), SPELL_ARCANE_BREATH, false); events.Repeat(12s, 15s); break; case EVENT_SPELL_ARCANE_STORM: + if (_executingVortex) + { + events.Repeat(10s, 15s); + break; + } me->CastCustomSpell(SPELL_ARCANE_STORM, SPELLVALUE_MAX_TARGETS, DUNGEON_MODE(5, 12), me, true); events.Repeat(10s, 15s); break; @@ -407,6 +418,7 @@ struct boss_malygos : public BossAI break; case EVENT_START_VORTEX_0: { + _executingVortex = true; bLockHealthCheck = true; Talk(SAY_MAGIC_BLAST); EntryCheckPredicate pred(NPC_POWER_SPARK); @@ -425,7 +437,9 @@ struct boss_malygos : public BossAI } break; case EVENT_VORTEX_FLY_TO_CENTER: - me->GetMotionMaster()->MovePoint(MI_POINT_VORTEX_CENTER, CenterPos.GetPositionX(), CenterPos.GetPositionY(), CenterPos.GetPositionZ() + 20.0f); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->GetMotionMaster()->MovePoint(MI_POINT_VORTEX_CENTER, VortexPos); break; case EVENT_START_VORTEX_REAL: { @@ -433,63 +447,9 @@ struct boss_malygos : public BossAI me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_CUSTOM_SPELL_01); me->HandleEmoteCommand(EMOTE_STATE_CUSTOM_SPELL_01); - Position pos; - float angle = (me->GetOrientation() >= M_PI / 4 ? me->GetOrientation() - M_PI / 4 : 7 * M_PI / 4 + me->GetOrientation()); - pos.m_positionX = CenterPos.GetPositionX() + cos(angle) * 40.0f; - pos.m_positionY = CenterPos.GetPositionY() + std::sin(angle) * 40.0f; - pos.m_positionZ = CenterPos.GetPositionZ() + 20.0f; - pos.SetOrientation(pos.GetAngle(&CenterPos)); - - if (Creature* vp = me->SummonCreature(NPC_WORLD_TRIGGER_LAOI, pos, TEMPSUMMON_TIMED_DESPAWN, 14000)) - { - vp->SetDisableGravity(true); - - me->GetMap()->DoForAllPlayers([&](Player* player) - { - if (!player->IsAlive() || player->IsGameMaster()) - return; - - Position plrpos; - float playerAngle = CenterPos.GetAngle(player); - plrpos.m_positionX = CenterPos.GetPositionX() + cos(playerAngle) * 5.0f; - plrpos.m_positionY = CenterPos.GetPositionY() + std::sin(playerAngle) * 5.0f; - plrpos.m_positionZ = CenterPos.GetPositionZ() + 18.0f; - plrpos.SetOrientation(plrpos.GetAngle(&CenterPos)); - - if (Creature* vortex = me->SummonCreature(NPC_VORTEX, plrpos, TEMPSUMMON_TIMED_DESPAWN, 15000)) - { - player->CastSpell(player, SPELL_FREEZE_ANIM, true); - player->CastSpell(vortex, SPELL_VORTEX_CONTROL_VEHICLE, true); - if (!player->GetVehicle()) // didn't work somehow, try again with a different way, if fails - break - { - player->EnterVehicle(vortex, 0); - if (!player->GetVehicle()) - return; - } - //player->ClearUnitState(UNIT_STATE_ONVEHICLE); - - Movement::MoveSplineInit init(player); // TODO: has to be removed and handled with vehicle exit and vehicle enter code - init.MoveTo(CenterPos.GetPositionX(), CenterPos.GetPositionY(), CenterPos.GetPositionZ()); - init.SetFacing(player->GetOrientation()); - init.SetTransportExit(); - init.Launch(); - - player->SetUnitMovementFlags(MOVEMENTFLAG_NONE); - player->SetDisableGravity(true); - - WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); - data << player->GetPackGUID(); - player->SendMessageToSet(&data, true); - - sScriptMgr->AnticheatSetUnderACKmount(player); - - player->SetGuidValue(PLAYER_FARSIGHT, vp->GetGUID()); - vortex->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - } - }); - } - - events.RescheduleEvent(EVENT_VORTEX_LAND_0, 11s, 1); + me->CastSpell(me, SPELL_VORTEX_1, true); + me->CastSpell(me, SPELL_VORTEX_VISUAL, true); + me->CastSpell(me, SPELL_VORTEX_DUMMY, true); break; } case EVENT_VORTEX_LAND_0: @@ -497,10 +457,12 @@ struct boss_malygos : public BossAI break; case EVENT_VORTEX_LAND_1: { + _executingVortex = false; bLockHealthCheck = false; EntryCheckPredicate pred(NPC_POWER_SPARK); summons.DoAction(ACTION_POWER_SPARK_FOLLOW, pred); me->RemoveUnitFlag(UNIT_FLAG_PACIFIED); + me->SetReactState(REACT_AGGRESSIVE); me->ResumeChasingVictim(); events.RescheduleEvent(EVENT_START_VORTEX_0, 60s, 1); break; @@ -779,98 +741,6 @@ struct boss_malygos : public BossAI } }; -#define VORTEX_DEFAULT_DIFF 250 -#define VORTEX_TRAVEL_TIME 3000 - -struct npc_vortex_ride : public VehicleAI -{ - npc_vortex_ride(Creature* creature) : VehicleAI(creature) - { - vortexRadius = urand(22, 28); - float h = urand(15, 30); - float angle = CenterPos.GetAngle(me); - Position pos; - pos.m_positionX = CenterPos.GetPositionX() + vortexRadius * cos(angle); - pos.m_positionY = CenterPos.GetPositionY() + vortexRadius * std::sin(angle); - pos.m_positionZ = CenterPos.GetPositionZ() + h; - pos.SetOrientation(pos.GetAngle(&CenterPos)); - me->SetPosition(pos); - timer = 0; - despawnTimer = 9500; - bUpdatedFlying = false; - } - - uint32 timer; - uint32 despawnTimer; - bool bUpdatedFlying; - float vortexRadius; - - void PassengerBoarded(Unit* pass, int8 /*seat*/, bool apply) override - { - if (!pass || apply || !pass->IsPlayer()) - return; - - Player* player = pass->ToPlayer(); - float speed = player->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()) / (1.0f * 0.001f); - player->SetDisableGravity(false); // packet only would lead to issues elsewhere - player->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), speed); - player->RemoveAura(SPELL_FREEZE_ANIM); - player->SetGuidValue(PLAYER_FARSIGHT, ObjectGuid::Empty); - - sScriptMgr->AnticheatSetCanFlybyServer(player, false); - sScriptMgr->AnticheatSetUnderACKmount(player); - } - - void UpdateAI(uint32 diff) override - { - if (despawnTimer <= diff) - { - despawnTimer = 0; - me->UpdatePosition(CenterPos.GetPositionX(), CenterPos.GetPositionY(), CenterPos.GetPositionZ() + 18.0f, 0.0f, true); - me->StopMovingOnCurrentPos(); - if (Vehicle* vehicle = me->GetVehicleKit()) - vehicle->RemoveAllPassengers(); - me->DespawnOrUnsummon(); - return; - } - else - despawnTimer -= diff; - - if (timer <= diff) - { - float angle = CenterPos.GetAngle(me); - float newangle = angle + 2 * M_PI / ((float)VORTEX_TRAVEL_TIME / VORTEX_DEFAULT_DIFF); - if (newangle >= 2 * M_PI) - newangle -= 2 * M_PI; - float newx = CenterPos.GetPositionX() + vortexRadius * cos(newangle); - float newy = CenterPos.GetPositionY() + vortexRadius * std::sin(newangle); - float arcangle = me->GetAngle(newx, newy); - float dist = 2 * me->GetDistance2d(newx, newy); - if (me->GetVehicleKit()) - if (Unit* pass = me->GetVehicleKit()->GetPassenger(0)) - if (Player* player = pass->ToPlayer()) - { - if (!bUpdatedFlying && timer) - { - bUpdatedFlying = true; - player->SetDisableGravity(true); - } - - player->SendMonsterMove(me->GetPositionX() + dist * cos(arcangle), me->GetPositionY() + dist * std::sin(arcangle), me->GetPositionZ(), VORTEX_DEFAULT_DIFF * 2, SPLINEFLAG_FLYING); - me->Relocate(newx, newy); - } - - timer = (diff - timer <= VORTEX_DEFAULT_DIFF) ? VORTEX_DEFAULT_DIFF - (diff - timer) : 0; - } - else - timer -= diff; - } - - void AttackStart(Unit* /*who*/) override {} - void MoveInLineOfSight(Unit* /*who*/) override {} - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override { damage = 0; } -}; - struct npc_power_spark : public NullCreatureAI { npc_power_spark(Creature* creature) : NullCreatureAI(creature) @@ -948,7 +818,15 @@ struct npc_power_spark : public NullCreatureAI { if (_instance) if (Creature* malygos = _instance->GetCreature(DATA_MALYGOS)) + { + if (malygos->HasAura(SPELL_VORTEX_1)) + { + me->GetMotionMaster()->MoveIdle(); + _moveTimer = 2000; + return; + } me->GetMotionMaster()->MovePoint(0, *malygos); + } _moveTimer = 2000; } else @@ -1273,6 +1151,80 @@ struct go_the_focusing_iris : public GameObjectAI } }; +// 56105 - Vortex +class spell_malygos_vortex_dummy : public SpellScript +{ + PrepareSpellScript(spell_malygos_vortex_dummy); + + bool Load() override + { + return GetCaster()->IsCreature(); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Creature* caster = GetCaster()->ToCreature(); + if (!caster) + return; + + if (InstanceScript* instance = caster->GetInstanceScript()) + instance->SetData(DATA_VORTEX_HANDLING, 0); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_malygos_vortex_dummy::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 55873 - Vortex +class spell_malygos_vortex_visual : public AuraScript +{ + PrepareAuraScript(spell_malygos_vortex_visual); + + bool Load() override + { + return GetCaster()->IsCreature(); + } + + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_VORTEX_1, SPELL_VORTEX_TELEPORT }); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Creature* caster = GetCaster()->ToCreature(); + if (!caster) + return; + + for (auto const* ref : caster->GetThreatMgr().GetUnsortedThreatList()) + { + if (Player* player = ref->GetVictim()->ToPlayer()) + { + if (player->IsGameMaster()) + continue; + + if (InstanceScript* instance =caster->GetInstanceScript()) + { + if (Creature* trigger =ObjectAccessor::GetCreature(*caster, instance->GetGuidData(DATA_VORTEX_TRIGGER))) + trigger->CastSpell(player, SPELL_VORTEX_TELEPORT, true); + } + } + } + + caster->GetMotionMaster()->MoveLand(MI_POINT_VORTEX_LAND, VortexLandPos); + caster->RemoveAura(SPELL_VORTEX_1); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn( + spell_malygos_vortex_visual::OnRemove, + EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + class spell_eoe_ph3_surge_of_power : public SpellScript { PrepareSpellScript(spell_eoe_ph3_surge_of_power); @@ -1363,7 +1315,6 @@ void AddSC_boss_malygos() { RegisterEoECreatureAI(boss_malygos); RegisterEoECreatureAI(npc_power_spark); - RegisterEoECreatureAI(npc_vortex_ride); RegisterEoECreatureAI(npc_alexstrasza); RegisterGameObjectAI(go_the_focusing_iris); RegisterEoECreatureAI(npc_nexus_lord); @@ -1374,4 +1325,6 @@ void AddSC_boss_malygos() RegisterSpellScript(spell_wyrmrest_skytalon_ride_red_dragon_buddy_trigger); RegisterSpellScript(spell_eoe_ph3_surge_of_power); + RegisterSpellScript(spell_malygos_vortex_dummy); + RegisterSpellScript(spell_malygos_vortex_visual); } diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h index c77eb635c..d46499c5c 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h @@ -60,6 +60,8 @@ enum Data DATA_IRIS_ACTIVATED, DATA_SET_IRIS_INACTIVE, DATA_HIDE_IRIS_AND_PORTAL, + DATA_VORTEX_HANDLING, + DATA_VORTEX_TRIGGER, }; enum eSpells @@ -78,7 +80,9 @@ enum eSpells SPELL_ALEXSTRASZA_GIFT = 61028, SPELL_SUMMON_RED_DRAGON_BUDDY = 56070, - SPELL_RIDE_RED_DRAGON = 56072 + SPELL_RIDE_RED_DRAGON = 56072, + + SPELL_VORTEX_4 = 55853, }; enum eAchiev @@ -116,6 +120,8 @@ enum AlexstraszaEvents /*** POSITIONS/WAYPOINTS BELOW ***/ const Position CenterPos = {754.395f, 1301.27f, 266.10f, 0.0f}; +const Position VortexPos = {754.393f, 1301.27f, 292.91f, 0.0f}; +const Position VortexLandPos = {754.362f, 1301.61f, 266.17f, 0.0f}; const Position FourSidesPos[] = { diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index 0b4e5060f..c14e71177 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -48,6 +48,52 @@ struct instance_eye_of_eternity : public InstanceScript } bool _pokeAchievementValid = false; + GuidVector _vortexTriggers; + + void OnCreatureCreate(Creature* creature) override + { + InstanceScript::OnCreatureCreate(creature); + + if (creature->GetEntry() == NPC_VORTEX) + _vortexTriggers.push_back(creature->GetGUID()); + } + + ObjectGuid GetGuidData(uint32 data) const override + { + if (data == DATA_VORTEX_TRIGGER) + return !_vortexTriggers.empty() ? _vortexTriggers.front() : ObjectGuid::Empty; + + return InstanceScript::GetGuidData(data); + } + + void VortexHandling() + { + Creature* malygos = GetCreature(DATA_MALYGOS); + if (!malygos) + return; + + for (ObjectGuid const& guid : _vortexTriggers) + { + uint8 counter = 0; + if (Creature* trigger = instance->GetCreature(guid)) + { + for (auto* ref : malygos->GetThreatMgr().GetUnsortedThreatList()) + { + if (counter >= 5) + break; + + if (Player* player = ref->GetVictim()->ToPlayer()) + { + if (player->IsGameMaster() || player->HasAura(SPELL_VORTEX_4)) + continue; + + player->CastSpell(trigger, SPELL_VORTEX_4, true); + counter++; + } + } + } + } + } void OnPlayerEnter(Player* player) override { @@ -108,6 +154,9 @@ struct instance_eye_of_eternity : public InstanceScript if (GameObject* portal = GetGameObject(DATA_EXIT_PORTAL)) portal->SetPhaseMask(2, true); break; + case DATA_VORTEX_HANDLING: + VortexHandling(); + break; } } From def5924d3be70267471333f47f27fe25aca1e088 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 21 Feb 2026 22:51:24 +0000 Subject: [PATCH 201/335] chore(DB): import pending files Referenced commit(s): 0994714bd1cef1364154c353091585bcbac9843d --- .../rev_vortex_spell_scripts.sql => db_world/2026_02_21_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_vortex_spell_scripts.sql => db_world/2026_02_21_04.sql} (97%) diff --git a/data/sql/updates/pending_db_world/rev_vortex_spell_scripts.sql b/data/sql/updates/db_world/2026_02_21_04.sql similarity index 97% rename from data/sql/updates/pending_db_world/rev_vortex_spell_scripts.sql rename to data/sql/updates/db_world/2026_02_21_04.sql index 1d35e2f20..0fdea4d91 100644 --- a/data/sql/updates/pending_db_world/rev_vortex_spell_scripts.sql +++ b/data/sql/updates/db_world/2026_02_21_04.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_21_03 -> 2026_02_21_04 DELETE FROM `spell_script_names` WHERE `spell_id` IN (56105, 55873); INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (56105, 'spell_malygos_vortex_dummy'), From a4e1975a334586095b69dc2af0b1b1ace7165354 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 22 Feb 2026 05:14:02 -0300 Subject: [PATCH 202/335] fix(DB/Creature): Fix Power Spark movement (#24798) --- .../updates/pending_db_world/rev_1771736808435225100.sql | 8 ++++++++ .../Northrend/Nexus/EyeOfEternity/boss_malygos.cpp | 1 - 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771736808435225100.sql diff --git a/data/sql/updates/pending_db_world/rev_1771736808435225100.sql b/data/sql/updates/pending_db_world/rev_1771736808435225100.sql new file mode 100644 index 000000000..baaa3a046 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771736808435225100.sql @@ -0,0 +1,8 @@ +-- +DELETE FROM `creature_template_addon` WHERE `entry` = 30084; +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(30084, 0, 0, 0, 0, 0, 0, '55845'); + +DELETE FROM `creature_template_movement` WHERE `CreatureId` = 30084; +INSERT INTO `creature_template_movement` (`CreatureId`, `Flight`) VALUES +(30084, 1); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 7c68f7a4f..2f965f509 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -746,7 +746,6 @@ struct npc_power_spark : public NullCreatureAI npc_power_spark(Creature* creature) : NullCreatureAI(creature) { _instance = me->GetInstanceScript(); - me->CastSpell(me, SPELL_POWER_SPARK_VISUAL, false); _checkTimer = 1000; _moveTimer = 0; } From 65cbe0a8187d0d192104b964d0e4cca8326d5ecd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 22 Feb 2026 08:15:04 +0000 Subject: [PATCH 203/335] chore(DB): import pending files Referenced commit(s): a4e1975a334586095b69dc2af0b1b1ace7165354 --- .../rev_1771736808435225100.sql => db_world/2026_02_22_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771736808435225100.sql => db_world/2026_02_22_00.sql} (89%) diff --git a/data/sql/updates/pending_db_world/rev_1771736808435225100.sql b/data/sql/updates/db_world/2026_02_22_00.sql similarity index 89% rename from data/sql/updates/pending_db_world/rev_1771736808435225100.sql rename to data/sql/updates/db_world/2026_02_22_00.sql index baaa3a046..d672711a7 100644 --- a/data/sql/updates/pending_db_world/rev_1771736808435225100.sql +++ b/data/sql/updates/db_world/2026_02_22_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_21_04 -> 2026_02_22_00 -- DELETE FROM `creature_template_addon` WHERE `entry` = 30084; INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES From 0759d4700094709d3af37102a5160c362de247ae Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 22 Feb 2026 10:55:18 -0300 Subject: [PATCH 204/335] fix(Scripts/EoE): Remove useless Focusing Iris script (#24804) --- .../rev_1771764309163193800.sql | 2 + .../Nexus/EyeOfEternity/boss_malygos.cpp | 14 ------ .../Nexus/EyeOfEternity/eye_of_eternity.h | 3 +- .../instance_eye_of_eternity.cpp | 48 ++++++++----------- 4 files changed, 23 insertions(+), 44 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771764309163193800.sql diff --git a/data/sql/updates/pending_db_world/rev_1771764309163193800.sql b/data/sql/updates/pending_db_world/rev_1771764309163193800.sql new file mode 100644 index 000000000..797a96634 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771764309163193800.sql @@ -0,0 +1,2 @@ +-- +UPDATE `gameobject_template` SET `ScriptName` = '' WHERE `entry` IN (193958, 193960) AND `ScriptName` = 'go_the_focusing_iris'; diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 2f965f509..2f228e856 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -1137,19 +1137,6 @@ struct npc_eoe_wyrmrest_skytalon : public VehicleAI } }; -struct go_the_focusing_iris : public GameObjectAI -{ - go_the_focusing_iris(GameObject* go) : GameObjectAI(go) { } - - bool GossipHello(Player* /*user*/, bool /*reportUse*/) override - { - if (InstanceScript* instance = me->GetInstanceScript()) - instance->SetData(DATA_IRIS_ACTIVATED, 0); - - return true; - } -}; - // 56105 - Vortex class spell_malygos_vortex_dummy : public SpellScript { @@ -1315,7 +1302,6 @@ void AddSC_boss_malygos() RegisterEoECreatureAI(boss_malygos); RegisterEoECreatureAI(npc_power_spark); RegisterEoECreatureAI(npc_alexstrasza); - RegisterGameObjectAI(go_the_focusing_iris); RegisterEoECreatureAI(npc_nexus_lord); RegisterEoECreatureAI(npc_scion_of_eternity); RegisterEoECreatureAI(npc_hover_disk); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h index d46499c5c..8d6eed06c 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h @@ -97,7 +97,8 @@ enum eAchiev enum EoEMisc : uint32 { AREA_EYE_OF_ETERNITY = 4500, - EVENT_IRIS_ACTIVATED = 20158, + EVENT_DESTROY_PLATFORM = 20158, + EVENT_IRIS_ACTIVATED = 20711, PLATFORM_DESTROY_DAMAGE = 6500000, INTRO_MOVEMENT_INTERVAL = 25000, }; diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index c14e71177..efa2bcf9f 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -97,15 +97,7 @@ struct instance_eye_of_eternity : public InstanceScript void OnPlayerEnter(Player* player) override { - if (GetBossState(DATA_MALYGOS) != DONE) - return; - - ProcessEvent(nullptr, EVENT_IRIS_ACTIVATED); - if (GameObject* iris = GetGameObject(DATA_IRIS)) - if (iris->GetPhaseMask() != 2) - iris->SetPhaseMask(2, true); - - if (player && player->IsAlive()) + if (player && player->IsAlive() && IsBossDone(DATA_MALYGOS)) player->CastSpell(player, SPELL_SUMMON_RED_DRAGON_BUDDY, true); } @@ -114,13 +106,16 @@ struct instance_eye_of_eternity : public InstanceScript InstanceScript::OnGameObjectCreate(gameobject); uint32 entry = gameobject->GetEntry(); - if ((entry == GO_IRIS_N || entry == GO_IRIS_H) && GetBossState(DATA_MALYGOS) == DONE) - gameobject->SetPhaseMask(2, true); - if (entry == GO_NEXUS_PLATFORM && GetBossState(DATA_MALYGOS) == DONE) + if (IsBossDone(DATA_MALYGOS)) { - gameobject->ModifyHealth(-int32(PLATFORM_DESTROY_DAMAGE)); - gameobject->EnableCollision(false); + if (entry == GO_IRIS_N || entry == GO_IRIS_H) + gameobject->SetPhaseMask(2, true); + else if (entry == GO_NEXUS_PLATFORM) + { + gameobject->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED, nullptr, true); + gameobject->EnableCollision(false); + } } } @@ -128,16 +123,6 @@ struct instance_eye_of_eternity : public InstanceScript { switch (type) { - case DATA_IRIS_ACTIVATED: - if (GetBossState(DATA_MALYGOS) == NOT_STARTED) - { - if (Creature* malygos = GetCreature(DATA_MALYGOS)) - { - if (Player* player = malygos->SelectNearestPlayer(250.0f)) - malygos->AI()->AttackStart(player); - } - } - break; case DATA_SET_IRIS_INACTIVE: { if (GameObject* iris = GetGameObject(DATA_IRIS)) @@ -204,15 +189,20 @@ struct instance_eye_of_eternity : public InstanceScript void ProcessEvent(WorldObject* /*unit*/, uint32 eventId) override { - if (eventId != EVENT_IRIS_ACTIVATED) - return; - - if (GameObject* platform = GetGameObject(DATA_NEXUS_PLATFORM)) + if (eventId == EVENT_IRIS_ACTIVATED) + { if (Creature* malygos = GetCreature(DATA_MALYGOS)) + if (Player* player = malygos->SelectNearestPlayer(250.0f)) + malygos->AI()->AttackStart(player); + } + else if (eventId == EVENT_DESTROY_PLATFORM) + { + if (GameObject* platform = GetGameObject(DATA_NEXUS_PLATFORM)) { - platform->ModifyHealth(-int32(PLATFORM_DESTROY_DAMAGE), malygos); + platform->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED, nullptr, true); platform->EnableCollision(false); } + } } bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* /*target*/, uint32 /*miscvalue1*/) override From cf92cfa59f7cdba21e3c2035b342aaafec85b4e9 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sun, 22 Feb 2026 14:55:29 +0100 Subject: [PATCH 205/335] fix(Core/CLI): Replace fgetws with ReadConsoleW for Windows console UTF-8 input (#24725) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- .../worldserver/CommandLine/CliRunnable.cpp | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/server/apps/worldserver/CommandLine/CliRunnable.cpp b/src/server/apps/worldserver/CommandLine/CliRunnable.cpp index 78b723a27..307bee1a5 100644 --- a/src/server/apps/worldserver/CommandLine/CliRunnable.cpp +++ b/src/server/apps/worldserver/CommandLine/CliRunnable.cpp @@ -25,7 +25,9 @@ #include "World.h" #include -#if AC_PLATFORM != AC_PLATFORM_WINDOWS +#if AC_PLATFORM == AC_PLATFORM_WINDOWS +#include +#else #include "Chat.h" #include "ChatCommand.h" #include @@ -108,6 +110,10 @@ int kb_hit_return() void CliThread() { #if AC_PLATFORM == AC_PLATFORM_WINDOWS + // Set console code pages to UTF-8 + SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); + // print this here the first time // later it will be printed after command queue updates PrintCliPrefix(); @@ -134,6 +140,14 @@ void CliThread() fInfo.dwTimeout = 0; FlashWindowEx(&fInfo); } + + // Get console input handle once for reading commands + HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); + if (hStdIn == INVALID_HANDLE_VALUE) + { + LOG_ERROR("server.worldserver", "Failed to get console input handle"); + return; + } #endif ///- As long as the World is running (no World::m_stopEvent), get the command line and handle it @@ -145,12 +159,18 @@ void CliThread() #if AC_PLATFORM == AC_PLATFORM_WINDOWS wchar_t commandbuf[256]; - if (fgetws(commandbuf, sizeof(commandbuf), stdin)) + DWORD charsRead = 0; + + if (ReadConsoleW(hStdIn, commandbuf, sizeof(commandbuf) / sizeof(wchar_t) - 1, &charsRead, nullptr)) { - if (!WStrToUtf8(commandbuf, wcslen(commandbuf), command)) + if (charsRead > 0) { - PrintCliPrefix(); - continue; + commandbuf[charsRead] = L'\0'; + if (!WStrToUtf8(commandbuf, charsRead, command)) + { + PrintCliPrefix(); + continue; + } } } #else From 7137295d6939403d8adef1045f025eae42cbbcb7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 22 Feb 2026 13:56:23 +0000 Subject: [PATCH 206/335] chore(DB): import pending files Referenced commit(s): 0759d4700094709d3af37102a5160c362de247ae --- .../rev_1771764309163193800.sql => db_world/2026_02_22_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771764309163193800.sql => db_world/2026_02_22_01.sql} (74%) diff --git a/data/sql/updates/pending_db_world/rev_1771764309163193800.sql b/data/sql/updates/db_world/2026_02_22_01.sql similarity index 74% rename from data/sql/updates/pending_db_world/rev_1771764309163193800.sql rename to data/sql/updates/db_world/2026_02_22_01.sql index 797a96634..00c2f0c2a 100644 --- a/data/sql/updates/pending_db_world/rev_1771764309163193800.sql +++ b/data/sql/updates/db_world/2026_02_22_01.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_22_00 -> 2026_02_22_01 -- UPDATE `gameobject_template` SET `ScriptName` = '' WHERE `entry` IN (193958, 193960) AND `ScriptName` = 'go_the_focusing_iris'; From f7ab757970227cf64fd56ea751f5350167474767 Mon Sep 17 00:00:00 2001 From: sogladev Date: Sun, 22 Feb 2026 15:00:03 +0100 Subject: [PATCH 207/335] chore(Scripts/Ulduar): boss_kologarn_pit_kill_bunny (#24636) Co-authored-by: Andrew <47818697+Nyeriah@users.noreply.github.com> --- .../Northrend/Ulduar/Ulduar/boss_kologarn.cpp | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp index 99e5c4de9..a1854f5a1 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp @@ -669,25 +669,29 @@ class spell_kologarn_focused_eyebeam : public SpellScript } }; +namespace pitKillBoundary { + static auto const boundaryIntersect = new BoundaryIntersectBoundary( + new RectangleBoundary(1782.0f, 1832.0f, -56.0f, 8.0f), + new ZRangeBoundary(400.0f, 439.0f) + ); +} + struct boss_kologarn_pit_kill_bunny : public NullCreatureAI { - boss_kologarn_pit_kill_bunny(Creature* creature) : NullCreatureAI(creature) { } + explicit boss_kologarn_pit_kill_bunny(Creature* creature) : NullCreatureAI(creature) { } void Reset() override { - RectangleBoundary* _boundaryXY = new RectangleBoundary(1782.0f, 1832.0f, -56.0f, 8.0f); - ZRangeBoundary* _boundaryZ = new ZRangeBoundary(400.0f, 439.0f); - _boundaryIntersect = new BoundaryIntersectBoundary(_boundaryXY, _boundaryZ); - - scheduler.Schedule(0s, [this](TaskContext context) + scheduler.CancelAll(); + scheduler.Schedule(0s, + [this](TaskContext context) { me->GetMap()->DoForAllPlayers([&](Player* player) { - if (_boundaryIntersect->IsWithinBoundary(player->GetPosition()) && !player->IsGameMaster()) - { + if (pitKillBoundary::boundaryIntersect->IsWithinBoundary(player->GetPosition()) && !player->IsGameMaster()) player->KillSelf(false); - } }); + context.Repeat(1s); }); } @@ -696,8 +700,6 @@ struct boss_kologarn_pit_kill_bunny : public NullCreatureAI { scheduler.Update(diff); } -private: - BoundaryIntersectBoundary const* _boundaryIntersect; }; // predicate function to select non main tank target From 7fadeb1141c48d552afd7c3bb40ef4b527272fa3 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 11:06:47 -0600 Subject: [PATCH 208/335] fix(Core/Spells): Beacon of Light no longer copies target healing modifiers (#24796) Co-authored-by: blinkysc --- src/server/game/Entities/Unit/Unit.h | 9 ++++++++- src/server/game/Spells/Spell.cpp | 15 +++++++++++++++ src/server/game/Spells/Spell.h | 2 ++ src/server/game/Spells/SpellEffects.cpp | 4 ++++ src/server/scripts/Spells/spell_paladin.cpp | 5 ++++- 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 96e99ab98..6be903f8b 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -386,6 +386,7 @@ private: Unit* const m_healer; Unit* const m_target; uint32 m_heal; + uint32 m_healBeforeTakenMods; uint32 m_effectiveHeal; uint32 m_absorb; SpellInfo const* const m_spellInfo; @@ -393,7 +394,7 @@ private: uint32 m_hitMask; public: explicit HealInfo(Unit* _healer, Unit* _target, uint32 _heal, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask) - : m_healer(_healer), m_target(_target), m_heal(_heal), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask), m_hitMask(0) + : m_healer(_healer), m_target(_target), m_heal(_heal), m_healBeforeTakenMods(0), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask), m_hitMask(0) { m_absorb = 0; m_effectiveHeal = 0; @@ -414,6 +415,11 @@ public: m_heal = amount; } + void SetHealBeforeTakenMods(uint32 amount) + { + m_healBeforeTakenMods = amount; + } + void SetEffectiveHeal(uint32 amount) { m_effectiveHeal = amount; @@ -422,6 +428,7 @@ public: [[nodiscard]] Unit* GetHealer() const { return m_healer; } [[nodiscard]] Unit* GetTarget() const { return m_target; } [[nodiscard]] uint32 GetHeal() const { return m_heal; } + [[nodiscard]] uint32 GetHealBeforeTakenMods() const { return m_healBeforeTakenMods; } [[nodiscard]] uint32 GetEffectiveHeal() const { return m_effectiveHeal; } [[nodiscard]] uint32 GetAbsorb() const { return m_absorb; } [[nodiscard]] SpellInfo const* GetSpellInfo() const { return m_spellInfo; }; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index e8fe0a346..fb9b33958 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -649,6 +649,7 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, m_diminishGroup = DIMINISHING_NONE; m_damage = 0; m_healing = 0; + m_damageBeforeTakenMods = 0; m_procAttacker = 0; m_procVictim = 0; m_procEx = 0; @@ -2337,6 +2338,7 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= targetInfo.processed = false; // Effects not apply on target targetInfo.alive = target->IsAlive(); targetInfo.damage = 0; + targetInfo.damageBeforeTakenMods = 0; targetInfo.crit = false; targetInfo.scaleAura = false; if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target) @@ -2712,6 +2714,17 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask()); + // Heal amount before SpellHealingBonusTaken, used by Beacon of Light + if (target->damageBeforeTakenMods != 0) + { + uint32 healBeforeTakenMods = uint32(-target->damageBeforeTakenMods); + if (crit) + healBeforeTakenMods = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, healBeforeTakenMods, nullptr); + healInfo.SetHealBeforeTakenMods(healBeforeTakenMods); + } + else + healInfo.SetHealBeforeTakenMods(addhealth); + // Set hitMask based on crit if (crit) healInfo.AddHitMask(PROC_HIT_CRITICAL); @@ -8297,6 +8310,7 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier) { m_damage = 0; m_healing = 0; + m_damageBeforeTakenMods = 0; HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET); @@ -8322,6 +8336,7 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier) m_damageMultipliers[i] *= multiplier[i]; } targetInfo.damage += m_damage; + targetInfo.damageBeforeTakenMods += m_damageBeforeTakenMods; } } diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index ea9fe3630..cb3f89540 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -273,6 +273,7 @@ struct TargetInfo bool crit:1; bool scaleAura:1; int32 damage; + int32 damageBeforeTakenMods; }; static const uint32 SPELL_INTERRUPT_NONPLAYER = 32747; @@ -683,6 +684,7 @@ public: // Damage and healing in effects need just calculate int32 m_damage; // Damge in effects count here int32 m_healing; // Healing in effects count here + int32 m_damageBeforeTakenMods; // ****************************************** // Spell trigger system diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 5aff04864..730dc9859 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1557,11 +1557,13 @@ void Spell::EffectHeal(SpellEffIndex effIndex) else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000) { addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex); + m_damageBeforeTakenMods -= addhealth; addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL); } else if (m_spellInfo->Id != 33778) // not lifebloom { addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex); + m_damageBeforeTakenMods -= addhealth; addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL); } @@ -1593,6 +1595,7 @@ void Spell::EffectHealPct(SpellEffIndex effIndex) return; uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL, effIndex); + m_damageBeforeTakenMods -= heal; heal = unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL); m_damage -= heal; @@ -1611,6 +1614,7 @@ void Spell::EffectHealMechanical(SpellEffIndex effIndex) return; uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, uint32(damage), HEAL, effIndex); + m_damageBeforeTakenMods -= heal; m_damage -= unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 163899a46..0e5f3b48a 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -2148,7 +2148,10 @@ class spell_pal_light_s_beacon : public AuraScript // Holy Light heals for 100%, Flash of Light heals for 50% uint32 healSpellId = procSpell->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_PALADIN_HOLY_LIGHT_R1)) ? SPELL_PALADIN_BEACON_OF_LIGHT_FLASH : SPELL_PALADIN_BEACON_OF_LIGHT_HOLY; - int32 heal = CalculatePct(healInfo->GetHeal(), aurEff->GetAmount()); + + // Use heal amount before target-specific modifiers to avoid copying them + uint32 healAmount = healInfo->GetHealBeforeTakenMods(); + int32 heal = CalculatePct(healAmount, aurEff->GetAmount()); Unit* beaconTarget = GetCaster(); if (!beaconTarget || !beaconTarget->HasAura(SPELL_PALADIN_BEACON_OF_LIGHT_AURA, eventInfo.GetActor()->GetGUID())) From ff990a42abbbf54def4d6a8fbce29a4b2d63cef6 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 11:07:18 -0600 Subject: [PATCH 209/335] fix(Core/Spells): Implement Honor Among Thieves spell scripts (#24799) Co-authored-by: blinkysc Co-authored-by: ccrs --- .../pending_db_world/rev_1771742446580585.sql | 7 ++ .../game/Spells/SpellInfoCorrections.cpp | 12 +-- src/server/scripts/Spells/spell_rogue.cpp | 87 ++++++++++++++++++- 3 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771742446580585.sql diff --git a/data/sql/updates/pending_db_world/rev_1771742446580585.sql b/data/sql/updates/pending_db_world/rev_1771742446580585.sql new file mode 100644 index 000000000..8824f4494 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771742446580585.sql @@ -0,0 +1,7 @@ +-- Honor Among Thieves spell script registration +DELETE FROM `spell_script_names` WHERE `spell_id` IN (51698, 51700, 51701, 52916); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(51698, 'spell_rog_honor_among_thieves'), +(51700, 'spell_rog_honor_among_thieves'), +(51701, 'spell_rog_honor_among_thieves'), +(52916, 'spell_rog_honor_among_thieves_proc'); diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index 86bd0acc6..dc5218fba 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -713,12 +713,6 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_SCRIPT_EFFECT; }); - // Honor Among Thieves - ApplySpellFix({ 51698, 51700, 51701 }, [](SpellInfo* spellInfo) - { - spellInfo->Effects[EFFECT_0].TriggerSpell = 51699; - }); - ApplySpellFix({ 5171, // Slice and Dice 6774 // Slice and Dice @@ -4388,6 +4382,12 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->AttributesEx4 |= SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND; }); + // Honor Among Thieves - allow area aura from different casters to coexist + ApplySpellFix({ 51698, 51700, 51701 }, [](SpellInfo* spellInfo) + { + spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE; + }); + // Absorb Life ApplySpellFix({ 34239 }, [](SpellInfo* spellInfo) { diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 925bd78c4..72aeb1270 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -51,7 +51,9 @@ enum RogueSpells SPELL_ROGUE_TURN_THE_TABLES_R1 = 52910, SPELL_ROGUE_TURN_THE_TABLES_R2 = 52914, SPELL_ROGUE_TURN_THE_TABLES_R3 = 52915, - SPELL_ROGUE_OVERKILL_TRIGGERED = 58427 + SPELL_ROGUE_OVERKILL_TRIGGERED = 58427, + SPELL_ROGUE_HONOR_AMONG_THIEVES_PROC = 52916, + SPELL_ROGUE_HONOR_AMONG_THIEVES_TRIGGERED = 51699 }; enum RogueSpellIcons @@ -932,6 +934,87 @@ class spell_rog_setup : public AuraScript } }; +// 51698, 51700, 51701 - Honor Among Thieves +class spell_rog_honor_among_thieves : public AuraScript +{ + PrepareAuraScript(spell_rog_honor_among_thieves); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ROGUE_HONOR_AMONG_THIEVES_TRIGGERED }); + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + Unit* caster = GetCaster(); + if (!caster || caster->HasAura(SPELL_ROGUE_HONOR_AMONG_THIEVES_TRIGGERED)) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + Unit* caster = GetCaster(); + if (!caster) + return; + + Unit* target = GetTarget(); + target->CastSpell(target, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, nullptr, aurEff, caster->GetGUID()); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_rog_honor_among_thieves::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_rog_honor_among_thieves::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 52916 - Honor Among Thieves (Proc) +class spell_rog_honor_among_thieves_proc : public SpellScript +{ + PrepareSpellScript(spell_rog_honor_among_thieves_proc); + + void FilterTargets(std::list& targets) + { + targets.clear(); + + Unit* target = GetOriginalCaster(); + if (!target) + return; + + targets.push_back(target); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rog_honor_among_thieves_proc::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY); + } +}; + +// 52916 - Honor Among Thieves (Proc Aura) +class spell_rog_honor_among_thieves_proc_aura : public AuraScript +{ + PrepareAuraScript(spell_rog_honor_among_thieves_proc_aura); + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetCaster(); + if (!caster) + return; + + if (Player* player = caster->ToPlayer()) + player->CastSpell(static_cast(nullptr), SPELL_ROGUE_HONOR_AMONG_THIEVES_TRIGGERED, true); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_rog_honor_among_thieves_proc_aura::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } +}; + // -51627 - Turn the Tables class spell_rog_turn_the_tables : public AuraScript { @@ -996,6 +1079,8 @@ void AddSC_rogue_spell_scripts() RegisterSpellScript(spell_rog_deadly_brew); RegisterSpellScript(spell_rog_quick_recovery); RegisterSpellScript(spell_rog_setup); + RegisterSpellScript(spell_rog_honor_among_thieves); + RegisterSpellAndAuraScriptPair(spell_rog_honor_among_thieves_proc, spell_rog_honor_among_thieves_proc_aura); RegisterSpellScript(spell_rog_turn_the_tables); RegisterSpellScript(spell_rog_turn_the_tables_proc); } From e281f10b5b41e18605d79e7bd5abca584af2def3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 22 Feb 2026 17:23:17 +0000 Subject: [PATCH 210/335] chore(DB): import pending files Referenced commit(s): 7fadeb1141c48d552afd7c3bb40ef4b527272fa3 --- .../rev_1771742446580585.sql => db_world/2026_02_22_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771742446580585.sql => db_world/2026_02_22_02.sql} (89%) diff --git a/data/sql/updates/pending_db_world/rev_1771742446580585.sql b/data/sql/updates/db_world/2026_02_22_02.sql similarity index 89% rename from data/sql/updates/pending_db_world/rev_1771742446580585.sql rename to data/sql/updates/db_world/2026_02_22_02.sql index 8824f4494..46dad52e1 100644 --- a/data/sql/updates/pending_db_world/rev_1771742446580585.sql +++ b/data/sql/updates/db_world/2026_02_22_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_22_01 -> 2026_02_22_02 -- Honor Among Thieves spell script registration DELETE FROM `spell_script_names` WHERE `spell_id` IN (51698, 51700, 51701, 52916); INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES From 2990f13840ca935359c1812ec7bfe44b6aac223d Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 11:27:54 -0600 Subject: [PATCH 211/335] fix(Core/Spells): Prevent extra attack abilities from chain-proccing (#24806) Co-authored-by: blinkysc Co-authored-by: trickerer --- .../game/Spells/Auras/SpellAuraEffects.cpp | 23 +++ src/test/mocks/ProcChanceTestHelper.h | 39 +++++ .../game/Spells/ExtraAttackChainProcTest.cpp | 149 ++++++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 src/test/server/game/Spells/ExtraAttackChainProcTest.cpp diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index ef713a32d..775aab3d5 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1239,6 +1239,29 @@ bool AuraEffect::CheckEffectProc(AuraApplication* aurApp, ProcEventInfo& eventIn if (GetCasterGUID() != eventInfo.GetActor()->GetGUID()) return false; break; + case SPELL_AURA_PROC_TRIGGER_SPELL: + case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE: + { + // Don't proc extra attacks while already processing extra attack spell + uint32 triggerSpellId = m_spellInfo->Effects[GetEffIndex()].TriggerSpell; + if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId)) + { + if (triggeredSpellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) + { + uint32 lastExtraAttackSpell = eventInfo.GetActor()->GetLastExtraAttackSpell(); + + // Patch 1.12.0(?) extra attack abilities can no longer chain proc themselves + if (lastExtraAttackSpell == triggerSpellId) + return false; + + // Patch 2.2.0 Sword Specialization (Warrior, Rogue) extra attack can no longer proc additional extra attacks + // 3.3.5 Sword Specialization (Warrior), Hack and Slash (Rogue) + if (lastExtraAttackSpell == SPELL_SWORD_SPECIALIZATION || lastExtraAttackSpell == SPELL_HACK_AND_SLASH) + return false; + } + } + break; + } default: break; } diff --git a/src/test/mocks/ProcChanceTestHelper.h b/src/test/mocks/ProcChanceTestHelper.h index 32a3dac98..41e0dfa38 100644 --- a/src/test/mocks/ProcChanceTestHelper.h +++ b/src/test/mocks/ProcChanceTestHelper.h @@ -282,6 +282,45 @@ public: return false; // Allow proc } + // ============================================================================= + // Extra Attack Chain-Proc Prevention - simulates SpellAuraEffects.cpp:1245-1261 + // ============================================================================= + + /** + * @brief Configuration for simulating extra attack chain-proc prevention + */ + struct ExtraAttackProcConfig + { + bool triggeredSpellHasExtraAttacks = false; // triggeredSpellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS) + uint32 triggerSpellId = 0; // m_spellInfo->Effects[GetEffIndex()].TriggerSpell + uint32 lastExtraAttackSpell = 0; // eventInfo.GetActor()->GetLastExtraAttackSpell() + }; + + /** + * @brief Simulate extra attack chain-proc prevention from CheckEffectProc + * Returns true if proc should be blocked + * + * @param config Extra attack proc configuration + * @return true if proc should be blocked + */ + static bool ShouldBlockExtraAttackChainProc(ExtraAttackProcConfig const& config) + { + // Only applies when the triggered spell grants extra attacks + if (!config.triggeredSpellHasExtraAttacks) + return false; + + // Patch 1.12.0(?) extra attack abilities can no longer chain proc themselves + if (config.lastExtraAttackSpell == config.triggerSpellId) + return true; + + // Patch 2.2.0 Sword Specialization (Warrior, Rogue) extra attack can no longer proc additional extra attacks + // 3.3.5 Sword Specialization (Warrior), Hack and Slash (Rogue) + if (config.lastExtraAttackSpell == 16459 || config.lastExtraAttackSpell == 66923) + return true; + + return false; + } + // ============================================================================= // DisableEffectsMask - simulates SpellAuras.cpp:2244-2258 // ============================================================================= diff --git a/src/test/server/game/Spells/ExtraAttackChainProcTest.cpp b/src/test/server/game/Spells/ExtraAttackChainProcTest.cpp new file mode 100644 index 000000000..50e33768f --- /dev/null +++ b/src/test/server/game/Spells/ExtraAttackChainProcTest.cpp @@ -0,0 +1,149 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * @file ExtraAttackChainProcTest.cpp + * @brief Unit tests for extra attack chain-proc prevention + * + * Tests the logic from SpellAuraEffects.cpp:1245-1261 (CheckEffectProc): + * - Self-chain prevention (same extra attack spell can't proc itself) + * - Cross-chain prevention (Sword Specialization / Hack and Slash block all extra attack procs) + * - Non-blacklisted extra attack spells allow cross-proccing + * - Non-extra-attack procs are unaffected by the guard + */ + +#include "ProcChanceTestHelper.h" +#include "gtest/gtest.h" + +using namespace testing; + +// Use existing enum from Unit.h: SPELL_SWORD_SPECIALIZATIONIALIZATION (16459), SPELL_HACK_AND_SLASH (66923) +constexpr uint32 SPELL_RECKONING = 32746; // Reckoning (Paladin) +constexpr uint32 SPELL_HAND_OF_JUSTICE = 15601; // Hand of Justice extra attack + +class ExtraAttackChainProcTest : public ::testing::Test +{ +protected: + ProcChanceTestHelper::ExtraAttackProcConfig MakeConfig( + bool hasExtraAttacks, uint32 triggerSpellId, uint32 lastExtraAttack) + { + ProcChanceTestHelper::ExtraAttackProcConfig config; + config.triggeredSpellHasExtraAttacks = hasExtraAttacks; + config.triggerSpellId = triggerSpellId; + config.lastExtraAttackSpell = lastExtraAttack; + return config; + } +}; + +// ============================================================================= +// Normal proc (no extra attack in progress) +// ============================================================================= + +TEST_F(ExtraAttackChainProcTest, NormalProc_AllowedWhenNoExtraAttackInProgress) +{ + // lastExtraAttackSpell == 0 means no extra attack is executing + auto config = MakeConfig(true, SPELL_SWORD_SPECIALIZATION, 0); + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockExtraAttackChainProc(config)) + << "Extra attack proc should be allowed when no extra attack is in progress"; +} + +// ============================================================================= +// Self-chain prevention +// ============================================================================= + +TEST_F(ExtraAttackChainProcTest, SelfChain_BlockedWhenSameSpell) +{ + // Sword Spec trying to proc during its own extra attack + auto config = MakeConfig(true, SPELL_SWORD_SPECIALIZATION, SPELL_SWORD_SPECIALIZATION); + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockExtraAttackChainProc(config)) + << "Extra attack spell should not chain-proc itself"; +} + +// ============================================================================= +// Cross-chain prevention (blacklisted spells) +// ============================================================================= + +TEST_F(ExtraAttackChainProcTest, CrossChain_BlockedBySwordSpecialization) +{ + // Reckoning trying to proc during Sword Spec extra attack + auto config = MakeConfig(true, SPELL_RECKONING, SPELL_SWORD_SPECIALIZATION); + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockExtraAttackChainProc(config)) + << "Sword Specialization extra attack should block all other extra attack procs"; +} + +TEST_F(ExtraAttackChainProcTest, CrossChain_BlockedByHackAndSlash) +{ + // Reckoning trying to proc during Hack and Slash extra attack + auto config = MakeConfig(true, SPELL_RECKONING, SPELL_HACK_AND_SLASH); + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockExtraAttackChainProc(config)) + << "Hack and Slash extra attack should block all other extra attack procs"; +} + +// ============================================================================= +// Non-blacklisted extra attacks allow cross-proccing +// ============================================================================= + +TEST_F(ExtraAttackChainProcTest, DifferentExtraAttack_AllowedWhenNotBlacklisted) +{ + // Sword Spec trying to proc during Hand of Justice extra attack + // Hand of Justice (15601) is not blacklisted, so cross-proc is allowed + auto config = MakeConfig(true, SPELL_SWORD_SPECIALIZATION, SPELL_HAND_OF_JUSTICE); + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockExtraAttackChainProc(config)) + << "Non-blacklisted extra attack spells should allow cross-proccing"; +} + +// ============================================================================= +// Non-extra-attack procs unaffected +// ============================================================================= + +TEST_F(ExtraAttackChainProcTest, NonExtraAttackProc_UnaffectedByExtraAttackState) +{ + // A proc that does NOT grant extra attacks should never be blocked, + // even during Sword Spec extra attack + auto config = MakeConfig(false, 12345, SPELL_SWORD_SPECIALIZATION); + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockExtraAttackChainProc(config)) + << "Non-extra-attack procs should be unaffected by extra attack state"; +} + +// ============================================================================= +// Real spell scenarios +// ============================================================================= + +TEST_F(ExtraAttackChainProcTest, Reckoning_SelfChainBlocked) +{ + // Reckoning (32746) trying to proc during its own extra attack + auto config = MakeConfig(true, SPELL_RECKONING, SPELL_RECKONING); + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockExtraAttackChainProc(config)) + << "Reckoning should not chain-proc itself"; +} + +TEST_F(ExtraAttackChainProcTest, Reckoning_AllowedDuringHandOfJustice) +{ + // Reckoning trying to proc during Hand of Justice extra attack + // Hand of Justice is not blacklisted, so Reckoning is allowed + auto config = MakeConfig(true, SPELL_RECKONING, SPELL_HAND_OF_JUSTICE); + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockExtraAttackChainProc(config)) + << "Reckoning should be allowed during Hand of Justice extra attack"; +} From fe0222cbdd108ced056ead5992b109702f3a5cdc Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sun, 22 Feb 2026 14:30:50 -0300 Subject: [PATCH 212/335] fix(DB/Loot): Tweak some Loot Conditions for profession drops (#24809) --- .../pending_db_world/rev_1771781260483912800.sql | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771781260483912800.sql diff --git a/data/sql/updates/pending_db_world/rev_1771781260483912800.sql b/data/sql/updates/pending_db_world/rev_1771781260483912800.sql new file mode 100644 index 000000000..f3625f7d9 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771781260483912800.sql @@ -0,0 +1,16 @@ +-- +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 10 AND `SourceGroup` IN (1267174, 1266870, 1267579, 1268083) AND `SourceEntry` = 43876 AND `ConditionTypeOrReference` = 7 AND `ConditionValue1` = 197; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(10, 1266870, 43876, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring Skill to loot A Guide to Northern Cloth Scavenging'), +(10, 1267174, 43876, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring Skill to loot A Guide to Northern Cloth Scavenging'), +(10, 1267579, 43876, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring Skill to loot A Guide to Northern Cloth Scavenging'), +(10, 1268083, 43876, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring Skill to loot A Guide to Northern Cloth Scavenging'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 10 AND `SourceGroup` IN (1260002) AND `SourceEntry` IN (42172,42173,42175,42176,42177,42178) AND `ConditionTypeOrReference` = 1 AND `ConditionValue1` IN (55993,55994,55996,55998,55997,55999); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(10, 1260002, 42172, 0, 0, 1, 0, 55993, 0, 0, 1, 0, 0, '', 'Player must not know this Tailoring pattern already'), +(10, 1260002, 42173, 0, 0, 1, 0, 55994, 0, 0, 1, 0, 0, '', 'Player must not know this Tailoring pattern already'), +(10, 1260002, 42175, 0, 0, 1, 0, 55996, 0, 0, 1, 0, 0, '', 'Player must not know this Tailoring pattern already'), +(10, 1260002, 42176, 0, 0, 1, 0, 55998, 0, 0, 1, 0, 0, '', 'Player must not know this Tailoring pattern already'), +(10, 1260002, 42177, 0, 0, 1, 0, 55997, 0, 0, 1, 0, 0, '', 'Player must not know this Tailoring pattern already'), +(10, 1260002, 42178, 0, 0, 1, 0, 55999, 0, 0, 1, 0, 0, '', 'Player must not know this Tailoring pattern already'); From c2e595abb9d181eff13a10e3800f0f0748cdcc22 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sun, 22 Feb 2026 15:10:43 -0300 Subject: [PATCH 213/335] fix(DB): Tweak some Loot Conditions for profession drops II (#24810) --- data/sql/updates/pending_db_world/rev_1771782375896428400.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771782375896428400.sql diff --git a/data/sql/updates/pending_db_world/rev_1771782375896428400.sql b/data/sql/updates/pending_db_world/rev_1771782375896428400.sql new file mode 100644 index 000000000..a30ea5de5 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771782375896428400.sql @@ -0,0 +1,2 @@ +-- +UPDATE `conditions` SET `ConditionTypeOrReference` = 25 WHERE `SourceTypeOrReferenceId` = 10 AND `SourceGroup` IN (1260002) AND `SourceEntry` IN (42172,42173,42175,42176,42177,42178) AND `ConditionTypeOrReference` = 1 AND `ConditionValue1` IN (55993,55994,55996,55998,55997,55999); From 7b5f56f76297d1b54fda42457a08b7f22e990c13 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 22 Feb 2026 18:14:03 +0000 Subject: [PATCH 214/335] chore(DB): import pending files Referenced commit(s): ff990a42abbbf54def4d6a8fbce29a4b2d63cef6 --- .../rev_1771781260483912800.sql => db_world/2026_02_22_03.sql} | 1 + .../rev_1771782375896428400.sql => db_world/2026_02_22_04.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1771781260483912800.sql => db_world/2026_02_22_03.sql} (98%) rename data/sql/updates/{pending_db_world/rev_1771782375896428400.sql => db_world/2026_02_22_04.sql} (86%) diff --git a/data/sql/updates/pending_db_world/rev_1771781260483912800.sql b/data/sql/updates/db_world/2026_02_22_03.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1771781260483912800.sql rename to data/sql/updates/db_world/2026_02_22_03.sql index f3625f7d9..9308306e9 100644 --- a/data/sql/updates/pending_db_world/rev_1771781260483912800.sql +++ b/data/sql/updates/db_world/2026_02_22_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_22_02 -> 2026_02_22_03 -- DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 10 AND `SourceGroup` IN (1267174, 1266870, 1267579, 1268083) AND `SourceEntry` = 43876 AND `ConditionTypeOrReference` = 7 AND `ConditionValue1` = 197; INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES diff --git a/data/sql/updates/pending_db_world/rev_1771782375896428400.sql b/data/sql/updates/db_world/2026_02_22_04.sql similarity index 86% rename from data/sql/updates/pending_db_world/rev_1771782375896428400.sql rename to data/sql/updates/db_world/2026_02_22_04.sql index a30ea5de5..67f5705a4 100644 --- a/data/sql/updates/pending_db_world/rev_1771782375896428400.sql +++ b/data/sql/updates/db_world/2026_02_22_04.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_22_03 -> 2026_02_22_04 -- UPDATE `conditions` SET `ConditionTypeOrReference` = 25 WHERE `SourceTypeOrReferenceId` = 10 AND `SourceGroup` IN (1260002) AND `SourceEntry` IN (42172,42173,42175,42176,42177,42178) AND `ConditionTypeOrReference` = 1 AND `ConditionValue1` IN (55993,55994,55996,55998,55997,55999); From 3931993109a61e5c2d79897b7fedcc201f496d99 Mon Sep 17 00:00:00 2001 From: trauntrow <84481188+trauntrow@users.noreply.github.com> Date: Sun, 22 Feb 2026 13:30:35 -0500 Subject: [PATCH 215/335] fix(DB/SAI): Homing Robot OOX-17/TN fix waypoints and aura (#24769) --- .../rev_1771548049716998200.sql | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771548049716998200.sql diff --git a/data/sql/updates/pending_db_world/rev_1771548049716998200.sql b/data/sql/updates/pending_db_world/rev_1771548049716998200.sql new file mode 100644 index 000000000..987817229 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771548049716998200.sql @@ -0,0 +1,37 @@ +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 7784; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 7784) AND (`source_type` = 0) AND (`id` IN (7)); +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 +(7784, 0, 7, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 28, 68499, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Homing Robot OOX-17/TN - On Respawn - Remove Aura \'OOX Lift Off\''); + +-- Update waypoints with sniffed data +DELETE FROM `waypoints` WHERE `entry` = 7784; +INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `orientation`, `point_comment`) VALUES +(7784, 1, -8832.505, -4374.4556, 45.228176, NULL, 'Homing Robot OOX-17/TN'), +(7784, 2, -8810.634, -4373.8345, 32.52725, NULL, 'Homing Robot OOX-17/TN'), +(7784, 3, -8794.969, -4366.311, 25.909113, NULL, 'Homing Robot OOX-17/TN'), +(7784, 4, -8752.488, -4366.4326, 24.156054, NULL, 'Homing Robot OOX-17/TN'), +(7784, 5, -8724.97, -4352.2266, 20.758305, NULL, 'Homing Robot OOX-17/TN'), +(7784, 6, -8708.822, -4353.277, 18.39893, NULL, 'Homing Robot OOX-17/TN'), +(7784, 7, -8684.997, -4379.1943, 13.580014, NULL, 'Homing Robot OOX-17/TN'), +(7784, 8, -8656.829, -4388.013, 12.268159, NULL, 'Homing Robot OOX-17/TN'), +(7784, 9, -8612.755, -4397.2524, 9.681026, NULL, 'Homing Robot OOX-17/TN'), +(7784, 10, -8578.566, -4408.652, 11.647685, NULL, 'Homing Robot OOX-17/TN'), +(7784, 11, -8539.096, -4421.452, 12.621063, NULL, 'Homing Robot OOX-17/TN'), +(7784, 12, -8514.029, -4425.8203, 13.824177, NULL, 'Homing Robot OOX-17/TN'), +(7784, 13, -8486.308, -4428.784, 11.725893, NULL, 'Homing Robot OOX-17/TN'), +(7784, 14, -8446.95, -4440.7183, 9.385215, NULL, 'Homing Robot OOX-17/TN'), +(7784, 15, -8417.598, -4445.191, 10.350303, NULL, 'Homing Robot OOX-17/TN'), +(7784, 16, -8388.8955, -4448.0015, 10.9764805, NULL, 'Homing Robot OOX-17/TN'), +(7784, 17, -8352.005, -4447.594, 10.134734, NULL, 'Homing Robot OOX-17/TN'), +(7784, 18, -8352.005, -4447.594, 10.134734, 0.0104949, 'Homing Robot OOX-17/TN'), +-- Fly waypoints to give lift off time to play +(7784, 19, -8327.56, -4442.5103, 18.585197, NULL, 'Homing Robot OOX-17/TN'), +(7784, 20, -8262.676, -4426.0054, 34.8352, NULL, 'Homing Robot OOX-17/TN'), +(7784, 21, -8161.7275, -4410.5435, 58.08519, NULL, 'Homing Robot OOX-17/TN'); + +-- Update SmartAI waypoint references to match sniffed data +-- ID 3: Ambush/pause trigger on WP18 (pause point with orientation) +-- ID 5: Despawn on WP21 (final fly waypoint) +UPDATE `smart_scripts` SET `event_param1` = 18 WHERE `entryorguid` = 7784 AND `source_type` = 0 AND `id` = 3; +UPDATE `smart_scripts` SET `event_param1` = 21 WHERE `entryorguid` = 7784 AND `source_type` = 0 AND `id` = 5; From 98cf3cb0072cf3bcde0bb1f7b688d083397924f3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 22 Feb 2026 18:31:56 +0000 Subject: [PATCH 216/335] chore(DB): import pending files Referenced commit(s): 2990f13840ca935359c1812ec7bfe44b6aac223d --- .../rev_1771548049716998200.sql => db_world/2026_02_22_05.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771548049716998200.sql => db_world/2026_02_22_05.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1771548049716998200.sql b/data/sql/updates/db_world/2026_02_22_05.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1771548049716998200.sql rename to data/sql/updates/db_world/2026_02_22_05.sql index 987817229..985aa3460 100644 --- a/data/sql/updates/pending_db_world/rev_1771548049716998200.sql +++ b/data/sql/updates/db_world/2026_02_22_05.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_22_04 -> 2026_02_22_05 UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 7784; DELETE FROM `smart_scripts` WHERE (`entryorguid` = 7784) AND (`source_type` = 0) AND (`id` IN (7)); From 96df2b3678419eaef82d16147aab63f4d4d0c6e0 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 12:32:41 -0600 Subject: [PATCH 217/335] fix(Core/Spells): Fix Lock and Load procs (#24795) Co-authored-by: blinkysc --- .../pending_db_world/rev_1740153600000000000.sql | 3 +++ src/server/game/Spells/Spell.cpp | 6 ++++++ src/server/game/Spells/Spell.h | 3 +++ src/server/scripts/Spells/spell_hunter.cpp | 11 ++++++++++- 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 data/sql/updates/pending_db_world/rev_1740153600000000000.sql diff --git a/data/sql/updates/pending_db_world/rev_1740153600000000000.sql b/data/sql/updates/pending_db_world/rev_1740153600000000000.sql new file mode 100644 index 000000000..54c12d40a --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1740153600000000000.sql @@ -0,0 +1,3 @@ +-- Lock and Load: allow periodic tick procs (Black Arrow, Explosive Trap) +-- SpellPhaseMask 6 = PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH +UPDATE `spell_proc` SET `SpellPhaseMask` = 6 WHERE `SpellId` = -56342; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index fb9b33958..9a1c2dc5e 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -719,6 +719,7 @@ Spell::~Spell() void Spell::InitExplicitTargets(SpellCastTargets const& targets) { m_targets = targets; + m_originalTargetGUID = targets.GetObjectTargetGUID(); // this function tries to correct spell explicit targets for spell // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside // this also makes sure that we correctly send explicit targets to client (removes redundant data) @@ -7855,6 +7856,11 @@ void Spell::DelayedChannel() SendChannelUpdate(m_timer); } +Unit* Spell::GetOriginalTarget() const +{ + return ObjectAccessor::GetUnit(*m_caster, m_originalTargetGUID); +} + bool Spell::UpdatePointers() { if (m_originalCasterGUID == m_caster->GetGUID()) diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index cb3f89540..a23d3b43c 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -585,6 +585,7 @@ public: Unit* GetCaster() const { return m_caster; } Unit* GetOriginalCaster() const { return m_originalCaster; } + Unit* GetOriginalTarget() const; SpellInfo const* GetSpellInfo() const { return m_spellInfo; } int32 GetPowerCost() const { return m_powerCost; } @@ -621,6 +622,8 @@ public: // e.g. damage around area spell trigered by victim aura and damage enemies of aura caster Unit* m_originalCaster; // cached pointer for m_originalCaster, updated at Spell::UpdatePointers() + ObjectGuid m_originalTargetGUID; // unit target saved before InitExplicitTargets strips it + Spell** m_selfContainer; // pointer to our spell container (if applicable) std::string GetDebugInfo() const; diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 860415bcf..74ffa2b77 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -67,6 +67,7 @@ enum HunterSpells SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT = 61389, SPELL_LOCK_AND_LOAD_TRIGGER = 56453, SPELL_LOCK_AND_LOAD_MARKER = 67544, + SPELL_FROST_TRAP_SLOW = 67035, SPELL_HUNTER_PET_LEGGINGS_OF_BEAST_MASTERY = 38297, // Leggings of Beast Mastery // Proc system spells @@ -1177,7 +1178,8 @@ class spell_hun_lock_and_load : public AuraScript return ValidateSpellInfo( { SPELL_LOCK_AND_LOAD_TRIGGER, - SPELL_LOCK_AND_LOAD_MARKER + SPELL_LOCK_AND_LOAD_MARKER, + SPELL_FROST_TRAP_SLOW }); } @@ -1197,6 +1199,13 @@ class spell_hun_lock_and_load : public AuraScript if (!spellInfo || !(spellInfo->GetSchoolMask() & (SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_FIRE))) return false; + // TODO: Research whether Lock and Load should proc on targets + // immune to Frost Trap slow (bosses) in WotLK 3.3.5a. + // if (Spell const* procSpell = eventInfo.GetProcSpell()) + // if (Unit* target = procSpell->GetOriginalTarget()) + // if (target->IsImmunedToSpell(sSpellMgr->GetSpellInfo(SPELL_FROST_TRAP_SLOW))) + // return false; + return roll_chance_i(aurEff->GetAmount()); } From f432f4f9746e9905950a6cbc2919d7992bae5a06 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 22 Feb 2026 18:53:00 +0000 Subject: [PATCH 218/335] chore(DB): import pending files Referenced commit(s): fe0222cbdd108ced056ead5992b109702f3a5cdc --- .../rev_1740153600000000000.sql => db_world/2026_02_22_06.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1740153600000000000.sql => db_world/2026_02_22_06.sql} (82%) diff --git a/data/sql/updates/pending_db_world/rev_1740153600000000000.sql b/data/sql/updates/db_world/2026_02_22_06.sql similarity index 82% rename from data/sql/updates/pending_db_world/rev_1740153600000000000.sql rename to data/sql/updates/db_world/2026_02_22_06.sql index 54c12d40a..a648d9938 100644 --- a/data/sql/updates/pending_db_world/rev_1740153600000000000.sql +++ b/data/sql/updates/db_world/2026_02_22_06.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_22_05 -> 2026_02_22_06 -- Lock and Load: allow periodic tick procs (Black Arrow, Explosive Trap) -- SpellPhaseMask 6 = PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH UPDATE `spell_proc` SET `SpellPhaseMask` = 6 WHERE `SpellId` = -56342; From 2bd4e4daeec225ce0895662628486e091369675f Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 13:10:51 -0600 Subject: [PATCH 219/335] fix(Core/Spells): Do not set proc SpellFamilyName without SpellFamilyMask (#24807) Co-authored-by: ariel- --- src/server/game/Spells/SpellMgr.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 4374d9d77..5751e7fec 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2040,7 +2040,6 @@ void SpellMgr::LoadSpellProcs() // Generate default proc entry from DBC data SpellProcEntry procEntry; procEntry.SchoolMask = 0; - procEntry.SpellFamilyName = spellInfo->SpellFamilyName; procEntry.SpellFamilyMask[0] = 0; procEntry.SpellFamilyMask[1] = 0; procEntry.SpellFamilyMask[2] = 0; @@ -2048,6 +2047,11 @@ void SpellMgr::LoadSpellProcs() if (spellInfo->Effects[i].IsEffect() && isTriggerAura[spellInfo->Effects[i].ApplyAuraName]) procEntry.SpellFamilyMask |= spellInfo->Effects[i].SpellClassMask; + if (procEntry.SpellFamilyMask) + procEntry.SpellFamilyName = spellInfo->SpellFamilyName; + else + procEntry.SpellFamilyName = 0; + procEntry.ProcFlags = spellInfo->ProcFlags; procEntry.SpellTypeMask = procSpellTypeMask; procEntry.SpellPhaseMask = PROC_SPELL_PHASE_HIT; From 9f1071856626e49c63eb513e177eae2c528895c1 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 13:11:06 -0600 Subject: [PATCH 220/335] fix(Core/Spells): Fix Swift Hand of Justice using wrong proc spell (#24808) Co-authored-by: blinkysc --- src/server/scripts/Spells/spell_item.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index b0a801b6e..0fd4e999a 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -246,7 +246,7 @@ enum SunwellExaltedNeck enum SwiftHandOfJustice { - SPELL_SWIFT_HAND_OF_JUSTICE_HEAL = 59914 + SPELL_SWIFT_HAND_OF_JUSTICE_HEAL = 59913 }; enum TinyAbominationInAJar From 5a53ca6560d2399614fd6851ab1c329d16266086 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 18:28:31 -0600 Subject: [PATCH 221/335] fix(Core/Spells): Fix Prayer of Mending not bouncing to full-HP members (#24815) Co-authored-by: blinkysc --- src/server/game/Grids/Notifiers/GridNotifiers.h | 2 +- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index afb6b71bb..400fc6fdb 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -1539,7 +1539,7 @@ namespace Acore return false; } - if (u->IsAlive() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && u->GetMaxHealth() - u->GetHealth() > i_hp) + if (u->IsAlive() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && u->GetMaxHealth() - u->GetHealth() >= i_hp) { i_hp = u->GetMaxHealth() - u->GetHealth(); return true; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 775aab3d5..77250413f 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -7365,6 +7365,12 @@ void AuraEffect::HandleRaidProcFromChargeAuraProc(AuraApplication* aurApp, ProcE void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurApp, ProcEventInfo& /*eventInfo*/) { + enum + { + SPELL_PRAYER_OF_MENDING_HEAL = 33110, + SPELL_PRAYER_OF_MENDING_VISUAL = 41637 + }; + Unit* target = aurApp->GetTarget(); // Currently only Prayer of Mending @@ -7373,7 +7379,6 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA LOG_DEBUG("spells.aura", "AuraEffect::HandleRaidProcFromChargeWithValueAuraProc: received not handled spell: {}", GetId()); return; } - uint32 triggerSpellId = 33110; int32 value = GetAmount(); @@ -7397,6 +7402,7 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA if (triggerTarget) { + target->CastSpell(triggerTarget, SPELL_PRAYER_OF_MENDING_VISUAL, true); target->CastCustomSpell(triggerTarget, GetId(), &value, nullptr, nullptr, true, nullptr, this, GetCasterGUID()); if (Aura* aura = triggerTarget->GetAura(GetId(), GetCasterGUID())) aura->SetCharges(jumps); @@ -7404,8 +7410,7 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA } } - LOG_DEBUG("spells.aura", "AuraEffect::HandleRaidProcFromChargeWithValueAuraProc: Triggering spell {} from aura {} proc", triggerSpellId, GetId()); - target->CastCustomSpell(target, triggerSpellId, &value, nullptr, nullptr, true, nullptr, this, GetCasterGUID()); + target->CastCustomSpell(target, SPELL_PRAYER_OF_MENDING_HEAL, &value, nullptr, nullptr, true, nullptr, this, GetCasterGUID()); } int32 AuraEffect::GetTotalTicks() const From af951de737f1747c37ff63db2f0ffe44a66203c5 Mon Sep 17 00:00:00 2001 From: sudlud Date: Mon, 23 Feb 2026 01:40:38 +0100 Subject: [PATCH 222/335] fix(DB/Gameobject): Sniffed Values for 'Offering Bowl' spawns (#24813) --- .../rev_1771793990610730500.sql | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771793990610730500.sql diff --git a/data/sql/updates/pending_db_world/rev_1771793990610730500.sql b/data/sql/updates/pending_db_world/rev_1771793990610730500.sql new file mode 100644 index 000000000..4003c3a58 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771793990610730500.sql @@ -0,0 +1,37 @@ +-- Update gameobject 'Offering Bowl' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (195068)) AND (`guid` IN (240205, 240206, 240207, 240208, 240209, 240210, 240211, 240212, 240213, 240214, 240215, 240216, 240217, 240218, 240219)); +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 +(240205, 195068, 0, 0, 0, 1, 1, 1780.13720703125, 269.758697509765625, 59.87249755859375, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240206, 195068, 0, 0, 0, 1, 1, 1777.3125, 220.5381927490234375, 59.57676315307617187, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240207, 195068, 1, 0, 0, 1, 1, 10053.5673828125, 2109.588623046875, 1329.647705078125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240208, 195068, 1, 0, 0, 1, 1, 10065.0107421875, 2118.71875, 1329.6578369140625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240209, 195068, 1, 0, 0, 1, 1, 10053.4443359375, 2128.55029296875, 1329.6578369140625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240210, 195068, 0, 0, 0, 1, 1, -5160.017578125, -869.029541015625, 507.289947509765625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240211, 195068, 0, 0, 0, 1, 1, -5159.92041015625, -870.56597900390625, 507.307281494140625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240212, 195068, 0, 0, 0, 1, 1, -9328.3662109375, 170.1875, 61.62678909301757812, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240213, 195068, 0, 0, 0, 1, 1, -9327.1318359375, 181.86285400390625, 61.65506362915039062, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240214, 195068, 1, 0, 0, 1, 1, 1180.125, -4457.48291015625, 21.48893928527832031, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240215, 195068, 1, 0, 0, 1, 1, 1186.0677490234375, -4471.15283203125, 21.37073898315429687, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240216, 195068, 1, 0, 0, 1, 1, 1172.282958984375, -4463.251953125, 21.28664779663085937, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240217, 195068, 1, 0, 0, 1, 1, -983.0086669921875, -70.095489501953125, 20.78351402282714843, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL), +(240218, 195068, 1, 0, 0, 1, 1, -984.638916015625, -76.1319427490234375, 20.85489082336425781, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL), +(240219, 195068, 1, 0, 0, 1, 1, -984.920166015625, -75.171875, 20.93883132934570312, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (195068)) AND (`guid` IN (1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185)); +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 +(1176, 195068, 530, 0, 0, 1, 1, -1782.2535400390625, 4935.55029296875, -22.6603317260742187, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1177, 195068, 530, 0, 0, 1, 1, -1835.9149169921875, 4922.8203125, -21.208261489868164, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1178, 195068, 530, 0, 0, 1, 1, -4310.3369140625, -12439.53515625, 17.13308906555175781, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1179, 195068, 530, 0, 0, 1, 1, -4318.94775390625, -12448.236328125, 17.12119102478027343, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1180, 195068, 530, 0, 0, 1, 1, -4319.37353515625, -12455.69140625, 17.32845878601074218, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1181, 195068, 530, 0, 0, 1, 1, -4322.97216796875, -12439.4619140625, 17.49305534362792968, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1182, 195068, 530, 0, 0, 1, 1, 9418.6474609375, -6849.44970703125, 15.08854198455810546, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1183, 195068, 530, 0, 0, 1, 1, 9418.884765625, -6854.578125, 14.94306755065917968, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1184, 195068, 571, 0, 0, 1, 1, 5851.962890625, 771.29864501953125, 641.49884033203125, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL), +(1185, 195068, 571, 0, 0, 1, 1, 5856.6162109375, 765.54339599609375, 641.33111572265625, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL); + +-- enable all spawns for eventEntry 51 +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (SELECT `guid` FROM `gameobject` WHERE `id` IN (195068))); +INSERT INTO `game_event_gameobject` (SELECT 51, `guid` FROM `gameobject` WHERE `id` IN (195068)); From adc14d93b27861a3d8fc1bf0ce5ed36123ca072f Mon Sep 17 00:00:00 2001 From: Nicolas Lebacq Date: Mon, 23 Feb 2026 01:41:32 +0100 Subject: [PATCH 223/335] fix(Scripts/ZulGurub): resolved an issue with Venoxis Holy Wrath spell targeting (#24746) --- src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp index e5057638a..e706c472c 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp @@ -123,7 +123,7 @@ public: context.Repeat(25s, 30s); }).Schedule(15s, 25s, PHASE_ONE, [this](TaskContext context) { - DoCastRandomTarget(SPELL_HOLY_WRATH); + DoCastMaxThreat(SPELL_HOLY_WRATH, 0, 100.0f, true); context.Repeat(12s, 22s); }); From 1194c4fe95631184b6e53da457742dcdf17e3403 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Feb 2026 00:41:45 +0000 Subject: [PATCH 224/335] chore(DB): import pending files Referenced commit(s): af951de737f1747c37ff63db2f0ffe44a66203c5 --- .../rev_1771793990610730500.sql => db_world/2026_02_23_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771793990610730500.sql => db_world/2026_02_23_00.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771793990610730500.sql b/data/sql/updates/db_world/2026_02_23_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771793990610730500.sql rename to data/sql/updates/db_world/2026_02_23_00.sql index 4003c3a58..e237501d3 100644 --- a/data/sql/updates/pending_db_world/rev_1771793990610730500.sql +++ b/data/sql/updates/db_world/2026_02_23_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_22_06 -> 2026_02_23_00 -- Update gameobject 'Offering Bowl' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (195068)) AND (`guid` IN (240205, 240206, 240207, 240208, 240209, 240210, 240211, 240212, 240213, 240214, 240215, 240216, 240217, 240218, 240219)); From 832e54081307bb34d852149dda0c7955260f29ba Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 22 Feb 2026 21:42:04 -0300 Subject: [PATCH 225/335] fix(DB/Creature): Malygos (10/25) despawn on evade (#24814) Co-authored-by: Claude Opus 4.6 --- data/sql/updates/pending_db_world/rev_1771800217482566400.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771800217482566400.sql diff --git a/data/sql/updates/pending_db_world/rev_1771800217482566400.sql b/data/sql/updates/pending_db_world/rev_1771800217482566400.sql new file mode 100644 index 000000000..ecebdea92 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771800217482566400.sql @@ -0,0 +1,2 @@ +-- Malygos (10 and 25) - Add despawn on evade (CREATURE_FLAG_EXTRA_HARD_RESET) +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|0x80000000 WHERE `entry` IN (28859, 31734); From c0ddf3d86046feb56d6a51fb109a0ebd2981ad24 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Feb 2026 00:42:38 +0000 Subject: [PATCH 226/335] chore(DB): import pending files Referenced commit(s): adc14d93b27861a3d8fc1bf0ce5ed36123ca072f --- .../rev_1771800217482566400.sql => db_world/2026_02_23_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771800217482566400.sql => db_world/2026_02_23_01.sql} (80%) diff --git a/data/sql/updates/pending_db_world/rev_1771800217482566400.sql b/data/sql/updates/db_world/2026_02_23_01.sql similarity index 80% rename from data/sql/updates/pending_db_world/rev_1771800217482566400.sql rename to data/sql/updates/db_world/2026_02_23_01.sql index ecebdea92..685f7cc8c 100644 --- a/data/sql/updates/pending_db_world/rev_1771800217482566400.sql +++ b/data/sql/updates/db_world/2026_02_23_01.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_23_00 -> 2026_02_23_01 -- Malygos (10 and 25) - Add despawn on evade (CREATURE_FLAG_EXTRA_HARD_RESET) UPDATE `creature_template` SET `flags_extra` = `flags_extra`|0x80000000 WHERE `entry` IN (28859, 31734); From 7c0701b41b2fc41de19ac761760fe99c3071dfed Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 18:44:05 -0600 Subject: [PATCH 227/335] fix(Core/Spells): Lock and Load proc on immune (#24818) --- src/server/scripts/Spells/spell_hunter.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 74ffa2b77..9512644dc 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -1199,12 +1199,11 @@ class spell_hun_lock_and_load : public AuraScript if (!spellInfo || !(spellInfo->GetSchoolMask() & (SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_FIRE))) return false; - // TODO: Research whether Lock and Load should proc on targets - // immune to Frost Trap slow (bosses) in WotLK 3.3.5a. - // if (Spell const* procSpell = eventInfo.GetProcSpell()) - // if (Unit* target = procSpell->GetOriginalTarget()) - // if (target->IsImmunedToSpell(sSpellMgr->GetSpellInfo(SPELL_FROST_TRAP_SLOW))) - // return false; + // immune to Frost Trap slow (bosses) in WotLK patch 3.2.0 + if (Spell const* procSpell = eventInfo.GetProcSpell()) + if (Unit* target = procSpell->GetOriginalTarget()) + if (target->IsImmunedToSpell(sSpellMgr->GetSpellInfo(SPELL_FROST_TRAP_SLOW))) + return false; return roll_chance_i(aurEff->GetAmount()); } From 6097aacc81ff40c047f09b9cfa2e0dca09995c78 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 18:49:20 -0600 Subject: [PATCH 228/335] fix(DB/Spells): Fix Darkmoon Card: Illusion restoring double mana (#24816) Co-authored-by: blinkysc --- data/sql/updates/pending_db_world/rev_1771802367872480571.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771802367872480571.sql diff --git a/data/sql/updates/pending_db_world/rev_1771802367872480571.sql b/data/sql/updates/pending_db_world/rev_1771802367872480571.sql new file mode 100644 index 000000000..d8322ceb2 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771802367872480571.sql @@ -0,0 +1,2 @@ +-- Darkmoon Card: Illusion - remove duplicate mana restore (handled by C++ script) +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` = -57350 AND `spell_effect` = 60242; From 3d23a63c7ee741027db0bfa181bc42d400ad02a4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Feb 2026 00:50:42 +0000 Subject: [PATCH 229/335] chore(DB): import pending files Referenced commit(s): 6097aacc81ff40c047f09b9cfa2e0dca09995c78 --- .../rev_1771802367872480571.sql => db_world/2026_02_23_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771802367872480571.sql => db_world/2026_02_23_02.sql} (79%) diff --git a/data/sql/updates/pending_db_world/rev_1771802367872480571.sql b/data/sql/updates/db_world/2026_02_23_02.sql similarity index 79% rename from data/sql/updates/pending_db_world/rev_1771802367872480571.sql rename to data/sql/updates/db_world/2026_02_23_02.sql index d8322ceb2..69dc72cdd 100644 --- a/data/sql/updates/pending_db_world/rev_1771802367872480571.sql +++ b/data/sql/updates/db_world/2026_02_23_02.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_23_01 -> 2026_02_23_02 -- Darkmoon Card: Illusion - remove duplicate mana restore (handled by C++ script) DELETE FROM `spell_linked_spell` WHERE `spell_trigger` = -57350 AND `spell_effect` = 60242; From beca6fef53caa4ccfa504a0bcc68f1e6eacf1913 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 19:11:21 -0600 Subject: [PATCH 230/335] fix(Core/Spells): Fix Lock and Load proccing from Explosive Trap activation (#24821) Co-authored-by: blinkysc --- src/server/scripts/Spells/spell_hunter.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 9512644dc..fa9e2d79e 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -1195,8 +1195,10 @@ class spell_hun_lock_and_load : public AuraScript if (!(eventInfo.GetTypeMask() & PROC_FLAG_DONE_TRAP_ACTIVATION)) return false; + // Patch 3.3.3: Lock and Load no longer triggers from Explosive Trap activation, + // only from frost trap activation. Fire traps proc via CheckPeriodicProc instead. SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || !(spellInfo->GetSchoolMask() & (SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_FIRE))) + if (!spellInfo || !(spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST)) return false; // immune to Frost Trap slow (bosses) in WotLK patch 3.2.0 From bce0be9fdb7312aa8657d9c5cbacaa8b471d8110 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 19:11:35 -0600 Subject: [PATCH 231/335] fix(Core/Spells): Prevent vehicles from receiving party/raid area auras (#24820) Co-authored-by: blinkysc --- src/server/game/Grids/Notifiers/GridNotifiers.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 400fc6fdb..34f0c09ad 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -1005,6 +1005,9 @@ namespace Acore AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid) : _source(obj), _refUnit(funit), _range(range), _raid(raid) {} bool operator()(Unit* u) { + if (u->IsVehicle()) + return false; + if (_raid) { if (!_refUnit->IsInRaidWith(u)) From b035d1f914fddf01276b4b13ed68eaca38a6c4b0 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sun, 22 Feb 2026 22:11:52 -0300 Subject: [PATCH 232/335] feat(Core/SmartScripts): Implement Target Type for Formations (#24811) --- .../game/AI/SmartScripts/SmartScript.cpp | 44 +++++++++++++++++++ .../game/AI/SmartScripts/SmartScriptMgr.cpp | 13 ++++++ .../game/AI/SmartScripts/SmartScriptMgr.h | 10 ++++- 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index f80a36d7a..ec4bf27d6 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -19,6 +19,7 @@ #include "Cell.h" #include "CellImpl.h" #include "ChatTextBuilder.h" +#include "CreatureGroups.h" #include "CreatureTextMgr.h" #include "GameEventMgr.h" #include "GossipDef.h" @@ -4062,6 +4063,49 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, break; } + case SMART_TARGET_FORMATION: + { + if (me) + { + if (CreatureGroup* group = me->GetFormation()) + { + uint32 formationType = e.target.formation.type; + uint32 entry = e.target.formation.entry; + bool excludeSelf = e.target.formation.excludeSelf; + + if (formationType == 1) // Leader only + { + if (Creature* leader = group->GetLeader()) + { + if ((!excludeSelf || leader != me) && (!entry || leader->GetEntry() == entry)) + targets.push_back(leader); + } + } + else // 0 = Members only, 2 = All + { + for (auto const& itr : group->GetMembers()) + { + Creature* member = itr.first; + + if (!member) + continue; + + if (excludeSelf && member == me) + continue; + + if (entry && member->GetEntry() != entry) + continue; + + if (formationType == 0 && member == group->GetLeader()) + continue; + + targets.push_back(member); + } + } + } + } + break; + } case SMART_TARGET_NONE: case SMART_TARGET_POSITION: default: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 52faaef4b..3f0cbdef0 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -531,6 +531,18 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) } break; } + case SMART_TARGET_FORMATION: + { + if (e.target.formation.type > 2) + { + LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} has invalid formation target type ({}, must be 0-2).", + e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType(), e.target.formation.type); + return false; + } + if (e.target.formation.entry && !IsCreatureValid(e, e.target.formation.entry)) + return false; + return IsSAIBoolValid(e, e.target.formation.excludeSelf); + } case SMART_TARGET_HOSTILE_SECOND_AGGRO: case SMART_TARGET_HOSTILE_LAST_AGGRO: case SMART_TARGET_HOSTILE_RANDOM: @@ -955,6 +967,7 @@ bool SmartAIMgr::CheckUnusedTargetParams(SmartScriptHolder const& e) case SMART_TARGET_RANDOM_POINT: return sizeof(SmartTarget::randomPoint); case SMART_TARGET_SUMMONED_CREATURES: return sizeof(SmartTarget::summonedCreatures); case SMART_TARGET_INSTANCE_STORAGE: return sizeof(SmartTarget::instanceStorage); + case SMART_TARGET_FORMATION: return sizeof(SmartTarget::formation); default: LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using a target {} with no unused params specified in SmartAIMgr::CheckUnusedTargetParams(), please report this.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType()); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 2601f5bd1..e87e01e62 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1581,8 +1581,9 @@ enum SMARTAI_TARGETS SMART_TARGET_ROLE_SELECTION = 203, // Range Max, TargetMask (Tanks (1), Healer (2) Damage (4)), resize list SMART_TARGET_SUMMONED_CREATURES = 204, // Entry SMART_TARGET_INSTANCE_STORAGE = 205, // Instance data index, Type (creature (1), gameobject (2)) + SMART_TARGET_FORMATION = 206, // Type (0: members only, 1: leader only, 2: all), CreatureEntry (0: any), ExcludeSelf (0/1) - SMART_TARGET_AC_END = 206 // placeholder + SMART_TARGET_AC_END = 207 // placeholder }; struct SmartTarget @@ -1759,6 +1760,13 @@ struct SmartTarget uint32 type; } instanceStorage; + struct + { + uint32 type; // 0: members only, 1: leader only, 2: all + uint32 entry; // creature entry filter, 0 = any + SAIBool excludeSelf; + } formation; + struct { SAIBool includePets; From 27f891543806a881cc554e4d8e4509ad692ff5dc Mon Sep 17 00:00:00 2001 From: Walter Pagani Date: Sun, 22 Feb 2026 22:12:23 -0300 Subject: [PATCH 233/335] fix(DB/Text): Add some translations (esES and esMX) (#24805) --- .../rev_1771767222932614900.sql | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771767222932614900.sql diff --git a/data/sql/updates/pending_db_world/rev_1771767222932614900.sql b/data/sql/updates/pending_db_world/rev_1771767222932614900.sql new file mode 100644 index 000000000..1a7de9af1 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771767222932614900.sql @@ -0,0 +1,89 @@ +UPDATE `acore_string` SET `locale_esES` = 'El comando ''{}'' no existe.', `locale_esMX` = 'El comando ''{}'' no existe.' WHERE `entry` = 6; +UPDATE `acore_string` SET `locale_esES` = 'El subcomando ''{}{}{}'' es ambiguo:', `locale_esMX` = 'El subcomando ''{}{}{}'' es ambiguo:' WHERE `entry` = 7; +UPDATE `acore_string` SET `locale_esES` = 'Posibles subcomandos:', `locale_esMX` = 'Posibles subcomandos:' WHERE `entry` = 8; +UPDATE `acore_string` SET `locale_esES` = '| Flags de la cuenta:', `locale_esMX` = '| Flags de la cuenta:' WHERE `entry` = 179; +UPDATE `acore_string` SET `locale_esES` = 'Este nombre es profano, elige otro.', `locale_esMX` = 'Este nombre es profano, elige otro.' WHERE `entry` = 187; +UPDATE `acore_string` SET `locale_esES` = '|- {}', `locale_esMX` = '|- {}' WHERE `entry` = 191; +UPDATE `acore_string` SET `locale_esES` = '|- {} ...', `locale_esMX` = '|- {} ...' WHERE `entry` = 192; +UPDATE `acore_string` SET `locale_esES` = 'El subcomando ''{}{}{}'' no existe.', `locale_esMX` = 'El subcomando ''{}{}{}'' no existe.' WHERE `entry` = 193; +UPDATE `acore_string` SET `locale_esES` = 'El comando ''{}'' es ambiguo:', `locale_esMX` = 'El comando ''{}'' es ambiguo:' WHERE `entry` = 194; +UPDATE `acore_string` SET `locale_esES` = '### USO: .{} ...', `locale_esMX` = '### USO: .{} ...' WHERE `entry` = 195; +UPDATE `acore_string` SET `locale_esES` = 'No hay información detallada de uso asociada a ''{}''. Esto nunca debería ocurrir con los comandos estándar de AzerothCore; si ocurre, repórtalo como un error.', `locale_esMX` = 'No hay información detallada de uso asociada a ''{}''. Esto nunca debería ocurrir con los comandos estándar de AzerothCore; si ocurre, repórtalo como un error.' WHERE `entry` = 196; +UPDATE `acore_string` SET `locale_esES` = 'Recuperar ID: {} | Item: {} ({}) | Cantidad: {}', `locale_esMX` = 'Recuperar ID: {} | Item: {} ({}) | Cantidad: {}' WHERE `entry` = 197; +UPDATE `acore_string` SET `locale_esES` = 'El jugador no tiene items recuperables', `locale_esMX` = 'El jugador no tiene items recuperables' WHERE `entry` = 198; +UPDATE `acore_string` SET `locale_esES` = 'El jugador no tiene item recuperable con id {}', `locale_esMX` = 'El jugador no tiene item recuperable con id {}' WHERE `entry` = 199; +UPDATE `acore_string` SET `locale_esES` = 'No se puede ir al spawn {} ya que solo existen {}', `locale_esMX` = 'No se puede ir al spawn {} ya que solo existen {}' WHERE `entry` = 288; +UPDATE `acore_string` SET `locale_esES` = 'Honorable', `locale_esMX` = 'Honorable' WHERE `entry` = 323; +UPDATE `acore_string` SET `locale_esES` = 'Venerado', `locale_esMX` = 'Venerado' WHERE `entry` = 324; +UPDATE `acore_string` SET `locale_esES` = 'Exaltado', `locale_esMX` = 'Exaltado' WHERE `entry` = 325; +UPDATE `acore_string` SET `locale_esES` = 'La facción {} ({}) no puede tener reputación.', `locale_esMX` = 'La facción {} ({}) no puede tener reputación.' WHERE `entry` = 326; +UPDATE `acore_string` SET `locale_esES` = ' [sin reputación]', `locale_esMX` = ' [sin reputación]' WHERE `entry` = 327; +UPDATE `acore_string` SET `locale_esES` = 'Personajes en la cuenta {} (Id: {})', `locale_esMX` = 'Personajes en la cuenta {} (Id: {})' WHERE `entry` = 328; +UPDATE `acore_string` SET `locale_esES` = ' {} (GUID {})', `locale_esMX` = ' {} (GUID {})' WHERE `entry` = 329; +UPDATE `acore_string` SET `locale_esES` = '¡No se encontraron jugadores!', `locale_esMX` = '¡No se encontraron jugadores!' WHERE `entry` = 330; +UPDATE `acore_string` SET `locale_esES` = 'El costo del item extendido {} no existe', `locale_esMX` = 'El costo del item extendido {} no existe' WHERE `entry` = 331; +UPDATE `acore_string` SET `locale_esES` = 'El modo GM está activado.', `locale_esMX` = 'El modo GM está activado.' WHERE `entry` = 332; +UPDATE `acore_string` SET `locale_esES` = 'El modo GM está desactivado.', `locale_esMX` = 'El modo GM está desactivado.' WHERE `entry` = 333; +UPDATE `acore_string` SET `locale_esES` = 'La insignia de chat de GM está activada.', `locale_esMX` = 'La insignia de chat de GM está activada.' WHERE `entry` = 334; +UPDATE `acore_string` SET `locale_esES` = 'La insignia de chat de GM está desactivada.', `locale_esMX` = 'La insignia de chat de GM está desactivada.' WHERE `entry` = 335; +UPDATE `acore_string` SET `locale_esES` = 'Reparas todos los items de {}.', `locale_esMX` = 'Reparas todos los items de {}.' WHERE `entry` = 336; +UPDATE `acore_string` SET `locale_esES` = 'Todos tus items reparados por {}.', `locale_esMX` = 'Todos tus items reparados por {}.' WHERE `entry` = 337; +UPDATE `acore_string` SET `locale_esES` = 'Has configurado el modo caminar sobre el agua {} para {}.', `locale_esMX` = 'Has configurado el modo caminar sobre el agua {} para {}.' WHERE `entry` = 338; +UPDATE `acore_string` SET `locale_esES` = 'Tu modo de caminar sobre el agua {} por {}.', `locale_esMX` = 'Tu modo de caminar sobre el agua {} por {}.' WHERE `entry` = 339; +UPDATE `acore_string` SET `locale_esES` = '{} ahora te está siguiendo.', `locale_esMX` = '{} ahora te está siguiendo.' WHERE `entry` = 340; +UPDATE `acore_string` SET `locale_esES` = '{} no te está siguiendo.', `locale_esMX` = '{} no te está siguiendo.' WHERE `entry` = 341; +UPDATE `acore_string` SET `locale_esES` = '{} ya no te está siguiendo.', `locale_esMX` = '{} ya no te está siguiendo.' WHERE `entry` = 342; +UPDATE `acore_string` SET `locale_esES` = 'La criatura (entry: {}) no puede ser domesticada.', `locale_esMX` = 'La criatura (entry: {}) no puede ser domesticada.' WHERE `entry` = 343; +UPDATE `acore_string` SET `locale_esES` = 'Ya tienes mascota.', `locale_esMX` = 'Ya tienes mascota.' WHERE `entry` = 344; +UPDATE `acore_string` SET `locale_esES` = 'Se solicitará una personalización forzada para el jugador {} en el próximo inicio de sesión.', `locale_esMX` = 'Se solicitará una personalización forzada para el jugador {} en el próximo inicio de sesión.' WHERE `entry` = 345; +UPDATE `acore_string` SET `locale_esES` = 'Se solicitará una personalización forzada para el jugador {} (GUID #{}) en el próximo inicio de sesión.', `locale_esMX` = 'Se solicitará una personalización forzada para el jugador {} (GUID #{}) en el próximo inicio de sesión.' WHERE `entry` = 346; +UPDATE `acore_string` SET `locale_esES` = '¡TaxiNode ID {} no encontrado!', `locale_esMX` = '¡TaxiNode ID {} no encontrado!' WHERE `entry` = 347; +UPDATE `acore_string` SET `locale_esES` = 'El objeto de juego (Entrada: {}) tiene datos no válidos y no se puede generar.', `locale_esMX` = 'El objeto de juego (Entrada: {}) tiene datos no válidos y no se puede generar.' WHERE `entry` = 348; +UPDATE `acore_string` SET `locale_esES` = '{} (idx:{}) - |cffffffff|Htítulo:{}|h[{} {}]|h|r {} {} ', `locale_esMX` = '{} (idx:{}) - |cffffffff|Htítulo:{}|h[{} {}]|h|r {} {} ' WHERE `entry` = 349; +UPDATE `acore_string` SET `locale_esES` = '{} (idx: {}) - [{} {}] {} {} ', `locale_esMX` = '{} (idx: {}) - [{} {}] {} {} ' WHERE `entry` = 350; +UPDATE `acore_string` SET `locale_esES` = '¡No se encontraron títulos!', `locale_esMX` = '¡No se encontraron títulos!' WHERE `entry` = 351; +UPDATE `acore_string` SET `locale_esES` = 'ID de título no válido: {}.', `locale_esMX` = 'ID de título no válido: {}.' WHERE `entry` = 352; +UPDATE `acore_string` SET `locale_esES` = 'Se agregó el título {} ({}) a la lista de títulos conocidos para el jugador {}.', `locale_esMX` = 'Se agregó el título {} ({}) a la lista de títulos conocidos para el jugador {}.' WHERE `entry` = 353; +UPDATE `acore_string` SET `locale_esES` = 'El título {} ({}) se eliminó de la lista de títulos conocidos para el jugador {}.', `locale_esMX` = 'El título {} ({}) se eliminó de la lista de títulos conocidos para el jugador {}.' WHERE `entry` = 354; +UPDATE `acore_string` SET `locale_esES` = 'Título {} ({}) establecido como título seleccionado actual para el jugador {}.', `locale_esMX` = 'Título {} ({}) establecido como título seleccionado actual para el jugador {}.' WHERE `entry` = 355; +UPDATE `acore_string` SET `locale_esES` = 'El título seleccionado actualmente para el jugador {} se restableció porque no se conoce ahora.', `locale_esMX` = 'El título seleccionado actualmente para el jugador {} se restableció porque no se conoce ahora.' WHERE `entry` = 356; +UPDATE `acore_string` SET `locale_esES` = 'Estado del comando de trucos:', `locale_esMX` = 'Estado del comando de trucos:' WHERE `entry` = 357; +UPDATE `acore_string` SET `locale_esES` = 'Modo Dios: {}.', `locale_esMX` = 'Modo Dios: {}.' WHERE `entry` = 358; +UPDATE `acore_string` SET `locale_esES` = 'Tiempo de lanzamiento: {}.', `locale_esMX` = 'Tiempo de lanzamiento: {}.' WHERE `entry` = 359; +UPDATE `acore_string` SET `locale_esES` = 'Enfriamiento: {}.', `locale_esMX` = 'Enfriamiento: {}.' WHERE `entry` = 360; +UPDATE `acore_string` SET `locale_esES` = 'Fuerza: {}.', `locale_esMX` = 'Fuerza: {}.' WHERE `entry` = 361; +UPDATE `acore_string` SET `locale_esES` = 'Caminar sobre el agua: {}.', `locale_esMX` = 'Caminar sobre el agua: {}.' WHERE `entry` = 362; +UPDATE `acore_string` SET `locale_esES` = 'El jugador {} no puede susurrarte más.', `locale_esMX` = 'El jugador {} no puede susurrarte más.' WHERE `entry` = 363; +UPDATE `acore_string` SET `locale_esES` = 'Taxinodes: {}.', `locale_esMX` = 'Taxinodes: {}.' WHERE `entry` = 364; +UPDATE `acore_string` SET `locale_esES` = '|cffffffff{}|r items equipados eliminados por {}.', `locale_esMX` = '|cffffffff{}|r items equipados eliminados por {}.' WHERE `entry` = 365; +UPDATE `acore_string` SET `locale_esES` = '| cffffffff {} | r items en bolsas equipadas eliminados para {}', `locale_esMX` = '| cffffffff {} | r items en bolsas equipadas eliminados para {}' WHERE `entry` = 366; +UPDATE `acore_string` SET `locale_esES` = '|cffffffff{}|r items en el banco eliminados por {}.', `locale_esMX` = '|cffffffff{}|r items en el banco eliminados por {}.' WHERE `entry` = 367; +UPDATE `acore_string` SET `locale_esES` = '|cffffffff{}|r llaves en el llavero eliminadas para {}', `locale_esMX` = '|cffffffff{}|r llaves en el llavero eliminadas para {}' WHERE `entry` = 368; +UPDATE `acore_string` SET `locale_esES` = '|cffffffff{}|r monedas eliminadas por {}.', `locale_esMX` = '|cffffffff{}|r monedas eliminadas por {}.' WHERE `entry` = 369; +UPDATE `acore_string` SET `locale_esES` = '|cffffffff{}|r artículos en recompra de proveedores eliminados por {}.', `locale_esMX` = '|cffffffff{}|r artículos en recompra de proveedores eliminados por {}.' WHERE `entry` = 370; +UPDATE `acore_string` SET `locale_esES` = '¡La Alianza capturó el Cementerio Sur!', `locale_esMX` = '¡La Alianza capturó el Cementerio Sur!' WHERE `entry` = 10068; +UPDATE `acore_string` SET `locale_esES` = '¡La Alianza capturó el Cementerio Oeste!', `locale_esMX` = '¡La Alianza capturó el Cementerio Oeste!' WHERE `entry` = 10069; +UPDATE `acore_string` SET `locale_esES` = '¡La Alianza capturó el Cementerio Este!', `locale_esMX` = '¡La Alianza capturó el Cementerio Este!' WHERE `entry` = 10070; +UPDATE `acore_string` SET `locale_esES` = '¡La Horda capturó el Cementerio Sur!', `locale_esMX` = '¡La Horda capturó el Cementerio Sur!' WHERE `entry` = 10071; +UPDATE `acore_string` SET `locale_esES` = '¡La Horda capturó el Cementerio Oeste!', `locale_esMX` = '¡La Horda capturó el Cementerio Oeste!' WHERE `entry` = 10072; +UPDATE `acore_string` SET `locale_esES` = '¡La Horda capturó el Cementerio Este!', `locale_esMX` = '¡La Horda capturó el Cementerio Este!' WHERE `entry` = 10073; +UPDATE `acore_string` SET `locale_esES` = 'Horda', `locale_esMX` = 'Horda' WHERE `entry` = 12056; +UPDATE `acore_string` SET `locale_esES` = 'Alianza', `locale_esMX` = 'Alianza' WHERE `entry` = 12057; +UPDATE `acore_string` SET `locale_esES` = '¡La batalla por Conquista del Invierno está a punto de comenzar!', `locale_esMX` = '¡La batalla por Conquista del Invierno está a punto de comenzar!' WHERE `entry` = 12058; +UPDATE `acore_string` SET `locale_esES` = 'Has alcanzado el rango 1: Cabo', `locale_esMX` = 'Has alcanzado el rango 1: Cabo' WHERE `entry` = 12059; +UPDATE `acore_string` SET `locale_esES` = 'Has alcanzado el rango 2: primer teniente', `locale_esMX` = 'Has alcanzado el rango 2: primer teniente' WHERE `entry` = 12060; +UPDATE `acore_string` SET `locale_esES` = 'La torre del homenaje del sureste', `locale_esMX` = 'La torre del homenaje del sureste' WHERE `entry` = 12061; +UPDATE `acore_string` SET `locale_esES` = 'La torre del homenaje del noreste', `locale_esMX` = 'La torre del homenaje del noreste' WHERE `entry` = 12062; +UPDATE `acore_string` SET `locale_esES` = 'La torre del homenaje suroeste', `locale_esMX` = 'La torre del homenaje suroeste' WHERE `entry` = 12063; +UPDATE `acore_string` SET `locale_esES` = 'La torre del homenaje del noroeste', `locale_esMX` = 'La torre del homenaje del noroeste' WHERE `entry` = 12064; +UPDATE `acore_string` SET `locale_esES` = '{} ha sido dañada!', `locale_esMX` = '{} ha sido dañada!' WHERE `entry` = 12065; +UPDATE `acore_string` SET `locale_esES` = '{} ha sido destruida!', `locale_esMX` = '{} ha sido destruida!' WHERE `entry` = 12066; +UPDATE `acore_string` SET `locale_esES` = '¡Comienza la batalla por Conquista del Invierno!', `locale_esMX` = '¡Comienza la batalla por Conquista del Invierno!' WHERE `entry` = 12067; +UPDATE `acore_string` SET `locale_esES` = '¡{} ha defendido con éxito la fortaleza Conquista del Invierno!', `locale_esMX` = '¡{} ha defendido con éxito la fortaleza Conquista del Invierno!' WHERE `entry` = 12068; +UPDATE `acore_string` SET `locale_esES` = '{} ha sido capturado por {}', `locale_esMX` = '{} ha sido capturado por {}' WHERE `entry` = 12050; +UPDATE `acore_string` SET `locale_esES` = '{} está bajo ataque por {}', `locale_esMX` = '{} está bajo ataque por {}' WHERE `entry` = 12051; +UPDATE `acore_string` SET `locale_esES` = 'El taller del asedio del Templo Roto', `locale_esMX` = 'El taller del asedio del Templo Roto' WHERE `entry` = 12052; +UPDATE `acore_string` SET `locale_esES` = 'El taller de asedio del Anillo Hundido', `locale_esMX` = 'El taller de asedio del Anillo Hundido' WHERE `entry` = 12055; +UPDATE `acore_string` SET `locale_esES`='Activar o desactivar vuelo instantáneo', `locale_esMX`='Activar o desactivar vuelo instantáneo' WHERE `entry`=30077; +UPDATE `acore_string` SET `locale_esES`='Vuelo instantáneo activado.', `locale_esMX`='Vuelo instantáneo activado.' WHERE `entry`=30078; +UPDATE `acore_string` SET `locale_esES`='Vuelo instantáneo desactivado.', `locale_esMX`='Vuelo instantáneo desactivado.' WHERE `entry`=30079; From 76dd25d751a6176d1744ef351f9dd2af22dd4583 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Feb 2026 01:31:30 +0000 Subject: [PATCH 234/335] chore(DB): import pending files Referenced commit(s): beca6fef53caa4ccfa504a0bcc68f1e6eacf1913 --- .../rev_1771767222932614900.sql => db_world/2026_02_23_03.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771767222932614900.sql => db_world/2026_02_23_03.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771767222932614900.sql b/data/sql/updates/db_world/2026_02_23_03.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771767222932614900.sql rename to data/sql/updates/db_world/2026_02_23_03.sql index 1a7de9af1..2a09ecbdd 100644 --- a/data/sql/updates/pending_db_world/rev_1771767222932614900.sql +++ b/data/sql/updates/db_world/2026_02_23_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_23_02 -> 2026_02_23_03 UPDATE `acore_string` SET `locale_esES` = 'El comando ''{}'' no existe.', `locale_esMX` = 'El comando ''{}'' no existe.' WHERE `entry` = 6; UPDATE `acore_string` SET `locale_esES` = 'El subcomando ''{}{}{}'' es ambiguo:', `locale_esMX` = 'El subcomando ''{}{}{}'' es ambiguo:' WHERE `entry` = 7; UPDATE `acore_string` SET `locale_esES` = 'Posibles subcomandos:', `locale_esMX` = 'Posibles subcomandos:' WHERE `entry` = 8; From 40e0a1e5454a4bf55f1f01b1485c9a73837ecfc9 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Sun, 22 Feb 2026 19:44:52 -0600 Subject: [PATCH 235/335] fix(Core/Spells): Fix Kill Command stacks not being consumed (#24822) Co-authored-by: blinkysc --- src/server/scripts/Spells/spell_hunter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index fa9e2d79e..da98fe256 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -76,7 +76,7 @@ enum HunterSpells SPELL_HUNTER_RAPID_RECUPERATION_R1 = 56654, SPELL_HUNTER_RAPID_RECUPERATION_R2 = 58882, SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS = 57894, - SPELL_HUNTER_KILL_COMMAND_HUNTER = 34026, + SPELL_HUNTER_KILL_COMMAND_HUNTER = 34027, SPELL_HUNTER_RAPID_RECUPERATION_MANA_R1 = 56654, SPELL_HUNTER_RAPID_RECUPERATION_MANA_R2 = 58882, SPELL_HUNTER_PIERCING_SHOTS = 63468, From 0faf08c2602023d24348bae938a8cef19463f3b5 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sun, 22 Feb 2026 23:26:25 -0300 Subject: [PATCH 236/335] fix(DB/Loot): Cover more WotLK creatures in the Loot Normalization (#24819) --- .../rev_1771805490746014200.sql | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771805490746014200.sql diff --git a/data/sql/updates/pending_db_world/rev_1771805490746014200.sql b/data/sql/updates/pending_db_world/rev_1771805490746014200.sql new file mode 100644 index 000000000..d2a785586 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771805490746014200.sql @@ -0,0 +1,235 @@ +-- +DELETE FROM `creature_loot_template` WHERE `Entry` IN (24291, 23776, 24104, 26862, 26863, 29885, 27821, 26290, 30492); +UPDATE `creature_template` SET `lootid` = 0 WHERE `Entry` IN (24291, 23776, 24104, 26862, 26863, 29885, 27821, 26290, 30492); + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (24398,24400,31693,24201,24238,24469,25301,25601,25789,25801,25804,26578,26828,26836,27006,27007,27008,27009,27122,27210,27247,27334,27579,27580,27859,28068,28255,29375,29503,29614,29836,30831,30925,31139,31399,32278,32353,24440,25228,25234,25488,28399,29026,29696,29710,31040,32181,23725,23993,24329,24371,24547,24900,24914,25618,26287,26291,26293,26333,26360,26406,26417,26633,26838,26841,26858,27002,27018,27105,27249,27383,27578,27645,27647,27732,27743,27744,27860,28199,28200,28443,28467,28477,28597,28659,28784,28793,29664,30829,30830,30861,30892,30954,31180,31184,31188,31198,31203,31206,31229,31255,31502,32770,32772,40419) AND `Reference` IN (1200067,1200068,1200069,1200071,1200076,1200077,1200078,1200079,1200080,1200170,1200171,1200179,1200180,1200270,1200271,1200272,1200273,1200274,1200275,1200276,1200277,1200279,1200280,1200281,1200282,1200369,1200370,1200371,1200372,1200373,1200374,1200375,1200376,1200377,1200379,1200380,1200381,1200382,1270001,1270002); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `GroupId`, `Comment`) VALUES +(23725, 1, 1200270, 0, 5, 'Stone Giant - World Loot Level 70'), +(23993, 1, 1200271, 0, 5, 'Sepulchral Overseer - World Loot Level 71'), +(24201, 1, 1200372, 0, 5, 'Dalronn the Controller - World Loot Level 72'), +(24201, 33470, 1270002, 25, 0, 'Dalronn the Controller - Frostweave Cloth Elite'), +(24238, 1, 1200370, 0, 5, 'Bjorn Halgurdsson - World Loot Level 70'), +(24238, 33470, 1270002, 25, 0, 'Bjorn Halgurdsson - Frostweave Cloth Elite'), +(24329, 1, 1200270, 0, 5, 'Runed Stone Giant - World Loot Level 70'), +(24371, 1, 1200271, 0, 5, 'Megalith - World Loot Level 71'), +(24398, 1, 1200171, 0, 5, 'Steel Gate Excavator - World Loot Level 71'), +(24398, 33470, 1270001, 25, 0, 'Steel Gate Excavator - Frostweave Cloth Normal'), +(24400, 1, 1200170, 0, 5, 'Steel Gate Archaeologist - World Loot Level 70'), +(24400, 2, 1200171, 0, 5, 'Steel Gate Archaeologist - World Loot Level 71'), +(24400, 33470, 1270001, 25, 0, 'Steel Gate Archaeologist - Frostweave Cloth Normal'), +(24440, 1, 1200071, 0, 5, 'Gjalerbron Gargoyle - World Loot Level 71'), +(24469, 1, 1200369, 0, 5, 'Magnataur Huntress - World Loot Level 69'), +(24469, 33470, 1270002, 25, 0, 'Magnataur Huntress - Frostweave Cloth Elite'), +(24547, 1, 1200271, 0, 5, 'Hozzer - World Loot Level 71'), +(24900, 1, 1200272, 0, 5, 'Abdul the Insane - World Loot Level 72'), +(24914, 1, 1200280, 0, 5, 'Sorlof - World Loot Level 80'), +(25228, 1, 1200069, 0, 5, 'Risen Crypt Lord - World Loot Level 69'), +(25234, 1, 1200068, 0, 5, 'Stormfleet Deckhand - World Loot Level 68'), +(25234, 2, 1200069, 0, 5, 'Stormfleet Deckhand - World Loot Level 69'), +(25301, 1, 1200372, 0, 5, 'Counselor Talbot - World Loot Level 72'), +(25301, 33470, 1270002, 25, 0, 'Counselor Talbot - Frostweave Cloth Elite'), +(25488, 1, 1200068, 0, 5, 'Wooly Rhino Calf - World Loot Level 68'), +(25601, 1, 1200372, 0, 5, 'Prince Valanar - World Loot Level 72'), +(25601, 33470, 1270002, 25, 0, 'Prince Valanar - Frostweave Cloth Elite'), +(25618, 1, 1200270, 0, 5, 'Varidus the Flenser - World Loot Level 70'), +(25789, 1, 1200371, 0, 5, 'Gammothra the Tormentor - World Loot Level 71'), +(25789, 33470, 1270002, 25, 0, 'Gammothra the Tormentor - Frostweave Cloth Elite'), +(25801, 1, 1200372, 0, 5, 'Nedar, Lord of Rhinos - World Loot Level 72'), +(25801, 33470, 1270002, 25, 0, 'Nedar, Lord of Rhinos - Frostweave Cloth Elite'), +(25804, 1, 1200372, 0, 5, 'Harold Lane - World Loot Level 72'), +(25804, 33470, 1270002, 25, 0, 'Harold Lane - Frostweave Cloth Elite'), +(26287, 1, 1200273, 0, 5, 'Icestorm - World Loot Level 73'), +(26291, 1, 1200273, 0, 5, 'Crystalline Ice Giant - World Loot Level 73'), +(26291, 2, 1200274, 0, 5, 'Crystalline Ice Giant - World Loot Level 74'), +(26293, 1, 1200273, 0, 5, 'Hulking Jormungar - World Loot Level 73'), +(26293, 2, 1200274, 0, 5, 'Hulking Jormungar - World Loot Level 74'), +(26333, 1, 1200271, 0, 5, 'Corrupted Lothalor Ancient - World Loot Level 71'), +(26333, 2, 1200272, 0, 5, 'Corrupted Lothalor Ancient - World Loot Level 72'), +(26360, 1, 1200274, 0, 5, 'Rattlebore - World Loot Level 74'), +(26406, 1, 1200274, 0, 5, 'The Anvil - World Loot Level 74'), +(26417, 1, 1200274, 0, 5, 'Runed Giant - World Loot Level 74'), +(26417, 2, 1200275, 0, 5, 'Runed Giant - World Loot Level 75'), +(26578, 1, 1200374, 0, 5, 'Mistress of the Coldwind - World Loot Level 74'), +(26578, 33470, 1270002, 25, 0, 'Mistress of the Coldwind - Frostweave Cloth Elite'), +(26633, 1, 1200275, 0, 5, 'Ursoc - World Loot Level 75'), +(26828, 1, 1200374, 0, 5, 'Magister Keldonus - World Loot Level 74'), +(26828, 33470, 1270002, 25, 0, 'Magister Keldonus - Frostweave Cloth Elite'), +(26836, 1, 1200374, 0, 5, 'Gigantaur - World Loot Level 74'), +(26836, 33470, 1270002, 25, 0, 'Gigantaur - Frostweave Cloth Elite'), +(26838, 1, 1200274, 0, 5, 'Dreadtalon - World Loot Level 74'), +(26841, 1, 1200273, 0, 5, 'Reanimated Frost Wyrm - World Loot Level 73'), +(26841, 2, 1200274, 0, 5, 'Reanimated Frost Wyrm - World Loot Level 74'), +(26858, 1, 1200275, 0, 5, 'Sarathstra - World Loot Level 75'), +(27002, 1, 1200274, 0, 5, 'Grom\'thar the Thunderbringer - World Loot Level 74'), +(27006, 1, 1200373, 0, 5, 'Bonesunder - World Loot Level 73'), +(27006, 33470, 1270002, 25, 0, 'Bonesunder - Frostweave Cloth Elite'), +(27007, 1, 1200373, 0, 5, 'Iceshatter - World Loot Level 73'), +(27007, 33470, 1270002, 25, 0, 'Iceshatter - Frostweave Cloth Elite'), +(27008, 1, 1200373, 0, 5, 'Bloodfeast - World Loot Level 73'), +(27008, 33470, 1270002, 25, 0, 'Bloodfeast - Frostweave Cloth Elite'), +(27009, 1, 1200373, 0, 5, 'Drakegore - World Loot Level 73'), +(27009, 33470, 1270002, 25, 0, 'Drakegore - Frostweave Cloth Elite'), +(27018, 1, 1200275, 0, 5, 'Shade of Arugal - World Loot Level 75'), +(27105, 1, 1200273, 0, 5, 'Kreug Oathbreaker - World Loot Level 73'), +(27122, 1, 1200374, 0, 5, 'Overseer Deathgaze - World Loot Level 74'), +(27122, 33470, 1270002, 25, 0, 'Overseer Deathgaze - Frostweave Cloth Elite'), +(27210, 1, 1200372, 0, 5, 'High General Abbendis - World Loot Level 72'), +(27210, 33470, 1270002, 25, 0, 'High General Abbendis - Frostweave Cloth Elite'), +(27247, 1, 1200372, 0, 5, 'Devout Bodyguard - World Loot Level 72'), +(27247, 33470, 1270002, 25, 0, 'Devout Bodyguard - Frostweave Cloth Elite'), +(27249, 1, 1200274, 0, 5, 'Alystros the Verdant Keeper - World Loot Level 74'), +(27334, 1, 1200374, 0, 5, 'Onslaught Commander Iustus - World Loot Level 74'), +(27334, 33470, 1270002, 25, 0, 'Onslaught Commander Iustus - Frostweave Cloth Elite'), +(27383, 1, 1200273, 0, 5, 'Thel\'zan the Duskbringer - World Loot Level 73'), +(27578, 1, 1200275, 0, 5, 'Goremaw - World Loot Level 75'), +(27579, 1, 1200375, 0, 5, 'Varlam - World Loot Level 75'), +(27579, 33470, 1270002, 25, 0, 'Varlam - Frostweave Cloth Elite'), +(27580, 1, 1200375, 0, 5, 'Selas - World Loot Level 75'), +(27580, 33470, 1270002, 25, 0, 'Selas - Frostweave Cloth Elite'), +(27645, 1, 1200279, 0, 5, 'Phantasmal Cloudscraper - World Loot Level 79'), +(27647, 1, 1200279, 0, 5, 'Phantasmal Ogre - World Loot Level 79'), +(27732, 1, 1200280, 0, 5, 'Master Necromancer - World Loot Level 80'), +(27743, 1, 1200279, 0, 5, 'Infinite Hunter - World Loot Level 79'), +(27743, 2, 1200280, 0, 5, 'Infinite Hunter - World Loot Level 80'), +(27744, 1, 1200279, 0, 5, 'Infinite Agent - World Loot Level 79'), +(27744, 2, 1200280, 0, 5, 'Infinite Agent - World Loot Level 80'), +(27859, 1, 1200372, 0, 5, 'Vanthryn the Merciless - World Loot Level 72'), +(27859, 33470, 1270002, 25, 0, 'Vanthryn the Merciless - Frostweave Cloth Elite'), +(27860, 1, 1200272, 0, 5, 'Luthion the Vile - World Loot Level 72'), +(28068, 1, 1200376, 0, 5, 'Prophet of Sseratus - World Loot Level 76'), +(28068, 33470, 1270002, 25, 0, 'Prophet of Sseratus - Frostweave Cloth Elite'), +(28199, 1, 1200279, 0, 5, 'Tomb Stalker - World Loot Level 79'), +(28199, 2, 1200280, 0, 5, 'Tomb Stalker - World Loot Level 80'), +(28200, 1, 1200279, 0, 5, 'Dark Necromancer - World Loot Level 79'), +(28200, 2, 1200280, 0, 5, 'Dark Necromancer - World Loot Level 80'), +(28255, 1, 1200376, 0, 5, 'Malas the Corrupter - World Loot Level 76'), +(28255, 33470, 1270002, 25, 0, 'Malas the Corrupter - Frostweave Cloth Elite'), +(28399, 1, 1200077, 0, 5, 'Zeptek the Destroyer - World Loot Level 77'), +(28443, 1, 1200277, 0, 5, 'Thalgran Blightbringer - World Loot Level 77'), +(28467, 1, 1200277, 0, 5, 'Broodmother Slivina - World Loot Level 77'), +(28477, 1, 1200276, 0, 5, 'Scion of Quetz\'lun - World Loot Level 76'), +(28477, 2, 1200277, 0, 5, 'Scion of Quetz\'lun - World Loot Level 77'), +(28597, 1, 1200276, 0, 5, 'Guardian of Zim\'Rhuk - World Loot Level 76'), +(28597, 2, 1200277, 0, 5, 'Guardian of Zim\'Rhuk - World Loot Level 77'), +(28659, 1, 1200277, 0, 5, 'Artruis the Heartless - World Loot Level 77'), +(28784, 1, 1200276, 0, 5, 'Altar Warden - World Loot Level 76'), +(28784, 2, 1200277, 0, 5, 'Altar Warden - World Loot Level 77'), +(28793, 1, 1200276, 0, 5, 'Darmuk - World Loot Level 76'), +(29026, 1, 1200076, 0, 5, 'Kolramas Slime - World Loot Level 76'), +(29375, 1, 1200380, 0, 5, 'Stormforged Iron Giant - World Loot Level 80'), +(29375, 33470, 1270002, 25, 0, 'Stormforged Iron Giant - Frostweave Cloth Elite'), +(29503, 1, 1200379, 0, 5, 'Fjorn - World Loot Level 79'), +(29503, 2, 1200380, 0, 5, 'Fjorn - World Loot Level 80'), +(29503, 33470, 1270002, 25, 0, 'Fjorn - Frostweave Cloth Elite'), +(29614, 1, 1200379, 0, 5, 'Onslaught Darkweaver - World Loot Level 79'), +(29614, 2, 1200380, 0, 5, 'Onslaught Darkweaver - World Loot Level 80'), +(29614, 33470, 1270002, 25, 0, 'Onslaught Darkweaver - Frostweave Cloth Elite'), +(29664, 1, 1200275, 0, 5, 'Ragemane - World Loot Level 75'), +(29696, 1, 1200079, 0, 5, 'Stormforged Pursuer - World Loot Level 79'), +(29696, 2, 1200080, 0, 5, 'Stormforged Pursuer - World Loot Level 80'), +(29710, 1, 1200078, 0, 5, 'Onslaught Destrier - World Loot Level 78'), +(29710, 2, 1200079, 0, 5, 'Onslaught Destrier - World Loot Level 79'), +(29836, 1, 1200377, 0, 5, 'Drakkari Battle Rider - World Loot Level 77'), +(29836, 33470, 1270002, 25, 0, 'Drakkari Battle Rider - Frostweave Cloth Elite'), +(30829, 1, 1200279, 0, 5, 'Salranax the Flesh Render - World Loot Level 79'), +(30830, 1, 1200279, 0, 5, 'Underking Talonox - World Loot Level 79'), +(30831, 1, 1200379, 0, 5, 'High Priest Yath\'amon - World Loot Level 79'), +(30831, 33470, 1270002, 25, 0, 'High Priest Yath\'amon - Frostweave Cloth Elite'), +(30861, 1, 1200280, 0, 5, 'Unbound Ancient - World Loot Level 80'), +(30892, 1, 1200276, 0, 5, 'Portal Guardian - World Loot Level 76'), +(30925, 1, 1200380, 0, 5, 'Drakkari Battle Rider (1) - World Loot Level 80'), +(30925, 2, 1200381, 0, 5, 'Drakkari Battle Rider (1) - World Loot Level 81'), +(30925, 33470, 1270002, 25, 0, 'Drakkari Battle Rider (1) - Frostweave Cloth Elite'), +(30954, 1, 1200280, 0, 5, 'Rokir - World Loot Level 80'), +(31040, 1, 1200077, 0, 5, 'Wrathstrike Gargoyle - World Loot Level 77'), +(31040, 2, 1200078, 0, 5, 'Wrathstrike Gargoyle - World Loot Level 78'), +(31139, 1, 1200381, 0, 5, 'Pustulent Horror - World Loot Level 81'), +(31139, 2, 1200382, 0, 5, 'Pustulent Horror - World Loot Level 82'), +(31139, 33470, 1270002, 25, 0, 'Pustulent Horror - Frostweave Cloth Elite'), +(31180, 1, 1200280, 0, 5, 'Master Necromancer (1) - World Loot Level 80'), +(31184, 1, 1200280, 0, 5, 'Dark Necromancer (1) - World Loot Level 80'), +(31188, 1, 1200280, 0, 5, 'Tomb Stalker (1) - World Loot Level 80'), +(31198, 1, 1200282, 0, 5, 'Coprous the Defiled - World Loot Level 82'), +(31203, 1, 1200280, 0, 5, 'Infinite Agent (1) - World Loot Level 80'), +(31206, 1, 1200280, 0, 5, 'Infinite Hunter (1) - World Loot Level 80'), +(31229, 1, 1200280, 0, 5, 'Ancient Watcher - World Loot Level 80'), +(31255, 1, 1200280, 0, 5, 'Saronite Shaper - World Loot Level 80'), +(31399, 1, 1200380, 0, 5, 'Foreman Thaldrin - World Loot Level 80'), +(31399, 33470, 1270002, 25, 0, 'Foreman Thaldrin - Frostweave Cloth Elite'), +(31502, 1, 1200281, 0, 5, 'Portal Guardian (1) - World Loot Level 81'), +(31693, 1, 1200179, 0, 5, 'Stormforged Saboteur - World Loot Level 79'), +(31693, 2, 1200180, 0, 5, 'Stormforged Saboteur - World Loot Level 80'), +(31693, 33470, 1270001, 25, 0, 'Stormforged Saboteur - Frostweave Cloth Normal'), +(32181, 1, 1200080, 0, 5, 'Living Plague - World Loot Level 80'), +(32278, 1, 1200380, 0, 5, 'Harbinger of Horror - World Loot Level 80'), +(32278, 33470, 1270002, 25, 0, 'Harbinger of Horror - Frostweave Cloth Elite'), +(32353, 1, 1200380, 0, 5, 'Archavon Warder - World Loot Level 80'), +(32353, 33470, 1270002, 25, 0, 'Archavon Warder - Frostweave Cloth Elite'), +(32770, 1, 1200280, 0, 5, 'Enraged Fleshrender - World Loot Level 80'), +(32772, 1, 1200280, 0, 5, 'Skeletal Footsoldier - World Loot Level 80'), +(40419, 1, 1200282, 0, 5, 'Charscale Assaulter - World Loot Level 82'); + +-- Loose Items +DELETE FROM `creature_loot_template` +WHERE `Item` IN (33358,33359,33360,33361,33362,33363,33364,33372,33373,33374,33375,33376,33377,33378,33390,33391,33392,33393,33394,33395,33396,33404,33405,33406,33407,33408,33409,33410,33422,33423,33424,33425,33426,33427,33428,33429,33430,33431,33437,33438,33439,33440,33365,33366,33367,33368,33369,33370,33371,33379,33380,33381,33382,33383,33384,33385,33397,33398,33399,33400,33401,33402,33403,33412,33413,33414,33415,33416,33417,33419,33433,33434,33435,33436,35955,35956,35957,35958,35959,35960,35961,35962,36067,36068,36069,36070,36071,36072,36073,36074,36179,36180,36181,36182,36183,36184,36185,36186,36291,36292,36293,36294,36295,36296,36297,36298,36403,36417,36431,36445,36459,36473,36487,36501,36515,36529,36543,36557,36571,36585,36599,36613,36627,36641,36655,36669,36683,36697,36711,35963,35964,35965,35966,35967,35968,35969,35970,36075,36076,36077,36078,36079,36080,36081,36082,36187,36188,36189,36190,36191,36192,36193,36194,36299,36300,36301,36302,36303,36304,36305,36306,36404,36418,36432,36446,36460,36474,36488,36502,36516,36530,36544,36558,36572,36586,36600,36614,36628,36642,36656,36670,36684,36698,36712,35971,35972,35973,35974,35975,35976,35977,35978,36083,36084,36085,36086,36087,36088,36089,36090,36195,36196,36197,36198,36199,36200,36201,36202,36307,36308,36309,36310,36311,36312,36313,36314,36405,36419,36433,36447,36461,36475,36489,36503,36517,36531,36545,36559,36573,36587,36601,36615,36629,36643,36657,36671,36685,36699,36713,35979,35980,35981,35982,35983,35984,35985,35986,36091,36092,36093,36094,36095,36096,36097,36098,36203,36204,36205,36206,36207,36208,36209,36210,36315,36316,36317,36318,36319,36320,36321,36322,36406,36420,36434,36448,36462,36476,36490,36504,36518,36532,36546,36560,36574,36588,36602,36616,36630,36644,36658,36672,36686,36700,36714,35987,35988,35989,35990,35991,35992,35993,35994,36099,36100,36101,36102,36103,36104,36105,36106,36211,36212,36213,36214,36215,36216,36217,36218,36323,36324,36325,36326,36327,36328,36329,36330,36407,36421,36435,36449,36463,35995,35996,35997,35998,35999,36000,36001,36002,36107,36108,36109,36110,36111,36112,36113,36114,36219,36220,36221,36222,36223,36224,36225,36226,36331,36332,36333,36334,36335,36336,36337,36338,36408,36422,36436,36450,36464,36478,36492,36506,36520,36534,36548,36562,36576,36590,36604,36618,36632,36646,36660,36674,36688,36702,36716,36003,36004,36005,36006,36007,36008,36009,36010,36115,36116,36117,36118,36119,36120,36121,36122,36227,36228,36229,36230,36231,36232,36233,36234,36339,36340,36341,36342,36343,36344,36345,36346,36409,36423,36437,36451,36465,36479,36493,36507,36521,36535,36549,36563,36577,36591,36605,36619,36633,36647,36661,36675,36689,36703,36717,36011,36012,36013,36014,36015,36016,36017,36018,36123,36124,36125,36126,36127,36128,36129,36130,36235,36236,36237,36238,36239,36240,36241,36242,36347,36348,36349,36350,36351,36352,36353,36354,36410,36424,36438,36452,36466,36480,36494,36508,36522,36536,36550,36564,36578,36592,36606,36620,36634,36648,36662,36676,36690,36704,36718,36019,36020,36021,36022,36023,36024,36025,36026,36131,36132,36133,36134,36135,36136,36137,36138,36243,36244,36245,36246,36247,36248,36249,36250,36355,36356,36357,36358,36359,36360,36361,36362,36411,36425,36439,36453,36467,36481,36495,36509,36523,36537,36551,36565,36579,36593,36607,36621,36635,36649,36663,36677,36691,36705,36719,36027,36028,36029,36030,36031,36032,36033,36034,36139,36140,36141,36142,36143,36144,36145,36146,36251,36252,36253,36254,36255,36256,36257,36258,36363,36364,36365,36366,36367,36368,36369,36370,36412,36426,36440,36468,36482,36496,36510,36524,36538,36552,36566,36580,36594,36608,36622,36636,36650,36664,36678,36692,36706,36720,36035,36036,36037,36038,36039,36040,36041,36042,36147,36148,36149,36150,36151,36152,36153,36154,36259,36260,36261,36262,36263,36264,36265,36266,36371,36372,36373,36374,36375,36376,36377,36378,36413,36427,36441,36455,36469,36483,36497,36511,36525,36539,36553,36567,36581,36595,36609,36623,36637,36651,36665,36679,36693,36707,36721,36043,36044,36045,36046,36047,36048,36049,36050,36155,36156,36157,36158,36159,36160,36161,36162,36267,36268,36269,36270,36271,36272,36273,36274,36379,36380,36381,36382,36383,36384,36385,36386,36414,36428,36442,36456,36470,36484,36498,36512,36526,36540,36554,36568,36582,36596,36610,36624,36638,36652,36666,36680,36694,36708,36722,36051,36052,36053,36054,36055,36056,36057,36058,36163,36164,36165,36166,36167,36168,36169,36170,36275,36276,36277,36278,36279,36280,36281,36282,36387,36388,36389,36390,36391,36392,36393,36394,36415,36429,36443,36457,36471,36485,36499,36513,36527,36541,36555,36569,36583,36597,36611,36625,36639,36653,36667,36681,36695,36709,36723,36059,36060,36061,36062,36063,36064,36065,36066,36171,36172,36173,36174,36175,36176,36177,36178,36283,36284,36285,36286,36287,36288,36289,36290,36395,36396,36397,36398,36399,36400,36401,36402,36416,36430,36444,36458,36472,36486,36500,36514,36528,36542,36556,36570,36584,36598,36612,36626,36640,36654,36668,36682,36696,36710,36724,37743,37744,37745,37746,37747,37748,37749,37751,37752,37762,37772,37782,37753,37763,37773,37783,37803,37819,37754,37764,37774,37795,37796,37820,37755,37775,37785,37802,37811,37817,37756,37765,37776,37786,37807,37821,37757,37766,37777,37787,37805,37813,37758,37767,37778,37789,37804,37810,37812,37759,37768,37790,37806,37808,37809,37769,37779,37792,37797,37823,37760,37770,37780,37793,37822,37761,37771,37781,37794,37824,37254,37835,43573,44308,44309,44310,44311,44312,44313,22829,22832,37091,37093,37097,43463,43465,43467,33447,33448,43507,43508,43509,43510,43622,43876,39152,41777,41778,41779,41780,41781,41782,41783,41784,41785,41786,41787,41788,41789,42172,42173,42175,42176,42177,42178,43297,43624,45912,33470) +AND `Entry` IN (24398,24400,31693,24201,24238,24469,25301,25601,25789,25801,25804,26578,26828,26836,27006,27007,27008,27009,27122,27210,27247,27334,27579,27580,27859,28068,28255,29375,29503,29614,29836,30831,30925,31139,31399,32278,32353,24440,25228,25234,25488,28399,29026,29696,29710,31040,32181,23725,23993,24329,24371,24547,24900,24914,25618,26287,26291,26293,26333,26360,26406,26417,26633,26838,26841,26858,27002,27018,27105,27249,27383,27578,27645,27647,27732,27743,27744,27860,28199,28200,28443,28467,28477,28597,28659,28784,28793,29664,30829,30830,30861,30892,30954,31180,31184,31188,31198,31203,31206,31229,31255,31502,32770,32772,40419) AND `Reference` = 0; +-- Delete Legacy References +DELETE FROM `creature_loot_template` WHERE +`Entry` IN (24398,24400,31693,24201,24238,24469,25301,25601,25789,25801,25804,26578,26828,26836,27006,27007,27008,27009,27122,27210,27247,27334,27579,27580,27859,28068,28255,29375,29503,29614,29836,30831,30925,31139,31399,32278,32353,24440,25228,25234,25488,28399,29026,29696,29710,31040,32181,23725,23993,24329,24371,24547,24900,24914,25618,26287,26291,26293,26333,26360,26406,26417,26633,26838,26841,26858,27002,27018,27105,27249,27383,27578,27645,27647,27732,27743,27744,27860,28199,28200,28443,28467,28477,28597,28659,28784,28793,29664,30829,30830,30861,30892,30954,31180,31184,31188,31198,31203,31206,31229,31255,31502,32770,32772,40419) +AND `Reference` IN (26001,26040,26000,24727,26002,26008,26007,26009,26006,26005,26010,26014,26013,26015,26012,26004,26011,26003,26018,26020,26021,26028,26019,26022,26023,26024,26016,26017,26025); + +-- Removes Frostweave Cloth from a boss' Reference +DELETE FROM `reference_loot_template` WHERE (`Entry` = 35045) AND (`Item` IN (33470)); + +DELETE FROM `reference_loot_template` WHERE (`Entry` IN (1200369,1200275,1200282,1200382)); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(1200369, 1, 1206874, 10, 0, 1, 0, 1, 1, 'WotLK Greys 68-74 Level Range'), +(1200369, 2, 1226870, 5, 0, 1, 1, 1, 1, 'WotLK Greens 68-70 Level Range'), +(1200369, 3, 1226971, 5, 0, 1, 1, 1, 1, 'WotLK Greens 69-71 Level Range'), +(1200369, 4, 1236871, 0.1, 0, 1, 0, 1, 1, 'WotLK Blues 68-71 Level Range'), +(1200369, 5, 1266870, 100, 0, 1, 0, 1, 1, 'WotLK Profession Drops 68-70 Level Range'), +(1200369, 6, 1256875, 3, 0, 1, 0, 1, 1, 'WotLK Potions 68-75 Level Range'), +(1200369, 7, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'), + +(1200275, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200275, 2, 1227375, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 73-75 Level Range'), +(1200275, 3, 1227476, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 74-76 Level Range'), +(1200275, 4, 1227577, 3.33, 0, 1, 1, 1, 1, 'WotLK Greens 75-77 Level Range'), +(1200275, 5, 1237375, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 73-75 Level Range'), +(1200275, 6, 1237476, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 74-76 Level Range'), +(1200275, 7, 1237577, 0.033, 0, 1, 2, 1, 1, 'WotLK Blues 75-77 Level Range'), +(1200275, 8, 1267579, 100, 0, 1, 0, 1, 1, 'WotLK Profession Drops 75-79 Level Range'), + +(1200282, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200282, 2, 1228082, 5, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +(1200282, 3, 1228183, 5, 0, 1, 1, 1, 1, 'WotLK Greens 81-83 Level Range'), +(1200282, 4, 1238083, 0.1, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +(1200282, 5, 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +(1200282, 6, 1268083, 100, 0, 1, 0, 1, 1, 'WotLK Profession Drops 80+ Level Range'), + +(1200382, 1, 1207583, 10, 0, 1, 0, 1, 1, 'WotLK Greys 75+ Level Range'), +(1200382, 2, 1228082, 5, 0, 1, 1, 1, 1, 'WotLK Greens 80-82 Level Range'), +(1200382, 3, 1228183, 5, 0, 1, 1, 1, 1, 'WotLK Greens 81-83 Level Range'), +(1200382, 4, 1238083, 0.1, 0, 1, 2, 1, 1, 'WotLK Blues 80-83 Level Range'), +(1200382, 5, 1248083, 0.01, 0, 1, 0, 1, 1, 'WotLK Purples 80+ Level Range'), +(1200382, 6, 1268083, 100, 0, 1, 0, 1, 1, 'WotLK Profession Drops 80+ Level Range'), +(1200382, 7, 1257683, 3, 0, 1, 0, 1, 1, 'WotLK Potions 76-83 Level Range'), +(1200382, 8, 1256883, 1, 0, 1, 0, 1, 1, 'WotLK Scrolls'); + +DELETE FROM `reference_loot_template` WHERE `Entry` IN (26000,26001,26009,26011,26016,26017,26018,26019,26020,26021,26022,26023,26024,26025,26028); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 1 AND `SourceGroup` IN (24398,24400,31693,24201,24238,24469,25301,25601,25789,25801,25804,26578,26828,26836,27006,27007,27008,27009,27122,27210,27247,27334,27579,27580,27859,28068,28255,29375,29503,29614,29836,30831,30925,31139,31399,32278,32353,24440,25228,25234,25488,28399,29026,29696,29710,31040,32181,23725,23993,24329,24371,24547,24900,24914,25618,26287,26291,26293,26333,26360,26406,26417,26633,26838,26841,26858,27002,27018,27105,27249,27383,27578,27645,27647,27732,27743,27744,27860,28199,28200,28443,28467,28477,28597,28659,28784,28793,29664,30829,30830,30861,30892,30954,31180,31184,31188,31198,31203,31206,31229,31255,31502,32770,32772,40419) +AND `SourceEntry` IN ( +39152, -- Manual: Heavy Frostweave Bandage +42172, -- Pattern: Red Lumberjack Shirt +42173, -- Pattern: Blue Lumberjack Shirt +42175, -- Pattern: Green Lumberjack Shirt +42177, -- Pattern: Red Workman's Shirt +42178, -- Pattern: Rustic Workman's Shirt +43507, -- Recipe: Tasty Cupcake +43508, -- Recipe: Last Week's Mammoth +43509, -- Recipe: Bad Clams +43510 -- Recipe: Haunted Herring +); + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 1) AND (`SourceGroup` = 26863) AND (`SourceEntry` = 43510) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 7) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 185) AND (`ConditionValue2` = 1) AND (`ConditionValue3` = 0); From 80947bf4098ba9cdcd81ef7df9f1728a6fd45d4c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Feb 2026 02:27:51 +0000 Subject: [PATCH 237/335] chore(DB): import pending files Referenced commit(s): 0faf08c2602023d24348bae938a8cef19463f3b5 --- .../rev_1771805490746014200.sql => db_world/2026_02_23_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771805490746014200.sql => db_world/2026_02_23_04.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771805490746014200.sql b/data/sql/updates/db_world/2026_02_23_04.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771805490746014200.sql rename to data/sql/updates/db_world/2026_02_23_04.sql index d2a785586..974b48c7f 100644 --- a/data/sql/updates/pending_db_world/rev_1771805490746014200.sql +++ b/data/sql/updates/db_world/2026_02_23_04.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_23_03 -> 2026_02_23_04 -- DELETE FROM `creature_loot_template` WHERE `Entry` IN (24291, 23776, 24104, 26862, 26863, 29885, 27821, 26290, 30492); UPDATE `creature_template` SET `lootid` = 0 WHERE `Entry` IN (24291, 23776, 24104, 26862, 26863, 29885, 27821, 26290, 30492); From 2d8a1135020b65875f754a5718e5775237d49857 Mon Sep 17 00:00:00 2001 From: Rocco Silipo <108557877+Rorschach91@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:56:36 +0100 Subject: [PATCH 238/335] fix (DB/Condition): Remove pre-requisites for Playing Along quest. (#24825) Co-authored-by: Gultask <100873791+Gultask@users.noreply.github.com> --- data/sql/updates/pending_db_world/Playing_Along.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/Playing_Along.sql diff --git a/data/sql/updates/pending_db_world/Playing_Along.sql b/data/sql/updates/pending_db_world/Playing_Along.sql new file mode 100644 index 000000000..f24dcc253 --- /dev/null +++ b/data/sql/updates/pending_db_world/Playing_Along.sql @@ -0,0 +1,2 @@ +-- Remove conditions +DELETE FROM `conditions` WHERE `SourceEntry` = 12528 AND `SourceTypeOrReferenceId` = 19 AND `ConditionValue1` = 12654; From 57119764a796fbdb1022c91c1f3a89fe4aa565d2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Feb 2026 11:57:39 +0000 Subject: [PATCH 239/335] chore(DB): import pending files Referenced commit(s): 2d8a1135020b65875f754a5718e5775237d49857 --- .../Playing_Along.sql => db_world/2026_02_23_05.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/Playing_Along.sql => db_world/2026_02_23_05.sql} (76%) diff --git a/data/sql/updates/pending_db_world/Playing_Along.sql b/data/sql/updates/db_world/2026_02_23_05.sql similarity index 76% rename from data/sql/updates/pending_db_world/Playing_Along.sql rename to data/sql/updates/db_world/2026_02_23_05.sql index f24dcc253..5208a64c9 100644 --- a/data/sql/updates/pending_db_world/Playing_Along.sql +++ b/data/sql/updates/db_world/2026_02_23_05.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_23_04 -> 2026_02_23_05 -- Remove conditions DELETE FROM `conditions` WHERE `SourceEntry` = 12528 AND `SourceTypeOrReferenceId` = 19 AND `ConditionValue1` = 12654; From 4277ac0b262b229bf798339c77b1254aedfabf1b Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:37:37 -0600 Subject: [PATCH 240/335] fix(Core/Spells): Fix Rapid Recuperation, Rapid Killing, and auto-generate PROC_ATTR_REQ_SPELLMOD (#24830) Co-authored-by: blinkysc --- .../rev_1771855011429365338.sql | 9 ++ .../game/Spells/Auras/SpellAuraEffects.cpp | 6 - src/server/game/Spells/SpellMgr.cpp | 14 ++ src/server/scripts/Spells/spell_hunter.cpp | 49 ++---- .../game/Spells/SpellProcAttributeTest.cpp | 146 ++++++++++++++++++ 5 files changed, 183 insertions(+), 41 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771855011429365338.sql diff --git a/data/sql/updates/pending_db_world/rev_1771855011429365338.sql b/data/sql/updates/pending_db_world/rev_1771855011429365338.sql new file mode 100644 index 000000000..4d22aeed6 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771855011429365338.sql @@ -0,0 +1,9 @@ +-- Fix spell_script_names for spell_hun_rapid_recuperation +-- Script was moved from talent (53228/53232) to periodic mana aura (56654/58882) +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_hun_rapid_recuperation'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(56654, 'spell_hun_rapid_recuperation'), +(58882, 'spell_hun_rapid_recuperation'); + +-- Remove explicit Inner Focus spell_proc entry (now auto-generated with PROC_ATTR_REQ_SPELLMOD) +DELETE FROM `spell_proc` WHERE `SpellId` = 14751; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 77250413f..1b793832b 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -6563,12 +6563,6 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) caster->CastSpell(target, triggerSpellId, false); return; } - // Hunter - Rapid Recuperation - case 56654: - case 58882: - int32 amount = int32(target->GetMaxPower(POWER_MANA) * GetAmount() / 100.0f); - target->CastCustomSpell(target, triggerSpellId, &amount, nullptr, nullptr, true, nullptr, this); - return; } } diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 5751e7fec..a179c1963 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2073,6 +2073,20 @@ void SpellMgr::LoadSpellProcs() if (addTriggerFlag) procEntry.AttributesMask |= PROC_ATTR_TRIGGERED_CAN_PROC; + // Modifier auras with charges should require spellmod validation + if (spellInfo->ProcCharges) + { + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_FLAT_MODIFIER) || + spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_PCT_MODIFIER)) + { + procEntry.AttributesMask |= PROC_ATTR_REQ_SPELLMOD; + break; + } + } + } + // Calculate DisableEffectsMask for effects that shouldn't trigger procs uint32 nonProcMask = 0; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index da98fe256..8a10dede6 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -73,8 +73,6 @@ enum HunterSpells // Proc system spells SPELL_HUNTER_THRILL_OF_THE_HUNT_MANA = 34720, SPELL_HUNTER_REPLENISHMENT = 57669, - SPELL_HUNTER_RAPID_RECUPERATION_R1 = 56654, - SPELL_HUNTER_RAPID_RECUPERATION_R2 = 58882, SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS = 57894, SPELL_HUNTER_KILL_COMMAND_HUNTER = 34027, SPELL_HUNTER_RAPID_RECUPERATION_MANA_R1 = 56654, @@ -1403,48 +1401,29 @@ class spell_hun_hunting_party : public AuraScript } }; -// -53228 - Rapid Recuperation +// 56654, 58882 - Rapid Recuperation class spell_hun_rapid_recuperation : public AuraScript { PrepareAuraScript(spell_hun_rapid_recuperation); - bool Validate(SpellInfo const* /*spellInfo*/) override + bool Validate(SpellInfo const* spellInfo) override { - return ValidateSpellInfo({ SPELL_HUNTER_RAPID_RECUPERATION_R1, SPELL_HUNTER_RAPID_RECUPERATION_R2 }); + return ValidateSpellInfo({ spellInfo->Effects[EFFECT_0].TriggerSpell }); } - bool CheckProc(ProcEventInfo& eventInfo) - { - SpellInfo const* procSpell = eventInfo.GetSpellInfo(); - if (!procSpell) - return false; - - // This effect only from Rapid Killing (mana regen) - return (procSpell->SpellFamilyFlags[1] & 0x01000000) != 0; - } - - void HandleProc(ProcEventInfo& /*eventInfo*/) + void HandlePeriodic(AuraEffect const* aurEff) { PreventDefaultAction(); - uint32 triggeredSpell = 0; - switch (GetSpellInfo()->Id) - { - case 53228: // Rank 1 - triggeredSpell = SPELL_HUNTER_RAPID_RECUPERATION_R1; - break; - case 53232: // Rank 2 - triggeredSpell = SPELL_HUNTER_RAPID_RECUPERATION_R2; - break; - default: - return; - } - GetTarget()->CastSpell(GetTarget(), triggeredSpell, true); + + Unit* target = GetTarget(); + uint32 triggerSpellId = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; + int32 amount = CalculatePct(static_cast(target->GetMaxPower(POWER_MANA)), aurEff->GetAmount()); + target->CastCustomSpell(target, triggerSpellId, &amount, nullptr, nullptr, true, nullptr, aurEff); } void Register() override { - DoCheckProc += AuraCheckProcFn(spell_hun_rapid_recuperation::CheckProc); - OnProc += AuraProcFn(spell_hun_rapid_recuperation::HandleProc); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_hun_rapid_recuperation::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); } }; @@ -1522,7 +1501,7 @@ class spell_hun_kill_command_pet : public AuraScript } }; -// -53228 - Rapid Recuperation (trigger) +// -53228 - Rapid Recuperation (talent aura) class spell_hun_rapid_recuperation_trigger : public AuraScript { PrepareAuraScript(spell_hun_rapid_recuperation_trigger); @@ -1559,8 +1538,8 @@ class spell_hun_rapid_recuperation_trigger : public AuraScript return; uint8 rank = GetSpellInfo()->GetRank(); - if (rank > 0 && rank <= 2) - GetTarget()->CastSpell(GetTarget(), triggerSpells[rank - 1], true, nullptr, aurEff); + uint32 spellId = triggerSpells[rank - 1]; + eventInfo.GetActor()->CastSpell(eventInfo.GetActor(), spellId, true, nullptr, aurEff); } void Register() override @@ -1676,9 +1655,9 @@ void AddSC_hunter_spell_scripts() RegisterSpellScript(spell_hun_explosive_shot); RegisterSpellScript(spell_hun_thrill_of_the_hunt); RegisterSpellScript(spell_hun_hunting_party); - RegisterSpellScript(spell_hun_rapid_recuperation); RegisterSpellScript(spell_hun_glyph_of_mend_pet); // Proc system scripts + RegisterSpellScript(spell_hun_rapid_recuperation); RegisterSpellScript(spell_hun_kill_command_pet); RegisterSpellScript(spell_hun_piercing_shots); RegisterSpellScript(spell_hun_rapid_recuperation_trigger); diff --git a/src/test/server/game/Spells/SpellProcAttributeTest.cpp b/src/test/server/game/Spells/SpellProcAttributeTest.cpp index 536c105d8..1b6609881 100644 --- a/src/test/server/game/Spells/SpellProcAttributeTest.cpp +++ b/src/test/server/game/Spells/SpellProcAttributeTest.cpp @@ -31,6 +31,7 @@ #include "ProcChanceTestHelper.h" #include "ProcEventInfoHelper.h" +#include "SpellInfoTestHelper.h" #include "AuraStub.h" #include "UnitStub.h" #include "gtest/gtest.h" @@ -135,6 +136,151 @@ TEST_F(SpellProcAttributeTest, ReqSpellmod_AttributeNotSet) EXPECT_FALSE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD); } +// ============================================================================= +// PROC_ATTR_REQ_SPELLMOD Auto-Generation Tests +// Validates that LoadSpellProcs auto-generates REQ_SPELLMOD for modifier +// auras with charges, preventing charge consumption by unrelated spells. +// ============================================================================= + +namespace +{ + // Replicates the auto-generation logic from SpellMgr::LoadSpellProcs + void ApplyAutoGeneratedSpellmodFlag(SpellInfo const* spellInfo, SpellProcEntry& procEntry) + { + if (spellInfo->ProcCharges) + { + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_FLAT_MODIFIER) || + spellInfo->Effects[i].IsAura(SPELL_AURA_ADD_PCT_MODIFIER)) + { + procEntry.AttributesMask |= PROC_ATTR_REQ_SPELLMOD; + break; + } + } + } + } +} + +TEST_F(SpellProcAttributeTest, ReqSpellmod_AutoGen_PctModifierWithCharges) +{ + // Rapid Killing (35099): ADD_PCT_MODIFIER + 1 charge + auto spellInfo = SpellInfoBuilder() + .WithId(35099) + .WithEffect(0, SPELL_EFFECT_APPLY_AURA, SPELL_AURA_ADD_PCT_MODIFIER) + .WithProcFlags(PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS) + .WithProcCharges(1) + .BuildUnique(); + + SpellProcEntry procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS) + .WithCharges(1) + .WithChance(100.0f) + .Build(); + + ApplyAutoGeneratedSpellmodFlag(spellInfo.get(), procEntry); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD); +} + +TEST_F(SpellProcAttributeTest, ReqSpellmod_AutoGen_FlatModifierWithCharges) +{ + // Clearcasting-like: ADD_FLAT_MODIFIER + charges + auto spellInfo = SpellInfoBuilder() + .WithId(12345) + .WithEffect(0, SPELL_EFFECT_APPLY_AURA, SPELL_AURA_ADD_FLAT_MODIFIER) + .WithProcCharges(2) + .BuildUnique(); + + SpellProcEntry procEntry = SpellProcEntryBuilder() + .WithCharges(2) + .WithChance(100.0f) + .Build(); + + ApplyAutoGeneratedSpellmodFlag(spellInfo.get(), procEntry); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD); +} + +TEST_F(SpellProcAttributeTest, ReqSpellmod_AutoGen_NoCharges_NotSet) +{ + // Modifier aura without charges should NOT get the flag + auto spellInfo = SpellInfoBuilder() + .WithId(12345) + .WithEffect(0, SPELL_EFFECT_APPLY_AURA, SPELL_AURA_ADD_PCT_MODIFIER) + .WithProcCharges(0) + .BuildUnique(); + + SpellProcEntry procEntry = SpellProcEntryBuilder() + .WithCharges(0) + .WithChance(100.0f) + .Build(); + + ApplyAutoGeneratedSpellmodFlag(spellInfo.get(), procEntry); + + EXPECT_FALSE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD); +} + +TEST_F(SpellProcAttributeTest, ReqSpellmod_AutoGen_NonModifierWithCharges_NotSet) +{ + // Non-modifier aura with charges should NOT get the flag + auto spellInfo = SpellInfoBuilder() + .WithId(12345) + .WithEffect(0, SPELL_EFFECT_APPLY_AURA, SPELL_AURA_PROC_TRIGGER_SPELL) + .WithProcCharges(1) + .BuildUnique(); + + SpellProcEntry procEntry = SpellProcEntryBuilder() + .WithCharges(1) + .WithChance(100.0f) + .Build(); + + ApplyAutoGeneratedSpellmodFlag(spellInfo.get(), procEntry); + + EXPECT_FALSE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD); +} + +TEST_F(SpellProcAttributeTest, ReqSpellmod_AutoGen_ModifierOnSecondEffect) +{ + // Modifier on effect index 1, not 0 + auto spellInfo = SpellInfoBuilder() + .WithId(12345) + .WithEffect(0, SPELL_EFFECT_APPLY_AURA, SPELL_AURA_PROC_TRIGGER_SPELL) + .WithEffect(1, SPELL_EFFECT_APPLY_AURA, SPELL_AURA_ADD_FLAT_MODIFIER) + .WithProcCharges(1) + .BuildUnique(); + + SpellProcEntry procEntry = SpellProcEntryBuilder() + .WithCharges(1) + .WithChance(100.0f) + .Build(); + + ApplyAutoGeneratedSpellmodFlag(spellInfo.get(), procEntry); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD); +} + +TEST_F(SpellProcAttributeTest, ReqSpellmod_AutoGen_PreservesExistingAttributes) +{ + // Should OR with existing attributes, not replace + auto spellInfo = SpellInfoBuilder() + .WithId(12345) + .WithEffect(0, SPELL_EFFECT_APPLY_AURA, SPELL_AURA_ADD_PCT_MODIFIER) + .WithProcCharges(1) + .BuildUnique(); + + SpellProcEntry procEntry = SpellProcEntryBuilder() + .WithCharges(1) + .WithChance(100.0f) + .WithAttributesMask(PROC_ATTR_TRIGGERED_CAN_PROC) + .Build(); + + ApplyAutoGeneratedSpellmodFlag(spellInfo.get(), procEntry); + + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD); + EXPECT_TRUE(procEntry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC); +} + // ============================================================================= // PROC_ATTR_USE_STACKS_FOR_CHARGES (0x10) Tests // ============================================================================= From d0f4ef26b797ac486eefaf1db7148cd8cbb38b78 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:38:17 -0600 Subject: [PATCH 241/335] chore(Core/Spells): Remove duplicate seed of corruption spellscript (#24831) Co-authored-by: blinkysc --- .../rev_1771866173424640746.sql | 1 + src/server/scripts/Spells/spell_warlock.cpp | 123 ------------------ 2 files changed, 1 insertion(+), 123 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1771866173424640746.sql diff --git a/data/sql/updates/pending_db_world/rev_1771866173424640746.sql b/data/sql/updates/pending_db_world/rev_1771866173424640746.sql new file mode 100644 index 000000000..6a6809be8 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771866173424640746.sql @@ -0,0 +1 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_warl_seed_of_corruption_aura', 'spell_warl_seed_of_corruption_generic_aura'); diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index f424f242f..95c2929a3 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -63,12 +63,8 @@ enum WarlockSpells SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2 = 60956, SPELL_WARLOCK_LIFE_TAP_ENERGIZE = 31818, SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2 = 32553, - SPELL_WARLOCK_SEED_OF_CORRUPTION_R1 = 27243, SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R1 = 27285, - SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R2 = 47833, - SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R3 = 47834, SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_GENERIC = 32865, - SPELL_WARLOCK_SEED_OF_CORRUPTION_VISUAL = 37826, SPELL_WARLOCK_SOULSHATTER = 32835, SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117, @@ -742,123 +738,6 @@ class spell_warl_seed_of_corruption_damage : public SpellScript } }; -// -27243 - Seed of Corruption -class spell_warl_seed_of_corruption_aura: public AuraScript -{ - PrepareAuraScript(spell_warl_seed_of_corruption_aura); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ - SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R1, - SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R2, - SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R3, - SPELL_WARLOCK_SEED_OF_CORRUPTION_VISUAL - }); - } - - void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) - { - if (!GetCaster()) - return; - - // effect 1 scales with 14% of caster's SP (DBC data) - amount = GetCaster()->SpellDamageBonusDone(GetUnitOwner(), GetSpellInfo(), amount, DOT, aurEff->GetEffIndex(), aurEff->GetPctMods()); - } - - void Detonate(AuraEffect const* aurEff) - { - if (!GetCaster() || !GetTarget()) - return; - - GetTarget()->CastSpell(GetTarget(), SPELL_WARLOCK_SEED_OF_CORRUPTION_VISUAL, true, nullptr, aurEff); - GetCaster()->CastSpell(GetTarget(), sSpellMgr->GetSpellWithRank(SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R1, GetSpellInfo()->GetRank()), true, nullptr, aurEff); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - int32 remainingDamage = aurEff->GetAmount() - damageInfo->GetDamage(); - if (remainingDamage > 0) - { - GetAura()->GetEffect(EFFECT_1)->SetAmount(remainingDamage); - } - else // damage threshold has been reached - { - Remove(AURA_REMOVE_BY_DEFAULT); - Detonate(aurEff); - } - } - - void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode(); - if (removeMode == AURA_REMOVE_BY_DEATH) - Detonate(aurEff); - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_seed_of_corruption_aura::CalculateAmount, EFFECT_1, SPELL_AURA_DUMMY); - AfterEffectRemove += AuraEffectRemoveFn(spell_warl_seed_of_corruption_aura::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); - OnEffectProc += AuraEffectProcFn(spell_warl_seed_of_corruption_aura::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); - } -}; - -// Monster spells, triggered only on detonation threshold reached (not on death) -// 32863 - Seed of Corruption -// 36123 - Seed of Corruption -// 38252 - Seed of Corruption -// 39367 - Seed of Corruption -// 44141 - Seed of Corruption -// 70388 - Seed of Corruption -class spell_warl_seed_of_corruption_generic_aura: public AuraScript -{ - PrepareAuraScript(spell_warl_seed_of_corruption_generic_aura); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_GENERIC, SPELL_WARLOCK_SEED_OF_CORRUPTION_VISUAL }); - } - - void Detonate(AuraEffect const* aurEff) - { - if (!GetCaster() || !GetTarget()) - return; - - GetTarget()->CastSpell(GetTarget(), SPELL_WARLOCK_SEED_OF_CORRUPTION_VISUAL, true, nullptr, aurEff); - GetCaster()->CastCustomSpell(SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_GENERIC, SPELLVALUE_BASE_POINT0, GetSpellInfo()->GetEffect(EFFECT_1).CalcValue(), GetTarget(), true, nullptr, aurEff); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - int32 remainingDamage = aurEff->GetAmount() - damageInfo->GetDamage(); - if (remainingDamage > 0) - { - GetAura()->GetEffect(EFFECT_1)->SetAmount(remainingDamage); - } - else // damage threshold has been reached - { - Remove(AURA_REMOVE_BY_DEFAULT); - Detonate(aurEff); - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_warl_seed_of_corruption_generic_aura::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); - } -}; - // 29858 - Soulshatter class spell_warl_soulshatter : public SpellScript { @@ -1975,8 +1854,6 @@ void AddSC_warlock_spell_scripts() RegisterSpellScript(spell_warl_life_tap); RegisterSpellScript(spell_warl_ritual_of_doom_effect); RegisterSpellScript(spell_warl_seed_of_corruption_damage); - RegisterSpellScript(spell_warl_seed_of_corruption_aura); - RegisterSpellScript(spell_warl_seed_of_corruption_generic_aura); RegisterSpellScript(spell_warl_shadow_ward); RegisterSpellScript(spell_warl_siphon_life); RegisterSpellScript(spell_warl_soulshatter); From d39a03b7ab7b51a0e85efa4cb0c5364054fba96e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Feb 2026 18:38:49 +0000 Subject: [PATCH 242/335] chore(DB): import pending files Referenced commit(s): 4277ac0b262b229bf798339c77b1254aedfabf1b --- .../rev_1771855011429365338.sql => db_world/2026_02_23_06.sql} | 1 + .../rev_1771866173424640746.sql => db_world/2026_02_23_07.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1771855011429365338.sql => db_world/2026_02_23_06.sql} (92%) rename data/sql/updates/{pending_db_world/rev_1771866173424640746.sql => db_world/2026_02_23_07.sql} (76%) diff --git a/data/sql/updates/pending_db_world/rev_1771855011429365338.sql b/data/sql/updates/db_world/2026_02_23_06.sql similarity index 92% rename from data/sql/updates/pending_db_world/rev_1771855011429365338.sql rename to data/sql/updates/db_world/2026_02_23_06.sql index 4d22aeed6..01167c6ed 100644 --- a/data/sql/updates/pending_db_world/rev_1771855011429365338.sql +++ b/data/sql/updates/db_world/2026_02_23_06.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_23_05 -> 2026_02_23_06 -- Fix spell_script_names for spell_hun_rapid_recuperation -- Script was moved from talent (53228/53232) to periodic mana aura (56654/58882) DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_hun_rapid_recuperation'; diff --git a/data/sql/updates/pending_db_world/rev_1771866173424640746.sql b/data/sql/updates/db_world/2026_02_23_07.sql similarity index 76% rename from data/sql/updates/pending_db_world/rev_1771866173424640746.sql rename to data/sql/updates/db_world/2026_02_23_07.sql index 6a6809be8..1314e88cb 100644 --- a/data/sql/updates/pending_db_world/rev_1771866173424640746.sql +++ b/data/sql/updates/db_world/2026_02_23_07.sql @@ -1 +1,2 @@ +-- DB update 2026_02_23_06 -> 2026_02_23_07 DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_warl_seed_of_corruption_aura', 'spell_warl_seed_of_corruption_generic_aura'); From e3f6693d1a7669c0182c96eaf77fb6234936e092 Mon Sep 17 00:00:00 2001 From: Jasper <97269008+jads147@users.noreply.github.com> Date: Mon, 23 Feb 2026 20:25:49 +0100 Subject: [PATCH 243/335] fix(Core/DynamicObject): Fix Death and Decay not ticking while stationary (#24205) Co-authored-by: blinkysc <37940565+blinkysc@users.noreply.github.com> --- src/server/game/Entities/DynamicObject/DynamicObject.cpp | 8 ++++++++ src/server/game/Entities/DynamicObject/DynamicObject.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp index 5a6465404..173969381 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp +++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp @@ -272,3 +272,11 @@ void DynamicObject::UnbindFromCaster() _caster->_UnregisterDynObject(this); _caster = nullptr; } + +bool DynamicObject::IsUpdateNeeded() +{ + if (GetByteValue(DYNAMICOBJECT_BYTES, 0) == DYNAMIC_OBJECT_AREA_SPELL) + return true; + + return WorldObject::IsUpdateNeeded(); +} diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h index b5ff4b1c7..ae87d8108 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.h +++ b/src/server/game/Entities/DynamicObject/DynamicObject.h @@ -62,6 +62,8 @@ public: ObjectGuid const& GetOldFarsightGUID() const { return _oldFarsightGUID; } + bool IsUpdateNeeded() override; + protected: Aura* _aura; Aura* _removedAura; From 3001b11d9a76a2ffba9112ed70c74d06c8fc5922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefano=20Borz=C3=AC?= Date: Mon, 23 Feb 2026 20:40:33 +0100 Subject: [PATCH 244/335] chore(Core/Battleground): expose damange,healing and kills attribute for modules (#24801) --- src/server/game/Battlegrounds/BattlegroundScore.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/server/game/Battlegrounds/BattlegroundScore.h b/src/server/game/Battlegrounds/BattlegroundScore.h index 80ce87fe0..de0663cdc 100644 --- a/src/server/game/Battlegrounds/BattlegroundScore.h +++ b/src/server/game/Battlegrounds/BattlegroundScore.h @@ -59,7 +59,12 @@ struct AC_GAME_API BattlegroundScore friend class Arena; friend class Battleground; -protected: + public: + [[nodiscard]] uint32 GetKillingBlows() const { return KillingBlows; } + [[nodiscard]] uint32 GetDamageDone() const { return DamageDone; } + [[nodiscard]] uint32 GetHealingDone() const { return HealingDone; } + + protected: BattlegroundScore(ObjectGuid playerGuid) : PlayerGuid(playerGuid) { } virtual ~BattlegroundScore() = default; @@ -97,12 +102,9 @@ protected: // For Logging purpose virtual std::string ToString() const { return ""; } - [[nodiscard]] uint32 GetKillingBlows() const { return KillingBlows; } [[nodiscard]] uint32 GetDeaths() const { return Deaths; } [[nodiscard]] uint32 GetHonorableKills() const { return HonorableKills; } [[nodiscard]] uint32 GetBonusHonor() const { return BonusHonor; } - [[nodiscard]] uint32 GetDamageDone() const { return DamageDone; } - [[nodiscard]] uint32 GetHealingDone() const { return HealingDone; } [[nodiscard]] virtual uint32 GetAttr1() const { return 0; } [[nodiscard]] virtual uint32 GetAttr2() const { return 0; } From b041bd54e158941e010db5b7f834f304f187b9f4 Mon Sep 17 00:00:00 2001 From: sudlud Date: Tue, 24 Feb 2026 01:46:34 +0100 Subject: [PATCH 245/335] fix(DB/Gameobject): Sniffed Values for 'Mixed Fruit Bowl' spawns (#24832) --- .../rev_1771880222045839200.sql | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771880222045839200.sql diff --git a/data/sql/updates/pending_db_world/rev_1771880222045839200.sql b/data/sql/updates/pending_db_world/rev_1771880222045839200.sql new file mode 100644 index 000000000..e10d16bf2 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771880222045839200.sql @@ -0,0 +1,35 @@ +-- Update gameobject 'Mixed Fruit Bowl' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (195067)) AND (`guid` IN (240026, 240040, 240052, 240053, 240054, 240055, 240056, 240059, 240061, 240062, 240220, 240221, 240222, 240223, 240224, 240225, 240226, 240227, 240228, 240229, 240230)); +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 +(240026, 195067, 571, 0, 0, 1, 1, 5854.46533203125, 767.34027099609375, 641.37200927734375, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL), +(240040, 195067, 530, 0, 0, 1, 1, 9419.5224609375, -6850.59716796875, 15.02394580841064453, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240052, 195067, 530, 0, 0, 1, 1, -4314.91162109375, -12442.8330078125, 17.23089027404785156, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240053, 195067, 530, 0, 0, 1, 1, -4313.84716796875, -12446.4931640625, 17.29690933227539062, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240054, 195067, 530, 0, 0, 1, 1, -4324.51025390625, -12450.021484375, 16.69842720031738281, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240055, 195067, 530, 0, 0, 1, 1, -4324.767578125, -12454.0107421875, 16.80428314208984375, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240056, 195067, 530, 0, 0, 1, 1, -4309.53125, -12421.048828125, 17.52263069152832031, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240059, 195067, 530, 0, 0, 1, 1, -1782.921875, 4936.822265625, -22.6595134735107421, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240061, 195067, 530, 0, 0, 1, 1, -1829.6197509765625, 4920.39697265625, -21.5714244842529296, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240062, 195067, 530, 0, 0, 1, 1, -1814.9097900390625, 4911.5078125, -21.3174991607666015, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240220, 195067, 0, 0, 0, 1, 1, 1778.8472900390625, 260.072906494140625, 59.49801254272460937, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240221, 195067, 1, 0, 0, 1, 1, 10054.146484375, 2124.819580078125, 1329.703125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240222, 195067, 1, 0, 0, 1, 1, 10047.404296875, 2110.173583984375, 1329.648193359375, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240223, 195067, 1, 0, 0, 1, 1, 10059.8408203125, 2122.515625, 1329.6710205078125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240224, 195067, 0, 0, 0, 1, 1, -5161.68603515625, -869.670166015625, 507.202484130859375, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240225, 195067, 0, 0, 0, 1, 1, -9352.4326171875, 172.9270782470703125, 61.57478713989257812, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240226, 195067, 1, 0, 0, 1, 1, 1175.46533203125, -4455.31591796875, 21.52185630798339843, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240227, 195067, 1, 0, 0, 1, 1, 1185.3629150390625, -4460.861328125, 21.10199546813964843, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240228, 195067, 1, 0, 0, 1, 1, 1179.267333984375, -4468.45166015625, 21.2471466064453125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240229, 195067, 1, 0, 0, 1, 1, -983.56597900390625, -73.3246536254882812, 20.64240455627441406, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL), +(240230, 195067, 1, 0, 0, 1, 1, -980.89239501953125, -79.265625, 20.10221290588378906, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL); + +-- remove invalid spawns +-- these do not show in sniffs (most likely hand placed spawns) +DELETE FROM `gameobject` WHERE (`id` IN (195067)) AND (`guid` IN (240067, 240063, 240066, 240064, 240065, 240030, 240034, 240031, 240032, 240033, 240036, 240037, 240038, 240035, 240048, 240046, 240047, 240049, 240042, 240045, 240043, 240044, 240015, 240014, 240016, 240058, 240057, 240060, 240050, 240051, 240041, 240039, 240027, 240028, 240029, 240025)); +DELETE FROM `gameobject_addon` WHERE (`guid` IN (240067, 240063, 240066, 240064, 240065, 240030, 240034, 240031, 240032, 240033, 240036, 240037, 240038, 240035, 240048, 240046, 240047, 240049, 240042, 240045, 240043, 240044, 240015, 240014, 240016, 240058, 240057, 240060, 240050, 240051, 240041, 240039, 240027, 240028, 240029, 240025)); +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (240067, 240063, 240066, 240064, 240065, 240030, 240034, 240031, 240032, 240033, 240036, 240037, 240038, 240035, 240048, 240046, 240047, 240049, 240042, 240045, 240043, 240044, 240015, 240014, 240016, 240058, 240057, 240060, 240050, 240051, 240041, 240039, 240027, 240028, 240029, 240025)); + +-- enable all spawns for eventEntry 51 +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (SELECT `guid` FROM `gameobject` WHERE `id` IN (195067))); +INSERT INTO `game_event_gameobject` (SELECT 51, `guid` FROM `gameobject` WHERE `id` IN (195067)); From e8ce0330879adf9f68a23f99ac89a13de4a4f80d Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Mon, 23 Feb 2026 18:46:50 -0600 Subject: [PATCH 246/335] fix(Core/Spells): Prevent stealth from breaking on friendly proc spells (#24834) Co-authored-by: blinkysc Co-authored-by: ariel- --- src/server/game/Spells/Auras/SpellAuras.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index a6fa20e6c..d313b5ca1 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2177,6 +2177,14 @@ uint8 Aura::GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo, return 0; } + // Don't consume stealth charges from friendly spells + if (m_spellInfo->HasAura(SPELL_AURA_MOD_STEALTH)) + { + if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) + if (spellInfo->IsPositive()) + return 0; + } + // check if we have charges to proc with if (IsUsingCharges() && !GetCharges()) return 0; From 0fb5b2dfe374d8c25f664be4db9b60dc68e61cb7 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Mon, 23 Feb 2026 18:47:03 -0600 Subject: [PATCH 247/335] fix(Core/Spells): Fix Beacon of Light healing attribution (#24836) Co-authored-by: blinkysc --- src/server/scripts/Spells/spell_paladin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 0e5f3b48a..8b9dc5c44 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -2157,7 +2157,7 @@ class spell_pal_light_s_beacon : public AuraScript if (!beaconTarget || !beaconTarget->HasAura(SPELL_PALADIN_BEACON_OF_LIGHT_AURA, eventInfo.GetActor()->GetGUID())) return; - eventInfo.GetActor()->CastCustomSpell(healSpellId, SPELLVALUE_BASE_POINT0, heal, beaconTarget, true, nullptr, aurEff); + eventInfo.GetActor()->CastCustomSpell(healSpellId, SPELLVALUE_BASE_POINT0, heal, beaconTarget, true, nullptr, aurEff, eventInfo.GetActor()->GetGUID()); } void Register() override From e9360f56c4c791cae4caf0df7d2d0a1052dc98a9 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Mon, 23 Feb 2026 19:47:23 -0500 Subject: [PATCH 248/335] fix(Core/AuthSession): Send proper account flags for authentication responses. (#24829) --- .../apps/authserver/Server/AuthSession.cpp | 31 ++++++++++--------- .../apps/authserver/Server/AuthSession.h | 1 + .../Database/Implementation/LoginDatabase.cpp | 4 +-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/server/apps/authserver/Server/AuthSession.cpp b/src/server/apps/authserver/Server/AuthSession.cpp index e5315c9ec..ce4a1e590 100644 --- a/src/server/apps/authserver/Server/AuthSession.cpp +++ b/src/server/apps/authserver/Server/AuthSession.cpp @@ -136,13 +136,13 @@ std::unordered_map const Handlers = AuthSession::InitHandler void AccountInfo::LoadResult(Field* fields) { - // 0 1 2 3 4 5 - // SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.failed_logins, - // 6 7 + // 0 1 2 3 4 5 6 + // SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.Flags, a.failed_logins, + // 7 8 // ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, ab.unbandate = ab.bandate, - // 8 9 + // 9 10 // ipb.unbandate > UNIX_TIMESTAMP() OR ipb.unbandate = ipb.bandate, ipb.unbandate = ipb.bandate, - // 10 + // 11 // aa.gmlevel (, more query-specific fields) // FROM account a LEFT JOIN account_access aa ON a.id = aa.id LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 LEFT JOIN ip_banned ipb ON ipb.ip = ? WHERE a.username = ? @@ -151,10 +151,11 @@ void AccountInfo::LoadResult(Field* fields) IsLockedToIP = fields[2].Get(); LockCountry = fields[3].Get(); LastIP = fields[4].Get(); - FailedLogins = fields[5].Get(); - IsBanned = fields[6].Get() || fields[8].Get(); - IsPermanentlyBanned = fields[7].Get() || fields[9].Get(); - SecurityLevel = static_cast(fields[10].Get()) > SEC_CONSOLE ? SEC_CONSOLE : static_cast(fields[10].Get()); + Flags = fields[5].Get(); + FailedLogins = fields[6].Get(); + IsBanned = fields[7].Get() || fields[9].Get(); + IsPermanentlyBanned = fields[8].Get() || fields[10].Get(); + SecurityLevel = static_cast(fields[11].Get()) > SEC_CONSOLE ? SEC_CONSOLE : static_cast(fields[12].Get()); // Use our own uppercasing of the account name instead of using UPPER() in mysql query // This is how the account was created in the first place and changing it now would result in breaking @@ -387,10 +388,10 @@ void AuthSession::LogonChallengeCallback(PreparedQueryResult result) uint8 securityFlags = 0; // Check if a TOTP token is needed - if (!fields[11].IsNull()) + if (!fields[12].IsNull()) { securityFlags = 4; - _totpSecret = fields[11].Get(); + _totpSecret = fields[12].Get(); if (auto const& secret = sSecretMgr->GetSecret(SECRET_TOTP_MASTER_KEY)) { @@ -406,8 +407,8 @@ void AuthSession::LogonChallengeCallback(PreparedQueryResult result) } _srp6.emplace(_accountInfo.Login, - fields[12].Get(), - fields[13].Get()); + fields[13].Get(), + fields[14].Get()); // Fill the response packet with the result if (AuthHelper::IsAcceptedClientBuild(_build)) @@ -531,7 +532,7 @@ bool AuthSession::HandleLogonProof() proof.M2 = M2; proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; - proof.AccountFlags = ACCOUNT_FLAG_PROPASS_LOCK; // enum AccountFlag + proof.AccountFlags = _accountInfo.Flags; proof.SurveyId = 0; proof.LoginFlags = 0; // 0x1 = has account message @@ -667,7 +668,7 @@ void AuthSession::ReconnectChallengeCallback(PreparedQueryResult result) Field* fields = result->Fetch(); _accountInfo.LoadResult(fields); - _sessionKey = fields[11].Get(); + _sessionKey = fields[12].Get(); Acore::Crypto::GetRandomBytes(_reconnectProof); _status = STATUS_RECONNECT_PROOF; diff --git a/src/server/apps/authserver/Server/AuthSession.h b/src/server/apps/authserver/Server/AuthSession.h index 0c61e5e2f..0ea2fafff 100644 --- a/src/server/apps/authserver/Server/AuthSession.h +++ b/src/server/apps/authserver/Server/AuthSession.h @@ -54,6 +54,7 @@ struct AccountInfo bool IsLockedToIP = false; std::string LockCountry; std::string LastIP; + uint32 Flags; uint32 FailedLogins = 0; bool IsBanned = false; bool IsPermanentlyBanned = false; diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp index 1e091b56e..298ae09d5 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.cpp +++ b/src/server/database/Database/Implementation/LoginDatabase.cpp @@ -24,7 +24,7 @@ void LoginDatabaseConnection::DoPrepareStatements() m_stmts.resize(MAX_LOGINDATABASE_STATEMENTS); PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, - "SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.failed_logins, " + "SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.Flags, a.failed_logins, " "ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, ab.unbandate = ab.bandate, " "ipb.unbandate > UNIX_TIMESTAMP() OR ipb.unbandate = ipb.bandate, ipb.unbandate = ipb.bandate, " "aa.gmlevel, a.totp_secret, a.salt, a.verifier " @@ -34,7 +34,7 @@ void LoginDatabaseConnection::DoPrepareStatements() "LEFT JOIN ip_banned ipb ON ipb.ip = ? " "WHERE a.username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_RECONNECTCHALLENGE, - "SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.failed_logins, " + "SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.Flags, a.failed_logins, " "ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, ab.unbandate = ab.bandate, " "ipb.unbandate > UNIX_TIMESTAMP() OR ipb.unbandate = ipb.bandate, ipb.unbandate = ipb.bandate, " "aa.gmlevel, a.session_key " From af7e91f9a982941579d532908101d3e239dac9e3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 24 Feb 2026 00:47:38 +0000 Subject: [PATCH 249/335] chore(DB): import pending files Referenced commit(s): b041bd54e158941e010db5b7f834f304f187b9f4 --- .../rev_1771880222045839200.sql => db_world/2026_02_24_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771880222045839200.sql => db_world/2026_02_24_00.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771880222045839200.sql b/data/sql/updates/db_world/2026_02_24_00.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771880222045839200.sql rename to data/sql/updates/db_world/2026_02_24_00.sql index e10d16bf2..977118e2c 100644 --- a/data/sql/updates/pending_db_world/rev_1771880222045839200.sql +++ b/data/sql/updates/db_world/2026_02_24_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_23_07 -> 2026_02_24_00 -- Update gameobject 'Mixed Fruit Bowl' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (195067)) AND (`guid` IN (240026, 240040, 240052, 240053, 240054, 240055, 240056, 240059, 240061, 240062, 240220, 240221, 240222, 240223, 240224, 240225, 240226, 240227, 240228, 240229, 240230)); From 8b9cdfde1302be9493c737a0d27a829283909a68 Mon Sep 17 00:00:00 2001 From: sogladev Date: Tue, 24 Feb 2026 01:47:49 +0100 Subject: [PATCH 250/335] fix(DB/QuestTracker): add index (#24803) Co-authored-by: Shauren --- .../updates/pending_db_characters/rev_1771762913747659496.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 data/sql/updates/pending_db_characters/rev_1771762913747659496.sql diff --git a/data/sql/updates/pending_db_characters/rev_1771762913747659496.sql b/data/sql/updates/pending_db_characters/rev_1771762913747659496.sql new file mode 100644 index 000000000..fd65b3f01 --- /dev/null +++ b/data/sql/updates/pending_db_characters/rev_1771762913747659496.sql @@ -0,0 +1,4 @@ +-- +ALTER TABLE `quest_tracker` + MODIFY COLUMN `id` int UNSIGNED NOT NULL DEFAULT 0 FIRST, + ADD UNIQUE INDEX `idx_latest_quest_for_character`(`id`, `character_guid`, `quest_accept_time` DESC); From 34f1d2b39a8a127c06888b7286f24aef64d60d3d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 24 Feb 2026 00:47:57 +0000 Subject: [PATCH 251/335] chore(DB): import pending files Referenced commit(s): e8ce0330879adf9f68a23f99ac89a13de4a4f80d --- .../2026_02_24_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_characters/rev_1771762913747659496.sql => db_characters/2026_02_24_00.sql} (81%) diff --git a/data/sql/updates/pending_db_characters/rev_1771762913747659496.sql b/data/sql/updates/db_characters/2026_02_24_00.sql similarity index 81% rename from data/sql/updates/pending_db_characters/rev_1771762913747659496.sql rename to data/sql/updates/db_characters/2026_02_24_00.sql index fd65b3f01..7ea5edb57 100644 --- a/data/sql/updates/pending_db_characters/rev_1771762913747659496.sql +++ b/data/sql/updates/db_characters/2026_02_24_00.sql @@ -1,3 +1,4 @@ +-- DB update 2025_09_03_00 -> 2026_02_24_00 -- ALTER TABLE `quest_tracker` MODIFY COLUMN `id` int UNSIGNED NOT NULL DEFAULT 0 FIRST, From 782d4d539d191238583bbfa3ebcf37590f486513 Mon Sep 17 00:00:00 2001 From: sudlud Date: Tue, 24 Feb 2026 01:48:22 +0100 Subject: [PATCH 252/335] fix(DB/Creature): Sniffed Values for 'Catrina' spawns (#24840) --- .../rev_1771884996282642200.sql | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771884996282642200.sql diff --git a/data/sql/updates/pending_db_world/rev_1771884996282642200.sql b/data/sql/updates/pending_db_world/rev_1771884996282642200.sql new file mode 100644 index 000000000..5388909fb --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771884996282642200.sql @@ -0,0 +1,18 @@ +-- Update creature 'Catrina' with sniffed values +-- updated spawns +DELETE FROM `creature` WHERE (`id1` IN (34383)) AND (`guid` IN (240226, 240227, 240259, 240260, 240261, 240262, 240263, 240264, 240265, 240266)); +INSERT INTO `creature` (`guid`, `id1`, `map`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(240226, 34383, 1, 1, 1, 1, 1181.736083984375, -4463.10791015625, 21.34230422973632812, 1.221730470657348632, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240227, 34383, 0, 1, 1, 1, -9329.3876953125, 178.1302032470703125, 61.78533172607421875, 3.909537553787231445, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240259, 34383, 571, 1, 1, 1, 5852.19775390625, 763.51214599609375, 641.49072265625, 3.909537553787231445, 120, 0, 0, 0, 0, 0, "", 46248, 1, NULL), +(240260, 34383, 0, 1, 1, 1, 1803.7447509765625, 219.59722900390625, 60.44121551513671875, 1.361356854438781738, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240261, 34383, 530, 1, 1, 1, 9409.2080078125, -6841.0087890625, 16.17881965637207031, 2.513274192810058593, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240262, 34383, 1, 1, 1, 1, 10048.3330078125, 2122.397705078125, 1330.0263671875, 3.141592741012573242, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240263, 34383, 1, 1, 1, 1, -977.62677001953125, -74.53125, 19.17006301879882812, 0.244346097111701965, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240264, 34383, 530, 1, 1, 1, -4314.36474609375, -12451.16015625, 17.92534828186035156, 5.724679946899414062, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240265, 34383, 530, 1, 1, 1, -1792.2708740234375, 4921.30810546875, -21.5448799133300781, 2.58308720588684082, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240266, 34383, 0, 1, 1, 1, -5145.17041015625, -856.00177001953125, 508.79412841796875, 0.907571196556091308, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL); + +-- enable all spawns for eventEntry 51 +DELETE FROM `game_event_creature` WHERE (`eventEntry` = 51) AND (`guid` IN (SELECT `guid` FROM `creature` WHERE `id1` IN (34383))); +INSERT INTO `game_event_creature` (SELECT 51, `guid` FROM `creature` WHERE `id1` IN (34383)); From badbf52adc06b2e03b5ae904833726c2bc7388a1 Mon Sep 17 00:00:00 2001 From: sudlud Date: Tue, 24 Feb 2026 01:48:39 +0100 Subject: [PATCH 253/335] fix(DB/Creature): Sniffed Values for 'Chapman' spawns (#24839) --- .../rev_1771884370767583400.sql | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771884370767583400.sql diff --git a/data/sql/updates/pending_db_world/rev_1771884370767583400.sql b/data/sql/updates/pending_db_world/rev_1771884370767583400.sql new file mode 100644 index 000000000..56d14b62d --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771884370767583400.sql @@ -0,0 +1,18 @@ +-- Update creature 'Chapman' with sniffed values +-- updated spawns +DELETE FROM `creature` WHERE (`id1` IN (34382)) AND (`guid` IN (240228, 240229, 240251, 240252, 240253, 240254, 240255, 240256, 240257, 240258)); +INSERT INTO `creature` (`guid`, `id1`, `map`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(240228, 34382, 1, 1, 1, 1, 1179.814208984375, -4461.45654296875, 21.46875, 1.326450228691101074, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240229, 34382, 0, 1, 1, 1, -9332.0263671875, 179.579864501953125, 61.80413055419921875, 4.468042850494384765, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240251, 34382, 571, 1, 1, 1, 5850.04931640625, 766.30731201171875, 640.9990234375, 4.468042850494384765, 120, 0, 0, 0, 0, 0, "", 46248, 1, NULL), +(240252, 34382, 0, 1, 1, 1, 1806.5382080078125, 219.423614501953125, 60.46582794189453125, 1.65806281566619873, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240253, 34382, 530, 1, 1, 1, 9409.1982421875, -6837.9130859375, 16.3055572509765625, 3.630284786224365234, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240254, 34382, 1, 1, 1, 1, 10047.9189453125, 2119.15625, 1329.9794921875, 3.176499128341674804, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240255, 34382, 1, 1, 1, 1, -978.0225830078125, -72.6458358764648437, 19.29324531555175781, 0.401425719261169433, 120, 0, 0, 0, 0, 0, "", 46368, 1, NULL), +(240256, 34382, 530, 1, 1, 1, -4312.234375, -12449.03515625, 17.73958396911621093, 5.654866695404052734, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240257, 34382, 530, 1, 1, 1, -1788.236083984375, 4925.75244140625, -21.6491146087646484, 2.460914134979248046, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240258, 34382, 0, 1, 1, 1, -5147.53466796875, -853.826416015625, 508.66314697265625, 0.698131680488586425, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL); + +-- enable all spawns for eventEntry 51 +DELETE FROM `game_event_creature` WHERE (`eventEntry` = 51) AND (`guid` IN (SELECT `guid` FROM `creature` WHERE `id1` IN (34382))); +INSERT INTO `game_event_creature` (SELECT 51, `guid` FROM `creature` WHERE `id1` IN (34382)); From 7e05ed0be9cddf81909dd84654006fa573066013 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 24 Feb 2026 00:48:47 +0000 Subject: [PATCH 254/335] chore(DB): import pending files Referenced commit(s): e9360f56c4c791cae4caf0df7d2d0a1052dc98a9 --- .../rev_1771884370767583400.sql => db_world/2026_02_24_01.sql} | 1 + .../rev_1771884996282642200.sql => db_world/2026_02_24_02.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1771884370767583400.sql => db_world/2026_02_24_01.sql} (98%) rename data/sql/updates/{pending_db_world/rev_1771884996282642200.sql => db_world/2026_02_24_02.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1771884370767583400.sql b/data/sql/updates/db_world/2026_02_24_01.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1771884370767583400.sql rename to data/sql/updates/db_world/2026_02_24_01.sql index 56d14b62d..ac3ea3219 100644 --- a/data/sql/updates/pending_db_world/rev_1771884370767583400.sql +++ b/data/sql/updates/db_world/2026_02_24_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_24_00 -> 2026_02_24_01 -- Update creature 'Chapman' with sniffed values -- updated spawns DELETE FROM `creature` WHERE (`id1` IN (34382)) AND (`guid` IN (240228, 240229, 240251, 240252, 240253, 240254, 240255, 240256, 240257, 240258)); diff --git a/data/sql/updates/pending_db_world/rev_1771884996282642200.sql b/data/sql/updates/db_world/2026_02_24_02.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1771884996282642200.sql rename to data/sql/updates/db_world/2026_02_24_02.sql index 5388909fb..017ac6e65 100644 --- a/data/sql/updates/pending_db_world/rev_1771884996282642200.sql +++ b/data/sql/updates/db_world/2026_02_24_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_24_01 -> 2026_02_24_02 -- Update creature 'Catrina' with sniffed values -- updated spawns DELETE FROM `creature` WHERE (`id1` IN (34383)) AND (`guid` IN (240226, 240227, 240259, 240260, 240261, 240262, 240263, 240264, 240265, 240266)); From bdba826606e5d4f6199c505fa6fe3b2e807f8c32 Mon Sep 17 00:00:00 2001 From: sudlud Date: Tue, 24 Feb 2026 01:49:00 +0100 Subject: [PATCH 255/335] fix(DB/Gameobject): Sniffed Values for 'Spirit Candle' spawns (#24835) --- .../rev_1771882014186629900.sql | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771882014186629900.sql diff --git a/data/sql/updates/pending_db_world/rev_1771882014186629900.sql b/data/sql/updates/pending_db_world/rev_1771882014186629900.sql new file mode 100644 index 000000000..58cd9fbae --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771882014186629900.sql @@ -0,0 +1,38 @@ +-- Update gameobject 'Spirit Candle' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (195090)) AND (`guid` IN (240070, 240072, 240080, 240092, 240096, 240099, 240113, 240118, 240123, 240126, 240131, 240133, 240137, 240139, 240146, 240147, 240152, 240155, 240158, 240164, 240165, 240174, 240186, 240193)); +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 +(240070, 195090, 1, 0, 0, 1, 1, 1184.34375, -4469.79150390625, 21.29567146301269531, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 51943, NULL), +(240072, 195090, 1, 0, 0, 1, 1, 1171.8125, -4463.70166015625, 21.26313972473144531, 3.804818391799926757, 0, 0, -0.94551849365234375, 0.325568377971649169, 120, 255, 1, "", 51943, NULL), +(240080, 195090, 0, 0, 0, 1, 1, -9329.173828125, 184.0850677490234375, 62.915771484375, 3.804818391799926757, 0, 0, -0.94551849365234375, 0.325568377971649169, 120, 255, 1, "", 51943, NULL), +(240092, 195090, 0, 0, 0, 1, 1, -9332.388671875, 174.9496612548828125, 63.12789535522460937, 4.031712055206298828, 0, 0, -0.90258502960205078, 0.430511653423309326, 120, 255, 1, "", 51943, NULL), +(240096, 195090, 571, 0, 0, 1, 1, 5857.65283203125, 765.75, 642.55218505859375, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 46248, NULL), +(240099, 195090, 571, 0, 0, 1, 1, 5852.61962890625, 768.34027099609375, 642.14642333984375, 3.804818391799926757, 0, 0, -0.94551849365234375, 0.325568377971649169, 120, 255, 1, "", 46248, NULL), +(240113, 195090, 0, 0, 0, 1, 1, 1804.7396240234375, 215.421875, 65.87223052978515625, 1.500982880592346191, 0, 0, 0.681998252868652343, 0.731353819370269775, 120, 255, 1, "", 51943, NULL), +(240118, 195090, 0, 0, 0, 1, 1, 1777.4444580078125, 219.4965362548828125, 59.60799789428710937, 0.15707901120185852, 0, 0, 0.078458786010742187, 0.996917366981506347, 120, 255, 1, "", 51943, NULL), +(240123, 195090, 530, 0, 0, 1, 1, 9406.931640625, -6839.236328125, 16.12152862548828125, 1.500982880592346191, 0, 0, 0.681998252868652343, 0.731353819370269775, 120, 255, 1, "", 51943, NULL), +(240126, 195090, 530, 0, 0, 1, 1, 9419.6396484375, -6851.48974609375, 14.99889087677001953, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 51943, NULL), +(240131, 195090, 1, 0, 0, 1, 1, 10063.31640625, 2129.739501953125, 1329.6578369140625, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 51943, NULL), +(240133, 195090, 1, 0, 0, 1, 1, 10049.5517578125, 2113.663330078125, 1329.699951171875, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 51943, NULL), +(240137, 195090, 1, 0, 0, 1, 1, 10061, 2124.7744140625, 1329.6578369140625, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 51943, NULL), +(240139, 195090, 1, 0, 0, 1, 1, 10066.6513671875, 2120.208251953125, 1329.6578369140625, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 51943, NULL), +(240146, 195090, 1, 0, 0, 1, 1, -981.625, -66.9791641235351562, 20.97347450256347656, 3.804818391799926757, 0, 0, -0.94551849365234375, 0.325568377971649169, 120, 255, 1, "", 46368, NULL), +(240147, 195090, 1, 0, 0, 1, 1, -985.3211669921875, -76.3576431274414062, 21.0618743896484375, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 46368, NULL), +(240152, 195090, 530, 0, 0, 1, 1, -4325.02099609375, -12437.486328125, 17.54513931274414062, 3.804818391799926757, 0, 0, -0.94551849365234375, 0.325568377971649169, 120, 255, 1, "", 51943, NULL), +(240155, 195090, 530, 0, 0, 1, 1, -4323.68212890625, -12439.642578125, 17.47939491271972656, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 51943, NULL), +(240158, 195090, 530, 0, 0, 1, 1, -4311.05908203125, -12439.4658203125, 17.12792778015136718, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 51943, NULL), +(240164, 195090, 530, 0, 0, 1, 1, -1791.73095703125, 4917.93603515625, -21.0255756378173828, 2.967041015625, 0, 0, 0.996193885803222656, 0.087165042757987976, 120, 255, 1, "", 51943, NULL), +(240165, 195090, 530, 0, 0, 1, 1, -1789.701416015625, 4922.515625, -21.0878028869628906, 2.478367090225219726, 0, 0, 0.94551849365234375, 0.325568377971649169, 120, 255, 1, "", 51943, NULL), +(240174, 195090, 530, 0, 0, 1, 1, -1784.0103759765625, 4926.54443359375, -21.1391143798828125, 1.937312245368957519, 0, 0, 0.824125289916992187, 0.566407561302185058, 120, 255, 1, "", 51943, NULL), +(240186, 195090, 0, 0, 0, 1, 1, -5163.095703125, -880.0538330078125, 507.278106689453125, 1.361356139183044433, 0, 0, 0.629320144653320312, 0.77714616060256958, 120, 255, 1, "", 51943, NULL), +(240193, 195090, 0, 0, 0, 1, 1, -5160.6162109375, -870.092041015625, 507.264434814453125, 0.977383077144622802, 0, 0, 0.469470977783203125, 0.882947921752929687, 120, 255, 1, "", 51943, NULL); + +-- remove invalid spawns +-- these do not show in sniffs (most likely hand placed spawns) +DELETE FROM `gameobject` WHERE (`id` IN (195090)) AND (`guid` IN (240179, 240180, 240182, 240068, 240181, 240007, 240183, 240194, 240185, 240184, 240192, 240189, 240191, 240188, 240187, 240190, 240076, 240077, 240078, 240089, 240079, 240090, 240088, 240094, 240091, 240081, 240093, 240082, 240083, 240084, 240085, 240086, 240087, 240115, 240114, 240110, 240116, 240117, 240111, 240112, 240145, 240142, 240144, 240143, 240148, 240141, 240134, 240140, 240135, 240136, 240132, 240138, 240127, 240130, 240129, 240128, 240073, 240074, 240071, 240075, 240069, 240163, 240178, 240171, 240172, 240162, 240177, 240173, 240161, 240166, 240168, 240169, 240170, 240167, 240175, 240176, 240160, 240157, 240159, 240149, 240156, 240154, 240150, 240153, 240151, 240119, 240122, 240120, 240124, 240121, 240125, 240106, 240108, 240107, 240105, 240103, 240102, 240104, 240101, 240109, 240100, 240098, 240095, 240097)); +DELETE FROM `gameobject_addon` WHERE (`guid` IN (240179, 240180, 240182, 240068, 240181, 240007, 240183, 240194, 240185, 240184, 240192, 240189, 240191, 240188, 240187, 240190, 240076, 240077, 240078, 240089, 240079, 240090, 240088, 240094, 240091, 240081, 240093, 240082, 240083, 240084, 240085, 240086, 240087, 240115, 240114, 240110, 240116, 240117, 240111, 240112, 240145, 240142, 240144, 240143, 240148, 240141, 240134, 240140, 240135, 240136, 240132, 240138, 240127, 240130, 240129, 240128, 240073, 240074, 240071, 240075, 240069, 240163, 240178, 240171, 240172, 240162, 240177, 240173, 240161, 240166, 240168, 240169, 240170, 240167, 240175, 240176, 240160, 240157, 240159, 240149, 240156, 240154, 240150, 240153, 240151, 240119, 240122, 240120, 240124, 240121, 240125, 240106, 240108, 240107, 240105, 240103, 240102, 240104, 240101, 240109, 240100, 240098, 240095, 240097)); +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (240179, 240180, 240182, 240068, 240181, 240007, 240183, 240194, 240185, 240184, 240192, 240189, 240191, 240188, 240187, 240190, 240076, 240077, 240078, 240089, 240079, 240090, 240088, 240094, 240091, 240081, 240093, 240082, 240083, 240084, 240085, 240086, 240087, 240115, 240114, 240110, 240116, 240117, 240111, 240112, 240145, 240142, 240144, 240143, 240148, 240141, 240134, 240140, 240135, 240136, 240132, 240138, 240127, 240130, 240129, 240128, 240073, 240074, 240071, 240075, 240069, 240163, 240178, 240171, 240172, 240162, 240177, 240173, 240161, 240166, 240168, 240169, 240170, 240167, 240175, 240176, 240160, 240157, 240159, 240149, 240156, 240154, 240150, 240153, 240151, 240119, 240122, 240120, 240124, 240121, 240125, 240106, 240108, 240107, 240105, 240103, 240102, 240104, 240101, 240109, 240100, 240098, 240095, 240097)); + +-- enable all spawns for eventEntry 51 +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (SELECT `guid` FROM `gameobject` WHERE `id` IN (195090))); +INSERT INTO `game_event_gameobject` (SELECT 51, `guid` FROM `gameobject` WHERE `id` IN (195090)); From 99aa2991cd959aba67ecc08714501c4ba54cd877 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 24 Feb 2026 00:49:08 +0000 Subject: [PATCH 256/335] chore(DB): import pending files Referenced commit(s): af7e91f9a982941579d532908101d3e239dac9e3 --- .../rev_1771882014186629900.sql => db_world/2026_02_24_03.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771882014186629900.sql => db_world/2026_02_24_03.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771882014186629900.sql b/data/sql/updates/db_world/2026_02_24_03.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771882014186629900.sql rename to data/sql/updates/db_world/2026_02_24_03.sql index 58cd9fbae..93bd9c441 100644 --- a/data/sql/updates/pending_db_world/rev_1771882014186629900.sql +++ b/data/sql/updates/db_world/2026_02_24_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_24_02 -> 2026_02_24_03 -- Update gameobject 'Spirit Candle' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (195090)) AND (`guid` IN (240070, 240072, 240080, 240092, 240096, 240099, 240113, 240118, 240123, 240126, 240131, 240133, 240137, 240139, 240146, 240147, 240152, 240155, 240158, 240164, 240165, 240174, 240186, 240193)); From 1e96a1a46ab88955aef8954e474ebb58b2b04df4 Mon Sep 17 00:00:00 2001 From: sudlud Date: Tue, 24 Feb 2026 01:49:42 +0100 Subject: [PATCH 257/335] fix(DB/Gameobject): Sniffed Values for 'Bread of the Dead' spawns (#24833) --- .../rev_1771880798886137000.sql | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771880798886137000.sql diff --git a/data/sql/updates/pending_db_world/rev_1771880798886137000.sql b/data/sql/updates/pending_db_world/rev_1771880798886137000.sql new file mode 100644 index 000000000..c9e2bb9fb --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771880798886137000.sql @@ -0,0 +1,38 @@ +-- Update gameobject 'Bread of the Dead' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (195066)) AND (`guid` IN (240285, 240288, 240292, 240293, 240296, 240297, 240299, 240300, 240301, 240305, 240306, 240308, 240311, 240313, 240314, 240317)); +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 +(240285, 195066, 0, 0, 0, 1, 1, -9328.341796875, 170.201385498046875, 61.66754913330078125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240288, 195066, 0, 0, 0, 1, 1, -9327.125, 181.875, 61.65489959716796875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240292, 195066, 0, 0, 0, 1, 1, -5159.9931640625, -869.015625, 507.290924072265625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240293, 195066, 0, 0, 0, 1, 1, -5159.9130859375, -870.5538330078125, 507.307281494140625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240296, 195066, 1, 0, 0, 1, 1, 10065.05078125, 2118.71533203125, 1329.6578369140625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240297, 195066, 1, 0, 0, 1, 1, 10053.484375, 2128.546875, 1329.6578369140625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240299, 195066, 1, 0, 0, 1, 1, 10053.607421875, 2109.585205078125, 1329.647705078125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240300, 195066, 0, 0, 0, 1, 1, 1777.3194580078125, 220.55035400390625, 59.57674789428710937, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240301, 195066, 0, 0, 0, 1, 1, 1780.1614990234375, 269.7725830078125, 59.87250518798828125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240305, 195066, 1, 0, 0, 1, 1, 1186.07470703125, -4471.140625, 21.37079811096191406, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240306, 195066, 1, 0, 0, 1, 1, 1180.1319580078125, -4457.470703125, 21.48912811279296875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240308, 195066, 1, 0, 0, 1, 1, 1172.30908203125, -4463.2255859375, 21.28818511962890625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240311, 195066, 1, 0, 0, 1, 1, -984.6319580078125, -76.1215286254882812, 20.85416603088378906, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL), +(240313, 195066, 1, 0, 0, 1, 1, -983.00177001953125, -70.0833358764648437, 20.78368377685546875, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL), +(240314, 195066, 1, 0, 0, 1, 1, -984.9132080078125, -75.1597213745117187, 20.9375, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL), +(240317, 195066, 1, 0, 0, 1, 1, -984.30902099609375, -72.329864501953125, 20.99181556701660156, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (195066)) AND (`guid` IN (1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250)); +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 +(1241, 195066, 530, 0, 0, 1, 1, -1782.203125, 4935.56494140625, -22.6640510559082031, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1242, 195066, 530, 0, 0, 1, 1, -1835.9114990234375, 4922.8037109375, -21.2072257995605468, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1243, 195066, 530, 0, 0, 1, 1, -4310.30224609375, -12439.513671875, 17.13646507263183593, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1244, 195066, 530, 0, 0, 1, 1, -4318.94775390625, -12448.236328125, 17.12119102478027343, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1245, 195066, 530, 0, 0, 1, 1, -4319.33837890625, -12455.673828125, 17.32951545715332031, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1246, 195066, 530, 0, 0, 1, 1, -4322.93212890625, -12439.4658203125, 17.49305534362792968, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1247, 195066, 530, 0, 0, 1, 1, 9418.6708984375, -6849.43603515625, 15.08937931060791015, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1248, 195066, 530, 0, 0, 1, 1, 9418.8916015625, -6854.56591796875, 14.94360065460205078, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1249, 195066, 571, 0, 0, 1, 1, 5851.9697265625, 771.310791015625, 641.49603271484375, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL), +(1250, 195066, 571, 0, 0, 1, 1, 5856.6416015625, 765.55731201171875, 641.31524658203125, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL); + +-- enable all spawns for eventEntry 51 +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (SELECT `guid` FROM `gameobject` WHERE `id` IN (195066))); +INSERT INTO `game_event_gameobject` (SELECT 51, `guid` FROM `gameobject` WHERE `id` IN (195066)); From be468b4b35951e999f28bffaf52d671648f02182 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 24 Feb 2026 00:49:45 +0000 Subject: [PATCH 258/335] chore(DB): import pending files Referenced commit(s): badbf52adc06b2e03b5ae904833726c2bc7388a1 --- .../rev_1771880798886137000.sql => db_world/2026_02_24_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771880798886137000.sql => db_world/2026_02_24_04.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771880798886137000.sql b/data/sql/updates/db_world/2026_02_24_04.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771880798886137000.sql rename to data/sql/updates/db_world/2026_02_24_04.sql index c9e2bb9fb..e237e5a12 100644 --- a/data/sql/updates/pending_db_world/rev_1771880798886137000.sql +++ b/data/sql/updates/db_world/2026_02_24_04.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_24_03 -> 2026_02_24_04 -- Update gameobject 'Bread of the Dead' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (195066)) AND (`guid` IN (240285, 240288, 240292, 240293, 240296, 240297, 240299, 240300, 240301, 240305, 240306, 240308, 240311, 240313, 240314, 240317)); From 5d33af0d4019456ab44e2aa936ee6c543225deb4 Mon Sep 17 00:00:00 2001 From: sudlud Date: Tue, 24 Feb 2026 01:52:05 +0100 Subject: [PATCH 259/335] fix(DB/Gameobject): Sniffed Values for 'Bottle' spawns (#24837) --- .../rev_1771883662965307700.sql | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771883662965307700.sql diff --git a/data/sql/updates/pending_db_world/rev_1771883662965307700.sql b/data/sql/updates/pending_db_world/rev_1771883662965307700.sql new file mode 100644 index 000000000..aaa5bf11e --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771883662965307700.sql @@ -0,0 +1,78 @@ +-- Update gameobject 'Bottle' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (182807)) AND (`guid` IN (23644, 240263, 240265, 240266, 240267, 240268, 240269, 240270, 240271, 240272, 240273, 240274, 240275, 240276, 240277, 240278)); +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 +(23644, 182807, 530, 0, 0, 1, 1, 9672.1162109375, -7346.4375, 11.93113899230957031, 6.03883981704711914, 0, 0, -0.12186908721923828, 0.9925462007522583, 120, 255, 1, "", 45435, NULL), +(240263, 182807, 1, 0, 0, 1, 1, 1184.0242919921875, -4469.83154296875, 21.28516578674316406, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240265, 182807, 0, 0, 0, 1, 1, 1780.1805419921875, 214.78125, 59.85344696044921875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240266, 182807, 0, 0, 0, 1, 1, 1780.763916015625, 215.611114501953125, 59.79877471923828125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240267, 182807, 1, 0, 0, 1, 1, 10063.404296875, 2111.8525390625, 1329.65625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240268, 182807, 1, 0, 0, 1, 1, 10062.7314453125, 2129.979248046875, 1329.6578369140625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240269, 182807, 1, 0, 0, 1, 1, 10065.5224609375, 2118.4619140625, 1329.6578369140625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240270, 182807, 1, 0, 0, 1, 1, 10054.7939453125, 2132.236083984375, 1329.6578369140625, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240271, 182807, 1, 0, 0, 1, 1, 10053.69140625, 2125.3056640625, 1329.686767578125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240272, 182807, 0, 0, 0, 1, 1, -5161.265625, -870.734375, 507.233123779296875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240273, 182807, 0, 0, 0, 1, 1, -5160.73291015625, -871.28302001953125, 507.27001953125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240274, 182807, 0, 0, 0, 1, 1, -9326.84765625, 170.8072967529296875, 62.82540512084960937, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240275, 182807, 0, 0, 0, 1, 1, -9335.4580078125, 175.404510498046875, 61.60723114013671875, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240276, 182807, 1, 0, 0, 1, 1, 1174.357666015625, -4455.34033203125, 21.55141258239746093, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(240277, 182807, 1, 0, 0, 1, 1, -984.73785400390625, -73.1875, 20.99459648132324218, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL), +(240278, 182807, 1, 0, 0, 1, 1, -980.77081298828125, -79.8229141235351562, 20.13351821899414062, 0, 0, 0, 0, 1, 120, 255, 1, "", 46368, NULL); + +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (23644, 240263, 240265, 240266, 240267, 240268, 240269, 240270, 240271, 240272, 240273, 240274, 240275, 240276, 240277, 240278)); +INSERT INTO `game_event_gameobject` (`eventEntry`,`guid`) VALUES +-- static spawn +-- (51, 23644), +(51, 240263), +(51, 240265), +(51, 240266), +(51, 240267), +(51, 240268), +(51, 240269), +(51, 240270), +(51, 240271), +(51, 240272), +(51, 240273), +(51, 240274), +(51, 240275), +(51, 240276), +(51, 240277), +(51, 240278); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (182807)) AND (`guid` IN (1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818)); +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 +(1806, 182807, 530, 0, 0, 1, 1, -1783.0885009765625, 4936.236328125, -22.6301651000976562, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1807, 182807, 530, 0, 0, 1, 1, -1791.9254150390625, 4910.330078125, -21.3478565216064453, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1808, 182807, 530, 0, 0, 1, 1, -1836.095458984375, 4923.36279296875, -21.2411785125732421, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1809, 182807, 530, 0, 0, 1, 1, -4309.3369140625, -12420.2744140625, 17.54578399658203125, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1810, 182807, 530, 0, 0, 1, 1, -4314.44287109375, -12446.46875, 17.27439308166503906, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1811, 182807, 530, 0, 0, 1, 1, -4320.0224609375, -12455.6806640625, 17.30128669738769531, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1812, 182807, 530, 0, 0, 1, 1, -4320.51904296875, -12453.1630859375, 17.25063705444335937, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1813, 182807, 530, 0, 0, 1, 1, -4323.4375, -12438.888671875, 17.51183891296386718, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1814, 182807, 530, 0, 0, 1, 1, -4325.0087890625, -12439.8818359375, 17.46257972717285156, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1815, 182807, 530, 0, 0, 1, 1, 9417.6826171875, -6856.62841796875, 14.8602142333984375, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1816, 182807, 530, 0, 0, 1, 1, 9418.265625, -6855.798828125, 14.89146232604980468, 0, 0, 0, 0, 1, 120, 255, 1, "", 51943, NULL), +(1817, 182807, 571, 0, 0, 1, 1, 5849.689453125, 771.4617919921875, 640.58172607421875, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL), +(1818, 182807, 571, 0, 0, 1, 1, 5855.94873046875, 765.8055419921875, 641.4307861328125, 0, 0, 0, 0, 1, 120, 255, 1, "", 46248, NULL); + +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818)); +INSERT INTO `game_event_gameobject` (`eventEntry`,`guid`) VALUES +(51, 1806), +(51, 1807), +(51, 1808), +(51, 1809), +(51, 1810), +(51, 1811), +(51, 1812), +(51, 1813), +(51, 1814), +(51, 1815), +(51, 1816), +(51, 1817), +(51, 1818); + +-- remove duplicate spawns +DELETE FROM `gameobject` WHERE (`id` IN (182807)) AND (`guid` IN (240005, 240264)); +DELETE FROM `gameobject_addon` WHERE (`guid` IN (240005, 240264)); +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 51) AND (`guid` IN (240005, 240264)); From 3fb46dd4ae36a0a64a15b6efa67cbf1e496e22b9 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Mon, 23 Feb 2026 18:52:27 -0600 Subject: [PATCH 260/335] fix(Core/Spells): Fix Cut to the Chase S&D duration (#24841) Co-authored-by: blinkysc --- src/server/scripts/Spells/spell_rogue.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 72aeb1270..b0ffb02a6 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -844,19 +844,22 @@ class spell_rog_cut_to_the_chase : public AuraScript { PrepareAuraScript(spell_rog_cut_to_the_chase); - void HandleProc(ProcEventInfo& /*eventInfo*/) + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) { PreventDefaultAction(); - // Refresh Slice and Dice to 5 combo point max duration - if (AuraEffect const* snDEffect = GetTarget()->GetAuraEffect(SPELL_AURA_MOD_MELEE_HASTE, SPELLFAMILY_ROGUE, 0x40000, 0, 0)) + // Refresh Slice and Dice to its 5 combo point maximum duration + Unit* caster = eventInfo.GetActor(); + if (AuraEffect const* snd = caster->GetAuraEffect(SPELL_AURA_MOD_MELEE_HASTE, SPELLFAMILY_ROGUE, 0x40000, 0, 0, caster->GetGUID())) { - snDEffect->GetBase()->SetDuration(snDEffect->GetSpellInfo()->GetMaxDuration(), true); + int32 maxDuration = snd->GetSpellInfo()->GetMaxDuration(); + snd->GetBase()->SetDuration(maxDuration, true); + snd->GetBase()->SetMaxDuration(snd->GetBase()->GetDuration()); } } void Register() override { - OnProc += AuraProcFn(spell_rog_cut_to_the_chase::HandleProc); + OnEffectProc += AuraEffectProcFn(spell_rog_cut_to_the_chase::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); } }; From d1c548d1276aa4bdc899240682c042e1cf8c5bef Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 24 Feb 2026 00:53:08 +0000 Subject: [PATCH 261/335] chore(DB): import pending files Referenced commit(s): 5d33af0d4019456ab44e2aa936ee6c543225deb4 --- .../rev_1771883662965307700.sql => db_world/2026_02_24_05.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771883662965307700.sql => db_world/2026_02_24_05.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771883662965307700.sql b/data/sql/updates/db_world/2026_02_24_05.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771883662965307700.sql rename to data/sql/updates/db_world/2026_02_24_05.sql index aaa5bf11e..4d7dfa70f 100644 --- a/data/sql/updates/pending_db_world/rev_1771883662965307700.sql +++ b/data/sql/updates/db_world/2026_02_24_05.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_24_04 -> 2026_02_24_05 -- Update gameobject 'Bottle' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (182807)) AND (`guid` IN (23644, 240263, 240265, 240266, 240267, 240268, 240269, 240270, 240271, 240272, 240273, 240274, 240275, 240276, 240277, 240278)); From b4773da8a2d547d932424286037be5e98df9e5fd Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Tue, 24 Feb 2026 04:03:44 +0100 Subject: [PATCH 262/335] chore(Github): Update issue labeler action to version 1.0.3 (#24802) --- .github/workflows/issue-labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/issue-labeler.yml b/.github/workflows/issue-labeler.yml index 2c3fd0e99..1a87c1419 100644 --- a/.github/workflows/issue-labeler.yml +++ b/.github/workflows/issue-labeler.yml @@ -11,6 +11,6 @@ jobs: steps: - name: Issue Labeler id: issue-labeler - uses: azerothcore/GitHub-Actions@issue-labeler-1.0.2 + uses: azerothcore/GitHub-Actions@issue-labeler-1.0.3 with: token: ${{ secrets.GITHUB_TOKEN }} From 56d2efc31eda6bbcf57fe153345622b8a9eab1e9 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Mon, 23 Feb 2026 22:52:40 -0500 Subject: [PATCH 263/335] fix(Core/AuthSession): Correct typo in query field fetch. (#24842) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 天鹭 <18535853+PkllonG@users.noreply.github.com> --- src/server/apps/authserver/Server/AuthSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/apps/authserver/Server/AuthSession.cpp b/src/server/apps/authserver/Server/AuthSession.cpp index ce4a1e590..b0692a03b 100644 --- a/src/server/apps/authserver/Server/AuthSession.cpp +++ b/src/server/apps/authserver/Server/AuthSession.cpp @@ -155,7 +155,7 @@ void AccountInfo::LoadResult(Field* fields) FailedLogins = fields[6].Get(); IsBanned = fields[7].Get() || fields[9].Get(); IsPermanentlyBanned = fields[8].Get() || fields[10].Get(); - SecurityLevel = static_cast(fields[11].Get()) > SEC_CONSOLE ? SEC_CONSOLE : static_cast(fields[12].Get()); + SecurityLevel = static_cast(fields[11].Get()) > SEC_CONSOLE ? SEC_CONSOLE : static_cast(fields[11].Get()); // Use our own uppercasing of the account name instead of using UPPER() in mysql query // This is how the account was created in the first place and changing it now would result in breaking From cd2f222946f53aaeb4c3c2525e6c194b0018460a Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Tue, 24 Feb 2026 00:56:30 -0600 Subject: [PATCH 264/335] fix(Core/Spells): Fix negative SPELL_AURA_MOD_DAMAGE_DONE client display (#24843) Co-authored-by: blinkysc Co-authored-by: ariel- --- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 1b793832b..5b8599136 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5340,11 +5340,10 @@ void AuraEffect::HandleModDamageDone(AuraApplication const* aurApp, uint8 mode, // This information for client side use only if (target->IsPlayer()) { - uint16 baseField = GetAmount() >= 0 ? PLAYER_FIELD_MOD_DAMAGE_DONE_POS : PLAYER_FIELD_MOD_DAMAGE_DONE_NEG; for (uint16 i = 0; i < MAX_SPELL_SCHOOL; ++i) if (GetMiscValue() & (1 << i)) - target->ApplyModUInt32Value(baseField + i, GetAmount(), apply); + target->ApplyModInt32Value(baseField + i, GetAmount(), apply); if (Guardian* pet = target->ToPlayer()->GetGuardianPet()) pet->UpdateAttackPowerAndDamage(); From 0e562c3209de1c20cb23fc8a85955907f77dbfd5 Mon Sep 17 00:00:00 2001 From: Tereneckla Date: Tue, 24 Feb 2026 15:24:33 +0000 Subject: [PATCH 265/335] fix(DB/Spell): update Maelstrom Weapon PPM (#24845) --- .../updates/pending_db_world/rev_1771922837503577074.sql | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771922837503577074.sql diff --git a/data/sql/updates/pending_db_world/rev_1771922837503577074.sql b/data/sql/updates/pending_db_world/rev_1771922837503577074.sql new file mode 100644 index 000000000..22c933cce --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771922837503577074.sql @@ -0,0 +1,6 @@ +-- +UPDATE `spell_proc`SET `ProcsPerMinute` = 2 WHERE `SpellId` = 51528; +UPDATE `spell_proc`SET `ProcsPerMinute` = 4 WHERE `SpellId` = 51529; +UPDATE `spell_proc`SET `ProcsPerMinute` = 6 WHERE `SpellId` = 51530; +UPDATE `spell_proc`SET `ProcsPerMinute` = 8 WHERE `SpellId` = 51531; +UPDATE `spell_proc`SET `ProcsPerMinute` = 10 WHERE `SpellId` = 51532; From 9b04591440a38d867348b1392c83c1d8ec43a69e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 24 Feb 2026 15:25:43 +0000 Subject: [PATCH 266/335] chore(DB): import pending files Referenced commit(s): 0e562c3209de1c20cb23fc8a85955907f77dbfd5 --- .../rev_1771922837503577074.sql => db_world/2026_02_24_06.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771922837503577074.sql => db_world/2026_02_24_06.sql} (88%) diff --git a/data/sql/updates/pending_db_world/rev_1771922837503577074.sql b/data/sql/updates/db_world/2026_02_24_06.sql similarity index 88% rename from data/sql/updates/pending_db_world/rev_1771922837503577074.sql rename to data/sql/updates/db_world/2026_02_24_06.sql index 22c933cce..cbe15a9e5 100644 --- a/data/sql/updates/pending_db_world/rev_1771922837503577074.sql +++ b/data/sql/updates/db_world/2026_02_24_06.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_24_05 -> 2026_02_24_06 -- UPDATE `spell_proc`SET `ProcsPerMinute` = 2 WHERE `SpellId` = 51528; UPDATE `spell_proc`SET `ProcsPerMinute` = 4 WHERE `SpellId` = 51529; From 06d16564024bd974ba14ab153f0ee9a94835214d Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 24 Feb 2026 19:34:15 -0300 Subject: [PATCH 267/335] =?UTF-8?q?fix(Scripts/Ulduar):=20Remove=20GUID-ba?= =?UTF-8?q?sed=20harpoon=20identification=20in=20Razors=E2=80=A6=20(#24846?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Keader Co-authored-by: Claude Opus 4.6 --- .../Ulduar/Ulduar/boss_razorscale.cpp | 119 +++++++----------- .../Ulduar/Ulduar/instance_ulduar.cpp | 21 ---- .../scripts/Northrend/Ulduar/Ulduar/ulduar.h | 6 - 3 files changed, 44 insertions(+), 102 deletions(-) diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index 2a2efb95c..9a0315e9f 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -44,7 +44,6 @@ enum Spells SPELL_CHAIN_2 = 49682, SPELL_CHAIN_3 = 49683, SPELL_CHAIN_4 = 49684, - SPELL_LAUNCH_CHAIN = 62505, // Dark Rune Sentinel SPELL_WHIRLWIND = 63808, @@ -207,31 +206,11 @@ struct boss_razorscale : public BossAI void SpellHit(Unit* caster, SpellInfo const* spell) override { - if (!caster || !instance) + if (!caster) return; switch (spell->Id) { - case SPELL_LAUNCH_CHAIN: - { - uint32 spellId = SPELL_CHAIN_4; - - if (caster->GetGUID() == instance->GetGuidData(DATA_HARPOON_FIRE_STATE_1)) - { - spellId = SPELL_CHAIN_1; - } - else if (caster->GetGUID() == instance->GetGuidData(DATA_HARPOON_FIRE_STATE_2)) - { - spellId = SPELL_CHAIN_2; - } - else if (caster->GetGUID() == instance->GetGuidData(DATA_HARPOON_FIRE_STATE_3)) - { - spellId = SPELL_CHAIN_3; - } - - caster->CastSpell(me, spellId, true); - } - break; case SPELL_CHAIN_1: case SPELL_CHAIN_2: case SPELL_CHAIN_3: @@ -447,16 +426,16 @@ struct boss_razorscale : public BossAI events.ScheduleEvent(EVENT_FLY_UP, 2s); break; case EVENT_FLY_UP: + { me->SetInCombatWithZone(); // just in case - if (instance) - for( int i = 0; i < 4; ++i ) - if (Creature* hfs = instance->GetCreature(DATA_HARPOON_FIRE_STATE_1 + i)) - { - me->SummonCreature(34188, hfs->GetPositionX(), hfs->GetPositionY(), hfs->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 22000); - hfs->AI()->SetData(1, 0); - } + std::list hfsList; + me->GetCreaturesWithEntryInRange(hfsList, 300.0f, NPC_HARPOON_FIRE_STATE); + for (Creature* hfs : hfsList) + { + me->SummonCreature(34188, hfs->GetPositionX(), hfs->GetPositionY(), hfs->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 22000); + hfs->AI()->SetData(1, 0); + } - me->RemoveAura(SPELL_LAUNCH_CHAIN); me->RemoveAura(SPELL_CHAIN_1); me->RemoveAura(SPELL_CHAIN_3); if (RAID_MODE(0, 1)) @@ -506,6 +485,7 @@ struct boss_razorscale : public BossAI } break; + } case EVENT_RESUME_FIXING: for (uint8 i = 0; i < 3; ++i) if (Creature* c = ObjectAccessor::GetCreature(*me, ExpeditionEngineerGUIDs[i])) @@ -621,9 +601,10 @@ public: creature->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); // reset npcs NPC_HARPOON_FIRE_STATE - for (uint8 i = 0; i < 4; ++i) - if (Creature* hfs = instance->GetCreature(DATA_HARPOON_FIRE_STATE_1 + i)) - hfs->AI()->SetData(1, 0); + std::list hfsList; + razorscale->GetCreaturesWithEntryInRange(hfsList, 300.0f, NPC_HARPOON_FIRE_STATE); + for (Creature* hfs : hfsList) + hfs->AI()->SetData(1, 0); if (razorscale->AI()) { @@ -687,18 +668,19 @@ struct npc_ulduar_harpoonfirestate : public NullCreatureAI uint32 GetHarpoonGunIdForThisHFS() { - if (pInstance) - { - if (me->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_1)) - return GO_HARPOON_GUN_1; - else if (me->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_2)) - return GO_HARPOON_GUN_2; - else if (me->GetGUID() == pInstance->GetGuidData(DATA_HARPOON_FIRE_STATE_3)) - return GO_HARPOON_GUN_3; - else - return GO_HARPOON_GUN_4; - } - return 0; + static uint32 const harpoonEntries[] = { GO_HARPOON_GUN_1, GO_HARPOON_GUN_2, GO_HARPOON_GUN_3, GO_HARPOON_GUN_4 }; + for (uint32 entry : harpoonEntries) + if (me->FindNearestGameObject(entry, 5.0f)) + return entry; + + // Fallback: determine by X position + if (me->GetPositionX() > 595) + return GO_HARPOON_GUN_4; + else if (me->GetPositionX() > 585) + return GO_HARPOON_GUN_3; + else if (me->GetPositionX() > 575) + return GO_HARPOON_GUN_2; + return GO_HARPOON_GUN_1; } void SetData(uint32 id, uint32 value) override @@ -706,7 +688,6 @@ struct npc_ulduar_harpoonfirestate : public NullCreatureAI switch (id) { case 1: // cleanup at the start of the fight - if (pInstance) { uint32 h_entry = GetHarpoonGunIdForThisHFS(); if (GameObject* wh = me->FindNearestGameObject(h_entry, 5.0f)) @@ -743,7 +724,7 @@ struct npc_ulduar_harpoonfirestate : public NullCreatureAI if (!razorscale) return; if (!razorscale->HasAura(value)) - me->CastSpell(razorscale, SPELL_LAUNCH_CHAIN, true); + me->CastSpell(razorscale, value, true); } break; } @@ -832,15 +813,16 @@ struct npc_ulduar_expedition_engineer : public NullCreatureAI return; } - for( int i = 0; i < 4; ++i ) - if (Creature* fs = pInstance->GetCreature(DATA_HARPOON_FIRE_STATE_1 + i)) - if (!fs->AI()->GetData(2)) - { - float a = rand_norm() * M_PI; - me->GetMotionMaster()->MovePoint(0, fs->GetPositionX() + 3.0f * cos(a), fs->GetPositionY() + 3.0f * std::sin(a), fs->GetPositionZ()); - fixingGUID = fs->GetGUID(); - return; - } + std::list hfsList; + me->GetCreaturesWithEntryInRange(hfsList, 300.0f, NPC_HARPOON_FIRE_STATE); + for (Creature* fs : hfsList) + if (!fs->AI()->GetData(2)) + { + float a = rand_norm() * M_PI; + me->GetMotionMaster()->MovePoint(0, fs->GetPositionX() + 3.0f * cos(a), fs->GetPositionY() + 3.0f * std::sin(a), fs->GetPositionZ()); + fixingGUID = fs->GetGUID(); + return; + } Reset(); // all harpoons repaired me->GetMotionMaster()->MoveTargetedHome(); @@ -877,30 +859,17 @@ public: return true; } - uint32 npc = 0; uint32 spell = 0; switch (go->GetEntry()) { - case GO_HARPOON_GUN_1: - npc = DATA_HARPOON_FIRE_STATE_1; - spell = SPELL_CHAIN_1; - break; - case GO_HARPOON_GUN_2: - npc = DATA_HARPOON_FIRE_STATE_2; - spell = SPELL_CHAIN_2; - break; - case GO_HARPOON_GUN_3: - npc = DATA_HARPOON_FIRE_STATE_3; - spell = SPELL_CHAIN_3; - break; - case GO_HARPOON_GUN_4: - npc = DATA_HARPOON_FIRE_STATE_4; - spell = SPELL_CHAIN_4; - break; + case GO_HARPOON_GUN_1: spell = SPELL_CHAIN_1; break; + case GO_HARPOON_GUN_2: spell = SPELL_CHAIN_2; break; + case GO_HARPOON_GUN_3: spell = SPELL_CHAIN_3; break; + case GO_HARPOON_GUN_4: spell = SPELL_CHAIN_4; break; } - if (Creature* hfs = pInstance->GetCreature(npc)) - hfs->AI()->SetData(3, spell); + if (Creature* hfs = go->FindNearestCreature(NPC_HARPOON_FIRE_STATE, 5.0f)) + hfs->AI()->SetData(3, spell); go->SetLootState(GO_JUST_DEACTIVATED); return true; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index 3d179883c..7d4b0d1d3 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -154,9 +154,6 @@ public: uint32 m_unbrokenAchievement; uint32 m_mageBarrier; - // Razorscale - ObjectGuid m_RazorscaleHarpoonFireStateGUID[4]; - // Hodir bool hmHodir; Position normalChestPosition = { 1967.152588f, -204.188461f, 432.686951f, 5.50957f }; @@ -472,18 +469,6 @@ public: if (!m_algalonTimer) creature->DespawnOrUnsummon(); break; - case NPC_HARPOON_FIRE_STATE: - { - if (creature->GetPositionX() > 595 ) - m_RazorscaleHarpoonFireStateGUID[3] = creature->GetGUID(); - else if (creature->GetPositionX() > 585 ) - m_RazorscaleHarpoonFireStateGUID[2] = creature->GetGUID(); - else if (creature->GetPositionX() > 575 ) - m_RazorscaleHarpoonFireStateGUID[1] = creature->GetGUID(); - else - m_RazorscaleHarpoonFireStateGUID[0] = creature->GetGUID(); - } - break; //! These creatures are summoned by something else than Algalon //! but need to be controlled/despawned by him - so they need to be //! registered in his summon list @@ -803,12 +788,6 @@ public: case DATA_REPAIR_STATION2: return m_RepairSGUID[1]; - // Razorscales Harpoon Fire State GUIDs - case DATA_HARPOON_FIRE_STATE_1: - case DATA_HARPOON_FIRE_STATE_2: - case DATA_HARPOON_FIRE_STATE_3: - case DATA_HARPOON_FIRE_STATE_4: - return m_RazorscaleHarpoonFireStateGUID[data - 200]; } return GetObjectGuid(data); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index f443536ea..5307e6758 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -66,12 +66,6 @@ enum UlduarData DATA_UNBROKEN_ACHIEVEMENT = 105, DATA_LEVIATHAN_DOORS = 106, - // Razorscales Harpoon Fire State GUIDs - DATA_HARPOON_FIRE_STATE_1 = 200, - DATA_HARPOON_FIRE_STATE_2 = 201, - DATA_HARPOON_FIRE_STATE_3 = 202, - DATA_HARPOON_FIRE_STATE_4 = 203, - // Mimiron creatures DATA_MIMIRON_LEVIATHAN_MKII = 301, DATA_MIMIRON_VX001 = 302, From 30beeed2aea1ebc778c969225f03fdc809a1c779 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Tue, 24 Feb 2026 17:17:24 -0600 Subject: [PATCH 268/335] fix(Core/Spells): Block SPELL_EFFECT_ENERGIZE_PCT on isolated targets (#24844) Co-authored-by: blinkysc --- src/server/game/Spells/SpellEffects.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 730dc9859..634bde4f1 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1997,6 +1997,12 @@ void Spell::EffectEnergizePct(SpellEffIndex effIndex) if (!unitTarget->IsAlive()) return; + if (unitTarget->HasUnitState(UNIT_STATE_ISOLATED)) + { + m_caster->SendSpellDamageImmune(unitTarget, GetSpellInfo()->Id); + return; + } + if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS)) return; From 90d7228222ad58ffd8386352869e0e000b57552c Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Tue, 24 Feb 2026 17:17:40 -0600 Subject: [PATCH 269/335] fix(Core/Spells): Fix Piercing Shots to roll remaining damage on refresh (#24852) Co-authored-by: blinkysc --- src/server/scripts/Spells/spell_hunter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 8a10dede6..7877a9bd9 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -1581,7 +1581,7 @@ class spell_hun_piercing_shots : public AuraScript ASSERT(piercingShots->GetMaxTicks() > 0); bp /= piercingShots->GetMaxTicks(); - caster->CastCustomSpell(target, SPELL_HUNTER_PIERCING_SHOTS, &bp, nullptr, nullptr, true, nullptr, aurEff); + target->CastDelayedSpellWithPeriodicAmount(caster, SPELL_HUNTER_PIERCING_SHOTS, SPELL_AURA_PERIODIC_DAMAGE, bp); } void Register() override From 1e73383b54ac1912ccf0ab87db36cce24758f1cb Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Tue, 24 Feb 2026 19:04:14 -0600 Subject: [PATCH 270/335] fix(Core/Spells): Restore asserts in SetSpellModTakingSpell (#24862) Co-authored-by: blinkysc --- src/server/game/Entities/Player/Player.cpp | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a27181eec..c2ea1d5f9 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -10028,22 +10028,9 @@ bool Player::HasSpellModApplied(SpellModifier* mod, Spell* spell) void Player::SetSpellModTakingSpell(Spell* spell, bool apply) { if (apply && m_spellModTakingSpell) - { - LOG_INFO("misc", "Player::SetSpellModTakingSpell (A1) - {}, {}", spell->m_spellInfo->Id, m_spellModTakingSpell->m_spellInfo->Id); - return; - //ASSERT(m_spellModTakingSpell == nullptr); - } + ASSERT(m_spellModTakingSpell == nullptr); else if (!apply) - { - if (!m_spellModTakingSpell) - LOG_INFO("misc", "Player::SetSpellModTakingSpell (B1) - {}", spell->m_spellInfo->Id); - else if (m_spellModTakingSpell != spell) - { - LOG_INFO("misc", "Player::SetSpellModTakingSpell (C1) - {}, {}", spell->m_spellInfo->Id, m_spellModTakingSpell->m_spellInfo->Id); - return; - } - //ASSERT(m_spellModTakingSpell && m_spellModTakingSpell == spell); - } + ASSERT(m_spellModTakingSpell && m_spellModTakingSpell == spell); m_spellModTakingSpell = apply ? spell : nullptr; } From 25ff0c9ef491457576092255529cef1f05284c0f Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Tue, 24 Feb 2026 19:15:16 -0600 Subject: [PATCH 271/335] fix(Core/Spells): Exempt kill/death events from triggered-spell proc filter (#24859) Co-authored-by: blinkysc --- src/server/game/Spells/Auras/SpellAuras.cpp | 5 +- src/test/mocks/ProcChanceTestHelper.h | 6 +- .../Spells/SpellProcTriggeredFilterTest.cpp | 108 ++++++++++++++++++ 3 files changed, 117 insertions(+), 2 deletions(-) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index d313b5ca1..9bb9ba9e3 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2164,9 +2164,12 @@ uint8 Aura::GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo, return 0; // check if aura can proc when spell is triggered (exception for hunter auto shot & wands) + // Kill/killed/death events should not be blocked by the triggered-spell check - + // the kill itself is the proc trigger, not the spell that dealt the killing blow if (!GetSpellInfo()->HasAttribute(SPELL_ATTR3_CAN_PROC_FROM_PROCS) && !(procEntry->AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC) && - !(eventInfo.GetTypeMask() & AUTO_ATTACK_PROC_FLAG_MASK)) + !(eventInfo.GetTypeMask() & AUTO_ATTACK_PROC_FLAG_MASK) && + !(eventInfo.GetTypeMask() & (PROC_FLAG_KILL | PROC_FLAG_KILLED | PROC_FLAG_DEATH))) { if (spell->IsTriggered() && !spell->GetSpellInfo()->HasAttribute(SPELL_ATTR3_NOT_A_PROC)) return 0; diff --git a/src/test/mocks/ProcChanceTestHelper.h b/src/test/mocks/ProcChanceTestHelper.h index 41e0dfa38..6ce878b8f 100644 --- a/src/test/mocks/ProcChanceTestHelper.h +++ b/src/test/mocks/ProcChanceTestHelper.h @@ -268,9 +268,13 @@ public: // Check if triggered spell filtering applies // SpellAuras.cpp:2195-2208 + static constexpr uint32 KILL_DEATH_PROC_FLAG_MASK = + PROC_FLAG_KILL | PROC_FLAG_KILLED | PROC_FLAG_DEATH; + if (!config.auraHasCanProcFromProcs && !(procEntry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC) && - !(eventTypeMask & AUTO_ATTACK_PROC_FLAG_MASK)) + !(eventTypeMask & AUTO_ATTACK_PROC_FLAG_MASK) && + !(eventTypeMask & KILL_DEATH_PROC_FLAG_MASK)) { // Filter triggered spells unless they have NOT_A_PROC if (config.isTriggered && !config.spellHasNotAProc) diff --git a/src/test/server/game/Spells/SpellProcTriggeredFilterTest.cpp b/src/test/server/game/Spells/SpellProcTriggeredFilterTest.cpp index 997425915..d55510e34 100644 --- a/src/test/server/game/Spells/SpellProcTriggeredFilterTest.cpp +++ b/src/test/server/game/Spells/SpellProcTriggeredFilterTest.cpp @@ -251,6 +251,114 @@ TEST_F(SpellProcTriggeredFilterTest, TakenAutoAttack_AllowsTriggeredSpells) << "TAKEN_MELEE_AUTO_ATTACK should allow triggered spells"; } +// ============================================================================= +// PROC_FLAG_KILL / PROC_FLAG_KILLED / PROC_FLAG_DEATH Exception +// Kill/death events bypass the triggered-spell filter because +// the kill itself is the proc trigger, not the spell that dealt +// the killing blow. +// ============================================================================= + +TEST_F(SpellProcTriggeredFilterTest, KillEvent_AllowsTriggeredSpells) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = false; + + auto procEntry = CreateBasicProcEntry(); + + // PROC_FLAG_KILL should bypass triggered-spell filter + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_KILL)) + << "PROC_FLAG_KILL should allow triggered spells"; +} + +TEST_F(SpellProcTriggeredFilterTest, KilledEvent_AllowsTriggeredSpells) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = false; + + auto procEntry = CreateBasicProcEntry(); + + // PROC_FLAG_KILLED should bypass triggered-spell filter + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_KILLED)) + << "PROC_FLAG_KILLED should allow triggered spells"; +} + +TEST_F(SpellProcTriggeredFilterTest, DeathEvent_AllowsTriggeredSpells) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = false; + + auto procEntry = CreateBasicProcEntry(); + + // PROC_FLAG_DEATH should bypass triggered-spell filter + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_DEATH)) + << "PROC_FLAG_DEATH should allow triggered spells"; +} + +TEST_F(SpellProcTriggeredFilterTest, KillWithOtherFlags_StillAllowsTriggeredSpells) +{ + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.auraHasCanProcFromProcs = false; + config.spellHasNotAProc = false; + + auto procEntry = CreateBasicProcEntry(); + + // PROC_FLAG_KILL combined with other flags should still bypass + uint32 combinedEvent = PROC_FLAG_KILL | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG; + + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, combinedEvent)) + << "PROC_FLAG_KILL combined with other flags should still bypass filter"; +} + +TEST_F(SpellProcTriggeredFilterTest, Scenario_RapidKilling_AutoShotKill) +{ + // Rapid Killing (34949) has PROC_FLAG_KILL + // Auto Shot (75) repeated casts are IsTriggered=true + // Kill event should proc Rapid Killing regardless + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; // Auto Shot is triggered + config.auraHasCanProcFromProcs = false; // Rapid Killing doesn't have this + config.spellHasNotAProc = false; // Auto Shot doesn't have NOT_A_PROC + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_KILL) + .WithChance(100.0f) + .Build(); + + // PROC_FLAG_KILL exemption should allow this + EXPECT_FALSE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_KILL)) + << "Rapid Killing should proc from Auto Shot kill"; +} + +TEST_F(SpellProcTriggeredFilterTest, KillEvent_SelfLoopStillBlocked) +{ + // Even with kill event exemption, self-loop should still be blocked + ProcChanceTestHelper::TriggeredSpellConfig config; + config.isTriggered = true; + config.triggeredByAuraSpellId = 34949; // Same as proc aura + config.procAuraSpellId = 34949; + + auto procEntry = SpellProcEntryBuilder() + .WithProcFlags(PROC_FLAG_KILL) + .WithChance(100.0f) + .Build(); + + EXPECT_TRUE(ProcChanceTestHelper::ShouldBlockTriggeredSpell( + config, procEntry, PROC_FLAG_KILL)) + << "Self-loop should still block even on kill events"; +} + // ============================================================================= // Combined Scenarios // ============================================================================= From b31a9379b8da0bdeed0a11ce936876436bb32b76 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 24 Feb 2026 22:25:16 -0300 Subject: [PATCH 272/335] fix(Scripts/Ulduar): fix teleporters not activating after boss kills (#24860) Co-authored-by: Vincent-Michael Co-authored-by: Claude Sonnet 4.6 Co-authored-by: Keader --- .../rev_1771973777858165300.sql | 2 ++ .../rev_1771974367980813900.sql | 14 ++++++++ .../Northrend/Ulduar/Ulduar/ulduar.cpp | 36 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771973777858165300.sql create mode 100644 data/sql/updates/pending_db_world/rev_1771974367980813900.sql diff --git a/data/sql/updates/pending_db_world/rev_1771973777858165300.sql b/data/sql/updates/pending_db_world/rev_1771973777858165300.sql new file mode 100644 index 000000000..515a8ce6e --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771973777858165300.sql @@ -0,0 +1,2 @@ +-- +UPDATE `conditions` SET `ConditionValue3` = 2 WHERE `SourceGroup` = 10389 AND `SourceEntry` IN (0, 1, 2, 3, 4, 5, 6, 8) AND `SourceTypeOrReferenceId` = 15; diff --git a/data/sql/updates/pending_db_world/rev_1771974367980813900.sql b/data/sql/updates/pending_db_world/rev_1771974367980813900.sql new file mode 100644 index 000000000..3a4311632 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771974367980813900.sql @@ -0,0 +1,14 @@ +DELETE FROM `smart_scripts` WHERE `entryorguid` = 194569 AND `source_type` = 1 AND `id` IN (0, 1, 2); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceGroup` = 2 AND `SourceEntry` = 194569 AND `SourceId` = 1; +DELETE FROM `spell_script_names` WHERE `spell_id` IN (64014, 64024, 64025, 64028, 64029, 64030, 64031, 64032, 65042); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(64014, 'spell_ulduar_teleporter'), +(64024, 'spell_ulduar_teleporter'), +(64025, 'spell_ulduar_teleporter'), +(64028, 'spell_ulduar_teleporter'), +(64029, 'spell_ulduar_teleporter'), +(64030, 'spell_ulduar_teleporter'), +(64031, 'spell_ulduar_teleporter'), +(64032, 'spell_ulduar_teleporter'), +(65042, 'spell_ulduar_teleporter'); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp index 4a72bf5ab..0601363a2 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.cpp @@ -23,6 +23,7 @@ #include "Player.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" +#include "Spell.h" #include "SpellAuraEffects.h" #include "SpellScript.h" #include "SpellScriptLoader.h" @@ -544,9 +545,44 @@ struct npc_salvaged_siege_engine : public VehicleAI } }; +// 64014 - Expedition Base Camp Teleport +// 64024 - Conservatory of Life Teleport +// 64025 - Halls of Invention Teleport +// 64028 - Colossal Forge Teleport +// 64029 - Shattered Walkway Teleport +// 64030 - Antechamber of Ulduar Teleport +// 64031 - Scrapyard Teleport +// 64032 - Formation Grounds Teleport +// 65042 - Prison of Yogg-Saron Teleport +class spell_ulduar_teleporter : public SpellScript +{ + PrepareSpellScript(spell_ulduar_teleporter); + + SpellCastResult CheckRequirement() + { + Unit* target = GetExplTargetUnit(); + if (!target || !target->IsPlayer()) + return SPELL_FAILED_DONT_REPORT; + + if (target->IsInCombat()) + { + Spell::SendCastResult(target->ToPlayer(), GetSpellInfo(), 0, SPELL_FAILED_AFFECTING_COMBAT); + return SPELL_FAILED_AFFECTING_COMBAT; + } + + return SPELL_CAST_OK; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_ulduar_teleporter::CheckRequirement); + } +}; + void AddSC_ulduar() { new npc_ulduar_keeper(); + RegisterSpellScript(spell_ulduar_teleporter); RegisterSpellScript(spell_ulduar_energy_sap_aura); RegisterUlduarCreatureAI(npc_ulduar_snow_mound); RegisterUlduarCreatureAI(npc_ulduar_storm_tempered_keeper); From fca1ee550de866bbd3d089d76ca60a13d521142e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 01:26:24 +0000 Subject: [PATCH 273/335] chore(DB): import pending files Referenced commit(s): b31a9379b8da0bdeed0a11ce936876436bb32b76 --- .../rev_1771973777858165300.sql => db_world/2026_02_25_00.sql} | 1 + .../rev_1771974367980813900.sql => db_world/2026_02_25_01.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1771973777858165300.sql => db_world/2026_02_25_00.sql} (78%) rename data/sql/updates/{pending_db_world/rev_1771974367980813900.sql => db_world/2026_02_25_01.sql} (94%) diff --git a/data/sql/updates/pending_db_world/rev_1771973777858165300.sql b/data/sql/updates/db_world/2026_02_25_00.sql similarity index 78% rename from data/sql/updates/pending_db_world/rev_1771973777858165300.sql rename to data/sql/updates/db_world/2026_02_25_00.sql index 515a8ce6e..0c2545ebc 100644 --- a/data/sql/updates/pending_db_world/rev_1771973777858165300.sql +++ b/data/sql/updates/db_world/2026_02_25_00.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_24_06 -> 2026_02_25_00 -- UPDATE `conditions` SET `ConditionValue3` = 2 WHERE `SourceGroup` = 10389 AND `SourceEntry` IN (0, 1, 2, 3, 4, 5, 6, 8) AND `SourceTypeOrReferenceId` = 15; diff --git a/data/sql/updates/pending_db_world/rev_1771974367980813900.sql b/data/sql/updates/db_world/2026_02_25_01.sql similarity index 94% rename from data/sql/updates/pending_db_world/rev_1771974367980813900.sql rename to data/sql/updates/db_world/2026_02_25_01.sql index 3a4311632..cb8ab60b1 100644 --- a/data/sql/updates/pending_db_world/rev_1771974367980813900.sql +++ b/data/sql/updates/db_world/2026_02_25_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_00 -> 2026_02_25_01 DELETE FROM `smart_scripts` WHERE `entryorguid` = 194569 AND `source_type` = 1 AND `id` IN (0, 1, 2); DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceGroup` = 2 AND `SourceEntry` = 194569 AND `SourceId` = 1; From e17df40a570d79eef75f7cba47af32154a3f079f Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Tue, 24 Feb 2026 19:38:11 -0600 Subject: [PATCH 274/335] fix(Core/Spells): Fix SetSpellModTakingSpell assert from re-entrant calls (#24863) Co-authored-by: blinkysc --- src/server/game/Entities/Player/Player.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c2ea1d5f9..532263828 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -10027,10 +10027,10 @@ bool Player::HasSpellModApplied(SpellModifier* mod, Spell* spell) void Player::SetSpellModTakingSpell(Spell* spell, bool apply) { - if (apply && m_spellModTakingSpell) - ASSERT(m_spellModTakingSpell == nullptr); - else if (!apply) - ASSERT(m_spellModTakingSpell && m_spellModTakingSpell == spell); + if (apply && m_spellModTakingSpell && m_spellModTakingSpell != spell) + return; + else if (!apply && m_spellModTakingSpell != spell) + return; m_spellModTakingSpell = apply ? spell : nullptr; } From f88fda4f1972d32d26140cf91432caa9ef5578da Mon Sep 17 00:00:00 2001 From: dataCenter430 <161712630+dataCenter430@users.noreply.github.com> Date: Tue, 24 Feb 2026 21:39:24 -0500 Subject: [PATCH 275/335] feat(Core/LFG): Implement Debug.LFG config option (#24854) --- .../acore_string_debug_lfg_conf.sql | 4 ++++ src/server/apps/worldserver/worldserver.conf.dist | 8 ++++++++ src/server/game/DungeonFinding/LFGMgr.cpp | 14 +++++++++++--- src/server/game/Miscellaneous/Language.h | 3 ++- src/server/game/World/WorldConfig.cpp | 1 + src/server/game/World/WorldConfig.h | 1 + 6 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 data/sql/updates/pending_db_world/acore_string_debug_lfg_conf.sql diff --git a/data/sql/updates/pending_db_world/acore_string_debug_lfg_conf.sql b/data/sql/updates/pending_db_world/acore_string_debug_lfg_conf.sql new file mode 100644 index 000000000..b7411f9e6 --- /dev/null +++ b/data/sql/updates/pending_db_world/acore_string_debug_lfg_conf.sql @@ -0,0 +1,4 @@ +-- Add acore_string for Debug.LFG config message (same pattern as Debug.Battleground / Debug.Arena) +DELETE FROM `acore_string` WHERE `entry` = 30098; +INSERT INTO `acore_string` (`entry`, `content_default`) VALUES +(30098, 'LFG Debugging is already enabled in the config, thus you are unable to enable/disable it with command.'); diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 16d333b21..3bb2c4b85 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -4666,6 +4666,14 @@ Debug.Battleground = 0 Debug.Arena = 0 +# +# Debug.LFG +# Description: Enable or disable LFG 1 player queue mode. (If enabled, the in-game command is disabled.) +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Debug.LFG = 0 + # ################################################################################################### diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index fe44c400d..61724fa25 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -42,7 +42,7 @@ namespace lfg { - LFGMgr::LFGMgr(): m_lfgProposalId(1), m_options(sWorld->getIntConfig(CONFIG_LFG_OPTIONSMASK)), m_Testing(false) + LFGMgr::LFGMgr(): m_lfgProposalId(1), m_options(sWorld->getIntConfig(CONFIG_LFG_OPTIONSMASK)), m_Testing(sWorld->getBoolConfig(CONFIG_DEBUG_LFG)) { for (uint8 team = 0; team < 2; ++team) { @@ -805,8 +805,16 @@ namespace lfg void LFGMgr::ToggleTesting() { - m_Testing = !m_Testing; - ChatHandler(nullptr).SendWorldText(m_Testing ? LANG_DEBUG_LFG_ON : LANG_DEBUG_LFG_OFF); + if (sWorld->getBoolConfig(CONFIG_DEBUG_LFG)) + { + m_Testing = true; + ChatHandler(nullptr).SendWorldText(LANG_DEBUG_LFG_CONF); + } + else + { + m_Testing = !m_Testing; + ChatHandler(nullptr).SendWorldText(m_Testing ? LANG_DEBUG_LFG_ON : LANG_DEBUG_LFG_OFF); + } } /** diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 31ae7965a..7d76a57cc 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1368,6 +1368,7 @@ enum AcoreStrings // 30087-30095 reserved for passive anticheat LANG_DEBUG_LFG_ON = 30096, - LANG_DEBUG_LFG_OFF = 30097 + LANG_DEBUG_LFG_OFF = 30097, + LANG_DEBUG_LFG_CONF = 30098 }; #endif diff --git a/src/server/game/World/WorldConfig.cpp b/src/server/game/World/WorldConfig.cpp index d0bdfb48c..62759608b 100644 --- a/src/server/game/World/WorldConfig.cpp +++ b/src/server/game/World/WorldConfig.cpp @@ -644,6 +644,7 @@ void WorldConfig::BuildConfigCache() //Debug SetConfigValue(CONFIG_DEBUG_BATTLEGROUND, "Debug.Battleground", false); SetConfigValue(CONFIG_DEBUG_ARENA, "Debug.Arena", false); + SetConfigValue(CONFIG_DEBUG_LFG, "Debug.LFG", false); SetConfigValue(CONFIG_GM_LEVEL_CHANNEL_MODERATION, "Channel.ModerationGMLevel", 1); diff --git a/src/server/game/World/WorldConfig.h b/src/server/game/World/WorldConfig.h index e0408c7fd..3cf19aa21 100644 --- a/src/server/game/World/WorldConfig.h +++ b/src/server/game/World/WorldConfig.h @@ -121,6 +121,7 @@ enum ServerConfigs CONFIG_ITEMDELETE_VENDOR, CONFIG_DEBUG_BATTLEGROUND, CONFIG_DEBUG_ARENA, + CONFIG_DEBUG_LFG, CONFIG_DUNGEON_ACCESS_REQUIREMENTS_PORTAL_CHECK_ILVL, CONFIG_DUNGEON_ACCESS_REQUIREMENTS_LFG_DBC_LEVEL_OVERRIDE, CONFIG_REGEN_HP_CANNOT_REACH_TARGET_IN_RAID, From f3779c8924b37b302b0045e6716d472ea23fb0b0 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Tue, 24 Feb 2026 20:51:15 -0600 Subject: [PATCH 276/335] fix(DB/Spell): Fix Threat of Thassarian not proccing on MH miss/dodge/parry (#24864) Co-authored-by: blinkysc --- data/sql/updates/pending_db_world/rev_1771984985196552455.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771984985196552455.sql diff --git a/data/sql/updates/pending_db_world/rev_1771984985196552455.sql b/data/sql/updates/pending_db_world/rev_1771984985196552455.sql new file mode 100644 index 000000000..33227c4d3 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771984985196552455.sql @@ -0,0 +1,4 @@ +-- HitMask 0x477 = PROC_HIT_NORMAL | PROC_HIT_CRITICAL | PROC_HIT_MISS | PROC_HIT_DODGE | PROC_HIT_PARRY | PROC_HIT_BLOCK | PROC_HIT_ABSORB +DELETE FROM `spell_proc` WHERE `SpellId` = -65661; +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +(-65661, 0, 15, 4194321, 537001988, 0, 0x10, 0, 2, 0x477, 0, 0, 0, 100, 0, 0); From e28881d0b81c1183859ccdc3961cb2a51b696170 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 02:52:24 +0000 Subject: [PATCH 277/335] chore(DB): import pending files Referenced commit(s): f88fda4f1972d32d26140cf91432caa9ef5578da --- .../2026_02_25_02.sql} | 1 + .../rev_1771984985196552455.sql => db_world/2026_02_25_03.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/acore_string_debug_lfg_conf.sql => db_world/2026_02_25_02.sql} (88%) rename data/sql/updates/{pending_db_world/rev_1771984985196552455.sql => db_world/2026_02_25_03.sql} (92%) diff --git a/data/sql/updates/pending_db_world/acore_string_debug_lfg_conf.sql b/data/sql/updates/db_world/2026_02_25_02.sql similarity index 88% rename from data/sql/updates/pending_db_world/acore_string_debug_lfg_conf.sql rename to data/sql/updates/db_world/2026_02_25_02.sql index b7411f9e6..c1fc15a1b 100644 --- a/data/sql/updates/pending_db_world/acore_string_debug_lfg_conf.sql +++ b/data/sql/updates/db_world/2026_02_25_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_01 -> 2026_02_25_02 -- Add acore_string for Debug.LFG config message (same pattern as Debug.Battleground / Debug.Arena) DELETE FROM `acore_string` WHERE `entry` = 30098; INSERT INTO `acore_string` (`entry`, `content_default`) VALUES diff --git a/data/sql/updates/pending_db_world/rev_1771984985196552455.sql b/data/sql/updates/db_world/2026_02_25_03.sql similarity index 92% rename from data/sql/updates/pending_db_world/rev_1771984985196552455.sql rename to data/sql/updates/db_world/2026_02_25_03.sql index 33227c4d3..8e6f5a0e1 100644 --- a/data/sql/updates/pending_db_world/rev_1771984985196552455.sql +++ b/data/sql/updates/db_world/2026_02_25_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_02 -> 2026_02_25_03 -- HitMask 0x477 = PROC_HIT_NORMAL | PROC_HIT_CRITICAL | PROC_HIT_MISS | PROC_HIT_DODGE | PROC_HIT_PARRY | PROC_HIT_BLOCK | PROC_HIT_ABSORB DELETE FROM `spell_proc` WHERE `SpellId` = -65661; INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES From 37416f0fa0411f1e16b92576c93e4ea717e2e42b Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Tue, 24 Feb 2026 21:55:13 -0600 Subject: [PATCH 278/335] fix(DB/Spell): Fix Killing Machine PPM values for ranks 3-5 (#24866) Co-authored-by: blinkysc Co-authored-by: Ariel Bastos --- .../updates/pending_db_world/rev_1771990265346528243.sql | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771990265346528243.sql diff --git a/data/sql/updates/pending_db_world/rev_1771990265346528243.sql b/data/sql/updates/pending_db_world/rev_1771990265346528243.sql new file mode 100644 index 000000000..3de1867cf --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771990265346528243.sql @@ -0,0 +1,8 @@ +-- Fix Killing Machine PPM values for ranks 3-5 +-- Previous values (1, 2, 4, 6, 8) used non-linear scaling +-- Correct values (1, 2, 3, 4, 5) use linear scaling matching tooltip +-- Formula: attackSpeed * talentRank / 60, yielding talentRank PPM + +UPDATE `spell_proc` SET `ProcsPerMinute` = 3 WHERE `SpellId` = 51128; -- Killing Machine Rank 3 +UPDATE `spell_proc` SET `ProcsPerMinute` = 4 WHERE `SpellId` = 51129; -- Killing Machine Rank 4 +UPDATE `spell_proc` SET `ProcsPerMinute` = 5 WHERE `SpellId` = 51130; -- Killing Machine Rank 5 From 179a188ad0eef8bf0df51ed421ac35fa60de6339 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 03:57:45 +0000 Subject: [PATCH 279/335] chore(DB): import pending files Referenced commit(s): 37416f0fa0411f1e16b92576c93e4ea717e2e42b --- .../rev_1771990265346528243.sql => db_world/2026_02_25_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771990265346528243.sql => db_world/2026_02_25_04.sql} (92%) diff --git a/data/sql/updates/pending_db_world/rev_1771990265346528243.sql b/data/sql/updates/db_world/2026_02_25_04.sql similarity index 92% rename from data/sql/updates/pending_db_world/rev_1771990265346528243.sql rename to data/sql/updates/db_world/2026_02_25_04.sql index 3de1867cf..b4e43f7a0 100644 --- a/data/sql/updates/pending_db_world/rev_1771990265346528243.sql +++ b/data/sql/updates/db_world/2026_02_25_04.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_03 -> 2026_02_25_04 -- Fix Killing Machine PPM values for ranks 3-5 -- Previous values (1, 2, 4, 6, 8) used non-linear scaling -- Correct values (1, 2, 3, 4, 5) use linear scaling matching tooltip From 45ea548ff69445a1da9526606e3675a06d3cb92f Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Tue, 24 Feb 2026 23:20:02 -0600 Subject: [PATCH 280/335] fix(Scripts/Spells): Add missing Druid T10 Balance 2P bonus (#24865) Co-authored-by: blinkysc Co-authored-by: Ariel Bastos --- .../pending_db_world/rev_1771984985196552455.sql | 7 +++++++ src/server/scripts/Spells/spell_druid.cpp | 15 +++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771984985196552455.sql diff --git a/data/sql/updates/pending_db_world/rev_1771984985196552455.sql b/data/sql/updates/pending_db_world/rev_1771984985196552455.sql new file mode 100644 index 000000000..6f913477f --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771984985196552455.sql @@ -0,0 +1,7 @@ +-- Threat of Thassarian: OH attack should fire even when MH misses/dodges/parries +-- SpellTypeMask 0 = don't filter by spell type (miss/dodge/parry have no damage, so +-- PROC_SPELL_TYPE_DAMAGE won't match - need to allow PROC_SPELL_TYPE_NO_DMG_HEAL too) +-- HitMask 0x477 = PROC_HIT_NORMAL | PROC_HIT_CRITICAL | PROC_HIT_MISS | PROC_HIT_DODGE | PROC_HIT_PARRY | PROC_HIT_BLOCK | PROC_HIT_ABSORB +DELETE FROM `spell_proc` WHERE `SpellId` = -65661; +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +(-65661, 0, 15, 4194321, 537001988, 0, 0x10, 0, 2, 0x477, 0, 0, 0, 100, 0, 0); diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 2bac18112..fea4d869e 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -88,6 +88,8 @@ enum DruidSpells SPELL_DRUID_GLYPH_OF_RIP = 54818, SPELL_DRUID_RIP_DURATION_LACERATE_DMG = 60141, SPELL_DRUID_REJUVENATION_T10_PROC = 70691, + SPELL_DRUID_BALANCE_T10_BONUS = 70718, + SPELL_DRUID_BALANCE_T10_BONUS_PROC = 70721, SPELL_DRUID_LANGUISH = 71023, // T9 Feral Relic SPELL_DRUID_T9_FERAL_RELIC_BEAR = 67354, @@ -234,6 +236,11 @@ class spell_dru_omen_of_clarity : public AuraScript { PrepareAuraScript(spell_dru_omen_of_clarity); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRUID_BALANCE_T10_BONUS, SPELL_DRUID_BALANCE_T10_BONUS_PROC }); + } + bool CheckProc(ProcEventInfo& eventInfo) { SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); @@ -268,9 +275,17 @@ class spell_dru_omen_of_clarity : public AuraScript return true; } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + Unit* target = GetTarget(); + if (target->HasAura(SPELL_DRUID_BALANCE_T10_BONUS)) + target->CastSpell(nullptr, SPELL_DRUID_BALANCE_T10_BONUS_PROC, true, nullptr, aurEff); + } + void Register() override { DoCheckProc += AuraCheckProcFn(spell_dru_omen_of_clarity::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dru_omen_of_clarity::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; From 3cb5c9685fe44843b6c2a8e8f77202f687ef98a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 05:21:06 +0000 Subject: [PATCH 281/335] chore(DB): import pending files Referenced commit(s): 45ea548ff69445a1da9526606e3675a06d3cb92f --- .../rev_1771984985196552455.sql => db_world/2026_02_25_05.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771984985196552455.sql => db_world/2026_02_25_05.sql} (94%) diff --git a/data/sql/updates/pending_db_world/rev_1771984985196552455.sql b/data/sql/updates/db_world/2026_02_25_05.sql similarity index 94% rename from data/sql/updates/pending_db_world/rev_1771984985196552455.sql rename to data/sql/updates/db_world/2026_02_25_05.sql index 6f913477f..e4146818c 100644 --- a/data/sql/updates/pending_db_world/rev_1771984985196552455.sql +++ b/data/sql/updates/db_world/2026_02_25_05.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_04 -> 2026_02_25_05 -- Threat of Thassarian: OH attack should fire even when MH misses/dodges/parries -- SpellTypeMask 0 = don't filter by spell type (miss/dodge/parry have no damage, so -- PROC_SPELL_TYPE_DAMAGE won't match - need to allow PROC_SPELL_TYPE_NO_DMG_HEAL too) From bb10c2c5411e3277408390f7793ef3883490db0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E9=B9=AD?= <18535853+PkllonG@users.noreply.github.com> Date: Wed, 25 Feb 2026 15:18:12 +0800 Subject: [PATCH 282/335] fix(SpellEffects): GameObject Rotation (#24850) --- src/server/game/Spells/SpellEffects.cpp | 12 ++++++++---- src/server/scripts/Commands/cs_gobject.cpp | 3 ++- src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp | 6 ++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 634bde4f1..5e4bc73c6 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3761,7 +3761,8 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) Map* map = target->GetMap(); - if (!pGameObj->Create(map->GenerateLowGuid(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY)) + G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), target->GetOrientation()); + if (!pGameObj->Create(map->GenerateLowGuid(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), rotation, 100, GO_STATE_READY)) { delete pGameObj; return; @@ -4109,12 +4110,13 @@ void Spell::EffectDuel(SpellEffIndex effIndex) GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject(); Map* map = m_caster->GetMap(); + G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), m_caster->GetOrientation()); if (!pGameObj->Create(map->GenerateLowGuid(), gameobject_id, map, m_caster->GetPhaseMask(), m_caster->GetPositionX() + (unitTarget->GetPositionX() - m_caster->GetPositionX()) / 2, m_caster->GetPositionY() + (unitTarget->GetPositionY() - m_caster->GetPositionY()) / 2, m_caster->GetPositionZ(), - m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY)) + m_caster->GetOrientation(), rotation, 0, GO_STATE_READY)) { delete pGameObj; return; @@ -4590,7 +4592,8 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); Map* map = m_caster->GetMap(); - if (!pGameObj->Create(map->GenerateLowGuid(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY)) + G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), m_caster->GetOrientation()); + if (!pGameObj->Create(map->GenerateLowGuid(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), rotation, 0, GO_STATE_READY)) { delete pGameObj; return; @@ -5394,7 +5397,8 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject(); - if (!pGameObj->Create(cMap->GenerateLowGuid(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY)) + G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), m_caster->GetOrientation()); + if (!pGameObj->Create(cMap->GenerateLowGuid(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), rotation, 100, GO_STATE_READY)) { delete pGameObj; return; diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index c23832e99..50ccde003 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -117,7 +117,8 @@ public: GameObject* object = sObjectMgr->IsGameObjectStaticTransport(objectInfo->entry) ? new StaticTransport() : new GameObject(); ObjectGuid::LowType guidLow = map->GenerateLowGuid(); - if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMaskForSpawn(), x, y, z, o, G3D::Quat(), 0, GO_STATE_READY)) + G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), o); + if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMaskForSpawn(), x, y, z, o, rotation, 0, GO_STATE_READY)) { delete object; return false; diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp index 6221ee83b..33e2fb9fa 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp @@ -177,7 +177,8 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId) return true; } - if (!go->Create(map->GenerateLowGuid(), SI_SILITHYST_MOUND, map, player->GetPhaseMask(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY)) + G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), player->GetOrientation()); + if (!go->Create(map->GenerateLowGuid(), SI_SILITHYST_MOUND, map, player->GetPhaseMask(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), rotation, 100, GO_STATE_READY)) { delete go; return true; @@ -211,7 +212,8 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId) return true; } - if (!go->Create(map->GenerateLowGuid(), SI_SILITHYST_MOUND, map, player->GetPhaseMask(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY)) + G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), player->GetOrientation()); + if (!go->Create(map->GenerateLowGuid(), SI_SILITHYST_MOUND, map, player->GetPhaseMask(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), rotation, 100, GO_STATE_READY)) { delete go; return true; From c990b7ad31aeea15b5b3c8137ba77589830f6c7b Mon Sep 17 00:00:00 2001 From: sudlud Date: Wed, 25 Feb 2026 14:38:29 +0100 Subject: [PATCH 283/335] fix(DB/Gameobject): Sniffed Values for 'Serpentshrine Console' spawns (#24861) --- .../updates/pending_db_world/rev_1771976066531376600.sql | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771976066531376600.sql diff --git a/data/sql/updates/pending_db_world/rev_1771976066531376600.sql b/data/sql/updates/pending_db_world/rev_1771976066531376600.sql new file mode 100644 index 000000000..6756e4862 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771976066531376600.sql @@ -0,0 +1,7 @@ +-- Update gameobject 'Serpentshrine Console' with sniffed values +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (185115, 185117, 185118)) AND (`guid` IN (191, 192, 193)); +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 +(191, 185115, 548, 0, 0, 1, 1, 373.139404296875, -465.10626220703125, 30.71641731262207031, 3.22885894775390625, 0, 0, -0.99904823303222656, 0.043619260191917419, 7200, 255, 0, "", 49345, NULL), +(192, 185117, 548, 0, 0, 1, 1, -245.729354858398437, -381.39300537109375, -0.18703900277614593, 2.879789113998413085, 0, 0, 0.991444587707519531, 0.130528271198272705, 7200, 255, 0, "", 49345, NULL), +(193, 185118, 548, 0, 0, 1, 1, 123.2582168579101562, -432.356719970703125, -1.19655394554138183, 4.799657344818115234, 0, 0, -0.67558956146240234, 0.737277925014495849, 7200, 255, 0, "", 49345, NULL); From af567db104173e7b79143c114fb7ee81d5898221 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 13:39:36 +0000 Subject: [PATCH 284/335] chore(DB): import pending files Referenced commit(s): c990b7ad31aeea15b5b3c8137ba77589830f6c7b --- .../rev_1771976066531376600.sql => db_world/2026_02_25_06.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771976066531376600.sql => db_world/2026_02_25_06.sql} (96%) diff --git a/data/sql/updates/pending_db_world/rev_1771976066531376600.sql b/data/sql/updates/db_world/2026_02_25_06.sql similarity index 96% rename from data/sql/updates/pending_db_world/rev_1771976066531376600.sql rename to data/sql/updates/db_world/2026_02_25_06.sql index 6756e4862..6219aed98 100644 --- a/data/sql/updates/pending_db_world/rev_1771976066531376600.sql +++ b/data/sql/updates/db_world/2026_02_25_06.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_05 -> 2026_02_25_06 -- Update gameobject 'Serpentshrine Console' with sniffed values -- new spawns DELETE FROM `gameobject` WHERE (`id` IN (185115, 185117, 185118)) AND (`guid` IN (191, 192, 193)); From 3eab74da3a07ab94257ec02cea359f06dceb87fb Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Wed, 25 Feb 2026 08:56:37 -0600 Subject: [PATCH 285/335] fix(DB/Loot): Remove duplicate Void Crystal from disenchant entry 67 (#24871) Co-authored-by: blinkysc Co-authored-by: Gultask <100873791+Gultask@users.noreply.github.com> --- .../pending_db_world/rev_1772001496427044016.sql | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772001496427044016.sql diff --git a/data/sql/updates/pending_db_world/rev_1772001496427044016.sql b/data/sql/updates/pending_db_world/rev_1772001496427044016.sql new file mode 100644 index 000000000..3b5a5a090 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772001496427044016.sql @@ -0,0 +1,11 @@ +-- Remove erroneous reference from disenchant entry 67 that causes double Void Crystal drops +-- Entry 67 already guarantees 1 Void Crystal (GroupId=0, 100% chance) +-- The reference to table 44012 (GroupId=1, 67% chance) added a second Void Crystal +DELETE FROM `disenchant_loot_template` WHERE `Entry` = 67 AND `Item` = 44012; +DELETE FROM `reference_loot_template` WHERE (`Entry` = 44012); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34097); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34097, 29765, 0, 0, 0, 1, 1, 1, 1, 'Leggings of the Fallen Hero'), +(34097, 29766, 0, 0, 0, 1, 1, 1, 1, 'Leggings of the Fallen Champion'), +(34097, 29767, 0, 0, 0, 1, 1, 1, 1, 'Leggings of the Fallen Defender'); From e3f4a0e09233e55c71c24a89bf0cb35de7557f52 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 14:57:51 +0000 Subject: [PATCH 286/335] chore(DB): import pending files Referenced commit(s): 3eab74da3a07ab94257ec02cea359f06dceb87fb --- .../rev_1772001496427044016.sql => db_world/2026_02_25_07.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772001496427044016.sql => db_world/2026_02_25_07.sql} (94%) diff --git a/data/sql/updates/pending_db_world/rev_1772001496427044016.sql b/data/sql/updates/db_world/2026_02_25_07.sql similarity index 94% rename from data/sql/updates/pending_db_world/rev_1772001496427044016.sql rename to data/sql/updates/db_world/2026_02_25_07.sql index 3b5a5a090..077f07150 100644 --- a/data/sql/updates/pending_db_world/rev_1772001496427044016.sql +++ b/data/sql/updates/db_world/2026_02_25_07.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_06 -> 2026_02_25_07 -- Remove erroneous reference from disenchant entry 67 that causes double Void Crystal drops -- Entry 67 already guarantees 1 Void Crystal (GroupId=0, 100% chance) -- The reference to table 44012 (GroupId=1, 67% chance) added a second Void Crystal From 823bf84a1243598593c27d0f2921919c01ff2e0e Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Wed, 25 Feb 2026 10:12:13 -0600 Subject: [PATCH 287/335] chore(Scripts/Spells): Remove duplicate Shaman T8 Electrified script (#24869) Co-authored-by: blinkysc --- .../fix_shaman_t8_electrified_double_proc.sql | 2 + src/server/scripts/Spells/spell_shaman.cpp | 56 +++---------------- 2 files changed, 11 insertions(+), 47 deletions(-) create mode 100644 data/sql/updates/pending_db_world/fix_shaman_t8_electrified_double_proc.sql diff --git a/data/sql/updates/pending_db_world/fix_shaman_t8_electrified_double_proc.sql b/data/sql/updates/pending_db_world/fix_shaman_t8_electrified_double_proc.sql new file mode 100644 index 000000000..68bcbf01a --- /dev/null +++ b/data/sql/updates/pending_db_world/fix_shaman_t8_electrified_double_proc.sql @@ -0,0 +1,2 @@ +-- Remove stale spell_script_names entry for spell_sha_t8_electrified. +DELETE FROM `spell_script_names` WHERE `spell_id` = 64928 AND `ScriptName` = 'spell_sha_t8_electrified'; diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 03ce3b39c..8490f4b34 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -1296,45 +1296,6 @@ class spell_sha_flurry_proc : public AuraScript } }; -// 64928 - Item - Shaman T8 Elemental 4P Bonus -class spell_sha_t8_electrified : public AuraScript -{ - PrepareAuraScript(spell_sha_t8_electrified); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_ELECTRIFIED }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - // Do not proc from Lightning Overload (patch 3.1~) - if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - { - if (spellInfo->Id == SPELL_SHAMAN_LIGHTNING_BOLT_OVERLOAD) - { - return; - } - } - - SpellInfo const* electrifiedDot = sSpellMgr->AssertSpellInfo(SPELL_SHAMAN_ELECTRIFIED); - int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()) / electrifiedDot->GetMaxTicks()); - - eventInfo.GetProcTarget()->CastDelayedSpellWithPeriodicAmount(eventInfo.GetActor(), SPELL_SHAMAN_ELECTRIFIED, SPELL_AURA_PERIODIC_DAMAGE, amount); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_sha_t8_electrified::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - // 55440 - Glyph of Healing Wave class spell_sha_glyph_of_healing_wave : public AuraScript { @@ -2063,16 +2024,18 @@ class spell_sha_t8_elemental_4p_bonus : public AuraScript if (!damageInfo || !damageInfo->GetDamage()) return; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ELECTRIFIED); - if (!spellInfo) - return; + // Do not proc from Lightning Overload (patch 3.1~) + if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) + { + if (spellInfo->Id == SPELL_SHAMAN_LIGHTNING_BOLT_OVERLOAD) + return; + } + SpellInfo const* electrifiedDot = sSpellMgr->AssertSpellInfo(SPELL_SHAMAN_ELECTRIFIED); int32 amount = CalculatePct(static_cast(damageInfo->GetDamage()), aurEff->GetAmount()); - amount /= spellInfo->GetMaxTicks(); + amount /= electrifiedDot->GetMaxTicks(); - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetActionTarget(); - target->CastDelayedSpellWithPeriodicAmount(caster, SPELL_SHAMAN_ELECTRIFIED, SPELL_AURA_PERIODIC_DAMAGE, amount); + eventInfo.GetProcTarget()->CastDelayedSpellWithPeriodicAmount(eventInfo.GetActor(), SPELL_SHAMAN_ELECTRIFIED, SPELL_AURA_PERIODIC_DAMAGE, amount); } void Register() override @@ -2242,7 +2205,6 @@ void AddSC_shaman_spell_scripts() RegisterSpellScript(spell_sha_stoneclaw_totem); RegisterSpellScript(spell_sha_thunderstorm); RegisterSpellScript(spell_sha_flurry_proc); - RegisterSpellScript(spell_sha_t8_electrified); RegisterSpellScript(spell_sha_glyph_of_healing_wave); RegisterSpellScript(spell_sha_spirit_hunt); RegisterSpellScript(spell_sha_frozen_power); From 2fe33a782dc8defcd753dc0106628f05ab48a193 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Wed, 25 Feb 2026 10:13:05 -0600 Subject: [PATCH 288/335] fix(DB/Spells): Prevent Focused Attacks from proccing on offhand attacks (#24870) Co-authored-by: blinkysc --- data/sql/updates/pending_db_world/rev_1772001104333030701.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772001104333030701.sql diff --git a/data/sql/updates/pending_db_world/rev_1772001104333030701.sql b/data/sql/updates/pending_db_world/rev_1772001104333030701.sql new file mode 100644 index 000000000..51eced45e --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772001104333030701.sql @@ -0,0 +1,4 @@ +-- Focused Attacks should not proc from offhand attacks (including Fan of Knives offhand) +DELETE FROM `spell_script_names` WHERE `spell_id` = -51634 AND `ScriptName` = 'spell_gen_no_offhand_proc'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-51634, 'spell_gen_no_offhand_proc'); From d3a914d90fc5a4fd7368b6e88e1511f008f995ad Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 16:13:42 +0000 Subject: [PATCH 289/335] chore(DB): import pending files Referenced commit(s): 823bf84a1243598593c27d0f2921919c01ff2e0e --- .../2026_02_25_08.sql} | 1 + .../rev_1772001104333030701.sql => db_world/2026_02_25_09.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/fix_shaman_t8_electrified_double_proc.sql => db_world/2026_02_25_08.sql} (80%) rename data/sql/updates/{pending_db_world/rev_1772001104333030701.sql => db_world/2026_02_25_09.sql} (87%) diff --git a/data/sql/updates/pending_db_world/fix_shaman_t8_electrified_double_proc.sql b/data/sql/updates/db_world/2026_02_25_08.sql similarity index 80% rename from data/sql/updates/pending_db_world/fix_shaman_t8_electrified_double_proc.sql rename to data/sql/updates/db_world/2026_02_25_08.sql index 68bcbf01a..9ecbd30d7 100644 --- a/data/sql/updates/pending_db_world/fix_shaman_t8_electrified_double_proc.sql +++ b/data/sql/updates/db_world/2026_02_25_08.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_25_07 -> 2026_02_25_08 -- Remove stale spell_script_names entry for spell_sha_t8_electrified. DELETE FROM `spell_script_names` WHERE `spell_id` = 64928 AND `ScriptName` = 'spell_sha_t8_electrified'; diff --git a/data/sql/updates/pending_db_world/rev_1772001104333030701.sql b/data/sql/updates/db_world/2026_02_25_09.sql similarity index 87% rename from data/sql/updates/pending_db_world/rev_1772001104333030701.sql rename to data/sql/updates/db_world/2026_02_25_09.sql index 51eced45e..149b2ace9 100644 --- a/data/sql/updates/pending_db_world/rev_1772001104333030701.sql +++ b/data/sql/updates/db_world/2026_02_25_09.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_08 -> 2026_02_25_09 -- Focused Attacks should not proc from offhand attacks (including Fan of Knives offhand) DELETE FROM `spell_script_names` WHERE `spell_id` = -51634 AND `ScriptName` = 'spell_gen_no_offhand_proc'; INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES From f9fc2027812cafb0d0fd200fa4429698ff1f70f7 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Wed, 25 Feb 2026 10:20:50 -0600 Subject: [PATCH 290/335] fix(Scripts/Spells): Fix Retaliation self-damage and charge loss on activation (#24868) Co-authored-by: blinkysc Co-authored-by: Vincent-Michael --- src/server/scripts/Spells/spell_warrior.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index 421875469..e863c2e3c 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -47,7 +47,7 @@ enum WarriorSpells SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF = 65156, SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT = 64976, SPELL_WARRIOR_LAST_STAND_TRIGGERED = 12976, - SPELL_WARRIOR_RETALIATION_DAMAGE = 22858, + SPELL_WARRIOR_RETALIATION_DAMAGE = 20240, SPELL_WARRIOR_SLAM = 50783, SPELL_WARRIOR_SUNDER_ARMOR = 58567, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1 = 12723, @@ -884,19 +884,14 @@ class spell_warr_retaliation : public AuraScript bool CheckProc(ProcEventInfo& eventInfo) { - if (!eventInfo.GetActor() || !eventInfo.GetProcTarget()) - { - return false; - } - // check attack comes not from behind and warrior is not stunned - return GetTarget()->isInFront(eventInfo.GetActor(), M_PI) && !GetTarget()->HasUnitState(UNIT_STATE_STUNNED); + return eventInfo.GetActionTarget()->isInFront(eventInfo.GetActor(), float(M_PI)) && !GetTarget()->HasUnitState(UNIT_STATE_STUNNED); } void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_WARRIOR_RETALIATION_DAMAGE, true, nullptr, aurEff); + eventInfo.GetActionTarget()->CastSpell(eventInfo.GetActor(), SPELL_WARRIOR_RETALIATION_DAMAGE, true, nullptr, aurEff); } void Register() override From 4d2402a28528228c49cbdb77affd6d4df7263066 Mon Sep 17 00:00:00 2001 From: sudlud Date: Wed, 25 Feb 2026 18:41:59 +0100 Subject: [PATCH 291/335] fix(DB/Gameobject): Sniffed Values for 'Blood of Heroes' spawns (#24855) --- .../rev_1771967006571378200.sql | 265 ++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771967006571378200.sql diff --git a/data/sql/updates/pending_db_world/rev_1771967006571378200.sql b/data/sql/updates/pending_db_world/rev_1771967006571378200.sql new file mode 100644 index 000000000..4852a4f43 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771967006571378200.sql @@ -0,0 +1,265 @@ +-- Update gameobject 'Blood of Heroes' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (176213)) AND (`guid` IN (45512, 45736, 45853, 45892, 45934, 45936, 5276, 5277, 5278, 5279, 5281)); +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 +(45512, 176213, 0, 0, 0, 1, 1, 2412.71240234375, -1721.55712890625, 107.0056533813476562, 2.897245407104492187, 0, 0, 0.99254608154296875, 0.121869951486587524, 7200, 255, 1, "", 49345, NULL), +(45736, 176213, 0, 0, 0, 1, 1, 2192.737060546875, -4479.205078125, 87.65995025634765625, 3.036838293075561523, 0, 0, 0.998628616333007812, 0.052353221923112869, 7200, 255, 1, "", 49345, NULL), +(45853, 176213, 0, 0, 0, 1, 1, 2958.036865234375, -3485.06298828125, 146.221649169921875, 3.281238555908203125, 0, 0, -0.99756336212158203, 0.069766148924827575, 7200, 255, 1, "", 48120, NULL), +(45892, 176213, 0, 0, 0, 1, 1, 2888.376953125, -4086.28564453125, 101.3808364868164062, 4.084071159362792968, 0, 0, -0.8910064697265625, 0.453990638256072998, 7200, 255, 1, "", 50664, NULL), +(45934, 176213, 0, 0, 0, 1, 1, 1873.2691650390625, -3189.559326171875, 128.554168701171875, 0.15707901120185852, 0, 0, 0.078458786010742187, 0.996917366981506347, 7200, 255, 1, "", 50664, NULL), +(45936, 176213, 0, 0, 0, 1, 1, 2115.703125, -4691.1162109375, 74.33621978759765625, 1.151916384696960449, 0, 0, 0.544638633728027343, 0.838670849800109863, 7200, 255, 1, "", 50063, NULL), +(5276, 176213, 0, 0, 0, 1, 1, 1529.1024169921875, -1427.0694580078125, 65.4904937744140625, 3.281238555908203125, 0, 0, -0.99756336212158203, 0.069766148924827575, 7200, 255, 1, "", 48632, NULL), +(5277, 176213, 0, 0, 0, 1, 1, 1705.8743896484375, -4690.13818359375, 48.97421646118164062, 3.194002151489257812, 0, 0, -0.99965667724609375, 0.026201646775007247, 7200, 255, 1, "", 45572, NULL), +(5278, 176213, 0, 0, 0, 1, 1, 1846.7938232421875, -3825.264892578125, 135.515899658203125, 1.832594871520996093, 0, 0, 0.793353080749511718, 0.608761727809906005, 7200, 255, 1, "", 48632, NULL), +(5279, 176213, 0, 0, 0, 1, 1, 1748.163330078125, -4453.13525390625, 74.26271820068359375, 4.223697185516357421, 0, 0, -0.85716724395751953, 0.515038192272186279, 7200, 255, 1, "", 50664, NULL), +(5281, 176213, 0, 0, 0, 1, 1, 1342.5572509765625, -1382.5677490234375, 46.89192962646484375, 2.775068521499633789, 0, 0, 0.983254432678222656, 0.182238012552261352, 7200, 255, 1, "", 45613, NULL); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (176213)) AND (`guid` IN (9478, 9479, 9480, 9481, 9482, 9483, 9484, 9485, 9486, 9487, 9488, 9489, 9490, 9491, 9492, 9493, 9494, 9495, 9496, 9497, 9498, 9499, 9500, 9501, 9502, 9503, 9504, 9505, 9506, 9507, 9508, 9509, 9510, 9511, 9512, 9513, 9514, 9515, 9516, 9517, 9518, 9519, 9520, 9521, 9522, 9523, 9524, 9525, 9526, 9527, 9528, 9529, 9530, 9531, 9532, 9533, 9534, 9535, 9536, 9537, 9538, 9539, 9540, 9541, 9542, 9543, 9544, 9545, 9546, 9547, 9548, 9549, 9550, 9551, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9581, 9582, 9583, 9584, 9585, 9586, 9587)); +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 +(9478, 176213, 0, 0, 0, 1, 1, 1030.57763671875, -2519.484130859375, 59.16263198852539062, 3.368495941162109375, 0, 0, -0.99357128143310546, 0.113208353519439697, 7200, 255, 1, "", 51943, NULL), +(9479, 176213, 0, 0, 0, 1, 1, 1111.51025390625, -2569.175537109375, 59.25194168090820312, 4.799657344818115234, 0, 0, -0.67558956146240234, 0.737277925014495849, 7200, 255, 1, "", 47168, NULL), +(9480, 176213, 0, 0, 0, 1, 1, 1158.575439453125, -2524.986572265625, 60.75162887573242187, 5.6897735595703125, 0, 0, -0.29237174987792968, 0.956304728984832763, 7200, 255, 1, "", 52237, NULL), +(9481, 176213, 0, 0, 0, 1, 1, 1163.8092041015625, -2415.5107421875, 62.01439285278320312, 4.031712055206298828, 0, 0, -0.90258502960205078, 0.430511653423309326, 7200, 255, 1, "", 51943, NULL), +(9482, 176213, 0, 0, 0, 1, 1, 1206.1214599609375, -2316.496337890625, 57.17169189453125, 4.049167633056640625, 0, 0, -0.89879322052001953, 0.438372820615768432, 7200, 255, 1, "", 52237, NULL), +(9483, 176213, 0, 0, 0, 1, 1, 1233.2296142578125, -2373.74462890625, 58.92098617553710937, 4.049167633056640625, 0, 0, -0.89879322052001953, 0.438372820615768432, 7200, 255, 1, "", 49345, NULL), +(9484, 176213, 0, 0, 0, 1, 1, 1272.578125, -1328.576416015625, 61.89749526977539062, 1.431168079376220703, 0, 0, 0.656058311462402343, 0.754710197448730468, 7200, 255, 1, "", 46902, NULL), +(9485, 176213, 0, 0, 0, 1, 1, 1291.939208984375, -2565.14794921875, 111.5222930908203125, 5.654868602752685546, 0, 0, -0.30901622772216796, 0.95105677843093872, 7200, 255, 1, "", 51739, NULL), +(9486, 176213, 0, 0, 0, 1, 1, 1316.46875, -1556.3819580078125, 59.41793441772460937, 3.595378875732421875, 0, 0, -0.97437000274658203, 0.224951311945915222, 7200, 255, 1, "", 46158, NULL), +(9487, 176213, 0, 0, 0, 1, 1, 1347.8597412109375, -1459.9820556640625, 55.78710556030273437, 1.780233979225158691, 0, 0, 0.7771453857421875, 0.629321098327636718, 7200, 255, 1, "", 47720, NULL), +(9488, 176213, 0, 0, 0, 1, 1, 1362.1129150390625, -1630.07470703125, 59.96099090576171875, 2.164205789566040039, 0, 0, 0.882946968078613281, 0.469472706317901611, 7200, 255, 1, "", 45942, NULL), +(9489, 176213, 0, 0, 0, 1, 1, 1374.470458984375, -1289.638916015625, 57.52788543701171875, 1.308995485305786132, 0, 0, 0.608760833740234375, 0.793353796005249023, 7200, 255, 1, "", 46158, NULL), +(9490, 176213, 0, 0, 0, 1, 1, 1410.818115234375, -1443.8800048828125, 55.8153533935546875, 4.956737518310546875, 0, 0, -0.61566066741943359, 0.788011372089385986, 7200, 255, 1, "", 45613, NULL), +(9491, 176213, 0, 0, 0, 1, 1, 1439.4039306640625, -1602.9307861328125, 69.56070709228515625, 4.537858963012695312, 0, 0, -0.76604366302490234, 0.642788589000701904, 7200, 255, 1, "", 47720, NULL), +(9492, 176213, 0, 0, 0, 1, 1, 1460.2784423828125, -2069.739501953125, 51.20478057861328125, 2.687806606292724609, 0, 0, 0.974370002746582031, 0.224951311945915222, 7200, 255, 1, "", 49345, NULL), +(9493, 176213, 0, 0, 0, 1, 1, 1461.8394775390625, -1833.0867919921875, 58.57114028930664062, 4.660029888153076171, 0, 0, -0.72537422180175781, 0.688354730606079101, 7200, 255, 1, "", 45854, NULL), +(9494, 176213, 0, 0, 0, 1, 1, 1465.2467041015625, -1875.5672607421875, 58.71155548095703125, 6.14356088638305664, 0, 0, -0.06975555419921875, 0.997564136981964111, 7200, 255, 1, "", 45942, NULL), +(9495, 176213, 0, 0, 0, 1, 1, 1502.3804931640625, -1486.1605224609375, 57.18505859375, 6.195919513702392578, 0, 0, -0.04361915588378906, 0.999048233032226562, 7200, 255, 1, "", 49345, NULL), +(9496, 176213, 0, 0, 0, 1, 1, 1519.316650390625, -3125.2138671875, 94.45519256591796875, 4.747295856475830078, 0, 0, -0.69465827941894531, 0.719339847564697265, 7200, 255, 1, "", 45942, NULL), +(9497, 176213, 0, 0, 0, 1, 1, 1523.3292236328125, -1864.1004638671875, 59.60967254638671875, 4.206246376037597656, 0, 0, -0.86162853240966796, 0.50753939151763916, 7200, 255, 1, "", 45942, NULL), +(9498, 176213, 0, 0, 0, 1, 1, 1549.2196044921875, -1884.0067138671875, 57.76182174682617187, 0.401424884796142578, 0, 0, 0.199367523193359375, 0.979924798011779785, 7200, 255, 1, "", 46902, NULL), +(9499, 176213, 0, 0, 0, 1, 1, 1581.6258544921875, -3296.41259765625, 92.71665191650390625, 2.513273954391479492, 0, 0, 0.951056480407714843, 0.309017121791839599, 7200, 255, 1, "", 50664, NULL), +(9500, 176213, 0, 0, 0, 1, 1, 1585.51416015625, -1368.17236328125, 61.84386444091796875, 2.792518377304077148, 0, 0, 0.984807014465332031, 0.173652306199073791, 7200, 255, 1, "", 46158, NULL), +(9501, 176213, 0, 0, 0, 1, 1, 1601.953857421875, -3041.421142578125, 78.50331878662109375, 2.460912704467773437, 0, 0, 0.942641258239746093, 0.333807557821273803, 7200, 255, 1, "", 49345, NULL), +(9502, 176213, 0, 0, 0, 1, 1, 1645.173828125, -710.92181396484375, 55.31115341186523437, 0.471238493919372558, 0, 0, 0.233445167541503906, 0.972369968891143798, 7200, 255, 1, "", 45942, NULL), +(9503, 176213, 0, 0, 0, 1, 1, 1645.7691650390625, -1603.4722900390625, 60.60010528564453125, 3.647741317749023437, 0, 0, -0.96814727783203125, 0.250381410121917724, 7200, 255, 1, "", 45435, NULL), +(9504, 176213, 0, 0, 0, 1, 1, 1646.7236328125, -5121.603515625, 77.622894287109375, 3.124123096466064453, 0, 0, 0.99996185302734375, 0.008734640665352344, 7200, 255, 1, "", 51666, NULL), +(9505, 176213, 0, 0, 0, 1, 1, 1647.9044189453125, -4851.15966796875, 83.16530609130859375, 1.221729278564453125, 0, 0, 0.573575973510742187, 0.819152355194091796, 7200, 255, 1, "", 48632, NULL), +(9506, 176213, 0, 0, 0, 1, 1, 1678.4527587890625, -5024.9462890625, 82.38230133056640625, 1.570795774459838867, 0, 0, 0.707106590270996093, 0.707106947898864746, 7200, 255, 1, "", 50664, NULL), +(9507, 176213, 0, 0, 0, 1, 1, 1682.929931640625, -715.29656982421875, 57.69023895263671875, 2.44346022605895996, 0, 0, 0.939692497253417968, 0.34202045202255249, 7200, 255, 1, "", 46158, NULL), +(9508, 176213, 0, 0, 0, 1, 1, 1685.576416015625, -4392.080078125, 85.64618682861328125, 3.961898565292358398, 0, 0, -0.91705989837646484, 0.398749500513076782, 7200, 255, 1, "", 50664, NULL), +(9509, 176213, 0, 0, 0, 1, 1, 1704.4141845703125, -2287.104248046875, 58.94126510620117187, 5.044002056121826171, 0, 0, -0.58070278167724609, 0.814115643501281738, 7200, 255, 1, "", 52237, NULL), +(9510, 176213, 0, 0, 0, 1, 1, 1710.78076171875, -2340.359375, 59.8973541259765625, 1.780233979225158691, 0, 0, 0.7771453857421875, 0.629321098327636718, 7200, 255, 1, "", 50664, NULL), +(9511, 176213, 0, 0, 0, 1, 1, 1715.69091796875, -4480.84130859375, 67.46282958984375, 5.916667938232421875, 0, 0, -0.18223476409912109, 0.98325502872467041, 7200, 255, 1, "", 45435, NULL), +(9512, 176213, 0, 0, 0, 1, 1, 1717.7158203125, -4847.892578125, 92.53662109375, 2.984498262405395507, 0, 0, 0.996916770935058593, 0.078466430306434631, 7200, 255, 1, "", 51666, NULL), +(9513, 176213, 0, 0, 0, 1, 1, 1719.0057373046875, -1334.0836181640625, 65.16336822509765625, 0.645771682262420654, 0, 0, 0.317304611206054687, 0.948323667049407958, 7200, 255, 1, "", 45854, NULL), +(9514, 176213, 0, 0, 0, 1, 1, 1723.9923095703125, -1128.4765625, 61.83336639404296875, 0.837757468223571777, 0, 0, 0.406736373901367187, 0.913545548915863037, 7200, 255, 1, "", 46248, NULL), +(9515, 176213, 0, 0, 0, 1, 1, 1728.4073486328125, -3505.175048828125, 127.25274658203125, 4.398232460021972656, 0, 0, -0.80901622772216796, 0.587786316871643066, 7200, 255, 1, "", 50664, NULL), +(9516, 176213, 0, 0, 0, 1, 1, 1735.6893310546875, -4043.825927734375, 116.1277923583984375, 4.241150379180908203, 0, 0, -0.85264015197753906, 0.522498607635498046, 7200, 255, 1, "", 50664, NULL), +(9517, 176213, 0, 0, 0, 1, 1, 1742.0836181640625, -3792.190185546875, 127.144073486328125, 3.90954136848449707, 0, 0, -0.92718315124511718, 0.37460830807685852, 7200, 255, 1, "", 52237, NULL), +(9518, 176213, 0, 0, 0, 1, 1, 1743.3619384765625, -4438.28955078125, 75.40395355224609375, 4.607671737670898437, 0, 0, -0.74314403533935546, 0.669131457805633544, 7200, 255, 1, "", 48632, NULL), +(9519, 176213, 0, 0, 0, 1, 1, 1767.2125244140625, -3318.948974609375, 102.4638595581054687, 1.884953022003173828, 0, 0, 0.809016227722167968, 0.587786316871643066, 7200, 255, 1, "", 50664, NULL), +(9520, 176213, 0, 0, 0, 1, 1, 1774.233642578125, -4839.80224609375, 91.5816497802734375, 2.530723094940185546, 0, 0, 0.953716278076171875, 0.300707906484603881, 7200, 255, 1, "", 46182, NULL), +(9521, 176213, 0, 0, 0, 1, 1, 1780.121337890625, -5134.4033203125, 74.627838134765625, 0.191985160112380981, 0, 0, 0.095845222473144531, 0.995396256446838378, 7200, 255, 1, "", 50664, NULL), +(9522, 176213, 0, 0, 0, 1, 1, 1805.7340087890625, -4136.9423828125, 94.75803375244140625, 6.056293010711669921, 0, 0, -0.11320304870605468, 0.993571877479553222, 7200, 255, 1, "", 50664, NULL), +(9523, 176213, 0, 0, 0, 1, 1, 1810.6544189453125, -5022.1884765625, 87.799163818359375, 0.977383077144622802, 0, 0, 0.469470977783203125, 0.882947921752929687, 7200, 255, 1, "", 50664, NULL), +(9524, 176213, 0, 0, 0, 1, 1, 1817.9827880859375, -3521.613037109375, 115.2667083740234375, 0.767943859100341796, 0, 0, 0.374606132507324218, 0.927184045314788818, 7200, 255, 1, "", 45942, NULL), +(9525, 176213, 0, 0, 0, 1, 1, 1819.2908935546875, -5033.21875, 88.9647216796875, 1.780233979225158691, 0, 0, 0.7771453857421875, 0.629321098327636718, 7200, 255, 1, "", 52237, NULL), +(9526, 176213, 0, 0, 0, 1, 1, 1823.8018798828125, -2462.234130859375, 70.6959686279296875, 5.881760597229003906, 0, 0, -0.19936752319335937, 0.979924798011779785, 7200, 255, 1, "", 45572, NULL), +(9527, 176213, 0, 0, 0, 1, 1, 1832.8035888671875, -4419.21337890625, 82.59712982177734375, 0.802850961685180664, 0, 0, 0.390730857849121093, 0.920504987239837646, 7200, 255, 1, "", 45770, NULL), +(9528, 176213, 0, 0, 0, 1, 1, 1832.9140625, -4374.04541015625, 98.33393096923828125, 5.759587764739990234, 0, 0, -0.25881862640380859, 0.965925931930541992, 7200, 255, 1, "", 45572, NULL), +(9529, 176213, 0, 0, 0, 1, 1, 1836.9097900390625, -4485.103515625, 74.07691192626953125, 4.834563255310058593, 0, 0, -0.66261959075927734, 0.748956084251403808, 7200, 255, 1, "", 45942, NULL), +(9530, 176213, 0, 0, 0, 1, 1, 1837.0533447265625, -1499.4857177734375, 59.5760040283203125, 3.22885894775390625, 0, 0, -0.99904823303222656, 0.043619260191917419, 7200, 255, 1, "", 48632, NULL), +(9531, 176213, 0, 0, 0, 1, 1, 1843.9600830078125, -3573.161376953125, 113.4916534423828125, 3.43830275535583496, 0, 0, -0.98901557922363281, 0.147811368107795715, 7200, 255, 1, "", 52237, NULL), +(9532, 176213, 0, 0, 0, 1, 1, 1845.767333984375, -1638.98095703125, 59.77754592895507812, 5.096362113952636718, 0, 0, -0.55919265747070312, 0.829037725925445556, 7200, 255, 1, "", 45854, NULL), +(9533, 176213, 0, 0, 0, 1, 1, 1859.8663330078125, -4938.02294921875, 74.93915557861328125, 3.24634718894958496, 0, 0, -0.99862861633300781, 0.052353221923112869, 7200, 255, 1, "", 50664, NULL), +(9534, 176213, 0, 0, 0, 1, 1, 1870.0045166015625, -3988.166259765625, 118.5684280395507812, 0.174532130360603332, 0, 0, 0.087155342102050781, 0.996194720268249511, 7200, 255, 1, "", 49345, NULL), +(9535, 176213, 0, 0, 0, 1, 1, 1876.0130615234375, -4825.20068359375, 110.0122528076171875, 4.066620349884033203, 0, 0, -0.89493370056152343, 0.44619917869567871, 7200, 255, 1, "", 46248, NULL), +(9536, 176213, 0, 0, 0, 1, 1, 1893.234619140625, -3021.161376953125, 75.18372344970703125, 4.136432647705078125, 0, 0, -0.87881660461425781, 0.477159708738327026, 7200, 255, 1, "", 50664, NULL), +(9537, 176213, 0, 0, 0, 1, 1, 1904.0816650390625, -1558.71875, 59.09841537475585937, 0.15707901120185852, 0, 0, 0.078458786010742187, 0.996917366981506347, 7200, 255, 1, "", 54261, NULL), +(9538, 176213, 0, 0, 0, 1, 1, 1909.2803955078125, -3565.246337890625, 115.581207275390625, 5.166176319122314453, 0, 0, -0.52991867065429687, 0.84804844856262207, 7200, 255, 1, "", 50664, NULL), +(9539, 176213, 0, 0, 0, 1, 1, 1945.2076416015625, -4410.9912109375, 73.882720947265625, 1.291541695594787597, 0, 0, 0.60181427001953125, 0.798636078834533691, 7200, 255, 1, "", 50664, NULL), +(9540, 176213, 0, 0, 0, 1, 1, 1954.7691650390625, -4858.17919921875, 105.0598526000976562, 2.879789113998413085, 0, 0, 0.991444587707519531, 0.130528271198272705, 7200, 255, 1, "", 50664, NULL), +(9541, 176213, 0, 0, 0, 1, 1, 1966.1785888671875, -3421.71728515625, 102.4839096069335937, 5.672322273254394531, 0, 0, -0.3007049560546875, 0.953717231750488281, 7200, 255, 1, "", 51739, NULL), +(9542, 176213, 0, 0, 0, 1, 1, 1968.90625, -2337.35498046875, 59.43008804321289062, 2.740161895751953125, 0, 0, 0.979924201965332031, 0.199370384216308593, 7200, 255, 1, "", 51943, NULL), +(9543, 176213, 0, 0, 0, 1, 1, 1974.90234375, -3975.155517578125, 122.6777725219726562, 5.759587764739990234, 0, 0, -0.25881862640380859, 0.965925931930541992, 7200, 255, 1, "", 50664, NULL), +(9544, 176213, 0, 0, 0, 1, 1, 1975.990234375, -3610.39794921875, 123.4244384765625, 1.413715124130249023, 0, 0, 0.649447441101074218, 0.760406434535980224, 7200, 255, 1, "", 50664, NULL), +(9545, 176213, 0, 0, 0, 1, 1, 1980.374755859375, -4824.86279296875, 93.14084625244140625, 0.15707901120185852, 0, 0, 0.078458786010742187, 0.996917366981506347, 7200, 255, 1, "", 45942, NULL), +(9546, 176213, 0, 0, 0, 1, 1, 1984.4683837890625, -3204.544677734375, 90.8921661376953125, 5.777040958404541015, 0, 0, -0.25037956237792968, 0.968147754669189453, 7200, 255, 1, "", 46158, NULL), +(9547, 176213, 0, 0, 0, 1, 1, 1987.42822265625, -4193.2275390625, 11.91735076904296875, 2.111847877502441406, 0, 0, 0.870355606079101562, 0.492423713207244873, 7200, 255, 1, "", 46248, NULL), +(9548, 176213, 0, 0, 0, 1, 1, 1990.5465087890625, -4574.73681640625, 73.62023162841796875, 3.735006093978881835, 0, 0, -0.95630455017089843, 0.292372345924377441, 7200, 255, 1, "", 46182, NULL), +(9549, 176213, 0, 0, 0, 1, 1, 1994.635009765625, -5024.892578125, 74.05865478515625, 5.445427894592285156, 0, 0, -0.40673637390136718, 0.913545548915863037, 7200, 255, 1, "", 45942, NULL), +(9550, 176213, 0, 0, 0, 1, 1, 2006.6827392578125, -3222.05126953125, 87.8593292236328125, 5.375615119934082031, 0, 0, -0.4383707046508789, 0.898794233798980712, 7200, 255, 1, "", 45942, NULL), +(9551, 176213, 0, 0, 0, 1, 1, 2009.135009765625, -4917.5986328125, 75.2410736083984375, 3.211419343948364257, 0, 0, -0.9993906021118164, 0.034906134009361267, 7200, 255, 1, "", 48632, NULL), +(9552, 176213, 0, 0, 0, 1, 1, 2037.09619140625, -3642.14501953125, 129.0787200927734375, 1.675513744354248046, 0, 0, 0.743144035339355468, 0.669131457805633544, 7200, 255, 1, "", 52237, NULL), +(9553, 176213, 0, 0, 0, 1, 1, 2051.180419921875, -3508.745361328125, 118.5655899047851562, 2.67034769058227539, 0, 0, 0.972369194030761718, 0.233448356389999389, 7200, 255, 1, "", 50664, NULL), +(9554, 176213, 0, 0, 0, 1, 1, 2053.743896484375, -4648.36474609375, 83.34580230712890625, 0.767943859100341796, 0, 0, 0.374606132507324218, 0.927184045314788818, 7200, 255, 1, "", 50664, NULL), +(9555, 176213, 0, 0, 0, 1, 1, 2056.85986328125, -4507.48193359375, 75.1407012939453125, 1.32644820213317871, 0, 0, 0.615660667419433593, 0.788011372089385986, 7200, 255, 1, "", 51739, NULL), +(9556, 176213, 0, 0, 0, 1, 1, 2063.5517578125, -5230.8525390625, 83.868865966796875, 5.35816192626953125, 0, 0, -0.446197509765625, 0.894934535026550292, 7200, 255, 1, "", 51943, NULL), +(9557, 176213, 0, 0, 0, 1, 1, 2064.053955078125, -4074.828125, 90.22777557373046875, 5.410521507263183593, 0, 0, -0.42261791229248046, 0.906307935714721679, 7200, 255, 1, "", 50664, NULL), +(9558, 176213, 0, 0, 0, 1, 1, 2084.8515625, -2508.86767578125, 61.53487014770507812, 3.054326534271240234, 0, 0, 0.999048233032226562, 0.043619260191917419, 7200, 255, 1, "", 52237, NULL), +(9559, 176213, 0, 0, 0, 1, 1, 2103.125, -3786.889892578125, 135.1818695068359375, 5.532694816589355468, 0, 0, -0.3665008544921875, 0.93041771650314331, 7200, 255, 1, "", 50664, NULL), +(9560, 176213, 0, 0, 0, 1, 1, 2105.1337890625, -3619.1015625, 154.1257476806640625, 2.111847877502441406, 0, 0, 0.870355606079101562, 0.492423713207244873, 7200, 255, 1, "", 49345, NULL), +(9561, 176213, 0, 0, 0, 1, 1, 2107.758056640625, -3381.773681640625, 128.1119232177734375, 5.096362113952636718, 0, 0, -0.55919265747070312, 0.829037725925445556, 7200, 255, 1, "", 50664, NULL), +(9562, 176213, 0, 0, 0, 1, 1, 2127.1455078125, -2736.7705078125, 75.9159393310546875, 4.607671737670898437, 0, 0, -0.74314403533935546, 0.669131457805633544, 7200, 255, 1, "", 50664, NULL), +(9563, 176213, 0, 0, 0, 1, 1, 2150.30078125, -3978.30810546875, 131.941009521484375, 6.265733242034912109, 0, 0, -0.00872611999511718, 0.999961912631988525, 7200, 255, 1, "", 50664, NULL), +(9564, 176213, 0, 0, 0, 1, 1, 2160.73828125, -5239.59375, 87.311309814453125, 3.141592741012573242, 0, 0, -1, 0, 7200, 255, 1, "", 50664, NULL), +(9565, 176213, 0, 0, 0, 1, 1, 2229.63671875, -2957.7822265625, 110.7782363891601562, 1.274088263511657714, 0, 0, 0.594821929931640625, 0.80385744571685791, 7200, 255, 1, "", 50664, NULL), +(9566, 176213, 0, 0, 0, 1, 1, 2258.832763671875, -5300.38134765625, 82.1673126220703125, 2.740161895751953125, 0, 0, 0.979924201965332031, 0.199370384216308593, 7200, 255, 1, "", 50664, NULL), +(9567, 176213, 0, 0, 0, 1, 1, 2280.908447265625, -5077.03759765625, 60.30791473388671875, 3.45575571060180664, 0, 0, -0.98768806457519531, 0.156436234712600708, 7200, 255, 1, "", 46248, NULL), +(9568, 176213, 0, 0, 0, 1, 1, 2286.678955078125, -4329.5078125, 74.61035919189453125, 0.628316879272460937, 0, 0, 0.309016227722167968, 0.95105677843093872, 7200, 255, 1, "", 50664, NULL), +(9569, 176213, 0, 0, 0, 1, 1, 2318.726318359375, -5221.6796875, 84.40213775634765625, 5.410521507263183593, 0, 0, -0.42261791229248046, 0.906307935714721679, 7200, 255, 1, "", 50664, NULL), +(9570, 176213, 0, 0, 0, 1, 1, 2373.094482421875, -5115.44873046875, 77.14237213134765625, 4.852017402648925781, 0, 0, -0.65605831146240234, 0.754710197448730468, 7200, 255, 1, "", 51739, NULL), +(9571, 176213, 0, 0, 0, 1, 1, 2376.9853515625, -1591.8665771484375, 111.531646728515625, 3.543023586273193359, 0, 0, -0.97992420196533203, 0.199370384216308593, 7200, 255, 1, "", 49345, NULL), +(9572, 176213, 0, 0, 0, 1, 1, 2395.571533203125, -2495.600830078125, 73.28113555908203125, 0.942476630210876464, 0, 0, 0.453989982604980468, 0.891006767749786376, 7200, 255, 1, "", 50664, NULL), +(9573, 176213, 0, 0, 0, 1, 1, 2407.165283203125, -3680.369873046875, 179.73968505859375, 5.148722648620605468, 0, 0, -0.53729915618896484, 0.843391716480255126, 7200, 255, 1, "", 49345, NULL), +(9574, 176213, 0, 0, 0, 1, 1, 2493.391845703125, -2460.99951171875, 73.755462646484375, 1.518436193466186523, 0, 0, 0.6883544921875, 0.725374460220336914, 7200, 255, 1, "", 52237, NULL), +(9575, 176213, 0, 0, 0, 1, 1, 2494.3125, -5134.03466796875, 75.277496337890625, 3.961898565292358398, 0, 0, -0.91705989837646484, 0.398749500513076782, 7200, 255, 1, "", 51739, NULL), +(9576, 176213, 0, 0, 0, 1, 1, 2514.671875, -3735.68359375, 178.346588134765625, 4.468043327331542968, 0, 0, -0.7880105972290039, 0.615661680698394775, 7200, 255, 1, "", 49345, NULL), +(9577, 176213, 0, 0, 0, 1, 1, 2589.39697265625, -1948.304931640625, 86.82270050048828125, 4.9218292236328125, 0, 0, -0.62932014465332031, 0.77714616060256958, 7200, 255, 1, "", 52237, NULL), +(9578, 176213, 0, 0, 0, 1, 1, 2628.4482421875, -4129.61572265625, 82.30001068115234375, 5.742135047912597656, 0, 0, -0.26723766326904296, 0.96363067626953125, 7200, 255, 1, "", 49345, NULL), +(9579, 176213, 0, 0, 0, 1, 1, 2749.6328125, -4022.224365234375, 96.02788543701171875, 2.321286916732788085, 0, 0, 0.917059898376464843, 0.398749500513076782, 7200, 255, 1, "", 52237, NULL), +(9580, 176213, 0, 0, 0, 1, 1, 2818.875732421875, -3605.743408203125, 100.899322509765625, 0.24434557557106018, 0, 0, 0.121869087219238281, 0.9925462007522583, 7200, 255, 1, "", 50664, NULL), +(9581, 176213, 0, 0, 0, 1, 1, 2871.005615234375, -3688.7236328125, 113.7974166870117187, 4.415683269500732421, 0, 0, -0.80385684967041015, 0.594822824001312255, 7200, 255, 1, "", 51666, NULL), +(9582, 176213, 0, 0, 0, 1, 1, 2948.663330078125, -3924.848876953125, 111.3591690063476562, 5.148722648620605468, 0, 0, -0.53729915618896484, 0.843391716480255126, 7200, 255, 1, "", 47720, NULL), +(9583, 176213, 0, 0, 0, 1, 1, 2996.583984375, -3676.655517578125, 134.7823486328125, 2.583080768585205078, 0, 0, 0.961260795593261718, 0.275640487670898437, 7200, 255, 1, "", 47800, NULL), +(9584, 176213, 0, 0, 0, 1, 1, 3111.05322265625, -3684.288330078125, 135.5951690673828125, 3.926995515823364257, 0, 0, -0.92387866973876953, 0.38268551230430603, 7200, 255, 1, "", 48120, NULL), +(9585, 176213, 0, 0, 0, 1, 1, 3112.603515625, -3688.038330078125, 134.407806396484375, 3.194002151489257812, 0, 0, -0.99965667724609375, 0.026201646775007247, 7200, 255, 1, "", 46248, NULL), +(9586, 176213, 0, 0, 0, 1, 1, 3131.486083984375, -3521.912841796875, 154.18524169921875, 5.218535900115966796, 0, 0, -0.507537841796875, 0.861629426479339599, 7200, 255, 1, "", 47800, NULL), +(9587, 176213, 0, 0, 0, 1, 1, 940.89410400390625, -2501.37353515625, 58.77406692504882812, 2.617989301681518554, 0, 0, 0.965925216674804687, 0.258821308612823486, 7200, 255, 1, "", 54261, NULL); + +-- remaining spawns (no sniffed values available) +-- (`guid` IN (45514, 45868, 5280)) + +SET @POOL := 298; + +DELETE FROM `pool_gameobject` WHERE `pool_entry` = @POOL; +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(5276, @POOL, 0, 'Blood of Heroes'), +(5277, @POOL, 0, 'Blood of Heroes'), +(5278, @POOL, 0, 'Blood of Heroes'), +(5279, @POOL, 0, 'Blood of Heroes'), +(5280, @POOL, 0, 'Blood of Heroes'), +(5281, @POOL, 0, 'Blood of Heroes'), +(9478, @POOL, 0, 'Blood of Heroes'), +(9479, @POOL, 0, 'Blood of Heroes'), +(9480, @POOL, 0, 'Blood of Heroes'), +(9481, @POOL, 0, 'Blood of Heroes'), +(9482, @POOL, 0, 'Blood of Heroes'), +(9483, @POOL, 0, 'Blood of Heroes'), +(9484, @POOL, 0, 'Blood of Heroes'), +(9485, @POOL, 0, 'Blood of Heroes'), +(9486, @POOL, 0, 'Blood of Heroes'), +(9487, @POOL, 0, 'Blood of Heroes'), +(9488, @POOL, 0, 'Blood of Heroes'), +(9489, @POOL, 0, 'Blood of Heroes'), +(9490, @POOL, 0, 'Blood of Heroes'), +(9491, @POOL, 0, 'Blood of Heroes'), +(9492, @POOL, 0, 'Blood of Heroes'), +(9493, @POOL, 0, 'Blood of Heroes'), +(9494, @POOL, 0, 'Blood of Heroes'), +(9495, @POOL, 0, 'Blood of Heroes'), +(9496, @POOL, 0, 'Blood of Heroes'), +(9497, @POOL, 0, 'Blood of Heroes'), +(9498, @POOL, 0, 'Blood of Heroes'), +(9499, @POOL, 0, 'Blood of Heroes'), +(9500, @POOL, 0, 'Blood of Heroes'), +(9501, @POOL, 0, 'Blood of Heroes'), +(9502, @POOL, 0, 'Blood of Heroes'), +(9503, @POOL, 0, 'Blood of Heroes'), +(9504, @POOL, 0, 'Blood of Heroes'), +(9505, @POOL, 0, 'Blood of Heroes'), +(9506, @POOL, 0, 'Blood of Heroes'), +(9507, @POOL, 0, 'Blood of Heroes'), +(9508, @POOL, 0, 'Blood of Heroes'), +(9509, @POOL, 0, 'Blood of Heroes'), +(9510, @POOL, 0, 'Blood of Heroes'), +(9511, @POOL, 0, 'Blood of Heroes'), +(9512, @POOL, 0, 'Blood of Heroes'), +(9513, @POOL, 0, 'Blood of Heroes'), +(9514, @POOL, 0, 'Blood of Heroes'), +(9515, @POOL, 0, 'Blood of Heroes'), +(9516, @POOL, 0, 'Blood of Heroes'), +(9517, @POOL, 0, 'Blood of Heroes'), +(9518, @POOL, 0, 'Blood of Heroes'), +(9519, @POOL, 0, 'Blood of Heroes'), +(9520, @POOL, 0, 'Blood of Heroes'), +(9521, @POOL, 0, 'Blood of Heroes'), +(9522, @POOL, 0, 'Blood of Heroes'), +(9523, @POOL, 0, 'Blood of Heroes'), +(9524, @POOL, 0, 'Blood of Heroes'), +(9525, @POOL, 0, 'Blood of Heroes'), +(9526, @POOL, 0, 'Blood of Heroes'), +(9527, @POOL, 0, 'Blood of Heroes'), +(9528, @POOL, 0, 'Blood of Heroes'), +(9529, @POOL, 0, 'Blood of Heroes'), +(9530, @POOL, 0, 'Blood of Heroes'), +(9531, @POOL, 0, 'Blood of Heroes'), +(9532, @POOL, 0, 'Blood of Heroes'), +(9533, @POOL, 0, 'Blood of Heroes'), +(9534, @POOL, 0, 'Blood of Heroes'), +(9535, @POOL, 0, 'Blood of Heroes'), +(9536, @POOL, 0, 'Blood of Heroes'), +(9537, @POOL, 0, 'Blood of Heroes'), +(9538, @POOL, 0, 'Blood of Heroes'), +(9539, @POOL, 0, 'Blood of Heroes'), +(9540, @POOL, 0, 'Blood of Heroes'), +(9541, @POOL, 0, 'Blood of Heroes'), +(9542, @POOL, 0, 'Blood of Heroes'), +(9543, @POOL, 0, 'Blood of Heroes'), +(9544, @POOL, 0, 'Blood of Heroes'), +(9545, @POOL, 0, 'Blood of Heroes'), +(9546, @POOL, 0, 'Blood of Heroes'), +(9547, @POOL, 0, 'Blood of Heroes'), +(9548, @POOL, 0, 'Blood of Heroes'), +(9549, @POOL, 0, 'Blood of Heroes'), +(9550, @POOL, 0, 'Blood of Heroes'), +(9551, @POOL, 0, 'Blood of Heroes'), +(9552, @POOL, 0, 'Blood of Heroes'), +(9553, @POOL, 0, 'Blood of Heroes'), +(9554, @POOL, 0, 'Blood of Heroes'), +(9555, @POOL, 0, 'Blood of Heroes'), +(9556, @POOL, 0, 'Blood of Heroes'), +(9557, @POOL, 0, 'Blood of Heroes'), +(9558, @POOL, 0, 'Blood of Heroes'), +(9559, @POOL, 0, 'Blood of Heroes'), +(9560, @POOL, 0, 'Blood of Heroes'), +(9561, @POOL, 0, 'Blood of Heroes'), +(9562, @POOL, 0, 'Blood of Heroes'), +(9563, @POOL, 0, 'Blood of Heroes'), +(9564, @POOL, 0, 'Blood of Heroes'), +(9565, @POOL, 0, 'Blood of Heroes'), +(9566, @POOL, 0, 'Blood of Heroes'), +(9567, @POOL, 0, 'Blood of Heroes'), +(9568, @POOL, 0, 'Blood of Heroes'), +(9569, @POOL, 0, 'Blood of Heroes'), +(9570, @POOL, 0, 'Blood of Heroes'), +(9571, @POOL, 0, 'Blood of Heroes'), +(9572, @POOL, 0, 'Blood of Heroes'), +(9573, @POOL, 0, 'Blood of Heroes'), +(9574, @POOL, 0, 'Blood of Heroes'), +(9575, @POOL, 0, 'Blood of Heroes'), +(9576, @POOL, 0, 'Blood of Heroes'), +(9577, @POOL, 0, 'Blood of Heroes'), +(9578, @POOL, 0, 'Blood of Heroes'), +(9579, @POOL, 0, 'Blood of Heroes'), +(9580, @POOL, 0, 'Blood of Heroes'), +(9581, @POOL, 0, 'Blood of Heroes'), +(9582, @POOL, 0, 'Blood of Heroes'), +(9583, @POOL, 0, 'Blood of Heroes'), +(9584, @POOL, 0, 'Blood of Heroes'), +(9585, @POOL, 0, 'Blood of Heroes'), +(9586, @POOL, 0, 'Blood of Heroes'), +(9587, @POOL, 0, 'Blood of Heroes'), +(45512, @POOL, 0, 'Blood of Heroes'), +(45514, @POOL, 0, 'Blood of Heroes'), +(45736, @POOL, 0, 'Blood of Heroes'), +(45853, @POOL, 0, 'Blood of Heroes'), +(45868, @POOL, 0, 'Blood of Heroes'), +(45892, @POOL, 0, 'Blood of Heroes'), +(45934, @POOL, 0, 'Blood of Heroes'), +(45936, @POOL, 0, 'Blood of Heroes'); + +DELETE FROM `pool_template` WHERE `entry` = @POOL; +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@POOL, 15, 'Blood of Heroes'); From cfd45f86dc6dd7603b8bd462d3240d9fdeaf5862 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 17:43:04 +0000 Subject: [PATCH 292/335] chore(DB): import pending files Referenced commit(s): 4d2402a28528228c49cbdb77affd6d4df7263066 --- .../rev_1771967006571378200.sql => db_world/2026_02_25_10.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771967006571378200.sql => db_world/2026_02_25_10.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771967006571378200.sql b/data/sql/updates/db_world/2026_02_25_10.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771967006571378200.sql rename to data/sql/updates/db_world/2026_02_25_10.sql index 4852a4f43..bba48a9cc 100644 --- a/data/sql/updates/pending_db_world/rev_1771967006571378200.sql +++ b/data/sql/updates/db_world/2026_02_25_10.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_09 -> 2026_02_25_10 -- Update gameobject 'Blood of Heroes' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (176213)) AND (`guid` IN (45512, 45736, 45853, 45892, 45934, 45936, 5276, 5277, 5278, 5279, 5281)); From ec7cf77d24dd991c86f6114f965d1ac77813f9ea Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:58:27 -0300 Subject: [PATCH 293/335] fix(DB/GameObject): Set Sniffed Flags to Serpentshrine Console Misc Doodad (#24876) --- data/sql/updates/pending_db_world/rev_1772037778481526100.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772037778481526100.sql diff --git a/data/sql/updates/pending_db_world/rev_1772037778481526100.sql b/data/sql/updates/pending_db_world/rev_1772037778481526100.sql new file mode 100644 index 000000000..b2031bb11 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772037778481526100.sql @@ -0,0 +1,2 @@ +-- +UPDATE `gameobject_template_addon` SET `flags` = 16 WHERE (`entry` IN (185115, 185117, 185118)); From d2b60765b17dec74e52cf6afc40f6624298fcc22 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 17:59:46 +0000 Subject: [PATCH 294/335] chore(DB): import pending files Referenced commit(s): ec7cf77d24dd991c86f6114f965d1ac77813f9ea --- .../rev_1772037778481526100.sql => db_world/2026_02_25_11.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772037778481526100.sql => db_world/2026_02_25_11.sql} (69%) diff --git a/data/sql/updates/pending_db_world/rev_1772037778481526100.sql b/data/sql/updates/db_world/2026_02_25_11.sql similarity index 69% rename from data/sql/updates/pending_db_world/rev_1772037778481526100.sql rename to data/sql/updates/db_world/2026_02_25_11.sql index b2031bb11..fb27fbc81 100644 --- a/data/sql/updates/pending_db_world/rev_1772037778481526100.sql +++ b/data/sql/updates/db_world/2026_02_25_11.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_25_10 -> 2026_02_25_11 -- UPDATE `gameobject_template_addon` SET `flags` = 16 WHERE (`entry` IN (185115, 185117, 185118)); From 460e2e0cac546f1d9252639e3b10b3477c6a3a9a Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Wed, 25 Feb 2026 12:41:42 -0600 Subject: [PATCH 295/335] fix(Core/Spells): Prevent friendly spells from breaking stealth (#24875) --- src/server/game/Spells/Auras/SpellAuras.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 9bb9ba9e3..0c908e848 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2184,7 +2184,7 @@ uint8 Aura::GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo, if (m_spellInfo->HasAura(SPELL_AURA_MOD_STEALTH)) { if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - if (spellInfo->IsPositive()) + if (spellInfo->IsPositive() || !eventInfo.GetActor()->IsHostileTo(aurApp->GetTarget())) return 0; } From f370dce7f862fab64f9f4806b7436ece3ce8de6e Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Wed, 25 Feb 2026 18:20:23 -0300 Subject: [PATCH 296/335] fix(DB/Spells): Port Proc Cooldowns from old spell_proc_event table (#24878) --- .../rev_1772046138468225100.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772046138468225100.sql diff --git a/data/sql/updates/pending_db_world/rev_1772046138468225100.sql b/data/sql/updates/pending_db_world/rev_1772046138468225100.sql new file mode 100644 index 000000000..8959b5311 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772046138468225100.sql @@ -0,0 +1,17 @@ +-- +DELETE FROM `spell_proc` WHERE `SpellId` IN (21747,24256,27997,28460,33511,33522,38319,40303,43730,43983,45396,45398,45444,55717); +INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES +(21747, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 50000, 0), -- Lawbringer +(24256, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 240000, 0), -- Primal Blessing Trigger DND +(27997, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 50000, 0), -- Spellsurge Trigger +(28460, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 5000, 0), -- Wail of Souls +(33511, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 17000, 0), -- Mana Restore +(33522, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 25000, 0), -- Mana Restore 2 +(38319, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 50000, 0), -- Forgotten Knowledge +(40303, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1000, 0), -- Spell Bomb +(43730, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 8000, 0), -- Stormchops +(43983, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 500, 0), -- Energy Storm +(45396, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 45000, 0), -- Blessed Weapon Coating +(45398, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 45000, 0), -- Righteous Weapon Coating +(45444, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 45000, 0), -- Bonfire's Blessing +(55717, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 5000, 0); -- Wail of Souls From e54c21941ad354d788060227a8e99d2144e31143 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 21:21:30 +0000 Subject: [PATCH 297/335] chore(DB): import pending files Referenced commit(s): f370dce7f862fab64f9f4806b7436ece3ce8de6e --- .../rev_1772046138468225100.sql => db_world/2026_02_25_12.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772046138468225100.sql => db_world/2026_02_25_12.sql} (97%) diff --git a/data/sql/updates/pending_db_world/rev_1772046138468225100.sql b/data/sql/updates/db_world/2026_02_25_12.sql similarity index 97% rename from data/sql/updates/pending_db_world/rev_1772046138468225100.sql rename to data/sql/updates/db_world/2026_02_25_12.sql index 8959b5311..038e3a13a 100644 --- a/data/sql/updates/pending_db_world/rev_1772046138468225100.sql +++ b/data/sql/updates/db_world/2026_02_25_12.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_11 -> 2026_02_25_12 -- DELETE FROM `spell_proc` WHERE `SpellId` IN (21747,24256,27997,28460,33511,33522,38319,40303,43730,43983,45396,45398,45444,55717); INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `DisableEffectsMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES From 0064cdd9ffe5702b8077e7879ec464982d9f3195 Mon Sep 17 00:00:00 2001 From: sudlud Date: Wed, 25 Feb 2026 22:57:00 +0100 Subject: [PATCH 298/335] fix(DB/Gameobject): Sniffed Values for 'unnamed flames' spawns (#24879) --- .../updates/pending_db_world/rev_1772049216964671100.sql | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772049216964671100.sql diff --git a/data/sql/updates/pending_db_world/rev_1772049216964671100.sql b/data/sql/updates/pending_db_world/rev_1772049216964671100.sql new file mode 100644 index 000000000..b0af3bf27 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772049216964671100.sql @@ -0,0 +1,7 @@ +-- Update gameobject 'unnamed flames' with sniffed values +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (184511, 184512, 184513)) AND (`guid` IN (198, 199, 200)); +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 +(198, 184511, 530, 0, 0, 1, 1, 4014.947021484375, 1910.8055419921875, 247.6915130615234375, 3.710935592651367187, 0, 0, -0.95975399017333984, 0.280842065811157226, 120, 255, 1, "", 45704, NULL), +(199, 184512, 530, 0, 0, 1, 1, 4017.040771484375, 1909.5833740234375, 247.8500213623046875, 5.209121227264404296, 0, 0, -0.51158809661865234, 0.85923081636428833, 120, 255, 1, "", 45704, NULL), +(200, 184513, 530, 0, 0, 1, 1, 4015.8291015625, 1909.7274169921875, 247.7547149658203125, 3.043226480484008789, 0, 0, 0.998790740966796875, 0.049163278192281723, 120, 255, 1, "", 45704, NULL); From 16daeea31600033220570d34be0596066248987e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 21:58:06 +0000 Subject: [PATCH 299/335] chore(DB): import pending files Referenced commit(s): 0064cdd9ffe5702b8077e7879ec464982d9f3195 --- .../rev_1772049216964671100.sql => db_world/2026_02_25_13.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772049216964671100.sql => db_world/2026_02_25_13.sql} (95%) diff --git a/data/sql/updates/pending_db_world/rev_1772049216964671100.sql b/data/sql/updates/db_world/2026_02_25_13.sql similarity index 95% rename from data/sql/updates/pending_db_world/rev_1772049216964671100.sql rename to data/sql/updates/db_world/2026_02_25_13.sql index b0af3bf27..e40bea950 100644 --- a/data/sql/updates/pending_db_world/rev_1772049216964671100.sql +++ b/data/sql/updates/db_world/2026_02_25_13.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_12 -> 2026_02_25_13 -- Update gameobject 'unnamed flames' with sniffed values -- new spawns DELETE FROM `gameobject` WHERE (`id` IN (184511, 184512, 184513)) AND (`guid` IN (198, 199, 200)); From fcd7e383c2a5812d7f10f28f67749d014197d65b Mon Sep 17 00:00:00 2001 From: Tereneckla Date: Wed, 25 Feb 2026 22:19:46 +0000 Subject: [PATCH 300/335] fix(DB/Spells): Add scrolls to the str/agi spell group (#24877) --- data/sql/updates/pending_db_world/rev_1772038558469780044.sql | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772038558469780044.sql diff --git a/data/sql/updates/pending_db_world/rev_1772038558469780044.sql b/data/sql/updates/pending_db_world/rev_1772038558469780044.sql new file mode 100644 index 000000000..079cd2da1 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772038558469780044.sql @@ -0,0 +1,3 @@ +-- +DELETE FROM `spell_group` WHERE `id` = 1088 AND `spell_id` IN (-1066, -1067); +INSERT INTO `spell_group` (`id`,`spell_id`) VALUES (1088, -1066), (1088, -1067); From 4694cb25704bd7cfff993217c9fbd9867db417ce Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 22:20:56 +0000 Subject: [PATCH 301/335] chore(DB): import pending files Referenced commit(s): fcd7e383c2a5812d7f10f28f67749d014197d65b --- .../rev_1772038558469780044.sql => db_world/2026_02_25_14.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772038558469780044.sql => db_world/2026_02_25_14.sql} (78%) diff --git a/data/sql/updates/pending_db_world/rev_1772038558469780044.sql b/data/sql/updates/db_world/2026_02_25_14.sql similarity index 78% rename from data/sql/updates/pending_db_world/rev_1772038558469780044.sql rename to data/sql/updates/db_world/2026_02_25_14.sql index 079cd2da1..27a19e0f6 100644 --- a/data/sql/updates/pending_db_world/rev_1772038558469780044.sql +++ b/data/sql/updates/db_world/2026_02_25_14.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_13 -> 2026_02_25_14 -- DELETE FROM `spell_group` WHERE `id` = 1088 AND `spell_id` IN (-1066, -1067); INSERT INTO `spell_group` (`id`,`spell_id`) VALUES (1088, -1066), (1088, -1067); From 0d7baa00f6661143e6aaedc2b68715ef23208c54 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Wed, 25 Feb 2026 19:43:52 -0300 Subject: [PATCH 302/335] fix(DB/Loot): Remove ilvl 146 Weapons in the 72-74 Level Range that were never supposed to drop in original WotLK (#24885) --- .../rev_1772058834607248000.sql | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772058834607248000.sql diff --git a/data/sql/updates/pending_db_world/rev_1772058834607248000.sql b/data/sql/updates/pending_db_world/rev_1772058834607248000.sql new file mode 100644 index 000000000..a38ec606c --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772058834607248000.sql @@ -0,0 +1,20 @@ +-- +DELETE FROM `reference_loot_template` WHERE `Entry` = 1227274 AND `Item` IN ( +36533, -- Adorned Broadsword +36603, -- Archaic Longspear +36575, -- Dragonflayer Hatchet +36505, -- Frosted Steel Mallet +36631, -- Horned Crossbow +36687, -- Illuminated Scepter +36547, -- Jester's Stick +36519, -- Moonlit Katana +36701, -- Pine Needle Staff +36715, -- Runed Shuriken, 146 +36589, -- Segmenting Broadaxe +36491, -- Serrated Maul +36659, -- Shivery Wand +36645, -- Tuskarr Boomstick +36477, -- Twin-Edged Stiletto +36673, -- Wise Dagger +36617 -- Yielding Bow +); From 46ceba3d002f5dce9413e88a4ae2e437bf2524bb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 22:49:18 +0000 Subject: [PATCH 303/335] chore(DB): import pending files Referenced commit(s): 0d7baa00f6661143e6aaedc2b68715ef23208c54 --- .../rev_1772058834607248000.sql => db_world/2026_02_25_15.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772058834607248000.sql => db_world/2026_02_25_15.sql} (92%) diff --git a/data/sql/updates/pending_db_world/rev_1772058834607248000.sql b/data/sql/updates/db_world/2026_02_25_15.sql similarity index 92% rename from data/sql/updates/pending_db_world/rev_1772058834607248000.sql rename to data/sql/updates/db_world/2026_02_25_15.sql index a38ec606c..9cd997993 100644 --- a/data/sql/updates/pending_db_world/rev_1772058834607248000.sql +++ b/data/sql/updates/db_world/2026_02_25_15.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_14 -> 2026_02_25_15 -- DELETE FROM `reference_loot_template` WHERE `Entry` = 1227274 AND `Item` IN ( 36533, -- Adorned Broadsword From 2ff0ec82112510dc5c892a9d0d807938572ec0b3 Mon Sep 17 00:00:00 2001 From: sudlud Date: Thu, 26 Feb 2026 00:09:34 +0100 Subject: [PATCH 304/335] fix(DB/Gameobject): Sniffed Values for 'Doodad_WoodSign%' spawns (#24882) --- .../rev_1772057308668452700.sql | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772057308668452700.sql diff --git a/data/sql/updates/pending_db_world/rev_1772057308668452700.sql b/data/sql/updates/pending_db_world/rev_1772057308668452700.sql new file mode 100644 index 000000000..9fea76a40 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772057308668452700.sql @@ -0,0 +1,22 @@ +-- Update gameobject 'Doodad_WoodSign%' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (175657, 175656)) AND (`guid` IN (45623, 45624)); +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 +(45623, 175657, 0, 0, 0, 1, 1, 3447.166015625, -3369.943603515625, 140.924652099609375, 4.7944183349609375, -0.11731481552124023, 0.128026962280273437, -0.66532611846923828, 0.726076781749725341, 120, 255, 1, "", 46248, NULL), +(45624, 175656, 0, 0, 0, 1, 1, 3446.5439453125, -3370.093017578125, 140.956390380859375, 1.658061861991882324, 0, 0, 0.737277030944824218, 0.67559051513671875, 120, 255, 1, "", 46248, NULL); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (175647, 175648, 175649, 175650, 175651, 175652, 175653, 175656, 175657, 191103, 191104, 191105)) AND (`guid` IN (1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838)); +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 +(1827, 175647, 0, 0, 0, 1, 1, 3524.133544921875, -3377.8134765625, 133.013336181640625, 2.967044830322265625, -0.00380182266235351, -0.04345226287841796, 0.995245933532714843, 0.087080210447311401, 120, 255, 1, "", 51943, NULL), +(1828, 175648, 0, 0, 0, 1, 1, 3524.405029296875, -3376.470458984375, 132.1711578369140625, 2.967034816741943359, -0.01886367797851562, -0.21561527252197265, 0.9725799560546875, 0.085102535784244537, 120, 255, 1, "", 51943, NULL), +(1829, 175649, 0, 0, 0, 1, 1, 3524.434326171875, -3376.182373046875, 133.055755615234375, 6.108653545379638671, 0, 0, -0.08715534210205078, 0.996194720268249511, 120, 255, 1, "", 51943, NULL), +(1830, 175650, 0, 0, 0, 1, 1, 3523.578369140625, -3377.0380859375, 132.5085906982421875, 1.396262884140014648, -0.03341388702392578, -0.02803707122802734, 0.642175674438476562, 0.765315532684326171, 120, 255, 1, "", 51943, NULL), +(1831, 175651, 0, 0, 0, 1, 1, 3558.121337890625, -3320.4375, 130.2952880859375, 4.450591087341308593, 0.07945871353149414, -0.10355281829833984, -0.78656578063964843, 0.603554010391235351, 120, 255, 1, "", 51943, NULL), +(1832, 175652, 0, 0, 0, 1, 1, 3555.34716796875, -3319.654541015625, 129.94805908203125, 1.308995485305786132, 0, 0, 0.608760833740234375, 0.793353796005249023, 120, 255, 1, "", 51943, NULL), +(1833, 175653, 0, 0, 0, 1, 1, 3555.99267578125, -3321.162109375, 129.500030517578125, 2.879780769348144531, 0.005692958831787109, 0.043245315551757812, 0.990500450134277343, 0.130408123135566711, 120, 255, 1, "", 51943, NULL), +(1834, 175656, 533, 0, 0, 3, 1, 3446.5439453125, -3370.093017578125, 140.9564361572265625, 1.658061861991882324, 0, 0, 0.737277030944824218, 0.67559051513671875, 7200, 255, 1, "", 45942, NULL), +(1835, 175657, 533, 0, 0, 3, 1, 3447.166015625, -3369.943603515625, 140.9246978759765625, 4.7944183349609375, -0.11731481552124023, 0.128026962280273437, -0.66532611846923828, 0.726076781749725341, 7200, 255, 1, "", 45942, NULL), +(1836, 191103, 595, 0, 0, 3, 1, 2317.92431640625, 1055.965087890625, 138.809112548828125, 0.261798620223999023, 0.043245792388916015, 0.005692481994628906, 0.130401611328125, 0.990501284599304199, 7200, 255, 1, "", 46248, NULL), +(1837, 191104, 595, 0, 0, 3, 1, 2319.237060546875, 1054.982177734375, 139.2571563720703125, 4.97418975830078125, 0, 0, -0.60876083374023437, 0.793353796005249023, 7200, 255, 1, "", 46248, NULL), +(1838, 191105, 595, 0, 0, 3, 1, 2316.443115234375, 1054.273193359375, 139.6043853759765625, 1.83259439468383789, 0.07945871353149414, 0.103552818298339843, 0.786565780639648437, 0.603554010391235351, 7200, 255, 1, "", 46248, NULL); From aafe5f8b2f1b0cb94b4bd3df7d6ab9bb4e29152f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 25 Feb 2026 23:33:16 +0000 Subject: [PATCH 305/335] chore(DB): import pending files Referenced commit(s): 46ceba3d002f5dce9413e88a4ae2e437bf2524bb --- .../rev_1772057308668452700.sql => db_world/2026_02_25_16.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772057308668452700.sql => db_world/2026_02_25_16.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1772057308668452700.sql b/data/sql/updates/db_world/2026_02_25_16.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1772057308668452700.sql rename to data/sql/updates/db_world/2026_02_25_16.sql index 9fea76a40..65d115f1b 100644 --- a/data/sql/updates/pending_db_world/rev_1772057308668452700.sql +++ b/data/sql/updates/db_world/2026_02_25_16.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_15 -> 2026_02_25_16 -- Update gameobject 'Doodad_WoodSign%' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (175657, 175656)) AND (`guid` IN (45623, 45624)); From 00550945dfb01ba1419c23967d44ed7cbd07b9b5 Mon Sep 17 00:00:00 2001 From: sudlud Date: Thu, 26 Feb 2026 03:27:00 +0100 Subject: [PATCH 306/335] fix(DB/Gameobject): Sniffed Values for 'Sitting Skeleton 03' spawns (#24883) --- .../rev_1772058465656331100.sql | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772058465656331100.sql diff --git a/data/sql/updates/pending_db_world/rev_1772058465656331100.sql b/data/sql/updates/pending_db_world/rev_1772058465656331100.sql new file mode 100644 index 000000000..d9d1811a0 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772058465656331100.sql @@ -0,0 +1,23 @@ +-- Update gameobject 'Sitting Skeleton 03' with sniffed values +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (185436)) AND (`guid` IN (2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072)); +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 +(2058, 185436, 530, 0, 0, 1, 1, -3907.8671875, 2093.739013671875, 95.62811279296875, 3.543023586273193359, 0, 0, -0.97992420196533203, 0.199370384216308593, 120, 255, 1, "", 45942, NULL), +(2059, 185436, 530, 0, 0, 1, 1, -564.967041015625, 4154.21337890625, 68.07680511474609375, 3.78736734390258789, 0, 0, -0.94832324981689453, 0.317305892705917358, 120, 255, 1, "", 45942, NULL), +(2060, 185436, 530, 0, 0, 1, 1, -574.1278076171875, 4140.8173828125, 68.09943389892578125, 2.583080768585205078, 0, 0, 0.961260795593261718, 0.275640487670898437, 120, 255, 1, "", 45942, NULL), +(2061, 185436, 530, 0, 0, 1, 1, -589.0184326171875, 4162.07666015625, 66.71608734130859375, 2.076939344406127929, 0, 0, 0.861628532409667968, 0.50753939151763916, 120, 255, 1, "", 45942, NULL), +(2062, 185436, 530, 0, 0, 1, 1, -600.029296875, 4182.40869140625, 65.08914947509765625, 5.131268978118896484, 0, 0, -0.54463863372802734, 0.838670849800109863, 120, 255, 1, "", 45942, NULL), +(2063, 185436, 530, 0, 0, 1, 1, -603.2060546875, 4110.416015625, 89.74161529541015625, 3.351046562194824218, 0, 0, -0.99452114105224609, 0.104535527527332305, 120, 255, 1, "", 45942, NULL), +(2064, 185436, 530, 0, 0, 1, 1, -705.45172119140625, 4170.107421875, 58.10678482055664062, 2.042035102844238281, 0, 0, 0.852640151977539062, 0.522498607635498046, 120, 255, 1, "", 45942, NULL), +(2065, 185436, 530, 0, 0, 1, 1, 2020.396484375, 6883.37109375, 179.0448760986328125, 4.223697185516357421, 0, 0, -0.85716724395751953, 0.515038192272186279, 120, 255, 1, "", 45942, NULL), +(2066, 185436, 530, 0, 0, 1, 1, 2020.7047119140625, 6866.521484375, 175.3189239501953125, 4.817109584808349609, 0, 0, -0.66913032531738281, 0.74314504861831665, 120, 255, 1, "", 45942, NULL), +(2067, 185436, 530, 0, 0, 1, 1, 2086.187744140625, 6900.2080078125, 192.64654541015625, 5.532694816589355468, 0, 0, -0.3665008544921875, 0.93041771650314331, 120, 255, 1, "", 45942, NULL), +(2068, 185436, 530, 0, 0, 1, 1, 2093.576904296875, 6905.708984375, 184.14654541015625, 0.820303261280059814, 0, 0, 0.398748397827148437, 0.917060375213623046, 120, 255, 1, "", 45942, NULL), +(2069, 185436, 530, 0, 0, 1, 1, 2095.02099609375, 6914.87158203125, 184.14654541015625, 4.852017402648925781, 0, 0, -0.65605831146240234, 0.754710197448730468, 120, 255, 1, "", 45942, NULL), +(2070, 185436, 530, 0, 0, 1, 1, 2332.642822265625, 6017.2548828125, 143.2427978515625, 2.460912704467773437, 0, 0, 0.942641258239746093, 0.333807557821273803, 120, 255, 1, "", 45942, NULL), +(2071, 185436, 530, 0, 0, 1, 1, 236.929473876953125, 4335.20556640625, 119.2413330078125, 2.164205789566040039, 0, 0, 0.882946968078613281, 0.469472706317901611, 120, 255, 1, "", 45942, NULL), +(2072, 185436, 530, 0, 0, 1, 1, 2378.47021484375, 5942.01025390625, 152.7965545654296875, 5.811946868896484375, 0, 0, -0.2334451675415039, 0.972369968891143798, 120, 255, 1, "", 45942, NULL); + +-- enable all spawns for eventEntry 12 +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 12) AND (`guid` IN (SELECT `guid` FROM `gameobject` WHERE `id` IN (185436))); +INSERT INTO `game_event_gameobject` (SELECT 12, `guid` FROM `gameobject` WHERE `id` IN (185436)); From 905a274895c1c6497924a6241c88ab6647cca197 Mon Sep 17 00:00:00 2001 From: sudlud Date: Thu, 26 Feb 2026 03:27:37 +0100 Subject: [PATCH 307/335] fix(DB/Gameobject): Sniffed Values for 'Huge Sitting Skeleton 02' spawns (#24884) --- .../rev_1772058806703413600.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772058806703413600.sql diff --git a/data/sql/updates/pending_db_world/rev_1772058806703413600.sql b/data/sql/updates/pending_db_world/rev_1772058806703413600.sql new file mode 100644 index 000000000..4e76c7076 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772058806703413600.sql @@ -0,0 +1,17 @@ +-- Update gameobject 'Huge Sitting Skeleton 02' with sniffed values +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (185457)) AND (`guid` IN (1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153)); +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 +(1145, 185457, 530, 0, 0, 1, 1, -1938.5836181640625, 5561.431640625, -12.428135871887207, 0.471238493919372558, 0, 0, 0.233445167541503906, 0.972369968891143798, 120, 255, 1, "", 45942, NULL), +(1146, 185457, 530, 0, 0, 1, 1, -3905.52294921875, 2069.8984375, 94.74691009521484375, 5.969027042388916015, 0, 0, -0.1564340591430664, 0.987688362598419189, 120, 255, 1, "", 46158, NULL), +(1147, 185457, 530, 0, 0, 1, 1, -3953.84423828125, 2105.051513671875, 101.2719573974609375, 1.169368624687194824, 0, 0, 0.551936149597167968, 0.833886384963989257, 120, 255, 1, "", 45942, NULL), +(1148, 185457, 530, 0, 0, 1, 1, 1865.3406982421875, 5589.482421875, 257.4517822265625, 2.146752834320068359, 0, 0, 0.878816604614257812, 0.477159708738327026, 120, 255, 1, "", 45942, NULL), +(1149, 185457, 530, 0, 0, 1, 1, 1964.1754150390625, 5582.79541015625, 260.20611572265625, 6.09120035171508789, 0, 0, -0.09584522247314453, 0.995396256446838378, 120, 255, 1, "", 45942, NULL), +(1150, 185457, 530, 0, 0, 1, 1, 2133.226318359375, 4733.923828125, 152.619537353515625, 6.14356088638305664, 0, 0, -0.06975555419921875, 0.997564136981964111, 120, 255, 1, "", 45942, NULL), +(1151, 185457, 530, 0, 0, 1, 1, 2242.098876953125, 4794.908203125, 156.0864410400390625, 2.967041015625, 0, 0, 0.996193885803222656, 0.087165042757987976, 120, 255, 1, "", 45942, NULL), +(1152, 185457, 530, 0, 0, 1, 1, 2382.612548828125, 6030.99560546875, 141.7354278564453125, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 120, 255, 1, "", 45942, NULL), +(1153, 185457, 530, 0, 0, 1, 1, 2462.454345703125, 5970.259765625, 154.7728729248046875, 3.926995515823364257, 0, 0, -0.92387866973876953, 0.38268551230430603, 120, 255, 1, "", 45942, NULL); + +-- enable all spawns for eventEntry 12 +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 12) AND (`guid` IN (SELECT `guid` FROM `gameobject` WHERE `id` IN (185457))); +INSERT INTO `game_event_gameobject` (SELECT 12, `guid` FROM `gameobject` WHERE `id` IN (185457)); From 00a5b78d72ba17dadfa953250d6e07bb3dc60918 Mon Sep 17 00:00:00 2001 From: sudlud Date: Thu, 26 Feb 2026 03:27:54 +0100 Subject: [PATCH 308/335] fix(DB/Gameobject): Sniffed Values for 'Huge Laying Skeleton 02' spawns (#24886) --- .../pending_db_world/rev_1772059110373151900.sql | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772059110373151900.sql diff --git a/data/sql/updates/pending_db_world/rev_1772059110373151900.sql b/data/sql/updates/pending_db_world/rev_1772059110373151900.sql new file mode 100644 index 000000000..dc04ea390 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772059110373151900.sql @@ -0,0 +1,12 @@ +-- Update gameobject 'Huge Laying Skeleton 02' with sniffed values +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (185458)) AND (`guid` IN (222, 223, 224, 225)); +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 +(222, 185458, 530, 0, 0, 1, 1, -3972.2392578125, 2224.816650390625, 102.3404464721679687, 0.593410074710845947, 0, 0, 0.292370796203613281, 0.95630502700805664, 120, 255, 1, "", 45942, NULL), +(223, 185458, 530, 0, 0, 1, 1, -3990.3056640625, 2148.642333984375, 104.2225723266601562, 0.139624491333961486, 0, 0, 0.06975555419921875, 0.997564136981964111, 120, 255, 1, "", 45942, NULL), +(224, 185458, 530, 0, 0, 1, 1, 2289.8935546875, 5987.240234375, 142.3500518798828125, 2.042035102844238281, 0, 0, 0.852640151977539062, 0.522498607635498046, 120, 255, 1, "", 45942, NULL), +(225, 185458, 530, 0, 0, 1, 1, 2362.826416015625, 5975.78369140625, 152.4012603759765625, 0.733038187026977539, 0, 0, 0.358367919921875, 0.933580458164215087, 120, 255, 1, "", 45942, NULL); + +-- enable all spawns for eventEntry 12 +DELETE FROM `game_event_gameobject` WHERE (`eventEntry` = 12) AND (`guid` IN (SELECT `guid` FROM `gameobject` WHERE `id` IN (185458))); +INSERT INTO `game_event_gameobject` (SELECT 12, `guid` FROM `gameobject` WHERE `id` IN (185458)); From 450e0c02921edb193c1212cbb7bd662386475c1e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 26 Feb 2026 02:28:04 +0000 Subject: [PATCH 309/335] chore(DB): import pending files Referenced commit(s): 00550945dfb01ba1419c23967d44ed7cbd07b9b5 --- .../rev_1772058465656331100.sql => db_world/2026_02_26_00.sql} | 1 + .../rev_1772058806703413600.sql => db_world/2026_02_26_01.sql} | 1 + .../rev_1772059110373151900.sql => db_world/2026_02_26_02.sql} | 1 + 3 files changed, 3 insertions(+) rename data/sql/updates/{pending_db_world/rev_1772058465656331100.sql => db_world/2026_02_26_00.sql} (98%) rename data/sql/updates/{pending_db_world/rev_1772058806703413600.sql => db_world/2026_02_26_01.sql} (98%) rename data/sql/updates/{pending_db_world/rev_1772059110373151900.sql => db_world/2026_02_26_02.sql} (97%) diff --git a/data/sql/updates/pending_db_world/rev_1772058465656331100.sql b/data/sql/updates/db_world/2026_02_26_00.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1772058465656331100.sql rename to data/sql/updates/db_world/2026_02_26_00.sql index d9d1811a0..00fffedab 100644 --- a/data/sql/updates/pending_db_world/rev_1772058465656331100.sql +++ b/data/sql/updates/db_world/2026_02_26_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_25_16 -> 2026_02_26_00 -- Update gameobject 'Sitting Skeleton 03' with sniffed values -- new spawns DELETE FROM `gameobject` WHERE (`id` IN (185436)) AND (`guid` IN (2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072)); diff --git a/data/sql/updates/pending_db_world/rev_1772058806703413600.sql b/data/sql/updates/db_world/2026_02_26_01.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1772058806703413600.sql rename to data/sql/updates/db_world/2026_02_26_01.sql index 4e76c7076..b6009e103 100644 --- a/data/sql/updates/pending_db_world/rev_1772058806703413600.sql +++ b/data/sql/updates/db_world/2026_02_26_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_26_00 -> 2026_02_26_01 -- Update gameobject 'Huge Sitting Skeleton 02' with sniffed values -- new spawns DELETE FROM `gameobject` WHERE (`id` IN (185457)) AND (`guid` IN (1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153)); diff --git a/data/sql/updates/pending_db_world/rev_1772059110373151900.sql b/data/sql/updates/db_world/2026_02_26_02.sql similarity index 97% rename from data/sql/updates/pending_db_world/rev_1772059110373151900.sql rename to data/sql/updates/db_world/2026_02_26_02.sql index dc04ea390..32dfbd59f 100644 --- a/data/sql/updates/pending_db_world/rev_1772059110373151900.sql +++ b/data/sql/updates/db_world/2026_02_26_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_26_01 -> 2026_02_26_02 -- Update gameobject 'Huge Laying Skeleton 02' with sniffed values -- new spawns DELETE FROM `gameobject` WHERE (`id` IN (185458)) AND (`guid` IN (222, 223, 224, 225)); From 5cf9ae11a58e27352e07c88c6039521938934697 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Thu, 26 Feb 2026 05:49:33 -0300 Subject: [PATCH 310/335] feat(Core/Commands): Add .spellinfo command with subcommands (#24867) Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> --- .../rev_1771989601546823271.sql | 8 + .../scripts/Commands/cs_script_loader.cpp | 2 + src/server/scripts/Commands/cs_spellinfo.cpp | 988 ++++++++++++++++++ 3 files changed, 998 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771989601546823271.sql create mode 100644 src/server/scripts/Commands/cs_spellinfo.cpp diff --git a/data/sql/updates/pending_db_world/rev_1771989601546823271.sql b/data/sql/updates/pending_db_world/rev_1771989601546823271.sql new file mode 100644 index 000000000..16cc99283 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771989601546823271.sql @@ -0,0 +1,8 @@ +-- +DELETE FROM `command` WHERE `name` IN ('spellinfo', 'spellinfo attributes', 'spellinfo effects', 'spellinfo targets', 'spellinfo all'); +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('spellinfo', 2, 'Syntax: .spellinfo $subcommand\n\nType .spellinfo to see a list of subcommands or .help spellinfo $subcommand to see info on subcommands.'), +('spellinfo attributes', 2, 'Syntax: .spellinfo attributes #spellid\n\nDisplays basic info and attribute flags for spell #spellid including SpellAttr0-7, custom attributes, stances, dispel type and mechanic.'), +('spellinfo effects', 2, 'Syntax: .spellinfo effects #spellid\n\nDisplays effect data for spell #spellid including effect type, aura type, base points, multipliers, misc values, mechanic, trigger spell, amplitude and class mask per effect.'), +('spellinfo targets', 2, 'Syntax: .spellinfo targets #spellid\n\nDisplays target data for spell #spellid including target mask, creature type, max affected targets, and per-effect TargetA, TargetB, radius and chain targets.'), +('spellinfo all', 2, 'Syntax: .spellinfo all #spellid\n\nDisplays all available data for spell #spellid including attributes, general properties, effects and targets.'); diff --git a/src/server/scripts/Commands/cs_script_loader.cpp b/src/server/scripts/Commands/cs_script_loader.cpp index 7e667a66c..68bd683f7 100644 --- a/src/server/scripts/Commands/cs_script_loader.cpp +++ b/src/server/scripts/Commands/cs_script_loader.cpp @@ -56,6 +56,7 @@ void AddSC_reset_commandscript(); void AddSC_send_commandscript(); void AddSC_server_commandscript(); void AddSC_spectator_commandscript(); +void AddSC_spellinfo_commandscript(); void AddSC_tele_commandscript(); void AddSC_ticket_commandscript(); void AddSC_titles_commandscript(); @@ -109,6 +110,7 @@ void AddCommandsScripts() AddSC_send_commandscript(); AddSC_server_commandscript(); AddSC_spectator_commandscript(); + AddSC_spellinfo_commandscript(); AddSC_tele_commandscript(); AddSC_ticket_commandscript(); AddSC_titles_commandscript(); diff --git a/src/server/scripts/Commands/cs_spellinfo.cpp b/src/server/scripts/Commands/cs_spellinfo.cpp new file mode 100644 index 000000000..46bf55b2e --- /dev/null +++ b/src/server/scripts/Commands/cs_spellinfo.cpp @@ -0,0 +1,988 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Chat.h" +#include "CommandScript.h" +#include "DBCStructure.h" +#include "Language.h" +#include "SmartEnum.h" +#include "SpellAuraDefines.h" +#include "SpellInfo.h" +#include "SpellMgr.h" + +using namespace Acore::ChatCommands; + +class spellinfo_commandscript : public CommandScript +{ +public: + spellinfo_commandscript() : CommandScript("spellinfo_commandscript") { } + + ChatCommandTable GetCommands() const override + { + static ChatCommandTable spellinfoCommandTable = + { + { "attributes", HandleSpellInfoAttributesCommand, SEC_GAMEMASTER, Console::Yes }, + { "effects", HandleSpellInfoEffectsCommand, SEC_GAMEMASTER, Console::Yes }, + { "targets", HandleSpellInfoTargetsCommand, SEC_GAMEMASTER, Console::Yes }, + { "all", HandleSpellInfoAllCommand, SEC_GAMEMASTER, Console::Yes } + }; + + static ChatCommandTable commandTable = + { + { "spellinfo", spellinfoCommandTable } + }; + + return commandTable; + } + + static char const* GetSpellEffectName(uint32 effect) + { + switch (effect) + { + case SPELL_EFFECT_INSTAKILL: return "SPELL_EFFECT_INSTAKILL"; + case SPELL_EFFECT_SCHOOL_DAMAGE: return "SPELL_EFFECT_SCHOOL_DAMAGE"; + case SPELL_EFFECT_DUMMY: return "SPELL_EFFECT_DUMMY"; + case SPELL_EFFECT_PORTAL_TELEPORT: return "SPELL_EFFECT_PORTAL_TELEPORT"; + case SPELL_EFFECT_TELEPORT_UNITS: return "SPELL_EFFECT_TELEPORT_UNITS"; + case SPELL_EFFECT_APPLY_AURA: return "SPELL_EFFECT_APPLY_AURA"; + case SPELL_EFFECT_ENVIRONMENTAL_DAMAGE: return "SPELL_EFFECT_ENVIRONMENTAL_DAMAGE"; + case SPELL_EFFECT_POWER_DRAIN: return "SPELL_EFFECT_POWER_DRAIN"; + case SPELL_EFFECT_HEALTH_LEECH: return "SPELL_EFFECT_HEALTH_LEECH"; + case SPELL_EFFECT_HEAL: return "SPELL_EFFECT_HEAL"; + case SPELL_EFFECT_BIND: return "SPELL_EFFECT_BIND"; + case SPELL_EFFECT_PORTAL: return "SPELL_EFFECT_PORTAL"; + case SPELL_EFFECT_RITUAL_BASE: return "SPELL_EFFECT_RITUAL_BASE"; + case SPELL_EFFECT_RITUAL_SPECIALIZE: return "SPELL_EFFECT_RITUAL_SPECIALIZE"; + case SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL: return "SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL"; + case SPELL_EFFECT_QUEST_COMPLETE: return "SPELL_EFFECT_QUEST_COMPLETE"; + case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: return "SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL"; + case SPELL_EFFECT_RESURRECT: return "SPELL_EFFECT_RESURRECT"; + case SPELL_EFFECT_ADD_EXTRA_ATTACKS: return "SPELL_EFFECT_ADD_EXTRA_ATTACKS"; + case SPELL_EFFECT_DODGE: return "SPELL_EFFECT_DODGE"; + case SPELL_EFFECT_EVADE: return "SPELL_EFFECT_EVADE"; + case SPELL_EFFECT_PARRY: return "SPELL_EFFECT_PARRY"; + case SPELL_EFFECT_BLOCK: return "SPELL_EFFECT_BLOCK"; + case SPELL_EFFECT_CREATE_ITEM: return "SPELL_EFFECT_CREATE_ITEM"; + case SPELL_EFFECT_WEAPON: return "SPELL_EFFECT_WEAPON"; + case SPELL_EFFECT_DEFENSE: return "SPELL_EFFECT_DEFENSE"; + case SPELL_EFFECT_PERSISTENT_AREA_AURA: return "SPELL_EFFECT_PERSISTENT_AREA_AURA"; + case SPELL_EFFECT_SUMMON: return "SPELL_EFFECT_SUMMON"; + case SPELL_EFFECT_LEAP: return "SPELL_EFFECT_LEAP"; + case SPELL_EFFECT_ENERGIZE: return "SPELL_EFFECT_ENERGIZE"; + case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: return "SPELL_EFFECT_WEAPON_PERCENT_DAMAGE"; + case SPELL_EFFECT_TRIGGER_MISSILE: return "SPELL_EFFECT_TRIGGER_MISSILE"; + case SPELL_EFFECT_OPEN_LOCK: return "SPELL_EFFECT_OPEN_LOCK"; + case SPELL_EFFECT_SUMMON_CHANGE_ITEM: return "SPELL_EFFECT_SUMMON_CHANGE_ITEM"; + case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: return "SPELL_EFFECT_APPLY_AREA_AURA_PARTY"; + case SPELL_EFFECT_LEARN_SPELL: return "SPELL_EFFECT_LEARN_SPELL"; + case SPELL_EFFECT_SPELL_DEFENSE: return "SPELL_EFFECT_SPELL_DEFENSE"; + case SPELL_EFFECT_DISPEL: return "SPELL_EFFECT_DISPEL"; + case SPELL_EFFECT_LANGUAGE: return "SPELL_EFFECT_LANGUAGE"; + case SPELL_EFFECT_DUAL_WIELD: return "SPELL_EFFECT_DUAL_WIELD"; + case SPELL_EFFECT_JUMP: return "SPELL_EFFECT_JUMP"; + case SPELL_EFFECT_JUMP_DEST: return "SPELL_EFFECT_JUMP_DEST"; + case SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER: return "SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER"; + case SPELL_EFFECT_SKILL_STEP: return "SPELL_EFFECT_SKILL_STEP"; + case SPELL_EFFECT_ADD_HONOR: return "SPELL_EFFECT_ADD_HONOR"; + case SPELL_EFFECT_SPAWN: return "SPELL_EFFECT_SPAWN"; + case SPELL_EFFECT_TRADE_SKILL: return "SPELL_EFFECT_TRADE_SKILL"; + case SPELL_EFFECT_STEALTH: return "SPELL_EFFECT_STEALTH"; + case SPELL_EFFECT_DETECT: return "SPELL_EFFECT_DETECT"; + case SPELL_EFFECT_TRANS_DOOR: return "SPELL_EFFECT_TRANS_DOOR"; + case SPELL_EFFECT_FORCE_CRITICAL_HIT: return "SPELL_EFFECT_FORCE_CRITICAL_HIT"; + case SPELL_EFFECT_GUARANTEE_HIT: return "SPELL_EFFECT_GUARANTEE_HIT"; + case SPELL_EFFECT_ENCHANT_ITEM: return "SPELL_EFFECT_ENCHANT_ITEM"; + case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY: return "SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY"; + case SPELL_EFFECT_TAMECREATURE: return "SPELL_EFFECT_TAMECREATURE"; + case SPELL_EFFECT_SUMMON_PET: return "SPELL_EFFECT_SUMMON_PET"; + case SPELL_EFFECT_LEARN_PET_SPELL: return "SPELL_EFFECT_LEARN_PET_SPELL"; + case SPELL_EFFECT_WEAPON_DAMAGE: return "SPELL_EFFECT_WEAPON_DAMAGE"; + case SPELL_EFFECT_CREATE_RANDOM_ITEM: return "SPELL_EFFECT_CREATE_RANDOM_ITEM"; + case SPELL_EFFECT_PROFICIENCY: return "SPELL_EFFECT_PROFICIENCY"; + case SPELL_EFFECT_SEND_EVENT: return "SPELL_EFFECT_SEND_EVENT"; + case SPELL_EFFECT_POWER_BURN: return "SPELL_EFFECT_POWER_BURN"; + case SPELL_EFFECT_THREAT: return "SPELL_EFFECT_THREAT"; + case SPELL_EFFECT_TRIGGER_SPELL: return "SPELL_EFFECT_TRIGGER_SPELL"; + case SPELL_EFFECT_APPLY_AREA_AURA_RAID: return "SPELL_EFFECT_APPLY_AREA_AURA_RAID"; + case SPELL_EFFECT_CREATE_MANA_GEM: return "SPELL_EFFECT_CREATE_MANA_GEM"; + case SPELL_EFFECT_HEAL_MAX_HEALTH: return "SPELL_EFFECT_HEAL_MAX_HEALTH"; + case SPELL_EFFECT_INTERRUPT_CAST: return "SPELL_EFFECT_INTERRUPT_CAST"; + case SPELL_EFFECT_DISTRACT: return "SPELL_EFFECT_DISTRACT"; + case SPELL_EFFECT_PULL: return "SPELL_EFFECT_PULL"; + case SPELL_EFFECT_PICKPOCKET: return "SPELL_EFFECT_PICKPOCKET"; + case SPELL_EFFECT_ADD_FARSIGHT: return "SPELL_EFFECT_ADD_FARSIGHT"; + case SPELL_EFFECT_UNTRAIN_TALENTS: return "SPELL_EFFECT_UNTRAIN_TALENTS"; + case SPELL_EFFECT_APPLY_GLYPH: return "SPELL_EFFECT_APPLY_GLYPH"; + case SPELL_EFFECT_HEAL_MECHANICAL: return "SPELL_EFFECT_HEAL_MECHANICAL"; + case SPELL_EFFECT_SUMMON_OBJECT_WILD: return "SPELL_EFFECT_SUMMON_OBJECT_WILD"; + case SPELL_EFFECT_SCRIPT_EFFECT: return "SPELL_EFFECT_SCRIPT_EFFECT"; + case SPELL_EFFECT_ATTACK: return "SPELL_EFFECT_ATTACK"; + case SPELL_EFFECT_SANCTUARY: return "SPELL_EFFECT_SANCTUARY"; + case SPELL_EFFECT_ADD_COMBO_POINTS: return "SPELL_EFFECT_ADD_COMBO_POINTS"; + case SPELL_EFFECT_CREATE_HOUSE: return "SPELL_EFFECT_CREATE_HOUSE"; + case SPELL_EFFECT_BIND_SIGHT: return "SPELL_EFFECT_BIND_SIGHT"; + case SPELL_EFFECT_DUEL: return "SPELL_EFFECT_DUEL"; + case SPELL_EFFECT_STUCK: return "SPELL_EFFECT_STUCK"; + case SPELL_EFFECT_SUMMON_PLAYER: return "SPELL_EFFECT_SUMMON_PLAYER"; + case SPELL_EFFECT_ACTIVATE_OBJECT: return "SPELL_EFFECT_ACTIVATE_OBJECT"; + case SPELL_EFFECT_GAMEOBJECT_DAMAGE: return "SPELL_EFFECT_GAMEOBJECT_DAMAGE"; + case SPELL_EFFECT_GAMEOBJECT_REPAIR: return "SPELL_EFFECT_GAMEOBJECT_REPAIR"; + case SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE: return "SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE"; + case SPELL_EFFECT_KILL_CREDIT: return "SPELL_EFFECT_KILL_CREDIT"; + case SPELL_EFFECT_THREAT_ALL: return "SPELL_EFFECT_THREAT_ALL"; + case SPELL_EFFECT_ENCHANT_HELD_ITEM: return "SPELL_EFFECT_ENCHANT_HELD_ITEM"; + case SPELL_EFFECT_FORCE_DESELECT: return "SPELL_EFFECT_FORCE_DESELECT"; + case SPELL_EFFECT_SELF_RESURRECT: return "SPELL_EFFECT_SELF_RESURRECT"; + case SPELL_EFFECT_SKINNING: return "SPELL_EFFECT_SKINNING"; + case SPELL_EFFECT_CHARGE: return "SPELL_EFFECT_CHARGE"; + case SPELL_EFFECT_CAST_BUTTON: return "SPELL_EFFECT_CAST_BUTTON"; + case SPELL_EFFECT_KNOCK_BACK: return "SPELL_EFFECT_KNOCK_BACK"; + case SPELL_EFFECT_DISENCHANT: return "SPELL_EFFECT_DISENCHANT"; + case SPELL_EFFECT_INEBRIATE: return "SPELL_EFFECT_INEBRIATE"; + case SPELL_EFFECT_FEED_PET: return "SPELL_EFFECT_FEED_PET"; + case SPELL_EFFECT_DISMISS_PET: return "SPELL_EFFECT_DISMISS_PET"; + case SPELL_EFFECT_REPUTATION: return "SPELL_EFFECT_REPUTATION"; + case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: return "SPELL_EFFECT_SUMMON_OBJECT_SLOT1"; + case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: return "SPELL_EFFECT_SUMMON_OBJECT_SLOT2"; + case SPELL_EFFECT_SUMMON_OBJECT_SLOT3: return "SPELL_EFFECT_SUMMON_OBJECT_SLOT3"; + case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: return "SPELL_EFFECT_SUMMON_OBJECT_SLOT4"; + case SPELL_EFFECT_DISPEL_MECHANIC: return "SPELL_EFFECT_DISPEL_MECHANIC"; + case SPELL_EFFECT_RESURRECT_PET: return "SPELL_EFFECT_RESURRECT_PET"; + case SPELL_EFFECT_DESTROY_ALL_TOTEMS: return "SPELL_EFFECT_DESTROY_ALL_TOTEMS"; + case SPELL_EFFECT_DURABILITY_DAMAGE: return "SPELL_EFFECT_DURABILITY_DAMAGE"; + case SPELL_EFFECT_112: return "SPELL_EFFECT_112"; + case SPELL_EFFECT_RESURRECT_NEW: return "SPELL_EFFECT_RESURRECT_NEW"; + case SPELL_EFFECT_ATTACK_ME: return "SPELL_EFFECT_ATTACK_ME"; + case SPELL_EFFECT_DURABILITY_DAMAGE_PCT: return "SPELL_EFFECT_DURABILITY_DAMAGE_PCT"; + case SPELL_EFFECT_SKIN_PLAYER_CORPSE: return "SPELL_EFFECT_SKIN_PLAYER_CORPSE"; + case SPELL_EFFECT_SPIRIT_HEAL: return "SPELL_EFFECT_SPIRIT_HEAL"; + case SPELL_EFFECT_SKILL: return "SPELL_EFFECT_SKILL"; + case SPELL_EFFECT_APPLY_AREA_AURA_PET: return "SPELL_EFFECT_APPLY_AREA_AURA_PET"; + case SPELL_EFFECT_TELEPORT_GRAVEYARD: return "SPELL_EFFECT_TELEPORT_GRAVEYARD"; + case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: return "SPELL_EFFECT_NORMALIZED_WEAPON_DMG"; + case SPELL_EFFECT_122: return "SPELL_EFFECT_122"; + case SPELL_EFFECT_SEND_TAXI: return "SPELL_EFFECT_SEND_TAXI"; + case SPELL_EFFECT_PULL_TOWARDS: return "SPELL_EFFECT_PULL_TOWARDS"; + case SPELL_EFFECT_MODIFY_THREAT_PERCENT: return "SPELL_EFFECT_MODIFY_THREAT_PERCENT"; + case SPELL_EFFECT_STEAL_BENEFICIAL_BUFF: return "SPELL_EFFECT_STEAL_BENEFICIAL_BUFF"; + case SPELL_EFFECT_PROSPECTING: return "SPELL_EFFECT_PROSPECTING"; + case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: return "SPELL_EFFECT_APPLY_AREA_AURA_FRIEND"; + case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: return "SPELL_EFFECT_APPLY_AREA_AURA_ENEMY"; + case SPELL_EFFECT_REDIRECT_THREAT: return "SPELL_EFFECT_REDIRECT_THREAT"; + case SPELL_EFFECT_PLAY_SOUND: return "SPELL_EFFECT_PLAY_SOUND"; + case SPELL_EFFECT_PLAY_MUSIC: return "SPELL_EFFECT_PLAY_MUSIC"; + case SPELL_EFFECT_UNLEARN_SPECIALIZATION: return "SPELL_EFFECT_UNLEARN_SPECIALIZATION"; + case SPELL_EFFECT_KILL_CREDIT2: return "SPELL_EFFECT_KILL_CREDIT2"; + case SPELL_EFFECT_CALL_PET: return "SPELL_EFFECT_CALL_PET"; + case SPELL_EFFECT_HEAL_PCT: return "SPELL_EFFECT_HEAL_PCT"; + case SPELL_EFFECT_ENERGIZE_PCT: return "SPELL_EFFECT_ENERGIZE_PCT"; + case SPELL_EFFECT_LEAP_BACK: return "SPELL_EFFECT_LEAP_BACK"; + case SPELL_EFFECT_CLEAR_QUEST: return "SPELL_EFFECT_CLEAR_QUEST"; + case SPELL_EFFECT_FORCE_CAST: return "SPELL_EFFECT_FORCE_CAST"; + case SPELL_EFFECT_FORCE_CAST_WITH_VALUE: return "SPELL_EFFECT_FORCE_CAST_WITH_VALUE"; + case SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE: return "SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE"; + case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: return "SPELL_EFFECT_APPLY_AREA_AURA_OWNER"; + case SPELL_EFFECT_KNOCK_BACK_DEST: return "SPELL_EFFECT_KNOCK_BACK_DEST"; + case SPELL_EFFECT_PULL_TOWARDS_DEST: return "SPELL_EFFECT_PULL_TOWARDS_DEST"; + case SPELL_EFFECT_ACTIVATE_RUNE: return "SPELL_EFFECT_ACTIVATE_RUNE"; + case SPELL_EFFECT_QUEST_FAIL: return "SPELL_EFFECT_QUEST_FAIL"; + case SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE: return "SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE"; + case SPELL_EFFECT_CHARGE_DEST: return "SPELL_EFFECT_CHARGE_DEST"; + case SPELL_EFFECT_QUEST_START: return "SPELL_EFFECT_QUEST_START"; + case SPELL_EFFECT_TRIGGER_SPELL_2: return "SPELL_EFFECT_TRIGGER_SPELL_2"; + case SPELL_EFFECT_SUMMON_RAF_FRIEND: return "SPELL_EFFECT_SUMMON_RAF_FRIEND"; + case SPELL_EFFECT_CREATE_TAMED_PET: return "SPELL_EFFECT_CREATE_TAMED_PET"; + case SPELL_EFFECT_DISCOVER_TAXI: return "SPELL_EFFECT_DISCOVER_TAXI"; + case SPELL_EFFECT_TITAN_GRIP: return "SPELL_EFFECT_TITAN_GRIP"; + case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC: return "SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC"; + case SPELL_EFFECT_CREATE_ITEM_2: return "SPELL_EFFECT_CREATE_ITEM_2"; + case SPELL_EFFECT_MILLING: return "SPELL_EFFECT_MILLING"; + case SPELL_EFFECT_ALLOW_RENAME_PET: return "SPELL_EFFECT_ALLOW_RENAME_PET"; + case SPELL_EFFECT_FORCE_CAST_2: return "SPELL_EFFECT_FORCE_CAST_2"; + case SPELL_EFFECT_TALENT_SPEC_COUNT: return "SPELL_EFFECT_TALENT_SPEC_COUNT"; + case SPELL_EFFECT_TALENT_SPEC_SELECT: return "SPELL_EFFECT_TALENT_SPEC_SELECT"; + case SPELL_EFFECT_163: return "SPELL_EFFECT_163"; + case SPELL_EFFECT_REMOVE_AURA: return "SPELL_EFFECT_REMOVE_AURA"; + default: return "UNKNOWN_EFFECT"; + } + } + + static char const* GetAuraTypeName(uint32 aura) + { + switch (aura) + { + case SPELL_AURA_NONE: return "SPELL_AURA_NONE"; + case SPELL_AURA_BIND_SIGHT: return "SPELL_AURA_BIND_SIGHT"; + case SPELL_AURA_MOD_POSSESS: return "SPELL_AURA_MOD_POSSESS"; + case SPELL_AURA_PERIODIC_DAMAGE: return "SPELL_AURA_PERIODIC_DAMAGE"; + case SPELL_AURA_DUMMY: return "SPELL_AURA_DUMMY"; + case SPELL_AURA_MOD_CONFUSE: return "SPELL_AURA_MOD_CONFUSE"; + case SPELL_AURA_MOD_CHARM: return "SPELL_AURA_MOD_CHARM"; + case SPELL_AURA_MOD_FEAR: return "SPELL_AURA_MOD_FEAR"; + case SPELL_AURA_PERIODIC_HEAL: return "SPELL_AURA_PERIODIC_HEAL"; + case SPELL_AURA_MOD_ATTACKSPEED: return "SPELL_AURA_MOD_ATTACKSPEED"; + case SPELL_AURA_MOD_THREAT: return "SPELL_AURA_MOD_THREAT"; + case SPELL_AURA_MOD_TAUNT: return "SPELL_AURA_MOD_TAUNT"; + case SPELL_AURA_MOD_STUN: return "SPELL_AURA_MOD_STUN"; + case SPELL_AURA_MOD_DAMAGE_DONE: return "SPELL_AURA_MOD_DAMAGE_DONE"; + case SPELL_AURA_MOD_DAMAGE_TAKEN: return "SPELL_AURA_MOD_DAMAGE_TAKEN"; + case SPELL_AURA_DAMAGE_SHIELD: return "SPELL_AURA_DAMAGE_SHIELD"; + case SPELL_AURA_MOD_STEALTH: return "SPELL_AURA_MOD_STEALTH"; + case SPELL_AURA_MOD_STEALTH_DETECT: return "SPELL_AURA_MOD_STEALTH_DETECT"; + case SPELL_AURA_MOD_INVISIBILITY: return "SPELL_AURA_MOD_INVISIBILITY"; + case SPELL_AURA_MOD_INVISIBILITY_DETECT: return "SPELL_AURA_MOD_INVISIBILITY_DETECT"; + case SPELL_AURA_OBS_MOD_HEALTH: return "SPELL_AURA_OBS_MOD_HEALTH"; + case SPELL_AURA_OBS_MOD_POWER: return "SPELL_AURA_OBS_MOD_POWER"; + case SPELL_AURA_MOD_RESISTANCE: return "SPELL_AURA_MOD_RESISTANCE"; + case SPELL_AURA_PERIODIC_TRIGGER_SPELL: return "SPELL_AURA_PERIODIC_TRIGGER_SPELL"; + case SPELL_AURA_PERIODIC_ENERGIZE: return "SPELL_AURA_PERIODIC_ENERGIZE"; + case SPELL_AURA_MOD_PACIFY: return "SPELL_AURA_MOD_PACIFY"; + case SPELL_AURA_MOD_ROOT: return "SPELL_AURA_MOD_ROOT"; + case SPELL_AURA_MOD_SILENCE: return "SPELL_AURA_MOD_SILENCE"; + case SPELL_AURA_REFLECT_SPELLS: return "SPELL_AURA_REFLECT_SPELLS"; + case SPELL_AURA_MOD_STAT: return "SPELL_AURA_MOD_STAT"; + case SPELL_AURA_MOD_SKILL: return "SPELL_AURA_MOD_SKILL"; + case SPELL_AURA_MOD_INCREASE_SPEED: return "SPELL_AURA_MOD_INCREASE_SPEED"; + case SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED: return "SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED"; + case SPELL_AURA_MOD_DECREASE_SPEED: return "SPELL_AURA_MOD_DECREASE_SPEED"; + case SPELL_AURA_MOD_INCREASE_HEALTH: return "SPELL_AURA_MOD_INCREASE_HEALTH"; + case SPELL_AURA_MOD_INCREASE_ENERGY: return "SPELL_AURA_MOD_INCREASE_ENERGY"; + case SPELL_AURA_MOD_SHAPESHIFT: return "SPELL_AURA_MOD_SHAPESHIFT"; + case SPELL_AURA_EFFECT_IMMUNITY: return "SPELL_AURA_EFFECT_IMMUNITY"; + case SPELL_AURA_STATE_IMMUNITY: return "SPELL_AURA_STATE_IMMUNITY"; + case SPELL_AURA_SCHOOL_IMMUNITY: return "SPELL_AURA_SCHOOL_IMMUNITY"; + case SPELL_AURA_DAMAGE_IMMUNITY: return "SPELL_AURA_DAMAGE_IMMUNITY"; + case SPELL_AURA_DISPEL_IMMUNITY: return "SPELL_AURA_DISPEL_IMMUNITY"; + case SPELL_AURA_PROC_TRIGGER_SPELL: return "SPELL_AURA_PROC_TRIGGER_SPELL"; + case SPELL_AURA_PROC_TRIGGER_DAMAGE: return "SPELL_AURA_PROC_TRIGGER_DAMAGE"; + case SPELL_AURA_TRACK_CREATURES: return "SPELL_AURA_TRACK_CREATURES"; + case SPELL_AURA_TRACK_RESOURCES: return "SPELL_AURA_TRACK_RESOURCES"; + case SPELL_AURA_46: return "SPELL_AURA_46"; + case SPELL_AURA_MOD_PARRY_PERCENT: return "SPELL_AURA_MOD_PARRY_PERCENT"; + case SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT: return "SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT"; + case SPELL_AURA_MOD_DODGE_PERCENT: return "SPELL_AURA_MOD_DODGE_PERCENT"; + case SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT: return "SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT"; + case SPELL_AURA_MOD_BLOCK_PERCENT: return "SPELL_AURA_MOD_BLOCK_PERCENT"; + case SPELL_AURA_MOD_WEAPON_CRIT_PERCENT: return "SPELL_AURA_MOD_WEAPON_CRIT_PERCENT"; + case SPELL_AURA_PERIODIC_LEECH: return "SPELL_AURA_PERIODIC_LEECH"; + case SPELL_AURA_MOD_HIT_CHANCE: return "SPELL_AURA_MOD_HIT_CHANCE"; + case SPELL_AURA_MOD_SPELL_HIT_CHANCE: return "SPELL_AURA_MOD_SPELL_HIT_CHANCE"; + case SPELL_AURA_TRANSFORM: return "SPELL_AURA_TRANSFORM"; + case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: return "SPELL_AURA_MOD_SPELL_CRIT_CHANCE"; + case SPELL_AURA_MOD_INCREASE_SWIM_SPEED: return "SPELL_AURA_MOD_INCREASE_SWIM_SPEED"; + case SPELL_AURA_MOD_DAMAGE_DONE_CREATURE: return "SPELL_AURA_MOD_DAMAGE_DONE_CREATURE"; + case SPELL_AURA_MOD_PACIFY_SILENCE: return "SPELL_AURA_MOD_PACIFY_SILENCE"; + case SPELL_AURA_MOD_SCALE: return "SPELL_AURA_MOD_SCALE"; + case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: return "SPELL_AURA_PERIODIC_HEALTH_FUNNEL"; + case SPELL_AURA_63: return "SPELL_AURA_63"; + case SPELL_AURA_PERIODIC_MANA_LEECH: return "SPELL_AURA_PERIODIC_MANA_LEECH"; + case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK: return "SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK"; + case SPELL_AURA_FEIGN_DEATH: return "SPELL_AURA_FEIGN_DEATH"; + case SPELL_AURA_MOD_DISARM: return "SPELL_AURA_MOD_DISARM"; + case SPELL_AURA_MOD_STALKED: return "SPELL_AURA_MOD_STALKED"; + case SPELL_AURA_SCHOOL_ABSORB: return "SPELL_AURA_SCHOOL_ABSORB"; + case SPELL_AURA_EXTRA_ATTACKS: return "SPELL_AURA_EXTRA_ATTACKS"; + case SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL: return "SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL"; + case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT: return "SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT"; + case SPELL_AURA_MOD_POWER_COST_SCHOOL: return "SPELL_AURA_MOD_POWER_COST_SCHOOL"; + case SPELL_AURA_REFLECT_SPELLS_SCHOOL: return "SPELL_AURA_REFLECT_SPELLS_SCHOOL"; + case SPELL_AURA_MOD_LANGUAGE: return "SPELL_AURA_MOD_LANGUAGE"; + case SPELL_AURA_FAR_SIGHT: return "SPELL_AURA_FAR_SIGHT"; + case SPELL_AURA_MECHANIC_IMMUNITY: return "SPELL_AURA_MECHANIC_IMMUNITY"; + case SPELL_AURA_MOUNTED: return "SPELL_AURA_MOUNTED"; + case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: return "SPELL_AURA_MOD_DAMAGE_PERCENT_DONE"; + case SPELL_AURA_MOD_PERCENT_STAT: return "SPELL_AURA_MOD_PERCENT_STAT"; + case SPELL_AURA_SPLIT_DAMAGE_PCT: return "SPELL_AURA_SPLIT_DAMAGE_PCT"; + case SPELL_AURA_WATER_BREATHING: return "SPELL_AURA_WATER_BREATHING"; + case SPELL_AURA_MOD_BASE_RESISTANCE: return "SPELL_AURA_MOD_BASE_RESISTANCE"; + case SPELL_AURA_MOD_REGEN: return "SPELL_AURA_MOD_REGEN"; + case SPELL_AURA_MOD_POWER_REGEN: return "SPELL_AURA_MOD_POWER_REGEN"; + case SPELL_AURA_CHANNEL_DEATH_ITEM: return "SPELL_AURA_CHANNEL_DEATH_ITEM"; + case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: return "SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN"; + case SPELL_AURA_MOD_HEALTH_REGEN_PERCENT: return "SPELL_AURA_MOD_HEALTH_REGEN_PERCENT"; + case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: return "SPELL_AURA_PERIODIC_DAMAGE_PERCENT"; + case SPELL_AURA_90: return "SPELL_AURA_90"; + case SPELL_AURA_MOD_DETECT_RANGE: return "SPELL_AURA_MOD_DETECT_RANGE"; + case SPELL_AURA_PREVENTS_FLEEING: return "SPELL_AURA_PREVENTS_FLEEING"; + case SPELL_AURA_MOD_UNATTACKABLE: return "SPELL_AURA_MOD_UNATTACKABLE"; + case SPELL_AURA_INTERRUPT_REGEN: return "SPELL_AURA_INTERRUPT_REGEN"; + case SPELL_AURA_GHOST: return "SPELL_AURA_GHOST"; + case SPELL_AURA_SPELL_MAGNET: return "SPELL_AURA_SPELL_MAGNET"; + case SPELL_AURA_MANA_SHIELD: return "SPELL_AURA_MANA_SHIELD"; + case SPELL_AURA_MOD_SKILL_TALENT: return "SPELL_AURA_MOD_SKILL_TALENT"; + case SPELL_AURA_MOD_ATTACK_POWER: return "SPELL_AURA_MOD_ATTACK_POWER"; + case SPELL_AURA_AURAS_VISIBLE: return "SPELL_AURA_AURAS_VISIBLE"; + case SPELL_AURA_MOD_RESISTANCE_PCT: return "SPELL_AURA_MOD_RESISTANCE_PCT"; + case SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS: return "SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS"; + case SPELL_AURA_MOD_TOTAL_THREAT: return "SPELL_AURA_MOD_TOTAL_THREAT"; + case SPELL_AURA_WATER_WALK: return "SPELL_AURA_WATER_WALK"; + case SPELL_AURA_FEATHER_FALL: return "SPELL_AURA_FEATHER_FALL"; + case SPELL_AURA_HOVER: return "SPELL_AURA_HOVER"; + case SPELL_AURA_ADD_FLAT_MODIFIER: return "SPELL_AURA_ADD_FLAT_MODIFIER"; + case SPELL_AURA_ADD_PCT_MODIFIER: return "SPELL_AURA_ADD_PCT_MODIFIER"; + case SPELL_AURA_ADD_TARGET_TRIGGER: return "SPELL_AURA_ADD_TARGET_TRIGGER"; + case SPELL_AURA_MOD_POWER_REGEN_PERCENT: return "SPELL_AURA_MOD_POWER_REGEN_PERCENT"; + case SPELL_AURA_ADD_CASTER_HIT_TRIGGER: return "SPELL_AURA_ADD_CASTER_HIT_TRIGGER"; + case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: return "SPELL_AURA_OVERRIDE_CLASS_SCRIPTS"; + case SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN: return "SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN"; + case SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT: return "SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT"; + case SPELL_AURA_MOD_HEALING: return "SPELL_AURA_MOD_HEALING"; + case SPELL_AURA_MOD_REGEN_DURING_COMBAT: return "SPELL_AURA_MOD_REGEN_DURING_COMBAT"; + case SPELL_AURA_MOD_MECHANIC_RESISTANCE: return "SPELL_AURA_MOD_MECHANIC_RESISTANCE"; + case SPELL_AURA_MOD_HEALING_PCT: return "SPELL_AURA_MOD_HEALING_PCT"; + case SPELL_AURA_119: return "SPELL_AURA_119"; + case SPELL_AURA_UNTRACKABLE: return "SPELL_AURA_UNTRACKABLE"; + case SPELL_AURA_EMPATHY: return "SPELL_AURA_EMPATHY"; + case SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT: return "SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT"; + case SPELL_AURA_MOD_TARGET_RESISTANCE: return "SPELL_AURA_MOD_TARGET_RESISTANCE"; + case SPELL_AURA_MOD_RANGED_ATTACK_POWER: return "SPELL_AURA_MOD_RANGED_ATTACK_POWER"; + case SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN: return "SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN"; + case SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT: return "SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT"; + case SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS: return "SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS"; + case SPELL_AURA_MOD_POSSESS_PET: return "SPELL_AURA_MOD_POSSESS_PET"; + case SPELL_AURA_MOD_SPEED_ALWAYS: return "SPELL_AURA_MOD_SPEED_ALWAYS"; + case SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS: return "SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS"; + case SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS: return "SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS"; + case SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT: return "SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT"; + case SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT: return "SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT"; + case SPELL_AURA_MOD_MANA_REGEN_INTERRUPT: return "SPELL_AURA_MOD_MANA_REGEN_INTERRUPT"; + case SPELL_AURA_MOD_HEALING_DONE: return "SPELL_AURA_MOD_HEALING_DONE"; + case SPELL_AURA_MOD_HEALING_DONE_PERCENT: return "SPELL_AURA_MOD_HEALING_DONE_PERCENT"; + case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE: return "SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE"; + case SPELL_AURA_MOD_MELEE_HASTE: return "SPELL_AURA_MOD_MELEE_HASTE"; + case SPELL_AURA_FORCE_REACTION: return "SPELL_AURA_FORCE_REACTION"; + case SPELL_AURA_MOD_RANGED_HASTE: return "SPELL_AURA_MOD_RANGED_HASTE"; + case SPELL_AURA_MOD_RANGED_AMMO_HASTE: return "SPELL_AURA_MOD_RANGED_AMMO_HASTE"; + case SPELL_AURA_MOD_BASE_RESISTANCE_PCT: return "SPELL_AURA_MOD_BASE_RESISTANCE_PCT"; + case SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE: return "SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE"; + case SPELL_AURA_SAFE_FALL: return "SPELL_AURA_SAFE_FALL"; + case SPELL_AURA_MOD_PET_TALENT_POINTS: return "SPELL_AURA_MOD_PET_TALENT_POINTS"; + case SPELL_AURA_ALLOW_TAME_PET_TYPE: return "SPELL_AURA_ALLOW_TAME_PET_TYPE"; + case SPELL_AURA_MECHANIC_IMMUNITY_MASK: return "SPELL_AURA_MECHANIC_IMMUNITY_MASK"; + case SPELL_AURA_RETAIN_COMBO_POINTS: return "SPELL_AURA_RETAIN_COMBO_POINTS"; + case SPELL_AURA_REDUCE_PUSHBACK: return "SPELL_AURA_REDUCE_PUSHBACK"; + case SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT: return "SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT"; + case SPELL_AURA_TRACK_STEALTHED: return "SPELL_AURA_TRACK_STEALTHED"; + case SPELL_AURA_MOD_DETECTED_RANGE: return "SPELL_AURA_MOD_DETECTED_RANGE"; + case SPELL_AURA_SPLIT_DAMAGE_FLAT: return "SPELL_AURA_SPLIT_DAMAGE_FLAT"; + case SPELL_AURA_MOD_STEALTH_LEVEL: return "SPELL_AURA_MOD_STEALTH_LEVEL"; + case SPELL_AURA_MOD_WATER_BREATHING: return "SPELL_AURA_MOD_WATER_BREATHING"; + case SPELL_AURA_MOD_REPUTATION_GAIN: return "SPELL_AURA_MOD_REPUTATION_GAIN"; + case SPELL_AURA_PET_DAMAGE_MULTI: return "SPELL_AURA_PET_DAMAGE_MULTI"; + case SPELL_AURA_MOD_SHIELD_BLOCKVALUE: return "SPELL_AURA_MOD_SHIELD_BLOCKVALUE"; + case SPELL_AURA_NO_PVP_CREDIT: return "SPELL_AURA_NO_PVP_CREDIT"; + case SPELL_AURA_MOD_AOE_AVOIDANCE: return "SPELL_AURA_MOD_AOE_AVOIDANCE"; + case SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT: return "SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT"; + case SPELL_AURA_POWER_BURN: return "SPELL_AURA_POWER_BURN"; + case SPELL_AURA_MOD_CRIT_DAMAGE_BONUS: return "SPELL_AURA_MOD_CRIT_DAMAGE_BONUS"; + case SPELL_AURA_164: return "SPELL_AURA_164"; + case SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS: return "SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS"; + case SPELL_AURA_MOD_ATTACK_POWER_PCT: return "SPELL_AURA_MOD_ATTACK_POWER_PCT"; + case SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT: return "SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT"; + case SPELL_AURA_MOD_DAMAGE_DONE_VERSUS: return "SPELL_AURA_MOD_DAMAGE_DONE_VERSUS"; + case SPELL_AURA_MOD_CRIT_PERCENT_VERSUS: return "SPELL_AURA_MOD_CRIT_PERCENT_VERSUS"; + case SPELL_AURA_DETECT_AMORE: return "SPELL_AURA_DETECT_AMORE"; + case SPELL_AURA_MOD_SPEED_NOT_STACK: return "SPELL_AURA_MOD_SPEED_NOT_STACK"; + case SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK: return "SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK"; + case SPELL_AURA_173: return "SPELL_AURA_173"; + case SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT: return "SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT"; + case SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT: return "SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT"; + case SPELL_AURA_SPIRIT_OF_REDEMPTION: return "SPELL_AURA_SPIRIT_OF_REDEMPTION"; + case SPELL_AURA_AOE_CHARM: return "SPELL_AURA_AOE_CHARM"; + case SPELL_AURA_MOD_DEBUFF_RESISTANCE: return "SPELL_AURA_MOD_DEBUFF_RESISTANCE"; + case SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE: return "SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE"; + case SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS: return "SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS"; + case SPELL_AURA_181: return "SPELL_AURA_181"; + case SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT: return "SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT"; + case SPELL_AURA_MOD_CRITICAL_THREAT: return "SPELL_AURA_MOD_CRITICAL_THREAT"; + case SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE: return "SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE"; + case SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE: return "SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE"; + case SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE: return "SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE"; + case SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE: return "SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE"; + case SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE: return "SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE"; + case SPELL_AURA_MOD_RATING: return "SPELL_AURA_MOD_RATING"; + case SPELL_AURA_MOD_FACTION_REPUTATION_GAIN: return "SPELL_AURA_MOD_FACTION_REPUTATION_GAIN"; + case SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED: return "SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED"; + case SPELL_AURA_MOD_MELEE_RANGED_HASTE: return "SPELL_AURA_MOD_MELEE_RANGED_HASTE"; + case SPELL_AURA_MELEE_SLOW: return "SPELL_AURA_MELEE_SLOW"; + case SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL: return "SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL"; + case SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL: return "SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL"; + case SPELL_AURA_MOD_COOLDOWN: return "SPELL_AURA_MOD_COOLDOWN"; + case SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE: return "SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE"; + case SPELL_AURA_198: return "SPELL_AURA_198"; + case SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT: return "SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT"; + case SPELL_AURA_MOD_XP_PCT: return "SPELL_AURA_MOD_XP_PCT"; + case SPELL_AURA_FLY: return "SPELL_AURA_FLY"; + case SPELL_AURA_IGNORE_COMBAT_RESULT: return "SPELL_AURA_IGNORE_COMBAT_RESULT"; + case SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE: return "SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE"; + case SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE: return "SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE"; + case SPELL_AURA_MOD_SCHOOL_CRIT_DMG_TAKEN: return "SPELL_AURA_MOD_SCHOOL_CRIT_DMG_TAKEN"; + case SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED: return "SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED"; + case SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED: return "SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED"; + case SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS: return "SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS"; + case SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS: return "SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS"; + case SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACKING: return "SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACKING"; + case SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED_NOT_STACKING: return "SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED_NOT_STACKING"; + case SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT: return "SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT"; + case SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT: return "SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT"; + case SPELL_AURA_214: return "SPELL_AURA_214"; + case SPELL_AURA_ARENA_PREPARATION: return "SPELL_AURA_ARENA_PREPARATION"; + case SPELL_AURA_HASTE_SPELLS: return "SPELL_AURA_HASTE_SPELLS"; + case SPELL_AURA_MOD_MELEE_HASTE_2: return "SPELL_AURA_MOD_MELEE_HASTE_2"; + case SPELL_AURA_HASTE_RANGED: return "SPELL_AURA_HASTE_RANGED"; + case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT: return "SPELL_AURA_MOD_MANA_REGEN_FROM_STAT"; + case SPELL_AURA_MOD_RATING_FROM_STAT: return "SPELL_AURA_MOD_RATING_FROM_STAT"; + case SPELL_AURA_IGNORED: return "SPELL_AURA_IGNORED"; + case SPELL_AURA_222: return "SPELL_AURA_222"; + case SPELL_AURA_RAID_PROC_FROM_CHARGE: return "SPELL_AURA_RAID_PROC_FROM_CHARGE"; + case SPELL_AURA_224: return "SPELL_AURA_224"; + case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE: return "SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE"; + case SPELL_AURA_PERIODIC_DUMMY: return "SPELL_AURA_PERIODIC_DUMMY"; + case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE: return "SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE"; + case SPELL_AURA_DETECT_STEALTH: return "SPELL_AURA_DETECT_STEALTH"; + case SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE: return "SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE"; + case SPELL_AURA_230: return "SPELL_AURA_230"; + case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE: return "SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE"; + case SPELL_AURA_MECHANIC_DURATION_MOD: return "SPELL_AURA_MECHANIC_DURATION_MOD"; + case SPELL_AURA_CHANGE_MODEL_FOR_ALL_HUMANOIDS: return "SPELL_AURA_CHANGE_MODEL_FOR_ALL_HUMANOIDS"; + case SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK: return "SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK"; + case SPELL_AURA_MOD_DISPEL_RESIST: return "SPELL_AURA_MOD_DISPEL_RESIST"; + case SPELL_AURA_CONTROL_VEHICLE: return "SPELL_AURA_CONTROL_VEHICLE"; + case SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER: return "SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER"; + case SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER: return "SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER"; + case SPELL_AURA_MOD_SCALE_2: return "SPELL_AURA_MOD_SCALE_2"; + case SPELL_AURA_MOD_EXPERTISE: return "SPELL_AURA_MOD_EXPERTISE"; + case SPELL_AURA_FORCE_MOVE_FORWARD: return "SPELL_AURA_FORCE_MOVE_FORWARD"; + case SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING: return "SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING"; + case SPELL_AURA_MOD_FACTION: return "SPELL_AURA_MOD_FACTION"; + case SPELL_AURA_COMPREHEND_LANGUAGE: return "SPELL_AURA_COMPREHEND_LANGUAGE"; + case SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL: return "SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL"; + case SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK: return "SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK"; + case SPELL_AURA_CLONE_CASTER: return "SPELL_AURA_CLONE_CASTER"; + case SPELL_AURA_MOD_COMBAT_RESULT_CHANCE: return "SPELL_AURA_MOD_COMBAT_RESULT_CHANCE"; + case SPELL_AURA_CONVERT_RUNE: return "SPELL_AURA_CONVERT_RUNE"; + case SPELL_AURA_MOD_INCREASE_HEALTH_2: return "SPELL_AURA_MOD_INCREASE_HEALTH_2"; + case SPELL_AURA_MOD_ENEMY_DODGE: return "SPELL_AURA_MOD_ENEMY_DODGE"; + case SPELL_AURA_MOD_SPEED_SLOW_ALL: return "SPELL_AURA_MOD_SPEED_SLOW_ALL"; + case SPELL_AURA_MOD_BLOCK_CRIT_CHANCE: return "SPELL_AURA_MOD_BLOCK_CRIT_CHANCE"; + case SPELL_AURA_MOD_DISARM_OFFHAND: return "SPELL_AURA_MOD_DISARM_OFFHAND"; + case SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT: return "SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT"; + case SPELL_AURA_NO_REAGENT_USE: return "SPELL_AURA_NO_REAGENT_USE"; + case SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS: return "SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS"; + case SPELL_AURA_258: return "SPELL_AURA_258"; + case SPELL_AURA_MOD_HOT_PCT: return "SPELL_AURA_MOD_HOT_PCT"; + case SPELL_AURA_SCREEN_EFFECT: return "SPELL_AURA_SCREEN_EFFECT"; + case SPELL_AURA_PHASE: return "SPELL_AURA_PHASE"; + case SPELL_AURA_ABILITY_IGNORE_AURASTATE: return "SPELL_AURA_ABILITY_IGNORE_AURASTATE"; + case SPELL_AURA_ALLOW_ONLY_ABILITY: return "SPELL_AURA_ALLOW_ONLY_ABILITY"; + case SPELL_AURA_264: return "SPELL_AURA_264"; + case SPELL_AURA_265: return "SPELL_AURA_265"; + case SPELL_AURA_266: return "SPELL_AURA_266"; + case SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL: return "SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL"; + case SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT: return "SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT"; + case SPELL_AURA_MOD_IGNORE_TARGET_RESIST: return "SPELL_AURA_MOD_IGNORE_TARGET_RESIST"; + case SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST: return "SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST"; + case SPELL_AURA_MOD_DAMAGE_FROM_CASTER: return "SPELL_AURA_MOD_DAMAGE_FROM_CASTER"; + case SPELL_AURA_IGNORE_MELEE_RESET: return "SPELL_AURA_IGNORE_MELEE_RESET"; + case SPELL_AURA_X_RAY: return "SPELL_AURA_X_RAY"; + case SPELL_AURA_ABILITY_CONSUME_NO_AMMO: return "SPELL_AURA_ABILITY_CONSUME_NO_AMMO"; + case SPELL_AURA_MOD_IGNORE_SHAPESHIFT: return "SPELL_AURA_MOD_IGNORE_SHAPESHIFT"; + case SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC: return "SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC"; + case SPELL_AURA_MOD_MAX_AFFECTED_TARGETS: return "SPELL_AURA_MOD_MAX_AFFECTED_TARGETS"; + case SPELL_AURA_MOD_DISARM_RANGED: return "SPELL_AURA_MOD_DISARM_RANGED"; + case SPELL_AURA_INITIALIZE_IMAGES: return "SPELL_AURA_INITIALIZE_IMAGES"; + case SPELL_AURA_MOD_ARMOR_PENETRATION_PCT: return "SPELL_AURA_MOD_ARMOR_PENETRATION_PCT"; + case SPELL_AURA_MOD_HONOR_GAIN_PCT: return "SPELL_AURA_MOD_HONOR_GAIN_PCT"; + case SPELL_AURA_MOD_BASE_HEALTH_PCT: return "SPELL_AURA_MOD_BASE_HEALTH_PCT"; + case SPELL_AURA_MOD_HEALING_RECEIVED: return "SPELL_AURA_MOD_HEALING_RECEIVED"; + case SPELL_AURA_LINKED: return "SPELL_AURA_LINKED"; + case SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR: return "SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR"; + case SPELL_AURA_ABILITY_PERIODIC_CRIT: return "SPELL_AURA_ABILITY_PERIODIC_CRIT"; + case SPELL_AURA_DEFLECT_SPELLS: return "SPELL_AURA_DEFLECT_SPELLS"; + case SPELL_AURA_IGNORE_HIT_DIRECTION: return "SPELL_AURA_IGNORE_HIT_DIRECTION"; + case SPELL_AURA_PREVENT_DURABILITY_LOSS: return "SPELL_AURA_PREVENT_DURABILITY_LOSS"; + case SPELL_AURA_MOD_CRIT_PCT: return "SPELL_AURA_MOD_CRIT_PCT"; + case SPELL_AURA_MOD_XP_QUEST_PCT: return "SPELL_AURA_MOD_XP_QUEST_PCT"; + case SPELL_AURA_OPEN_STABLE: return "SPELL_AURA_OPEN_STABLE"; + case SPELL_AURA_OVERRIDE_SPELLS: return "SPELL_AURA_OVERRIDE_SPELLS"; + case SPELL_AURA_PREVENT_REGENERATE_POWER: return "SPELL_AURA_PREVENT_REGENERATE_POWER"; + case SPELL_AURA_295: return "SPELL_AURA_295"; + case SPELL_AURA_SET_VEHICLE_ID: return "SPELL_AURA_SET_VEHICLE_ID"; + case SPELL_AURA_BLOCK_SPELL_FAMILY: return "SPELL_AURA_BLOCK_SPELL_FAMILY"; + case SPELL_AURA_STRANGULATE: return "SPELL_AURA_STRANGULATE"; + case SPELL_AURA_299: return "SPELL_AURA_299"; + case SPELL_AURA_SHARE_DAMAGE_PCT: return "SPELL_AURA_SHARE_DAMAGE_PCT"; + case SPELL_AURA_SCHOOL_HEAL_ABSORB: return "SPELL_AURA_SCHOOL_HEAL_ABSORB"; + case SPELL_AURA_302: return "SPELL_AURA_302"; + case SPELL_AURA_MOD_DAMAGE_DONE_VERSUS_AURASTATE: return "SPELL_AURA_MOD_DAMAGE_DONE_VERSUS_AURASTATE"; + case SPELL_AURA_MOD_FAKE_INEBRIATE: return "SPELL_AURA_MOD_FAKE_INEBRIATE"; + case SPELL_AURA_MOD_MINIMUM_SPEED: return "SPELL_AURA_MOD_MINIMUM_SPEED"; + case SPELL_AURA_306: return "SPELL_AURA_306"; + case SPELL_AURA_HEAL_ABSORB_TEST: return "SPELL_AURA_HEAL_ABSORB_TEST"; + case SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER: return "SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER"; + case SPELL_AURA_309: return "SPELL_AURA_309"; + case SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE: return "SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE"; + case SPELL_AURA_311: return "SPELL_AURA_311"; + case SPELL_AURA_312: return "SPELL_AURA_312"; + case SPELL_AURA_313: return "SPELL_AURA_313"; + case SPELL_AURA_PREVENT_RESURRECTION: return "SPELL_AURA_PREVENT_RESURRECTION"; + case SPELL_AURA_UNDERWATER_WALKING: return "SPELL_AURA_UNDERWATER_WALKING"; + case SPELL_AURA_PERIODIC_HASTE: return "SPELL_AURA_PERIODIC_HASTE"; + default: return "UNKNOWN_AURA"; + } + } + + static char const* GetTargetName(uint32 target) + { + switch (target) + { + case TARGET_UNIT_CASTER: return "TARGET_UNIT_CASTER"; + case TARGET_UNIT_NEARBY_ENEMY: return "TARGET_UNIT_NEARBY_ENEMY"; + case TARGET_UNIT_NEARBY_ALLY: return "TARGET_UNIT_NEARBY_ALLY"; + case TARGET_UNIT_NEARBY_PARTY: return "TARGET_UNIT_NEARBY_PARTY"; + case TARGET_UNIT_PET: return "TARGET_UNIT_PET"; + case TARGET_UNIT_TARGET_ENEMY: return "TARGET_UNIT_TARGET_ENEMY"; + case TARGET_UNIT_SRC_AREA_ENTRY: return "TARGET_UNIT_SRC_AREA_ENTRY"; + case TARGET_UNIT_DEST_AREA_ENTRY: return "TARGET_UNIT_DEST_AREA_ENTRY"; + case TARGET_DEST_HOME: return "TARGET_DEST_HOME"; + case TARGET_UNIT_SRC_AREA_UNK_11: return "TARGET_UNIT_SRC_AREA_UNK_11"; + case TARGET_UNIT_SRC_AREA_ENEMY: return "TARGET_UNIT_SRC_AREA_ENEMY"; + case TARGET_UNIT_DEST_AREA_ENEMY: return "TARGET_UNIT_DEST_AREA_ENEMY"; + case TARGET_DEST_DB: return "TARGET_DEST_DB"; + case TARGET_DEST_CASTER: return "TARGET_DEST_CASTER"; + case TARGET_UNIT_CASTER_AREA_PARTY: return "TARGET_UNIT_CASTER_AREA_PARTY"; + case TARGET_UNIT_TARGET_ALLY: return "TARGET_UNIT_TARGET_ALLY"; + case TARGET_SRC_CASTER: return "TARGET_SRC_CASTER"; + case TARGET_GAMEOBJECT_TARGET: return "TARGET_GAMEOBJECT_TARGET"; + case TARGET_UNIT_CONE_ENEMY_24: return "TARGET_UNIT_CONE_ENEMY_24"; + case TARGET_UNIT_TARGET_ANY: return "TARGET_UNIT_TARGET_ANY"; + case TARGET_GAMEOBJECT_ITEM_TARGET: return "TARGET_GAMEOBJECT_ITEM_TARGET"; + case TARGET_UNIT_MASTER: return "TARGET_UNIT_MASTER"; + case TARGET_DEST_DYNOBJ_ENEMY: return "TARGET_DEST_DYNOBJ_ENEMY"; + case TARGET_DEST_DYNOBJ_ALLY: return "TARGET_DEST_DYNOBJ_ALLY"; + case TARGET_UNIT_SRC_AREA_ALLY: return "TARGET_UNIT_SRC_AREA_ALLY"; + case TARGET_UNIT_DEST_AREA_ALLY: return "TARGET_UNIT_DEST_AREA_ALLY"; + case TARGET_DEST_CASTER_SUMMON: return "TARGET_DEST_CASTER_SUMMON"; + case TARGET_UNIT_SRC_AREA_PARTY: return "TARGET_UNIT_SRC_AREA_PARTY"; + case TARGET_UNIT_DEST_AREA_PARTY: return "TARGET_UNIT_DEST_AREA_PARTY"; + case TARGET_UNIT_TARGET_PARTY: return "TARGET_UNIT_TARGET_PARTY"; + case TARGET_DEST_CASTER_36: return "TARGET_DEST_CASTER_36"; + case TARGET_UNIT_LASTTARGET_AREA_PARTY: return "TARGET_UNIT_LASTTARGET_AREA_PARTY"; + case TARGET_UNIT_NEARBY_ENTRY: return "TARGET_UNIT_NEARBY_ENTRY"; + case TARGET_DEST_CASTER_FISHING: return "TARGET_DEST_CASTER_FISHING"; + case TARGET_GAMEOBJECT_NEARBY_ENTRY: return "TARGET_GAMEOBJECT_NEARBY_ENTRY"; + case TARGET_DEST_CASTER_FRONT_RIGHT: return "TARGET_DEST_CASTER_FRONT_RIGHT"; + case TARGET_DEST_CASTER_BACK_RIGHT: return "TARGET_DEST_CASTER_BACK_RIGHT"; + case TARGET_DEST_CASTER_BACK_LEFT: return "TARGET_DEST_CASTER_BACK_LEFT"; + case TARGET_DEST_CASTER_FRONT_LEFT: return "TARGET_DEST_CASTER_FRONT_LEFT"; + case TARGET_UNIT_TARGET_CHAINHEAL_ALLY: return "TARGET_UNIT_TARGET_CHAINHEAL_ALLY"; + case TARGET_DEST_NEARBY_ENTRY: return "TARGET_DEST_NEARBY_ENTRY"; + case TARGET_DEST_CASTER_FRONT: return "TARGET_DEST_CASTER_FRONT"; + case TARGET_DEST_CASTER_BACK: return "TARGET_DEST_CASTER_BACK"; + case TARGET_DEST_CASTER_RIGHT: return "TARGET_DEST_CASTER_RIGHT"; + case TARGET_DEST_CASTER_LEFT: return "TARGET_DEST_CASTER_LEFT"; + case TARGET_GAMEOBJECT_SRC_AREA: return "TARGET_GAMEOBJECT_SRC_AREA"; + case TARGET_GAMEOBJECT_DEST_AREA: return "TARGET_GAMEOBJECT_DEST_AREA"; + case TARGET_DEST_TARGET_ENEMY: return "TARGET_DEST_TARGET_ENEMY"; + case TARGET_UNIT_CONE_ENEMY_54: return "TARGET_UNIT_CONE_ENEMY_54"; + case TARGET_DEST_CASTER_FRONT_LEAP: return "TARGET_DEST_CASTER_FRONT_LEAP"; + case TARGET_UNIT_CASTER_AREA_RAID: return "TARGET_UNIT_CASTER_AREA_RAID"; + case TARGET_UNIT_TARGET_RAID: return "TARGET_UNIT_TARGET_RAID"; + case TARGET_UNIT_NEARBY_RAID: return "TARGET_UNIT_NEARBY_RAID"; + case TARGET_UNIT_CONE_ALLY: return "TARGET_UNIT_CONE_ALLY"; + case TARGET_UNIT_CONE_ENTRY: return "TARGET_UNIT_CONE_ENTRY"; + case TARGET_UNIT_TARGET_AREA_RAID_CLASS: return "TARGET_UNIT_TARGET_AREA_RAID_CLASS"; + case TARGET_UNK_62: return "TARGET_UNK_62"; + case TARGET_DEST_TARGET_ANY: return "TARGET_DEST_TARGET_ANY"; + case TARGET_DEST_TARGET_FRONT: return "TARGET_DEST_TARGET_FRONT"; + case TARGET_DEST_TARGET_BACK: return "TARGET_DEST_TARGET_BACK"; + case TARGET_DEST_TARGET_RIGHT: return "TARGET_DEST_TARGET_RIGHT"; + case TARGET_DEST_TARGET_LEFT: return "TARGET_DEST_TARGET_LEFT"; + case TARGET_DEST_TARGET_FRONT_RIGHT: return "TARGET_DEST_TARGET_FRONT_RIGHT"; + case TARGET_DEST_TARGET_BACK_RIGHT: return "TARGET_DEST_TARGET_BACK_RIGHT"; + case TARGET_DEST_TARGET_BACK_LEFT: return "TARGET_DEST_TARGET_BACK_LEFT"; + case TARGET_DEST_TARGET_FRONT_LEFT: return "TARGET_DEST_TARGET_FRONT_LEFT"; + case TARGET_DEST_CASTER_RANDOM: return "TARGET_DEST_CASTER_RANDOM"; + case TARGET_DEST_CASTER_RADIUS: return "TARGET_DEST_CASTER_RADIUS"; + case TARGET_DEST_TARGET_RANDOM: return "TARGET_DEST_TARGET_RANDOM"; + case TARGET_DEST_TARGET_RADIUS: return "TARGET_DEST_TARGET_RADIUS"; + case TARGET_DEST_CHANNEL_TARGET: return "TARGET_DEST_CHANNEL_TARGET"; + case TARGET_UNIT_CHANNEL_TARGET: return "TARGET_UNIT_CHANNEL_TARGET"; + case TARGET_DEST_DEST_FRONT: return "TARGET_DEST_DEST_FRONT"; + case TARGET_DEST_DEST_BACK: return "TARGET_DEST_DEST_BACK"; + case TARGET_DEST_DEST_RIGHT: return "TARGET_DEST_DEST_RIGHT"; + case TARGET_DEST_DEST_LEFT: return "TARGET_DEST_DEST_LEFT"; + case TARGET_DEST_DEST_FRONT_RIGHT: return "TARGET_DEST_DEST_FRONT_RIGHT"; + case TARGET_DEST_DEST_BACK_RIGHT: return "TARGET_DEST_DEST_BACK_RIGHT"; + case TARGET_DEST_DEST_BACK_LEFT: return "TARGET_DEST_DEST_BACK_LEFT"; + case TARGET_DEST_DEST_FRONT_LEFT: return "TARGET_DEST_DEST_FRONT_LEFT"; + case TARGET_DEST_DEST_RANDOM: return "TARGET_DEST_DEST_RANDOM"; + case TARGET_DEST_DEST: return "TARGET_DEST_DEST"; + case TARGET_DEST_DYNOBJ_NONE: return "TARGET_DEST_DYNOBJ_NONE"; + case TARGET_DEST_TRAJ: return "TARGET_DEST_TRAJ"; + case TARGET_UNIT_TARGET_MINIPET: return "TARGET_UNIT_TARGET_MINIPET"; + case TARGET_DEST_DEST_RADIUS: return "TARGET_DEST_DEST_RADIUS"; + case TARGET_UNIT_SUMMONER: return "TARGET_UNIT_SUMMONER"; + case TARGET_CORPSE_SRC_AREA_ENEMY: return "TARGET_CORPSE_SRC_AREA_ENEMY"; + case TARGET_UNIT_VEHICLE: return "TARGET_UNIT_VEHICLE"; + case TARGET_UNIT_TARGET_PASSENGER: return "TARGET_UNIT_TARGET_PASSENGER"; + case TARGET_UNIT_PASSENGER_0: return "TARGET_UNIT_PASSENGER_0"; + case TARGET_UNIT_PASSENGER_1: return "TARGET_UNIT_PASSENGER_1"; + case TARGET_UNIT_PASSENGER_2: return "TARGET_UNIT_PASSENGER_2"; + case TARGET_UNIT_PASSENGER_3: return "TARGET_UNIT_PASSENGER_3"; + case TARGET_UNIT_PASSENGER_4: return "TARGET_UNIT_PASSENGER_4"; + case TARGET_UNIT_PASSENGER_5: return "TARGET_UNIT_PASSENGER_5"; + case TARGET_UNIT_PASSENGER_6: return "TARGET_UNIT_PASSENGER_6"; + case TARGET_UNIT_PASSENGER_7: return "TARGET_UNIT_PASSENGER_7"; + case TARGET_UNIT_CONE_ENEMY_104: return "TARGET_UNIT_CONE_ENEMY_104"; + case TARGET_UNIT_UNK_105: return "TARGET_UNIT_UNK_105"; + case TARGET_DEST_CHANNEL_CASTER: return "TARGET_DEST_CHANNEL_CASTER"; + case TARGET_UNK_DEST_AREA_UNK_107: return "TARGET_UNK_DEST_AREA_UNK_107"; + case TARGET_GAMEOBJECT_CONE: return "TARGET_GAMEOBJECT_CONE"; + case TARGET_DEST_UNK_110: return "TARGET_DEST_UNK_110"; + default: return "TARGET_NONE"; + } + } + + static char const* GetDispelName(uint32 dispel) + { + switch (dispel) + { + case DISPEL_NONE: return "DISPEL_NONE"; + case DISPEL_MAGIC: return "DISPEL_MAGIC"; + case DISPEL_CURSE: return "DISPEL_CURSE"; + case DISPEL_DISEASE: return "DISPEL_DISEASE"; + case DISPEL_POISON: return "DISPEL_POISON"; + case DISPEL_STEALTH: return "DISPEL_STEALTH"; + case DISPEL_INVISIBILITY: return "DISPEL_INVISIBILITY"; + case DISPEL_ALL: return "DISPEL_ALL"; + case DISPEL_SPE_NPC_ONLY: return "DISPEL_SPE_NPC_ONLY"; + case DISPEL_ENRAGE: return "DISPEL_ENRAGE"; + case DISPEL_ZG_TICKET: return "DISPEL_ZG_TICKET"; + case DESPEL_OLD_UNUSED: return "DESPEL_OLD_UNUSED"; + default: return "UNKNOWN_DISPEL"; + } + } + + static char const* GetPowerName(uint32 power) + { + switch (power) + { + case POWER_MANA: return "POWER_MANA"; + case POWER_RAGE: return "POWER_RAGE"; + case POWER_FOCUS: return "POWER_FOCUS"; + case POWER_ENERGY: return "POWER_ENERGY"; + case POWER_HAPPINESS: return "POWER_HAPPINESS"; + case POWER_RUNE: return "POWER_RUNE"; + case POWER_RUNIC_POWER: return "POWER_RUNIC_POWER"; + case POWER_HEALTH: return "POWER_HEALTH"; + default: return "UNKNOWN_POWER"; + } + } + + static char const* GetDmgClassName(uint32 dmgClass) + { + switch (dmgClass) + { + case SPELL_DAMAGE_CLASS_NONE: return "SPELL_DAMAGE_CLASS_NONE"; + case SPELL_DAMAGE_CLASS_MAGIC: return "SPELL_DAMAGE_CLASS_MAGIC"; + case SPELL_DAMAGE_CLASS_MELEE: return "SPELL_DAMAGE_CLASS_MELEE"; + case SPELL_DAMAGE_CLASS_RANGED: return "SPELL_DAMAGE_CLASS_RANGED"; + default: return "UNKNOWN_DMG_CLASS"; + } + } + + static char const* GetPreventionTypeName(uint32 type) + { + switch (type) + { + case SPELL_PREVENTION_TYPE_NONE: return "SPELL_PREVENTION_TYPE_NONE"; + case SPELL_PREVENTION_TYPE_SILENCE: return "SPELL_PREVENTION_TYPE_SILENCE"; + case SPELL_PREVENTION_TYPE_PACIFY: return "SPELL_PREVENTION_TYPE_PACIFY"; + default: return "UNKNOWN_PREVENTION_TYPE"; + } + } + + static char const* GetSpellFamilyName(uint32 family) + { + switch (family) + { + case SPELLFAMILY_GENERIC: return "SPELLFAMILY_GENERIC"; + case SPELLFAMILY_UNK1: return "SPELLFAMILY_UNK1"; + case SPELLFAMILY_MAGE: return "SPELLFAMILY_MAGE"; + case SPELLFAMILY_WARRIOR: return "SPELLFAMILY_WARRIOR"; + case SPELLFAMILY_WARLOCK: return "SPELLFAMILY_WARLOCK"; + case SPELLFAMILY_PRIEST: return "SPELLFAMILY_PRIEST"; + case SPELLFAMILY_DRUID: return "SPELLFAMILY_DRUID"; + case SPELLFAMILY_ROGUE: return "SPELLFAMILY_ROGUE"; + case SPELLFAMILY_HUNTER: return "SPELLFAMILY_HUNTER"; + case SPELLFAMILY_PALADIN: return "SPELLFAMILY_PALADIN"; + case SPELLFAMILY_SHAMAN: return "SPELLFAMILY_SHAMAN"; + case SPELLFAMILY_UNK2: return "SPELLFAMILY_UNK2"; + case SPELLFAMILY_POTION: return "SPELLFAMILY_POTION"; + case SPELLFAMILY_DEATHKNIGHT: return "SPELLFAMILY_DEATHKNIGHT"; + case SPELLFAMILY_PET: return "SPELLFAMILY_PET"; + default: return "UNKNOWN_FAMILY"; + } + } + + template + static void PrintSpellAttrFlags(ChatHandler* handler, char const* label, uint32 flags) + { + handler->PSendSysMessage("{}: 0x{:08X}", label, flags); + for (auto attr : EnumUtils::Iterate()) + if (flags & static_cast(attr)) + handler->PSendSysMessage(" - {}", EnumUtils::ToConstant(attr)); + } + + static void PrintBasicInfo(ChatHandler* handler, SpellInfo const* spell) + { + int locale = handler->GetSessionDbcLocale(); + + handler->PSendSysMessage("ID: {}", spell->Id); + handler->PSendSysMessage("Name: {}", spell->SpellName[locale]); + if (spell->Rank[locale] && spell->Rank[locale][0] != '\0') + handler->PSendSysMessage("Rank: {}", spell->Rank[locale]); + + handler->PSendSysMessage("Dispel: {} ({})", spell->Dispel, GetDispelName(spell->Dispel)); + handler->PSendSysMessage("Mechanic: {} ({})", spell->Mechanic, EnumUtils::ToConstant(static_cast(spell->Mechanic))); + } + + static void PrintAttributes(ChatHandler* handler, SpellInfo const* spell) + { + PrintSpellAttrFlags(handler, "Attributes", spell->Attributes); + PrintSpellAttrFlags(handler, "AttributesEx", spell->AttributesEx); + PrintSpellAttrFlags(handler, "AttributesEx2", spell->AttributesEx2); + PrintSpellAttrFlags(handler, "AttributesEx3", spell->AttributesEx3); + PrintSpellAttrFlags(handler, "AttributesEx4", spell->AttributesEx4); + PrintSpellAttrFlags(handler, "AttributesEx5", spell->AttributesEx5); + PrintSpellAttrFlags(handler, "AttributesEx6", spell->AttributesEx6); + PrintSpellAttrFlags(handler, "AttributesEx7", spell->AttributesEx7); + + handler->PSendSysMessage("AttributesCu: 0x{:08X}", spell->AttributesCu); + if (spell->AttributesCu) + { + if (spell->AttributesCu & SPELL_ATTR0_CU_ENCHANT_PROC) handler->PSendSysMessage(" - SPELL_ATTR0_CU_ENCHANT_PROC"); + if (spell->AttributesCu & SPELL_ATTR0_CU_CONE_BACK) handler->PSendSysMessage(" - SPELL_ATTR0_CU_CONE_BACK"); + if (spell->AttributesCu & SPELL_ATTR0_CU_CONE_LINE) handler->PSendSysMessage(" - SPELL_ATTR0_CU_CONE_LINE"); + if (spell->AttributesCu & SPELL_ATTR0_CU_SHARE_DAMAGE) handler->PSendSysMessage(" - SPELL_ATTR0_CU_SHARE_DAMAGE"); + if (spell->AttributesCu & SPELL_ATTR0_CU_NO_INITIAL_THREAT) handler->PSendSysMessage(" - SPELL_ATTR0_CU_NO_INITIAL_THREAT"); + if (spell->AttributesCu & SPELL_ATTR0_CU_AURA_CC) handler->PSendSysMessage(" - SPELL_ATTR0_CU_AURA_CC"); + if (spell->AttributesCu & SPELL_ATTR0_CU_DONT_BREAK_STEALTH) handler->PSendSysMessage(" - SPELL_ATTR0_CU_DONT_BREAK_STEALTH"); + if (spell->AttributesCu & SPELL_ATTR0_CU_NO_PVP_FLAG) handler->PSendSysMessage(" - SPELL_ATTR0_CU_NO_PVP_FLAG"); + if (spell->AttributesCu & SPELL_ATTR0_CU_DIRECT_DAMAGE) handler->PSendSysMessage(" - SPELL_ATTR0_CU_DIRECT_DAMAGE"); + if (spell->AttributesCu & SPELL_ATTR0_CU_CHARGE) handler->PSendSysMessage(" - SPELL_ATTR0_CU_CHARGE"); + if (spell->AttributesCu & SPELL_ATTR0_CU_PICKPOCKET) handler->PSendSysMessage(" - SPELL_ATTR0_CU_PICKPOCKET"); + if (spell->AttributesCu & SPELL_ATTR0_CU_IGNORE_EVADE) handler->PSendSysMessage(" - SPELL_ATTR0_CU_IGNORE_EVADE"); + if (spell->AttributesCu & SPELL_ATTR0_CU_NEGATIVE_EFF0) handler->PSendSysMessage(" - SPELL_ATTR0_CU_NEGATIVE_EFF0"); + if (spell->AttributesCu & SPELL_ATTR0_CU_NEGATIVE_EFF1) handler->PSendSysMessage(" - SPELL_ATTR0_CU_NEGATIVE_EFF1"); + if (spell->AttributesCu & SPELL_ATTR0_CU_NEGATIVE_EFF2) handler->PSendSysMessage(" - SPELL_ATTR0_CU_NEGATIVE_EFF2"); + if (spell->AttributesCu & SPELL_ATTR0_CU_IGNORE_ARMOR) handler->PSendSysMessage(" - SPELL_ATTR0_CU_IGNORE_ARMOR"); + if (spell->AttributesCu & SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) handler->PSendSysMessage(" - SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER"); + if (spell->AttributesCu & SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) handler->PSendSysMessage(" - SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET"); + if (spell->AttributesCu & SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET) handler->PSendSysMessage(" - SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET"); + if (spell->AttributesCu & SPELL_ATTR0_CU_NEEDS_AMMO_DATA) handler->PSendSysMessage(" - SPELL_ATTR0_CU_NEEDS_AMMO_DATA"); + if (spell->AttributesCu & SPELL_ATTR0_CU_BINARY_SPELL) handler->PSendSysMessage(" - SPELL_ATTR0_CU_BINARY_SPELL"); + if (spell->AttributesCu & SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS) handler->PSendSysMessage(" - SPELL_ATTR0_CU_NO_POSITIVE_TAKEN_BONUS"); + if (spell->AttributesCu & SPELL_ATTR0_CU_SINGLE_AURA_STACK) handler->PSendSysMessage(" - SPELL_ATTR0_CU_SINGLE_AURA_STACK"); + if (spell->AttributesCu & SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC) handler->PSendSysMessage(" - SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC"); + if (spell->AttributesCu & SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED) handler->PSendSysMessage(" - SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED"); + if (spell->AttributesCu & SPELL_ATTR0_CU_POSITIVE_EFF0) handler->PSendSysMessage(" - SPELL_ATTR0_CU_POSITIVE_EFF0"); + if (spell->AttributesCu & SPELL_ATTR0_CU_POSITIVE_EFF1) handler->PSendSysMessage(" - SPELL_ATTR0_CU_POSITIVE_EFF1"); + if (spell->AttributesCu & SPELL_ATTR0_CU_POSITIVE_EFF2) handler->PSendSysMessage(" - SPELL_ATTR0_CU_POSITIVE_EFF2"); + if (spell->AttributesCu & SPELL_ATTR0_CU_FORCE_SEND_CATEGORY_COOLDOWNS) handler->PSendSysMessage(" - SPELL_ATTR0_CU_FORCE_SEND_CATEGORY_COOLDOWNS"); + if (spell->AttributesCu & SPELL_ATTR0_CU_ONLY_ONE_AREA_AURA) handler->PSendSysMessage(" - SPELL_ATTR0_CU_ONLY_ONE_AREA_AURA"); + if (spell->AttributesCu & SPELL_ATTR0_CU_ENCOUNTER_REWARD) handler->PSendSysMessage(" - SPELL_ATTR0_CU_ENCOUNTER_REWARD"); + if (spell->AttributesCu & SPELL_ATTR0_CU_BYPASS_MECHANIC_IMMUNITY) handler->PSendSysMessage(" - SPELL_ATTR0_CU_BYPASS_MECHANIC_IMMUNITY"); + } + + handler->PSendSysMessage("Stances: 0x{:08X}", spell->Stances); + handler->PSendSysMessage("StancesNot: 0x{:08X}", spell->StancesNot); + } + + static void PrintEffects(ChatHandler* handler, SpellInfo const* spell) + { + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + SpellEffectInfo const& eff = spell->Effects[i]; + + if (!eff.Effect) + continue; + + handler->PSendSysMessage("--- Effect {} ---", i); + handler->PSendSysMessage(" Effect: {} ({})", eff.Effect, GetSpellEffectName(eff.Effect)); + handler->PSendSysMessage(" Aura: {} ({})", static_cast(eff.ApplyAuraName), GetAuraTypeName(static_cast(eff.ApplyAuraName))); + handler->PSendSysMessage(" BasePoints: {}", eff.BasePoints); + handler->PSendSysMessage(" DieSides: {}", eff.DieSides); + handler->PSendSysMessage(" RealPointsPerLevel: {:.4f}", eff.RealPointsPerLevel); + handler->PSendSysMessage(" PointsPerComboPoint: {:.2f}", eff.PointsPerComboPoint); + handler->PSendSysMessage(" ValueMultiplier: {:.4f}", eff.ValueMultiplier); + handler->PSendSysMessage(" DamageMultiplier: {:.4f}", eff.DamageMultiplier); + handler->PSendSysMessage(" BonusMultiplier: {:.4f}", eff.BonusMultiplier); + handler->PSendSysMessage(" MiscValue: {}", eff.MiscValue); + handler->PSendSysMessage(" MiscValueB: {}", eff.MiscValueB); + handler->PSendSysMessage(" Mechanic: {} ({})", static_cast(eff.Mechanic), EnumUtils::ToConstant(eff.Mechanic)); + handler->PSendSysMessage(" TriggerSpell: {}", eff.TriggerSpell); + handler->PSendSysMessage(" Amplitude: {}", eff.Amplitude); + handler->PSendSysMessage(" ItemType: {}", eff.ItemType); + handler->PSendSysMessage(" SpellClassMask: 0x{:08X} 0x{:08X} 0x{:08X}", eff.SpellClassMask[0], eff.SpellClassMask[1], eff.SpellClassMask[2]); + } + } + + static void PrintTargets(ChatHandler* handler, SpellInfo const* spell) + { + handler->PSendSysMessage("Targets: 0x{:08X}", spell->Targets); + handler->PSendSysMessage("TargetCreatureType: 0x{:08X}", spell->TargetCreatureType); + handler->PSendSysMessage("MaxAffectedTargets: {}", spell->MaxAffectedTargets); + handler->PSendSysMessage("MaxTargetLevel: {}", spell->MaxTargetLevel); + + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + SpellEffectInfo const& eff = spell->Effects[i]; + + if (!eff.Effect) + continue; + + Targets targetA = eff.TargetA.GetTarget(); + Targets targetB = eff.TargetB.GetTarget(); + + handler->PSendSysMessage("--- Effect {} ---", i); + handler->PSendSysMessage(" TargetA: {} ({})", static_cast(targetA), GetTargetName(static_cast(targetA))); + handler->PSendSysMessage(" TargetB: {} ({})", static_cast(targetB), GetTargetName(static_cast(targetB))); + + if (eff.RadiusEntry) + handler->PSendSysMessage(" Radius: {:.1f}", eff.RadiusEntry->RadiusMax); + handler->PSendSysMessage(" ChainTarget: {}", eff.ChainTarget); + } + } + + static void PrintGeneralInfo(ChatHandler* handler, SpellInfo const* spell) + { + if (spell->CastTimeEntry) + handler->PSendSysMessage("CastTime: {} ms", spell->CastTimeEntry->CastTime); + + if (spell->DurationEntry) + handler->PSendSysMessage("Duration: {} / {} / {} ms", spell->DurationEntry->Duration[0], spell->DurationEntry->Duration[1], spell->DurationEntry->Duration[2]); + + if (spell->RangeEntry) + handler->PSendSysMessage("Range: {:.1f}-{:.1f} (hostile), {:.1f}-{:.1f} (friendly)", + spell->RangeEntry->RangeMin[0], spell->RangeEntry->RangeMax[0], + spell->RangeEntry->RangeMin[1], spell->RangeEntry->RangeMax[1]); + + handler->PSendSysMessage("RecoveryTime: {} ms", spell->RecoveryTime); + handler->PSendSysMessage("CategoryRecoveryTime: {} ms", spell->CategoryRecoveryTime); + handler->PSendSysMessage("StartRecoveryTime: {} ms (Category: {})", spell->StartRecoveryTime, spell->StartRecoveryCategory); + + handler->PSendSysMessage("InterruptFlags: 0x{:08X}", spell->InterruptFlags); + handler->PSendSysMessage("AuraInterruptFlags: 0x{:08X}", spell->AuraInterruptFlags); + handler->PSendSysMessage("ChannelInterruptFlags: 0x{:08X}", spell->ChannelInterruptFlags); + + handler->PSendSysMessage("ProcFlags: 0x{:08X}", spell->ProcFlags); + handler->PSendSysMessage("ProcChance: {}%", spell->ProcChance); + handler->PSendSysMessage("ProcCharges: {}", spell->ProcCharges); + + handler->PSendSysMessage("SpellLevel: {}, BaseLevel: {}, MaxLevel: {}", spell->SpellLevel, spell->BaseLevel, spell->MaxLevel); + + handler->PSendSysMessage("PowerType: {} ({})", spell->PowerType, GetPowerName(spell->PowerType)); + handler->PSendSysMessage("ManaCost: {}", spell->ManaCost); + handler->PSendSysMessage("ManaCostPercentage: {}", spell->ManaCostPercentage); + handler->PSendSysMessage("ManaPerSecond: {}", spell->ManaPerSecond); + + handler->PSendSysMessage("Speed: {:.2f}", spell->Speed); + + handler->PSendSysMessage("StackAmount: {}", spell->StackAmount); + + if (spell->EquippedItemClass >= 0) + handler->PSendSysMessage("EquippedItemClass: {}, SubClassMask: 0x{:08X}, InvTypeMask: 0x{:08X}", + spell->EquippedItemClass, static_cast(spell->EquippedItemSubClassMask), static_cast(spell->EquippedItemInventoryTypeMask)); + + handler->PSendSysMessage("SpellFamilyName: {} ({})", spell->SpellFamilyName, GetSpellFamilyName(spell->SpellFamilyName)); + handler->PSendSysMessage("SpellFamilyFlags: 0x{:08X} 0x{:08X} 0x{:08X}", spell->SpellFamilyFlags[0], spell->SpellFamilyFlags[1], spell->SpellFamilyFlags[2]); + + handler->PSendSysMessage("DmgClass: {} ({})", spell->DmgClass, GetDmgClassName(spell->DmgClass)); + handler->PSendSysMessage("PreventionType: {} ({})", spell->PreventionType, GetPreventionTypeName(spell->PreventionType)); + handler->PSendSysMessage("SchoolMask: 0x{:02X}", spell->SchoolMask); + } + + static bool HandleSpellInfoAttributesCommand(ChatHandler* handler, SpellInfo const* spell) + { + if (!spell) + { + handler->SendErrorMessage(LANG_COMMAND_NOSPELLFOUND); + return false; + } + + handler->PSendSysMessage("===== SPELL ATTRIBUTES ====="); + PrintBasicInfo(handler, spell); + PrintAttributes(handler, spell); + handler->PSendSysMessage("============================"); + return true; + } + + static bool HandleSpellInfoEffectsCommand(ChatHandler* handler, SpellInfo const* spell) + { + if (!spell) + { + handler->SendErrorMessage(LANG_COMMAND_NOSPELLFOUND); + return false; + } + + handler->PSendSysMessage("====== SPELL EFFECTS ======"); + PrintBasicInfo(handler, spell); + PrintEffects(handler, spell); + handler->PSendSysMessage("==========================="); + return true; + } + + static bool HandleSpellInfoTargetsCommand(ChatHandler* handler, SpellInfo const* spell) + { + if (!spell) + { + handler->SendErrorMessage(LANG_COMMAND_NOSPELLFOUND); + return false; + } + + handler->PSendSysMessage("====== SPELL TARGETS ======"); + PrintBasicInfo(handler, spell); + PrintTargets(handler, spell); + handler->PSendSysMessage("==========================="); + return true; + } + + static bool HandleSpellInfoAllCommand(ChatHandler* handler, SpellInfo const* spell) + { + if (!spell) + { + handler->SendErrorMessage(LANG_COMMAND_NOSPELLFOUND); + return false; + } + + handler->PSendSysMessage("========== SPELL INFO =========="); + PrintBasicInfo(handler, spell); + PrintAttributes(handler, spell); + PrintGeneralInfo(handler, spell); + PrintEffects(handler, spell); + PrintTargets(handler, spell); + handler->PSendSysMessage("================================"); + return true; + } +}; + +void AddSC_spellinfo_commandscript() +{ + new spellinfo_commandscript(); +} From 585184b639e4bc474dc8ba288950af59c7b812c3 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 26 Feb 2026 02:49:52 -0600 Subject: [PATCH 311/335] fix(DB/Proc): Add missing NONE DmgClass proc flags to Blue Dragon (#24890) Co-authored-by: blinkysc --- data/sql/updates/pending_db_world/rev_1772086971482356750.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772086971482356750.sql diff --git a/data/sql/updates/pending_db_world/rev_1772086971482356750.sql b/data/sql/updates/pending_db_world/rev_1772086971482356750.sql new file mode 100644 index 000000000..a2ce8e378 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772086971482356750.sql @@ -0,0 +1,2 @@ +-- Darkmoon Card: Blue Dragon - add NONE DmgClass proc flags and fix phase to CAST +UPDATE `spell_proc` SET `ProcFlags` = 0x15400, `SpellPhaseMask` = 1 WHERE `SpellId` = 23688; From 1358d73e23bd9d248a01a8349b16e8400703f658 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 26 Feb 2026 02:50:19 -0600 Subject: [PATCH 312/335] fix(Core/Spells): Fix Hungering Cold breaking from disease damage (#24888) Co-authored-by: blinkysc Co-authored-by: ariel- --- src/server/scripts/Spells/spell_dk.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 06afadf85..6222592b8 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -614,16 +614,18 @@ class spell_dk_hungering_cold : public AuraScript { PrepareAuraScript(spell_dk_hungering_cold); - void HandleProc(ProcEventInfo& eventInfo) + bool CheckProc(ProcEventInfo& eventInfo) { - PreventDefaultAction(); - if (eventInfo.GetDamageInfo() && eventInfo.GetDamageInfo()->GetDamage() > 0 && (!eventInfo.GetSpellInfo() || eventInfo.GetSpellInfo()->Dispel != DISPEL_DISEASE)) - SetDuration(0); + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return true; + + return spellInfo->Dispel != DISPEL_DISEASE; } void Register() override { - OnProc += AuraProcFn(spell_dk_hungering_cold::HandleProc); + DoCheckProc += AuraCheckProcFn(spell_dk_hungering_cold::CheckProc); } }; From e6aae1e1c4b562eccad16254da3e63b7d6ef58cc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 26 Feb 2026 08:50:38 +0000 Subject: [PATCH 313/335] chore(DB): import pending files Referenced commit(s): 5cf9ae11a58e27352e07c88c6039521938934697 --- .../rev_1771989601546823271.sql => db_world/2026_02_26_03.sql} | 1 + .../rev_1772086971482356750.sql => db_world/2026_02_26_04.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1771989601546823271.sql => db_world/2026_02_26_03.sql} (96%) rename data/sql/updates/{pending_db_world/rev_1772086971482356750.sql => db_world/2026_02_26_04.sql} (80%) diff --git a/data/sql/updates/pending_db_world/rev_1771989601546823271.sql b/data/sql/updates/db_world/2026_02_26_03.sql similarity index 96% rename from data/sql/updates/pending_db_world/rev_1771989601546823271.sql rename to data/sql/updates/db_world/2026_02_26_03.sql index 16cc99283..6052a569e 100644 --- a/data/sql/updates/pending_db_world/rev_1771989601546823271.sql +++ b/data/sql/updates/db_world/2026_02_26_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_26_02 -> 2026_02_26_03 -- DELETE FROM `command` WHERE `name` IN ('spellinfo', 'spellinfo attributes', 'spellinfo effects', 'spellinfo targets', 'spellinfo all'); INSERT INTO `command` (`name`, `security`, `help`) VALUES diff --git a/data/sql/updates/pending_db_world/rev_1772086971482356750.sql b/data/sql/updates/db_world/2026_02_26_04.sql similarity index 80% rename from data/sql/updates/pending_db_world/rev_1772086971482356750.sql rename to data/sql/updates/db_world/2026_02_26_04.sql index a2ce8e378..8dc44aeda 100644 --- a/data/sql/updates/pending_db_world/rev_1772086971482356750.sql +++ b/data/sql/updates/db_world/2026_02_26_04.sql @@ -1,2 +1,3 @@ +-- DB update 2026_02_26_03 -> 2026_02_26_04 -- Darkmoon Card: Blue Dragon - add NONE DmgClass proc flags and fix phase to CAST UPDATE `spell_proc` SET `ProcFlags` = 0x15400, `SpellPhaseMask` = 1 WHERE `SpellId` = 23688; From 028db4c0332c03f27d4847ff0bb533012bdc7d91 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 26 Feb 2026 10:18:24 -0600 Subject: [PATCH 314/335] fix(Core/Spells): Check DONT_BREAK_STEALTH in stealth proc guard (#24898) Co-authored-by: blinkysc --- src/server/game/Spells/Auras/SpellAuras.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 0c908e848..dc5eac5e6 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2184,7 +2184,7 @@ uint8 Aura::GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo, if (m_spellInfo->HasAura(SPELL_AURA_MOD_STEALTH)) { if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - if (spellInfo->IsPositive() || !eventInfo.GetActor()->IsHostileTo(aurApp->GetTarget())) + if (spellInfo->IsPositive() || !eventInfo.GetActor()->IsHostileTo(aurApp->GetTarget()) || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) return 0; } From 54dba754835c07216636e33525ff58ce0f429ddf Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 26 Feb 2026 12:00:33 -0600 Subject: [PATCH 315/335] fix(Core/Spells): Turn the Tables buff only applies to the rogue (#24896) Co-authored-by: blinkysc --- src/server/scripts/Spells/spell_rogue.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index b0ffb02a6..832ec5c35 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -1046,13 +1046,19 @@ class spell_rog_turn_the_tables : public AuraScript }; // 52910, 52914, 52915 - Turn the Tables (proc) -class spell_rog_turn_the_tables_proc : public AuraScript +class spell_rog_turn_the_tables_proc : public SpellScript { - PrepareAuraScript(spell_rog_turn_the_tables_proc); + PrepareSpellScript(spell_rog_turn_the_tables_proc); + + void FilterTargets(std::list& targets) + { + targets.clear(); + targets.push_back(GetCaster()); + } void Register() override { - // No special handling needed - default behavior + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rog_turn_the_tables_proc::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); } }; From 76ec5e39a0bb3b75b779501a854c83e8e669cab2 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Thu, 26 Feb 2026 15:56:59 -0300 Subject: [PATCH 316/335] fix(DB/Loot): Gluth Loot Table (#24737) Co-authored-by: amed80 <8395873+amed80@users.noreply.github.com> --- .../rev_1771283323680167400.sql | 305 ++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771283323680167400.sql diff --git a/data/sql/updates/pending_db_world/rev_1771283323680167400.sql b/data/sql/updates/pending_db_world/rev_1771283323680167400.sql new file mode 100644 index 000000000..aa3c47b12 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771283323680167400.sql @@ -0,0 +1,305 @@ +-- Gluth +DELETE FROM `creature_loot_template` WHERE (`Entry` = 15932) AND `GroupId` = 2; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(15932, 39139, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Ravaging Sabatons'), +(15932, 39140, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Knife of Incision'), +(15932, 39141, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Deflection Band'), +(15932, 39146, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Collar of Dissolution'), +(15932, 39188, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Chivalric Chestguard'), +(15932, 39189, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Boots of Persistence'), +(15932, 39190, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Agonal Sash'), +(15932, 39191, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Splint-Bound Leggings'), +(15932, 39192, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Gloves of Dark Gestures'), +(15932, 39193, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Band of Neglected Pleas'), +(15932, 39194, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Rusted-Link Spiked Gauntlets'), +(15932, 39195, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Bracers of Lost Sentiments'), +(15932, 39196, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Boots of the Worshiper'), +(15932, 39197, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Gauntlets of the Master'), +(15932, 39198, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Frostblight Pauldrons'), +(15932, 39199, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Watchful Eye'), +(15932, 39200, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Grieving Spellblade'), +(15932, 39215, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Boots of the Follower'), +(15932, 39216, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Sash of Mortal Desire'), +(15932, 39217, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Avenging Combat Leggings'), +(15932, 39221, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Wraith Spear'), +(15932, 39224, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Leggings of Discord'), +(15932, 39225, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Cloak of Armed Strife'), +(15932, 39226, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Maexxna\'s Femur'), +(15932, 39228, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Web Cocoon Grips'), +(15932, 39229, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Embrace of the Spider'), +(15932, 39230, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Spaulders of the Monstrosity'), +(15932, 39231, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Timeworn Silken Band'), +(15932, 39232, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Pendant of Lost Vocations'), +(15932, 39233, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Aegis of Damnation'), +(15932, 39234, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Plague-Impervious Boots'), +(15932, 39235, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Bone-Framed Bracers'), +(15932, 39236, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Trespasser\'s Boots'), +(15932, 39237, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Spaulders of Resumed Battle'), +(15932, 39239, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Chestplate of the Risen Soldier'), +(15932, 39240, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Noth\'s Curse'), +(15932, 39241, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Dark Shroud of the Scourge'), +(15932, 39242, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Robes of Hoarse Breaths'), +(15932, 39243, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Handgrips of the Foredoomed'), +(15932, 39244, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Ring of the Fated'), +(15932, 39245, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Demise'), +(15932, 39246, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Amulet of Autopsy'), +(15932, 39247, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Cuffs of Dark Shadows'), +(15932, 39248, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Tunic of the Lost Pack'), +(15932, 39249, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Shoulderplates of Bloodshed'), +(15932, 39250, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Ring of Holy Cleansing'), +(15932, 39251, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Necrogenic Belt'), +(15932, 39252, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Preceptor\'s Bindings'), +(15932, 39254, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Saltarello Shoes'), +(15932, 39255, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Staff of the Plague Beast'), +(15932, 39261, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Tainted Girdle of Mending'), +(15932, 39262, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Gauntlets of Combined Strength'), +(15932, 39267, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Abomination Shoulderblades'), +(15932, 39270, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Hatestrike'), +(15932, 39271, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Blade of Dormant Memories'), +(15932, 39272, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Drape of Surgery'), +(15932, 39273, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Sullen Cloth Boots'), +(15932, 39274, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Retcher\'s Shoulderpads'), +(15932, 39275, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Contagion Gloves'), +(15932, 39276, 0, 0, 0, 1, 2, 1, 1, 'Gluth - The Skull of Ruin'), +(15932, 39277, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Sealing Ring of Grobbulus'), +(15932, 39278, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Bands of Anxiety'), +(15932, 39279, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Blistered Belt of Decay'), +(15932, 39280, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Leggings of Innumerable Barbs'), +(15932, 39281, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Infection Repulser'), +(15932, 39282, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Bone-Linked Amulet'), +(15932, 39283, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Putrescent Bands'), +(15932, 39284, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Miasma Mantle'), +(15932, 39285, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Handgrips of Turmoil'), +(15932, 39296, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Accursed Bow of the Elite'), +(15932, 39297, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Cloak of Darkening'), +(15932, 39298, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Waistguard of the Tutor'), +(15932, 39299, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Rapid Attack Gloves'), +(15932, 39306, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Plated Gloves of Relief'), +(15932, 39307, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Iron Rings of Endurance'), +(15932, 39308, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Girdle of Lenience'), +(15932, 39309, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Leggings of the Instructor'), +(15932, 39310, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Mantle of the Extensive Mind'), +(15932, 39311, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Scepter of Murmuring Spirits'), +(15932, 39344, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Slayer of the Lifeless'), +(15932, 39345, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Girdle of the Ascended Phantom'), +(15932, 39369, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Sabatons of Deathlike Gloom'), +(15932, 39379, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Spectral Rider\'s Girdle'), +(15932, 39386, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Tunic of Dislocation'), +(15932, 39388, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Spirit-World Glass'), +(15932, 39389, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Signet of the Malevolent'), +(15932, 39390, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Resurgent Phantom Bindings'), +(15932, 39391, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Heinous Mail Chestguard'), +(15932, 39392, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Veiled Amulet of Life'), +-- (15932, 39427, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Omen of Ruin'), +-- (15932, 39467, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Minion Bracers'), +-- (15932, 39468, 0, 0, 0, 1, 2, 1, 1, 'Gluth - The Stray'), +-- (15932, 39470, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Medallion of the Disgraced'), +-- (15932, 39472, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Chain of Latent Energies'), +-- (15932, 39473, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Contortion'), +(15932, 39256, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Sulfur Stave'), +(15932, 39257, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Loatheb\'s Shadow'), +(15932, 39258, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Legplates of Inescapable Death'), +(15932, 39259, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Fungi-Stained Coverings'), +(15932, 39260, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Helm of the Corrupted Mind'), +(15932, 39291, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Torment of the Banished'), +(15932, 39292, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Repelling Charge'), +(15932, 39293, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Blackened Legplates of Feugen'), +(15932, 39294, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Arc-Scorched Helmet'), +(15932, 39295, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Cowl of Sheet Lightning'), +(15932, 39393, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Claymore of Ancient Power'), +(15932, 39394, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Charmed Cierge'), +(15932, 39395, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Thane\'s Tainted Greathelm'), +(15932, 39396, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Gown of Blaumeux'), +(15932, 39397, 0, 0, 0, 1, 2, 1, 1, 'Gluth - Pauldrons of Havoc'); + +DELETE FROM `reference_loot_template` WHERE (`Entry` = 34142); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34142, 39701, 0, 0, 0, 1, 1, 1, 1, 'Dawnwalkers'), +(34142, 39702, 0, 0, 0, 1, 1, 1, 1, 'Arachnoid Gold Band'), +(34142, 39703, 0, 0, 0, 1, 1, 1, 1, 'Rescinding Grips'), +(34142, 39704, 0, 0, 0, 1, 1, 1, 1, 'Pauldrons of Unnatural Death'), +(34142, 39706, 0, 0, 0, 1, 1, 1, 1, 'Sabatons of Sudden Reprisal'), +(34142, 39712, 0, 0, 0, 1, 1, 1, 1, 'Gemmed Wand of the Nerubians'), +(34142, 39714, 0, 0, 0, 1, 1, 1, 1, 'Webbed Death'), +(34142, 39716, 0, 0, 0, 1, 1, 1, 1, 'Shield of Assimilation'), +(34142, 39717, 0, 0, 0, 1, 1, 1, 1, 'Inexorable Sabatons'), +(34142, 39718, 0, 0, 0, 1, 1, 1, 1, 'Corpse Scarab Handguards'), +(34142, 39719, 0, 0, 0, 1, 1, 1, 1, 'Mantle of the Locusts'), +(34142, 39720, 0, 0, 0, 1, 1, 1, 1, 'Leggings of Atrophy'), +(34142, 39721, 0, 0, 0, 1, 1, 1, 1, 'Sash of the Parlor'), +(34142, 39722, 0, 0, 0, 1, 1, 1, 1, 'Swarm Bindings'), +-- (34142, 40064, 0, 0, 0, 1, 1, 1, 1, 'Thunderstorm Amulet'), +-- (34142, 40065, 0, 0, 0, 1, 1, 1, 1, 'Fool\'s Trial'), +-- (34142, 40069, 0, 0, 0, 1, 1, 1, 1, 'Heritage'), +-- (34142, 40071, 0, 0, 0, 1, 1, 1, 1, 'Chains of Adoration'), +-- (34142, 40074, 0, 0, 0, 1, 1, 1, 1, 'Strong-Handed Ring'), +-- (34142, 40075, 0, 0, 0, 1, 1, 1, 1, 'Ruthlessness'), +-- (34142, 40080, 0, 0, 0, 1, 1, 1, 1, 'Lost Jewel'), +-- (34142, 40107, 0, 0, 0, 1, 1, 1, 1, 'Sand-Worn Band'), +-- (34142, 40108, 0, 0, 0, 1, 1, 1, 1, 'Seized Beauty'), +(34142, 39723, 0, 0, 0, 1, 1, 1, 1, 'Fire-Scorched Greathelm'), +(34142, 39724, 0, 0, 0, 1, 1, 1, 1, 'Cult\'s Chestguard'), +(34142, 39725, 0, 0, 0, 1, 1, 1, 1, 'Epaulets of the Grieving Servant'), +(34142, 39726, 0, 0, 0, 1, 1, 1, 1, 'Callous-Hearted Gauntlets'), +(34142, 39727, 0, 0, 0, 1, 1, 1, 1, 'Dislocating Handguards'), +(34142, 39728, 0, 0, 0, 1, 1, 1, 1, 'Totem of Misery'), +(34142, 39729, 0, 0, 0, 1, 1, 1, 1, 'Bracers of the Tyrant'), +(34142, 39730, 0, 0, 0, 1, 1, 1, 1, 'Widow\'s Fury'), +(34142, 39731, 0, 0, 0, 1, 1, 1, 1, 'Punctilious Bindings'), +(34142, 39732, 0, 0, 0, 1, 1, 1, 1, 'Faerlina\'s Madness'), +(34142, 39733, 0, 0, 0, 1, 1, 1, 1, 'Gloves of Token Respect'), +(34142, 39734, 0, 0, 0, 1, 1, 1, 1, 'Atonement Greaves'), +(34142, 39735, 0, 0, 0, 1, 1, 1, 1, 'Belt of False Dignity'), +(34142, 39756, 0, 0, 0, 1, 1, 1, 1, 'Tunic of Prejudice'), +(34142, 39757, 0, 0, 0, 1, 1, 1, 1, 'Idol of Worship'), +(34142, 39758, 0, 0, 0, 1, 1, 1, 1, 'The Jawbone'), +(34142, 39759, 0, 0, 0, 1, 1, 1, 1, 'Ablative Chitin Girdle'), +(34142, 39760, 0, 0, 0, 1, 1, 1, 1, 'Helm of Diminished Pride'), +(34142, 39761, 0, 0, 0, 1, 1, 1, 1, 'Infectious Skitterer Leggings'), +(34142, 39762, 0, 0, 0, 1, 1, 1, 1, 'Torn Web Wrapping'), +(34142, 39763, 0, 0, 0, 1, 1, 1, 1, 'Wraith Strike'), +(34142, 39764, 0, 0, 0, 1, 1, 1, 1, 'Bindings of the Hapless Prey'), +(34142, 39765, 0, 0, 0, 1, 1, 1, 1, 'Sinner\'s Bindings'), +(34142, 39766, 0, 0, 0, 1, 1, 1, 1, 'Matriarch\'s Spawn'), +(34142, 39767, 0, 0, 0, 1, 1, 1, 1, 'Undiminished Battleplate'), +(34142, 39768, 0, 0, 0, 1, 1, 1, 1, 'Cowl of the Perished'), +(34142, 40060, 0, 0, 0, 1, 1, 1, 1, 'Distorted Limbs'), +(34142, 40061, 0, 0, 0, 1, 1, 1, 1, 'Quivering Tunic'), +(34142, 40062, 0, 0, 0, 1, 1, 1, 1, 'Digested Silken Robes'), +(34142, 40063, 0, 0, 0, 1, 1, 1, 1, 'Mantle of Shattered Kinship'), +-- (34142, 40250, 0, 0, 0, 1, 1, 1, 1, 'Aged Winter Cloak'), +-- (34142, 40251, 0, 0, 0, 1, 1, 1, 1, 'Shroud of Luminosity'), +-- (34142, 40252, 0, 0, 0, 1, 1, 1, 1, 'Cloak of the Shadowed Sun'), +-- (34142, 40253, 0, 0, 0, 1, 1, 1, 1, 'Shawl of the Old Maid'), +-- (34142, 40254, 0, 0, 0, 1, 1, 1, 1, 'Cloak of Averted Crisis'), +-- (34142, 40255, 0, 0, 0, 1, 1, 1, 1, 'Dying Curse'), +-- (34142, 40256, 0, 0, 0, 1, 1, 1, 1, 'Grim Toll'), +-- (34142, 40257, 0, 0, 0, 1, 1, 1, 1, 'Defender\'s Code'), +-- (34142, 40258, 0, 0, 0, 1, 1, 1, 1, 'Forethought Talisman'), +(34142, 40259, 0, 0, 0, 1, 1, 1, 1, 'Waistguard of Divine Grace'), +(34142, 40260, 0, 0, 0, 1, 1, 1, 1, 'Belt of the Tortured'), +(34142, 40261, 0, 0, 0, 1, 1, 1, 1, 'Crude Discolored Battlegrips'), +(34142, 40262, 0, 0, 0, 1, 1, 1, 1, 'Gloves of Calculated Risk'), +(34142, 40263, 0, 0, 0, 1, 1, 1, 1, 'Fleshless Girdle'), +(34142, 40264, 0, 0, 0, 1, 1, 1, 1, 'Split Greathammer'), +(34142, 40265, 0, 0, 0, 1, 1, 1, 1, 'Arrowsong'), +(34142, 40266, 0, 0, 0, 1, 1, 1, 1, 'Hero\'s Surrender'), +(34142, 40267, 0, 0, 0, 1, 1, 1, 1, 'Totem of Hex'), +(34142, 40268, 0, 0, 0, 1, 1, 1, 1, 'Libram of Tolerance'), +(34142, 40269, 0, 0, 0, 1, 1, 1, 1, 'Boots of Persuasion'), +(34142, 40270, 0, 0, 0, 1, 1, 1, 1, 'Boots of Septic Wounds'), +(34142, 40271, 0, 0, 0, 1, 1, 1, 1, 'Sash of Solitude'), +(34142, 40272, 0, 0, 0, 1, 1, 1, 1, 'Girdle of the Gambit'), +(34142, 40273, 0, 0, 0, 1, 1, 1, 1, 'Surplus Limb'), +(34142, 40274, 0, 0, 0, 1, 1, 1, 1, 'Bracers of Liberation'), +(34142, 40275, 0, 0, 0, 1, 1, 1, 1, 'Depraved Linked Belt'), +(34142, 40277, 0, 0, 0, 1, 1, 1, 1, 'Tunic of Indulgence'), +(34142, 40278, 0, 0, 0, 1, 1, 1, 1, 'Girdle of Chivalry'), +(34142, 40279, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of the Exhausted'), +(34142, 40280, 0, 0, 0, 1, 1, 1, 1, 'Origin of Nightmares'), +(34142, 40281, 0, 0, 0, 1, 1, 1, 1, 'Twilight Mist'), +(34142, 40282, 0, 0, 0, 1, 1, 1, 1, 'Slime Stream Bands'), +(34142, 40283, 0, 0, 0, 1, 1, 1, 1, 'Fallout Impervious Tunic'), +(34142, 40284, 0, 0, 0, 1, 1, 1, 1, 'Plague Igniter'), +(34142, 40285, 0, 0, 0, 1, 1, 1, 1, 'Desecrated Past'), +(34142, 40287, 0, 0, 0, 1, 1, 1, 1, 'Cowl of Vanity'), +(34142, 40288, 0, 0, 0, 1, 1, 1, 1, 'Spaulders of Incoherence'), +(34142, 40289, 0, 0, 0, 1, 1, 1, 1, 'Sympathetic Amice'), +(34142, 40351, 0, 0, 0, 1, 1, 1, 1, 'Mantle of the Fatigued Sage'), +(34142, 40294, 0, 0, 0, 1, 1, 1, 1, 'Riveted Abomination Leggings'), +(34142, 40296, 0, 0, 0, 1, 1, 1, 1, 'Cover of Silence'), +(34142, 40297, 0, 0, 0, 1, 1, 1, 1, 'Sabatons of Endurance'), +(34142, 40298, 0, 0, 0, 1, 1, 1, 1, 'Faceguard of the Succumbed'), +(34142, 40299, 0, 0, 0, 1, 1, 1, 1, 'Pauldrons of the Abandoned'), +(34142, 40300, 0, 0, 0, 1, 1, 1, 1, 'Spire of Sunset'), +(34142, 40301, 0, 0, 0, 1, 1, 1, 1, 'Cincture of Polarity'), +(34142, 40302, 0, 0, 0, 1, 1, 1, 1, 'Benefactor\'s Gauntlets'), +(34142, 40303, 0, 0, 0, 1, 1, 1, 1, 'Wraps of the Persecuted'), +(34142, 40304, 0, 0, 0, 1, 1, 1, 1, 'Headpiece of Fungal Bloom'), +(34142, 40305, 0, 0, 0, 1, 1, 1, 1, 'Spaulders of Egotism'), +(34142, 40306, 0, 0, 0, 1, 1, 1, 1, 'Bracers of the Unholy Knight'), +(34142, 40315, 0, 0, 0, 1, 1, 1, 1, 'Shoulderpads of Secret Arts'), +(34142, 40316, 0, 0, 0, 1, 1, 1, 1, 'Gauntlets of Guiding Touch'), +(34142, 40317, 0, 0, 0, 1, 1, 1, 1, 'Girdle of Razuvious'), +(34142, 40318, 0, 0, 0, 1, 1, 1, 1, 'Legplates of Double Strikes'), +(34142, 40319, 0, 0, 0, 1, 1, 1, 1, 'Chestpiece of Suspicion'), +(34142, 40320, 0, 0, 0, 1, 1, 1, 1, 'Faithful Steel Sabatons'), +(34142, 40321, 0, 0, 0, 1, 1, 1, 1, 'Idol of the Shooting Star'), +(34142, 40322, 0, 0, 0, 1, 1, 1, 1, 'Totem of Dueling'), +(34142, 40323, 0, 0, 0, 1, 1, 1, 1, 'Esteemed Bindings'), +(34142, 40324, 0, 0, 0, 1, 1, 1, 1, 'Bands of Mutual Respect'), +(34142, 40325, 0, 0, 0, 1, 1, 1, 1, 'Bindings of the Expansive Mind'), +(34142, 40326, 0, 0, 0, 1, 1, 1, 1, 'Boots of Forlorn Wishes'), +(34142, 40327, 0, 0, 0, 1, 1, 1, 1, 'Girdle of Recuperation'), +(34142, 40328, 0, 0, 0, 1, 1, 1, 1, 'Helm of Vital Protection'), +(34142, 40329, 0, 0, 0, 1, 1, 1, 1, 'Hood of the Exodus'), +(34142, 40330, 0, 0, 0, 1, 1, 1, 1, 'Bracers of Unrelenting Attack'), +(34142, 40331, 0, 0, 0, 1, 1, 1, 1, 'Leggings of Failed Escape'), +(34142, 40332, 0, 0, 0, 1, 1, 1, 1, 'Abetment Bracers'), +(34142, 40333, 0, 0, 0, 1, 1, 1, 1, 'Leggings of Fleeting Moments'), +(34142, 40334, 0, 0, 0, 1, 1, 1, 1, 'Burdened Shoulderplates'), +(34142, 40335, 0, 0, 0, 1, 1, 1, 1, 'Touch of Horror'), +(34142, 40336, 0, 0, 0, 1, 1, 1, 1, 'Life and Death'), +(34142, 40337, 0, 0, 0, 1, 1, 1, 1, 'Libram of Resurgence'), +(34142, 40338, 0, 0, 0, 1, 1, 1, 1, 'Bindings of Yearning'), +(34142, 40339, 0, 0, 0, 1, 1, 1, 1, 'Gothik\'s Cowl'), +(34142, 40340, 0, 0, 0, 1, 1, 1, 1, 'Helm of Unleashed Energy'), +(34142, 40341, 0, 0, 0, 1, 1, 1, 1, 'Shackled Cinch'), +(34142, 40342, 0, 0, 0, 1, 1, 1, 1, 'Idol of Awakening'), +(34142, 40286, 0, 0, 0, 1, 1, 1, 1, 'Mantle of the Corrupted'), +(34142, 40343, 0, 0, 0, 1, 1, 1, 1, 'Armageddon'), +(34142, 40344, 0, 0, 0, 1, 1, 1, 1, 'Helm of the Grave'), +(34142, 40345, 0, 0, 0, 1, 1, 1, 1, 'Broken Promise'), +(34142, 40346, 0, 0, 0, 1, 1, 1, 1, 'Final Voyage'), +(34142, 40347, 0, 0, 0, 1, 1, 1, 1, 'Zeliek\'s Gauntlets'), +(34142, 40348, 0, 0, 0, 1, 1, 1, 1, 'Damnation'), +(34142, 40349, 0, 0, 0, 1, 1, 1, 1, 'Gloves of Peaceful Death'), +(34142, 40350, 0, 0, 0, 1, 1, 1, 1, 'Urn of Lost Memories'), +(34142, 40352, 0, 0, 0, 1, 1, 1, 1, 'Leggings of Voracious Shadows'), +(34142, 40184, 0, 0, 0, 1, 1, 1, 1, 'Crippled Treads'), +(34142, 40185, 0, 0, 0, 1, 1, 1, 1, 'Shoulderguards of Opportunity'), +(34142, 40186, 0, 0, 0, 1, 1, 1, 1, 'Thrusting Bands'), +(34142, 40187, 0, 0, 0, 1, 1, 1, 1, 'Poignant Sabatons'), +(34142, 40188, 0, 0, 0, 1, 1, 1, 1, 'Gauntlets of the Disobedient'), +(34142, 40189, 0, 0, 0, 1, 1, 1, 1, 'Angry Dread'), +(34142, 40190, 0, 0, 0, 1, 1, 1, 1, 'Spinning Fate'), +(34142, 40191, 0, 0, 0, 1, 1, 1, 1, 'Libram of Radiance'), +(34142, 40192, 0, 0, 0, 1, 1, 1, 1, 'Accursed Spine'), +(34142, 40193, 0, 0, 0, 1, 1, 1, 1, 'Tunic of Masked Suffering'), +(34142, 40196, 0, 0, 0, 1, 1, 1, 1, 'Legguards of the Undisturbed'), +(34142, 40197, 0, 0, 0, 1, 1, 1, 1, 'Gloves of the Fallen Wizard'), +(34142, 40198, 0, 0, 0, 1, 1, 1, 1, 'Bands of Impurity'), +(34142, 40200, 0, 0, 0, 1, 1, 1, 1, 'Belt of Potent Chanting'), +(34142, 40602, 0, 0, 0, 1, 1, 1, 1, 'Robes of Mutation'), +(34142, 40201, 0, 0, 0, 1, 1, 1, 1, 'Leggings of Colossal Strides'), +(34142, 40203, 0, 0, 0, 1, 1, 1, 1, 'Breastplate of Tormented Rage'), +(34142, 40204, 0, 0, 0, 1, 1, 1, 1, 'Legguards of the Apostle'), +(34142, 40205, 0, 0, 0, 1, 1, 1, 1, 'Stalk-Skin Belt'), +(34142, 40206, 0, 0, 0, 1, 1, 1, 1, 'Iron-Spring Jumpers'), +(34142, 40207, 0, 0, 0, 1, 1, 1, 1, 'Sigil of Awareness'), +(34142, 40208, 0, 0, 0, 1, 1, 1, 1, 'Cryptfiend\'s Bite'), +(34142, 40209, 0, 0, 0, 1, 1, 1, 1, 'Bindings of the Decrepit'), +(34142, 40210, 0, 0, 0, 1, 1, 1, 1, 'Chestguard of Bitter Charms'), +(34142, 40233, 0, 0, 0, 1, 1, 1, 1, 'The Undeath Carrier'), +(34142, 40234, 0, 0, 0, 1, 1, 1, 1, 'Heigan\'s Putrid Vestments'), +(34142, 40235, 0, 0, 0, 1, 1, 1, 1, 'Helm of Pilgrimage'), +(34142, 40236, 0, 0, 0, 1, 1, 1, 1, 'Serene Echoes'), +(34142, 40237, 0, 0, 0, 1, 1, 1, 1, 'Eruption-Scarred Boots'), +(34142, 40238, 0, 0, 0, 1, 1, 1, 1, 'Gloves of the Dancing Bear'), +(34142, 40239, 0, 0, 0, 1, 1, 1, 1, 'The Hand of Nerub'), +(34142, 40240, 0, 0, 0, 1, 1, 1, 1, 'Greaves of Turbulence'), +(34142, 40241, 0, 0, 0, 1, 1, 1, 1, 'Girdle of Unity'), +(34142, 40242, 0, 0, 0, 1, 1, 1, 1, 'Grotesque Handgrips'), +(34142, 40243, 0, 0, 0, 1, 1, 1, 1, 'Footwraps of Vile Deceit'), +(34142, 40244, 0, 0, 0, 1, 1, 1, 1, 'The Impossible Dream'), +(34142, 40245, 0, 0, 0, 1, 1, 1, 1, 'Fading Glow'), +(34142, 40246, 0, 0, 0, 1, 1, 1, 1, 'Boots of Impetuous Ideals'), +(34142, 40247, 0, 0, 0, 1, 1, 1, 1, 'Cowl of Innocent Delight'), +(34142, 40249, 0, 0, 0, 1, 1, 1, 1, 'Vest of Vitality'); +-- (34142, 40406, 0, 0, 0, 1, 1, 1, 1, 'Inevitable Defeat'), +-- (34142, 40407, 0, 0, 0, 1, 1, 1, 1, 'Silent Crusader'), +-- (34142, 40408, 0, 0, 0, 1, 1, 1, 1, 'Haunting Call'), +-- (34142, 40409, 0, 0, 0, 1, 1, 1, 1, 'Boots of the Escaped Captive'), +-- (34142, 40410, 0, 0, 0, 1, 1, 1, 1, 'Shadow of the Ghoul'), +-- (34142, 40412, 0, 0, 0, 1, 1, 1, 1, 'Ousted Bead Necklace'), +-- (34142, 40414, 0, 0, 0, 1, 1, 1, 1, 'Shoulderguards of the Undaunted'); From 9df01c67fab44a162dfef4da175814ab350714ec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 26 Feb 2026 18:58:23 +0000 Subject: [PATCH 317/335] chore(DB): import pending files Referenced commit(s): 76ec5e39a0bb3b75b779501a854c83e8e669cab2 --- .../rev_1771283323680167400.sql => db_world/2026_02_26_05.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771283323680167400.sql => db_world/2026_02_26_05.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771283323680167400.sql b/data/sql/updates/db_world/2026_02_26_05.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771283323680167400.sql rename to data/sql/updates/db_world/2026_02_26_05.sql index aa3c47b12..fccdc9d88 100644 --- a/data/sql/updates/pending_db_world/rev_1771283323680167400.sql +++ b/data/sql/updates/db_world/2026_02_26_05.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_26_04 -> 2026_02_26_05 -- Gluth DELETE FROM `creature_loot_template` WHERE (`Entry` = 15932) AND `GroupId` = 2; INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES From 22dd44f4d1e6713bff0e712c6952c7e0c68ae9ab Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 26 Feb 2026 16:36:23 -0600 Subject: [PATCH 318/335] fix(Core/Scripts): Remove duplicate spell scripts causing double-firing (#24905) Co-authored-by: blinkysc --- .../rev_1772139853408206022.sql | 8 +++ .../boss_deathbringer_saurfang.cpp | 43 ---------------- .../IcecrownCitadel/icecrown_citadel.cpp | 22 --------- .../BlackTemple/instance_black_temple.cpp | 24 --------- src/server/scripts/Spells/spell_item.cpp | 26 ---------- src/server/scripts/Spells/spell_paladin.cpp | 28 ----------- src/server/scripts/Spells/spell_priest.cpp | 33 ------------- src/server/scripts/Spells/spell_warlock.cpp | 49 ------------------- 8 files changed, 8 insertions(+), 225 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1772139853408206022.sql diff --git a/data/sql/updates/pending_db_world/rev_1772139853408206022.sql b/data/sql/updates/pending_db_world/rev_1772139853408206022.sql new file mode 100644 index 000000000..7d076608d --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772139853408206022.sql @@ -0,0 +1,8 @@ +-- Remove duplicate spell scripts that caused handlers to fire twice +DELETE FROM `spell_script_names` WHERE `spell_id` = 54937 AND `ScriptName` = 'spell_pal_glyph_of_holy_light_proc'; +DELETE FROM `spell_script_names` WHERE `spell_id` = 41404 AND `ScriptName` = 'spell_black_temple_dementia_aura'; +DELETE FROM `spell_script_names` WHERE `spell_id` = 64440 AND `ScriptName` = 'spell_item_blade_ward_enchant'; +DELETE FROM `spell_script_names` WHERE `spell_id` = 37594 AND `ScriptName` = 'spell_pri_item_greater_heal_refund'; +DELETE FROM `spell_script_names` WHERE `spell_id` = 69483 AND `ScriptName` = 'spell_icc_dark_reckoning_aura'; +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_warl_demonic_pact_aura'; +DELETE FROM `spell_script_names` WHERE `spell_id` = 72176 AND `ScriptName` = 'spell_deathbringer_blood_link_blood_beast_aura'; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index ded579444..ad895c564 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -1096,48 +1096,6 @@ class spell_deathbringer_blood_link_aura : public AuraScript } }; -class spell_deathbringer_blood_link_blood_beast_aura : public AuraScript -{ - PrepareAuraScript(spell_deathbringer_blood_link_blood_beast_aura); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_BLOOD_LINK_DUMMY }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - SpellInfo const* procSpell = eventInfo.GetSpellInfo(); - return eventInfo.GetActor() && eventInfo.GetActionTarget() && ((damageInfo && damageInfo->GetDamage()) || eventInfo.GetHitMask() & PROC_EX_ABSORB) && (!procSpell || procSpell->SpellIconID != 2731); // Xinef: Mark of the Fallen Champion - } - - void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - /* - uint32 markCount = 0; - if (Map* map = eventInfo.GetActor()->FindMap()) - if (InstanceMap* imap = map->ToInstanceMap()) - if (InstanceScript* isc = imap->GetInstanceScript()) - if (ObjectGuid sguid = isc->GetGuidData(3) //DATA_DEATHBRINGER_SAURFANG - if (Creature* saurfang = ObjectAccessor::GetCreature(*eventInfo.GetActor(), sguid)) - markCount = saurfang->IsAIEnabled ? saurfang->AI()->GetData(123456) : 0; //FALLEN_CHAMPION_CAST_COUNT - */ - int32 basepoints = int32(3.0f /*+ 0.5f + 0.5f*markCount*/); - - eventInfo.GetActor()->CastCustomSpell(SPELL_BLOOD_LINK_DUMMY, SPELLVALUE_BASE_POINT0, basepoints, eventInfo.GetActionTarget(), true); - return; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_deathbringer_blood_link_blood_beast_aura::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_deathbringer_blood_link_blood_beast_aura::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - class spell_deathbringer_blood_link : public SpellScript { PrepareSpellScript(spell_deathbringer_blood_link); @@ -1371,7 +1329,6 @@ void AddSC_boss_deathbringer_saurfang() new npc_muradin_bronzebeard_icc(); new npc_saurfang_event(); RegisterSpellScript(spell_deathbringer_blood_link_aura); - RegisterSpellScript(spell_deathbringer_blood_link_blood_beast_aura); RegisterSpellScript(spell_deathbringer_blood_beast_blood_link); RegisterSpellScript(spell_deathbringer_blood_link); RegisterSpellAndAuraScriptPair(spell_deathbringer_blood_power, spell_deathbringer_blood_power_aura); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 8254ed5ef..1c1743841 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -2295,27 +2295,6 @@ class spell_icc_web_wrap_aura : public AuraScript } }; -class spell_icc_dark_reckoning_aura : public AuraScript -{ - PrepareAuraScript(spell_icc_dark_reckoning_aura); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ 69482 }); - } - - void OnPeriodic(AuraEffect const* /*aurEff*/) - { - if (Unit* caster = GetCaster()) - caster->CastSpell(GetTarget(), 69482, true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_icc_dark_reckoning_aura::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } -}; - class spell_stinky_precious_decimate : public SpellScript { PrepareSpellScript(spell_stinky_precious_decimate); @@ -3681,7 +3660,6 @@ void AddSC_icecrown_citadel() // pussywizard below: RegisterSpellScript(spell_icc_web_wrap_aura); - RegisterSpellScript(spell_icc_dark_reckoning_aura); RegisterSpellScript(spell_stinky_precious_decimate); RegisterSpellScript(spell_icc_yf_frozen_orb_aura); RegisterSpellScript(spell_icc_yh_volley_aura); diff --git a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp index bbf157a1f..5d971da18 100644 --- a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp +++ b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp @@ -446,29 +446,6 @@ class spell_black_temple_curse_of_vitality_aura : public AuraScript } }; -class spell_black_temple_dementia_aura : public AuraScript -{ - PrepareAuraScript(spell_black_temple_dementia_aura); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DEMENTIA1, SPELL_DEMENTIA2 }); - } - - void OnPeriodic(AuraEffect const* /*aurEff*/) - { - if (roll_chance_i(50)) - GetTarget()->CastSpell(GetTarget(), SPELL_DEMENTIA1, true); - else - GetTarget()->CastSpell(GetTarget(), SPELL_DEMENTIA2, true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_black_temple_dementia_aura::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } -}; - // 39649 - Summon Shadowfiends class spell_black_temple_summon_shadowfiends : public SpellScript { @@ -525,7 +502,6 @@ void AddSC_instance_black_temple() RegisterSpellScript(spell_black_temple_bloodbolt); RegisterSpellScript(spell_black_temple_consuming_strikes_aura); RegisterSpellScript(spell_black_temple_curse_of_vitality_aura); - RegisterSpellScript(spell_black_temple_dementia_aura); RegisterSpellScript(spell_black_temple_summon_shadowfiends); RegisterSpellScript(spell_black_temple_l5_arcane_charge); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 0fd4e999a..a9a430cf1 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -1206,31 +1206,6 @@ class spell_item_trauma : public AuraScript } }; -class spell_item_blade_ward_enchant : public AuraScript -{ - PrepareAuraScript(spell_item_blade_ward_enchant); - - void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - if (!eventInfo.GetActionTarget()) - { - return; - } - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(64442 /*SPELL_BLADE_WARDING*/)) - { - int32 basepoints = spellInfo->Effects[EFFECT_0].CalcValue() * this->GetStackAmount(); - eventInfo.GetActionTarget()->CastCustomSpell(spellInfo->Id, SPELLVALUE_BASE_POINT0, basepoints, eventInfo.GetActor(), true); - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_blade_ward_enchant::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - class spell_item_blood_draining_enchant : public AuraScript { PrepareAuraScript(spell_item_blood_draining_enchant); @@ -6236,7 +6211,6 @@ void AddSC_item_spell_scripts() RegisterSpellScript(spell_item_fetch_ball); RegisterSpellScript(spell_item_oracle_ablutions); RegisterSpellScript(spell_item_trauma); - RegisterSpellScript(spell_item_blade_ward_enchant); RegisterSpellScript(spell_item_blood_draining_enchant); RegisterSpellScript(spell_item_dragon_kite_summon_lightning_bunny); RegisterSpellScript(spell_item_enchanted_broom_periodic); diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 8b9dc5c44..a9f8ebfe1 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -1404,33 +1404,6 @@ class spell_pal_spiritual_attunement : public AuraScript } }; -// 54937 - Glyph of Holy Light (proc trigger) -class spell_pal_glyph_of_holy_light_proc : public AuraScript -{ - PrepareAuraScript(spell_pal_glyph_of_holy_light_proc); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PALADIN_GLYPH_OF_HOLY_LIGHT_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - HealInfo* healInfo = eventInfo.GetHealInfo(); - if (!healInfo || !healInfo->GetHeal()) - return; - - int32 bp = CalculatePct(int32(healInfo->GetHeal()), aurEff->GetAmount()); - GetTarget()->CastCustomSpell(SPELL_PALADIN_GLYPH_OF_HOLY_LIGHT_HEAL, SPELLVALUE_BASE_POINT0, bp, eventInfo.GetActionTarget(), true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_glyph_of_holy_light_proc::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - // 1022 - Hand of Protection class spell_pal_hand_of_protection : public SpellScript { @@ -2209,7 +2182,6 @@ void AddSC_paladin_spell_scripts() RegisterSpellScript(spell_pal_judgement_of_light_heal); RegisterSpellScript(spell_pal_judgement_of_wisdom_mana); RegisterSpellScript(spell_pal_spiritual_attunement); - RegisterSpellScript(spell_pal_glyph_of_holy_light_proc); RegisterSpellScript(spell_pal_t3_6p_bonus); RegisterSpellScript(spell_pal_t8_2p_bonus); RegisterSpellScript(spell_pal_glyph_of_divinity); diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index a5df31868..223a5d52a 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -360,38 +360,6 @@ class spell_pri_hymn_of_hope : public SpellScript } }; -// 37594 - Greater Heal Refund -class spell_pri_item_greater_heal_refund : public AuraScript -{ - PrepareAuraScript(spell_pri_item_greater_heal_refund); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PRIEST_ITEM_EFFICIENCY }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (HealInfo* healInfo = eventInfo.GetHealInfo()) - if (Unit* healTarget = healInfo->GetTarget()) - if (eventInfo.GetHitMask() & PROC_EX_NO_OVERHEAL && healTarget->IsFullHealth()) - return true; - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), SPELL_PRIEST_ITEM_EFFICIENCY, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pri_item_greater_heal_refund::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_pri_item_greater_heal_refund::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - // 60123 - Lightwell class spell_pri_lightwell : public SpellScript { @@ -1448,7 +1416,6 @@ void AddSC_priest_spell_scripts() RegisterSpellScript(spell_pri_glyph_of_prayer_of_healing); RegisterSpellScript(spell_pri_guardian_spirit); RegisterSpellScript(spell_pri_hymn_of_hope); - RegisterSpellScript(spell_pri_item_greater_heal_refund); RegisterSpellScript(spell_pri_lightwell); RegisterSpellScript(spell_pri_lightwell_renew); RegisterSpellScript(spell_pri_mana_burn); diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 95c2929a3..b7b09b350 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -1306,54 +1306,6 @@ class spell_warl_voidwalker_pet_passive : public AuraScript } }; -// 54909, 53646 - Demonic Pact -class spell_warl_demonic_pact_aura : public AuraScript -{ - PrepareAuraScript(spell_warl_demonic_pact_aura); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARLOCK_DEMONIC_PACT_PROC }); - } - - bool AfterCheckProc(ProcEventInfo& eventInfo, bool isTriggeredAtSpellProcEvent) - { - return isTriggeredAtSpellProcEvent && eventInfo.GetActor() && eventInfo.GetActor()->IsPet(); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - if (eventInfo.GetActor()->HasSpellCooldown(aurEff->GetId())) - return; - - if (Unit* owner = eventInfo.GetActor()->GetOwner()) - { - int32 currentBonus = 0; - if (AuraEffect* demonicAurEff = owner->GetAuraEffect(SPELL_WARLOCK_DEMONIC_PACT_PROC, EFFECT_0)) - { - currentBonus = demonicAurEff->GetAmount(); - } - - if (AuraEffect* talentAurEff = owner->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, WARLOCK_ICON_ID_DEMONIC_PACT, EFFECT_0)) - { - int32 spellDamageMinusBonus = owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_MAGIC) - currentBonus; - if (spellDamageMinusBonus < 0) - return; - int32 bp = int32((talentAurEff->GetAmount() / 100.0f) * spellDamageMinusBonus); - owner->CastCustomSpell((Unit*)nullptr, SPELL_WARLOCK_DEMONIC_PACT_PROC, &bp, &bp, 0, true, nullptr, talentAurEff); - eventInfo.GetActor()->AddSpellCooldown(aurEff->GetId(), 0, eventInfo.GetProcCooldown()); - } - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_warl_demonic_pact_aura::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - // -980 - Curse of Agony class spell_warl_curse_of_agony : public AuraScript { @@ -1861,7 +1813,6 @@ void AddSC_warlock_spell_scripts() RegisterSpellScript(spell_warl_drain_soul); RegisterSpellScript(spell_warl_shadowburn); RegisterSpellScript(spell_warl_voidwalker_pet_passive); - RegisterSpellScript(spell_warl_demonic_pact_aura); RegisterSpellScript(spell_warl_curse_of_agony); RegisterSpellScript(spell_warl_glyph_of_corruption_nightfall); RegisterSpellScript(spell_warl_nightfall); From 5adb7e07e81ad757abd78fb217188c3580cbf292 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 26 Feb 2026 22:37:31 +0000 Subject: [PATCH 319/335] chore(DB): import pending files Referenced commit(s): 22dd44f4d1e6713bff0e712c6952c7e0c68ae9ab --- .../rev_1772139853408206022.sql => db_world/2026_02_26_06.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772139853408206022.sql => db_world/2026_02_26_06.sql} (95%) diff --git a/data/sql/updates/pending_db_world/rev_1772139853408206022.sql b/data/sql/updates/db_world/2026_02_26_06.sql similarity index 95% rename from data/sql/updates/pending_db_world/rev_1772139853408206022.sql rename to data/sql/updates/db_world/2026_02_26_06.sql index 7d076608d..8108b3dbd 100644 --- a/data/sql/updates/pending_db_world/rev_1772139853408206022.sql +++ b/data/sql/updates/db_world/2026_02_26_06.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_26_05 -> 2026_02_26_06 -- Remove duplicate spell scripts that caused handlers to fire twice DELETE FROM `spell_script_names` WHERE `spell_id` = 54937 AND `ScriptName` = 'spell_pal_glyph_of_holy_light_proc'; DELETE FROM `spell_script_names` WHERE `spell_id` = 41404 AND `ScriptName` = 'spell_black_temple_dementia_aura'; From 424f97208a04546a3f83bfe0a287b1c35a89287f Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Thu, 26 Feb 2026 18:52:50 -0600 Subject: [PATCH 320/335] fix(Core/Spells): Allow Mutilate offhand to proc Focused Attacks (#24907) --- .../rev_1772144945706318839.sql | 7 ++++++ src/server/scripts/Spells/spell_rogue.cpp | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772144945706318839.sql diff --git a/data/sql/updates/pending_db_world/rev_1772144945706318839.sql b/data/sql/updates/pending_db_world/rev_1772144945706318839.sql new file mode 100644 index 000000000..f243d2ffe --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772144945706318839.sql @@ -0,0 +1,7 @@ +-- Replace generic no-offhand-proc with Focused Attacks-specific script +-- that only blocks Fan of Knives offhand from proccing, allowing Mutilate +-- offhand and other offhand attacks to proc normally +DELETE FROM `spell_script_names` WHERE `spell_id` = -51634 AND `ScriptName` = 'spell_gen_no_offhand_proc'; +DELETE FROM `spell_script_names` WHERE `spell_id` = -51634 AND `ScriptName` = 'spell_rog_focused_attacks'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-51634, 'spell_rog_focused_attacks'); diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 832ec5c35..a234dbb5d 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -1062,6 +1062,30 @@ class spell_rog_turn_the_tables_proc : public SpellScript } }; +// -51634 - Focused Attacks +// Block Fan of Knives offhand from proccing +class spell_rog_focused_attacks : public AuraScript +{ + PrepareAuraScript(spell_rog_focused_attacks); + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Block Fan of Knives offhand (0x40000) from proccing + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE + && (spellInfo->SpellFamilyFlags[1] & 0x40000) + && (eventInfo.GetTypeMask() & PROC_FLAG_DONE_OFFHAND_ATTACK)) + return false; + + return true; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_rog_focused_attacks::CheckProc); + } +}; + void AddSC_rogue_spell_scripts() { RegisterSpellScript(spell_rog_savage_combat); @@ -1092,4 +1116,5 @@ void AddSC_rogue_spell_scripts() RegisterSpellAndAuraScriptPair(spell_rog_honor_among_thieves_proc, spell_rog_honor_among_thieves_proc_aura); RegisterSpellScript(spell_rog_turn_the_tables); RegisterSpellScript(spell_rog_turn_the_tables_proc); + RegisterSpellScript(spell_rog_focused_attacks); } From 672d44b862acd9086c295061cffba662633fbd84 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 27 Feb 2026 00:54:04 +0000 Subject: [PATCH 321/335] chore(DB): import pending files Referenced commit(s): 424f97208a04546a3f83bfe0a287b1c35a89287f --- .../rev_1772144945706318839.sql => db_world/2026_02_27_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772144945706318839.sql => db_world/2026_02_27_00.sql} (92%) diff --git a/data/sql/updates/pending_db_world/rev_1772144945706318839.sql b/data/sql/updates/db_world/2026_02_27_00.sql similarity index 92% rename from data/sql/updates/pending_db_world/rev_1772144945706318839.sql rename to data/sql/updates/db_world/2026_02_27_00.sql index f243d2ffe..dcc7aef2a 100644 --- a/data/sql/updates/pending_db_world/rev_1772144945706318839.sql +++ b/data/sql/updates/db_world/2026_02_27_00.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_26_06 -> 2026_02_27_00 -- Replace generic no-offhand-proc with Focused Attacks-specific script -- that only blocks Fan of Knives offhand from proccing, allowing Mutilate -- offhand and other offhand attacks to proc normally From 9f79d53b6634f28e79ffe427a2e58754be70595a Mon Sep 17 00:00:00 2001 From: sudlud Date: Fri, 27 Feb 2026 13:33:09 +0100 Subject: [PATCH 322/335] =?UTF-8?q?fix(DB/Creature):=20Sniffed=20Values=20?= =?UTF-8?q?for=20'Day=20of=20the=20Dead=20Celebrants=20and=20=E2=80=A6=20(?= =?UTF-8?q?#24856)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rev_1771915997105053200.sql | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1771915997105053200.sql diff --git a/data/sql/updates/pending_db_world/rev_1771915997105053200.sql b/data/sql/updates/pending_db_world/rev_1771915997105053200.sql new file mode 100644 index 000000000..cab89e1ec --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1771915997105053200.sql @@ -0,0 +1,146 @@ +-- Update creature 'Day of the Dead Celebrants and Spirits' with sniffed values +-- updated spawns +DELETE FROM `creature` WHERE (`id1` IN (35250, 34479, 35243, 35249, 35253, 35251, 34483, 34482, 34435, 34477, 35256, 35254, 35244, 34476, 34480, 35252, 34484, 35246, 35260, 35261, 35258, 35259, 34481, 34478, 35247, 35248)) AND (`guid` IN (240194, 240195, 240196, 240197, 240198, 240199, 240200, 240201, 240202, 240203, 240204, 240205, 240206, 240207, 240208, 240209, 240210, 240211, 240212, 240213, 240214, 240215, 240216, 240217, 240218, 240219, 240220, 240221, 240222, 240223, 240224, 240225, 240230, 240231, 240232, 240233, 240234, 240235, 240236, 240237, 240238, 240239, 240240, 240242, 240243, 240244, 240245, 240246, 240247, 240248, 240249, 240250, 240267, 240268, 240269, 240270, 240271, 240272, 240273, 240274, 240275, 240276, 240277, 240278, 240279, 240280, 240281, 240282, 240283, 240284, 240285, 240286, 240287, 240288, 240289, 240290, 240291, 240292, 240293, 240294, 240295, 240296, 240297, 240298, 240299, 240300, 240301, 240302, 240339, 240340)); +INSERT INTO `creature` (`guid`, `id1`, `map`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(240194, 35250, 1, 1, 1, 0, 10043.6669921875, 2113.713623046875, 1329.7412109375, 1.274090290069580078, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240195, 35250, 1, 1, 1, 0, 10051.814453125, 2133.114501953125, 1329.7408447265625, 3.490658521652221679, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240196, 35250, 1, 1, 1, 0, 10045.91015625, 2116.8681640625, 1329.798828125, 3.909537553787231445, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240197, 35250, 1, 1, 1, 0, 10055.6962890625, 2118.001708984375, 1329.921630859375, 0.663225114345550537, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240198, 35250, 1, 1, 1, 0, 10059.9599609375, 2132.404541015625, 1329.7412109375, 3.839724302291870117, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240199, 35250, 1, 1, 1, 0, 10055.529296875, 2123.998291015625, 1329.8065185546875, 1.274090290069580078, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240200, 35250, 1, 1, 1, 0, 10051.5224609375, 2114.09375, 1329.7943115234375, 1.29154360294342041, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240201, 34479, 1, 1, 1, 0, 10055.2470703125, 2133.329833984375, 1329.7412109375, 3.159045934677124023, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240202, 35243, 530, 1, 1, 0, 9403.03515625, -6833.92529296875, 16.70704078674316406, 0.541052043437957763, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240203, 35243, 530, 1, 1, 0, 9406.4033203125, -6845.60791015625, 16.06168174743652343, 3.996803998947143554, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240204, 35243, 530, 1, 1, 0, 9407.63671875, -6826.66650390625, 17.45138931274414062, 4.450589656829833984, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240205, 35243, 530, 1, 1, 0, 9409.37109375, -6860.70654296875, 14.8249359130859375, 1.640609502792358398, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240206, 35249, 0, 1, 1, 0, -9349.6611328125, 175.8524322509765625, 61.64120864868164062, 0.48869219422340393, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240207, 35253, 1, 1, 1, 0, 1174.734375, -4465.51416015625, 21.36942481994628906, 1.745329260826110839, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240208, 35253, 1, 1, 1, 0, 1181.6041259765625, -4467.734375, 21.3765869140625, 3.787364482879638671, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240209, 35253, 1, 1, 1, 0, 1181.796875, -4458.68408203125, 21.44613838195800781, 1.832595705986022949, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240210, 35253, 1, 1, 1, 0, 1175.84375, -4458.7900390625, 21.59824943542480468, 1.064650893211364746, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240211, 35251, 1, 1, 1, 0, 1170.4478759765625, -4461.51025390625, 21.47426605224609375, 6.17846536636352539, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240212, 35251, 1, 1, 1, 0, 1172.79345703125, -4455.80908203125, 21.683502197265625, 0.069813169538974761, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240213, 34483, 530, 1, 1, 0, 9417.505859375, -6851.2099609375, 15.09478092193603515, 3.420845270156860351, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240214, 35243, 530, 1, 1, 0, 9406.1298828125, -6857.921875, 15.11687183380126953, 0.226892799139022827, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240215, 35243, 530, 1, 1, 0, 9403.6708984375, -6849.658203125, 15.91330623626708984, 1.169370532035827636, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240216, 35249, 0, 1, 1, 0, -9328.5595703125, 163.611114501953125, 61.89540481567382812, 2.548180580139160156, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240217, 35249, 0, 1, 1, 0, -9332.03515625, 170.70660400390625, 61.70401382446289062, 1.308996915817260742, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240218, 35249, 0, 1, 1, 0, -9336.9580078125, 174.185760498046875, 61.64844512939453125, 0.733038306236267089, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240219, 35249, 0, 1, 1, 0, -9328.5556640625, 185.888885498046875, 62.81067657470703125, 4.206243515014648437, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240220, 35249, 0, 1, 1, 0, -9324.376953125, 176.2569427490234375, 61.75640869140625, 4.363323211669921875, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240221, 35249, 0, 1, 1, 0, -9321.2939453125, 172.7256927490234375, 61.70332717895507812, 4.066617012023925781, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240222, 35249, 0, 1, 1, 0, -9346.34375, 177.373260498046875, 61.64120864868164062, 3.560471534729003906, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240223, 35249, 0, 1, 1, 0, -9343.953125, 186.0885467529296875, 61.64120864868164062, 4.939281940460205078, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240224, 35249, 0, 1, 1, 0, -9348.5625, 171.079864501953125, 61.64120864868164062, 4.15388345718383789, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240225, 35249, 0, 1, 1, 0, -9325.70703125, 167.404510498046875, 61.66920089721679687, 2.94960641860961914, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240230, 34482, 1, 1, 1, 0, 1178.8629150390625, -4471.86962890625, 21.17310333251953125, 1.378810048103332519, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240231, 34435, 0, 1, 1, 0, -9338.0263671875, 186.1354217529296875, 61.62332534790039062, 4.206243515014648437, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240232, 34477, 1, 1, 1, 0, 1186.829833984375, -4472.38720703125, 21.49950408935546875, 1.692969322204589843, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240233, 35256, 571, 1, 1, 0, 5855.5380859375, 766.54864501953125, 641.56671142578125, 3.787364482879638671, 120, 0, 0, 0, 0, 0, "", 46368, 1, NULL), +(240234, 35254, 571, 1, 1, 0, 5850.15283203125, 769.9913330078125, 640.817626953125, 3.106686115264892578, 120, 0, 0, 0, 0, 0, "", 46368, 1, NULL), +(240235, 35254, 571, 1, 1, 0, 5847.70751953125, 772.88543701171875, 640.46234130859375, 4.939281940460205078, 120, 0, 0, 0, 0, 0, "", 46368, 1, NULL), +(240236, 35254, 571, 1, 1, 0, 5850.7265625, 774.95831298828125, 640.53619384765625, 4.590215682983398437, 120, 0, 0, 0, 0, 0, "", 46368, 1, NULL), +(240237, 35254, 571, 1, 1, 0, 5854.5625, 769.9375, 641.3104248046875, 4.15388345718383789, 120, 0, 0, 0, 0, 0, "", 46368, 1, NULL), +(240238, 35254, 571, 1, 1, 0, 5854.24462890625, 762.48089599609375, 641.18548583984375, 3.31612563133239746, 120, 0, 0, 0, 0, 0, "", 46368, 1, NULL), +(240239, 35254, 571, 1, 1, 0, 5848.58056640625, 770.54339599609375, 640.6075439453125, 5.445427417755126953, 120, 0, 0, 0, 0, 0, "", 46368, 1, NULL), +(240240, 35254, 571, 1, 1, 0, 5858.05126953125, 763.140625, 640.97076416015625, 2.548180580139160156, 120, 0, 0, 0, 0, 0, "", 46368, 1, NULL), +(240242, 35254, 571, 1, 1, 0, 5860.416015625, 765.40802001953125, 640.8057861328125, 4.066617012023925781, 120, 0, 0, 0, 0, 0, "", 46368, 1, NULL), +(240243, 35254, 571, 1, 1, 0, 5856.31591796875, 764, 641.2667236328125, 6.038839340209960937, 120, 0, 0, 0, 0, 0, "", 46368, 1, NULL), +(240244, 35244, 0, 1, 1, 0, 1831.29345703125, 213.154510498046875, 60.45892333984375, 3.647738218307495117, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240245, 35244, 0, 1, 1, 0, 1830.107666015625, 221.470489501953125, 60.79235076904296875, 2.635447263717651367, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240246, 35244, 0, 1, 1, 0, 1824.79345703125, 210.56597900390625, 60.20412826538085937, 0.226892799139022827, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240247, 35244, 0, 1, 1, 0, 1835.3680419921875, 257.9600830078125, 59.87485122680664062, 4.049163818359375, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240248, 35244, 0, 1, 1, 0, 1833.7899169921875, 247.517364501953125, 59.9253387451171875, 2.0245819091796875, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240249, 35244, 0, 1, 1, 0, 1820.8680419921875, 261.94964599609375, 60.06829833984375, 0.104719758033752441, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240250, 34476, 0, 1, 1, 0, 1778.5364990234375, 218.2413177490234375, 59.76784896850585937, 1.082104086875915527, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240267, 34480, 1, 1, 1, 0, -979.08856201171875, -79.9652786254882812, 19.96615791320800781, 1.064650893211364746, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240268, 35252, 1, 1, 1, 0, -978.95660400390625, -65.2430572509765625, 21.8000946044921875, 0.453785598278045654, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240269, 35252, 1, 1, 1, 0, -983.6180419921875, -74.5416641235351562, 20.65581512451171875, 0.366519153118133544, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240270, 35252, 1, 1, 1, 0, -974.638916015625, -84.0590286254882812, 20.59402084350585937, 1.274090290069580078, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240271, 35252, 1, 1, 1, 0, -976.685791015625, -67.859375, 19.32087326049804687, 3.996803998947143554, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240272, 35252, 1, 1, 1, 0, -981.70831298828125, -76.1371536254882812, 20.18576431274414062, 4.066617012023925781, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240273, 34484, 530, 1, 1, 0, -4307.6318359375, -12420.607421875, 17.64993476867675781, 4.921828269958496093, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240274, 35246, 530, 1, 1, 0, -4324.26416015625, -12444.34375, 17.27714729309082031, 4.398229598999023437, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240275, 35246, 530, 1, 1, 0, -4322.69970703125, -12456.544921875, 17.44094657897949218, 6.0737457275390625, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240276, 35246, 530, 1, 1, 0, -4320.296875, -12438.9267578125, 17.69791793823242187, 5.410520553588867187, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240277, 35246, 530, 1, 1, 0, -4322.423828125, -12449.6181640625, 16.97788047790527343, 6.2657318115234375, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240278, 35246, 530, 1, 1, 0, -4308.39404296875, -12429.40625, 17.04607200622558593, 4.206243515014648437, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240279, 35246, 530, 1, 1, 0, -4312.236328125, -12434.603515625, 17.15652656555175781, 3.31612563133239746, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240280, 35246, 530, 1, 1, 0, -4314.046875, -12441.451171875, 17.30897712707519531, 4.537856101989746093, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240281, 35246, 530, 1, 1, 0, -4314.90625, -12430.2880859375, 17.558502197265625, 3.438298702239990234, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240282, 35260, 530, 1, 1, 0, -1784.904541015625, 4934.78662109375, -22.4792404174804687, 3.543018341064453125, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240283, 35261, 530, 1, 1, 0, -1801.1197509765625, 4913.8818359375, -21.8948688507080078, 2.268928050994873046, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240284, 35258, 530, 1, 1, 0, -1781.51220703125, 4932.91845703125, -22.36956787109375, 3.857177734375, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240285, 35258, 530, 1, 1, 0, -1824.8941650390625, 4920.689453125, -21.8328437805175781, 1.01229095458984375, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240286, 35258, 530, 1, 1, 0, -1828.8385009765625, 4923.3515625, -21.8637142181396484, 1.064650893211364746, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240287, 35258, 530, 1, 1, 0, -1785.263916015625, 4938.56494140625, -22.5346794128417968, 3.281219005584716796, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240288, 35259, 530, 1, 1, 0, -1803.53125, 4911.09716796875, -21.7488002777099609, 2.740166902542114257, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240289, 35259, 530, 1, 1, 0, -1792, 4913.0546875, -21.3998279571533203, 2.007128715515136718, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240290, 35259, 530, 1, 1, 0, -1797.486083984375, 4914.01025390625, -21.7077884674072265, 1.500983119010925292, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240291, 35259, 530, 1, 1, 0, -1794.4617919921875, 4911.29345703125, -21.4007549285888671, 2.111848354339599609, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240292, 34481, 0, 1, 1, 0, -5166.08154296875, -881.12677001953125, 507.390594482421875, 1.082104086875915527, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240293, 34478, 0, 1, 1, 0, -5160.71533203125, -882.70489501953125, 507.3590087890625, 1.780235767364501953, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240294, 35247, 0, 1, 1, 0, -5161.99658203125, -863.6632080078125, 507.281585693359375, 4.834561824798583984, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240295, 35247, 0, 1, 1, 0, -5154.46875, -866.9305419921875, 507.900146484375, 3.420845270156860351, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240296, 35247, 0, 1, 1, 0, -5157.59033203125, -864.23089599609375, 507.502685546875, 3.996803998947143554, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240297, 35247, 0, 1, 1, 0, -5166.62841796875, -874.4444580078125, 507.21295166015625, 0.837758064270019531, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240298, 35248, 0, 1, 1, 0, -5157.13720703125, -875.779541015625, 507.76727294921875, 2.076941728591918945, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240299, 35248, 0, 1, 1, 0, -5165.798828125, -866.6875, 506.89959716796875, 5.829399585723876953, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240300, 35248, 0, 1, 1, 0, -5153.845703125, -872.18927001953125, 508.302032470703125, 2.775073528289794921, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240301, 35248, 0, 1, 1, 0, -5162.43603515625, -877.17706298828125, 507.35357666015625, 1.431169986724853515, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240302, 35248, 0, 1, 1, 0, -5167.7275390625, -870.47918701171875, 506.750396728515625, 0.279252678155899047, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240339, 35250, 1, 1, 1, 0, 10059.9951171875, 2126.338623046875, 1329.7412109375, 3.769911050796508789, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(240340, 35250, 1, 1, 1, 0, 10052.1318359375, 2108.732666015625, 1329.73095703125, 1.378810048103332519, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL); + +-- new spawns +DELETE FROM `creature` WHERE (`id1` IN (35243, 35244, 35246, 35249, 35250, 35251, 35252, 35258, 35259)) AND (`guid` IN (53793, 53794, 53795, 53796, 53797, 53798, 53799, 53800, 53801, 53802, 53803, 53804, 53805, 53806, 53807, 53808, 53809, 53810, 53811, 53812, 53813, 53814, 53815, 53816, 53817, 53818, 53819, 53820, 53821, 53822, 53823, 53824, 53825, 53826, 53827, 53828, 53829, 53830, 53831)); +INSERT INTO `creature` (`guid`, `id1`, `map`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(53793, 35243, 530, 1, 1, 0, 9410.404296875, -6856.34033203125, 14.88649463653564453, 4.049163818359375, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53794, 35243, 530, 1, 1, 0, 9411.26953125, -6832.328125, 16.75127601623535156, 3.228859186172485351, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53795, 35243, 530, 1, 1, 0, 9417.37890625, -6840.1875, 15.81598854064941406, 2.129301786422729492, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53796, 35243, 530, 1, 1, 0, 9417.46875, -6832.5693359375, 16.11979293823242187, 4.084070205688476562, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53797, 35243, 530, 1, 1, 0, 9421.55859375, -6836.08349609375, 15.54009628295898437, 3.246312379837036132, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53798, 35244, 0, 1, 1, 0, 1776.6875, 227.5694427490234375, 59.8570556640625, 0.05235987901687622, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53799, 35244, 0, 1, 1, 0, 1779.7117919921875, 249.8559112548828125, 59.92548370361328125, 1.378810048103332519, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53800, 35244, 0, 1, 1, 0, 1780.986083984375, 264.322906494140625, 59.7176513671875, 5.358160972595214843, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53801, 35244, 0, 1, 1, 0, 1781.376708984375, 257.161468505859375, 59.58280181884765625, 4.590215682983398437, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53802, 35244, 0, 1, 1, 0, 1781.576416015625, 230.75347900390625, 59.88961410522460937, 5.864306449890136718, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53803, 35244, 0, 1, 1, 0, 1786.8021240234375, 208.7118072509765625, 59.82406997680664062, 1.169370532035827636, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53804, 35244, 0, 1, 1, 0, 1789.220458984375, 213.685760498046875, 59.9723358154296875, 4.188790321350097656, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53805, 35244, 0, 1, 1, 0, 1802.546875, 215.5625, 65.95556640625, 1.65806281566619873, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53806, 35244, 0, 1, 1, 0, 1808.763916015625, 215.5590362548828125, 65.95556640625, 1.623156189918518066, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53807, 35244, 0, 1, 1, 0, 1823.607666015625, 218.8819427490234375, 60.47595977783203125, 1.29154360294342041, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53808, 35244, 0, 1, 1, 0, 1825.2725830078125, 257.40972900390625, 59.95352935791015625, 1.93731546401977539, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53809, 35244, 0, 1, 1, 0, 1825.670166015625, 249.7916717529296875, 60.12625885009765625, 0.48869219422340393, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53810, 35244, 0, 1, 1, 0, 1826.1163330078125, 263.0382080078125, 59.77779006958007812, 3.420845270156860351, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53811, 35246, 530, 1, 1, 0, -4329.2119140625, -12448.7431640625, 17.27162742614746093, 0.506145477294921875, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53812, 35249, 0, 1, 1, 0, -9350.6982421875, 168.251739501953125, 61.64437484741210937, 1.01229095458984375, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53813, 35250, 1, 1, 1, 0, 10061.029296875, 2110.626708984375, 1329.734375, 1.29154360294342041, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53814, 35250, 1, 1, 1, 0, 10061.646484375, 2118.564208984375, 1329.7435302734375, 2.967059612274169921, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53815, 35250, 1, 1, 1, 0, 10065.287109375, 2103.282958984375, 1330.635498046875, 4.066617012023925781, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53816, 35250, 1, 1, 1, 0, 10066.953125, 2123.397705078125, 1329.7412109375, 2.967059612274169921, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53817, 35250, 1, 1, 1, 0, 10067.0908203125, 2128.99658203125, 1329.7412109375, 3.630284786224365234, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53818, 35250, 1, 1, 1, 0, 10068.2255859375, 2117.38720703125, 1329.76416015625, 1.832595705986022949, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53819, 35251, 1, 1, 1, 0, 1185.26220703125, -4465.97412109375, 21.38922119140625, 2.408554315567016601, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53820, 35251, 1, 1, 1, 0, 1186.7586669921875, -4462.24853515625, 21.24035835266113281, 1.274090290069580078, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53821, 35251, 1, 1, 1, 0, 1192.923583984375, -4467.40966796875, 21.63202285766601562, 3.176499128341674804, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53822, 35252, 1, 1, 1, 0, -984.48785400390625, -82.5694427490234375, 21.32398033142089843, 1.29154360294342041, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53823, 35252, 1, 1, 1, 0, -986.09375, -79.298614501953125, 21.44527244567871093, 1.134464025497436523, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53824, 35252, 1, 1, 1, 0, -988.1961669921875, -76.1545181274414062, 22.06944465637207031, 1.832595705986022949, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53825, 35252, 1, 1, 1, 0, -988.50177001953125, -70.1875, 22.69485855102539062, 6.17846536636352539, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53826, 35258, 530, 1, 1, 0, -1832.876708984375, 4923.1708984375, -21.4524955749511718, 1.134464025497436523, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53827, 35258, 530, 1, 1, 0, -1834.5208740234375, 4926.9765625, -21.4531154632568359, 0.977384388446807861, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53828, 35258, 530, 1, 1, 0, -1837.7239990234375, 4927.68505859375, -21.1529521942138671, 1.29154360294342041, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53829, 35259, 530, 1, 1, 0, -1803.751708984375, 4906.93994140625, -21.3884010314941406, 2.356194496154785156, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53830, 35259, 530, 1, 1, 0, -1812.2760009765625, 4911.76220703125, -21.3407649993896484, 0.907571196556091308, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL), +(53831, 35259, 530, 1, 1, 0, -1815.9166259765625, 4913.81005859375, -21.4253044128417968, 1.535889744758605957, 120, 0, 0, 0, 0, 0, "", 51943, 1, NULL); + +-- remove duplicate spawns +DELETE FROM `creature` WHERE (`id1` IN (35254)) AND (`guid` IN (240241)); +DELETE FROM `creature_addon` WHERE (`guid` IN (240241)); +DELETE FROM `game_event_creature` WHERE (`eventEntry` = 51) AND (`guid` IN (240241)); + +-- enable all spawns for eventEntry 51 +DELETE FROM `game_event_creature` WHERE (`eventEntry` = 51) AND (`guid` IN (SELECT `guid` FROM `creature` WHERE `id1` IN (34435, 34476, 34477, 34478, 34479, 34480, 34481, 34482, 34483, 34484, 35243, 35244, 35246, 35247, 35248, 35249, 35250, 35251, 35252, 35253, 35254, 35256, 35258, 35259, 35260, 35261))); +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) (SELECT 51, `guid` FROM `creature` WHERE `id1` IN (34435, 34476, 34477, 34478, 34479, 34480, 34481, 34482, 34483, 34484, 35243, 35244, 35246, 35247, 35248, 35249, 35250, 35251, 35252, 35253, 35254, 35256, 35258, 35259, 35260, 35261)); From 12927674f457ee797a0684116e7d6c740d82fe5e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 27 Feb 2026 12:34:14 +0000 Subject: [PATCH 323/335] chore(DB): import pending files Referenced commit(s): 9f79d53b6634f28e79ffe427a2e58754be70595a --- .../rev_1771915997105053200.sql => db_world/2026_02_27_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1771915997105053200.sql => db_world/2026_02_27_01.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1771915997105053200.sql b/data/sql/updates/db_world/2026_02_27_01.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1771915997105053200.sql rename to data/sql/updates/db_world/2026_02_27_01.sql index cab89e1ec..bf2a5cfb9 100644 --- a/data/sql/updates/pending_db_world/rev_1771915997105053200.sql +++ b/data/sql/updates/db_world/2026_02_27_01.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_27_00 -> 2026_02_27_01 -- Update creature 'Day of the Dead Celebrants and Spirits' with sniffed values -- updated spawns DELETE FROM `creature` WHERE (`id1` IN (35250, 34479, 35243, 35249, 35253, 35251, 34483, 34482, 34435, 34477, 35256, 35254, 35244, 34476, 34480, 35252, 34484, 35246, 35260, 35261, 35258, 35259, 34481, 34478, 35247, 35248)) AND (`guid` IN (240194, 240195, 240196, 240197, 240198, 240199, 240200, 240201, 240202, 240203, 240204, 240205, 240206, 240207, 240208, 240209, 240210, 240211, 240212, 240213, 240214, 240215, 240216, 240217, 240218, 240219, 240220, 240221, 240222, 240223, 240224, 240225, 240230, 240231, 240232, 240233, 240234, 240235, 240236, 240237, 240238, 240239, 240240, 240242, 240243, 240244, 240245, 240246, 240247, 240248, 240249, 240250, 240267, 240268, 240269, 240270, 240271, 240272, 240273, 240274, 240275, 240276, 240277, 240278, 240279, 240280, 240281, 240282, 240283, 240284, 240285, 240286, 240287, 240288, 240289, 240290, 240291, 240292, 240293, 240294, 240295, 240296, 240297, 240298, 240299, 240300, 240301, 240302, 240339, 240340)); From 74dd60a7b1964f509eafc1abb815ae1a4ee8e6da Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 27 Feb 2026 08:41:22 -0600 Subject: [PATCH 324/335] fix(Core/Spells): Fix Swift Hand of Justice healing for 0 (#24911) Co-authored-by: blinkysc Co-authored-by: ariel- --- src/server/scripts/Spells/spell_item.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index a9a430cf1..6c14b0563 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -5903,7 +5903,10 @@ class spell_item_swift_hand_justice_dummy : public AuraScript void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - eventInfo.GetActor()->CastSpell(nullptr, SPELL_SWIFT_HAND_OF_JUSTICE_HEAL, true, nullptr, aurEff); + + Unit* caster = eventInfo.GetActor(); + int32 bp0 = static_cast(caster->CountPctFromMaxHealth(aurEff->GetAmount())); + caster->CastCustomSpell(SPELL_SWIFT_HAND_OF_JUSTICE_HEAL, SPELLVALUE_BASE_POINT0, bp0, nullptr, true, nullptr, aurEff); } void Register() override From 396c35be2f5a847a950f45e5f22248c22c7cfeda Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 27 Feb 2026 08:42:17 -0600 Subject: [PATCH 325/335] fix(Core/Spells): Fix Cobra Strikes stack consumption (#24906) Co-authored-by: blinkysc Co-authored-by: TrinityCore --- .../rev_1772186400000000000.sql | 5 ++ src/server/game/Entities/Unit/Unit.cpp | 17 +++++++ src/server/game/Spells/SpellInfo.cpp | 6 +-- .../game/Spells/SpellInfoCorrections.cpp | 7 --- src/server/scripts/Spells/spell_hunter.cpp | 48 ++++++++++++++++++- 5 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1772186400000000000.sql diff --git a/data/sql/updates/pending_db_world/rev_1772186400000000000.sql b/data/sql/updates/pending_db_world/rev_1772186400000000000.sql new file mode 100644 index 000000000..5445b657a --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772186400000000000.sql @@ -0,0 +1,5 @@ +-- Cobra Strikes spell script bindings +DELETE FROM `spell_script_names` WHERE `spell_id` IN (-53256, 53257); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-53256, 'spell_hun_cobra_strikes'), +(53257, 'spell_hun_cobra_strikes_triggered'); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 9f63466b1..56604d76e 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -13040,6 +13040,23 @@ void Unit::TriggerAurasProcOnEvent(std::list* myProcAuras, std AuraApplicationProcContainer myAurasTriggeringProc; GetProcAurasTriggeredOnEvent(myAurasTriggeringProc, myProcAuras, myProcEventInfo); + // needed for example for Cobra Strikes, pet does the attack, but aura is on owner + if (Player* modOwner = GetSpellModOwner()) + { + if (modOwner != this && spell) + { + std::list modAuras; + for (auto itr = modOwner->GetAppliedAuras().begin(); itr != modOwner->GetAppliedAuras().end(); ++itr) + { + if (spell->m_appliedMods.count(itr->second->GetBase()) != 0) + modAuras.push_back(itr->second); + } + + if (!modAuras.empty()) + modOwner->GetProcAurasTriggeredOnEvent(myAurasTriggeringProc, &modAuras, myProcEventInfo); + } + } + // prepare data for target trigger ProcEventInfo targetProcEventInfo = ProcEventInfo(this, actionTarget, this, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo); AuraApplicationProcContainer targetAurasTriggeringProc; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 209a54923..978f73d9f 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1313,10 +1313,10 @@ bool SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const if (affectSpell->SpellFamilyName != SpellFamilyName) return false; - if (mod->mask & SpellFamilyFlags) - return true; + if (mod->mask && !(mod->mask & SpellFamilyFlags)) + return false; - return false; + return true; } bool SpellInfo::CanPierceImmuneAura(SpellInfo const* aura) const diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index dc5218fba..8553143a5 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -652,13 +652,6 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT; }); - // Cobra Strikes - ApplySpellFix({ 53257 }, [](SpellInfo* spellInfo) - { - spellInfo->ProcCharges = 2; - spellInfo->StackAmount = 0; - }); - // Kill Command // Kill Command, Overpower ApplySpellFix({ 34027, 37529 }, [](SpellInfo* spellInfo) diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 7877a9bd9..fce48f898 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -78,7 +78,8 @@ enum HunterSpells SPELL_HUNTER_RAPID_RECUPERATION_MANA_R1 = 56654, SPELL_HUNTER_RAPID_RECUPERATION_MANA_R2 = 58882, SPELL_HUNTER_PIERCING_SHOTS = 63468, - SPELL_HUNTER_T9_4P_GREATNESS = 68130 + SPELL_HUNTER_T9_4P_GREATNESS = 68130, + SPELL_HUNTER_COBRA_STRIKES_TRIGGERED = 53257 }; enum HunterSpellIcons @@ -934,6 +935,49 @@ class spell_hun_misdirection_proc : public AuraScript } }; +// -53256 - Cobra Strikes (talent) +class spell_hun_cobra_strikes : public AuraScript +{ + PrepareAuraScript(spell_hun_cobra_strikes); + + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->Effects[EFFECT_0].TriggerSpell }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(aurEff->GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell); + if (!triggeredSpellInfo) + return; + + GetTarget()->CastCustomSpell(triggeredSpellInfo->Id, SPELLVALUE_AURA_STACK, triggeredSpellInfo->StackAmount, GetTarget(), true); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_hun_cobra_strikes::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + +// 53257 - Cobra Strikes (triggered buff) +class spell_hun_cobra_strikes_triggered : public AuraScript +{ + PrepareAuraScript(spell_hun_cobra_strikes_triggered); + + void HandleStackDrop(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + ModStackAmount(-1); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_hun_cobra_strikes_triggered::HandleStackDrop, EFFECT_0, SPELL_AURA_ADD_FLAT_MODIFIER); + } +}; + // 781 - Disengage class spell_hun_disengage : public SpellScript { @@ -1633,6 +1677,8 @@ void AddSC_hunter_spell_scripts() RegisterSpellScript(spell_hun_aspect_of_the_beast); RegisterSpellScript(spell_hun_ascpect_of_the_viper); RegisterSpellScript(spell_hun_chimera_shot); + RegisterSpellScript(spell_hun_cobra_strikes); + RegisterSpellScript(spell_hun_cobra_strikes_triggered); RegisterSpellScript(spell_hun_disengage); RegisterSpellScript(spell_hun_improved_mend_pet); RegisterSpellScript(spell_hun_invigoration); From df04120c16a9ac67098d14ba317ff73475388f24 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 27 Feb 2026 08:42:40 -0600 Subject: [PATCH 326/335] fix(DB/Proc): Add missing NONE DmgClass flags and fix SpellPhaseMask for on-cast procs (#24903) Co-authored-by: blinkysc --- .../rev_1772134223874742153.sql | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772134223874742153.sql diff --git a/data/sql/updates/pending_db_world/rev_1772134223874742153.sql b/data/sql/updates/pending_db_world/rev_1772134223874742153.sql new file mode 100644 index 000000000..11a2e8965 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772134223874742153.sql @@ -0,0 +1,50 @@ +-- Fix "on cast" procs: add missing NONE DmgClass flags and correct SpellPhaseMask +-- These spells have tooltips like "chance on successful spellcast" but were missing +-- DONE_SPELL_NONE_DMG_CLASS_POS/NEG flags, preventing NONE-DmgClass spells from +-- proccing them. Some also had SpellPhaseMask=2 (HIT) instead of 1 (CAST). + +-- [27521] Mana Restore - "2% chance on successful spellcast to restore mana" +-- Phase HIT->CAST, add NONE flags: 0x14000 -> 0x15400 +UPDATE `spell_proc` SET `ProcFlags` = 0x15400, `SpellPhaseMask` = 1 WHERE `SpellId` = 27521; + +-- [27774] The Furious Storm - "Chance on spell cast to increase your spell power" +-- Phase HIT->CAST, add NONE flags: 0x14000 -> 0x15400 +UPDATE `spell_proc` SET `ProcFlags` = 0x15400, `SpellPhaseMask` = 1 WHERE `SpellId` = 27774; + +-- [32837] Spell Focus Trigger - "Chance on successful spellcast to grant Spell Haste" +-- Phase HIT->CAST, add NONE flags: 0x14000 -> 0x15400 +UPDATE `spell_proc` SET `ProcFlags` = 0x15400, `SpellPhaseMask` = 1 WHERE `SpellId` = 32837; + +-- [32980] Arcane Might - "2% chance on successful spellcast to increase spell power" +-- No spell_proc entry existed. Add with NONE flags and CAST phase. +DELETE FROM `spell_proc` WHERE `SpellId` = 32980; +INSERT INTO `spell_proc` (`SpellId`, `ProcFlags`, `SpellPhaseMask`) VALUES (32980, 0x15400, 1); + +-- [32981] Verdant Flame - "Chance on successful spellcast to restore Mana" +-- No spell_proc entry existed. Add with NONE flags and CAST phase. +DELETE FROM `spell_proc` WHERE `SpellId` = 32981; +INSERT INTO `spell_proc` (`SpellId`, `ProcFlags`, `SpellPhaseMask`) VALUES (32981, 0x15400, 1); + +-- [34584] Love Struck - "Chance on spell cast to increase your Spirit" +-- Phase HIT->CAST, add NONE flags: 0x14000 -> 0x15400 +UPDATE `spell_proc` SET `ProcFlags` = 0x15400, `SpellPhaseMask` = 1 WHERE `SpellId` = 34584; + +-- [38334] Proc Mana Regen - "Your spell casts have a chance to allow mana regen" +-- Phase HIT->CAST, add NONE flags: 0x14000 -> 0x15400 +UPDATE `spell_proc` SET `ProcFlags` = 0x15400, `SpellPhaseMask` = 1 WHERE `SpellId` = 38334; + +-- [55381] Mana Restore - "2% chance on successful spellcast to restore mana" +-- Phase HIT->CAST, add NONE flags: 0x14000 -> 0x15400 +UPDATE `spell_proc` SET `ProcFlags` = 0x15400, `SpellPhaseMask` = 1 WHERE `SpellId` = 55381; + +-- [58442] Airy Pale Ale - "Chance on successful spellcast to restore mana" +-- Phase HIT->CAST, add NONE flags: 0x14000 -> 0x15400 +UPDATE `spell_proc` SET `ProcFlags` = 0x15400, `SpellPhaseMask` = 1 WHERE `SpellId` = 58442; + +-- [62114] Flow of Knowledge - "Your spell casts have a chance to increase spell power" +-- Phase HIT->CAST, add NONE flags: 0x54000 -> 0x55400 +UPDATE `spell_proc` SET `ProcFlags` = 0x55400, `SpellPhaseMask` = 1 WHERE `SpellId` = 62114; + +-- [71585] Item - Icecrown 25 Emblem Healer Trinket - "Your spell casts have a chance to grant mana per 5 sec" +-- Phase already CAST, just add NONE flags: 0x14000 -> 0x15400 +UPDATE `spell_proc` SET `ProcFlags` = 0x15400 WHERE `SpellId` = 71585; From 03b27f47846c5853c0b38e4359de943a76cffadf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 27 Feb 2026 14:54:17 +0000 Subject: [PATCH 327/335] chore(DB): import pending files Referenced commit(s): 74dd60a7b1964f509eafc1abb815ae1a4ee8e6da --- .../rev_1772134223874742153.sql => db_world/2026_02_27_02.sql} | 1 + .../rev_1772186400000000000.sql => db_world/2026_02_27_03.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1772134223874742153.sql => db_world/2026_02_27_02.sql} (98%) rename data/sql/updates/{pending_db_world/rev_1772186400000000000.sql => db_world/2026_02_27_03.sql} (85%) diff --git a/data/sql/updates/pending_db_world/rev_1772134223874742153.sql b/data/sql/updates/db_world/2026_02_27_02.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1772134223874742153.sql rename to data/sql/updates/db_world/2026_02_27_02.sql index 11a2e8965..87c0e1c03 100644 --- a/data/sql/updates/pending_db_world/rev_1772134223874742153.sql +++ b/data/sql/updates/db_world/2026_02_27_02.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_27_01 -> 2026_02_27_02 -- Fix "on cast" procs: add missing NONE DmgClass flags and correct SpellPhaseMask -- These spells have tooltips like "chance on successful spellcast" but were missing -- DONE_SPELL_NONE_DMG_CLASS_POS/NEG flags, preventing NONE-DmgClass spells from diff --git a/data/sql/updates/pending_db_world/rev_1772186400000000000.sql b/data/sql/updates/db_world/2026_02_27_03.sql similarity index 85% rename from data/sql/updates/pending_db_world/rev_1772186400000000000.sql rename to data/sql/updates/db_world/2026_02_27_03.sql index 5445b657a..0ce64a530 100644 --- a/data/sql/updates/pending_db_world/rev_1772186400000000000.sql +++ b/data/sql/updates/db_world/2026_02_27_03.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_27_02 -> 2026_02_27_03 -- Cobra Strikes spell script bindings DELETE FROM `spell_script_names` WHERE `spell_id` IN (-53256, 53257); INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES From 4c44b03e516a936ba45d667d09651e1c5c543d74 Mon Sep 17 00:00:00 2001 From: sudlud Date: Fri, 27 Feb 2026 18:29:00 +0100 Subject: [PATCH 328/335] fix(DB/Gameobject): Sniffed Values for 'Doodad_OrcBonFire01' spawns (#24919) --- .../sql/updates/pending_db_world/rev_1772202396609034600.sql | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772202396609034600.sql diff --git a/data/sql/updates/pending_db_world/rev_1772202396609034600.sql b/data/sql/updates/pending_db_world/rev_1772202396609034600.sql new file mode 100644 index 000000000..1ff48ae84 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772202396609034600.sql @@ -0,0 +1,5 @@ +-- Update gameobject 'Doodad_OrcBonFire01' with sniffed values +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (192612)) AND (`guid` IN (50)); +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 +(50, 192612, 530, 0, 0, 1, 1, 7567.4794921875, -7359.6064453125, 161.88848876953125, 3.159062385559082031, 0, 0, -0.99996185302734375, 0.008734640665352344, 120, 255, 1, "", 49822, NULL); From 997d57fd62714999ed15d3ac3b3bdab0b2f118b9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 27 Feb 2026 17:30:12 +0000 Subject: [PATCH 329/335] chore(DB): import pending files Referenced commit(s): 4c44b03e516a936ba45d667d09651e1c5c543d74 --- .../rev_1772202396609034600.sql => db_world/2026_02_27_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772202396609034600.sql => db_world/2026_02_27_04.sql} (93%) diff --git a/data/sql/updates/pending_db_world/rev_1772202396609034600.sql b/data/sql/updates/db_world/2026_02_27_04.sql similarity index 93% rename from data/sql/updates/pending_db_world/rev_1772202396609034600.sql rename to data/sql/updates/db_world/2026_02_27_04.sql index 1ff48ae84..f57b5dcdb 100644 --- a/data/sql/updates/pending_db_world/rev_1772202396609034600.sql +++ b/data/sql/updates/db_world/2026_02_27_04.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_27_03 -> 2026_02_27_04 -- Update gameobject 'Doodad_OrcBonFire01' with sniffed values -- new spawns DELETE FROM `gameobject` WHERE (`id` IN (192612)) AND (`guid` IN (50)); From 5273146cb6c1059e201e908cb620d86579fcfc87 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 27 Feb 2026 11:39:42 -0600 Subject: [PATCH 330/335] fix(Core/Spells): Restrict Beacon of Light proc to intended heals (#24921) Co-authored-by: blinkysc --- .../updates/pending_db_world/rev_1772207125325046.sql | 10 ++++++++++ src/server/scripts/Spells/spell_paladin.cpp | 8 +------- 2 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1772207125325046.sql diff --git a/data/sql/updates/pending_db_world/rev_1772207125325046.sql b/data/sql/updates/pending_db_world/rev_1772207125325046.sql new file mode 100644 index 000000000..aeb239fc0 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772207125325046.sql @@ -0,0 +1,10 @@ +-- Beacon of Light (53651): restrict proc to Holy Light, Flash of Light, Holy Shock, Lay on Hands +-- Previously had no SpellFamily filter, allowing unintended heals to transfer: +-- Glyph of Holy Light (54968), Seal of Light (20167), JoL (20267) +-- SpellFamilyName=10 (PALADIN) blocks Glyph of Holy Light (GENERIC family) +-- SpellFamilyMask 0xC0008000/0x00010000 allows only: +-- Holy Light (635) Flags[0]=0x80000000 +-- Flash of Light (19750) Flags[0]=0x40000000 +-- Lay on Hands (633) Flags[0]=0x00008000 +-- Holy Shock heal (25914) Flags[1]=0x00010000 +UPDATE `spell_proc` SET `SpellFamilyName` = 10, `SpellFamilyMask0` = 0xC0008000, `SpellFamilyMask1` = 0x00010000 WHERE `SpellId` = 53651; diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index a9f8ebfe1..44b210542 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -2088,18 +2088,12 @@ class spell_pal_light_s_beacon : public AuraScript SPELL_PALADIN_BEACON_OF_LIGHT_AURA, SPELL_PALADIN_BEACON_OF_LIGHT_FLASH, SPELL_PALADIN_BEACON_OF_LIGHT_HOLY, - SPELL_PALADIN_HOLY_LIGHT_R1, - SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL + SPELL_PALADIN_HOLY_LIGHT_R1 }); } bool CheckProc(ProcEventInfo& eventInfo) { - // Don't proc from Judgement of Light heals — JoL sets originalCaster to - // the paladin for combat log, but the heal is actually cast by the attacker. - if (eventInfo.GetSpellInfo() && eventInfo.GetSpellInfo()->Id == SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL) - return false; - // Don't proc if the heal target is the beacon target (no double heal) if (GetTarget()->HasAura(SPELL_PALADIN_BEACON_OF_LIGHT_AURA, eventInfo.GetActor()->GetGUID())) return false; From f5ababeb11a4d0854deb134fc21d11a0b7644dbe Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 27 Feb 2026 17:41:08 +0000 Subject: [PATCH 331/335] chore(DB): import pending files Referenced commit(s): 5273146cb6c1059e201e908cb620d86579fcfc87 --- .../rev_1772207125325046.sql => db_world/2026_02_27_05.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772207125325046.sql => db_world/2026_02_27_05.sql} (94%) diff --git a/data/sql/updates/pending_db_world/rev_1772207125325046.sql b/data/sql/updates/db_world/2026_02_27_05.sql similarity index 94% rename from data/sql/updates/pending_db_world/rev_1772207125325046.sql rename to data/sql/updates/db_world/2026_02_27_05.sql index aeb239fc0..dc62f9411 100644 --- a/data/sql/updates/pending_db_world/rev_1772207125325046.sql +++ b/data/sql/updates/db_world/2026_02_27_05.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_27_04 -> 2026_02_27_05 -- Beacon of Light (53651): restrict proc to Holy Light, Flash of Light, Holy Shock, Lay on Hands -- Previously had no SpellFamily filter, allowing unintended heals to transfer: -- Glyph of Holy Light (54968), Seal of Light (20167), JoL (20267) From 34687103091d29b3f032125402bda107788e6c4e Mon Sep 17 00:00:00 2001 From: sudlud Date: Fri, 27 Feb 2026 18:42:11 +0100 Subject: [PATCH 332/335] fix(Core/BF/BG): update Titan Relic spawns with sniffed values (#24912) --- src/server/game/Battlefield/Zones/BattlefieldWG.cpp | 2 +- src/server/game/Battlegrounds/Zones/BattlegroundSA.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index 6f61e1fa7..64ddbecf1 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -224,7 +224,7 @@ bool BattlefieldWG::Update(uint32 diff) void BattlefieldWG::OnBattleStart() { // Spawn titan relic - GameObject* go = SpawnGameObject(GO_WINTERGRASP_TITAN_S_RELIC, 5440.0f, 2840.8f, 430.43f, 0); + GameObject* go = SpawnGameObject(GO_WINTERGRASP_TITAN_S_RELIC, 5440.37890625f, 2840.493408203125f, 430.2816162109375, 4.45059061050415039f); // VerifiedBuild 51943 if (go) { // Update faction of relic, only attacker can click on diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h index 97c101497..273bd5f82 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h @@ -195,7 +195,7 @@ float const BG_SA_ObjSpawnlocs[BG_SA_MAXOBJ][4] = { 1227.667f, -212.555f, 55.372f, 0.5023f }, { 1214.681f, 81.21f, 53.413f, 5.745f }, { 878.555f, -108.2f, 117.845f, 0.0f }, - { 836.5f, -108.8f, 120.219f, 0.0f }, + { 837.0653076171875f, -107.536727905273437f, 127.0248489379882812f, 4.468043327331542968f }, // VerifiedBuild 46158 // Ships { 2679.696777f, -826.891235f, 3.712860f, 5.78367f}, //rot2 1 rot3 0.0002f { 2574.003662f, 981.261475f, 2.603424f, 0.807696f}, From 2b28b1268304791b8c6bce8e1920777a4b42851e Mon Sep 17 00:00:00 2001 From: sudlud Date: Fri, 27 Feb 2026 18:42:43 +0100 Subject: [PATCH 333/335] fix(DB/Gameobject): Sniffed Values for 'unnamed yellow dome' spawns (#24894) --- .../updates/pending_db_world/rev_1772110383846082100.sql | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772110383846082100.sql diff --git a/data/sql/updates/pending_db_world/rev_1772110383846082100.sql b/data/sql/updates/pending_db_world/rev_1772110383846082100.sql new file mode 100644 index 000000000..81a574744 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772110383846082100.sql @@ -0,0 +1,6 @@ +-- Update gameobject 'unnamed yellow dome' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (193796, 193795)) AND (`guid` IN (268695, 268770)); +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 +(268695, 193796, 571, 0, 0, 1, 1, 7628.9599609375, 2060.48779296875, 586.426513671875, 3.703464746475219726, 0, 0, -0.96079635620117187, 0.277255088090896606, 120, 255, 1, "", 45942, NULL), +(268770, 193795, 571, 0, 0, 1, 1, 7888.88037109375, 2058.36279296875, 586.39581298828125, 3.729639530181884765, 0, 0, -0.95708560943603515, 0.289805322885513305, 120, 255, 1, "", 45942, NULL); From 8f57a130726ff1311a394be889cdbcf5305617d0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 27 Feb 2026 17:43:30 +0000 Subject: [PATCH 334/335] chore(DB): import pending files Referenced commit(s): f5ababeb11a4d0854deb134fc21d11a0b7644dbe --- .../rev_1772110383846082100.sql => db_world/2026_02_27_06.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1772110383846082100.sql => db_world/2026_02_27_06.sql} (95%) diff --git a/data/sql/updates/pending_db_world/rev_1772110383846082100.sql b/data/sql/updates/db_world/2026_02_27_06.sql similarity index 95% rename from data/sql/updates/pending_db_world/rev_1772110383846082100.sql rename to data/sql/updates/db_world/2026_02_27_06.sql index 81a574744..5fefd2dad 100644 --- a/data/sql/updates/pending_db_world/rev_1772110383846082100.sql +++ b/data/sql/updates/db_world/2026_02_27_06.sql @@ -1,3 +1,4 @@ +-- DB update 2026_02_27_05 -> 2026_02_27_06 -- Update gameobject 'unnamed yellow dome' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (193796, 193795)) AND (`guid` IN (268695, 268770)); From 9ecaf5aca5360902f6c8e0266f547af66426f35c Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 27 Feb 2026 14:02:50 -0600 Subject: [PATCH 335/335] fix(Core/Spells): Remove range check on split damage auras (#24899) Co-authored-by: blinkysc --- src/server/game/Entities/Unit/Unit.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 56604d76e..9efc4fa62 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -2495,13 +2495,6 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->IsAlive()) continue; - // Limit effect range to spell's cast range. (Only for single target auras, AreaAuras don't need it) - // Ignore LOS attribute is only used for the cast portion of the spell - SpellInfo const* splitSpellInfo = (*itr)->GetSpellInfo(); - if (!splitSpellInfo->Effects[(*itr)->GetEffIndex()].IsAreaAuraEffect()) - if (!caster->IsWithinDist(victim, splitSpellInfo->GetMaxRange(splitSpellInfo->IsPositive(), caster))) - continue; - int32 splitDamage = (*itr)->GetAmount(); // absorb must be smaller than the damage itself @@ -2567,13 +2560,7 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->IsAlive()) continue; - // Limit effect range to spell's cast range. (Only for single target auras, AreaAuras don't need it) - // Ignore LOS attribute is only used for the cast portion of the spell SpellInfo const* splitSpellInfo = (*itr)->GetSpellInfo(); - if (!splitSpellInfo->Effects[(*itr)->GetEffIndex()].IsAreaAuraEffect()) - if (!caster->IsWithinDist(victim, splitSpellInfo->GetMaxRange(splitSpellInfo->IsPositive(), caster))) - continue; - uint32 splitDamage = CalculatePct(dmgInfo.GetDamage(), (*itr)->GetAmount()); SpellSchoolMask splitSchoolMask = schoolMask;