aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/scripts')
-rw-r--r--src/server/scripts/Commands/cs_cast.cpp15
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp19
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/blackrock_spire.h6
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp30
-rw-r--r--src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp119
-rw-r--r--src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.h4
-rw-r--r--src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp140
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp62
-rw-r--r--src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp68
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h3
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp6
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp2
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp19
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp14
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp423
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp818
-rw-r--r--src/server/scripts/Northrend/zone_dragonblight.cpp26
-rw-r--r--src/server/scripts/Northrend/zone_wintergrasp.cpp196
-rw-r--r--src/server/scripts/Outland/BlackTemple/black_temple.h18
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp24
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp93
-rw-r--r--src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp189
-rw-r--r--src/server/scripts/Outland/zone_hellfire_peninsula.cpp184
-rw-r--r--src/server/scripts/Pet/pet_hunter.cpp2
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp20
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp8
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp154
-rw-r--r--src/server/scripts/Spells/spell_item.cpp117
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp6
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp144
-rw-r--r--src/server/scripts/Spells/spell_shaman.cpp56
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp87
-rw-r--r--src/server/scripts/World/go_scripts.cpp25
34 files changed, 1793 insertions, 1308 deletions
diff --git a/src/server/scripts/Commands/cs_cast.cpp b/src/server/scripts/Commands/cs_cast.cpp
index 44c606a360f..45e6c65cc6b 100644
--- a/src/server/scripts/Commands/cs_cast.cpp
+++ b/src/server/scripts/Commands/cs_cast.cpp
@@ -99,8 +99,7 @@ public:
return false;
}
- bool triggered = (triggeredStr != NULL);
-
+ TriggerCastFlags triggered = (triggeredStr != NULL) ? TRIGGERED_FULL_DEBUG_MASK : TRIGGERED_NONE;
handler->GetSession()->GetPlayer()->CastSpell(target, spellId, triggered);
return true;
@@ -132,8 +131,7 @@ public:
return false;
}
- bool triggered = (triggeredStr != NULL);
-
+ TriggerCastFlags triggered = (triggeredStr != NULL) ? TRIGGERED_FULL_DEBUG_MASK : TRIGGERED_NONE;
caster->CastSpell(handler->GetSession()->GetPlayer(), spellId, triggered);
return true;
@@ -167,8 +165,7 @@ public:
return false;
}
- bool triggered = (triggeredStr != NULL);
-
+ TriggerCastFlags triggered = (triggeredStr != NULL) ? TRIGGERED_FULL_DEBUG_MASK : TRIGGERED_NONE;
float x, y, z;
handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, dist);
@@ -230,8 +227,7 @@ public:
return false;
}
- bool triggered = (triggeredStr != NULL);
-
+ TriggerCastFlags triggered = (triggeredStr != NULL) ? TRIGGERED_FULL_DEBUG_MASK : TRIGGERED_NONE;
caster->CastSpell(caster->GetVictim(), spellId, triggered);
return true;
@@ -274,8 +270,7 @@ public:
return false;
}
- bool triggered = (triggeredStr != NULL);
-
+ TriggerCastFlags triggered = (triggeredStr != NULL) ? TRIGGERED_FULL_DEBUG_MASK : TRIGGERED_NONE;
caster->CastSpell(x, y, z, spellId, triggered);
return true;
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 16217fbaea6..1e4daaea2d2 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -2268,19 +2268,20 @@ public:
// melee damage by specific school
if (!spellStr)
{
- uint32 absorb = 0;
- uint32 resist = 0;
+ Player* attacker = handler->GetSession()->GetPlayer();
+ DamageInfo dmgInfo(attacker, target, damage, nullptr, schoolmask, SPELL_DIRECT_DAMAGE, BASE_ATTACK);
+ attacker->CalcAbsorbResist(dmgInfo);
- handler->GetSession()->GetPlayer()->CalcAbsorbResist(target, schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
-
- if (damage <= absorb + resist)
+ if (!dmgInfo.GetDamage())
return true;
- damage -= absorb + resist;
+ damage = dmgInfo.GetDamage();
- handler->GetSession()->GetPlayer()->DealDamageMods(target, damage, &absorb);
- handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
- handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0);
+ uint32 absorb = dmgInfo.GetAbsorb();
+ uint32 resist = dmgInfo.GetResist();
+ attacker->DealDamageMods(target, damage, &absorb);
+ attacker->DealDamage(target, damage, nullptr, DIRECT_DAMAGE, schoolmask, nullptr, false);
+ attacker->SendAttackStateUpdate(HITINFO_AFFECTS_VICTIM, target, 0, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0);
return true;
}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/blackrock_spire.h b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/blackrock_spire.h
index 446cc48d2f7..2c0f16c4ff2 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/blackrock_spire.h
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/blackrock_spire.h
@@ -48,7 +48,8 @@ enum DataTypes
DATA_HALL_RUNE_4 = 19,
DATA_HALL_RUNE_5 = 20,
DATA_HALL_RUNE_6 = 21,
- DATA_HALL_RUNE_7 = 22
+ DATA_HALL_RUNE_7 = 22,
+ DATA_SCARSHIELD_INFILTRATOR = 23
};
enum CreaturesIds
@@ -71,7 +72,8 @@ enum CreaturesIds
NPC_BLACKHAND_SUMMONER = 9818,
NPC_BLACKHAND_VETERAN = 9819,
NPC_BLACKHAND_INCARCERATOR = 10316,
- NPC_LORD_VICTOR_NEFARIUS = 10162
+ NPC_LORD_VICTOR_NEFARIUS = 10162,
+ NPC_SCARSHIELD_INFILTRATOR = 10299
};
enum AdditionalData
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp
index bbe8fda37eb..89617a9f4ef 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp
@@ -109,6 +109,9 @@ public:
if (GetBossState(DATA_GYTH) == DONE)
creature->DisappearAndDie();
break;
+ case NPC_SCARSHIELD_INFILTRATOR:
+ ScarshieldInfiltrator = creature->GetGUID();
+ break;
}
}
@@ -318,6 +321,8 @@ public:
return TheBeast;
case DATA_GENERAL_DRAKKISATH:
return GeneralDrakkisath;
+ case DATA_SCARSHIELD_INFILTRATOR:
+ return ScarshieldInfiltrator;
case GO_EMBERSEER_IN:
return go_emberseerin;
case GO_DOORS:
@@ -496,6 +501,7 @@ public:
ObjectGuid LordVictorNefarius;
ObjectGuid TheBeast;
ObjectGuid GeneralDrakkisath;
+ ObjectGuid ScarshieldInfiltrator;
ObjectGuid go_emberseerin;
ObjectGuid go_doors;
ObjectGuid go_emberseerout;
@@ -565,9 +571,33 @@ public:
}
};
+class at_nearby_scarshield_infiltrator : public AreaTriggerScript
+{
+public:
+ at_nearby_scarshield_infiltrator() : AreaTriggerScript("at_nearby_scarshield_infiltrator") { }
+
+ bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) override
+ {
+ if (player->IsAlive())
+ if (InstanceScript* instance = player->GetInstanceScript())
+ if (Creature* infiltrator = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_SCARSHIELD_INFILTRATOR)))
+ {
+ if (player->getLevel() >= 57)
+ infiltrator->AI()->SetData(1, 1);
+ else if (infiltrator->GetEntry() == NPC_SCARSHIELD_INFILTRATOR)
+ infiltrator->AI()->Talk(0, player);
+
+ return true;
+ }
+
+ return false;
+ }
+};
+
void AddSC_instance_blackrock_spire()
{
new instance_blackrock_spire();
new at_dragonspire_hall();
new at_blackrock_stadium();
+ new at_nearby_scarshield_infiltrator();
}
diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
index d0430ebb3e5..67bda699643 100644
--- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
+++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
@@ -54,7 +54,6 @@ enum Yells
enum Spells
{
SPELL_UNLOCK = 6421,
-
SPELL_DARK_OFFERING = 7154
};
@@ -205,6 +204,123 @@ public:
};
+enum ArugalSpells
+{
+ SPELL_TELE_UPPER = 7587,
+ SPELL_TELE_SPAWN = 7586,
+ SPELL_TELE_STAIRS = 7136,
+ NUM_TELEPORT_SPELLS = 3,
+ SPELL_ARUGAL_CURSE = 7621,
+ SPELL_THUNDERSHOCK = 7803,
+ SPELL_VOIDBOLT = 7588
+};
+
+enum ArugalTexts
+{
+ SAY_AGGRO = 1, // You, too, shall serve!
+ SAY_TRANSFORM = 2, // Release your rage!
+ SAY_SLAY = 3 // Another falls!
+};
+
+enum ArugalEvents
+{
+ EVENT_VOID_BOLT = 1,
+ EVENT_TELEPORT,
+ EVENT_THUNDERSHOCK,
+ EVENT_CURSE
+};
+
+class boss_archmage_arugal : public CreatureScript
+{
+ public:
+ boss_archmage_arugal() : CreatureScript("boss_archmage_arugal") { }
+
+ struct boss_archmage_arugalAI : public BossAI
+ {
+ boss_archmage_arugalAI(Creature* creature) : BossAI(creature, BOSS_ARUGAL) { }
+
+ uint32 teleportSpells[NUM_TELEPORT_SPELLS] =
+ {
+ SPELL_TELE_SPAWN,
+ SPELL_TELE_UPPER,
+ SPELL_TELE_STAIRS
+ };
+
+ void KilledUnit(Unit* who) override
+ {
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
+ }
+
+ void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) override
+ {
+ if (spell->Id == SPELL_ARUGAL_CURSE)
+ Talk(SAY_TRANSFORM);
+ }
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ _EnterCombat();
+ Talk(SAY_AGGRO);
+ events.ScheduleEvent(EVENT_CURSE, Seconds(7));
+ events.ScheduleEvent(EVENT_TELEPORT, Seconds(15));
+ events.ScheduleEvent(EVENT_VOID_BOLT, Seconds(1));
+ events.ScheduleEvent(EVENT_THUNDERSHOCK, Seconds(10));
+ }
+
+ void AttackStart(Unit* who) override
+ {
+ AttackStartCaster(who, 100.0f); // void bolt range is 100.f
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_CURSE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 30.0f, true))
+ DoCast(target, SPELL_ARUGAL_CURSE);
+ events.Repeat(Seconds(15));
+ break;
+ case EVENT_TELEPORT:
+ {
+ // ensure we never cast the same teleport twice in a row
+ uint8 spellIndex = urand(1, NUM_TELEPORT_SPELLS-1);
+ std::swap(teleportSpells[0], teleportSpells[spellIndex]);
+ DoCast(teleportSpells[0]);
+ events.Repeat(Seconds(20));
+ break;
+ }
+ case EVENT_THUNDERSHOCK:
+ DoCastAOE(SPELL_THUNDERSHOCK);
+ events.Repeat(Seconds(30));
+ break;
+ case EVENT_VOID_BOLT:
+ DoCastVictim(SPELL_VOIDBOLT);
+ events.Repeat(Seconds(5));
+ break;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_archmage_arugalAI>(creature);
+ }
+};
+
class spell_shadowfang_keep_haunting_spirits : public SpellScriptLoader
{
public:
@@ -248,5 +364,6 @@ void AddSC_shadowfang_keep()
{
new npc_shadowfang_prisoner();
new npc_arugal_voidwalker();
+ new boss_archmage_arugal();
new spell_shadowfang_keep_haunting_spirits();
}
diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.h b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.h
index 88edc3f1ee1..7e508191f69 100644
--- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.h
+++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.h
@@ -26,8 +26,8 @@ enum DataTypes
TYPE_FREE_NPC = 1,
TYPE_RETHILGORE = 2,
TYPE_FENRUS = 3,
- TYPE_NANDOS = 4
+ TYPE_NANDOS = 4,
+ BOSS_ARUGAL = 5
};
#endif
-
diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
index adcb4f9fc9a..d9c929794cc 100644
--- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
+++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
@@ -175,7 +175,7 @@ void AddSC_arathi_highlands();
void AddSC_blasted_lands();
void AddSC_burning_steppes();
void AddSC_duskwood();
-void AddSC_eastern_plaguelands();
+//void AddSC_eastern_plaguelands();
void AddSC_ghostlands();
void AddSC_hinterlands();
void AddSC_isle_of_queldanas();
@@ -352,7 +352,7 @@ void AddEasternKingdomsScripts()
AddSC_blasted_lands();
AddSC_burning_steppes();
AddSC_duskwood();
- AddSC_eastern_plaguelands();
+ //AddSC_eastern_plaguelands();
AddSC_ghostlands();
AddSC_hinterlands();
AddSC_isle_of_queldanas();
diff --git a/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp
deleted file mode 100644
index c35c8629cef..00000000000
--- a/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-/* ScriptData
-SDName: Eastern_Plaguelands
-SD%Complete: 100
-SDComment: Quest support: 5211. Special vendor Augustus the Touched
-SDCategory: Eastern Plaguelands
-EndScriptData */
-
-/* ContentData
-npc_ghoul_flayer
-npc_augustus_the_touched
-npc_darrowshire_spirit
-EndContentData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedGossip.h"
-#include "Player.h"
-#include "WorldSession.h"
-
-class npc_ghoul_flayer : public CreatureScript
-{
-public:
- npc_ghoul_flayer() : CreatureScript("npc_ghoul_flayer") { }
-
- struct npc_ghoul_flayerAI : public ScriptedAI
- {
- npc_ghoul_flayerAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() override { }
-
- void EnterCombat(Unit* /*who*/) override { }
-
- void JustDied(Unit* killer) override
- {
- if (killer->GetTypeId() == TYPEID_PLAYER)
- me->SummonCreature(11064, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 60000);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_ghoul_flayerAI(creature);
- }
-};
-
-/*######
-## npc_augustus_the_touched
-######*/
-
-class npc_augustus_the_touched : public CreatureScript
-{
-public:
- npc_augustus_the_touched() : CreatureScript("npc_augustus_the_touched") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- ClearGossipMenuFor(player);
- if (action == GOSSIP_ACTION_TRADE)
- player->GetSession()->SendListInventory(creature->GetGUID());
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (creature->IsVendor() && player->GetQuestRewardStatus(6164))
- AddGossipItemFor(player, GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
-
- SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
- return true;
- }
-};
-
-/*######
-## npc_darrowshire_spirit
-######*/
-
-enum DarrowshireSpirit
-{
- SPELL_SPIRIT_SPAWNIN = 17321
-};
-
-class npc_darrowshire_spirit : public CreatureScript
-{
-public:
- npc_darrowshire_spirit() : CreatureScript("npc_darrowshire_spirit") { }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- SendGossipMenuFor(player, 3873, creature->GetGUID());
- player->TalkedToCreature(creature->GetEntry(), creature->GetGUID());
- creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_darrowshire_spiritAI(creature);
- }
-
- struct npc_darrowshire_spiritAI : public ScriptedAI
- {
- npc_darrowshire_spiritAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() override
- {
- DoCast(me, SPELL_SPIRIT_SPAWNIN);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
-
- void EnterCombat(Unit* /*who*/) override { }
- };
-};
-
-void AddSC_eastern_plaguelands()
-{
- new npc_ghoul_flayer();
- new npc_augustus_the_touched();
- new npc_darrowshire_spirit();
-}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp
index 137da1002af..34a456ae502 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp
@@ -16,19 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
-Name: The_Black_Morass
-%Complete: 30
-Comment: Misc NPC's and mobs for instance. Most here far from complete.
-Category: Caverns of Time, The Black Morass
-*/
-
-/* ContentData
-npc_medivh_bm
-npc_time_rift
-npc_saat
-EndContentData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
@@ -365,57 +352,8 @@ public:
};
-enum Saat
-{
- SPELL_CHRONO_BEACON = 34975,
- ITEM_CHRONO_BEACON = 24289
-};
-
-#define GOSSIP_ITEM_OBTAIN "[PH] Obtain Chrono-Beacon"
-
-class npc_saat : public CreatureScript
-{
-public:
- npc_saat() : CreatureScript("npc_saat") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- ClearGossipMenuFor(player);
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- CloseGossipMenuFor(player);
- creature->CastSpell(player, SPELL_CHRONO_BEACON, false);
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE && !player->HasItemCount(ITEM_CHRONO_BEACON))
- {
- AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_OBTAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- SendGossipMenuFor(player, 10000, creature->GetGUID());
- return true;
- }
- else if (player->GetQuestRewardStatus(QUEST_OPENING_PORTAL) && !player->HasItemCount(ITEM_CHRONO_BEACON))
- {
- AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_OBTAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- SendGossipMenuFor(player, 10001, creature->GetGUID());
- return true;
- }
-
- SendGossipMenuFor(player, 10002, creature->GetGUID());
- return true;
- }
-
-};
-
void AddSC_the_black_morass()
{
new npc_medivh_bm();
new npc_time_rift();
- new npc_saat();
}
diff --git a/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp b/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp
index b7f88200077..7a7c104bdba 100644
--- a/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp
+++ b/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp
@@ -16,18 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Stonetalon_Mountains
-SD%Complete: 95
-SDComment: Quest support: 6627, 6523
-SDCategory: Stonetalon Mountains
-EndScriptData */
-
-/* ContentData
-npc_braug_dimspirit
-npc_kaya_flathoof
-EndContentData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
@@ -35,61 +23,6 @@ EndContentData */
#include "Player.h"
/*######
-## npc_braug_dimspirit
-######*/
-
-#define GOSSIP_HBD1 "Ysera"
-#define GOSSIP_HBD2 "Neltharion"
-#define GOSSIP_HBD3 "Nozdormu"
-#define GOSSIP_HBD4 "Alexstrasza"
-#define GOSSIP_HBD5 "Malygos"
-
-class npc_braug_dimspirit : public CreatureScript
-{
-public:
- npc_braug_dimspirit() : CreatureScript("npc_braug_dimspirit") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- ClearGossipMenuFor(player);
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- CloseGossipMenuFor(player);
- creature->CastSpell(player, 6766, false);
-
- }
- if (action == GOSSIP_ACTION_INFO_DEF+2)
- {
- CloseGossipMenuFor(player);
- player->AreaExploredOrEventHappens(6627);
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(6627) == QUEST_STATUS_INCOMPLETE)
- {
- AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HBD1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HBD2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HBD3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HBD4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HBD5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- SendGossipMenuFor(player, 5820, creature->GetGUID());
- }
- else
- SendGossipMenuFor(player, 5819, creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
## npc_kaya_flathoof
######*/
@@ -174,6 +107,5 @@ public:
void AddSC_stonetalon_mountains()
{
- new npc_braug_dimspirit();
new npc_kaya_flathoof();
}
diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h
index 685d0f51edd..2eda9509bb8 100644
--- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h
+++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h
@@ -33,7 +33,8 @@ enum DataTypes
DATA_WATCHER_NARJIL,
DATA_WATCHER_GASHRA,
DATA_WATCHER_SILTHIK,
- DATA_ANUBARAK_WALL
+ DATA_ANUBARAK_WALL,
+ DATA_ANUBARAK_WALL_2
};
enum CreatureIds
diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp
index 06a91d58705..2860698a8b2 100644
--- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp
@@ -121,12 +121,16 @@ public:
_petCount = 0;
}
+ bool CanAIAttack(Unit const* /*who*/) const override { return true; } // do not check boundary here
+
void EnterCombat(Unit* who) override
{
BossAI::EnterCombat(who);
if (GameObject* door = instance->GetGameObject(DATA_ANUBARAK_WALL))
door->SetGoState(GO_STATE_ACTIVE); // open door for now
+ if (GameObject* door2 = instance->GetGameObject(DATA_ANUBARAK_WALL_2))
+ door2->SetGoState(GO_STATE_ACTIVE);
Talk(SAY_AGGRO);
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_GOTTA_GO_START_EVENT);
@@ -179,6 +183,8 @@ public:
case EVENT_CLOSE_DOOR:
if (GameObject* door = instance->GetGameObject(DATA_ANUBARAK_WALL))
door->SetGoState(GO_STATE_READY);
+ if (GameObject* door2 = instance->GetGameObject(DATA_ANUBARAK_WALL_2))
+ door2->SetGoState(GO_STATE_READY);
break;
case EVENT_POUND:
DoCastVictim(SPELL_POUND);
diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp
index 7338774c21e..c41ec1c488d 100644
--- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp
@@ -789,7 +789,7 @@ struct npc_hadronox_foeAI : public ScriptedAI
me->GetMotionMaster()->MovePoint(MOVE_HADRONOX, hadronoxStep[2]);
break;
}
- me->GetMotionMaster()->MoveChase(hadronox);
+ AttackStart(hadronox);
}
break;
}
diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp
index ea912da4c3d..0d52a09bbdc 100644
--- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp
@@ -138,10 +138,10 @@ class boss_krik_thir : public CreatureScript
for (uint8 i = 1; i <= 3; ++i)
{
- std::list<TempSummon*> summons;
- me->SummonCreatureGroup(i, &summons);
- for (TempSummon* summon : summons)
- summon->AI()->SetData(DATA_PET_GROUP, i);
+ std::list<TempSummon*> adds;
+ me->SummonCreatureGroup(i, &adds);
+ for (TempSummon* add : adds)
+ add->AI()->SetData(DATA_PET_GROUP, i);
}
}
@@ -416,10 +416,7 @@ class npc_watcher_gashra : public CreatureScript
struct npc_watcher_gashraAI : public npc_gatewatcher_petAI
{
- npc_watcher_gashraAI(Creature* creature) : npc_gatewatcher_petAI(creature, true)
- {
- me->SetReactState(REACT_PASSIVE);
- }
+ npc_watcher_gashraAI(Creature* creature) : npc_gatewatcher_petAI(creature, true) { }
void Reset() override
{
@@ -928,11 +925,15 @@ class spell_gatewatcher_subboss_trigger : public SpellScriptLoader
void HandleTargets(std::list<WorldObject*>& targetList)
{
// Remove any Watchers that are already in combat
- for (std::list<WorldObject*>::iterator it = targetList.begin(); it != targetList.end(); ++it)
+ auto it = targetList.begin();
+ while (it != targetList.end())
{
if (Creature* creature = (*it)->ToCreature())
if (creature->IsAlive() && !creature->IsInCombat())
+ {
+ ++it;
continue;
+ }
it = targetList.erase(it);
}
diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp
index 8af4f6cecc4..7f0ce5c369e 100644
--- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp
@@ -41,7 +41,8 @@ ObjectData const creatureData[] =
ObjectData const gameobjectData[] =
{
- { GO_ANUBARAK_DOOR_3, DATA_ANUBARAK_WALL },
+ { GO_ANUBARAK_DOOR_1, DATA_ANUBARAK_WALL },
+ { GO_ANUBARAK_DOOR_3, DATA_ANUBARAK_WALL_2 },
{ 0, 0 } // END
};
@@ -77,6 +78,17 @@ class instance_azjol_nerub : public InstanceMapScript
if (Creature* gatewatcher = GetCreature(DATA_KRIKTHIR))
gatewatcher->AI()->DoAction(-ACTION_GATEWATCHER_GREET);
}
+
+ bool CheckRequiredBosses(uint32 bossId, Player const* player) const override
+ {
+ if (_SkipCheckRequiredBosses(player))
+ return true;
+
+ if (bossId > DATA_KRIKTHIR && GetBossState(DATA_KRIKTHIR) != DONE)
+ return false;
+
+ return true;
+ }
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
index 1041d250cc7..976ef3e34db 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
@@ -16,9 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-// Known bugs:
-// Gormok - Snobolled (creature at back)
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "trial_of_the_crusader.h"
@@ -71,14 +68,16 @@ enum BossSpells
//Gormok
SPELL_IMPALE = 66331,
SPELL_STAGGERING_STOMP = 67648,
- SPELL_RISING_ANGER = 66636,
//Snobold
+ SPELL_RISING_ANGER = 66636,
SPELL_SNOBOLLED = 66406,
SPELL_BATTER = 66408,
SPELL_FIRE_BOMB = 66313,
SPELL_FIRE_BOMB_1 = 66317,
SPELL_FIRE_BOMB_DOT = 66318,
SPELL_HEAD_CRACK = 66407,
+ SPELL_JUMP_TO_HAND = 66342,
+ SPELL_RIDE_PLAYER = 66245,
//Acidmaw & Dreadscale Generic
SPELL_SWEEP = 66794,
@@ -117,38 +116,41 @@ enum BossSpells
enum MyActions
{
ACTION_ENABLE_FIRE_BOMB = 1,
- ACTION_DISABLE_FIRE_BOMB = 2
+ ACTION_DISABLE_FIRE_BOMB = 2,
+ ACTION_ACTIVE_SNOBOLD = 3
};
enum Events
{
// Gormok
EVENT_IMPALE = 1,
- EVENT_STAGGERING_STOMP = 2,
- EVENT_THROW = 3,
+ EVENT_STAGGERING_STOMP,
+ EVENT_THROW,
// Snobold
- EVENT_FIRE_BOMB = 4,
- EVENT_BATTER = 5,
- EVENT_HEAD_CRACK = 6,
+ EVENT_FIRE_BOMB,
+ EVENT_BATTER,
+ EVENT_HEAD_CRACK,
+ EVENT_SNOBOLLED,
+ EVENT_CHECK_MOUNT,
// Acidmaw & Dreadscale
- EVENT_BITE = 7,
- EVENT_SPEW = 8,
- EVENT_SLIME_POOL = 9,
- EVENT_SPIT = 10,
- EVENT_SPRAY = 11,
- EVENT_SWEEP = 12,
- EVENT_SUBMERGE = 13,
- EVENT_EMERGE = 14,
- EVENT_SUMMON_ACIDMAW = 15,
+ EVENT_BITE,
+ EVENT_SPEW,
+ EVENT_SLIME_POOL,
+ EVENT_SPIT,
+ EVENT_SPRAY,
+ EVENT_SWEEP,
+ EVENT_SUBMERGE,
+ EVENT_EMERGE,
+ EVENT_SUMMON_ACIDMAW,
// Icehowl
- EVENT_FEROCIOUS_BUTT = 16,
- EVENT_MASSIVE_CRASH = 17,
- EVENT_WHIRL = 18,
- EVENT_ARCTIC_BREATH = 19,
- EVENT_TRAMPLE = 20
+ EVENT_FEROCIOUS_BUTT,
+ EVENT_MASSIVE_CRASH,
+ EVENT_WHIRL,
+ EVENT_ARCTIC_BREATH,
+ EVENT_TRAMPLE
};
enum Phases
@@ -158,6 +160,13 @@ enum Phases
PHASE_SUBMERGED = 3
};
+enum GormokMisc
+{
+ DATA_NEW_TARGET = 1,
+ GORMOK_HAND_SEAT = 4,
+ PLAYER_VEHICLE_ID = 444,
+};
+
class boss_gormok : public CreatureScript
{
public:
@@ -169,9 +178,9 @@ class boss_gormok : public CreatureScript
void Reset() override
{
- events.ScheduleEvent(EVENT_IMPALE, urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS));
- events.ScheduleEvent(EVENT_STAGGERING_STOMP, 15*IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_THROW, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_IMPALE, Seconds(8), Seconds(10));
+ events.ScheduleEvent(EVENT_STAGGERING_STOMP, Seconds(15));
+ events.ScheduleEvent(EVENT_THROW, Seconds(15), Seconds(30));
summons.DespawnAll();
}
@@ -216,18 +225,7 @@ class boss_gormok : public CreatureScript
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
- me->SetInCombatWithZone();
instance->SetData(TYPE_NORTHREND_BEASTS, GORMOK_IN_PROGRESS);
-
- for (uint8 i = 0; i < MAX_SNOBOLDS; i++)
- {
- if (Creature* pSnobold = DoSpawnCreature(NPC_SNOBOLD_VASSAL, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0))
- {
- pSnobold->EnterVehicle(me, i);
- pSnobold->SetInCombatWithZone();
- pSnobold->AI()->DoAction(ACTION_ENABLE_FIRE_BOMB);
- }
- }
}
void DamageTaken(Unit* /*who*/, uint32& damage) override
@@ -235,8 +233,14 @@ class boss_gormok : public CreatureScript
// despawn the remaining passengers on death
if (damage >= me->GetHealth())
for (uint8 i = 0; i < MAX_SNOBOLDS; ++i)
- if (Unit* pSnobold = me->GetVehicleKit()->GetPassenger(i))
- pSnobold->ToCreature()->DespawnOrUnsummon();
+ if (Unit* snobold = me->GetVehicleKit()->GetPassenger(i))
+ snobold->ToCreature()->DespawnOrUnsummon();
+ }
+
+ void PassengerBoarded(Unit* who, int8 seatId, bool apply) override
+ {
+ if (apply && seatId == GORMOK_HAND_SEAT)
+ who->CastSpell(me, SPELL_RISING_ANGER, true);
}
void UpdateAI(uint32 diff) override
@@ -255,30 +259,28 @@ class boss_gormok : public CreatureScript
{
case EVENT_IMPALE:
DoCastVictim(SPELL_IMPALE);
- events.ScheduleEvent(EVENT_IMPALE, urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS));
- return;
+ events.Repeat(Seconds(8), Seconds(10));
+ break;
case EVENT_STAGGERING_STOMP:
DoCastVictim(SPELL_STAGGERING_STOMP);
- events.ScheduleEvent(EVENT_STAGGERING_STOMP, 15*IN_MILLISECONDS);
- return;
+ events.Repeat(Seconds(15));
+ break;
case EVENT_THROW:
for (uint8 i = 0; i < MAX_SNOBOLDS; ++i)
{
- if (Unit* pSnobold = me->GetVehicleKit()->GetPassenger(i))
+ if (Unit* snobold = me->GetVehicleKit()->GetPassenger(i))
{
- pSnobold->ExitVehicle();
- pSnobold->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- pSnobold->ToCreature()->SetReactState(REACT_AGGRESSIVE);
- pSnobold->ToCreature()->AI()->DoAction(ACTION_DISABLE_FIRE_BOMB);
- pSnobold->CastSpell(me, SPELL_RISING_ANGER, true);
- Talk(EMOTE_SNOBOLLED);
+ snobold->ExitVehicle();
+ snobold->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ snobold->GetAI()->DoAction(ACTION_DISABLE_FIRE_BOMB);
+ snobold->CastSpell(me, SPELL_JUMP_TO_HAND, true);
break;
}
}
- events.ScheduleEvent(EVENT_THROW, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
- return;
+ events.Repeat(Seconds(15), Seconds(30));
+ break;
default:
- return;
+ break;
}
}
@@ -292,6 +294,23 @@ class boss_gormok : public CreatureScript
}
};
+class SnobolledTargetSelector : public std::unary_function<Unit*, bool>
+{
+public:
+ SnobolledTargetSelector(Unit const* /*unit*/) { }
+
+ bool operator()(Unit* unit) const
+ {
+ if (unit->GetTypeId() != TYPEID_PLAYER)
+ return false;
+
+ if (unit->HasAura(SPELL_RIDE_PLAYER) || unit->HasAura(SPELL_SNOBOLLED))
+ return false;
+
+ return true;
+ }
+};
+
class npc_snobold_vassal : public CreatureScript
{
public:
@@ -299,59 +318,24 @@ class npc_snobold_vassal : public CreatureScript
struct npc_snobold_vassalAI : public ScriptedAI
{
- npc_snobold_vassalAI(Creature* creature) : ScriptedAI(creature)
+ npc_snobold_vassalAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _isActive(false)
{
- _targetDied = false;
- _instance = creature->GetInstanceScript();
_instance->SetData(DATA_SNOBOLD_COUNT, INCREASE);
+ SetCombatMovement(false);
}
void Reset() override
{
- _events.ScheduleEvent(EVENT_BATTER, 5*IN_MILLISECONDS);
- _events.ScheduleEvent(EVENT_HEAD_CRACK, 25*IN_MILLISECONDS);
-
- _targetGUID.Clear();
- _targetDied = false;
-
- //Workaround for Snobold
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- }
-
- void EnterCombat(Unit* who) override
- {
- _targetGUID = who->GetGUID();
- me->TauntApply(who);
- DoCast(who, SPELL_SNOBOLLED);
- }
-
- void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) override
- {
- if (pDoneBy->GetGUID() == _targetGUID)
- uiDamage = 0;
- }
-
- void MovementInform(uint32 type, uint32 pointId) override
- {
- if (type != POINT_MOTION_TYPE)
- return;
-
- switch (pointId)
- {
- case 0:
- if (_targetDied)
- me->DespawnOrUnsummon();
- break;
- default:
- break;
- }
+ me->SetInCombatWithZone();
+ _events.ScheduleEvent(EVENT_CHECK_MOUNT, Seconds(1));
+ _events.ScheduleEvent(EVENT_FIRE_BOMB, Seconds(5), Seconds(30));
}
void JustDied(Unit* /*killer*/) override
{
if (Unit* target = ObjectAccessor::GetPlayer(*me, _targetGUID))
- if (target->IsAlive())
- target->RemoveAurasDueToSpell(SPELL_SNOBOLLED);
+ target->RemoveAurasDueToSpell(SPELL_SNOBOLLED);
_instance->SetData(DATA_SNOBOLD_COUNT, DECREASE);
}
@@ -360,50 +344,69 @@ class npc_snobold_vassal : public CreatureScript
switch (action)
{
case ACTION_ENABLE_FIRE_BOMB:
- _events.ScheduleEvent(EVENT_FIRE_BOMB, urand(5*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ _events.ScheduleEvent(EVENT_FIRE_BOMB, Seconds(5), Seconds(30));
break;
case ACTION_DISABLE_FIRE_BOMB:
_events.CancelEvent(EVENT_FIRE_BOMB);
break;
+ case ACTION_ACTIVE_SNOBOLD:
+ _isActive = true;
+ break;
default:
break;
}
}
- void UpdateAI(uint32 diff) override
+ void SetGUID(ObjectGuid guid, int32 id) override
{
- if (!UpdateVictim() || _targetDied)
+ if (id == DATA_NEW_TARGET)
+ if (Unit* target = ObjectAccessor::GetPlayer(*me, guid))
+ {
+ _targetGUID = guid;
+ AttackStart(target);
+ _events.ScheduleEvent(EVENT_BATTER, Seconds(5));
+ _events.ScheduleEvent(EVENT_HEAD_CRACK, Seconds(25));
+ _events.ScheduleEvent(EVENT_SNOBOLLED, Milliseconds(500));
+ }
+ }
+
+ void AttackStart(Unit* who) override
+ {
+ //Snobold only melee attack players that is your vehicle
+ if (!_isActive || who->GetGUID() != _targetGUID)
return;
- if (Unit* target = ObjectAccessor::GetPlayer(*me, _targetGUID))
+ ScriptedAI::AttackStart(who);
+ }
+
+ void MountOnBoss()
+ {
+ Unit* gormok = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_GORMOK));
+ if (gormok && gormok->IsAlive())
{
- if (!target->IsAlive())
- {
- Unit* gormok = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_GORMOK));
- if (gormok && gormok->IsAlive())
- {
- SetCombatMovement(false);
- _targetDied = true;
+ me->AttackStop();
+ _targetGUID.Clear();
+ _isActive = false;
+ _events.CancelEvent(EVENT_BATTER);
+ _events.CancelEvent(EVENT_HEAD_CRACK);
- // looping through Gormoks seats
- for (uint8 i = 0; i < MAX_SNOBOLDS; i++)
- {
- if (!gormok->GetVehicleKit()->GetPassenger(i))
- {
- me->EnterVehicle(gormok, i);
- DoAction(ACTION_ENABLE_FIRE_BOMB);
- break;
- }
- }
- }
- else if (Unit* target2 = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ for (uint8 i = 0; i < MAX_SNOBOLDS; i++)
+ {
+ if (!gormok->GetVehicleKit()->GetPassenger(i))
{
- _targetGUID = target2->GetGUID();
- me->GetMotionMaster()->MoveJump(*target2, 15.0f, 15.0f);
+ me->EnterVehicle(gormok, i);
+ DoAction(ACTION_ENABLE_FIRE_BOMB);
+ break;
}
}
}
+ //Without Boss, snobolds should jump in another players
+ else if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, SnobolledTargetSelector(me)))
+ me->CastSpell(target, SPELL_RIDE_PLAYER, true);
+ }
+ void UpdateAI(uint32 diff) override
+ {
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
@@ -416,35 +419,46 @@ class npc_snobold_vassal : public CreatureScript
case EVENT_FIRE_BOMB:
if (me->GetVehicleBase())
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, -me->GetVehicleBase()->GetCombatReach(), true))
- me->CastSpell(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), SPELL_FIRE_BOMB, true);
- _events.ScheduleEvent(EVENT_FIRE_BOMB, 20*IN_MILLISECONDS);
- return;
+ me->CastSpell(target, SPELL_FIRE_BOMB);
+ _events.Repeat(Seconds(20));
+ break;
case EVENT_HEAD_CRACK:
- // commented out while SPELL_SNOBOLLED gets fixed
- //if (Unit* target = ObjectAccessor::GetPlayer(*me, m_uiTargetGUID))
- DoCastVictim(SPELL_HEAD_CRACK);
- _events.ScheduleEvent(EVENT_HEAD_CRACK, 30*IN_MILLISECONDS);
- return;
+ DoCast(me->GetVehicleBase(), SPELL_HEAD_CRACK);
+ _events.Repeat(Seconds(30));
+ break;
case EVENT_BATTER:
- // commented out while SPELL_SNOBOLLED gets fixed
- //if (Unit* target = ObjectAccessor::GetPlayer(*me, m_uiTargetGUID))
- DoCastVictim(SPELL_BATTER);
- _events.ScheduleEvent(EVENT_BATTER, 10*IN_MILLISECONDS);
- return;
+ DoCast(me->GetVehicleBase(), SPELL_BATTER);
+ _events.Repeat(Seconds(10));
+ break;
+ case EVENT_SNOBOLLED:
+ DoCastAOE(SPELL_SNOBOLLED);
+ break;
+ case EVENT_CHECK_MOUNT:
+ if (!me->GetVehicleBase())
+ MountOnBoss();
+ _events.Repeat(Seconds(1));
+ break;
default:
- return;
+ break;
}
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
}
- // do melee attack only when not on Gormoks back
- if (!me->GetVehicleBase())
+ if (!UpdateVictim())
+ return;
+
+ // do melee attack only if is in player back.
+ if (_isActive)
DoMeleeAttackIfReady();
}
+
private:
EventMap _events;
InstanceScript* _instance;
ObjectGuid _targetGUID;
- bool _targetDied;
+ bool _isActive;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -1145,6 +1159,138 @@ class boss_icehowl : public CreatureScript
}
};
+class spell_gormok_jump_to_hand : public SpellScriptLoader
+{
+public:
+ spell_gormok_jump_to_hand() : SpellScriptLoader("spell_gormok_jump_to_hand") { }
+
+ class spell_gormok_jump_to_hand_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gormok_jump_to_hand_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_RIDE_PLAYER))
+ return false;
+ return true;
+ }
+
+ bool Load() override
+ {
+ if (GetCaster() && GetCaster()->GetEntry() == NPC_SNOBOLD_VASSAL)
+ return true;
+ return false;
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ {
+ if (CreatureAI* gormokAI = GetTarget()->ToCreature()->AI())
+ {
+ if (Unit* target = gormokAI->SelectTarget(SELECT_TARGET_RANDOM, 0, SnobolledTargetSelector(GetTarget())))
+ {
+ gormokAI->Talk(EMOTE_SNOBOLLED);
+ caster->GetAI()->DoAction(ACTION_ACTIVE_SNOBOLD);
+ caster->CastSpell(target, SPELL_RIDE_PLAYER, true);
+ }
+ }
+ }
+ }
+
+ void Register() override
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_gormok_jump_to_hand_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_CONTROL_VEHICLE, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_gormok_jump_to_hand_AuraScript();
+ }
+};
+
+class spell_gormok_ride_player : public SpellScriptLoader
+{
+public:
+ spell_gormok_ride_player() : SpellScriptLoader("spell_gormok_ride_player") { }
+
+ class spell_gormok_ride_player_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gormok_ride_player_AuraScript);
+
+ bool Load() override
+ {
+ if (GetCaster() && GetCaster()->GetEntry() == NPC_SNOBOLD_VASSAL)
+ return true;
+ return false;
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+ if (target->GetTypeId() != TYPEID_PLAYER || !target->IsInWorld())
+ return;
+
+ if (!target->CreateVehicleKit(PLAYER_VEHICLE_ID, 0))
+ return;
+
+ if (Unit *caster = GetCaster())
+ caster->GetAI()->SetGUID(target->GetGUID(), DATA_NEW_TARGET);
+ }
+
+ void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveVehicleKit();
+ }
+
+ void Register() override
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_gormok_ride_player_AuraScript::OnApply, EFFECT_0, SPELL_AURA_CONTROL_VEHICLE, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_gormok_ride_player_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_CONTROL_VEHICLE, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_gormok_ride_player_AuraScript();
+ }
+};
+
+class spell_gormok_snobolled : public SpellScriptLoader
+{
+public:
+ spell_gormok_snobolled() : SpellScriptLoader("spell_gormok_snobolled") { }
+
+ class spell_gormok_snobolled_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gormok_snobolled_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_RIDE_PLAYER))
+ return false;
+ return true;
+ }
+
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ if (!GetTarget()->HasAura(SPELL_RIDE_PLAYER))
+ Remove();
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_gormok_snobolled_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_gormok_snobolled_AuraScript();
+ }
+};
+
class spell_jormungars_paralytic_toxin : public SpellScriptLoader
{
public:
@@ -1293,6 +1439,9 @@ void AddSC_boss_northrend_beasts()
new npc_snobold_vassal();
new npc_firebomb();
new spell_gormok_fire_bomb();
+ new spell_gormok_jump_to_hand();
+ new spell_gormok_ride_player();
+ new spell_gormok_snobolled();
new boss_acidmaw();
new boss_dreadscale();
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
index 5f884ccee9e..85126b35cdb 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
@@ -56,21 +56,26 @@ enum Spells
SPELL_MANA_BARRIER = 70842,
SPELL_SHADOW_BOLT = 71254,
SPELL_DEATH_AND_DECAY = 71001,
- SPELL_DOMINATE_MIND_H = 71289,
+ SPELL_DOMINATE_MIND = 71289,
+ SPELL_DOMINATE_MIND_SCALE = 71290,
SPELL_FROSTBOLT = 71420,
SPELL_FROSTBOLT_VOLLEY = 72905,
SPELL_TOUCH_OF_INSIGNIFICANCE = 71204,
SPELL_SUMMON_SHADE = 71363,
- SPELL_SHADOW_CHANNELING = 43897, // Prefight, during intro
+ SPELL_SHADOW_CHANNELING = 43897,
SPELL_DARK_TRANSFORMATION_T = 70895,
SPELL_DARK_EMPOWERMENT_T = 70896,
SPELL_DARK_MARTYRDOM_T = 70897,
+ SPELL_SUMMON_SPIRITS = 72478,
// Achievement
SPELL_FULL_HOUSE = 72827, // does not exist in dbc but still can be used for criteria check
// Both Adds
SPELL_TELEPORT_VISUAL = 41236,
+ SPELL_CLEAR_ALL_DEBUFFS = 34098,
+ SPELL_FULL_HEAL = 17683,
+ SPELL_PERMANENT_FEIGN_DEATH = 70628,
// Fanatics
SPELL_DARK_TRANSFORMATION = 70900,
@@ -86,7 +91,7 @@ enum Spells
SPELL_DEATHCHILL_BOLT = 70594,
SPELL_DEATHCHILL_BLAST = 70906,
SPELL_CURSE_OF_TORPOR = 71237,
- SPELL_SHORUD_OF_THE_OCCULT = 70768,
+ SPELL_SHROUD_OF_THE_OCCULT = 70768,
SPELL_ADHERENT_S_DETERMINATION = 71234,
SPELL_DARK_MARTYRDOM_ADHERENT = 70903,
@@ -108,44 +113,6 @@ enum Spells
enum EventTypes
{
- // Lady Deathwhisper
- EVENT_INTRO_2 = 1,
- EVENT_INTRO_3 = 2,
- EVENT_INTRO_4 = 3,
- EVENT_INTRO_5 = 4,
- EVENT_INTRO_6 = 5,
- EVENT_INTRO_7 = 6,
- EVENT_BERSERK = 7,
- EVENT_DEATH_AND_DECAY = 8,
- EVENT_DOMINATE_MIND_H = 9,
-
- // Phase 1 only
- EVENT_P1_SUMMON_WAVE = 10,
- EVENT_P1_SHADOW_BOLT = 11,
- EVENT_P1_EMPOWER_CULTIST = 12,
- EVENT_P1_REANIMATE_CULTIST = 13,
-
- // Phase 2 only
- EVENT_P2_SUMMON_WAVE = 14,
- EVENT_P2_FROSTBOLT = 15,
- EVENT_P2_FROSTBOLT_VOLLEY = 16,
- EVENT_P2_TOUCH_OF_INSIGNIFICANCE = 17,
- EVENT_P2_SUMMON_SHADE = 18,
-
- // Shared adds events
- EVENT_CULTIST_DARK_MARTYRDOM = 19,
-
- // Cult Fanatic
- EVENT_FANATIC_NECROTIC_STRIKE = 20,
- EVENT_FANATIC_SHADOW_CLEAVE = 21,
- EVENT_FANATIC_VAMPIRIC_MIGHT = 22,
-
- // Cult Adherent
- EVENT_ADHERENT_FROST_FEVER = 23,
- EVENT_ADHERENT_DEATHCHILL = 24,
- EVENT_ADHERENT_CURSE_OF_TORPOR = 25,
- EVENT_ADHERENT_SHORUD_OF_THE_OCCULT = 26,
-
// Darnavan
EVENT_DARNAVAN_BLADESTORM = 27,
EVENT_DARNAVAN_CHARGE = 28,
@@ -163,6 +130,13 @@ enum Phases
PHASE_TWO = 3
};
+enum Groups
+{
+ GROUP_INTRO = 0,
+ GROUP_ONE = 1,
+ GROUP_TWO = 2
+};
+
enum DeprogrammingData
{
NPC_DARNAVAN_10 = 38472,
@@ -185,8 +159,6 @@ enum Actions
uint32 const SummonEntries[2] = {NPC_CULT_FANATIC, NPC_CULT_ADHERENT};
-#define GUID_CULTIST 1
-
Position const SummonPositions[7] =
{
{-578.7066f, 2154.167f, 51.01529f, 1.692969f}, // 1 Left Door 1 (Cult Fanatic)
@@ -229,43 +201,67 @@ class boss_lady_deathwhisper : public CreatureScript
void Initialize()
{
_waveCounter = 0;
- _nextVengefulShadeTargetGUID.Clear();
+ _nextVengefulShadeTargetGUID.clear();
+ _cultistQueue.clear();
_darnavanGUID.Clear();
+ _phase = PHASE_ALL;
+ scheduler.SetValidator([this]
+ {
+ return !(me->HasUnitState(UNIT_STATE_CASTING) && _phase != PHASE_INTRO);
+ });
}
void Reset() override
{
- _Reset();
- me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA));
- events.SetPhase(PHASE_ONE);
Initialize();
- DoCast(me, SPELL_SHADOW_CHANNELING);
- me->RemoveAurasDueToSpell(SPELL_BERSERK);
- me->RemoveAurasDueToSpell(SPELL_MANA_BARRIER);
+ _phase = PHASE_ONE;
+ DoCastSelf(SPELL_SHADOW_CHANNELING);
+ me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA));
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false);
}
void DoAction(int32 action) override
{
- switch (action)
+ if (action != ACTION_START_INTRO)
+ return;
+
+ if (!_introDone)
{
- case ACTION_START_INTRO:
- if (!_introDone)
+ _introDone = true;
+ Talk(SAY_INTRO_1);
+ _phase = PHASE_INTRO;
+ scheduler.Schedule(Seconds(10), GROUP_INTRO, [this](TaskContext context)
+ {
+ switch (context.GetRepeatCounter())
{
- _introDone = true;
- Talk(SAY_INTRO_1);
- events.SetPhase(PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_2, 11000, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_3, 21000, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_4, 31500, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_5, 39500, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_6, 48500, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_7, 58000, 0, PHASE_INTRO);
+ case 0:
+ Talk(SAY_INTRO_2);
+ context.Repeat(Seconds(21));
+ break;
+ case 1:
+ Talk(SAY_INTRO_3);
+ context.Repeat(Seconds(11));
+ break;
+ case 2:
+ Talk(SAY_INTRO_4);
+ context.Repeat(Seconds(9));
+ break;
+ case 3:
+ Talk(SAY_INTRO_5);
+ context.Repeat(Seconds(21));
+ break;
+ case 4:
+ Talk(SAY_INTRO_6);
+ context.Repeat(Seconds(10));
+ break;
+ case 5:
+ Talk(SAY_INTRO_7);
+ return;
+ default:
+ break;
}
- break;
- default:
- break;
+ });
}
}
@@ -274,7 +270,7 @@ class boss_lady_deathwhisper : public CreatureScript
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
return;
- if (victim && me->Attack(victim, true) && !events.IsInPhase(PHASE_ONE))
+ if (victim && me->Attack(victim, true) && _phase != PHASE_ONE)
me->GetMotionMaster()->MoveChase(victim);
}
@@ -282,31 +278,61 @@ class boss_lady_deathwhisper : public CreatureScript
{
if (!instance->CheckRequiredBosses(DATA_LADY_DEATHWHISPER, who->ToPlayer()))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_SEQUENCE_BREAK);
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
return;
}
+ me->SetCombatPulseDelay(5);
me->setActive(true);
DoZoneInCombat();
-
- events.Reset();
- events.SetPhase(PHASE_ONE);
+ _phase = PHASE_ONE;
+ scheduler.CancelGroup(GROUP_INTRO);
// phase-independent events
- events.ScheduleEvent(EVENT_BERSERK, 600000);
- events.ScheduleEvent(EVENT_DEATH_AND_DECAY, 10000);
+ scheduler
+ .Schedule(Minutes(10), [this](TaskContext /*context*/)
+ {
+ DoCastSelf(SPELL_BERSERK);
+ Talk(SAY_BERSERK);
+ })
+ .Schedule(Seconds(17), [this](TaskContext death_and_decay)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_DEATH_AND_DECAY);
+ death_and_decay.Repeat(Seconds(22), Seconds(30));
+ });
+ if (GetDifficulty() != RAID_DIFFICULTY_10MAN_NORMAL)
+ scheduler.Schedule(Seconds(27), [this](TaskContext dominate_mind)
+ {
+ Talk(SAY_DOMINATE_MIND);
+ for (uint8 i = 0; i < _dominateMindCount; i++)
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_DOMINATE_MIND))
+ DoCast(target, SPELL_DOMINATE_MIND);
+ dominate_mind.Repeat(Seconds(40), Seconds(45));
+ });
// phase one only
- events.ScheduleEvent(EVENT_P1_SUMMON_WAVE, 5000, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_P1_SHADOW_BOLT, urand(5500, 6000), 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_P1_EMPOWER_CULTIST, urand(20000, 30000), 0, PHASE_ONE);
- if (GetDifficulty() != RAID_DIFFICULTY_10MAN_NORMAL)
- events.ScheduleEvent(EVENT_DOMINATE_MIND_H, 27000);
+ scheduler
+ .Schedule(Seconds(5), GROUP_ONE, [this](TaskContext wave)
+ {
+ SummonWaveP1();
+ wave.Repeat(Seconds(IsHeroic() ? 45 : 60));
+ })
+ .Schedule(Seconds(2), GROUP_ONE, [this](TaskContext shadow_bolt)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_SHADOW_BOLT);
+ shadow_bolt.Repeat(Milliseconds(2450), Milliseconds(3600));
+ })
+ .Schedule(Seconds(15), GROUP_ONE, [this](TaskContext context)
+ {
+ DoImproveCultist();
+ context.Repeat(Seconds(25));
+ });
Talk(SAY_AGGRO);
DoStartNoMovement(who);
me->RemoveAurasDueToSpell(SPELL_SHADOW_CHANNELING);
- DoCast(me, SPELL_MANA_BARRIER, true);
-
+ DoCastSelf(SPELL_MANA_BARRIER, true);
instance->SetBossState(DATA_LADY_DEATHWHISPER, IN_PROGRESS);
}
@@ -338,7 +364,7 @@ class boss_lady_deathwhisper : public CreatureScript
{
if (Group* group = owner->GetGroup())
{
- for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
if (Player* member = itr->GetSource())
member->KilledMonsterCredit(NPC_DARNAVAN_CREDIT);
}
@@ -351,17 +377,14 @@ class boss_lady_deathwhisper : public CreatureScript
_JustDied();
}
- void JustReachedHome() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
- _JustReachedHome();
- instance->SetBossState(DATA_LADY_DEATHWHISPER, FAIL);
-
+ scheduler.CancelAll();
summons.DespawnAll();
if (Creature* darnavan = ObjectAccessor::GetCreature(*me, _darnavanGUID))
- {
darnavan->DespawnOrUnsummon();
- _darnavanGUID.Clear();
- }
+
+ _DespawnAtEvade();
}
void KilledUnit(Unit* victim) override
@@ -373,151 +396,98 @@ class boss_lady_deathwhisper : public CreatureScript
void DamageTaken(Unit* /*damageDealer*/, uint32& damage) override
{
// phase transition
- if (events.IsInPhase(PHASE_ONE) && damage > me->GetPower(POWER_MANA))
+ if (_phase == PHASE_ONE && damage > me->GetPower(POWER_MANA))
{
+ _phase = PHASE_TWO;
Talk(SAY_PHASE_2);
Talk(EMOTE_PHASE_2);
DoStartMovement(me->GetVictim());
+ DoResetThreat();
damage -= me->GetPower(POWER_MANA);
me->SetPower(POWER_MANA, 0);
me->RemoveAurasDueToSpell(SPELL_MANA_BARRIER);
- events.SetPhase(PHASE_TWO);
- events.ScheduleEvent(EVENT_P2_FROSTBOLT, urand(10000, 12000), 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_P2_FROSTBOLT_VOLLEY, urand(19000, 21000), 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_P2_TOUCH_OF_INSIGNIFICANCE, urand(6000, 9000), 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_P2_SUMMON_SHADE, urand(12000, 15000), 0, PHASE_TWO);
+ scheduler.CancelGroup(GROUP_ONE);
+
+ scheduler
+ .Schedule(Seconds(12), GROUP_TWO, [this](TaskContext frostbolt)
+ {
+ DoCastVictim(SPELL_FROSTBOLT);
+ frostbolt.Repeat();
+ })
+ .Schedule(Seconds(20), GROUP_TWO, [this](TaskContext frostboldVolley)
+ {
+ DoCastAOE(SPELL_FROSTBOLT_VOLLEY);
+ frostboldVolley.Repeat();
+ })
+ .Schedule(Seconds(6), Seconds(9), GROUP_TWO, [this](TaskContext touch)
+ {
+ if (me->GetVictim())
+ me->AddAura(SPELL_TOUCH_OF_INSIGNIFICANCE, me->EnsureVictim());
+ touch.Repeat();
+ })
+ .Schedule(Seconds(12), GROUP_TWO, [this](TaskContext summonShade)
+ {
+ me->CastCustomSpell(SPELL_SUMMON_SPIRITS, SPELLVALUE_MAX_TARGETS, Is25ManRaid() ? 2 : 1);
+ summonShade.Repeat();
+ });
+
// on heroic mode Lady Deathwhisper is immune to taunt effects in phase 2 and continues summoning adds
if (IsHeroic())
{
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
- events.ScheduleEvent(EVENT_P2_SUMMON_WAVE, 45000, 0, PHASE_TWO);
+ scheduler.Schedule(Seconds(), GROUP_TWO, [this](TaskContext context)
+ {
+ SummonWaveP2();
+ context.Repeat(Seconds(45));
+ });
}
}
}
- void JustSummoned(Creature* summon) override
+ void SpellHitTarget(Unit* target, const SpellInfo* spell) override
{
- if (summon->GetEntry() == NPC_DARNAVAN)
- _darnavanGUID = summon->GetGUID();
- else
- summons.Summon(summon);
+ if (spell->Id == SPELL_SUMMON_SPIRITS)
+ _nextVengefulShadeTargetGUID.push_back(target->GetGUID());
+ }
- Unit* target = NULL;
- if (summon->GetEntry() == NPC_VENGEFUL_SHADE)
+ void JustSummoned(Creature* summon) override
+ {
+ switch (summon->GetEntry())
{
- target = ObjectAccessor::GetUnit(*me, _nextVengefulShadeTargetGUID); // Vengeful Shade
- _nextVengefulShadeTargetGUID.Clear();
+ case NPC_DARNAVAN_10:
+ case NPC_DARNAVAN_25:
+ _darnavanGUID = summon->GetGUID();
+ summon->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM));
+ return;
+ case NPC_VENGEFUL_SHADE:
+ if (_nextVengefulShadeTargetGUID.empty())
+ break;
+ summon->AI()->SetGUID(_nextVengefulShadeTargetGUID.front());
+ _nextVengefulShadeTargetGUID.pop_front();
+ break;
+ case NPC_CULT_ADHERENT:
+ case NPC_CULT_FANATIC:
+ _cultistQueue.push_back(summon->GetGUID());
+ summon->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM));
+ break;
+ default:
+ break;
}
- else
- target = SelectTarget(SELECT_TARGET_RANDOM); // Wave adds
-
- summon->AI()->AttackStart(target); // CAN be NULL
- if (summon->GetEntry() == NPC_REANIMATED_FANATIC)
- summon->CastSpell(summon, SPELL_FANATIC_S_DETERMINATION, true);
- else if (summon->GetEntry() == NPC_REANIMATED_ADHERENT)
- summon->CastSpell(summon, SPELL_ADHERENT_S_DETERMINATION, true);
+ summons.Summon(summon);
}
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO))
+ if (!UpdateVictim() && _phase != PHASE_INTRO)
return;
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING) && !events.IsInPhase(PHASE_INTRO))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ scheduler.Update(diff, [this]
{
- switch (eventId)
- {
- case EVENT_INTRO_2:
- Talk(SAY_INTRO_2);
- break;
- case EVENT_INTRO_3:
- Talk(SAY_INTRO_3);
- break;
- case EVENT_INTRO_4:
- Talk(SAY_INTRO_4);
- break;
- case EVENT_INTRO_5:
- Talk(SAY_INTRO_5);
- break;
- case EVENT_INTRO_6:
- Talk(SAY_INTRO_6);
- break;
- case EVENT_INTRO_7:
- Talk(SAY_INTRO_7);
- break;
- case EVENT_DEATH_AND_DECAY:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_DEATH_AND_DECAY);
- events.ScheduleEvent(EVENT_DEATH_AND_DECAY, urand(22000, 30000));
- break;
- case EVENT_DOMINATE_MIND_H:
- Talk(SAY_DOMINATE_MIND);
- for (uint8 i = 0; i < _dominateMindCount; i++)
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_DOMINATE_MIND_H))
- DoCast(target, SPELL_DOMINATE_MIND_H);
- events.ScheduleEvent(EVENT_DOMINATE_MIND_H, urand(40000, 45000));
- break;
- case EVENT_P1_SUMMON_WAVE:
- SummonWaveP1();
- events.ScheduleEvent(EVENT_P1_SUMMON_WAVE, IsHeroic() ? 45000 : 60000, 0, PHASE_ONE);
- break;
- case EVENT_P1_SHADOW_BOLT:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_SHADOW_BOLT);
- events.ScheduleEvent(EVENT_P1_SHADOW_BOLT, urand(5000, 8000), 0, PHASE_ONE);
- break;
- case EVENT_P1_REANIMATE_CULTIST:
- ReanimateCultist();
- break;
- case EVENT_P1_EMPOWER_CULTIST:
- EmpowerCultist();
- events.ScheduleEvent(EVENT_P1_EMPOWER_CULTIST, urand(18000, 25000));
- break;
- case EVENT_P2_FROSTBOLT:
- DoCastVictim(SPELL_FROSTBOLT);
- events.ScheduleEvent(EVENT_P2_FROSTBOLT, urand(10000, 11000), 0, PHASE_TWO);
- break;
- case EVENT_P2_FROSTBOLT_VOLLEY:
- DoCastAOE(SPELL_FROSTBOLT_VOLLEY);
- events.ScheduleEvent(EVENT_P2_FROSTBOLT_VOLLEY, urand(13000, 15000), 0, PHASE_TWO);
- break;
- case EVENT_P2_TOUCH_OF_INSIGNIFICANCE:
- DoCastVictim(SPELL_TOUCH_OF_INSIGNIFICANCE);
- events.ScheduleEvent(EVENT_P2_TOUCH_OF_INSIGNIFICANCE, urand(9000, 13000), 0, PHASE_TWO);
- break;
- case EVENT_P2_SUMMON_SHADE:
- if (Unit* shadeTarget = SelectTarget(SELECT_TARGET_RANDOM, 1))
- {
- _nextVengefulShadeTargetGUID = shadeTarget->GetGUID();
- DoCast(shadeTarget, SPELL_SUMMON_SHADE);
- }
- events.ScheduleEvent(EVENT_P2_SUMMON_SHADE, urand(18000, 23000), 0, PHASE_TWO);
- break;
- case EVENT_P2_SUMMON_WAVE:
- SummonWaveP2();
- events.ScheduleEvent(EVENT_P2_SUMMON_WAVE, 45000, 0, PHASE_TWO);
- break;
- case EVENT_BERSERK:
- DoCast(me, SPELL_BERSERK);
- Talk(SAY_BERSERK);
- break;
- }
-
- if (me->HasUnitState(UNIT_STATE_CASTING) && !events.IsInPhase(PHASE_INTRO))
- return;
- }
-
- // We should not melee attack when barrier is up
- if (me->HasAura(SPELL_MANA_BARRIER))
- return;
-
- DoMeleeAttackIfReady();
+ // We should not melee attack when barrier is up
+ if (!me->HasAura(SPELL_MANA_BARRIER))
+ DoMeleeAttackIfReady();
+ });
}
// summoning function for first phase
@@ -568,72 +538,40 @@ class boss_lady_deathwhisper : public CreatureScript
summon->CastSpell(summon, SPELL_TELEPORT_VISUAL);
}
- void SetGUID(ObjectGuid guid, int32 id/* = 0*/) override
+ void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
{
- if (id != GUID_CULTIST)
- return;
-
- _reanimationQueue.push_back(guid);
- events.ScheduleEvent(EVENT_P1_REANIMATE_CULTIST, 3000, 0, PHASE_ONE);
+ if (summon->GetEntry() == NPC_CULT_ADHERENT || summon->GetEntry() == NPC_CULT_FANATIC)
+ _cultistQueue.remove(summon->GetGUID());
}
- void ReanimateCultist()
+ void DoImproveCultist()
{
- if (_reanimationQueue.empty())
+ if (_cultistQueue.empty())
return;
- ObjectGuid cultistGUID = _reanimationQueue.front();
- Creature* cultist = ObjectAccessor::GetCreature(*me, cultistGUID);
- _reanimationQueue.pop_front();
+ _cultistGUID = Trinity::Containers::SelectRandomContainerElement(_cultistQueue);
+ _cultistQueue.remove(_cultistGUID);
+ Creature* cultist = ObjectAccessor::GetCreature(*me, _cultistGUID);
if (!cultist)
return;
- Talk(SAY_ANIMATE_DEAD);
- DoCast(cultist, SPELL_DARK_MARTYRDOM_T);
- }
-
- void SpellHitTarget(Unit* target, SpellInfo const* spell) override
- {
- if (spell->Id == SPELL_DARK_MARTYRDOM_T)
+ if (RAND(0,1))
+ me->CastSpell(cultist, SPELL_DARK_MARTYRDOM_T);
+ else
{
- Position pos = target->GetPosition();
- if (target->GetEntry() == NPC_CULT_FANATIC)
- me->SummonCreature(NPC_REANIMATED_FANATIC, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- else
- me->SummonCreature(NPC_REANIMATED_ADHERENT, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
-
- if (TempSummon* summon = target->ToTempSummon())
- summon->UnSummon();
+ me->CastSpell(cultist, cultist->GetEntry() == NPC_CULT_FANATIC ? SPELL_DARK_TRANSFORMATION_T : SPELL_DARK_EMPOWERMENT_T, true);
+ Talk(uint8(cultist->GetEntry() == NPC_CULT_FANATIC ? SAY_DARK_TRANSFORMATION : SAY_DARK_EMPOWERMENT));
}
}
- void EmpowerCultist()
- {
- if (summons.empty())
- return;
-
- std::list<Creature*> temp;
- for (SummonList::iterator itr = summons.begin(); itr != summons.end(); ++itr)
- if (Creature* cre = ObjectAccessor::GetCreature(*me, *itr))
- if (cre->IsAlive() && (cre->GetEntry() == NPC_CULT_FANATIC || cre->GetEntry() == NPC_CULT_ADHERENT))
- temp.push_back(cre);
-
- // noone to empower
- if (temp.empty())
- return;
-
- // select random cultist
- Creature* cultist = Trinity::Containers::SelectRandomContainerElement(temp);
- DoCast(cultist, cultist->GetEntry() == NPC_CULT_FANATIC ? SPELL_DARK_TRANSFORMATION_T : SPELL_DARK_EMPOWERMENT_T, true);
- Talk(uint8(cultist->GetEntry() == NPC_CULT_FANATIC ? SAY_DARK_TRANSFORMATION : SAY_DARK_EMPOWERMENT));
- }
-
private:
- ObjectGuid _nextVengefulShadeTargetGUID;
ObjectGuid _darnavanGUID;
- GuidDeque _reanimationQueue;
+ ObjectGuid _cultistGUID;
+ GuidList _cultistQueue;
+ GuidList _nextVengefulShadeTargetGUID;
uint32 _waveCounter;
uint8 const _dominateMindCount;
+ uint8 _phase;
bool _introDone;
};
@@ -643,8 +581,6 @@ class boss_lady_deathwhisper : public CreatureScript
}
};
-typedef boss_lady_deathwhisper::boss_lady_deathwhisperAI DeathwisperAI;
-
class npc_cult_fanatic : public CreatureScript
{
public:
@@ -652,71 +588,91 @@ class npc_cult_fanatic : public CreatureScript
struct npc_cult_fanaticAI : public ScriptedAI
{
- npc_cult_fanaticAI(Creature* creature) : ScriptedAI(creature) { }
+ npc_cult_fanaticAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
void Reset() override
{
- Events.Reset();
- Events.ScheduleEvent(EVENT_FANATIC_NECROTIC_STRIKE, urand(10000, 12000));
- Events.ScheduleEvent(EVENT_FANATIC_SHADOW_CLEAVE, urand(14000, 16000));
- Events.ScheduleEvent(EVENT_FANATIC_VAMPIRIC_MIGHT, urand(20000, 27000));
- if (me->GetEntry() == NPC_CULT_FANATIC)
- Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, urand(18000, 32000));
+ _scheduler.CancelAll();
+ _scheduler
+ .SetValidator([this]
+ {
+ return !me->HasUnitState(UNIT_STATE_CASTING);
+ })
+ .Schedule(Seconds(17), [this](TaskContext vampiric_might)
+ {
+ DoCastSelf(SPELL_VAMPIRIC_MIGHT);
+ vampiric_might.Repeat(Seconds(25));
+ })
+ .Schedule(Seconds(12), [this](TaskContext shadow_cleave)
+ {
+ DoCastVictim(SPELL_SHADOW_CLEAVE);
+ shadow_cleave.Repeat(Seconds(14));
+ })
+ .Schedule(Seconds(10), [this](TaskContext necrotic_strike)
+ {
+ DoCastVictim(SPELL_NECROTIC_STRIKE);
+ necrotic_strike.Repeat(Seconds(17));
+ });
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
- if (spell->Id == SPELL_DARK_TRANSFORMATION)
- me->UpdateEntry(NPC_DEFORMED_FANATIC);
- else if (spell->Id == SPELL_DARK_TRANSFORMATION_T)
+ switch (spell->Id)
{
- Events.CancelEvent(EVENT_CULTIST_DARK_MARTYRDOM);
- me->InterruptNonMeleeSpells(true);
- DoCast(me, SPELL_DARK_TRANSFORMATION);
+ case SPELL_DARK_TRANSFORMATION_T:
+ me->InterruptNonMeleeSpells(true);
+ DoCastSelf(SPELL_DARK_TRANSFORMATION);
+ break;
+ case SPELL_DARK_TRANSFORMATION:
+ DoCastSelf(SPELL_FULL_HEAL);
+ me->UpdateEntry(NPC_DEFORMED_FANATIC);
+ break;
+ case SPELL_DARK_MARTYRDOM_T:
+ me->SetReactState(REACT_PASSIVE);
+ me->InterruptNonMeleeSpells(true);
+ me->AttackStop();
+ DoCastSelf(SPELL_DARK_MARTYRDOM_FANATIC);
+ break;
+ case SPELL_DARK_MARTYRDOM_FANATIC:
+ _scheduler
+ .Schedule(Seconds(2), [this](TaskContext /*context*/)
+ {
+ me->UpdateEntry(NPC_REANIMATED_FANATIC);
+ DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH);
+ DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS);
+ DoCastSelf(SPELL_FULL_HEAL, true);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_UNK_29 | UNIT_FLAG_NOT_SELECTABLE);
+ })
+ .Schedule(Seconds(6), [this](TaskContext /*context*/)
+ {
+ me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_UNK_29 | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoZoneInCombat(me);
+
+ if (Creature* ladyDeathwhisper = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_LADY_DEATHWHISPER)))
+ ladyDeathwhisper->AI()->Talk(SAY_ANIMATE_DEAD);
+ });
+ break;
+ default:
+ break;
}
}
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim())
- return;
-
- Events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
+ if (!UpdateVictim() && !me->HasAura(SPELL_PERMANENT_FEIGN_DEATH))
return;
- while (uint32 eventId = Events.ExecuteEvent())
+ _scheduler.Update(diff, [this]
{
- switch (eventId)
- {
- case EVENT_FANATIC_NECROTIC_STRIKE:
- DoCastVictim(SPELL_NECROTIC_STRIKE);
- Events.ScheduleEvent(EVENT_FANATIC_NECROTIC_STRIKE, urand(11000, 13000));
- break;
- case EVENT_FANATIC_SHADOW_CLEAVE:
- DoCastVictim(SPELL_SHADOW_CLEAVE);
- Events.ScheduleEvent(EVENT_FANATIC_SHADOW_CLEAVE, urand(9500, 11000));
- break;
- case EVENT_FANATIC_VAMPIRIC_MIGHT:
- DoCast(me, SPELL_VAMPIRIC_MIGHT);
- Events.ScheduleEvent(EVENT_FANATIC_VAMPIRIC_MIGHT, urand(20000, 27000));
- break;
- case EVENT_CULTIST_DARK_MARTYRDOM:
- DoCast(me, SPELL_DARK_MARTYRDOM_FANATIC);
- Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, urand(16000, 21000));
- break;
- }
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- }
-
- DoMeleeAttackIfReady();
+ DoMeleeAttackIfReady();
+ });
}
protected:
- EventMap Events;
+ TaskScheduler _scheduler;
+ InstanceScript* _instance;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -732,80 +688,88 @@ class npc_cult_adherent : public CreatureScript
struct npc_cult_adherentAI : public ScriptedAI
{
- npc_cult_adherentAI(Creature* creature) : ScriptedAI(creature) { }
+ npc_cult_adherentAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
void Reset() override
{
- Events.Reset();
- Events.ScheduleEvent(EVENT_ADHERENT_FROST_FEVER, urand(10000, 12000));
- Events.ScheduleEvent(EVENT_ADHERENT_DEATHCHILL, urand(14000, 16000));
- Events.ScheduleEvent(EVENT_ADHERENT_CURSE_OF_TORPOR, urand(14000, 16000));
- Events.ScheduleEvent(EVENT_ADHERENT_SHORUD_OF_THE_OCCULT, urand(32000, 39000));
- if (me->GetEntry() == NPC_CULT_ADHERENT)
- Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, urand(18000, 32000));
+ _scheduler.CancelAll();
+ _scheduler
+ .SetValidator([this]
+ {
+ return !me->HasUnitState(UNIT_STATE_CASTING);
+ })
+ .Schedule(Seconds(5), [this](TaskContext deathchill)
+ {
+ if (me->GetEntry() == NPC_EMPOWERED_ADHERENT)
+ DoCastVictim(SPELL_DEATHCHILL_BLAST);
+ else
+ DoCastVictim(SPELL_DEATHCHILL_BOLT);
+ deathchill.Repeat(Milliseconds(2500));
+ })
+ .Schedule(Seconds(15), [this](TaskContext shroud_of_the_occult)
+ {
+ DoCastSelf(SPELL_SHROUD_OF_THE_OCCULT);
+ shroud_of_the_occult.Repeat(Seconds(10));
+ })
+ .Schedule(Seconds(15), [this](TaskContext curse_of_torpor)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
+ DoCast(target, SPELL_CURSE_OF_TORPOR);
+ curse_of_torpor.Repeat(Seconds(18));
+ });
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
- if (spell->Id == SPELL_DARK_EMPOWERMENT)
- me->UpdateEntry(NPC_EMPOWERED_ADHERENT);
- else if (spell->Id == SPELL_DARK_EMPOWERMENT_T)
+ switch (spell->Id)
{
- Events.CancelEvent(EVENT_CULTIST_DARK_MARTYRDOM);
- me->InterruptNonMeleeSpells(true);
- DoCast(me, SPELL_DARK_EMPOWERMENT);
+ case SPELL_DARK_EMPOWERMENT_T:
+ me->UpdateEntry(NPC_EMPOWERED_ADHERENT);
+ break;
+ case SPELL_DARK_MARTYRDOM_T:
+ me->SetReactState(REACT_PASSIVE);
+ me->InterruptNonMeleeSpells(true);
+ me->AttackStop();
+ DoCastSelf(SPELL_DARK_MARTYRDOM_ADHERENT);
+ break;
+ case SPELL_DARK_MARTYRDOM_ADHERENT:
+ _scheduler
+ .Schedule(Seconds(2), [this](TaskContext /*context*/)
+ {
+ me->UpdateEntry(NPC_REANIMATED_ADHERENT);
+ DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH);
+ DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS);
+ DoCastSelf(SPELL_FULL_HEAL, true);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_UNK_29 | UNIT_FLAG_NOT_SELECTABLE);
+ })
+ .Schedule(Seconds(6), [this](TaskContext /*context*/)
+ {
+ me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_UNK_29 | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoCastSelf(SPELL_SHROUD_OF_THE_OCCULT);
+ DoZoneInCombat(me);
+
+ if (Creature* ladyDeathwhisper = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_LADY_DEATHWHISPER)))
+ ladyDeathwhisper->AI()->Talk(SAY_ANIMATE_DEAD);
+ });
+ break;
+ default:
+ break;
}
}
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim())
+ if (!UpdateVictim() && !me->HasAura(SPELL_PERMANENT_FEIGN_DEATH))
return;
- Events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- while (uint32 eventId = Events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_ADHERENT_FROST_FEVER:
- DoCastVictim(SPELL_FROST_FEVER);
- Events.ScheduleEvent(EVENT_ADHERENT_FROST_FEVER, urand(9000, 13000));
- break;
- case EVENT_ADHERENT_DEATHCHILL:
- if (me->GetEntry() == NPC_EMPOWERED_ADHERENT)
- DoCastVictim(SPELL_DEATHCHILL_BLAST);
- else
- DoCastVictim(SPELL_DEATHCHILL_BOLT);
- Events.ScheduleEvent(EVENT_ADHERENT_DEATHCHILL, urand(9000, 13000));
- break;
- case EVENT_ADHERENT_CURSE_OF_TORPOR:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
- DoCast(target, SPELL_CURSE_OF_TORPOR);
- Events.ScheduleEvent(EVENT_ADHERENT_CURSE_OF_TORPOR, urand(9000, 13000));
- break;
- case EVENT_ADHERENT_SHORUD_OF_THE_OCCULT:
- DoCast(me, SPELL_SHORUD_OF_THE_OCCULT);
- Events.ScheduleEvent(EVENT_ADHERENT_SHORUD_OF_THE_OCCULT, urand(27000, 32000));
- break;
- case EVENT_CULTIST_DARK_MARTYRDOM:
- DoCast(me, SPELL_DARK_MARTYRDOM_ADHERENT);
- Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, urand(16000, 21000));
- break;
- }
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- }
-
- DoMeleeAttackIfReady();
+ _scheduler.Update(diff);
}
protected:
- EventMap Events;
+ TaskScheduler _scheduler;
+ InstanceScript* _instance;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -821,15 +785,28 @@ class npc_vengeful_shade : public CreatureScript
struct npc_vengeful_shadeAI : public ScriptedAI
{
- npc_vengeful_shadeAI(Creature* creature) : ScriptedAI(creature)
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
+ npc_vengeful_shadeAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
+ me->SetReactState(REACT_PASSIVE);
me->AddAura(SPELL_VENGEFUL_BLAST_PASSIVE, me);
+
+ _scheduler
+ .Schedule(Seconds(2), [this](TaskContext /*context*/)
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->AI()->AttackStart(ObjectAccessor::GetUnit(*me, _targetGUID));
+ })
+ .Schedule(Seconds(7), [this](TaskContext /*context*/)
+ {
+ me->KillSelf();
+ });
+ }
+
+ void SetGUID(ObjectGuid guid, int32 /*type*/) override
+ {
+ _targetGUID = guid;
}
void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) override
@@ -846,6 +823,18 @@ class npc_vengeful_shade : public CreatureScript
break;
}
}
+
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff, [this]
+ {
+ DoMeleeAttackIfReady();
+ });
+ }
+
+ private:
+ TaskScheduler _scheduler;
+ ObjectGuid _targetGUID;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -875,10 +864,10 @@ class npc_darnavan : public CreatureScript
void Reset() override
{
_events.Reset();
- _events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, 10000);
- _events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, urand(20000, 25000));
- _events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, urand(25000, 30000));
- _events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, urand(5000, 8000));
+ _events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, Seconds(10));
+ _events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, Seconds(20), Seconds(25));
+ _events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, Seconds(25), Seconds(30));
+ _events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, Seconds(5), Seconds(8));
Initialize();
}
@@ -889,7 +878,7 @@ class npc_darnavan : public CreatureScript
{
if (Group* group = owner->GetGroup())
{
- for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
if (Player* member = itr->GetSource())
member->FailQuest(QUEST_DEPROGRAMMING);
}
@@ -925,7 +914,7 @@ class npc_darnavan : public CreatureScript
{
DoCastVictim(SPELL_SHATTERING_THROW);
_canShatter = false;
- _events.ScheduleEvent(EVENT_DARNAVAN_SHATTERING_THROW, 30000);
+ _events.ScheduleEvent(EVENT_DARNAVAN_SHATTERING_THROW, Seconds(30));
return;
}
@@ -933,7 +922,7 @@ class npc_darnavan : public CreatureScript
{
DoCastVictim(SPELL_CHARGE);
_canCharge = false;
- _events.ScheduleEvent(EVENT_DARNAVAN_CHARGE, 20000);
+ _events.ScheduleEvent(EVENT_DARNAVAN_CHARGE, Seconds(20));
return;
}
@@ -943,25 +932,25 @@ class npc_darnavan : public CreatureScript
{
case EVENT_DARNAVAN_BLADESTORM:
DoCast(SPELL_BLADESTORM);
- _events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, urand(90000, 100000));
+ _events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, Seconds(90), Seconds(100));
break;
case EVENT_DARNAVAN_CHARGE:
_canCharge = true;
break;
case EVENT_DARNAVAN_INTIMIDATING_SHOUT:
DoCast(SPELL_INTIMIDATING_SHOUT);
- _events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, urand(90000, 120000));
+ _events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, Seconds(90), Minutes(2));
break;
case EVENT_DARNAVAN_MORTAL_STRIKE:
DoCastVictim(SPELL_MORTAL_STRIKE);
- _events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, urand(15000, 30000));
+ _events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, Seconds(15), Seconds(30));
break;
case EVENT_DARNAVAN_SHATTERING_THROW:
_canShatter = true;
break;
case EVENT_DARNAVAN_SUNDER_ARMOR:
DoCastVictim(SPELL_SUNDER_ARMOR);
- _events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, urand(3000, 7000));
+ _events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, Seconds(3), Seconds(7));
break;
}
}
@@ -1013,50 +1002,86 @@ class spell_deathwhisper_mana_barrier : public SpellScriptLoader
}
};
-class spell_cultist_dark_martyrdom : public SpellScriptLoader
+class at_lady_deathwhisper_entrance : public AreaTriggerScript
{
public:
- spell_cultist_dark_martyrdom() : SpellScriptLoader("spell_cultist_dark_martyrdom") { }
+ at_lady_deathwhisper_entrance() : AreaTriggerScript("at_lady_deathwhisper_entrance") { }
- class spell_cultist_dark_martyrdom_SpellScript : public SpellScript
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
{
- PrepareSpellScript(spell_cultist_dark_martyrdom_SpellScript);
+ if (InstanceScript* instance = player->GetInstanceScript())
+ if (instance->GetBossState(DATA_LADY_DEATHWHISPER) != DONE)
+ if (Creature* ladyDeathwhisper = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_LADY_DEATHWHISPER)))
+ ladyDeathwhisper->AI()->DoAction(ACTION_START_INTRO);
+
+ return true;
+ }
+};
+
+class spell_deathwhisper_dominated_mind : public SpellScriptLoader
+{
+ public:
+ spell_deathwhisper_dominated_mind() : SpellScriptLoader("spell_deathwhisper_dominated_mind") { }
- void HandleEffect(SpellEffIndex /*effIndex*/)
+ class spell_deathwhisper_dominated_mind_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_deathwhisper_dominated_mind_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/) override
{
- if (GetCaster()->IsSummon())
- if (Unit* owner = GetCaster()->ToTempSummon()->GetSummoner())
- owner->GetAI()->SetGUID(GetCaster()->GetGUID(), GUID_CULTIST);
+ if (!sSpellMgr->GetSpellInfo(SPELL_DOMINATE_MIND_SCALE))
+ return false;
+ return true;
+ }
- GetCaster()->KillSelf();
- GetCaster()->SetDisplayId(uint32(GetCaster()->GetEntry() == NPC_CULT_FANATIC ? 38009 : 38010));
+ void HandleApply(AuraEffect const* /*eff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+ target->CastSpell(target, SPELL_DOMINATE_MIND_SCALE, true);
}
void Register() override
{
- OnEffectHitTarget += SpellEffectFn(spell_cultist_dark_martyrdom_SpellScript::HandleEffect, EFFECT_2, SPELL_EFFECT_FORCE_DESELECT);
+ AfterEffectApply += AuraEffectApplyFn(spell_deathwhisper_dominated_mind_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_AOE_CHARM, AURA_EFFECT_HANDLE_REAL);
}
};
- SpellScript* GetSpellScript() const override
+ AuraScript* GetAuraScript() const override
{
- return new spell_cultist_dark_martyrdom_SpellScript();
+ return new spell_deathwhisper_dominated_mind_AuraScript();
}
};
-class at_lady_deathwhisper_entrance : public AreaTriggerScript
+class spell_deathwhisper_summon_spirits : public SpellScriptLoader
{
public:
- at_lady_deathwhisper_entrance() : AreaTriggerScript("at_lady_deathwhisper_entrance") { }
+ spell_deathwhisper_summon_spirits() : SpellScriptLoader("spell_deathwhisper_summon_spirits") { }
- bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
+ class spell_deathwhisper_summon_spirits_SpellScript : public SpellScript
{
- if (InstanceScript* instance = player->GetInstanceScript())
- if (instance->GetBossState(DATA_LADY_DEATHWHISPER) != DONE)
- if (Creature* ladyDeathwhisper = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_LADY_DEATHWHISPER)))
- ladyDeathwhisper->AI()->DoAction(ACTION_START_INTRO);
+ PrepareSpellScript(spell_deathwhisper_summon_spirits_SpellScript);
- return true;
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_SHADE))
+ return false;
+ return true;
+ }
+
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_SUMMON_SHADE, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_deathwhisper_summon_spirits_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_deathwhisper_summon_spirits_SpellScript();
}
};
@@ -1068,6 +1093,7 @@ void AddSC_boss_lady_deathwhisper()
new npc_vengeful_shade();
new npc_darnavan();
new spell_deathwhisper_mana_barrier();
- new spell_cultist_dark_martyrdom();
+ new spell_deathwhisper_dominated_mind();
+ new spell_deathwhisper_summon_spirits();
new at_lady_deathwhisper_entrance();
}
diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp
index c22cd2d9ad7..cb5a7462000 100644
--- a/src/server/scripts/Northrend/zone_dragonblight.cpp
+++ b/src/server/scripts/Northrend/zone_dragonblight.cpp
@@ -701,6 +701,31 @@ class npc_torturer_lecraft : public CreatureScript
}
};
+enum MessengerTorvus
+{
+ NPC_MESSENGER_TORVUS = 26649,
+ QUEST_MESSAGE_FROM_THE_WEST = 12033,
+
+ TALK_0 = 0
+};
+
+class at_nearby_messenger_torvus : public AreaTriggerScript
+{
+public:
+ at_nearby_messenger_torvus() : AreaTriggerScript("at_nearby_messenger_torvus") { }
+
+ bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) override
+ {
+ if (player->IsAlive())
+ if (Quest const* quest = sObjectMgr->GetQuestTemplate(QUEST_MESSAGE_FROM_THE_WEST))
+ if (player->CanTakeQuest(quest, false))
+ if (Creature* creature = player->FindNearestCreature(NPC_MESSENGER_TORVUS, 50.0f, true))
+ creature->AI()->Talk(TALK_0, player);
+
+ return true;
+ }
+};
+
void AddSC_dragonblight()
{
new npc_commander_eligor_dawnbringer();
@@ -708,4 +733,5 @@ void AddSC_dragonblight()
new spell_q12096_q12092_bark();
new npc_wyrmrest_defender();
new npc_torturer_lecraft();
+ new at_nearby_messenger_torvus();
}
diff --git a/src/server/scripts/Northrend/zone_wintergrasp.cpp b/src/server/scripts/Northrend/zone_wintergrasp.cpp
index a85d97d4c1d..e45b1f42fa1 100644
--- a/src/server/scripts/Northrend/zone_wintergrasp.cpp
+++ b/src/server/scripts/Northrend/zone_wintergrasp.cpp
@@ -247,39 +247,39 @@ class npc_wg_queue : public CreatureScript
public:
npc_wg_queue() : CreatureScript("npc_wg_queue") { }
- struct npc_wg_queueAI : public ScriptedAI
- {
- npc_wg_queueAI(Creature* creature) : ScriptedAI(creature)
+ struct npc_wg_queueAI : public ScriptedAI
{
- FrostArmor_Timer = 0;
- }
+ npc_wg_queueAI(Creature* creature) : ScriptedAI(creature)
+ {
+ FrostArmor_Timer = 0;
+ }
- uint32 FrostArmor_Timer;
+ uint32 FrostArmor_Timer;
- void Reset() override
- {
- FrostArmor_Timer = 0;
- }
+ void Reset() override
+ {
+ FrostArmor_Timer = 0;
+ }
- void EnterCombat(Unit* /*who*/) override { }
+ void EnterCombat(Unit* /*who*/) override { }
- void UpdateAI(uint32 diff) override
- {
- if (FrostArmor_Timer <= diff)
+ void UpdateAI(uint32 diff) override
{
- DoCast(me, SPELL_FROST_ARMOR);
- FrostArmor_Timer = 180000;
+ if (FrostArmor_Timer <= diff)
+ {
+ DoCast(me, SPELL_FROST_ARMOR);
+ FrostArmor_Timer = 180000;
+ }
+ else FrostArmor_Timer -= diff;
+
+ DoMeleeAttackIfReady();
}
- else FrostArmor_Timer -= diff;
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_wg_queueAI(creature);
}
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_wg_queueAI(creature);
- }
bool OnGossipHello(Player* player, Creature* creature) override
{
@@ -474,26 +474,26 @@ class spell_wintergrasp_grab_passenger : public SpellScriptLoader
class achievement_wg_didnt_stand_a_chance : public AchievementCriteriaScript
{
-public:
- achievement_wg_didnt_stand_a_chance() : AchievementCriteriaScript("achievement_wg_didnt_stand_a_chance") { }
-
- bool OnCheck(Player* source, Unit* target) override
- {
- if (!target)
- return false;
+ public:
+ achievement_wg_didnt_stand_a_chance() : AchievementCriteriaScript("achievement_wg_didnt_stand_a_chance") { }
- if (Player* victim = target->ToPlayer())
+ bool OnCheck(Player* source, Unit* target) override
{
- if (!victim->IsMounted())
+ if (!target)
return false;
- if (Vehicle* vehicle = source->GetVehicle())
- if (vehicle->GetVehicleInfo()->m_ID == 244) // Wintergrasp Tower Cannon
- return true;
- }
+ if (Player* victim = target->ToPlayer())
+ {
+ if (!victim->IsMounted())
+ return false;
- return false;
- }
+ if (Vehicle* vehicle = source->GetVehicle())
+ if (vehicle->GetVehicleInfo()->m_ID == 244) // Wintergrasp Tower Cannon
+ return true;
+ }
+
+ return false;
+ }
};
enum WgTeleport
@@ -503,91 +503,91 @@ enum WgTeleport
class spell_wintergrasp_defender_teleport : public SpellScriptLoader
{
-public:
- spell_wintergrasp_defender_teleport() : SpellScriptLoader("spell_wintergrasp_defender_teleport") { }
-
- class spell_wintergrasp_defender_teleport_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_wintergrasp_defender_teleport_SpellScript);
+ public:
+ spell_wintergrasp_defender_teleport() : SpellScriptLoader("spell_wintergrasp_defender_teleport") { }
- SpellCastResult CheckCast()
+ class spell_wintergrasp_defender_teleport_SpellScript : public SpellScript
{
- if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG))
- if (Player* target = GetExplTargetUnit()->ToPlayer())
- // check if we are in Wintergrasp at all, SotA uses same teleport spells
- if ((target->GetZoneId() == 4197 && target->GetTeamId() != wg->GetDefenderTeam()) || target->HasAura(SPELL_WINTERGRASP_TELEPORT_TRIGGER))
- return SPELL_FAILED_BAD_TARGETS;
- return SPELL_CAST_OK;
- }
+ PrepareSpellScript(spell_wintergrasp_defender_teleport_SpellScript);
+
+ SpellCastResult CheckCast()
+ {
+ if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG))
+ if (Player* target = GetExplTargetUnit()->ToPlayer())
+ // check if we are in Wintergrasp at all, SotA uses same teleport spells
+ if ((target->GetZoneId() == 4197 && target->GetTeamId() != wg->GetDefenderTeam()) || target->HasAura(SPELL_WINTERGRASP_TELEPORT_TRIGGER))
+ return SPELL_FAILED_BAD_TARGETS;
+ return SPELL_CAST_OK;
+ }
- void Register() override
+ void Register() override
+ {
+ OnCheckCast += SpellCheckCastFn(spell_wintergrasp_defender_teleport_SpellScript::CheckCast);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
{
- OnCheckCast += SpellCheckCastFn(spell_wintergrasp_defender_teleport_SpellScript::CheckCast);
+ return new spell_wintergrasp_defender_teleport_SpellScript();
}
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_wintergrasp_defender_teleport_SpellScript();
- }
};
class spell_wintergrasp_defender_teleport_trigger : public SpellScriptLoader
{
-public:
- spell_wintergrasp_defender_teleport_trigger() : SpellScriptLoader("spell_wintergrasp_defender_teleport_trigger") { }
-
- class spell_wintergrasp_defender_teleport_trigger_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_wintergrasp_defender_teleport_trigger_SpellScript);
+ public:
+ spell_wintergrasp_defender_teleport_trigger() : SpellScriptLoader("spell_wintergrasp_defender_teleport_trigger") { }
- void HandleDummy(SpellEffIndex /*effindex*/)
+ class spell_wintergrasp_defender_teleport_trigger_SpellScript : public SpellScript
{
- if (Unit* target = GetHitUnit())
+ PrepareSpellScript(spell_wintergrasp_defender_teleport_trigger_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effindex*/)
{
- WorldLocation loc = target->GetWorldLocation();
- SetExplTargetDest(loc);
+ if (Unit* target = GetHitUnit())
+ {
+ WorldLocation loc = target->GetWorldLocation();
+ SetExplTargetDest(loc);
+ }
}
- }
- void Register() override
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_defender_teleport_trigger_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
{
- OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_defender_teleport_trigger_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ return new spell_wintergrasp_defender_teleport_trigger_SpellScript();
}
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_wintergrasp_defender_teleport_trigger_SpellScript();
- }
};
class condition_is_wintergrasp_horde : public ConditionScript
{
-public:
- condition_is_wintergrasp_horde() : ConditionScript("condition_is_wintergrasp_horde") { }
+ public:
+ condition_is_wintergrasp_horde() : ConditionScript("condition_is_wintergrasp_horde") { }
- bool OnConditionCheck(Condition const* /* condition */, ConditionSourceInfo& /* sourceInfo */)
- {
- Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
- if (wintergrasp->IsEnabled() && wintergrasp->GetDefenderTeam() == TEAM_HORDE)
- return true;
- return false;
- }
+ bool OnConditionCheck(Condition const* /* condition */, ConditionSourceInfo& /* sourceInfo */)
+ {
+ Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
+ if (wintergrasp && wintergrasp->IsEnabled() && wintergrasp->GetDefenderTeam() == TEAM_HORDE)
+ return true;
+ return false;
+ }
};
class condition_is_wintergrasp_alliance : public ConditionScript
{
-public:
- condition_is_wintergrasp_alliance() : ConditionScript("condition_is_wintergrasp_alliance") { }
+ public:
+ condition_is_wintergrasp_alliance() : ConditionScript("condition_is_wintergrasp_alliance") { }
- bool OnConditionCheck(Condition const* /* condition */, ConditionSourceInfo& /* sourceInfo */)
- {
- Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
- if (wintergrasp->IsEnabled() && wintergrasp->GetDefenderTeam() == TEAM_ALLIANCE)
- return true;
- return false;
- }
+ bool OnConditionCheck(Condition const* /* condition */, ConditionSourceInfo& /* sourceInfo */)
+ {
+ Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
+ if (wintergrasp && wintergrasp->IsEnabled() && wintergrasp->GetDefenderTeam() == TEAM_ALLIANCE)
+ return true;
+ return false;
+ }
};
void AddSC_wintergrasp()
diff --git a/src/server/scripts/Outland/BlackTemple/black_temple.h b/src/server/scripts/Outland/BlackTemple/black_temple.h
index 0856639f4c2..9d2c3dacb3f 100644
--- a/src/server/scripts/Outland/BlackTemple/black_temple.h
+++ b/src/server/scripts/Outland/BlackTemple/black_temple.h
@@ -47,27 +47,29 @@ enum DataTypes
DATA_BLOOD_ELF_COUNCIL_VOICE = 15,
DATA_GO_ILLIDAN_GATE = 16,
- DATA_GO_ILLIDAN_DOOR_R = 17,
- DATA_GO_ILLIDAN_DOOR_L = 18
};
enum CreatureIds
{
+ //Bosses
NPC_HIGH_WARLORD_NAJENTUS = 22887,
NPC_SUPREMUS = 22898,
NPC_SHADE_OF_AKAMA = 22841,
- NPC_AKAMA_SHADE = 23191, // This is the Akama that starts the Shade of Akama encounter.
- NPC_AKAMA = 23089, // This is the Akama that starts the Illidan encounter.
+ NPC_TERON_GOREFIEND = 22871,
+ NPC_GURTOGG_BLOODBOIL = 22948,
+ NPC_RELIQUARY_OF_SOULS = 22856,
+ NPC_MOTHER_SHAHRAZ = 22947,
+ NPC_ILLIDARI_COUNCIL = 23426,
+ NPC_ILLIDAN_STORMRAGE = 22917,
+ //Misc
NPC_GATHIOS_THE_SHATTERER = 22949,
NPC_HIGH_NETHERMANCER_ZEREVOR = 22950,
NPC_LADY_MALANDE = 22951,
NPC_VERAS_DARKSHADOW = 22952,
- NPC_ILLIDARI_COUNCIL = 23426,
NPC_BLOOD_ELF_COUNCIL_VOICE = 23499,
-
- NPC_ILLIDAN_STORMRAGE = 22917,
-
+ NPC_AKAMA = 23089, // This is the Akama that starts the Illidan encounter.
+ NPC_AKAMA_SHADE = 23191, // This is the Akama that starts the Shade of Akama encounter.
NPC_SUPREMUS_VOLCANO = 23085
};
diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
index a2215862219..07578b4c9ae 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
@@ -539,8 +539,7 @@ public:
void EnterCombat(Unit* /*who*/) override
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->setActive(true);
- DoZoneInCombat();
+ _EnterCombat();
}
void AttackStart(Unit* who) override
@@ -561,9 +560,6 @@ public:
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- for (uint8 i = DATA_GO_ILLIDAN_DOOR_R; i < DATA_GO_ILLIDAN_DOOR_L + 1; ++i)
- instance->HandleGameObject(instance->GetGuidData(i), true);
-
_JustDied();
}
@@ -1412,23 +1408,13 @@ public:
IllidanGUID = instance->GetGuidData(DATA_ILLIDAN_STORMRAGE);
GateGUID = instance->GetGuidData(DATA_GO_ILLIDAN_GATE);
- DoorGUID[0] = instance->GetGuidData(DATA_GO_ILLIDAN_DOOR_R);
- DoorGUID[1] = instance->GetGuidData(DATA_GO_ILLIDAN_DOOR_L);
if (JustCreated) // close all doors at create
- {
instance->HandleGameObject(GateGUID, false);
-
- for (uint8 i = 0; i < 2; ++i)
- instance->HandleGameObject(DoorGUID[i], false);
- }
else // open all doors, raid wiped
{
instance->HandleGameObject(GateGUID, true);
WalkCount = 1; // skip first wp
-
- for (uint8 i = 0; i < 2; ++i)
- instance->HandleGameObject(DoorGUID[i], true);
}
KillAllElites();
@@ -1480,9 +1466,6 @@ public:
void BeginTalk()
{
- instance->SetBossState(DATA_ILLIDAN_STORMRAGE, IN_PROGRESS);
- for (uint8 i = 0; i < 2; ++i)
- instance->HandleGameObject(DoorGUID[i], false);
if (Creature* illidan = ObjectAccessor::GetCreature(*me, IllidanGUID))
{
illidan->RemoveAurasDueToSpell(SPELL_KNEEL);
@@ -1674,10 +1657,6 @@ public:
{
switch (WalkCount)
{
- case 6:
- for (uint8 i = 0; i < 2; ++i)
- instance->HandleGameObject(DoorGUID[i], true);
- break;
case 8:
if (Phase == PHASE_WALK)
EnterPhase(PHASE_TALK);
@@ -1795,7 +1774,6 @@ public:
ObjectGuid ChannelGUID;
ObjectGuid SpiritGUID[2];
ObjectGuid GateGUID;
- ObjectGuid DoorGUID[2];
uint32 ChannelCount;
uint32 WalkCount;
uint32 TalkCount;
diff --git a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp
index 347843ec7ff..d83e9f8aed9 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp
@@ -46,7 +46,7 @@ enum Spells
SPELL_FIXATE = 40607,
SPELL_CHAIN_LIGHTNING = 39945,
SPELL_DESTRUCTIVE_POISON = 40874,
- SPELL_AKAMA_SOUL_EXPEL = 40902,
+ SPELL_AKAMA_SOUL_RETRIEVE = 40902,
// Shade
SPELL_THREAT = 41602,
SPELL_SHADE_OF_AKAMA_TRIGGER = 40955,
@@ -108,7 +108,7 @@ enum Events
EVENT_CHAIN_LIGHTNING = 4,
EVENT_DESTRUCTIVE_POISON = 5,
EVENT_START_BROKEN_FREE = 6,
- EVENT_START_SOUL_EXPEL = 7,
+ EVENT_START_SOUL_RETRIEVE = 7,
EVENT_EVADE_CHECK = 8,
EVENT_BROKEN_FREE_1 = 9,
EVENT_BROKEN_FREE_2 = 10,
@@ -246,11 +246,11 @@ public:
events.ScheduleEvent(EVENT_START_CHANNELERS_AND_SPAWNERS, Seconds(1));
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
events.ScheduleEvent(EVENT_EVADE_CHECK, Seconds(10));
- if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AKAMA_SHADE)))
+ if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE))
AttackStart(akama);
}
- if (spell->Id == SPELL_AKAMA_SOUL_EXPEL)
+ if (spell->Id == SPELL_AKAMA_SOUL_RETRIEVE)
DoCastSelf(SPELL_AKAMA_SOUL_EXPEL_CHANNEL);
}
@@ -273,7 +273,7 @@ public:
{
DoCastSelf(SPELL_SHADE_OF_AKAMA_TRIGGER);
- if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AKAMA_SHADE)))
+ if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE))
akama->AI()->DoAction(ACTION_SHADE_OF_AKAMA_DEAD);
for (ObjectGuid const& spawnerGuid : _spawners)
@@ -401,7 +401,7 @@ public:
_isInCombat = true;
me->SetWalk(false);
me->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL);
- if (Creature* shade = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SHADE_OF_AKAMA)))
+ if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA))
{
shade->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL);
AttackStart(shade);
@@ -445,7 +445,7 @@ public:
{
me->SetWalk(false);
me->SetFacingTo(0.08726646f, true);
- _events.ScheduleEvent(EVENT_START_SOUL_EXPEL, Seconds(1));
+ _events.ScheduleEvent(EVENT_START_SOUL_RETRIEVE, Seconds(1));
}
}
@@ -489,14 +489,14 @@ public:
break;
case EVENT_CHAIN_LIGHTNING:
DoCastVictim(SPELL_CHAIN_LIGHTNING);
- _events.Repeat(randtime(Seconds(8), Seconds(15)));
+ _events.Repeat(Seconds(8), Seconds(15));
break;
case EVENT_DESTRUCTIVE_POISON:
DoCastSelf(SPELL_DESTRUCTIVE_POISON);
- _events.Repeat(randtime(Seconds(3), Seconds(7)));
+ _events.Repeat(Seconds(3), Seconds(7));
break;
- case EVENT_START_SOUL_EXPEL:
- DoCast(SPELL_AKAMA_SOUL_EXPEL);
+ case EVENT_START_SOUL_RETRIEVE:
+ DoCast(SPELL_AKAMA_SOUL_RETRIEVE);
_events.ScheduleEvent(EVENT_START_BROKEN_FREE, Seconds(15));
break;
case EVENT_START_BROKEN_FREE:
@@ -541,7 +541,7 @@ public:
{
_summons.DespawnAll();
Talk(SAY_DEAD);
- if (Creature* shade = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SHADE_OF_AKAMA)))
+ if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA))
if (shade->IsAlive())
shade->AI()->EnterEvadeMode(EVADE_REASON_OTHER);
}
@@ -587,7 +587,7 @@ public:
{
_scheduler.Schedule(Seconds(2), [this](TaskContext channel)
{
- if (Creature* shade = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SHADE_OF_AKAMA)))
+ if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA))
{
if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
DoCastSelf(SPELL_SHADE_SOUL_CHANNEL);
@@ -657,12 +657,12 @@ public:
if (_leftSide)
{
_events.ScheduleEvent(EVENT_SPAWN_WAVE_B, Milliseconds(100));
- _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, randtime(Seconds(2), Seconds(5)));
+ _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, Seconds(2), Seconds(5));
}
else
{
_events.ScheduleEvent(EVENT_SPAWN_WAVE_B, Seconds(10));
- _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, randtime(Seconds(2), Seconds(5)));
+ _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, Seconds(2), Seconds(5));
}
break;
case ACTION_STOP_SPAWNING:
@@ -687,15 +687,15 @@ public:
{
case EVENT_SPAWN_WAVE_B:
DoCastSelf(SPELL_ASHTONGUE_WAVE_B);
- _events.Repeat(randtime(Seconds(50), Seconds(60)));
+ _events.Repeat(Seconds(50), Seconds(60));
break;
case EVENT_SUMMON_ASHTONGUE_SORCERER: // left
DoCastSelf(SPELL_SUMMON_ASHTONGUE_SORCERER);
- _events.Repeat(randtime(Seconds(30), Seconds(35)));
+ _events.Repeat(Seconds(30), Seconds(35));
break;
case EVENT_SUMMON_ASHTONGUE_DEFENDER: // right
DoCastSelf(SPELL_SUMMON_ASHTONGUE_DEFENDER);
- _events.Repeat(randtime(Seconds(30), Seconds(40)));
+ _events.Repeat(Seconds(30), Seconds(40));
break;
default:
break;
@@ -736,16 +736,13 @@ public:
void Reset() override
{
- if (Creature* shade = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SHADE_OF_AKAMA)))
+ if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA))
{
if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
me->GetMotionMaster()->MovePoint(0, shade->GetPosition());
- else
- {
- if (Creature* akama = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AKAMA_SHADE)))
- AttackStart(akama);
- }
+ else if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE))
+ AttackStart(akama);
}
Initialize();
}
@@ -777,7 +774,7 @@ public:
_scheduler.Schedule(Seconds(1) + Milliseconds(500), [this](TaskContext sorcer_channel)
{
- if (Creature* shade = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SHADE_OF_AKAMA)))
+ if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA))
{
if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
{
@@ -789,7 +786,7 @@ public:
{
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
_switchToCombat = true;
- if (Creature* akama = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AKAMA_SHADE)))
+ if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE))
AttackStart(akama);
}
}
@@ -837,7 +834,7 @@ public:
void Reset() override
{
- if (Creature* akama = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AKAMA_SHADE)))
+ if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE))
AttackStart(akama);
}
@@ -849,9 +846,9 @@ public:
void EnterCombat(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_HEROIC_STRIKE, Seconds(5));
- _events.ScheduleEvent(EVENT_SHIELD_BASH, randtime(Seconds(10), Seconds(16)));
- _events.ScheduleEvent(EVENT_DEBILITATING_STRIKE, randtime(Seconds(10), Seconds(16)));
- _events.ScheduleEvent(EVENT_WINDFURY, randtime(Seconds(8), Seconds(12)));
+ _events.ScheduleEvent(EVENT_SHIELD_BASH, Seconds(10), Seconds(16));
+ _events.ScheduleEvent(EVENT_DEBILITATING_STRIKE, Seconds(10), Seconds(16));
+ _events.ScheduleEvent(EVENT_WINDFURY, Seconds(8), Seconds(12));
}
@@ -868,19 +865,19 @@ public:
{
case EVENT_DEBILITATING_STRIKE:
DoCastVictim(SPELL_DEBILITATING_STRIKE);
- _events.Repeat(randtime(Seconds(20), Seconds(25)));
+ _events.Repeat(Seconds(20), Seconds(25));
break;
case EVENT_HEROIC_STRIKE:
DoCastSelf(SPELL_HEROIC_STRIKE);
- _events.Repeat(randtime(Seconds(5), Seconds(15)));
+ _events.Repeat(Seconds(5), Seconds(15));
break;
case EVENT_SHIELD_BASH:
DoCastVictim(SPELL_SHIELD_BASH);
- _events.Repeat(randtime(Seconds(10), Seconds(20)));
+ _events.Repeat(Seconds(10), Seconds(20));
break;
case EVENT_WINDFURY:
DoCastVictim(SPELL_WINDFURY);
- _events.Repeat(randtime(Seconds(6), Seconds(8)));
+ _events.Repeat(Seconds(6), Seconds(8));
break;
default:
break;
@@ -915,7 +912,7 @@ public:
void Reset() override
{
- if (Creature* akama = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AKAMA_SHADE)))
+ if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE))
AttackStart(akama);
}
@@ -926,8 +923,8 @@ public:
void EnterCombat(Unit* /*who*/) override
{
- _events.ScheduleEvent(EVENT_DEBILITATING_POISON, randtime(Milliseconds(500), Seconds(2)));
- _events.ScheduleEvent(EVENT_EVISCERATE, randtime(Seconds(2), Seconds(5)));
+ _events.ScheduleEvent(EVENT_DEBILITATING_POISON, Milliseconds(500), Seconds(2));
+ _events.ScheduleEvent(EVENT_EVISCERATE, Seconds(2), Seconds(5));
}
void EnterEvadeMode(EvadeReason /*why*/) override { }
@@ -945,11 +942,11 @@ public:
{
case EVENT_DEBILITATING_POISON:
DoCastVictim(SPELL_DEBILITATING_POISON);
- _events.Repeat(randtime(Seconds(15), Seconds(20)));
+ _events.Repeat(Seconds(15), Seconds(20));
break;
case EVENT_EVISCERATE:
DoCastVictim(SPELL_EVISCERATE);
- _events.Repeat(randtime(Seconds(12), Seconds(20)));
+ _events.Repeat(Seconds(12), Seconds(20));
break;
default:
break;
@@ -984,7 +981,7 @@ public:
void Reset() override
{
- if (Creature* akama = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AKAMA_SHADE)))
+ if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE))
AttackStart(akama);
}
@@ -1014,11 +1011,11 @@ public:
{
case EVENT_RAIN_OF_FIRE:
DoCastVictim(SPELL_RAIN_OF_FIRE);
- _events.Repeat(randtime(Seconds(15), Seconds(20)));
+ _events.Repeat(Seconds(15), Seconds(20));
break;
case EVENT_LIGHTNING_BOLT:
DoCastVictim(SPELL_LIGHTNING_BOLT);
- _events.Repeat(randtime(Seconds(8), Seconds(15)));
+ _events.Repeat(Seconds(8), Seconds(15));
break;
default:
break;
@@ -1062,7 +1059,7 @@ public:
{
Initialize();
- if (Creature* akama = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AKAMA_SHADE)))
+ if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE))
AttackStart(akama);
}
@@ -1073,7 +1070,7 @@ public:
void EnterCombat(Unit* /*who*/) override
{
- _events.ScheduleEvent(EVENT_SPIRIT_HEAL, randtime(Seconds(5), Seconds(6)));
+ _events.ScheduleEvent(EVENT_SPIRIT_HEAL, Seconds(5), Seconds(6));
}
void DamageTaken(Unit* /*who*/, uint32& /*damage*/) override
@@ -1083,7 +1080,7 @@ public:
{
DoCastSelf(SPELL_SPIRIT_MEND);
_spiritMend = true;
- _events.ScheduleEvent(EVENT_SPIRIT_MEND_RESET, randtime(Seconds(10),Seconds(15)));
+ _events.ScheduleEvent(EVENT_SPIRIT_MEND_RESET, Seconds(10),Seconds(15));
}
if (!_chainHeal)
@@ -1091,7 +1088,7 @@ public:
{
DoCastSelf(SPELL_CHAIN_HEAL);
_chainHeal = true;
- _events.ScheduleEvent(EVENT_CHAIN_HEAL_RESET, randtime(Seconds(10), Seconds(15)));
+ _events.ScheduleEvent(EVENT_CHAIN_HEAL_RESET, Seconds(10), Seconds(15));
}
}
@@ -1108,7 +1105,7 @@ public:
{
case EVENT_SPIRIT_HEAL:
DoCastSelf(SPELL_SPIRITBINDER_SPIRIT_HEAL);
- _events.Repeat(randtime(Seconds(13), Seconds(16)));
+ _events.Repeat(Seconds(13), Seconds(16));
break;
case EVENT_SPIRIT_MEND_RESET:
_spiritMend = false;
@@ -1157,7 +1154,7 @@ public:
if (motionType != POINT_MOTION_TYPE)
return;
- if (Creature* akama = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AKAMA_SHADE)))
+ if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE))
me->SetFacingToObject(akama);
}
diff --git a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp
index bac996918ac..2784792fe8d 100644
--- a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp
+++ b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp
@@ -22,17 +22,20 @@
DoorData const doorData[] =
{
{ GO_NAJENTUS_GATE, DATA_HIGH_WARLORD_NAJENTUS, DOOR_TYPE_PASSAGE },
- { GO_NAJENTUS_GATE, DATA_SUPREMUS, DOOR_TYPE_ROOM },
+ { GO_NAJENTUS_GATE, DATA_SUPREMUS, DOOR_TYPE_ROOM },
{ GO_SUPREMUS_GATE, DATA_SUPREMUS, DOOR_TYPE_PASSAGE },
- { GO_SHADE_OF_AKAMA_DOOR, DATA_SHADE_OF_AKAMA, DOOR_TYPE_ROOM },
- { GO_TERON_DOOR_1, DATA_TERON_GOREFIEND, DOOR_TYPE_ROOM },
- { GO_TERON_DOOR_2, DATA_TERON_GOREFIEND, DOOR_TYPE_ROOM },
+ { GO_SHADE_OF_AKAMA_DOOR, DATA_SHADE_OF_AKAMA, DOOR_TYPE_ROOM },
+ { GO_TERON_DOOR_1, DATA_TERON_GOREFIEND, DOOR_TYPE_ROOM },
+ { GO_TERON_DOOR_2, DATA_TERON_GOREFIEND, DOOR_TYPE_ROOM },
{ GO_GURTOGG_DOOR, DATA_GURTOGG_BLOODBOIL, DOOR_TYPE_PASSAGE },
{ GO_TEMPLE_DOOR, DATA_RELIQUARY_OF_SOULS, DOOR_TYPE_PASSAGE },
{ GO_MOTHER_SHAHRAZ_DOOR, DATA_MOTHER_SHAHRAZ, DOOR_TYPE_PASSAGE },
- { GO_COUNCIL_DOOR_1, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM },
- { GO_COUNCIL_DOOR_2, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM },
- { 0, 0, DOOR_TYPE_ROOM } // END
+ { GO_COUNCIL_DOOR_1, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM },
+ { GO_COUNCIL_DOOR_2, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM },
+ //{ GO_ILLIDAN_GATE, DATA_GO_ILLIDAN_GATE, DOOR_TYPE_PASSAGE },
+ { GO_ILLIDAN_DOOR_R, DATA_ILLIDAN_STORMRAGE, DOOR_TYPE_ROOM },
+ { GO_ILLIDAN_DOOR_L, DATA_ILLIDAN_STORMRAGE, DOOR_TYPE_ROOM },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
BossBoundaryData const boundaries =
@@ -49,6 +52,27 @@ BossBoundaryData const boundaries =
{ DATA_ILLIDAN_STORMRAGE, new EllipseBoundary(Position(694.8f, 309.0f), 70.0 , 85.0) }
};
+ObjectData const creatureData[] =
+{
+ { NPC_HIGH_WARLORD_NAJENTUS, DATA_HIGH_WARLORD_NAJENTUS },
+ { NPC_SUPREMUS, DATA_SUPREMUS },
+ { NPC_SHADE_OF_AKAMA, DATA_SHADE_OF_AKAMA },
+ { NPC_TERON_GOREFIEND, DATA_TERON_GOREFIEND },
+ { NPC_GURTOGG_BLOODBOIL, DATA_GURTOGG_BLOODBOIL },
+ { NPC_RELIQUARY_OF_SOULS, DATA_RELIQUARY_OF_SOULS },
+ { NPC_MOTHER_SHAHRAZ, DATA_MOTHER_SHAHRAZ },
+ { NPC_ILLIDARI_COUNCIL, DATA_ILLIDARI_COUNCIL },
+ { NPC_ILLIDAN_STORMRAGE, DATA_ILLIDAN_STORMRAGE },
+ { NPC_AKAMA_SHADE, DATA_AKAMA_SHADE },
+ { NPC_AKAMA, DATA_AKAMA },
+ { NPC_GATHIOS_THE_SHATTERER, DATA_GATHIOS_THE_SHATTERER },
+ { NPC_HIGH_NETHERMANCER_ZEREVOR, DATA_HIGH_NETHERMANCER_ZEREVOR },
+ { NPC_LADY_MALANDE, DATA_LADY_MALANDE },
+ { NPC_VERAS_DARKSHADOW, DATA_VERAS_DARKSHADOW },
+ { NPC_BLOOD_ELF_COUNCIL_VOICE, DATA_BLOOD_ELF_COUNCIL_VOICE },
+ { 0, 0 } // end
+};
+
class instance_black_temple : public InstanceMapScript
{
public:
@@ -61,165 +85,28 @@ class instance_black_temple : public InstanceMapScript
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
+ LoadObjectData(creatureData, nullptr);
LoadBossBoundaries(boundaries);
}
- void OnCreatureCreate(Creature* creature) override
- {
- switch (creature->GetEntry())
- {
- case NPC_HIGH_WARLORD_NAJENTUS:
- NajentusGUID = creature->GetGUID();
- break;
- case NPC_SUPREMUS:
- SupremusGUID = creature->GetGUID();
- break;
- case NPC_SHADE_OF_AKAMA:
- ShadeOfAkamaGUID = creature->GetGUID();
- break;
- case NPC_AKAMA_SHADE:
- AkamaShadeGUID = creature->GetGUID();
- break;
- case NPC_AKAMA:
- AkamaGUID = creature->GetGUID();
- break;
- case NPC_GATHIOS_THE_SHATTERER:
- GathiosTheShattererGUID = creature->GetGUID();
- break;
- case NPC_HIGH_NETHERMANCER_ZEREVOR:
- HighNethermancerZerevorGUID = creature->GetGUID();
- break;
- case NPC_LADY_MALANDE:
- LadyMalandeGUID = creature->GetGUID();
- break;
- case NPC_VERAS_DARKSHADOW:
- VerasDarkshadowGUID = creature->GetGUID();
- break;
- case NPC_ILLIDARI_COUNCIL:
- IllidariCouncilGUID = creature->GetGUID();
- break;
- case NPC_BLOOD_ELF_COUNCIL_VOICE:
- BloodElfCouncilVoiceGUID = creature->GetGUID();
- break;
- case NPC_ILLIDAN_STORMRAGE:
- IllidanStormrageGUID = creature->GetGUID();
- break;
- default:
- break;
- }
- }
-
void OnGameObjectCreate(GameObject* go) override
{
- switch (go->GetEntry())
- {
- case GO_NAJENTUS_GATE:
- case GO_SUPREMUS_GATE:
- case GO_SHADE_OF_AKAMA_DOOR:
- case GO_TERON_DOOR_1:
- case GO_TERON_DOOR_2:
- case GO_GURTOGG_DOOR:
- case GO_TEMPLE_DOOR:
- case GO_MOTHER_SHAHRAZ_DOOR:
- case GO_COUNCIL_DOOR_1:
- case GO_COUNCIL_DOOR_2:
- AddDoor(go, true);
- break;
- case GO_ILLIDAN_GATE:
- IllidanGateGUID = go->GetGUID();
- break;
- case GO_ILLIDAN_DOOR_R:
- IllidanDoorGUIDs[0] = go->GetGUID();
- break;
- case GO_ILLIDAN_DOOR_L:
- IllidanDoorGUIDs[1] = go->GetGUID();
- break;
- default:
- break;
- }
- }
+ if (go->GetEntry() == GO_ILLIDAN_GATE)
+ IllidanGateGUID = go->GetGUID();
- void OnGameObjectRemove(GameObject* go) override
- {
- switch (go->GetEntry())
- {
- case GO_NAJENTUS_GATE:
- case GO_SUPREMUS_GATE:
- case GO_SHADE_OF_AKAMA_DOOR:
- case GO_TERON_DOOR_1:
- case GO_TERON_DOOR_2:
- case GO_GURTOGG_DOOR:
- case GO_TEMPLE_DOOR:
- case GO_MOTHER_SHAHRAZ_DOOR:
- case GO_COUNCIL_DOOR_1:
- case GO_COUNCIL_DOOR_2:
- AddDoor(go, false);
- break;
- default:
- break;
- }
+ InstanceScript::OnGameObjectCreate(go);
}
ObjectGuid GetGuidData(uint32 type) const override
{
- switch (type)
- {
- case DATA_HIGH_WARLORD_NAJENTUS:
- return NajentusGUID;
- case DATA_SUPREMUS:
- return SupremusGUID;
- case DATA_SHADE_OF_AKAMA:
- return ShadeOfAkamaGUID;
- case DATA_AKAMA_SHADE:
- return AkamaShadeGUID;
- case DATA_AKAMA:
- return AkamaGUID;
- case DATA_GATHIOS_THE_SHATTERER:
- return GathiosTheShattererGUID;
- case DATA_HIGH_NETHERMANCER_ZEREVOR:
- return HighNethermancerZerevorGUID;
- case DATA_LADY_MALANDE:
- return LadyMalandeGUID;
- case DATA_VERAS_DARKSHADOW:
- return VerasDarkshadowGUID;
- case DATA_ILLIDARI_COUNCIL:
- return IllidariCouncilGUID;
- case DATA_BLOOD_ELF_COUNCIL_VOICE:
- return BloodElfCouncilVoiceGUID;
- case DATA_ILLIDAN_STORMRAGE:
- return IllidanStormrageGUID;
- case DATA_GO_ILLIDAN_GATE:
- return IllidanGateGUID;
- case DATA_GO_ILLIDAN_DOOR_R:
- return IllidanDoorGUIDs[0];
- case DATA_GO_ILLIDAN_DOOR_L:
- return IllidanDoorGUIDs[1];
- default:
- break;
- }
+ if (type == DATA_GO_ILLIDAN_GATE)
+ return IllidanGateGUID;
- return ObjectGuid::Empty;
+ return InstanceScript::GetGuidData(type);
}
protected:
- ObjectGuid NajentusGUID;
- ObjectGuid SupremusGUID;
- ObjectGuid ShadeOfAkamaGUID;
- ObjectGuid AkamaShadeGUID;
- ObjectGuid AkamaGUID;
-
- ObjectGuid GathiosTheShattererGUID;
- ObjectGuid HighNethermancerZerevorGUID;
- ObjectGuid LadyMalandeGUID;
- ObjectGuid VerasDarkshadowGUID;
-
- ObjectGuid IllidariCouncilGUID;
- ObjectGuid BloodElfCouncilVoiceGUID;
-
- ObjectGuid IllidanStormrageGUID;
-
ObjectGuid IllidanGateGUID;
- ObjectGuid IllidanDoorGUIDs[2];
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
index 90bf8bb1948..3b364d557ed 100644
--- a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
+++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
@@ -332,8 +332,14 @@ public:
enum FelGuard
{
- SPELL_SUMMON_POO = 37688,
- NPC_DERANGED_HELBOAR = 16863
+ SPELL_SUMMON_POO = 37688,
+ SPELL_FAKE_BLOOD = 37692,
+ NPC_DERANGED_HELBOAR = 16863,
+
+ EVENT_SEARCH_HELBOAR = 1,
+ EVENT_HELBOAR_FOUND = 2,
+ EVENT_SUMMON_POO = 3,
+ EVENT_FOLLOW_PLAYER = 4
};
class npc_fel_guard_hound : public CreatureScript
@@ -350,8 +356,8 @@ public:
void Initialize()
{
- checkTimer = 5000; //check for creature every 5 sec
helboarGUID.Clear();
+ _events.ScheduleEvent(EVENT_SEARCH_HELBOAR, Seconds(3));
}
void Reset() override
@@ -366,29 +372,54 @@ public:
if (Creature* helboar = ObjectAccessor::GetCreature(*me, helboarGUID))
{
- helboar->RemoveCorpse();
- DoCast(SPELL_SUMMON_POO);
-
- if (Player* owner = me->GetCharmerOrOwnerPlayerOrPlayerItself())
- me->GetMotionMaster()->MoveFollow(owner, 0.0f, 0.0f);
+ _events.CancelEvent(EVENT_SEARCH_HELBOAR);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK_UNARMED);
+ me->CastSpell(helboar, SPELL_FAKE_BLOOD);
+ _events.ScheduleEvent(EVENT_HELBOAR_FOUND, Seconds(2));
}
}
void UpdateAI(uint32 diff) override
{
- if (checkTimer <= diff)
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
{
- if (Creature* helboar = me->FindNearestCreature(NPC_DERANGED_HELBOAR, 10.0f, false))
+ switch (eventId)
{
- if (helboar->GetGUID() != helboarGUID && me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE && !me->FindCurrentSpellBySpellId(SPELL_SUMMON_POO))
- {
- helboarGUID = helboar->GetGUID();
- me->GetMotionMaster()->MovePoint(1, helboar->GetPositionX(), helboar->GetPositionY(), helboar->GetPositionZ());
- }
+ case EVENT_SEARCH_HELBOAR:
+ if (Creature* helboar = me->FindNearestCreature(NPC_DERANGED_HELBOAR, 10.0f, false))
+ {
+ if (helboar->GetGUID() != helboarGUID && me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE && !me->FindCurrentSpellBySpellId(SPELL_SUMMON_POO))
+ {
+ helboarGUID = helboar->GetGUID();
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(1, helboar->GetPositionX(), helboar->GetPositionY(), helboar->GetPositionZ());
+ helboar->DespawnOrUnsummon(Seconds(10));
+ }
+ }
+ _events.Repeat(Seconds(3));
+ break;
+ case EVENT_HELBOAR_FOUND:
+ if (Creature* helboar = ObjectAccessor::GetCreature(*me, helboarGUID))
+ {
+ me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK_UNARMED);
+ me->CastSpell(helboar, SPELL_FAKE_BLOOD);
+ _events.ScheduleEvent(EVENT_SUMMON_POO, Seconds(1));
+ }
+ break;
+ case EVENT_SUMMON_POO:
+ DoCast(SPELL_SUMMON_POO);
+ _events.ScheduleEvent(EVENT_FOLLOW_PLAYER, Seconds(2));
+ break;
+ case EVENT_FOLLOW_PLAYER:
+ me->SetWalk(false);
+ if (Player* owner = me->GetCharmerOrOwnerPlayerOrPlayerItself())
+ me->GetMotionMaster()->MoveFollow(owner, 0.0f, 0.0f);
+ _events.ScheduleEvent(EVENT_SEARCH_HELBOAR, Seconds(3));
+ break;
}
- checkTimer = 5000;
}
- else checkTimer -= diff;
if (!UpdateVictim())
return;
@@ -397,7 +428,7 @@ public:
}
private:
- uint32 checkTimer;
+ EventMap _events;
ObjectGuid helboarGUID;
};
@@ -892,6 +923,122 @@ public:
}
};
+enum Aledis
+{
+ SAY_CHALLENGE = 0,
+ SAY_DEFEATED = 1,
+ EVENT_TALK = 1,
+ EVENT_ATTACK = 2,
+ EVENT_EVADE = 3,
+ EVENT_FIREBALL = 4,
+ EVENT_FROSTNOVA = 5,
+ SPELL_FIREBALL = 20823,
+ SPELL_FROSTNOVA = 11831
+};
+
+class npc_magister_aledis : public CreatureScript
+{
+public:
+ npc_magister_aledis() : CreatureScript("npc_magister_aledis") { }
+
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 /*action*/) override
+ {
+ CloseGossipMenuFor(player);
+ creature->StopMoving();
+ ENSURE_AI(npc_magister_aledis::npc_magister_aledisAI, creature->AI())->StartFight(player);
+ return true;
+ }
+
+ struct npc_magister_aledisAI : public ScriptedAI
+ {
+ npc_magister_aledisAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void StartFight(Player* player)
+ {
+ me->Dismount();
+ me->SetFacingToObject(player, true);
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ _playerGUID = player->GetGUID();
+ _events.ScheduleEvent(EVENT_TALK, Seconds(2));
+ }
+
+ void Reset() override
+ {
+ me->RestoreFaction();
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32 &damage) override
+ {
+ if (damage > me->GetHealth() || me->HealthBelowPctDamaged(20, damage))
+ {
+ damage = 0;
+
+ _events.Reset();
+ me->RestoreFaction();
+ me->RemoveAllAuras();
+ me->DeleteThreatList();
+ me->CombatStop(true);
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ Talk(SAY_DEFEATED);
+
+ _events.ScheduleEvent(EVENT_EVADE, Minutes(1));
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_TALK:
+ Talk(SAY_CHALLENGE);
+ _events.ScheduleEvent(EVENT_ATTACK, Seconds(2));
+ break;
+ case EVENT_ATTACK:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ me->setFaction(FACTION_HOSTILE);
+ me->CombatStart(ObjectAccessor::GetPlayer(*me, _playerGUID));
+ _events.ScheduleEvent(EVENT_FIREBALL, 1);
+ _events.ScheduleEvent(EVENT_FROSTNOVA, Seconds(5));
+ break;
+ case EVENT_FIREBALL:
+ DoCast(SPELL_FIREBALL);
+ _events.ScheduleEvent(EVENT_FIREBALL, Seconds(10));
+ break;
+ case EVENT_FROSTNOVA:
+ DoCastAOE(SPELL_FROSTNOVA);
+ _events.ScheduleEvent(EVENT_FROSTNOVA, Seconds(20));
+ break;
+ case EVENT_EVADE:
+ EnterEvadeMode();
+ break;
+ }
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ ObjectGuid _playerGUID;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_magister_aledisAI(creature);
+ }
+};
+
void AddSC_hellfire_peninsula()
{
new npc_aeranas();
@@ -900,4 +1047,5 @@ void AddSC_hellfire_peninsula()
new npc_fel_guard_hound();
new npc_colonel_jules();
new npc_barada();
+ new npc_magister_aledis();
}
diff --git a/src/server/scripts/Pet/pet_hunter.cpp b/src/server/scripts/Pet/pet_hunter.cpp
index 5b4b26e599e..a155dbc36c4 100644
--- a/src/server/scripts/Pet/pet_hunter.cpp
+++ b/src/server/scripts/Pet/pet_hunter.cpp
@@ -215,7 +215,7 @@ class spell_pet_guard_dog : public SpellScriptLoader
Unit* caster = eventInfo.GetActor();
caster->CastSpell((Unit*)nullptr, SPELL_PET_GUARD_DOG_HAPPINESS, true);
- float addThreat = CalculatePct(eventInfo.GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster), aurEff->GetAmount());
+ float addThreat = CalculatePct(ASSERT_NOTNULL(eventInfo.GetSpellInfo())->Effects[EFFECT_0].CalcValue(caster), aurEff->GetAmount());
eventInfo.GetProcTarget()->AddThreat(caster, addThreat);
}
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index a1543e1199c..7cce7e4655e 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -2801,17 +2801,25 @@ public:
class player_ghoulAI : public PlayerAI
{
public:
- player_ghoulAI(Player* player, ObjectGuid ghoulGUID) : PlayerAI(player), _ghoulGUID(ghoulGUID) { }
+ player_ghoulAI(Player* player, ObjectGuid ghoulGUID) : PlayerAI(player), _ghoulGUID(ghoulGUID), _ghoulCheckTimer(1000){ }
- void UpdateAI(uint32 /*diff*/) override
+ void UpdateAI(uint32 diff) override
{
- Creature* ghoul = ObjectAccessor::GetCreature(*me, _ghoulGUID);
- if (!ghoul || !ghoul->IsAlive())
- me->RemoveAura(SPELL_DK_RAISE_ALLY);
+ if (_ghoulCheckTimer <= diff)
+ {
+ _ghoulCheckTimer = 1000;
+
+ Creature* ghoul = ObjectAccessor::GetCreature(*me, _ghoulGUID);
+ if (!ghoul || !ghoul->IsAlive())
+ me->RemoveAura(SPELL_DK_RAISE_ALLY);
+ }
+ else
+ _ghoulCheckTimer -= diff;
}
private:
ObjectGuid _ghoulGUID;
+ uint32 _ghoulCheckTimer;
};
// 46619 - Raise Ally
@@ -2833,7 +2841,7 @@ public:
void SendText()
{
if (Unit* original = GetOriginalCaster())
- original->Whisper(TEXT_RISE_ALLY, GetCaster()->ToPlayer(), true);
+ original->Unit::Whisper(TEXT_RISE_ALLY, GetCaster()->ToPlayer(), true);
}
void HandleSummon(SpellEffIndex effIndex)
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 794ef470d40..f1eaf45770e 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -1100,9 +1100,17 @@ class spell_gen_creature_permanent_feign_death : public SpellScriptLoader
target->ToCreature()->SetReactState(REACT_PASSIVE);
}
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+ target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
+ target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
+ }
+
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_gen_creature_permanent_feign_death_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_creature_permanent_feign_death_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index e95bfe4395c..e18dc838965 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -275,6 +275,70 @@ class spell_hun_chimera_shot : public SpellScriptLoader
}
};
+// -53256 - Cobra Strikes
+class spell_hun_cobra_strikes : public SpellScriptLoader
+{
+ public:
+ spell_hun_cobra_strikes() : SpellScriptLoader("spell_hun_cobra_strikes") { }
+
+ class spell_hun_cobra_strikes_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_cobra_strikes_AuraScript);
+
+ bool Validate(SpellInfo const* spellInfo) override
+ {
+ if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].TriggerSpell))
+ return false;
+ return true;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+
+ SpellInfo const* triggeredSpellInfo = sSpellMgr->AssertSpellInfo(GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell);
+ GetTarget()->CastCustomSpell(triggeredSpellInfo->Id, SPELLVALUE_AURA_STACK, triggeredSpellInfo->StackAmount, (Unit*)nullptr, true);
+ }
+
+ void Register() override
+ {
+ OnEffectProc += AuraEffectProcFn(spell_hun_cobra_strikes_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_hun_cobra_strikes_AuraScript();
+ }
+};
+
+// 53257 - Cobra Strikes (triggered spell)
+class spell_hun_cobra_strikes_triggered : public SpellScriptLoader
+{
+ public:
+ spell_hun_cobra_strikes_triggered() : SpellScriptLoader("spell_hun_cobra_strikes_triggered") { }
+
+ class spell_hun_cobra_strikes_triggered_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_cobra_strikes_triggered_AuraScript);
+
+ void HandleStackDrop(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
+ {
+ ModStackAmount(-1);
+ }
+
+ void Register() override
+ {
+ OnEffectProc += AuraEffectProcFn(spell_hun_cobra_strikes_triggered_AuraScript::HandleStackDrop, EFFECT_0, SPELL_AURA_ADD_FLAT_MODIFIER);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_hun_cobra_strikes_triggered_AuraScript();
+ }
+};
+
// 781 - Disengage
class spell_hun_disengage : public SpellScriptLoader
{
@@ -388,7 +452,7 @@ class spell_hun_glyph_of_mend_pet : public SpellScriptLoader
void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
- eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS, true);
+ eventInfo.GetProcTarget()->CastSpell((Unit*)nullptr, SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS, true);
}
void Register() override
@@ -664,35 +728,6 @@ class spell_hun_lock_and_load : public SpellScriptLoader
}
};
-// 56342 - Lock and Load (Rank 1)
-class spell_hun_lock_and_load_dummy : public SpellScriptLoader
-{
- public:
- spell_hun_lock_and_load_dummy() : SpellScriptLoader("spell_hun_lock_and_load_dummy") { }
-
- class spell_hun_lock_and_load_dummy_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_hun_lock_and_load_dummy_AuraScript);
-
- bool DummyCheck(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
- {
- // Prevents Aura proc from this dummy effect
- // Only rank 1 has this aura
- return false;
- }
-
- void Register() override
- {
- DoCheckEffectProc += AuraCheckEffectProcFn(spell_hun_lock_and_load_dummy_AuraScript::DummyCheck, EFFECT_2, SPELL_AURA_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_hun_lock_and_load_dummy_AuraScript();
- }
-};
-
// 53271 - Masters Call
class spell_hun_masters_call : public SpellScriptLoader
{
@@ -710,30 +745,58 @@ class spell_hun_masters_call : public SpellScriptLoader
return true;
}
+ bool Load() override
+ {
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
+ }
+
+ SpellCastResult DoCheckCast()
+ {
+ Pet* pet = GetCaster()->ToPlayer()->GetPet();
+ ASSERT(pet); // checked in Spell::CheckCast
+
+ if (!pet->IsAlive())
+ return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
+
+ // Do a mini Spell::CheckCasterAuras on the pet, no other way of doing this
+ SpellCastResult result = SPELL_CAST_OK;
+ uint32 const unitflag = pet->GetUInt32Value(UNIT_FIELD_FLAGS);
+ if (pet->GetCharmerGUID())
+ result = SPELL_FAILED_CHARMED;
+ else if (unitflag & UNIT_FLAG_STUNNED)
+ result = SPELL_FAILED_STUNNED;
+ else if (unitflag & UNIT_FLAG_FLEEING)
+ result = SPELL_FAILED_FLEEING;
+ else if (unitflag & UNIT_FLAG_CONFUSED)
+ result = SPELL_FAILED_CONFUSED;
+
+ if (result != SPELL_CAST_OK)
+ return result;
+
+ Unit* target = GetExplTargetUnit();
+ if (!target)
+ return SPELL_FAILED_BAD_TARGETS;
+
+ if (!pet->IsWithinLOSInMap(target))
+ return SPELL_FAILED_LINE_OF_SIGHT;
+
+ return SPELL_CAST_OK;
+ }
+
void HandleDummy(SpellEffIndex /*effIndex*/)
{
- if (Unit* ally = GetHitUnit())
- if (Player* caster = GetCaster()->ToPlayer())
- if (Pet* target = caster->GetPet())
- {
- TriggerCastFlags castMask = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_CASTER_AURASTATE);
- target->CastSpell(ally, GetEffectValue(), castMask);
- target->CastSpell(ally, GetSpellInfo()->Effects[EFFECT_0].CalcValue(), castMask);
- }
+ GetCaster()->ToPlayer()->GetPet()->CastSpell(GetHitUnit(), GetEffectValue(), true);
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
- if (Unit* target = GetHitUnit())
- {
- // Cannot be processed while pet is dead
- TriggerCastFlags castMask = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_CASTER_AURASTATE);
- target->CastSpell(target, SPELL_HUNTER_MASTERS_CALL_TRIGGERED, castMask);
- }
+ GetHitUnit()->CastSpell((Unit*)nullptr, SPELL_HUNTER_MASTERS_CALL_TRIGGERED, true);
}
void Register() override
{
+ OnCheckCast += SpellCheckCastFn(spell_hun_masters_call_SpellScript::DoCheckCast);
+
OnEffectHitTarget += SpellEffectFn(spell_hun_masters_call_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
OnEffectHitTarget += SpellEffectFn(spell_hun_masters_call_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
@@ -1505,6 +1568,8 @@ void AddSC_hunter_spell_scripts()
new spell_hun_aspect_of_the_beast();
new spell_hun_ascpect_of_the_viper();
new spell_hun_chimera_shot();
+ new spell_hun_cobra_strikes();
+ new spell_hun_cobra_strikes_triggered();
new spell_hun_disengage();
new spell_hun_glyph_of_arcane_shot();
new spell_hun_glyph_of_mend_pet();
@@ -1514,7 +1579,6 @@ void AddSC_hunter_spell_scripts()
new spell_hun_kill_command_pet();
new spell_hun_last_stand_pet();
new spell_hun_lock_and_load();
- new spell_hun_lock_and_load_dummy();
new spell_hun_masters_call();
new spell_hun_misdirection();
new spell_hun_misdirection_proc();
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index f51b9e8e965..b45df66e0ac 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -1961,6 +1961,8 @@ class spell_item_shadows_fate : public SpellScriptLoader
void HandleProc(ProcEventInfo& procInfo)
{
+ PreventDefaultAction();
+
Unit* caster = procInfo.GetActor();
Unit* target = GetCaster();
if (!caster || !target)
@@ -4343,6 +4345,119 @@ class spell_item_taunt_flag_targeting : public SpellScriptLoader
}
};
+// 13180 - Gnomish Mind Control Cap
+enum MindControlCap
+{
+ ROLL_CHANCE_DULLARD = 32,
+ ROLL_CHANCE_NO_BACKFIRE = 95,
+ SPELL_GNOMISH_MIND_CONTROL_CAP = 13181,
+ SPELL_DULLARD = 67809
+};
+
+class spell_item_mind_control_cap : public SpellScriptLoader
+{
+ public:
+ spell_item_mind_control_cap() : SpellScriptLoader("spell_item_mind_control_cap") { }
+
+ class spell_item_mind_control_cap_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_item_mind_control_cap_SpellScript);
+
+ bool Load() override
+ {
+ if (!GetCastItem())
+ return false;
+ return true;
+ }
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_GNOMISH_MIND_CONTROL_CAP) || !sSpellMgr->GetSpellInfo(SPELL_DULLARD))
+ return false;
+ return true;
+ }
+
+ void HandleDummy(SpellEffIndex /* effIndex */)
+ {
+ Unit* caster = GetCaster();
+ if (Unit* target = GetHitUnit())
+ {
+ if (roll_chance_i(ROLL_CHANCE_NO_BACKFIRE))
+ caster->CastSpell(target, roll_chance_i(ROLL_CHANCE_DULLARD) ? SPELL_DULLARD : SPELL_GNOMISH_MIND_CONTROL_CAP, true, GetCastItem());
+ else
+ target->CastSpell(caster, SPELL_GNOMISH_MIND_CONTROL_CAP, true); // backfire - 5% chance
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_item_mind_control_cap_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_item_mind_control_cap_SpellScript();
+ }
+};
+
+// 8344 - Universal Remote (Gnomish Universal Remote)
+enum UniversalRemote
+{
+ SPELL_CONTROL_MACHINE = 8345,
+ SPELL_MOBILITY_MALFUNCTION = 8346,
+ SPELL_TARGET_LOCK = 8347
+};
+
+class spell_item_universal_remote : public SpellScriptLoader
+{
+ public:
+ spell_item_universal_remote() : SpellScriptLoader("spell_item_universal_remote") { }
+
+ class spell_item_universal_remote_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_item_universal_remote_SpellScript);
+
+ bool Load() override
+ {
+ if (!GetCastItem())
+ return false;
+ return true;
+ }
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_CONTROL_MACHINE) || !sSpellMgr->GetSpellInfo(SPELL_MOBILITY_MALFUNCTION) || !sSpellMgr->GetSpellInfo(SPELL_TARGET_LOCK))
+ return false;
+ return true;
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ {
+ uint8 chance = urand(0, 99);
+ if (chance < 15)
+ GetCaster()->CastSpell(target, SPELL_TARGET_LOCK, true, GetCastItem());
+ else if (chance < 25)
+ GetCaster()->CastSpell(target, SPELL_MOBILITY_MALFUNCTION, true, GetCastItem());
+ else
+ GetCaster()->CastSpell(target, SPELL_CONTROL_MACHINE, true, GetCastItem());
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_item_universal_remote_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_item_universal_remote_SpellScript();
+ }
+};
+
enum ZandalarianCharms
{
SPELL_UNSTABLE_POWER_AURA_STACK = 24659,
@@ -4515,6 +4630,8 @@ void AddSC_item_spell_scripts()
new spell_item_charm_witch_doctor();
new spell_item_mana_drain();
new spell_item_taunt_flag_targeting();
+ new spell_item_mind_control_cap();
+ new spell_item_universal_remote();
new spell_item_zandalarian_charm("spell_item_unstable_power", SPELL_UNSTABLE_POWER_AURA_STACK);
new spell_item_zandalarian_charm("spell_item_restless_strength", SPELL_RESTLESS_STRENGTH_AURA_STACK);
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index 30dfd2cd5d0..2aaa2e29d9c 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -1303,6 +1303,8 @@ class spell_pal_infusion_of_light : public SpellScriptLoader
Unit* target = GetTarget();
int32 duration = sSpellMgr->AssertSpellInfo(SPELL_PALADIN_FLASH_OF_LIGHT_PROC)->GetMaxDuration() / 1000;
int32 pct = GetSpellInfo()->Effects[EFFECT_2].CalcValue();
+ ASSERT(duration > 0);
+
int32 bp0 = CalculatePct(healInfo->GetHeal() / duration, pct);
// Item - Paladin T9 Holy 4P Bonus
@@ -1540,7 +1542,7 @@ class spell_pal_judgement_of_light_heal : public SpellScriptLoader
Unit* caster = eventInfo.GetProcTarget();
int32 amount = static_cast<int32>(caster->CountPctFromMaxHealth(aurEff->GetAmount()));
- caster->CastCustomSpell(SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true);
+ caster->CastCustomSpell(SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff, GetCasterGUID());
}
void Register() override
@@ -1584,7 +1586,7 @@ class spell_pal_judgement_of_wisdom_mana : public SpellScriptLoader
Unit* caster = eventInfo.GetProcTarget();
int32 amount = CalculatePct(static_cast<int32>(caster->GetCreateMana()), aurEff->GetAmount());
- caster->CastCustomSpell(SPELL_PALADIN_JUDGEMENT_OF_WISDOM_MANA, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true);
+ caster->CastCustomSpell(SPELL_PALADIN_JUDGEMENT_OF_WISDOM_MANA, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff, GetCasterGUID());
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index 2eca20199b4..fd99888f8d9 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -2565,6 +2565,146 @@ public:
}
};
+enum ApplyHeatAndStir
+{
+ SPELL_SPURTS_AND_SMOKE = 38594,
+ SPELL_FAILED_MIX_1 = 43376,
+ SPELL_FAILED_MIX_2 = 43378,
+ SPELL_FAILED_MIX_3 = 43970,
+ SPELL_SUCCESSFUL_MIX = 43377,
+
+ CREATURE_GENERIC_TRIGGER_LAB = 24042,
+
+ TALK_0 = 0,
+ TALK_1 = 1
+};
+
+class spell_q11306_mixing_blood : public SpellScriptLoader
+{
+public:
+ spell_q11306_mixing_blood() : SpellScriptLoader("spell_q11306_mixing_blood") { }
+
+ class spell_q11306_mixing_blood_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q11306_mixing_blood_SpellScript);
+
+ void HandleEffect(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (Creature* trigger = caster->FindNearestCreature(CREATURE_GENERIC_TRIGGER_LAB, 100.0f))
+ trigger->AI()->DoCastSelf(SPELL_SPURTS_AND_SMOKE);
+ }
+
+ void Register() override
+ {
+ OnEffectHit += SpellEffectFn(spell_q11306_mixing_blood_SpellScript::HandleEffect, EFFECT_1, SPELL_EFFECT_SEND_EVENT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_q11306_mixing_blood_SpellScript();
+ }
+};
+
+class spell_q11306_mixing_vrykul_blood : public SpellScriptLoader
+{
+ public:
+ spell_q11306_mixing_vrykul_blood() : SpellScriptLoader("spell_q11306_mixing_vrykul_blood") { }
+
+ class spell_q11306_mixing_vrykul_blood_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q11306_mixing_vrykul_blood_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* caster = GetCaster())
+ {
+ uint8 chance = urand(0, 99);
+ uint32 spellId = 0;
+
+ // 90% chance of getting one out of three failure effects
+ if (chance < 30)
+ spellId = SPELL_FAILED_MIX_1;
+ else if (chance < 60)
+ spellId = SPELL_FAILED_MIX_2;
+ else if (chance < 90)
+ spellId = SPELL_FAILED_MIX_3;
+ else // 10% chance of successful cast
+ spellId = SPELL_SUCCESSFUL_MIX;
+
+ caster->CastSpell(caster, spellId, true);
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q11306_mixing_vrykul_blood_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_q11306_mixing_vrykul_blood_SpellScript();
+ }
+};
+
+class spell_q11306_failed_mix_43376 : public SpellScriptLoader
+{
+public:
+ spell_q11306_failed_mix_43376() : SpellScriptLoader("spell_q11306_failed_mix_43376") { }
+
+ class spell_q11306_failed_mix_43376_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q11306_failed_mix_43376_SpellScript);
+
+ void HandleEffect(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (Creature* trigger = caster->FindNearestCreature(CREATURE_GENERIC_TRIGGER_LAB, 100.0f))
+ trigger->AI()->Talk(TALK_0, caster);
+ }
+
+ void Register() override
+ {
+ OnEffectHit += SpellEffectFn(spell_q11306_failed_mix_43376_SpellScript::HandleEffect, EFFECT_1, SPELL_EFFECT_SEND_EVENT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_q11306_failed_mix_43376_SpellScript();
+ }
+};
+
+class spell_q11306_failed_mix_43378 : public SpellScriptLoader
+{
+public:
+ spell_q11306_failed_mix_43378() : SpellScriptLoader("spell_q11306_failed_mix_43378") { }
+
+ class spell_q11306_failed_mix_43378_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q11306_failed_mix_43378_SpellScript);
+
+ void HandleEffect(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (Creature* trigger = caster->FindNearestCreature(CREATURE_GENERIC_TRIGGER_LAB, 100.0f))
+ trigger->AI()->Talk(TALK_1, caster);
+ }
+
+ void Register() override
+ {
+ OnEffectHit += SpellEffectFn(spell_q11306_failed_mix_43378_SpellScript::HandleEffect, EFFECT_2, SPELL_EFFECT_SEND_EVENT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_q11306_failed_mix_43378_SpellScript();
+ }
+};
+
void AddSC_quest_spell_scripts()
{
new spell_q55_sacred_cleansing();
@@ -2628,4 +2768,8 @@ void AddSC_quest_spell_scripts()
new spell_q12414_hand_over_reins();
new spell_q13665_q13790_bested_trigger();
new spell_59064_59439_portals();
+ new spell_q11306_mixing_blood();
+ new spell_q11306_mixing_vrykul_blood();
+ new spell_q11306_failed_mix_43376();
+ new spell_q11306_failed_mix_43378();
}
diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp
index cff94b6e219..397427b505f 100644
--- a/src/server/scripts/Spells/spell_shaman.cpp
+++ b/src/server/scripts/Spells/spell_shaman.cpp
@@ -83,7 +83,8 @@ enum ShamanSpells
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_T10_ENHANCEMENT_4P_BONUS = 70832,
+ SPELL_SHAMAN_BLESSING_OF_THE_ETERNALS_R1 = 51554
};
enum ShamanSpellIcons
@@ -537,6 +538,46 @@ class spell_sha_earthen_power : public SpellScriptLoader
}
};
+// -51940 - Earthliving Weapon (Passive)
+class spell_sha_earthliving_weapon : public SpellScriptLoader
+{
+ public:
+ spell_sha_earthliving_weapon() : SpellScriptLoader("spell_sha_earthliving_weapon") { }
+
+ class spell_sha_earthliving_weapon_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sha_earthliving_weapon_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_BLESSING_OF_THE_ETERNALS_R1))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ int32 chance = 20;
+ Unit* caster = eventInfo.GetActor();
+ if (AuraEffect const* aurEff = caster->GetAuraEffectOfRankedSpell(SPELL_SHAMAN_BLESSING_OF_THE_ETERNALS_R1, EFFECT_1, caster->GetGUID()))
+ if (eventInfo.GetProcTarget()->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
+ chance += aurEff->GetAmount();
+
+ return roll_chance_i(chance);
+ }
+
+ void Register() override
+ {
+ DoCheckProc += AuraCheckProcFn(spell_sha_earthliving_weapon_AuraScript::CheckProc);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_sha_earthliving_weapon_AuraScript();
+ }
+};
+
// -1535 - Fire Nova
class spell_sha_fire_nova : public SpellScriptLoader
{
@@ -1222,19 +1263,12 @@ class spell_sha_item_mana_surge : public SpellScriptLoader
return true;
}
- bool CheckProc(ProcEventInfo& eventInfo)
- {
- DamageInfo* damageInfo = eventInfo.GetDamageInfo();
- if (!damageInfo || !damageInfo->GetSpellInfo())
- return false;
-
- return true;
- }
-
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
+ if (!spellInfo)
+ return;
int32 mana = spellInfo->CalcPowerCost(GetTarget(), eventInfo.GetSchoolMask());
int32 damage = CalculatePct(mana, 35);
@@ -1244,7 +1278,6 @@ class spell_sha_item_mana_surge : public SpellScriptLoader
void Register() override
{
- DoCheckProc += AuraCheckProcFn(spell_sha_item_mana_surge_AuraScript::CheckProc);
OnEffectProc += AuraEffectProcFn(spell_sha_item_mana_surge_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
}
};
@@ -2276,6 +2309,7 @@ void AddSC_shaman_spell_scripts()
new spell_sha_earth_shield();
new spell_sha_earthbind_totem();
new spell_sha_earthen_power();
+ new spell_sha_earthliving_weapon();
new spell_sha_fire_nova();
new spell_sha_flame_shock();
new spell_sha_flametongue_weapon();
diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp
index 492da48c455..cccebab6259 100644
--- a/src/server/scripts/Spells/spell_warlock.cpp
+++ b/src/server/scripts/Spells/spell_warlock.cpp
@@ -74,6 +74,7 @@ enum WarlockSpells
SPELL_WARLOCK_SHADOWFLAME = 37378,
SPELL_WARLOCK_FLAMESHADOW = 37379,
SPELL_WARLOCK_GLYPH_OF_SUCCUBUS = 56250,
+ SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_R1 = 18213,
SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_PROC = 18371
};
@@ -449,6 +450,50 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader
}
};
+// -1120 - Drain Soul
+class spell_warl_drain_soul : public SpellScriptLoader
+{
+ public:
+ spell_warl_drain_soul() : SpellScriptLoader("spell_warl_drain_soul") { }
+
+ class spell_warl_drain_soul_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_drain_soul_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_R1) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_PROC))
+ return false;
+ return true;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+
+ Unit* caster = eventInfo.GetActor();
+ // Improved Drain Soul
+ Aura const* impDrainSoul = caster->GetAuraOfRankedSpell(SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_R1, caster->GetGUID());
+ if (!impDrainSoul)
+ return;
+
+ int32 amount = CalculatePct(caster->GetMaxPower(POWER_MANA), impDrainSoul->GetSpellInfo()->Effects[EFFECT_2].CalcValue());
+ caster->CastCustomSpell(SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_PROC, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff);
+ }
+
+ void Register() override
+ {
+ OnEffectProc += AuraEffectProcFn(spell_warl_drain_soul_AuraScript::HandleProc, EFFECT_2, SPELL_AURA_PROC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_warl_drain_soul_AuraScript();
+ }
+};
+
// 47422 - Everlasting Affliction
class spell_warl_everlasting_affliction : public SpellScriptLoader
{
@@ -509,7 +554,7 @@ class spell_warl_fel_synergy : public SpellScriptLoader
if (!damageInfo || !damageInfo->GetDamage())
return false;
- return GetTarget()->GetGuardianPet();
+ return GetTarget()->GetGuardianPet() != nullptr;
}
void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
@@ -744,44 +789,6 @@ class spell_warl_health_funnel : public SpellScriptLoader
}
};
-// -18213 - Improved Drain Soul
-class spell_warl_improved_drain_soul : public SpellScriptLoader
-{
- public:
- spell_warl_improved_drain_soul() : SpellScriptLoader("spell_warl_improved_drain_soul") { }
-
- class spell_warl_improved_drain_soul_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_warl_improved_drain_soul_AuraScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_PROC))
- return false;
- return true;
- }
-
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
- {
- PreventDefaultAction();
-
- Unit* target = GetTarget();
- int32 bp0 = CalculatePct(target->GetMaxPower(POWER_MANA), GetSpellInfo()->Effects[EFFECT_2].BasePoints);
- target->CastCustomSpell(SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_PROC, SPELLVALUE_BASE_POINT0, bp0, target, true, nullptr, aurEff);
- }
-
- void Register() override
- {
- OnEffectProc += AuraEffectProcFn(spell_warl_improved_drain_soul_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_warl_improved_drain_soul_AuraScript();
- }
-};
-
// -1454 - Life Tap
class spell_warl_life_tap : public SpellScriptLoader
{
@@ -1484,6 +1491,7 @@ void AddSC_warlock_spell_scripts()
new spell_warl_demonic_circle_teleport();
new spell_warl_demonic_empowerment();
new spell_warl_demonic_pact();
+ new spell_warl_drain_soul();
new spell_warl_everlasting_affliction();
new spell_warl_fel_synergy();
new spell_warl_glyph_of_life_tap();
@@ -1491,7 +1499,6 @@ void AddSC_warlock_spell_scripts()
new spell_warl_haunt();
new spell_warl_health_funnel();
new spell_warl_glyph_of_corruption_nightfall();
- new spell_warl_improved_drain_soul();
new spell_warl_life_tap();
new spell_warl_nether_protection();
new spell_warl_ritual_of_doom_effect();
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index 272ba71d609..91166294355 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -1429,30 +1429,23 @@ public:
{
switch (eventId)
{
- case EVENT_MM_START_MUSIC:
- {
- if (!IsHolidayActive(HOLIDAY_FIRE_FESTIVAL))
- break;
-
- Map::PlayerList const &players = go->GetMap()->GetPlayers();
- for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ case EVENT_MM_START_MUSIC:
{
- if (Player* player = itr->GetSource())
+ if (!IsHolidayActive(HOLIDAY_FIRE_FESTIVAL))
+ break;
+
+ std::vector<Player*> playersNearby;
+ go->GetPlayerListInGrid(playersNearby, go->GetMap()->GetVisibilityRange());
+ for (Player* player : playersNearby)
{
if (player->GetTeamId() == TEAM_HORDE)
- {
go->PlayDirectMusic(EVENTMIDSUMMERFIREFESTIVAL_H, player);
- }
else
- {
go->PlayDirectMusic(EVENTMIDSUMMERFIREFESTIVAL_A, player);
- }
}
+ _events.ScheduleEvent(EVENT_MM_START_MUSIC, 5000); // Every 5 second's SMSG_PLAY_MUSIC packet (PlayDirectMusic) is pushed to the client (sniffed value)
+ break;
}
-
- _events.ScheduleEvent(EVENT_MM_START_MUSIC, 5000); // Every 5 second's SMSG_PLAY_MUSIC packet (PlayDirectMusic) is pushed to the client (sniffed value)
- break;
- }
default:
break;
}