mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-27 23:56:25 +00:00
fix(Core/Scripts): Blackwing Lair overhaul (#3673)
* [Core/Scripts] BWL - Make Razorgore talk, script blackwing mage, make his spell break eggs * more to vaelastrasz * accidentally removed some of the waypoints, fuck me * Broodlord Lashlayer overhaul + supressors * Formations, waypoints for Ebonroc and roaming Flamegor (might be non-blizzlike) * complete overhaul for the basic scripts, merge with TC * last for today, door cleanup and nefarian refactor (from TC) * Doors are now working, hooraay! * Fix the boss gossip that we broke... non-intentionally lolz * Vaelstraz intro - done * small corrections to the timers, they are not blizzlike since we got no sniffs.. :^) * nefarian checked, everything seems to be fine... let the cleanup begin now * SQL seems fine as well, let's gooo * Partially Revert "SQL seems fine as well, let's gooo" This partially reverts commit b1750da58d169e9ed916eb6a6a95da93caeb0ff8. * idk why mine's called wander_distance * wtb new eyes * lost an override @ flamegor * more junk to fix the compile * anything else? whining shit.. * SpellScript header.. * how about now? * hopefully this does the trick, the condition in general works just fine, the spell is targeting the boss * Update 0000_00_00_00.sql fuck. you. * Cleanup SQL, temp comment out code for creature relations so they don't pull several rooms at once * Move the file with proper revision and location * Remove the creature_relations *fix* until there's a proper core-side fix for it. * spawndist > wander_distance * compile fix * lost a bracket in the merge * *sigh* * add new line at the end * Nefarian's whitespaces * Vael's whitespaces * Razorgore good to go as well * Header as well * finale
This commit is contained in:
@@ -7,23 +7,33 @@
|
||||
#ifndef DEF_BLACKWING_LAIR_H
|
||||
#define DEF_BLACKWING_LAIR_H
|
||||
|
||||
#include "CreatureAIImpl.h"
|
||||
|
||||
uint32 const EncounterCount = 8;
|
||||
|
||||
#define BRLScriptName "instance_blackwing_lair"
|
||||
#define BWLScriptName "instance_blackwing_lair"
|
||||
#define DataHeader "BWL"
|
||||
|
||||
enum BWLEncounter
|
||||
{
|
||||
BOSS_RAZORGORE = 0,
|
||||
BOSS_VAELASTRAZ = 1,
|
||||
BOSS_BROODLORD = 2,
|
||||
BOSS_FIREMAW = 3,
|
||||
BOSS_EBONROC = 4,
|
||||
BOSS_FLAMEGOR = 5,
|
||||
BOSS_CHROMAGGUS = 6,
|
||||
BOSS_NEFARIAN = 7
|
||||
// Encounter States/Boss GUIDs
|
||||
DATA_RAZORGORE_THE_UNTAMED = 0,
|
||||
DATA_VAELASTRAZ_THE_CORRUPT = 1,
|
||||
DATA_BROODLORD_LASHLAYER = 2,
|
||||
DATA_FIREMAW = 3,
|
||||
DATA_EBONROC = 4,
|
||||
DATA_FLAMEGOR = 5,
|
||||
DATA_CHROMAGGUS = 6,
|
||||
DATA_NEFARIAN = 7,
|
||||
|
||||
// Additional Data
|
||||
DATA_LORD_VICTOR_NEFARIUS = 8,
|
||||
|
||||
// Doors
|
||||
DATA_GO_CHROMAGGUS_DOOR = 9
|
||||
};
|
||||
|
||||
enum CreatureIds
|
||||
enum BWLCreatureIds
|
||||
{
|
||||
NPC_RAZORGORE = 12435,
|
||||
NPC_BLACKWING_DRAGON = 12422,
|
||||
@@ -32,7 +42,7 @@ enum CreatureIds
|
||||
NPC_BLACKWING_WARLOCK = 12459,
|
||||
NPC_VAELASTRAZ = 13020,
|
||||
NPC_BROODLORD = 12017,
|
||||
NPC_FIRENAW = 11983,
|
||||
NPC_FIREMAW = 11983,
|
||||
NPC_EBONROC = 14601,
|
||||
NPC_FLAMEGOR = 11981,
|
||||
NPC_CHROMAGGUS = 14020,
|
||||
@@ -40,17 +50,17 @@ enum CreatureIds
|
||||
NPC_NEFARIAN = 11583
|
||||
};
|
||||
|
||||
enum BWLData64
|
||||
enum BWLGameObjectIds
|
||||
{
|
||||
DATA_RAZORGORE_THE_UNTAMED = 1,
|
||||
DATA_VAELASTRAZ_THE_CORRUPT,
|
||||
DATA_BROODLORD_LASHLAYER,
|
||||
DATA_FIRENAW,
|
||||
DATA_EBONROC,
|
||||
DATA_FLAMEGOR,
|
||||
DATA_CHROMAGGUS,
|
||||
DATA_LORD_VICTOR_NEFARIUS,
|
||||
DATA_NEFARIAN
|
||||
GO_BLACK_DRAGON_EGG = 177807,
|
||||
GO_PORTCULLIS_RAZORGORE = 175946,
|
||||
GO_PORTCULLIS_VAELASTRASZ = 175185,
|
||||
GO_PORTCULLIS_BROODLORD = 179365,
|
||||
GO_PORTCULLIS_THREEDRAGONS = 179115,
|
||||
GO_CHROMAGGUS_LEVER = 179148,
|
||||
GO_PORTCULLIS_CHROMAGGUS = 179116,
|
||||
GO_PORTCULLIS_NEFARIAN = 179117,
|
||||
GO_SUPPRESSION_DEVICE = 179784
|
||||
};
|
||||
|
||||
enum BWLEvents
|
||||
@@ -64,7 +74,10 @@ enum BWLMisc
|
||||
{
|
||||
// Razorgore Egg Event
|
||||
ACTION_PHASE_TWO = 1,
|
||||
DATA_EGG_EVENT
|
||||
DATA_EGG_EVENT = 2,
|
||||
TALK_EGG_BROKEN_RAND = 3,
|
||||
|
||||
SAY_NEFARIAN_VAEL_INTRO = 100003, // latest id in broadcast_text atm
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "blackwing_lair.h"
|
||||
#include "GameObject.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "InstanceScript.h"
|
||||
|
||||
enum Say
|
||||
{
|
||||
@@ -19,7 +22,8 @@ enum Spells
|
||||
SPELL_CLEAVE = 26350,
|
||||
SPELL_BLASTWAVE = 23331,
|
||||
SPELL_MORTALSTRIKE = 24573,
|
||||
SPELL_KNOCKBACK = 25778
|
||||
SPELL_KNOCKBACK = 25778,
|
||||
SPELL_SUPPRESSION_AURA = 22247 // Suppression Device Spell
|
||||
};
|
||||
|
||||
enum Events
|
||||
@@ -28,7 +32,15 @@ enum Events
|
||||
EVENT_BLASTWAVE = 2,
|
||||
EVENT_MORTALSTRIKE = 3,
|
||||
EVENT_KNOCKBACK = 4,
|
||||
EVENT_CHECK = 5
|
||||
EVENT_CHECK = 5,
|
||||
// Suppression Device Events
|
||||
EVENT_SUPPRESSION_CAST = 6,
|
||||
EVENT_SUPPRESSION_RESET = 7
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_DEACTIVATE = 0
|
||||
};
|
||||
|
||||
class boss_broodlord : public CreatureScript
|
||||
@@ -38,17 +50,11 @@ public:
|
||||
|
||||
struct boss_broodlordAI : public BossAI
|
||||
{
|
||||
boss_broodlordAI(Creature* creature) : BossAI(creature, BOSS_BROODLORD) { }
|
||||
boss_broodlordAI(Creature* creature) : BossAI(creature, DATA_BROODLORD_LASHLAYER) { }
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
if (instance->GetBossState(BOSS_VAELASTRAZ) != DONE)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
_EnterCombat();
|
||||
BossAI::EnterCombat(who);
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 8000);
|
||||
@@ -58,6 +64,16 @@ public:
|
||||
events.ScheduleEvent(EVENT_CHECK, 1000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
|
||||
std::list<GameObject*> _goList;
|
||||
GetGameObjectListWithEntryInGrid(_goList, me, GO_SUPPRESSION_DEVICE, 200.0f);
|
||||
for (std::list<GameObject*>::const_iterator itr = _goList.begin(); itr != _goList.end(); itr++)
|
||||
((*itr)->AI()->DoAction(ACTION_DEACTIVATE));
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
@@ -75,17 +91,17 @@ public:
|
||||
break;
|
||||
case EVENT_BLASTWAVE:
|
||||
DoCastVictim(SPELL_BLASTWAVE);
|
||||
events.ScheduleEvent(EVENT_BLASTWAVE, urand(8000, 16000));
|
||||
events.ScheduleEvent(EVENT_BLASTWAVE, 8000, 16000);
|
||||
break;
|
||||
case EVENT_MORTALSTRIKE:
|
||||
DoCastVictim(SPELL_MORTALSTRIKE);
|
||||
events.ScheduleEvent(EVENT_MORTALSTRIKE, urand(25000, 35000));
|
||||
events.ScheduleEvent(EVENT_MORTALSTRIKE, 25000, 35000);
|
||||
break;
|
||||
case EVENT_KNOCKBACK:
|
||||
DoCastVictim(SPELL_KNOCKBACK);
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
DoModifyThreatPercent(me->GetVictim(), -50);
|
||||
events.ScheduleEvent(EVENT_KNOCKBACK, urand(15000, 30000));
|
||||
events.ScheduleEvent(EVENT_KNOCKBACK, 15000, 30000);
|
||||
break;
|
||||
case EVENT_CHECK:
|
||||
if (me->GetDistance(me->GetHomePosition()) > 150.0f)
|
||||
@@ -108,7 +124,109 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class go_suppression_device : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_suppression_device() : GameObjectScript("go_suppression_device") { }
|
||||
|
||||
struct go_suppression_deviceAI : public GameObjectAI
|
||||
{
|
||||
go_suppression_deviceAI(GameObject* go) : GameObjectAI(go), _instance(go->GetInstanceScript()), _active(true) { }
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
if (_instance->GetBossState(DATA_BROODLORD_LASHLAYER) == DONE)
|
||||
{
|
||||
Deactivate();
|
||||
return;
|
||||
}
|
||||
|
||||
_events.ScheduleEvent(EVENT_SUPPRESSION_CAST, 5000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SUPPRESSION_CAST:
|
||||
if (go->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
go->CastSpell(nullptr, SPELL_SUPPRESSION_AURA);
|
||||
go->SendCustomAnim(0);
|
||||
}
|
||||
_events.ScheduleEvent(EVENT_SUPPRESSION_CAST, 5000);
|
||||
break;
|
||||
case EVENT_SUPPRESSION_RESET:
|
||||
Activate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnLootStateChanged(uint32 state, Unit* /*unit*/)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case GO_ACTIVATED:
|
||||
Deactivate();
|
||||
_events.CancelEvent(EVENT_SUPPRESSION_CAST);
|
||||
_events.ScheduleEvent(EVENT_SUPPRESSION_RESET, 30000, 120000);
|
||||
break;
|
||||
case GO_JUST_DEACTIVATED: // This case prevents the Gameobject despawn by Disarm Trap
|
||||
go->SetLootState(GO_READY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (action == ACTION_DEACTIVATE)
|
||||
{
|
||||
Deactivate();
|
||||
_events.CancelEvent(EVENT_SUPPRESSION_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
void Activate()
|
||||
{
|
||||
if (_active)
|
||||
return;
|
||||
_active = true;
|
||||
if (go->GetGoState() == GO_STATE_ACTIVE)
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
go->SetLootState(GO_READY);
|
||||
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
_events.ScheduleEvent(EVENT_SUPPRESSION_CAST, 1000);
|
||||
}
|
||||
|
||||
void Deactivate()
|
||||
{
|
||||
if (!_active)
|
||||
return;
|
||||
_active = false;
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
_events.CancelEvent(EVENT_SUPPRESSION_CAST);
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
EventMap _events;
|
||||
bool _active;
|
||||
};
|
||||
|
||||
GameObjectAI* GetAI(GameObject* go) const
|
||||
{
|
||||
return new go_suppression_deviceAI(go);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_broodlord()
|
||||
{
|
||||
new boss_broodlord();
|
||||
new go_suppression_device();
|
||||
}
|
||||
|
||||
@@ -5,9 +5,13 @@
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "Player.h"
|
||||
#include "blackwing_lair.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "GameObject.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "Map.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
enum Emotes
|
||||
{
|
||||
@@ -59,8 +63,13 @@ public:
|
||||
|
||||
struct boss_chromaggusAI : public BossAI
|
||||
{
|
||||
boss_chromaggusAI(Creature* creature) : BossAI(creature, BOSS_CHROMAGGUS)
|
||||
boss_chromaggusAI(Creature* creature) : BossAI(creature, DATA_CHROMAGGUS)
|
||||
{
|
||||
Initialize();
|
||||
|
||||
Breath1_Spell = 0;
|
||||
Breath2_Spell = 0;
|
||||
|
||||
// Select the 2 breaths that we are going to use until despawned
|
||||
// 5 possiblities for the first breath, 4 for the second, 20 total possiblites
|
||||
// This way we don't end up casting 2 of the same breath
|
||||
@@ -85,7 +94,7 @@ public:
|
||||
Breath2_Spell = SPELL_FROSTBURN;
|
||||
break;
|
||||
|
||||
// B1 - TL
|
||||
// B1 - TL
|
||||
case 4:
|
||||
Breath1_Spell = SPELL_TIMELAPSE;
|
||||
Breath2_Spell = SPELL_INCINERATE;
|
||||
@@ -103,7 +112,7 @@ public:
|
||||
Breath2_Spell = SPELL_FROSTBURN;
|
||||
break;
|
||||
|
||||
//B1 - Acid
|
||||
//B1 - Acid
|
||||
case 8:
|
||||
Breath1_Spell = SPELL_CORROSIVEACID;
|
||||
Breath2_Spell = SPELL_INCINERATE;
|
||||
@@ -121,7 +130,7 @@ public:
|
||||
Breath2_Spell = SPELL_FROSTBURN;
|
||||
break;
|
||||
|
||||
//B1 - Ignite
|
||||
//B1 - Ignite
|
||||
case 12:
|
||||
Breath1_Spell = SPELL_IGNITEFLESH;
|
||||
Breath2_Spell = SPELL_INCINERATE;
|
||||
@@ -139,7 +148,7 @@ public:
|
||||
Breath2_Spell = SPELL_FROSTBURN;
|
||||
break;
|
||||
|
||||
//B1 - Frost
|
||||
//B1 - Frost
|
||||
case 16:
|
||||
Breath1_Spell = SPELL_FROSTBURN;
|
||||
Breath2_Spell = SPELL_INCINERATE;
|
||||
@@ -161,24 +170,24 @@ public:
|
||||
EnterEvadeMode();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
void Initialize()
|
||||
{
|
||||
_Reset();
|
||||
|
||||
CurrentVurln_Spell = 0; // We use this to store our last vulnerabilty spell so we can remove it later
|
||||
Enraged = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
void Reset() override
|
||||
{
|
||||
if (instance->GetBossState(BOSS_FLAMEGOR) != DONE)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
_EnterCombat();
|
||||
_Reset();
|
||||
|
||||
events.ScheduleEvent(EVENT_SHIMMER, 0);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* victim) override
|
||||
{
|
||||
BossAI::EnterCombat(victim);
|
||||
|
||||
events.ScheduleEvent(EVENT_SHIMMER, 1000);
|
||||
events.ScheduleEvent(EVENT_BREATH_1, 30000);
|
||||
events.ScheduleEvent(EVENT_BREATH_2, 60000);
|
||||
events.ScheduleEvent(EVENT_AFFLICTION, 10000);
|
||||
@@ -214,13 +223,13 @@ public:
|
||||
break;
|
||||
}
|
||||
case EVENT_BREATH_1:
|
||||
DoCastVictim(Breath1_Spell);
|
||||
events.ScheduleEvent(EVENT_BREATH_1, 60000);
|
||||
break;
|
||||
DoCastVictim(Breath1_Spell);
|
||||
events.ScheduleEvent(EVENT_BREATH_1, 60000);
|
||||
break;
|
||||
case EVENT_BREATH_2:
|
||||
DoCastVictim(Breath2_Spell);
|
||||
events.ScheduleEvent(EVENT_BREATH_2, 60000);
|
||||
break;
|
||||
DoCastVictim(Breath2_Spell);
|
||||
events.ScheduleEvent(EVENT_BREATH_2, 60000);
|
||||
break;
|
||||
case EVENT_AFFLICTION:
|
||||
{
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
@@ -230,14 +239,14 @@ public:
|
||||
{
|
||||
DoCast(player, RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK, SPELL_BROODAF_RED, SPELL_BROODAF_BRONZE, SPELL_BROODAF_GREEN), true);
|
||||
|
||||
if (player->HasAura(SPELL_BROODAF_BLUE) &&
|
||||
if (player->HasAura(SPELL_BROODAF_BLUE) &&
|
||||
player->HasAura(SPELL_BROODAF_BLACK) &&
|
||||
player->HasAura(SPELL_BROODAF_RED) &&
|
||||
player->HasAura(SPELL_BROODAF_BRONZE) &&
|
||||
player->HasAura(SPELL_BROODAF_GREEN))
|
||||
{
|
||||
DoCast(player, SPELL_CHROMATIC_MUT_1);
|
||||
}
|
||||
{
|
||||
DoCast(player, SPELL_CHROMATIC_MUT_1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,9 +254,12 @@ public:
|
||||
break;
|
||||
case EVENT_FRENZY:
|
||||
DoCast(me, SPELL_FRENZY);
|
||||
events.ScheduleEvent(EVENT_FRENZY, urand(10000, 15000));
|
||||
events.ScheduleEvent(EVENT_FRENZY, 10000, 15000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
// Enrage if not already enraged and below 20%
|
||||
@@ -273,7 +285,46 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class go_chromaggus_lever : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_chromaggus_lever() : GameObjectScript("go_chromaggus_lever") { }
|
||||
|
||||
struct go_chromaggus_leverAI : public GameObjectAI
|
||||
{
|
||||
go_chromaggus_leverAI(GameObject* go) : GameObjectAI(go), _instance(go->GetInstanceScript()) { }
|
||||
|
||||
bool OnGossipHello(Player* player)
|
||||
{
|
||||
if (_instance->GetBossState(DATA_CHROMAGGUS) != DONE && _instance->GetBossState(DATA_CHROMAGGUS) != IN_PROGRESS)
|
||||
{
|
||||
_instance->SetBossState(DATA_CHROMAGGUS, IN_PROGRESS);
|
||||
|
||||
if (Creature* creature = _instance->instance->GetCreature(DATA_CHROMAGGUS))
|
||||
creature->AI()->AttackStart(player);
|
||||
|
||||
if (GameObject* go = _instance->instance->GetGameObject(DATA_GO_CHROMAGGUS_DOOR))
|
||||
_instance->HandleGameObject(0, true, go);
|
||||
}
|
||||
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE | GO_FLAG_IN_USE);
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
GameObjectAI* GetAI(GameObject* go) const override
|
||||
{
|
||||
return GetInstanceAI<go_chromaggus_leverAI>(go);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_chromaggus()
|
||||
{
|
||||
new boss_chromaggus();
|
||||
new go_chromaggus_lever();
|
||||
}
|
||||
|
||||
@@ -29,20 +29,15 @@ public:
|
||||
|
||||
struct boss_ebonrocAI : public BossAI
|
||||
{
|
||||
boss_ebonrocAI(Creature* creature) : BossAI(creature, BOSS_EBONROC) { }
|
||||
boss_ebonrocAI(Creature* creature) : BossAI(creature, DATA_EBONROC) { }
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
if (instance->GetBossState(BOSS_BROODLORD) != DONE)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
_EnterCombat();
|
||||
BossAI::EnterCombat(who);
|
||||
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, 10000, 20000);
|
||||
events.ScheduleEvent(EVENT_WINGBUFFET, 30000);
|
||||
events.ScheduleEvent(EVENT_SHADOWOFEBONROC, urand(8000, 10000));
|
||||
events.ScheduleEvent(EVENT_SHADOWOFEBONROC, 8000, 10000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -61,7 +56,7 @@ public:
|
||||
{
|
||||
case EVENT_SHADOWFLAME:
|
||||
DoCastVictim(SPELL_SHADOWFLAME);
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, 10000, 20000);
|
||||
break;
|
||||
case EVENT_WINGBUFFET:
|
||||
DoCastVictim(SPELL_WINGBUFFET);
|
||||
@@ -69,9 +64,12 @@ public:
|
||||
break;
|
||||
case EVENT_SHADOWOFEBONROC:
|
||||
DoCastVictim(SPELL_SHADOWOFEBONROC);
|
||||
events.ScheduleEvent(EVENT_SHADOWOFEBONROC, urand(8000, 10000));
|
||||
events.ScheduleEvent(EVENT_SHADOWOFEBONROC, 8000, 10000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
@@ -29,18 +29,13 @@ public:
|
||||
|
||||
struct boss_firemawAI : public BossAI
|
||||
{
|
||||
boss_firemawAI(Creature* creature) : BossAI(creature, BOSS_FIREMAW) { }
|
||||
boss_firemawAI(Creature* creature) : BossAI(creature, DATA_FIREMAW) { }
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
if (instance->GetBossState(BOSS_BROODLORD) != DONE)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
_EnterCombat();
|
||||
BossAI::EnterCombat(who);
|
||||
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, 10000, 20000);
|
||||
events.ScheduleEvent(EVENT_WINGBUFFET, 30000);
|
||||
events.ScheduleEvent(EVENT_FLAMEBUFFET, 5000);
|
||||
}
|
||||
@@ -61,7 +56,7 @@ public:
|
||||
{
|
||||
case EVENT_SHADOWFLAME:
|
||||
DoCastVictim(SPELL_SHADOWFLAME);
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, 10000, 20000);
|
||||
break;
|
||||
case EVENT_WINGBUFFET:
|
||||
DoCastVictim(SPELL_WINGBUFFET);
|
||||
@@ -74,6 +69,9 @@ public:
|
||||
events.ScheduleEvent(EVENT_FLAMEBUFFET, 5000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
@@ -34,18 +34,13 @@ public:
|
||||
|
||||
struct boss_flamegorAI : public BossAI
|
||||
{
|
||||
boss_flamegorAI(Creature* creature) : BossAI(creature, BOSS_FLAMEGOR) { }
|
||||
boss_flamegorAI(Creature* creature) : BossAI(creature, DATA_FLAMEGOR) { }
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
void EnterCombat(Unit* victim) override
|
||||
{
|
||||
if (instance->GetBossState(BOSS_BROODLORD) != DONE)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
_EnterCombat();
|
||||
BossAI::EnterCombat(victim);
|
||||
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, 10000, 20000);
|
||||
events.ScheduleEvent(EVENT_WINGBUFFET, 30000);
|
||||
events.ScheduleEvent(EVENT_FRENZY, 10000);
|
||||
}
|
||||
@@ -66,7 +61,7 @@ public:
|
||||
{
|
||||
case EVENT_SHADOWFLAME:
|
||||
DoCastVictim(SPELL_SHADOWFLAME);
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_SHADOWFLAME, 10000, 20000);
|
||||
break;
|
||||
case EVENT_WINGBUFFET:
|
||||
DoCastVictim(SPELL_WINGBUFFET);
|
||||
@@ -77,9 +72,12 @@ public:
|
||||
case EVENT_FRENZY:
|
||||
Talk(EMOTE_FRENZY);
|
||||
DoCast(me, SPELL_FRENZY);
|
||||
events.ScheduleEvent(EVENT_FRENZY, urand(8000, 10000));
|
||||
events.ScheduleEvent(EVENT_FRENZY, 8000, 10000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "blackwing_lair.h"
|
||||
#include "GameObject.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "MotionMaster.h"
|
||||
#include "Player.h"
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
enum Events
|
||||
{
|
||||
@@ -154,28 +158,26 @@ public:
|
||||
|
||||
struct boss_victor_nefariusAI : public BossAI
|
||||
{
|
||||
boss_victor_nefariusAI(Creature* creature) : BossAI(creature, BOSS_NEFARIAN) { }
|
||||
boss_victor_nefariusAI(Creature* creature) : BossAI(creature, DATA_NEFARIAN)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
SpawnedAdds = 0;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
SpawnedAdds = 0;
|
||||
Initialize();
|
||||
|
||||
if (me->GetMapId() == 469)
|
||||
{
|
||||
// pussywizard:
|
||||
bool reset = true;
|
||||
if (instance)
|
||||
if (/*Creature* nefarian = */instance->instance->GetCreature(instance->GetData64(DATA_NEFARIAN)))
|
||||
reset = false;
|
||||
if (reset)
|
||||
if (!me->FindNearestCreature(NPC_NEFARIAN, 1000.0f, true))
|
||||
_Reset();
|
||||
|
||||
// pussywizard:
|
||||
if (!instance || instance->GetBossState(BOSS_NEFARIAN) == DONE || instance->GetBossState(BOSS_NEFARIAN) == IN_PROGRESS)
|
||||
me->SetVisible(false);
|
||||
else
|
||||
me->SetVisible(true);
|
||||
|
||||
me->SetVisible(true);
|
||||
me->SetPhaseMask(1, true);
|
||||
me->SetUInt32Value(UNIT_NPC_FLAGS, 1);
|
||||
me->setFaction(35);
|
||||
@@ -201,14 +203,16 @@ public:
|
||||
me->SetUInt32Value(UNIT_NPC_FLAGS, 0);
|
||||
DoCast(me, SPELL_NEFARIANS_BARRIER);
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
||||
AttackStart(target);
|
||||
events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(3000, 10000));
|
||||
events.ScheduleEvent(EVENT_FEAR, urand(10000, 20000));
|
||||
//events.ScheduleEvent(EVENT_MIND_CONTROL, urand(30000, 35000));
|
||||
events.ScheduleEvent(EVENT_MIND_CONTROL, urand(30000, 35000));
|
||||
events.ScheduleEvent(EVENT_SPAWN_ADD, 10000);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit*) override
|
||||
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
|
||||
|
||||
{
|
||||
if (summon->GetEntry() != NPC_NEFARIAN)
|
||||
{
|
||||
@@ -262,7 +266,7 @@ public:
|
||||
case EVENT_SUCCESS_1:
|
||||
if (Unit* player = me->SelectNearestPlayer(60.0f))
|
||||
{
|
||||
me->SetInFront(player);
|
||||
me->SetFacingToObject(player);
|
||||
Talk(SAY_SUCCESS);
|
||||
if (GameObject* portcullis1 = me->FindNearestGameObject(GO_PORTCULLIS_ACTIVE, 65.0f))
|
||||
portcullis1->SetGoState(GO_STATE_ACTIVE);
|
||||
@@ -322,7 +326,7 @@ public:
|
||||
events.ScheduleEvent(EVENT_MIND_CONTROL, urand(30000, 35000));
|
||||
break;
|
||||
case EVENT_SPAWN_ADD:
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
for (uint8 i=0; i<2; ++i)
|
||||
{
|
||||
uint32 CreatureID;
|
||||
if (urand(0, 2) == 0)
|
||||
@@ -339,26 +343,25 @@ public:
|
||||
{
|
||||
if (Creature* nefarian = me->SummonCreature(NPC_NEFARIAN, NefarianLoc[0]))
|
||||
{
|
||||
nefarian->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD);
|
||||
nefarian->SetCanFly(true);
|
||||
nefarian->SetHover(false);
|
||||
nefarian->setActive(true);
|
||||
nefarian->SetHomePosition(NefarianLoc[1]);
|
||||
nefarian->GetMotionMaster()->MoveCharge(NefarianLoc[1].GetPositionX(), NefarianLoc[1].GetPositionY(), NefarianLoc[1].GetPositionZ(), 15.0f);
|
||||
|
||||
nefarian->AI()->DoCastAOE(SPELL_SHADOWFLAME_INITIAL);
|
||||
nefarian->SetCanFly(true);
|
||||
nefarian->SetDisableGravity(true);
|
||||
nefarian->CastSpell(nullptr, SPELL_SHADOWFLAME_INITIAL);
|
||||
nefarian->GetMotionMaster()->MovePoint(1, NefarianLoc[1]);
|
||||
}
|
||||
events.CancelEvent(EVENT_MIND_CONTROL);
|
||||
events.CancelEvent(EVENT_FEAR);
|
||||
events.CancelEvent(EVENT_SHADOW_BOLT);
|
||||
me->SetVisible(false);
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SPAWN_ADD, 4000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,17 +372,17 @@ public:
|
||||
{
|
||||
// pussywizard:
|
||||
InstanceScript* instance = player->GetInstanceScript();
|
||||
if (!instance || instance->GetBossState(BOSS_NEFARIAN) == DONE)
|
||||
if (!instance || instance->GetBossState(DATA_NEFARIAN) == DONE)
|
||||
return;
|
||||
|
||||
CloseGossipMenuFor(player);
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
Talk(SAY_GAMESBEGIN_1);
|
||||
BeginEvent(player);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 SpawnedAdds;
|
||||
private:
|
||||
uint32 SpawnedAdds;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
@@ -395,15 +398,23 @@ public:
|
||||
|
||||
struct boss_nefarianAI : public BossAI
|
||||
{
|
||||
boss_nefarianAI(Creature* creature) : BossAI(creature, BOSS_NEFARIAN) { }
|
||||
boss_nefarianAI(Creature* creature) : BossAI(creature, DATA_NEFARIAN)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
void Initialize()
|
||||
{
|
||||
Phase3 = false;
|
||||
canDespawn = false;
|
||||
DespawnTimer = 30000;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
canDespawn = true;
|
||||
@@ -420,7 +431,7 @@ public:
|
||||
Talk(SAY_RANDOM);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/) override
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
@@ -428,37 +439,40 @@ public:
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (rand() % 5)
|
||||
if (rand32() % 5)
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY, victim);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 /*id*/) override
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->SetWalk(false);
|
||||
me->SetInCombatWithZone();
|
||||
if (me->GetVictim())
|
||||
AttackStart(me->GetVictim());
|
||||
if (id == 1)
|
||||
{
|
||||
DoZoneInCombat();
|
||||
if (me->GetVictim())
|
||||
AttackStart(me->GetVictim());
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (canDespawn && DespawnTimer <= diff)
|
||||
{
|
||||
instance->SetBossState(BOSS_NEFARIAN, FAIL);
|
||||
instance->SetBossState(DATA_NEFARIAN, FAIL);
|
||||
|
||||
std::list<Creature*> constructList;
|
||||
me->GetCreatureListWithEntryInGrid(constructList, NPC_BONE_CONSTRUCT, 500.0f);
|
||||
for (std::list<Creature*>::const_iterator itr = constructList.begin(); itr != constructList.end(); ++itr)
|
||||
(*itr)->DespawnOrUnsummon();
|
||||
}
|
||||
else DespawnTimer -= diff;
|
||||
else
|
||||
{
|
||||
DespawnTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
@@ -499,53 +513,56 @@ public:
|
||||
case EVENT_CLASSCALL:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
switch (target->getClass())
|
||||
{
|
||||
case CLASS_MAGE:
|
||||
Talk(SAY_MAGE);
|
||||
DoCast(me, SPELL_MAGE);
|
||||
break;
|
||||
case CLASS_WARRIOR:
|
||||
Talk(SAY_WARRIOR);
|
||||
DoCast(me, SPELL_WARRIOR);
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
Talk(SAY_DRUID);
|
||||
DoCast(target, SPELL_DRUID);
|
||||
break;
|
||||
case CLASS_PRIEST:
|
||||
Talk(SAY_PRIEST);
|
||||
DoCast(me, SPELL_PRIEST);
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
Talk(SAY_PALADIN);
|
||||
DoCast(me, SPELL_PALADIN);
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
Talk(SAY_SHAMAN);
|
||||
DoCast(me, SPELL_SHAMAN);
|
||||
break;
|
||||
case CLASS_WARLOCK:
|
||||
Talk(SAY_WARLOCK);
|
||||
DoCast(me, SPELL_WARLOCK);
|
||||
break;
|
||||
case CLASS_HUNTER:
|
||||
Talk(SAY_HUNTER);
|
||||
DoCast(me, SPELL_HUNTER);
|
||||
break;
|
||||
case CLASS_ROGUE:
|
||||
Talk(SAY_ROGUE);
|
||||
DoCast(me, SPELL_ROGUE);
|
||||
break;
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
Talk(SAY_DEATH_KNIGHT);
|
||||
DoCast(me, SPELL_DEATH_KNIGHT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
{
|
||||
case CLASS_MAGE:
|
||||
Talk(SAY_MAGE);
|
||||
DoCast(me, SPELL_MAGE);
|
||||
break;
|
||||
case CLASS_WARRIOR:
|
||||
Talk(SAY_WARRIOR);
|
||||
DoCast(me, SPELL_WARRIOR);
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
Talk(SAY_DRUID);
|
||||
DoCast(target, SPELL_DRUID);
|
||||
break;
|
||||
case CLASS_PRIEST:
|
||||
Talk(SAY_PRIEST);
|
||||
DoCast(me, SPELL_PRIEST);
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
Talk(SAY_PALADIN);
|
||||
DoCast(me, SPELL_PALADIN);
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
Talk(SAY_SHAMAN);
|
||||
DoCast(me, SPELL_SHAMAN);
|
||||
break;
|
||||
case CLASS_WARLOCK:
|
||||
Talk(SAY_WARLOCK);
|
||||
DoCast(me, SPELL_WARLOCK);
|
||||
break;
|
||||
case CLASS_HUNTER:
|
||||
Talk(SAY_HUNTER);
|
||||
DoCast(me, SPELL_HUNTER);
|
||||
break;
|
||||
case CLASS_ROGUE:
|
||||
Talk(SAY_ROGUE);
|
||||
DoCast(me, SPELL_ROGUE);
|
||||
break;
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
Talk(SAY_DEATH_KNIGHT);
|
||||
DoCast(me, SPELL_DEATH_KNIGHT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CLASSCALL, urand(30000, 35000));
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
// Phase3 begins when health below 20 pct
|
||||
@@ -557,7 +574,7 @@ public:
|
||||
if ((*itr) && !(*itr)->IsAlive())
|
||||
{
|
||||
(*itr)->Respawn();
|
||||
(*itr)->SetInCombatWithZone();
|
||||
DoZoneInCombat((*itr));
|
||||
(*itr)->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
(*itr)->SetReactState(REACT_AGGRESSIVE);
|
||||
(*itr)->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
@@ -24,7 +24,7 @@ enum Spells
|
||||
SPELL_CHANNEL = 45537,
|
||||
SPELL_EGG_DESTROY = 19873,
|
||||
|
||||
SPELL_CLEAVE = 22540,
|
||||
SPELL_CLEAVE = 19632,
|
||||
SPELL_WARSTOMP = 24375,
|
||||
SPELL_FIREBALLVOLLEY = 22425,
|
||||
SPELL_CONFLAGRATION = 23023
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
|
||||
struct boss_razorgoreAI : public BossAI
|
||||
{
|
||||
boss_razorgoreAI(Creature* creature) : BossAI(creature, BOSS_RAZORGORE) { }
|
||||
boss_razorgoreAI(Creature* creature) : BossAI(creature, DATA_RAZORGORE_THE_UNTAMED) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -90,6 +90,9 @@ public:
|
||||
{
|
||||
if (action == ACTION_PHASE_TWO)
|
||||
DoChangePhase();
|
||||
|
||||
if (action == TALK_EGG_BROKEN_RAND)
|
||||
Talk(urand(SAY_EGGS_BROKEN1, SAY_EGGS_BROKEN3));
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
@@ -176,7 +179,18 @@ public:
|
||||
void HandleOnHit()
|
||||
{
|
||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
||||
{
|
||||
instance->SetData(DATA_EGG_EVENT, SPECIAL);
|
||||
}
|
||||
if (GameObject* egg = GetCaster()->FindNearestGameObject(GO_EGG, 100))
|
||||
{
|
||||
if (!egg)
|
||||
return;
|
||||
|
||||
GetCaster()->GetAI()->DoAction(TALK_EGG_BROKEN_RAND);
|
||||
egg->SetLootState(GO_READY);
|
||||
egg->UseDoorOrButton(10000);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
|
||||
@@ -5,33 +5,41 @@
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "blackwing_lair.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
constexpr float aNefariusSpawnLoc[4] = { -7466.16f, -1040.80f, 412.053f, 2.14675f };
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_LINE1 = 0,
|
||||
SAY_LINE2 = 1,
|
||||
SAY_LINE3 = 2,
|
||||
SAY_HALFLIFE = 3,
|
||||
SAY_KILLTARGET = 4
|
||||
SAY_LINE1 = 0,
|
||||
SAY_LINE2 = 1,
|
||||
SAY_LINE3 = 2,
|
||||
SAY_HALFLIFE = 3,
|
||||
SAY_KILLTARGET = 4
|
||||
};
|
||||
|
||||
enum Gossip
|
||||
{
|
||||
GOSSIP_ID = 21334,
|
||||
GOSSIP_ID = 21334,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_ESSENCEOFTHERED = 23513,
|
||||
SPELL_FLAMEBREATH = 23461,
|
||||
SPELL_FIRENOVA = 23462,
|
||||
SPELL_TAILSWIPE = 15847,
|
||||
SPELL_BURNINGADRENALINE = 23620,
|
||||
SPELL_CLEAVE = 20684 //Chain cleave is most likely named something different and contains a dummy effect
|
||||
SPELL_ESSENCEOFTHERED = 23513,
|
||||
SPELL_FLAMEBREATH = 23461,
|
||||
SPELL_FIRENOVA = 23462,
|
||||
SPELL_TAILSWIPE = 15847,
|
||||
SPELL_BURNINGADRENALINE = 18173, //Cast this one. It's what 3.3.5 DBM expects.
|
||||
SPELL_BURNINGADRENALINE_EXPLOSION = 23478,
|
||||
SPELL_CLEAVE = 19983, //Chain cleave is most likely named something different and contains a dummy effect
|
||||
SPELL_NEFARIUS_CORRUPTION = 23642,
|
||||
SPELL_RED_LIGHTNING = 19484,
|
||||
};
|
||||
|
||||
enum Events
|
||||
@@ -40,13 +48,16 @@ enum Events
|
||||
EVENT_SPEECH_2 = 2,
|
||||
EVENT_SPEECH_3 = 3,
|
||||
EVENT_SPEECH_4 = 4,
|
||||
EVENT_ESSENCEOFTHERED = 5,
|
||||
EVENT_FLAMEBREATH = 6,
|
||||
EVENT_FIRENOVA = 7,
|
||||
EVENT_TAILSWIPE = 8,
|
||||
EVENT_CLEAVE = 9,
|
||||
EVENT_BURNINGADRENALINE_CASTER = 10,
|
||||
EVENT_BURNINGADRENALINE_TANK = 11
|
||||
EVENT_SPEECH_5 = 5,
|
||||
EVENT_SPEECH_6 = 6,
|
||||
EVENT_SPEECH_7 = 7,
|
||||
EVENT_ESSENCEOFTHERED = 8,
|
||||
EVENT_FLAMEBREATH = 9,
|
||||
EVENT_FIRENOVA = 10,
|
||||
EVENT_TAILSWIPE = 11,
|
||||
EVENT_CLEAVE = 12,
|
||||
EVENT_BURNINGADRENALINE_CASTER = 13,
|
||||
EVENT_BURNINGADRENALINE_TANK = 14,
|
||||
};
|
||||
|
||||
class boss_vaelastrasz : public CreatureScript
|
||||
@@ -56,11 +67,19 @@ public:
|
||||
|
||||
struct boss_vaelAI : public BossAI
|
||||
{
|
||||
boss_vaelAI(Creature* creature) : BossAI(creature, BOSS_VAELASTRAZ)
|
||||
boss_vaelAI(Creature* creature) : BossAI(creature, DATA_VAELASTRAZ_THE_CORRUPT)
|
||||
{
|
||||
creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
creature->setFaction(35);
|
||||
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
PlayerGUID = 0;
|
||||
HasYelled = false;
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
me->setFaction(35);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
@@ -68,14 +87,13 @@ public:
|
||||
_Reset();
|
||||
|
||||
me->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
PlayerGUID = 0;
|
||||
|
||||
HasYelled = false;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
void EnterCombat(Unit* victim) override
|
||||
{
|
||||
_EnterCombat();
|
||||
BossAI::EnterCombat(victim);
|
||||
|
||||
DoCast(me, SPELL_ESSENCEOFTHERED);
|
||||
me->SetHealth(me->CountPctFromMaxHealth(30));
|
||||
@@ -99,7 +117,7 @@ public:
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (rand() % 5)
|
||||
if (rand32() % 5)
|
||||
return;
|
||||
|
||||
Talk(SAY_KILLTARGET, victim);
|
||||
@@ -117,22 +135,42 @@ public:
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SPEECH_1:
|
||||
me->SummonCreature(NPC_VICTOR_NEFARIUS, aNefariusSpawnLoc[0], aNefariusSpawnLoc[1], aNefariusSpawnLoc[2], aNefariusSpawnLoc[3], TEMPSUMMON_TIMED_DESPAWN, 26000);
|
||||
events.ScheduleEvent(EVENT_SPEECH_2, 1000);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
case EVENT_SPEECH_2:
|
||||
if (Creature* nefarius = me->GetMap()->GetCreature(m_nefariusGuid))
|
||||
{
|
||||
nefarius->CastSpell(me, SPELL_NEFARIUS_CORRUPTION, TRIGGERED_CAST_DIRECTLY);
|
||||
nefarius->MonsterYell(SAY_NEFARIAN_VAEL_INTRO, LANG_UNIVERSAL, 0);
|
||||
nefarius->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SPEECH_3, 18000);
|
||||
break;
|
||||
case EVENT_SPEECH_3:
|
||||
if (Creature* nefarius = me->GetMap()->GetCreature(m_nefariusGuid))
|
||||
nefarius->CastSpell(me, SPELL_RED_LIGHTNING, TRIGGERED_NONE);
|
||||
events.ScheduleEvent(EVENT_SPEECH_4, 2000);
|
||||
break;
|
||||
case EVENT_SPEECH_4:
|
||||
Talk(SAY_LINE1);
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
|
||||
events.ScheduleEvent(EVENT_SPEECH_2, 12000);
|
||||
events.ScheduleEvent(EVENT_SPEECH_5, 12000);
|
||||
break;
|
||||
case EVENT_SPEECH_2:
|
||||
case EVENT_SPEECH_5:
|
||||
Talk(SAY_LINE2);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
|
||||
events.ScheduleEvent(EVENT_SPEECH_3, 12000);
|
||||
events.ScheduleEvent(EVENT_SPEECH_6, 12000);
|
||||
break;
|
||||
case EVENT_SPEECH_3:
|
||||
case EVENT_SPEECH_6:
|
||||
Talk(SAY_LINE3);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
|
||||
events.ScheduleEvent(EVENT_SPEECH_4, 16000);
|
||||
events.ScheduleEvent(EVENT_SPEECH_7, 17000);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
case EVENT_SPEECH_4:
|
||||
case EVENT_SPEECH_7:
|
||||
me->setFaction(103);
|
||||
if (PlayerGUID && ObjectAccessor::GetUnit(*me, PlayerGUID))
|
||||
AttackStart(ObjectAccessor::GetUnit(*me, PlayerGUID));;
|
||||
@@ -155,7 +193,7 @@ public:
|
||||
break;
|
||||
case EVENT_FLAMEBREATH:
|
||||
DoCastVictim(SPELL_FLAMEBREATH);
|
||||
events.ScheduleEvent(EVENT_FLAMEBREATH, urand(8000, 14000));
|
||||
events.ScheduleEvent(EVENT_FLAMEBREATH, 8000, 14000);
|
||||
break;
|
||||
case EVENT_FIRENOVA:
|
||||
DoCastVictim(SPELL_FIRENOVA);
|
||||
@@ -171,27 +209,25 @@ public:
|
||||
break;
|
||||
case EVENT_BURNINGADRENALINE_CASTER:
|
||||
{
|
||||
Unit* target = nullptr;
|
||||
|
||||
uint8 i = 0;
|
||||
while (i < 3) // max 3 tries to get a random target with power_mana
|
||||
//selects a random target that isn't the current victim and is a mana user (selects mana users) but not pets
|
||||
//it also ignores targets who have the aura. We don't want to place the debuff on the same target twice.
|
||||
if (Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 1, [&](Unit* u) { return u && !u->IsPet() && u->getPowerType() == POWER_MANA && !u->HasAura(SPELL_BURNINGADRENALINE); }))
|
||||
{
|
||||
++i;
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); // not aggro leader
|
||||
if (target && target->getPowerType() == POWER_MANA)
|
||||
i = 3;
|
||||
me->CastSpell(target, SPELL_BURNINGADRENALINE, true);
|
||||
}
|
||||
if (target) // cast on self (see below)
|
||||
target->CastSpell(target, SPELL_BURNINGADRENALINE, true);
|
||||
}
|
||||
//reschedule the event
|
||||
events.ScheduleEvent(EVENT_BURNINGADRENALINE_CASTER, 15000);
|
||||
break;
|
||||
case EVENT_BURNINGADRENALINE_TANK:
|
||||
// have the victim cast the spell on himself otherwise the third effect aura will be applied to Vael instead of the player
|
||||
me->GetVictim()->CastSpell(me->GetVictim(), SPELL_BURNINGADRENALINE, true);
|
||||
//Vael has to cast it himself; contrary to the previous commit's comment. Nothing happens otherwise.
|
||||
me->CastSpell(me->GetVictim(), SPELL_BURNINGADRENALINE, true);
|
||||
events.ScheduleEvent(EVENT_BURNINGADRENALINE_TANK, 45000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
// Yell if hp lower than 15%
|
||||
@@ -204,27 +240,70 @@ public:
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
{
|
||||
if (summoned->GetEntry() == NPC_VICTOR_NEFARIUS)
|
||||
{
|
||||
// Set not selectable, so players won't interact with it
|
||||
summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
m_nefariusGuid = summoned->GetGUID();
|
||||
}
|
||||
}
|
||||
|
||||
void sGossipSelect(Player* player, uint32 sender, uint32 action) override
|
||||
{
|
||||
if (sender == GOSSIP_ID && action == 0)
|
||||
{
|
||||
CloseGossipMenuFor(player);
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
BeginSpeech(player);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint64 PlayerGUID;
|
||||
bool HasYelled;
|
||||
private:
|
||||
uint64 PlayerGUID;
|
||||
uint64 m_nefariusGuid;
|
||||
bool HasYelled;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new boss_vaelAI(creature);
|
||||
return GetInstanceAI<boss_vaelAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// Need to define an aurascript for EVENT_BURNINGADRENALINE's death effect.
|
||||
// 18173 - Burning Adrenaline
|
||||
class spell_vael_burning_adrenaline : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_vael_burning_adrenaline() : SpellScriptLoader("spell_vael_burning_adrenaline") { }
|
||||
|
||||
class spell_vael_burning_adrenaline_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_vael_burning_adrenaline_AuraScript);
|
||||
|
||||
void OnAuraRemoveHandler(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
//The tooltip says the on death the AoE occurs. According to information: http://qaliaresponse.stage.lithium.com/t5/WoW-Mayhem/Surviving-Burning-Adrenaline-For-tanks/td-p/48609
|
||||
//Burning Adrenaline can be survived therefore Blizzard's implementation was an AoE bomb that went off if you were still alive and dealt
|
||||
//damage to the target. You don't have to die for it to go off. It can go off whether you live or die.
|
||||
GetTarget()->CastSpell(GetTarget(), SPELL_BURNINGADRENALINE_EXPLOSION, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_vael_burning_adrenaline_AuraScript::OnAuraRemoveHandler, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_vael_burning_adrenaline_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_vaelastrasz()
|
||||
{
|
||||
new boss_vaelastrasz();
|
||||
new spell_vael_burning_adrenaline();
|
||||
}
|
||||
|
||||
@@ -5,22 +5,29 @@
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "blackwing_lair.h"
|
||||
#include "GameObject.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Map.h"
|
||||
#include "MotionMaster.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
/*
|
||||
Blackwing Lair Encounter:
|
||||
1 - boss_razorgore.cpp
|
||||
2 - boss_vaelastrasz.cpp
|
||||
3 - boss_broodlord_lashlayer.cpp
|
||||
4 - boss_firemaw.cpp
|
||||
5 - boss_ebonroc.cpp
|
||||
6 - boss_flamegor.cpp
|
||||
7 - boss_chromaggus.cpp
|
||||
8 - boss_nefarian.cpp
|
||||
*/
|
||||
DoorData const doorData[] =
|
||||
{
|
||||
{ GO_PORTCULLIS_RAZORGORE, DATA_RAZORGORE_THE_UNTAMED, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, // ID 175946 || GUID 7230
|
||||
{ GO_PORTCULLIS_VAELASTRASZ, DATA_VAELASTRAZ_THE_CORRUPT, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, // ID 175185 || GUID 7229
|
||||
{ GO_PORTCULLIS_BROODLORD, DATA_BROODLORD_LASHLAYER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, // ID 179365 || GUID 75159
|
||||
{ GO_PORTCULLIS_THREEDRAGONS, DATA_FIREMAW, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, // ID 179115 || GUID 75165
|
||||
{ GO_PORTCULLIS_THREEDRAGONS, DATA_EBONROC, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, // ID 179115 || GUID 75165
|
||||
{ GO_PORTCULLIS_THREEDRAGONS, DATA_FLAMEGOR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, // ID 179115 || GUID 75165
|
||||
{ GO_PORTCULLIS_CHROMAGGUS, DATA_CHROMAGGUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, // ID 179116 || GUID 75161
|
||||
{ GO_PORTCULLIS_NEFARIAN, DATA_NEFARIAN, DOOR_TYPE_ROOM, BOUNDARY_NONE}, // ID 179117 || GUID 75164
|
||||
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} // END
|
||||
};
|
||||
|
||||
Position const SummonPosition[8] =
|
||||
{
|
||||
@@ -39,13 +46,16 @@ uint32 const Entry[5] = {12422, 12458, 12416, 12420, 12459};
|
||||
class instance_blackwing_lair : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_blackwing_lair() : InstanceMapScript(BRLScriptName, 469) { }
|
||||
instance_blackwing_lair() : InstanceMapScript(BWLScriptName, 469) { }
|
||||
|
||||
struct instance_blackwing_lair_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_blackwing_lair_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
//SetHeaders(DataHeader);
|
||||
SetBossNumber(EncounterCount);
|
||||
LoadDoorData(doorData);
|
||||
//LoadObjectData(creatureData, gameObjectData);
|
||||
}
|
||||
|
||||
void Initialize() override
|
||||
@@ -53,121 +63,110 @@ public:
|
||||
// Razorgore
|
||||
EggCount = 0;
|
||||
EggEvent = 0;
|
||||
RazorgoreTheUntamedGUID = 0;
|
||||
RazorgoreDoorGUID = 0;
|
||||
EggList.clear();
|
||||
// Vaelastrasz the Corrupt
|
||||
VaelastraszTheCorruptGUID = 0;
|
||||
VaelastraszDoorGUID = 0;
|
||||
// Broodlord Lashlayer
|
||||
BroodlordLashlayerGUID = 0;
|
||||
BroodlordDoorGUID = 0;
|
||||
// 3 Dragons
|
||||
FiremawGUID = 0;
|
||||
EbonrocGUID = 0;
|
||||
FlamegorGUID = 0;
|
||||
ChrommagusDoorGUID = 0;
|
||||
// Chormaggus
|
||||
ChromaggusGUID = 0;
|
||||
NefarianDoorGUID = 0;
|
||||
// Nefarian
|
||||
LordVictorNefariusGUID = 0;
|
||||
NefarianGUID = 0;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_RAZORGORE:
|
||||
RazorgoreTheUntamedGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_BLACKWING_DRAGON:
|
||||
case NPC_BLACKWING_TASKMASTER:
|
||||
case NPC_BLACKWING_LEGIONAIRE:
|
||||
case NPC_BLACKWING_WARLOCK:
|
||||
if (Creature* razor = instance->GetCreature(RazorgoreTheUntamedGUID))
|
||||
razor->AI()->JustSummoned(creature);
|
||||
if (Creature* razor = instance->GetCreature(DATA_RAZORGORE_THE_UNTAMED))
|
||||
if (CreatureAI* razorAI = razor->AI())
|
||||
razorAI->JustSummoned(creature);
|
||||
break;
|
||||
case NPC_VAELASTRAZ:
|
||||
VaelastraszTheCorruptGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_BROODLORD:
|
||||
BroodlordLashlayerGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_FIRENAW:
|
||||
FiremawGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_EBONROC:
|
||||
EbonrocGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_FLAMEGOR:
|
||||
FlamegorGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_CHROMAGGUS:
|
||||
ChromaggusGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VICTOR_NEFARIUS:
|
||||
LordVictorNefariusGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_NEFARIAN:
|
||||
NefarianGUID = creature->GetGUID();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
InstanceScript::OnGameObjectCreate(go);
|
||||
|
||||
switch(go->GetEntry())
|
||||
{
|
||||
case 177807: // Egg
|
||||
if (GetBossState(BOSS_FIREMAW) == DONE)
|
||||
case GO_BLACK_DRAGON_EGG:
|
||||
if (GetBossState(DATA_FIREMAW) == DONE)
|
||||
go->SetPhaseMask(2, true);
|
||||
else
|
||||
EggList.push_back(go->GetGUID());
|
||||
break;
|
||||
case 175946: // Door
|
||||
RazorgoreDoorGUID = go->GetGUID();
|
||||
HandleGameObject(0, GetBossState(BOSS_RAZORGORE) == DONE, go);
|
||||
|
||||
case GO_PORTCULLIS_RAZORGORE:
|
||||
case GO_PORTCULLIS_VAELASTRASZ:
|
||||
case GO_PORTCULLIS_BROODLORD:
|
||||
case GO_PORTCULLIS_THREEDRAGONS:
|
||||
case GO_PORTCULLIS_CHROMAGGUS:
|
||||
case GO_PORTCULLIS_NEFARIAN:
|
||||
AddDoor(go, true);
|
||||
break;
|
||||
case 175185: // Door
|
||||
VaelastraszDoorGUID = go->GetGUID();
|
||||
HandleGameObject(0, GetBossState(BOSS_VAELASTRAZ) == DONE, go);
|
||||
break;
|
||||
case 180424: // Door
|
||||
BroodlordDoorGUID = go->GetGUID();
|
||||
HandleGameObject(0, GetBossState(BOSS_BROODLORD) == DONE, go);
|
||||
break;
|
||||
case 185483: // Door
|
||||
ChrommagusDoorGUID = go->GetGUID();
|
||||
HandleGameObject(0, GetBossState(BOSS_FIREMAW) == DONE && GetBossState(BOSS_EBONROC) == DONE && GetBossState(BOSS_FLAMEGOR) == DONE, go);
|
||||
break;
|
||||
case 181125: // Door
|
||||
NefarianDoorGUID = go->GetGUID();
|
||||
HandleGameObject(0, GetBossState(BOSS_CHROMAGGUS) == DONE, go);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go) override
|
||||
{
|
||||
if (go->GetEntry() == 177807) // Egg
|
||||
InstanceScript::OnGameObjectRemove(go);
|
||||
|
||||
if (go->GetEntry() == GO_BLACK_DRAGON_EGG)
|
||||
EggList.remove(go->GetGUID());
|
||||
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_PORTCULLIS_RAZORGORE:
|
||||
case GO_PORTCULLIS_VAELASTRASZ:
|
||||
case GO_PORTCULLIS_BROODLORD:
|
||||
case GO_PORTCULLIS_THREEDRAGONS:
|
||||
case GO_PORTCULLIS_CHROMAGGUS:
|
||||
case GO_PORTCULLIS_NEFARIAN:
|
||||
AddDoor(go, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckRequiredBosses(uint32 bossId, Player const* /* player */) const override
|
||||
{
|
||||
switch (bossId)
|
||||
{
|
||||
case DATA_BROODLORD_LASHLAYER:
|
||||
if (GetBossState(DATA_VAELASTRAZ_THE_CORRUPT) != DONE)
|
||||
return false;
|
||||
break;
|
||||
case DATA_FIREMAW:
|
||||
case DATA_EBONROC:
|
||||
case DATA_FLAMEGOR:
|
||||
if (GetBossState(DATA_BROODLORD_LASHLAYER) != DONE)
|
||||
return false;
|
||||
break;
|
||||
case DATA_CHROMAGGUS:
|
||||
if (GetBossState(DATA_FIREMAW) != DONE
|
||||
|| GetBossState(DATA_EBONROC) != DONE
|
||||
|| GetBossState(DATA_FLAMEGOR) != DONE)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 type, EncounterState state) override
|
||||
{
|
||||
// pussywizard:
|
||||
if (GetBossState(type) == DONE && state != DONE) // prevent undoneing a boss xd
|
||||
return false;
|
||||
|
||||
if (!InstanceScript::SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case BOSS_RAZORGORE:
|
||||
HandleGameObject(RazorgoreDoorGUID, state == DONE);
|
||||
case DATA_RAZORGORE_THE_UNTAMED:
|
||||
if (state == DONE)
|
||||
{
|
||||
for (std::list<uint64>::const_iterator itr = EggList.begin(); itr != EggList.end(); ++itr)
|
||||
@@ -176,30 +175,16 @@ public:
|
||||
}
|
||||
SetData(DATA_EGG_EVENT, NOT_STARTED);
|
||||
break;
|
||||
case BOSS_VAELASTRAZ:
|
||||
HandleGameObject(VaelastraszDoorGUID, state == DONE);
|
||||
break;
|
||||
case BOSS_BROODLORD:
|
||||
HandleGameObject(BroodlordDoorGUID, state == DONE);
|
||||
break;
|
||||
case BOSS_FIREMAW:
|
||||
case BOSS_EBONROC:
|
||||
case BOSS_FLAMEGOR:
|
||||
HandleGameObject(ChrommagusDoorGUID, GetBossState(BOSS_FIREMAW) == DONE && GetBossState(BOSS_EBONROC) == DONE && GetBossState(BOSS_FLAMEGOR) == DONE);
|
||||
break;
|
||||
case BOSS_CHROMAGGUS:
|
||||
HandleGameObject(NefarianDoorGUID, state == DONE);
|
||||
break;
|
||||
case BOSS_NEFARIAN:
|
||||
case DATA_NEFARIAN:
|
||||
switch (state)
|
||||
{
|
||||
case NOT_STARTED:
|
||||
if (Creature* nefarian = instance->GetCreature(NefarianGUID))
|
||||
if (Creature* nefarian = instance->GetCreature(DATA_NEFARIAN))
|
||||
nefarian->DespawnOrUnsummon();
|
||||
break;
|
||||
case FAIL:
|
||||
_events.ScheduleEvent(EVENT_RESPAWN_NEFARIUS, 15 * IN_MILLISECONDS * MINUTE);
|
||||
SetBossState(BOSS_NEFARIAN, NOT_STARTED);
|
||||
_events.ScheduleEvent(EVENT_RESPAWN_NEFARIUS, 15 * 60 * IN_MILLISECONDS); //15min
|
||||
SetBossState(DATA_NEFARIAN, NOT_STARTED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -209,33 +194,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 id) const override
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case DATA_RAZORGORE_THE_UNTAMED:
|
||||
return RazorgoreTheUntamedGUID;
|
||||
case DATA_VAELASTRAZ_THE_CORRUPT:
|
||||
return VaelastraszTheCorruptGUID;
|
||||
case DATA_BROODLORD_LASHLAYER:
|
||||
return BroodlordLashlayerGUID;
|
||||
case DATA_FIRENAW:
|
||||
return FiremawGUID;
|
||||
case DATA_EBONROC:
|
||||
return EbonrocGUID;
|
||||
case DATA_FLAMEGOR:
|
||||
return FlamegorGUID;
|
||||
case DATA_CHROMAGGUS:
|
||||
return ChromaggusGUID;
|
||||
case DATA_LORD_VICTOR_NEFARIUS:
|
||||
return LordVictorNefariusGUID;
|
||||
case DATA_NEFARIAN:
|
||||
return NefarianGUID;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
if (type == DATA_EGG_EVENT)
|
||||
@@ -243,7 +201,7 @@ public:
|
||||
switch (data)
|
||||
{
|
||||
case IN_PROGRESS:
|
||||
_events.ScheduleEvent(EVENT_RAZOR_SPAWN, 45 * IN_MILLISECONDS);
|
||||
_events.ScheduleEvent(EVENT_RAZOR_SPAWN, 45000);
|
||||
EggEvent = data;
|
||||
EggCount = 0;
|
||||
break;
|
||||
@@ -255,13 +213,13 @@ public:
|
||||
case SPECIAL:
|
||||
if (++EggCount == 15)
|
||||
{
|
||||
if (Creature* razor = instance->GetCreature(RazorgoreTheUntamedGUID))
|
||||
if (Creature* razor = instance->GetCreature(DATA_RAZORGORE_THE_UNTAMED))
|
||||
{
|
||||
SetData(DATA_EGG_EVENT, DONE);
|
||||
razor->RemoveAurasDueToSpell(42013); // MindControl
|
||||
DoRemoveAurasDueToSpellOnPlayers(42013);
|
||||
}
|
||||
_events.ScheduleEvent(EVENT_RAZOR_PHASE_TWO, IN_MILLISECONDS);
|
||||
_events.ScheduleEvent(EVENT_RAZOR_PHASE_TWO, 1000);
|
||||
_events.CancelEvent(EVENT_RAZOR_SPAWN);
|
||||
}
|
||||
if (EggEvent == NOT_STARTED)
|
||||
@@ -274,8 +232,8 @@ public:
|
||||
void OnUnitDeath(Unit* unit) override
|
||||
{
|
||||
//! HACK, needed because of buggy CreatureAI after charm
|
||||
if (unit->GetEntry() == NPC_RAZORGORE && GetBossState(BOSS_RAZORGORE) != DONE)
|
||||
SetBossState(BOSS_RAZORGORE, DONE);
|
||||
if (unit->GetEntry() == NPC_RAZORGORE && GetBossState(DATA_RAZORGORE_THE_UNTAMED) != DONE)
|
||||
SetBossState(DATA_RAZORGORE_THE_UNTAMED, DONE);
|
||||
}
|
||||
|
||||
void Update(uint32 diff) override
|
||||
@@ -290,18 +248,18 @@ public:
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_RAZOR_SPAWN:
|
||||
for (uint8 i = urand(2, 5); i > 0 ; --i)
|
||||
if (Creature* summon = instance->SummonCreature(Entry[urand(0, 4)], SummonPosition[urand(0, 7)]))
|
||||
summon->SetInCombatWithZone();
|
||||
_events.ScheduleEvent(EVENT_RAZOR_SPAWN, urand(12, 17)*IN_MILLISECONDS);
|
||||
for (uint8 i = urand(2, 5); i > 0; --i)
|
||||
if (Creature* summon = instance->SummonCreature(Entry[urand(0, 4)], SummonPosition[urand(0, 7)]))
|
||||
summon->AI()->DoZoneInCombat();
|
||||
_events.ScheduleEvent(EVENT_RAZOR_SPAWN, 12000, 17000);
|
||||
break;
|
||||
case EVENT_RAZOR_PHASE_TWO:
|
||||
_events.CancelEvent(EVENT_RAZOR_SPAWN);
|
||||
if (Creature* razor = instance->GetCreature(RazorgoreTheUntamedGUID))
|
||||
if (Creature* razor = instance->GetCreature(DATA_RAZORGORE_THE_UNTAMED))
|
||||
razor->AI()->DoAction(ACTION_PHASE_TWO);
|
||||
break;
|
||||
case EVENT_RESPAWN_NEFARIUS:
|
||||
if (Creature* nefarius = instance->GetCreature(LordVictorNefariusGUID))
|
||||
if (Creature* nefarius = instance->GetCreature(DATA_LORD_VICTOR_NEFARIUS))
|
||||
{
|
||||
nefarius->SetPhaseMask(1, true);
|
||||
nefarius->setActive(true);
|
||||
@@ -316,43 +274,51 @@ public:
|
||||
protected:
|
||||
// Misc
|
||||
EventMap _events;
|
||||
|
||||
// Razorgore
|
||||
uint8 EggCount;
|
||||
uint32 EggEvent;
|
||||
uint64 RazorgoreTheUntamedGUID;
|
||||
uint64 RazorgoreDoorGUID;
|
||||
std::list<uint64> EggList;
|
||||
|
||||
// Vaelastrasz the Corrupt
|
||||
uint64 VaelastraszTheCorruptGUID;
|
||||
uint64 VaelastraszDoorGUID;
|
||||
|
||||
// Broodlord Lashlayer
|
||||
uint64 BroodlordLashlayerGUID;
|
||||
uint64 BroodlordDoorGUID;
|
||||
|
||||
// 3 Dragons
|
||||
uint64 FiremawGUID;
|
||||
uint64 EbonrocGUID;
|
||||
uint64 FlamegorGUID;
|
||||
uint64 ChrommagusDoorGUID;
|
||||
|
||||
// Chormaggus
|
||||
uint64 ChromaggusGUID;
|
||||
uint64 NefarianDoorGUID;
|
||||
|
||||
// Nefarian
|
||||
uint64 LordVictorNefariusGUID;
|
||||
uint64 NefarianGUID;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_blackwing_lair_InstanceMapScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
// 22539 - Shadowflame (used in Blackwing Lair)
|
||||
class spell_bwl_shadowflame : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_bwl_shadowflame() : SpellScriptLoader("spell_bwl_shadowflame") { }
|
||||
|
||||
class spell_bwl_shadowflame_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_bwl_shadowflame_SpellScript);
|
||||
|
||||
void HandleEffectScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
// If the victim of the spell does not have "Onyxia Scale Cloak" - add the Shadow Flame DoT (22682)
|
||||
if (Unit* victim = GetHitUnit())
|
||||
if(!victim->HasAura(22683))
|
||||
victim->AddAura(22682, victim);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_bwl_shadowflame_SpellScript::HandleEffectScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_bwl_shadowflame_SpellScript;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_blackwing_lair()
|
||||
{
|
||||
new instance_blackwing_lair();
|
||||
new spell_bwl_shadowflame();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user