diff options
author | Malcrom <malcromdev@gmail.com> | 2013-06-24 13:48:02 -0230 |
---|---|---|
committer | Malcrom <malcromdev@gmail.com> | 2013-06-24 13:48:02 -0230 |
commit | eb743614703917d2fda8d6e3730dfb8aa6f5176e (patch) | |
tree | 791e25b47bfaf11df1aa129485df83cc8fdb0521 /src | |
parent | 9726a5174e22097373581bb5e20fad49e45b9a61 (diff) |
Core/Scripting: Updated BWL Scripts. Thanks to gerripeach for the base.
Closes #4952 #9283
Diffstat (limited to 'src')
13 files changed, 1473 insertions, 1221 deletions
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index b240100f642..f5cb3aea4c0 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -127,17 +127,17 @@ void AddSC_boss_gyth(); void AddSC_boss_rend_blackhand(); void AddSC_instance_blackrock_spire(); void AddSC_boss_razorgore(); //Blackwing lair -void AddSC_boss_vael(); +void AddSC_boss_vaelastrasz(); void AddSC_boss_broodlord(); void AddSC_boss_firemaw(); void AddSC_boss_ebonroc(); void AddSC_boss_flamegor(); void AddSC_boss_chromaggus(); void AddSC_boss_nefarian(); -void AddSC_boss_victor_nefarius(); -void AddSC_boss_mr_smite(); +void AddSC_instance_blackwing_lair(); void AddSC_deadmines(); //Deadmines void AddSC_instance_deadmines(); +void AddSC_boss_mr_smite(); void AddSC_gnomeregan(); //Gnomeregan void AddSC_instance_gnomeregan(); void AddSC_boss_attumen(); //Karazhan @@ -769,16 +769,16 @@ void AddEasternKingdomsScripts() AddSC_boss_rend_blackhand(); AddSC_instance_blackrock_spire(); AddSC_boss_razorgore(); //Blackwing lair - AddSC_boss_vael(); + AddSC_boss_vaelastrasz(); AddSC_boss_broodlord(); AddSC_boss_firemaw(); AddSC_boss_ebonroc(); AddSC_boss_flamegor(); AddSC_boss_chromaggus(); AddSC_boss_nefarian(); - AddSC_boss_victor_nefarius(); - AddSC_boss_mr_smite(); + AddSC_instance_blackwing_lair(); AddSC_deadmines(); //Deadmines + AddSC_boss_mr_smite(); AddSC_instance_deadmines(); AddSC_gnomeregan(); //Gnomeregan AddSC_instance_gnomeregan(); diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/blackwing_lair.h b/src/server/scripts/EasternKingdoms/BlackwingLair/blackwing_lair.h new file mode 100644 index 00000000000..acdbf0cd483 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/blackwing_lair.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#ifndef DEF_BLACKWING_LAIR_H +#define DEF_BLACKWING_LAIR_H + +uint32 const EncounterCount = 8; + +#define BRLScriptName "instance_blackwing_lair" + +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 +}; + +enum CreatureIds +{ + NPC_RAZORGORE = 12435, + NPC_BLACKWING_DRAGON = 12422, + NPC_BLACKWING_TASKMASTER = 12458, + NPC_BLACKWING_LEGIONAIRE = 12416, + NPC_BLACKWING_WARLOCK = 12459, + NPC_VAELASTRAZ = 13020, + NPC_BROODLORD = 12017, + NPC_FIRENAW = 11983, + NPC_EBONROC = 14601, + NPC_FLAMEGOR = 11981, + NPC_CHROMAGGUS = 14020, + NPC_VICTOR_NEFARIUS = 10162, + NPC_NEFARIAN = 11583 +}; + +enum BWLData64 +{ + 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 +}; + +enum BWLEvents +{ + EVENT_RAZOR_SPAWN = 1, + EVENT_RAZOR_PHASE_TWO = 2, + EVENT_RESPAWN_NEFARIUS = 3 +}; + +enum BWLMisc +{ + // Razorgore Egg Event + ACTION_PHASE_TWO = 1, + DATA_EGG_EVENT +}; + +#endif
\ No newline at end of file diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp index 5c05d365e00..d4a9d81fdb0 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp @@ -16,36 +16,31 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Broodlord_Lashlayer -SD%Complete: 100 -SDComment: -SDCategory: Blackwing Lair -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "blackwing_lair.h" enum Say { SAY_AGGRO = 0, - SAY_LEASH = 1, + SAY_LEASH = 1 }; -enum Events +enum Spells { - EVENT_CLEAVE = 1, - EVENT_MORTAL_STRIKE = 2, - EVENT_BLAST_WAVE = 3, - EVENT_KNOCK_BACK = 4, + SPELL_CLEAVE = 26350, + SPELL_BLASTWAVE = 23331, + SPELL_MORTALSTRIKE = 24573, + SPELL_KNOCKBACK = 25778 }; -enum Spells +enum Events { - SPELL_CLEAVE = 26350, - SPELL_BLAST_WAVE = 23331, - SPELL_MORTAL_STRIKE = 24573, - SPELL_KNOCK_BACK = 25778 + EVENT_CLEAVE = 1, + EVENT_BLASTWAVE = 2, + EVENT_MORTALSTRIKE = 3, + EVENT_KNOCKBACK = 4, + EVENT_CHECK = 5 }; class boss_broodlord : public CreatureScript @@ -53,28 +48,26 @@ class boss_broodlord : public CreatureScript public: boss_broodlord() : CreatureScript("boss_broodlord") { } - CreatureAI* GetAI(Creature* creature) const - { - return new boss_broodlordAI (creature); - } - - struct boss_broodlordAI : public ScriptedAI + struct boss_broodlordAI : public BossAI { - boss_broodlordAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() - { - // These timers are probably wrong - events.ScheduleEvent(EVENT_CLEAVE, 8000); - events.ScheduleEvent(EVENT_BLAST_WAVE, 12000); - events.ScheduleEvent(EVENT_MORTAL_STRIKE, 20000); - events.ScheduleEvent(EVENT_KNOCK_BACK, 30000); - } + boss_broodlordAI(Creature* creature) : BossAI(creature, BOSS_BROODLORD) { } void EnterCombat(Unit* /*who*/) { + if (instance->GetBossState(BOSS_VAELASTRAZ) != DONE) + { + EnterEvadeMode(); + return; + } + + _EnterCombat(); Talk(SAY_AGGRO); - DoZoneInCombat(); + + events.ScheduleEvent(EVENT_CLEAVE, 8000); + events.ScheduleEvent(EVENT_BLASTWAVE, 12000); + events.ScheduleEvent(EVENT_MORTALSTRIKE, 20000); + events.ScheduleEvent(EVENT_KNOCKBACK, 30000); + events.ScheduleEvent(EVENT_CHECK, 1000); } void UpdateAI(uint32 diff) @@ -82,11 +75,7 @@ public: if (!UpdateVictim()) return; - if (EnterEvadeIfOutOfCombatArea(diff)) - Talk(SAY_LEASH); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { @@ -94,40 +83,41 @@ public: { case EVENT_CLEAVE: DoCastVictim(SPELL_CLEAVE); - events.ScheduleEvent(EVENT_CLEAVE, 8000); + events.ScheduleEvent(EVENT_CLEAVE, 7000); + break; + case EVENT_BLASTWAVE: + DoCastVictim(SPELL_BLASTWAVE); + events.ScheduleEvent(EVENT_BLASTWAVE, urand(8000, 16000)); break; - case EVENT_MORTAL_STRIKE: - DoCastVictim(SPELL_MORTAL_STRIKE); - events.ScheduleEvent(EVENT_MORTAL_STRIKE, 20000); + case EVENT_MORTALSTRIKE: + DoCastVictim(SPELL_MORTALSTRIKE); + events.ScheduleEvent(EVENT_MORTALSTRIKE, urand(25000, 35000)); break; - case EVENT_BLAST_WAVE: - DoCastVictim(SPELL_BLAST_WAVE); - events.ScheduleEvent(EVENT_BLAST_WAVE, 12000); + case EVENT_KNOCKBACK: + DoCastVictim(SPELL_KNOCKBACK); + if (DoGetThreat(me->GetVictim())) + DoModifyThreatPercent(me->GetVictim(), -50); + events.ScheduleEvent(EVENT_KNOCKBACK, urand(15000, 30000)); break; - case EVENT_KNOCK_BACK: - if (Unit* target = me->GetVictim()) + case EVENT_CHECK: + if (me->GetDistance(me->GetHomePosition()) > 150.0f) { - DoCast(target, SPELL_BLAST_WAVE); - // Drop 50% of threat - if (DoGetThreat(target)) - DoModifyThreatPercent(target, -50); + Talk(SAY_LEASH); + EnterEvadeMode(); } - events.ScheduleEvent(EVENT_KNOCK_BACK, 30000); - break; - default: + events.ScheduleEvent(EVENT_CHECK, 1000); break; } } - if (EnterEvadeIfOutOfCombatArea(diff)) - Talk(SAY_LEASH); - DoMeleeAttackIfReady(); } - - private: - EventMap events; /// @todo: change BWL to instance script and bosses to BossAI }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_broodlordAI (creature); + } }; void AddSC_boss_broodlord() diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp index 9698d8c147f..ff3a5291dcd 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp @@ -16,15 +16,9 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Chromaggus -SD%Complete: 95 -SDComment: Chromatic Mutation disabled due to lack of core support -SDCategory: Blackwing Lair -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "blackwing_lair.h" enum Emotes { @@ -34,22 +28,22 @@ enum Emotes enum Spells { - //These spells are actually called elemental shield - //What they do is decrease all damage by 75% then they increase - //One school of damage by 1100% + // These spells are actually called elemental shield + // What they do is decrease all damage by 75% then they increase + // One school of damage by 1100% SPELL_FIRE_VULNERABILITY = 22277, SPELL_FROST_VULNERABILITY = 22278, SPELL_SHADOW_VULNERABILITY = 22279, SPELL_NATURE_VULNERABILITY = 22280, SPELL_ARCANE_VULNERABILITY = 22281, - //Other spells + // Other spells SPELL_INCINERATE = 23308, //Incinerate 23308, 23309 SPELL_TIMELAPSE = 23310, //Time lapse 23310, 23311(old threat mod that was removed in 2.01) SPELL_CORROSIVEACID = 23313, //Corrosive Acid 23313, 23314 SPELL_IGNITEFLESH = 23315, //Ignite Flesh 23315, 23316 SPELL_FROSTBURN = 23187, //Frost burn 23187, 23189 - //Brood Affliction 23173 - Scripted Spell that cycles through all targets within 100 yards and has a chance to cast one of the afflictions on them - //Since Scripted spells arn't coded I'll just write a function that does the same thing + // Brood Affliction 23173 - Scripted Spell that cycles through all targets within 100 yards and has a chance to cast one of the afflictions on them + // Since Scripted spells arn't coded I'll just write a function that does the same thing SPELL_BROODAF_BLUE = 23153, //Blue affliction 23153 SPELL_BROODAF_BLACK = 23154, //Black affliction 23154 SPELL_BROODAF_RED = 23155, //Red affliction 23155 (23168 on death) @@ -60,27 +54,31 @@ enum Spells SPELL_ENRAGE = 28747 }; +enum Events +{ + EVENT_SHIMMER = 1, + EVENT_BREATH_1 = 2, + EVENT_BREATH_2 = 3, + EVENT_AFFLICTION = 4, + EVENT_FRENZY = 5 +}; + class boss_chromaggus : public CreatureScript { public: boss_chromaggus() : CreatureScript("boss_chromaggus") { } - CreatureAI* GetAI(Creature* creature) const + struct boss_chromaggusAI : public BossAI { - return new boss_chromaggusAI (creature); - } - - struct boss_chromaggusAI : public ScriptedAI - { - boss_chromaggusAI(Creature* creature) : ScriptedAI(creature) + boss_chromaggusAI(Creature* creature) : BossAI(creature, BOSS_CHROMAGGUS) { - //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 - //TL TL would be stupid + // 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 + // TL TL would be stupid switch (urand(0, 19)) { - //B1 - Incin + // B1 - Incin case 0: Breath1_Spell = SPELL_INCINERATE; Breath2_Spell = SPELL_TIMELAPSE; @@ -98,7 +96,7 @@ public: Breath2_Spell = SPELL_FROSTBURN; break; - //B1 - TL + // B1 - TL case 4: Breath1_Spell = SPELL_TIMELAPSE; Breath2_Spell = SPELL_INCINERATE; @@ -174,117 +172,97 @@ public: EnterEvadeMode(); } - uint32 Breath1_Spell; - uint32 Breath2_Spell; - uint32 CurrentVurln_Spell; - - uint32 Shimmer_Timer; - uint32 Breath1_Timer; - uint32 Breath2_Timer; - uint32 Affliction_Timer; - uint32 Frenzy_Timer; - bool Enraged; - void Reset() { - CurrentVurln_Spell = 0; //We use this to store our last vulnerabilty spell so we can remove it later - - Shimmer_Timer = 0; //Time till we change vurlnerabilites - Breath1_Timer = 30000; //First breath is 30 seconds - Breath2_Timer = 60000; //Second is 1 minute so that we can alternate - Affliction_Timer = 10000; //This is special - 5 seconds means that we cast this on 1 player every 5 sconds - Frenzy_Timer = 15000; + _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*/) {} + void EnterCombat(Unit* /*who*/) + { + if (instance && instance->GetBossState(BOSS_FLAMEGOR) != DONE) + { + EnterEvadeMode(); + return; + } + _EnterCombat(); + + events.ScheduleEvent(EVENT_SHIMMER, 0); + events.ScheduleEvent(EVENT_BREATH_1, 30000); + events.ScheduleEvent(EVENT_BREATH_2, 60000); + events.ScheduleEvent(EVENT_AFFLICTION, 10000); + events.ScheduleEvent(EVENT_FRENZY, 15000); + } void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; - //Shimmer_Timer Timer - if (Shimmer_Timer <= diff) - { - //Remove old vulnerabilty spell - if (CurrentVurln_Spell) - me->RemoveAurasDueToSpell(CurrentVurln_Spell); - - //Cast new random vulnerabilty on self - uint32 spell = RAND(SPELL_FIRE_VULNERABILITY, SPELL_FROST_VULNERABILITY, - SPELL_SHADOW_VULNERABILITY, SPELL_NATURE_VULNERABILITY, SPELL_ARCANE_VULNERABILITY); - - DoCast(me, spell); - CurrentVurln_Spell = spell; + events.Update(diff); - Talk(EMOTE_SHIMMER); - Shimmer_Timer = 45000; - } else Shimmer_Timer -= diff; - - //Breath1_Timer - if (Breath1_Timer <= diff) - { - DoCastVictim(Breath1_Spell); - Breath1_Timer = 60000; - } else Breath1_Timer -= diff; - - //Breath2_Timer - if (Breath2_Timer <= diff) - { - DoCastVictim(Breath2_Spell); - Breath2_Timer = 60000; - } else Breath2_Timer -= diff; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - //Affliction_Timer - if (Affliction_Timer <= diff) + while (uint32 eventId = events.ExecuteEvent()) { - ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) + switch (eventId) { - if ((*i) && (*i)->GetSource()) - { - if (Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid())) + case EVENT_SHIMMER: { - //Cast affliction - DoCast(unit, RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK, - SPELL_BROODAF_RED, SPELL_BROODAF_BRONZE, SPELL_BROODAF_GREEN), true); - - //Chromatic mutation if target is effected by all afflictions - if (unit->HasAura(SPELL_BROODAF_BLUE) - && unit->HasAura(SPELL_BROODAF_BLACK) - && unit->HasAura(SPELL_BROODAF_RED) - && unit->HasAura(SPELL_BROODAF_BRONZE) - && unit->HasAura(SPELL_BROODAF_GREEN)) + // Remove old vulnerabilty spell + if (CurrentVurln_Spell) + me->RemoveAurasDueToSpell(CurrentVurln_Spell); + + // Cast new random vulnerabilty on self + uint32 spell = RAND(SPELL_FIRE_VULNERABILITY, SPELL_FROST_VULNERABILITY, SPELL_SHADOW_VULNERABILITY, SPELL_NATURE_VULNERABILITY, SPELL_ARCANE_VULNERABILITY); + DoCast(me, spell); + CurrentVurln_Spell = spell; + Talk(EMOTE_SHIMMER); + events.ScheduleEvent(EVENT_SHIMMER, 45000); + break; + } + case EVENT_BREATH_1: + DoCastVictim(Breath1_Spell); + events.ScheduleEvent(EVENT_BREATH_1, 60000); + break; + case EVENT_BREATH_2: + DoCastVictim(Breath2_Spell); + events.ScheduleEvent(EVENT_BREATH_2, 60000); + break; + case EVENT_AFFLICTION: + { + Map::PlayerList const &players = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { - //target->RemoveAllAuras(); - //DoCast(target, SPELL_CHROMATIC_MUT_1); - - //Chromatic mutation is causing issues - //Assuming it is caused by a lack of core support for Charm - //So instead we instant kill our target - - //WORKAROUND - if (unit->GetTypeId() == TYPEID_PLAYER) - unit->CastSpell(unit, 5, false); + if (Player* player = itr->GetSource()->ToPlayer()) + { + 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) && + 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); + } + + } } } - } + events.ScheduleEvent(EVENT_AFFLICTION, 10000); + break; + case EVENT_FRENZY: + DoCast(me, SPELL_FRENZY); + events.ScheduleEvent(EVENT_FRENZY, urand(10000, 15000)); + break; } + } - Affliction_Timer = 10000; - } else Affliction_Timer -= diff; - - //Frenzy_Timer - if (Frenzy_Timer <= diff) - { - DoCast(me, SPELL_FRENZY); - Talk(EMOTE_FRENZY); - Frenzy_Timer = urand(10000, 15000); - } else Frenzy_Timer -= diff; - - //Enrage if not already enraged and below 20% + // Enrage if not already enraged and below 20% if (!Enraged && HealthBelowPct(20)) { DoCast(me, SPELL_ENRAGE); @@ -293,10 +271,21 @@ public: DoMeleeAttackIfReady(); } + + private: + uint32 Breath1_Spell; + uint32 Breath2_Spell; + uint32 CurrentVurln_Spell; + bool Enraged; }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_chromaggusAI (creature); + } }; void AddSC_boss_chromaggus() { new boss_chromaggus(); -} +}
\ No newline at end of file diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp index 04b99c76105..7d21825851a 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp @@ -16,54 +16,45 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Ebonroc -SD%Complete: 50 -SDComment: Shadow of Ebonroc needs core support -SDCategory: Blackwing Lair -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "blackwing_lair.h" + +enum Spells +{ + SPELL_SHADOWFLAME = 22539, + SPELL_WINGBUFFET = 23339, + SPELL_SHADOWOFEBONROC = 23340 +}; -#define SPELL_SHADOWFLAME 22539 -#define SPELL_WINGBUFFET 23339 -#define SPELL_SHADOWOFEBONROC 23340 -#define SPELL_HEAL 41386 //The Heal spell of his Shadow -#define SPELL_THRASH 3391 +enum Events +{ + EVENT_SHADOWFLAME = 1, + EVENT_WINGBUFFET = 2, + EVENT_SHADOWOFEBONROC = 3 +}; class boss_ebonroc : public CreatureScript { public: boss_ebonroc() : CreatureScript("boss_ebonroc") { } - CreatureAI* GetAI(Creature* creature) const - { - return new boss_ebonrocAI (creature); - } - - struct boss_ebonrocAI : public ScriptedAI + struct boss_ebonrocAI : public BossAI { - boss_ebonrocAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 ShadowFlame_Timer; - uint32 WingBuffet_Timer; - uint32 ShadowOfEbonroc_Timer; - uint32 Heal_Timer; - uint32 Thrash_Timer; - - void Reset() - { - ShadowFlame_Timer = 15000; //These times are probably wrong - WingBuffet_Timer = 30000; - ShadowOfEbonroc_Timer = 45000; - Heal_Timer = 1000; - Thrash_Timer = 10000; - } + boss_ebonrocAI(Creature* creature) : BossAI(creature, BOSS_EBONROC) { } void EnterCombat(Unit* /*who*/) { - DoZoneInCombat(); + if (instance && instance->GetBossState(BOSS_BROODLORD) != DONE) + { + EnterEvadeMode(); + return; + } + _EnterCombat(); + + events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000)); + events.ScheduleEvent(EVENT_WINGBUFFET, 30000); + events.ScheduleEvent(EVENT_SHADOWOFEBONROC, urand(8000, 10000)); } void UpdateAI(uint32 diff) @@ -71,46 +62,38 @@ public: if (!UpdateVictim()) return; - //Shadowflame Timer - if (ShadowFlame_Timer <= diff) - { - DoCastVictim(SPELL_SHADOWFLAME); - ShadowFlame_Timer = urand(12000, 15000); - } else ShadowFlame_Timer -= diff; - - //Thrash Timer - if (Thrash_Timer <= diff) - { - DoCastVictim(SPELL_THRASH); - Thrash_Timer = urand(10000, 15000); - } else Thrash_Timer -= diff; - - //Wing Buffet Timer - if (WingBuffet_Timer <= diff) - { - DoCastVictim(SPELL_WINGBUFFET); - WingBuffet_Timer = 25000; - } else WingBuffet_Timer -= diff; + events.Update(diff); - //Shadow of Ebonroc Timer - if (ShadowOfEbonroc_Timer <= diff) - { - DoCastVictim(SPELL_SHADOWOFEBONROC); - ShadowOfEbonroc_Timer = urand(25000, 350000); - } else ShadowOfEbonroc_Timer -= diff; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - if (me->GetVictim() && me->GetVictim()->HasAura(SPELL_SHADOWOFEBONROC)) + while (uint32 eventId = events.ExecuteEvent()) { - if (Heal_Timer <= diff) + switch (eventId) { - DoCast(me, SPELL_HEAL); - Heal_Timer = urand(1000, 3000); - } else Heal_Timer -= diff; + case EVENT_SHADOWFLAME: + DoCastVictim(SPELL_SHADOWFLAME); + events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000)); + break; + case EVENT_WINGBUFFET: + DoCastVictim(SPELL_WINGBUFFET); + events.ScheduleEvent(EVENT_WINGBUFFET, 30000); + break; + case EVENT_SHADOWOFEBONROC: + DoCastVictim(SPELL_SHADOWOFEBONROC); + events.ScheduleEvent(EVENT_SHADOWOFEBONROC, urand(8000, 10000)); + break; + } } DoMeleeAttackIfReady(); } }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_ebonrocAI (creature); + } }; void AddSC_boss_ebonroc() diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp index 60564ea1acb..b32db2be450 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp @@ -16,48 +16,45 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Firemaw -SD%Complete: 100 -SDComment: -SDCategory: Blackwing Lair -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "blackwing_lair.h" -#define SPELL_SHADOWFLAME 22539 -#define SPELL_WINGBUFFET 23339 -#define SPELL_FLAMEBUFFET 23341 +enum Spells +{ + SPELL_SHADOWFLAME = 22539, + SPELL_WINGBUFFET = 23339, + SPELL_FLAMEBUFFET = 23341 +}; + +enum Events +{ + EVENT_SHADOWFLAME = 1, + EVENT_WINGBUFFET = 2, + EVENT_FLAMEBUFFET = 3 +}; class boss_firemaw : public CreatureScript { public: boss_firemaw() : CreatureScript("boss_firemaw") { } - CreatureAI* GetAI(Creature* creature) const - { - return new boss_firemawAI (creature); - } - - struct boss_firemawAI : public ScriptedAI + struct boss_firemawAI : public BossAI { - boss_firemawAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 ShadowFlame_Timer; - uint32 WingBuffet_Timer; - uint32 FlameBuffet_Timer; - - void Reset() - { - ShadowFlame_Timer = 30000; //These times are probably wrong - WingBuffet_Timer = 24000; - FlameBuffet_Timer = 5000; - } + boss_firemawAI(Creature* creature) : BossAI(creature, BOSS_FIREMAW) { } void EnterCombat(Unit* /*who*/) { - DoZoneInCombat(); + if (instance && instance->GetBossState(BOSS_BROODLORD) != DONE) + { + EnterEvadeMode(); + return; + } + _EnterCombat(); + + events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000)); + events.ScheduleEvent(EVENT_WINGBUFFET, 30000); + events.ScheduleEvent(EVENT_FLAMEBUFFET, 5000); } void UpdateAI(uint32 diff) @@ -65,35 +62,40 @@ public: if (!UpdateVictim()) return; - //ShadowFlame_Timer - if (ShadowFlame_Timer <= diff) - { - DoCastVictim(SPELL_SHADOWFLAME); - ShadowFlame_Timer = urand(15000, 18000); - } else ShadowFlame_Timer -= diff; + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - //WingBuffet_Timer - if (WingBuffet_Timer <= diff) + while (uint32 eventId = events.ExecuteEvent()) { - if (Unit* target = me->GetVictim()) + switch (eventId) { - DoCast(target, SPELL_WINGBUFFET); - if (DoGetThreat(target)) - DoModifyThreatPercent(target, -75); + case EVENT_SHADOWFLAME: + DoCastVictim(SPELL_SHADOWFLAME); + events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000)); + break; + case EVENT_WINGBUFFET: + DoCastVictim(SPELL_WINGBUFFET); + if (DoGetThreat(me->GetVictim())) + DoModifyThreatPercent(me->GetVictim(), -75); + events.ScheduleEvent(EVENT_WINGBUFFET, 30000); + break; + case EVENT_FLAMEBUFFET: + DoCastVictim(SPELL_FLAMEBUFFET); + events.ScheduleEvent(EVENT_FLAMEBUFFET, 5000); + break; } - WingBuffet_Timer = 25000; - } else WingBuffet_Timer -= diff; - - //FlameBuffet_Timer - if (FlameBuffet_Timer <= diff) - { - DoCastVictim(SPELL_FLAMEBUFFET); - FlameBuffet_Timer = 5000; - } else FlameBuffet_Timer -= diff; + } DoMeleeAttackIfReady(); } }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_firemawAI (creature); + } }; void AddSC_boss_firemaw() diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp index 5035c1e9c89..f5a3cd3e45f 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp @@ -16,15 +16,9 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Flamegor -SD%Complete: 100 -SDComment: -SDCategory: Blackwing Lair -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "blackwing_lair.h" enum Emotes { @@ -35,7 +29,14 @@ enum Spells { SPELL_SHADOWFLAME = 22539, SPELL_WINGBUFFET = 23339, - SPELL_FRENZY = 23342 //This spell periodically triggers fire nova + SPELL_FRENZY = 23342 //This spell periodically triggers fire nova +}; + +enum Events +{ + EVENT_SHADOWFLAME = 1, + EVENT_WINGBUFFET = 2, + EVENT_FRENZY = 3 }; class boss_flamegor : public CreatureScript @@ -43,29 +44,22 @@ class boss_flamegor : public CreatureScript public: boss_flamegor() : CreatureScript("boss_flamegor") { } - CreatureAI* GetAI(Creature* creature) const + struct boss_flamegorAI : public BossAI { - return new boss_flamegorAI (creature); - } - - struct boss_flamegorAI : public ScriptedAI - { - boss_flamegorAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 ShadowFlame_Timer; - uint32 WingBuffet_Timer; - uint32 Frenzy_Timer; - - void Reset() - { - ShadowFlame_Timer = 21000; //These times are probably wrong - WingBuffet_Timer = 35000; - Frenzy_Timer = 10000; - } + boss_flamegorAI(Creature* creature) : BossAI(creature, BOSS_FLAMEGOR) { } void EnterCombat(Unit* /*who*/) { - DoZoneInCombat(); + if (instance && instance->GetBossState(BOSS_BROODLORD) != DONE) + { + EnterEvadeMode(); + return; + } + _EnterCombat(); + + events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000)); + events.ScheduleEvent(EVENT_WINGBUFFET, 30000); + events.ScheduleEvent(EVENT_FRENZY, 10000); } void UpdateAI(uint32 diff) @@ -73,36 +67,41 @@ public: if (!UpdateVictim()) return; - //ShadowFlame_Timer - if (ShadowFlame_Timer <= diff) - { - DoCastVictim(SPELL_SHADOWFLAME); - ShadowFlame_Timer = urand(15000, 22000); - } else ShadowFlame_Timer -= diff; + events.Update(diff); - //WingBuffet_Timer - if (WingBuffet_Timer <= diff) + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) { - if (Unit* target = me->GetVictim()) + switch (eventId) { - DoCast(target, SPELL_WINGBUFFET); - if (DoGetThreat(target)) - DoModifyThreatPercent(target, -75); + case EVENT_SHADOWFLAME: + DoCastVictim(SPELL_SHADOWFLAME); + events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000)); + break; + case EVENT_WINGBUFFET: + DoCastVictim(SPELL_WINGBUFFET); + if (DoGetThreat(me->GetVictim())) + DoModifyThreatPercent(me->GetVictim(), -75); + events.ScheduleEvent(EVENT_WINGBUFFET, 30000); + break; + case EVENT_FRENZY: + Talk(EMOTE_FRENZY); + DoCast(me, SPELL_FRENZY); + events.ScheduleEvent(EVENT_FRENZY, urand(8000, 10000)); + break; } - WingBuffet_Timer = 25000; - } else WingBuffet_Timer -= diff; - - //Frenzy_Timer - if (Frenzy_Timer <= diff) - { - Talk(EMOTE_FRENZY); - DoCast(me, SPELL_FRENZY); - Frenzy_Timer = urand(8000, 10000); - } else Frenzy_Timer -= diff; + } DoMeleeAttackIfReady(); } }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_flamegorAI (creature); + } }; void AddSC_boss_flamegor() diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_nefarian.cpp index 77da6e54df0..1348bc7051f 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_nefarian.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_nefarian.cpp @@ -16,225 +16,545 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Nefarian -SD%Complete: 80 -SDComment: Some issues with class calls effecting more than one class -SDCategory: Blackwing Lair -EndScriptData */ - #include "ScriptMgr.h" +#include "ScriptedGossip.h" #include "ScriptedCreature.h" +#include "blackwing_lair.h" +#include "Player.h" + +enum Events +{ + // Victor Nefarius + EVENT_SPAWN_ADD = 1, + EVENT_SHADOW_BOLT = 2, + EVENT_FEAR = 3, + EVENT_MIND_CONTROL = 4, + + // Victor Nefarius UBRS Events + EVENT_PLAYER_CHECK = 5, + EVENT_GYTH_REND_1 = 6, + EVENT_GYTH_REND_2 = 7, + EVENT_GYTH_REND_3 = 8, + EVENT_GYTH_REND_4 = 9, + EVENT_GYTH_REND_5 = 10, + + // Nefarian + EVENT_SHADOWFLAME = 11, + EVENT_VEILOFSHADOW = 12, + EVENT_CLEAVE = 13, + EVENT_TAILLASH = 14, + EVENT_CLASSCALL = 15 +}; + +enum Says +{ + // Victor Nefarius + // UBRS text + SAY_GYTH_REND_1 = 0, + SAY_GYTH_REND_2 = 1, + SAY_GYTH_REND_3 = 2, + SAY_GYTH_REND_4 = 3, + SAY_GYTH_REND_5 = 4, + SAY_GYTH_REND_6 = 5, + SAY_GYTH_REND_7 = 6, + SAY_GYTH_REND_8 = 7, + SAY_GYTH_REND_9 = 8, + SAY_GYTH_REND_10 = 9, + // BWL text + SAY_GAMESBEGIN_1 = 10, + SAY_GAMESBEGIN_2 = 11, + // SAY_VAEL_INTRO = 12, Not used - when he corrupts Vaelastrasz + + // Nefarian + SAY_RANDOM = 0, + SAY_RAISE_SKELETONS = 1, + SAY_SLAY = 2, + SAY_DEATH = 3, + + SAY_MAGE = 4, + SAY_WARRIOR = 5, + SAY_DRUID = 6, + SAY_PRIEST = 7, + SAY_PALADIN = 8, + SAY_SHAMAN = 9, + SAY_WARLOCK = 10, + SAY_HUNTER = 11, + SAY_ROGUE = 12, + SAY_DEATH_KNIGHT = 13 +}; + +enum Gossip +{ + GOSSIP_ID = 21332, +}; -enum Say +enum Creatures { - SAY_RANDOM = 0, - SAY_RAISE_SKELETONS = 1, - SAY_SLAY = 2, - SAY_DEATH = 3, - - SAY_MAGE = 4, - SAY_WARRIOR = 5, - SAY_DRUID = 6, - SAY_PRIEST = 7, - SAY_PALADIN = 8, - SAY_SHAMAN = 9, - SAY_WARLOCK = 10, - SAY_HUNTER = 11, - SAY_ROGUE = 12, + // UBRS + NPC_REND_BLACKHAND = 10429, + // BWL + NPC_BRONZE_DRAKANOID = 14263, + NPC_BLUE_DRAKANOID = 14261, + NPC_RED_DRAKANOID = 14264, + NPC_GREEN_DRAKANOID = 14262, + NPC_BLACK_DRAKANOID = 14265, + NPC_CHROMATIC_DRAKANOID = 14302, + NPC_BONE_CONSTRUCT = 14605 }; enum Spells { - SPELL_SHADOWFLAME_INITIAL = 22972, + // Victor Nefarius + // UBRS Spells + SPELL_CHROMATIC_CHAOS = 16337, // Self Cast hits 10339 + SPELL_VAELASTRASZZ_SPAWN = 16354, // Self Cast Depawn one sec after + // BWL Spells + SPELL_SHADOWBOLT = 22677, + SPELL_SHADOWBOLT_VOLLEY = 22665, + SPELL_SHADOW_COMMAND = 22667, + SPELL_FEAR = 22678, + + SPELL_NEFARIANS_BARRIER = 22663, + + // Nefarian + SPELL_SHADOWFLAME_INITIAL = 22992, SPELL_SHADOWFLAME = 22539, SPELL_BELLOWINGROAR = 22686, SPELL_VEILOFSHADOW = 7068, SPELL_CLEAVE = 20691, SPELL_TAILLASH = 23364, - SPELL_BONECONTRUST = 23363, //23362, 23361 - SPELL_MAGE = 23410, //wild magic - SPELL_WARRIOR = 23397, //beserk + SPELL_MAGE = 23410, // wild magic + SPELL_WARRIOR = 23397, // beserk SPELL_DRUID = 23398, // cat form SPELL_PRIEST = 23401, // corrupted healing - SPELL_PALADIN = 23418, //syphon blessing - SPELL_SHAMAN = 23425, //totems - SPELL_WARLOCK = 23427, //infernals - SPELL_HUNTER = 23436, //bow broke - SPELL_ROGUE = 23414 //Paralise + SPELL_PALADIN = 23418, // syphon blessing + SPELL_SHAMAN = 23425, // totems + SPELL_WARLOCK = 23427, // infernals + SPELL_HUNTER = 23436, // bow broke + SPELL_ROGUE = 23414, // Paralise + SPELL_DEATH_KNIGHT = 49576 // Death Grip }; -class boss_nefarian : public CreatureScript +Position const DrakeSpawnLoc[2] = // drakonid +{ + {-7591.151855f, -1204.051880f, 476.800476f, 3.0f}, + {-7514.598633f, -1150.448853f, 476.796570f, 3.0f} +}; + +Position const NefarianLoc[2] = +{ + {-7449.763672f, -1387.816040f, 526.783691f, 3.0f}, // nefarian spawn + {-7535.456543f, -1279.562500f, 476.798706f, 3.0f} // nefarian move +}; + +uint32 const Entry[5] = {NPC_BRONZE_DRAKANOID, NPC_BLUE_DRAKANOID, NPC_RED_DRAKANOID, NPC_GREEN_DRAKANOID, NPC_BLACK_DRAKANOID}; + +class boss_victor_nefarius : public CreatureScript { public: - boss_nefarian() : CreatureScript("boss_nefarian") { } + boss_victor_nefarius() : CreatureScript("boss_victor_nefarius") { } - CreatureAI* GetAI(Creature* creature) const + struct boss_victor_nefariusAI : public BossAI { - return new boss_nefarianAI (creature); - } + boss_victor_nefariusAI(Creature* creature) : BossAI(creature, BOSS_NEFARIAN) { } - struct boss_nefarianAI : public ScriptedAI - { - boss_nefarianAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 ShadowFlame_Timer; - uint32 BellowingRoar_Timer; - uint32 VeilOfShadow_Timer; - uint32 Cleave_Timer; - uint32 TailLash_Timer; - uint32 ClassCall_Timer; - bool Phase3; + void Reset() + { + if(me->GetMapId() == 229) + { + events.ScheduleEvent(EVENT_PLAYER_CHECK, 5000); + } - uint32 DespawnTimer; + if(me->GetMapId() == 469) + { + if (!me->FindNearestCreature(NPC_NEFARIAN, 1000.0f, true)) + _Reset(); + SpawnedAdds = 0; + + me->SetVisible(true); + me->SetPhaseMask(1, true); + me->SetUInt32Value(UNIT_NPC_FLAGS, 1); + me->setFaction(35); + me->SetStandState(UNIT_STAND_STATE_SIT_HIGH_CHAIR); + me->RemoveAura(SPELL_NEFARIANS_BARRIER); + } + } - void Reset() + void JustReachedHome() { - ShadowFlame_Timer = 12000; // These times are probably wrong - BellowingRoar_Timer = 30000; - VeilOfShadow_Timer = 15000; - Cleave_Timer = 7000; - TailLash_Timer = 10000; - ClassCall_Timer = 35000; // 35-40 seconds - Phase3 = false; + Reset(); + } - DespawnTimer = 5000; + void BeginEvent(Player* target) + { + _EnterCombat(); + + Talk(SAY_GAMESBEGIN_2); + + me->setFaction(103); + me->SetUInt32Value(UNIT_NPC_FLAGS, 0); + DoCast(me, SPELL_NEFARIANS_BARRIER); + me->SetStandState(UNIT_STAND_STATE_STAND); + 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_SPAWN_ADD, 10000); } - void KilledUnit(Unit* Victim) + void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) { - if (rand()%5) + if (summon->GetEntry() != NPC_NEFARIAN) + { + summon->UpdateEntry(NPC_BONE_CONSTRUCT); + summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + summon->SetReactState(REACT_PASSIVE); + summon->SetStandState(UNIT_STAND_STATE_DEAD); + } + } + + void JustSummoned(Creature* /*summon*/) {} + + void UpdateAI(uint32 diff) + { + events.Update(diff); + + if(me->GetMapId() == 229) // UBRS EVENTS + { + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_PLAYER_CHECK: + if (Unit* player = SelectTarget(SELECT_TARGET_NEAREST, 0, 30.0f, false)) + events.ScheduleEvent(EVENT_GYTH_REND_1, 1000); + else + events.ScheduleEvent(EVENT_PLAYER_CHECK, 5000); + break; + case EVENT_GYTH_REND_1: + Talk(SAY_GYTH_REND_1); + events.ScheduleEvent(EVENT_GYTH_REND_2, 4000); + break; + case EVENT_GYTH_REND_2: + if (Unit* player = SelectTarget(SELECT_TARGET_NEAREST, 0, 30.0f, false)) + me->SetInFront(player); + me->SendMovementFlagUpdate(); + me->HandleEmoteCommand(EMOTE_ONESHOT_POINT); + events.ScheduleEvent(EVENT_GYTH_REND_3, 4000); + break; + case EVENT_GYTH_REND_3: + Talk(SAY_GYTH_REND_2); + events.ScheduleEvent(EVENT_GYTH_REND_4, 4000); + break; + case EVENT_GYTH_REND_4: + if (Creature* rend = me->FindNearestCreature(NPC_REND_BLACKHAND, 5.0f, true)) + me->SetInFront(rend); + me->SendMovementFlagUpdate(); + events.ScheduleEvent(EVENT_GYTH_REND_5, 4000); + break; + case EVENT_GYTH_REND_5: + me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); + events.ScheduleEvent(EVENT_GYTH_REND_5, 4000); + default: + break; + } + } + } + + if(me->GetMapId() != 469) return; - Talk(SAY_SLAY, Victim->GetGUID()); + // Only do this if we haven't spawned nefarian yet + if (UpdateVictim() && SpawnedAdds <= 42) + { + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SHADOW_BOLT: + switch (urand(0, 1)) + { + case 0: + DoCastVictim(SPELL_SHADOWBOLT_VOLLEY); + break; + case 1: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true)) + DoCast(target, SPELL_SHADOWBOLT); + break; + } + DoResetThreat(); + events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(3000, 10000)); + break; + case EVENT_FEAR: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true)) + DoCast(target, SPELL_FEAR); + events.ScheduleEvent(EVENT_FEAR, urand(10000, 20000)); + break; + case EVENT_MIND_CONTROL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true)) + DoCast(target, SPELL_SHADOW_COMMAND); + events.ScheduleEvent(EVENT_MIND_CONTROL, urand(30000, 35000)); + break; + case EVENT_SPAWN_ADD: + for (uint8 i=0; i<2; ++i) + { + uint32 CreatureID; + if (urand(0, 2) == 0) + CreatureID = NPC_CHROMATIC_DRAKANOID; + else + CreatureID = Entry[urand(0, 4)]; + if (Creature* dragon = me->SummonCreature(CreatureID, DrakeSpawnLoc[i])) + { + dragon->setFaction(103); + dragon->AI()->AttackStart(me->GetVictim()); + } + + if (++SpawnedAdds >= 42) + { + if (Creature* nefarian = me->SummonCreature(NPC_NEFARIAN, NefarianLoc[0])) + { + nefarian->setActive(true); + nefarian->SetCanFly(true); + nefarian->SetDisableGravity(true); + nefarian->AI()->DoCastAOE(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); + return; + } + } + events.ScheduleEvent(EVENT_SPAWN_ADD, 4000); + break; + } + } + } } - void JustDied(Unit* /*killer*/) + void sGossipSelect(Player* player, uint32 sender, uint32 action) { - Talk(SAY_DEATH); + if (sender == GOSSIP_ID && action == 0) + { + player->CLOSE_GOSSIP_MENU(); + Talk(SAY_GAMESBEGIN_1); + BeginEvent(player); + } + } + + private: + uint32 SpawnedAdds; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_victor_nefariusAI (creature); + } +}; + +class boss_nefarian : public CreatureScript +{ +public: + boss_nefarian() : CreatureScript("boss_nefarian") { } + + struct boss_nefarianAI : public BossAI + { + boss_nefarianAI(Creature* creature) : BossAI(creature, BOSS_NEFARIAN) { } + + void Reset() + { + Phase3 = false; + canDespawn = false; + DespawnTimer = 30000; + } + + void JustReachedHome() + { + canDespawn = true; } void EnterCombat(Unit* who) { + events.ScheduleEvent(EVENT_SHADOWFLAME, 12000); + events.ScheduleEvent(EVENT_FEAR, urand(25000, 35000)); + events.ScheduleEvent(EVENT_VEILOFSHADOW, urand(25000, 35000)); + events.ScheduleEvent(EVENT_CLEAVE, 7000); + //events.ScheduleEvent(EVENT_TAILLASH, 10000); + events.ScheduleEvent(EVENT_CLASSCALL, urand(30000, 35000)); Talk(SAY_RANDOM); + } - DoCast(who, SPELL_SHADOWFLAME_INITIAL); - DoZoneInCombat(); + void JustDied(Unit* /*Killer*/) + { + _JustDied(); + Talk(SAY_DEATH); } - void UpdateAI(uint32 diff) + void KilledUnit(Unit* victim) { - if (DespawnTimer <= diff) - { - if (!UpdateVictim()) - me->DespawnOrUnsummon(); - DespawnTimer = 5000; - } else DespawnTimer -= diff; + if (rand()%5) + return; - if (!UpdateVictim()) + Talk(SAY_SLAY, victim->GetGUID()); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) return; - //ShadowFlame_Timer - if (ShadowFlame_Timer <= diff) + if (id == 1) { - DoCastVictim(SPELL_SHADOWFLAME); - ShadowFlame_Timer = 12000; - } else ShadowFlame_Timer -= diff; + me->SetInCombatWithZone(); + if (me->GetVictim()) + AttackStart(me->GetVictim()); + } + } - //BellowingRoar_Timer - if (BellowingRoar_Timer <= diff) + void UpdateAI(uint32 diff) + { + if (canDespawn && DespawnTimer <= diff) { - DoCastVictim(SPELL_BELLOWINGROAR); - BellowingRoar_Timer = 30000; - } else BellowingRoar_Timer -= diff; + if (instance) + instance->SetBossState(BOSS_NEFARIAN, FAIL); - //VeilOfShadow_Timer - if (VeilOfShadow_Timer <= diff) - { - DoCastVictim(SPELL_VEILOFSHADOW); - VeilOfShadow_Timer = 15000; - } else VeilOfShadow_Timer -= diff; + 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(); - //Cleave_Timer - if (Cleave_Timer <= diff) - { - DoCastVictim(SPELL_CLEAVE); - Cleave_Timer = 7000; - } else Cleave_Timer -= diff; + } else DespawnTimer -= diff; - //TailLash_Timer - if (TailLash_Timer <= diff) - { - //Cast NYI since we need a better check for behind target - //DoCastVictim(SPELL_TAILLASH); + if (!UpdateVictim()) + return; - TailLash_Timer = 10000; - } else TailLash_Timer -= diff; + if (canDespawn) + canDespawn = false; - //ClassCall_Timer - if (ClassCall_Timer <= diff) - { - //Cast a random class call - //On official it is based on what classes are currently on the hostil list - //but we can't do that yet so just randomly call one + events.Update(diff); - switch (urand(0, 8)) + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - case 0: - Talk(SAY_MAGE); - DoCast(me, SPELL_MAGE); + case EVENT_SHADOWFLAME: + DoCastVictim(SPELL_SHADOWFLAME); + events.ScheduleEvent(EVENT_SHADOWFLAME, 12000); break; - case 1: - Talk(SAY_WARRIOR); - DoCast(me, SPELL_WARRIOR); + case EVENT_FEAR: + DoCastVictim(SPELL_BELLOWINGROAR); + events.ScheduleEvent(EVENT_FEAR, urand(25000, 35000)); break; - case 2: - Talk(SAY_DRUID); - DoCast(me, SPELL_DRUID); + case EVENT_VEILOFSHADOW: + DoCastVictim(SPELL_VEILOFSHADOW); + events.ScheduleEvent(EVENT_VEILOFSHADOW, urand(25000, 35000)); break; - case 3: - Talk(SAY_PRIEST); - DoCast(me, SPELL_PRIEST); + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + events.ScheduleEvent(EVENT_CLEAVE, 7000); break; - case 4: - Talk(SAY_PALADIN); - DoCast(me, SPELL_PALADIN); + case EVENT_TAILLASH: + // Cast NYI since we need a better check for behind target + DoCastVictim(SPELL_TAILLASH); + events.ScheduleEvent(EVENT_TAILLASH, 10000); break; - case 5: - Talk(SAY_SHAMAN); - DoCast(me, SPELL_SHAMAN); - break; - case 6: - Talk(SAY_WARLOCK); - DoCast(me, SPELL_WARLOCK); - break; - case 7: - Talk(SAY_HUNTER); - DoCast(me, SPELL_HUNTER); - break; - case 8: - Talk(SAY_ROGUE); - DoCast(me, SPELL_ROGUE); + 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; + } + events.ScheduleEvent(EVENT_CLASSCALL, urand(30000, 35000)); break; } + } - ClassCall_Timer = 35000 + (rand() % 5000); - } else ClassCall_Timer -= diff; - - //Phase3 begins when we are below X health + // Phase3 begins when health below 20 pct if (!Phase3 && HealthBelowPct(20)) { + 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) + if ((*itr) && !(*itr)->IsAlive()) + { + (*itr)->Respawn(); + (*itr)->SetInCombatWithZone(); + (*itr)->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + (*itr)->SetReactState(REACT_AGGRESSIVE); + (*itr)->SetStandState(UNIT_STAND_STATE_STAND); + } + Phase3 = true; Talk(SAY_RAISE_SKELETONS); } DoMeleeAttackIfReady(); } + + private: + bool canDespawn; + uint32 DespawnTimer; + bool Phase3; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_nefarianAI (creature); + } }; void AddSC_boss_nefarian() { + new boss_victor_nefarius(); new boss_nefarian(); } diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_razorgore.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_razorgore.cpp index 369e97ca99a..fa21b06d578 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_razorgore.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_razorgore.cpp @@ -16,17 +16,11 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Razorgore -SD%Complete: 50 -SDComment: Needs additional review. Phase 1 NYI (Grethok the Controller) -SDCategory: Blackwing Lair -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" - -//Razorgore Phase 2 Script +#include "SpellScript.h" +#include "blackwing_lair.h" +#include "Player.h" enum Say { @@ -38,47 +32,84 @@ enum Say enum Spells { + SPELL_MINDCONTROL = 42013, + SPELL_CHANNEL = 45537, + SPELL_EGG_DESTROY = 19873, + SPELL_CLEAVE = 22540, SPELL_WARSTOMP = 24375, SPELL_FIREBALLVOLLEY = 22425, SPELL_CONFLAGRATION = 23023 }; +enum Summons +{ + NPC_ELITE_DRACHKIN = 12422, + NPC_ELITE_WARRIOR = 12458, + NPC_WARRIOR = 12416, + NPC_MAGE = 12402, + NPC_WARLOCK = 12459, + + GO_EGG = 177807 +}; + +enum EVENTS +{ + EVENT_CLEAVE = 1, + EVENT_STOMP = 2, + EVENT_FIREBALL = 3, + EVENT_CONFLAGRATION = 4 +}; + class boss_razorgore : public CreatureScript { public: boss_razorgore() : CreatureScript("boss_razorgore") { } - CreatureAI* GetAI(Creature* creature) const + struct boss_razorgoreAI : public BossAI { - return new boss_razorgoreAI (creature); - } + boss_razorgoreAI(Creature* creature) : BossAI(creature, BOSS_RAZORGORE) { } - struct boss_razorgoreAI : public ScriptedAI - { - boss_razorgoreAI(Creature* creature) : ScriptedAI(creature) {} + void Reset() + { + _Reset(); - uint32 Cleave_Timer; - uint32 WarStomp_Timer; - uint32 FireballVolley_Timer; - uint32 Conflagration_Timer; + secondPhase = false; + if (instance) + instance->SetData(DATA_EGG_EVENT, NOT_STARTED); + } - void Reset() + void JustDied(Unit* /*killer*/) { - Cleave_Timer = 15000; //These times are probably wrong - WarStomp_Timer = 35000; - FireballVolley_Timer = 7000; - Conflagration_Timer = 12000; + _JustDied(); + Talk(SAY_DEATH); + + if (instance) + instance->SetData(DATA_EGG_EVENT, NOT_STARTED); } - void EnterCombat(Unit* /*who*/) + void DoChangePhase() { - DoZoneInCombat(); + events.ScheduleEvent(EVENT_CLEAVE, 15000); + events.ScheduleEvent(EVENT_STOMP, 35000); + events.ScheduleEvent(EVENT_FIREBALL, 7000); + events.ScheduleEvent(EVENT_CONFLAGRATION, 12000); + + secondPhase = true; + me->RemoveAllAuras(); + me->SetHealth(me->GetMaxHealth()); } - void JustDied(Unit* /*killer*/) + void DoAction(int32 action) { - Talk(SAY_DEATH); + if (action == ACTION_PHASE_TWO) + DoChangePhase(); + } + + void DamageTaken(Unit* /*who*/, uint32& damage) + { + if (!secondPhase) + damage = 0; } void UpdateAI(uint32 diff) @@ -86,50 +117,97 @@ public: if (!UpdateVictim()) return; - //Cleave_Timer - if (Cleave_Timer <= diff) - { - DoCastVictim(SPELL_CLEAVE); - Cleave_Timer = urand(7000, 10000); - } else Cleave_Timer -= diff; + events.Update(diff); - //WarStomp_Timer - if (WarStomp_Timer <= diff) - { - DoCastVictim(SPELL_WARSTOMP); - WarStomp_Timer = urand(15000, 25000); - } else WarStomp_Timer -= diff; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - //FireballVolley_Timer - if (FireballVolley_Timer <= diff) + while (uint32 eventId = events.ExecuteEvent()) { - DoCastVictim(SPELL_FIREBALLVOLLEY); - FireballVolley_Timer = urand(12000, 15000); - } else FireballVolley_Timer -= diff; + switch (eventId) + { + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + events.ScheduleEvent(EVENT_CLEAVE, urand(7000, 10000)); + break; + case EVENT_STOMP: + DoCastVictim(SPELL_WARSTOMP); + events.ScheduleEvent(EVENT_STOMP, urand(15000, 25000)); + break; + case EVENT_FIREBALL: + DoCastVictim(SPELL_FIREBALLVOLLEY); + events.ScheduleEvent(EVENT_FIREBALL, urand(12000, 15000)); + break; + case EVENT_CONFLAGRATION: + DoCastVictim(SPELL_CONFLAGRATION); + if (me->GetVictim() && me->GetVictim()->HasAura(SPELL_CONFLAGRATION)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true)) + me->TauntApply(target); + events.ScheduleEvent(EVENT_CONFLAGRATION, 30000); + break; + } + } + DoMeleeAttackIfReady(); + } - //Conflagration_Timer - if (Conflagration_Timer <= diff) - { - DoCastVictim(SPELL_CONFLAGRATION); - //We will remove this threat reduction and add an aura check. + private: + bool secondPhase; + }; - //if (DoGetThreat(me->GetVictim())) - //DoModifyThreatPercent(me->GetVictim(), -50); + CreatureAI* GetAI(Creature* creature) const + { + return new boss_razorgoreAI (creature); + } +}; - Conflagration_Timer = 12000; - } else Conflagration_Timer -= diff; +class go_orb_of_domination : public GameObjectScript +{ +public: + go_orb_of_domination() : GameObjectScript("go_orb_of_domination") { } - // Aura Check. If the gamer is affected by confliguration we attack a random gamer. - if (me->GetVictim() && me->GetVictim()->HasAura(SPELL_CONFLAGRATION)) - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true)) - me->TauntApply(target); + bool OnGossipHello(Player* player, GameObject* go) + { + if (InstanceScript* instance = go->GetInstanceScript()) + if (instance->GetData(DATA_EGG_EVENT) != DONE) + if (Creature* razor = Unit::GetCreature(*go, instance ? instance->GetData64(DATA_RAZORGORE_THE_UNTAMED) : 0)) + { + razor->Attack(player, true); + player->CastSpell(razor, SPELL_MINDCONTROL); + } + return true; + } +}; - DoMeleeAttackIfReady(); +class spell_egg_event : public SpellScriptLoader +{ + public: + spell_egg_event() : SpellScriptLoader("spell_egg_event") { } + + class spell_egg_eventSpellScript : public SpellScript + { + PrepareSpellScript(spell_egg_eventSpellScript); + + void HandleOnHit() + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + instance->SetData(DATA_EGG_EVENT, SPECIAL); + } + + void Register() + { + OnHit += SpellHitFn(spell_egg_eventSpellScript::HandleOnHit); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_egg_eventSpellScript(); } - }; }; void AddSC_boss_razorgore() { new boss_razorgore(); + new go_orb_of_domination(); + new spell_egg_event(); } diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp index dfa0f42f4a6..e7626c92ec0 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp @@ -16,37 +16,49 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Vaelastrasz -SD%Complete: 75 -SDComment: Burning Adrenaline not correctly implemented in core -SDCategory: Blackwing Lair -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "blackwing_lair.h" #include "ScriptedGossip.h" #include "Player.h" 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 }; -#define GOSSIP_ITEM "Start Event <Needs Gossip Text>" +enum Gossip +{ + 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 = 23620, + SPELL_CLEAVE = 20684 //Chain cleave is most likely named something different and contains a dummy effect +}; + +enum Events +{ + EVENT_SPEECH_1 = 1, + 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 }; class boss_vaelastrasz : public CreatureScript @@ -54,89 +66,47 @@ class boss_vaelastrasz : public CreatureScript public: boss_vaelastrasz() : CreatureScript("boss_vaelastrasz") { } - void SendDefaultMenu(Player* player, Creature* creature, uint32 action) + struct boss_vaelAI : public BossAI { - if (action == GOSSIP_ACTION_INFO_DEF + 1) //Fight time - { - player->CLOSE_GOSSIP_MENU(); - CAST_AI(boss_vaelastrasz::boss_vaelAI, creature->AI())->BeginSpeech(player); - } - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (sender == GOSSIP_SENDER_MAIN) - SendDefaultMenu(player, creature, action); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(907, creature->GetGUID()); - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_vaelAI (creature); - } - - struct boss_vaelAI : public ScriptedAI - { - boss_vaelAI(Creature* creature) : ScriptedAI(creature) + boss_vaelAI(Creature* creature) : BossAI(creature, BOSS_VAELASTRAZ) { creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); creature->setFaction(35); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } - uint64 PlayerGUID; - uint32 SpeechTimer; - uint32 SpeechNum; - uint32 Cleave_Timer; - uint32 FlameBreath_Timer; - uint32 FireNova_Timer; - uint32 BurningAdrenalineCaster_Timer; - uint32 BurningAdrenalineTank_Timer; - uint32 TailSwipe_Timer; - bool HasYelled; - bool DoingSpeech; - void Reset() { + _Reset(); + + me->SetStandState(UNIT_STAND_STATE_DEAD); PlayerGUID = 0; - SpeechTimer = 0; - SpeechNum = 0; - Cleave_Timer = 8000; // These times are probably wrong - FlameBreath_Timer = 11000; - BurningAdrenalineCaster_Timer = 15000; - BurningAdrenalineTank_Timer = 45000; - FireNova_Timer = 5000; - TailSwipe_Timer = 20000; + HasYelled = false; - DoingSpeech = false; } - void BeginSpeech(Unit* target) + void EnterCombat(Unit* /*who*/) { - //Stand up and begin speach - PlayerGUID = target->GetGUID(); + _EnterCombat(); - //10 seconds - Talk(SAY_LINE1); + DoCast(me, SPELL_ESSENCEOFTHERED); + me->SetHealth(me->CountPctFromMaxHealth(30)); + // now drop damage requirement to be able to take loot + me->ResetPlayerDamageReq(); - SpeechTimer = 10000; - SpeechNum = 0; - DoingSpeech = true; + events.ScheduleEvent(EVENT_CLEAVE, 10000); + events.ScheduleEvent(EVENT_FLAMEBREATH, 15000); + events.ScheduleEvent(EVENT_FIRENOVA, 20000); + events.ScheduleEvent(EVENT_TAILSWIPE, 11000); + events.ScheduleEvent(EVENT_BURNINGADRENALINE_CASTER, 15000); + events.ScheduleEvent(EVENT_BURNINGADRENALINE_TANK, 45000); + } + void BeginSpeech(Unit* target) + { + PlayerGUID = target->GetGUID(); me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + events.ScheduleEvent(EVENT_SPEECH_1, 1000); } void KilledUnit(Unit* victim) @@ -147,54 +117,95 @@ public: Talk(SAY_KILLTARGET, victim->GetGUID()); } - void EnterCombat(Unit* /*who*/) - { - DoCast(me, SPELL_ESSENCEOFTHERED); - DoZoneInCombat(); - me->SetHealth(me->CountPctFromMaxHealth(30)); - // now drop damage requirement to be able to take loot - me->ResetPlayerDamageReq(); - } - void UpdateAI(uint32 diff) { - //Speech - if (DoingSpeech) + events.Update(diff); + + // Speech + if (!UpdateVictim()) { - if (SpeechTimer <= diff) + while (uint32 eventId = events.ExecuteEvent()) { - switch (SpeechNum) + switch (eventId) { - case 0: - //16 seconds till next line + case EVENT_SPEECH_1: + Talk(SAY_LINE1); + me->SetStandState(UNIT_STAND_STATE_STAND); + me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); + events.ScheduleEvent(EVENT_SPEECH_2, 12000); + break; + case EVENT_SPEECH_2: Talk(SAY_LINE2); - SpeechTimer = 16000; - ++SpeechNum; + me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); + events.ScheduleEvent(EVENT_SPEECH_3, 12000); break; - case 1: - //This one is actually 16 seconds but we only go to 10 seconds because he starts attacking after he says "I must fight this!" + case EVENT_SPEECH_3: Talk(SAY_LINE3); - SpeechTimer = 10000; - ++SpeechNum; + me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); + events.ScheduleEvent(EVENT_SPEECH_4, 16000); break; - case 2: + case EVENT_SPEECH_4: me->setFaction(103); if (PlayerGUID && Unit::GetUnit(*me, PlayerGUID)) - { - AttackStart(Unit::GetUnit(*me, PlayerGUID)); - DoCast(me, SPELL_ESSENCEOFTHERED); - } - SpeechTimer = 0; - DoingSpeech = false; + AttackStart(Unit::GetUnit(*me, PlayerGUID));; break; } - } else SpeechTimer -= diff; + } + return; } - //Return since we have no target - if (!UpdateVictim()) + if (me->HasUnitState(UNIT_STATE_CASTING)) return; + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_CLEAVE: + events.ScheduleEvent(EVENT_CLEAVE, 15000); + DoCastVictim(SPELL_CLEAVE); + break; + case EVENT_FLAMEBREATH: + DoCastVictim(SPELL_FLAMEBREATH); + events.ScheduleEvent(EVENT_FLAMEBREATH, urand(8000, 14000)); + break; + case EVENT_FIRENOVA: + DoCastVictim(SPELL_FIRENOVA); + events.ScheduleEvent(EVENT_FIRENOVA, 15000); + break; + case EVENT_TAILSWIPE: + //Only cast if we are behind + /*if (!me->HasInArc(M_PI, me->GetVictim())) + { + DoCast(me->GetVictim(), SPELL_TAILSWIPE); + }*/ + events.ScheduleEvent(EVENT_TAILSWIPE, 15000); + break; + case EVENT_BURNINGADRENALINE_CASTER: + { + Unit* target = NULL; + + uint8 i = 0; + while (i < 3) // max 3 tries to get a random target with power_mana + { + ++i; + target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); // not aggro leader + if (target && target->getPowerType() == POWER_MANA) + i = 3; + } + if (target) // cast on self (see below) + target->CastSpell(target, SPELL_BURNINGADRENALINE, true); + } + 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); + events.ScheduleEvent(EVENT_BURNINGADRENALINE_TANK, 45000); + break; + } + } + // Yell if hp lower than 15% if (HealthBelowPct(15) && !HasYelled) { @@ -202,74 +213,30 @@ public: HasYelled = true; } - //Cleave_Timer - if (Cleave_Timer <= diff) - { - DoCastVictim(SPELL_CLEAVE); - Cleave_Timer = 15000; - } else Cleave_Timer -= diff; - - //FlameBreath_Timer - if (FlameBreath_Timer <= diff) - { - DoCastVictim(SPELL_FLAMEBREATH); - FlameBreath_Timer = urand(4000, 8000); - } else FlameBreath_Timer -= diff; - - //BurningAdrenalineCaster_Timer - if (BurningAdrenalineCaster_Timer <= diff) - { - Unit* target = NULL; - - uint8 i = 0; - while (i < 3) // max 3 tries to get a random target with power_mana - { - ++i; - target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); //not aggro leader - if (target && target->getPowerType() == POWER_MANA) - i = 3; - } - if (target) // cast on self (see below) - target->CastSpell(target, SPELL_BURNINGADRENALINE, 1); - - BurningAdrenalineCaster_Timer = 15000; - } else BurningAdrenalineCaster_Timer -= diff; - - //BurningAdrenalineTank_Timer - if (BurningAdrenalineTank_Timer <= diff) - { - // 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, 1); - - BurningAdrenalineTank_Timer = 45000; - } else BurningAdrenalineTank_Timer -= diff; - - //FireNova_Timer - if (FireNova_Timer <= diff) - { - DoCastVictim(SPELL_FIRENOVA); - FireNova_Timer = 5000; - } else FireNova_Timer -= diff; + DoMeleeAttackIfReady(); + } - //TailSwipe_Timer - if (TailSwipe_Timer <= diff) + void sGossipSelect(Player* player, uint32 sender, uint32 action) + { + if (sender == GOSSIP_ID && action == 0) { - //Only cast if we are behind - /*if (!me->HasInArc(M_PI, me->GetVictim())) - { - DoCastVictim(SPELL_TAILSWIPE); - }*/ - - TailSwipe_Timer = 20000; - } else TailSwipe_Timer -= diff; - - DoMeleeAttackIfReady(); + player->CLOSE_GOSSIP_MENU(); + BeginSpeech(player); + } } + + private: + uint64 PlayerGUID; + bool HasYelled; }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_vaelAI (creature); + } }; -void AddSC_boss_vael() +void AddSC_boss_vaelastrasz() { new boss_vaelastrasz(); } diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_victor_nefarius.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_victor_nefarius.cpp deleted file mode 100644 index 84670ed4e0c..00000000000 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_victor_nefarius.cpp +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright (C) 2008-2013 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: Boss_Victor_Nefarius -SD%Complete: 75 -SDComment: Missing some text, Vael beginning event, and spawns Nef in wrong place -SDCategory: Blackwing Lair -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -enum Says -{ - // UBRS text - SAY_GYTH_REND_1 = 0, - SAY_GYTH_REND_2 = 1, - SAY_GYTH_REND_3 = 2, - SAY_GYTH_REND_4 = 3, - SAY_GYTH_REND_5 = 4, - SAY_GYTH_REND_6 = 5, - SAY_GYTH_REND_7 = 6, - SAY_GYTH_REND_8 = 7, - SAY_GYTH_REND_9 = 8, - SAY_GYTH_REND_10 = 9, - // BWL text - SAY_GAMESBEGIN_1 = 10, - SAY_GAMESBEGIN_2 = 11, - //SAY_VAEL_INTRO = 12, Not used - when he corrupts Vaelastrasz -}; - -#define GOSSIP_ITEM_1 "I've made no mistakes." -#define GOSSIP_ITEM_2 "You have lost your mind, Nefarius. You speak in riddles." -#define GOSSIP_ITEM_3 "Please do." - -enum Creatures -{ - NPC_REND_BLACKHAND = 10429, - CREATURE_BRONZE_DRAKANOID = 14263, - CREATURE_BLUE_DRAKANOID = 14261, - CREATURE_RED_DRAKANOID = 14264, - CREATURE_GREEN_DRAKANOID = 14262, - CREATURE_BLACK_DRAKANOID = 14265, - - CREATURE_CHROMATIC_DRAKANOID = 14302, - CREATURE_NEFARIAN = 11583 -}; - -#define ADD_X1 -7591.151855f -#define ADD_X2 -7514.598633f -#define ADD_Y1 -1204.051880f -#define ADD_Y2 -1150.448853f -#define ADD_Z1 476.800476f -#define ADD_Z2 476.796570f - -#define NEF_X -7445 -#define NEF_Y -1332 -#define NEF_Z 536 - -#define HIDE_X -7592 -#define HIDE_Y -1264 -#define HIDE_Z 481 - -enum Spells -{ - // UBRS Spells - SPELL_CHROMATIC_CHAOS = 16337, // Self Cast hits 10339 - SPELL_VAELASTRASZZ_SPAWN = 16354, // Self Cast Depawn one sec after - // BWL Spells - SPELL_SHADOWBOLT = 21077, - SPELL_FEAR = 26070 -}; - -enum Events -{ - // UBRS Events - EVENT_PLAYER_CHECK = 0, - EVENT_GYTH_REND_1 = 1, - EVENT_GYTH_REND_2 = 2, - EVENT_GYTH_REND_3 = 3, - EVENT_GYTH_REND_4 = 4, - EVENT_GYTH_REND_5 = 5, -}; - -//This script is complicated -//Instead of morphing Victor Nefarius we will have him control phase 1 -//And then have him spawn "Nefarian" for phase 2 -//When phase 2 starts Victor Nefarius will go into hiding and stop attacking -//If Nefarian despawns because he killed the players then this guy will EnterEvadeMode -//and allow players to start the event over -//If nefarian dies then he will kill himself then he will kill himself in his hiding place -//To prevent players from doing the event twice - -class boss_victor_nefarius : public CreatureScript -{ -public: - boss_victor_nefarius() : CreatureScript("boss_victor_nefarius") { } - - struct boss_victor_nefariusAI : public ScriptedAI - { - boss_victor_nefariusAI(Creature* creature) : ScriptedAI(creature) - { - NefarianGUID = 0; - switch (urand(0, 19)) - { - case 0: - DrakType1 = CREATURE_BRONZE_DRAKANOID; - DrakType2 = CREATURE_BLUE_DRAKANOID; - break; - case 1: - DrakType1 = CREATURE_BRONZE_DRAKANOID; - DrakType2 = CREATURE_RED_DRAKANOID; - break; - case 2: - DrakType1 = CREATURE_BRONZE_DRAKANOID; - DrakType2 = CREATURE_GREEN_DRAKANOID; - break; - case 3: - DrakType1 = CREATURE_BRONZE_DRAKANOID; - DrakType2 = CREATURE_BLACK_DRAKANOID; - break; - case 4: - DrakType1 = CREATURE_BLUE_DRAKANOID; - DrakType2 = CREATURE_BRONZE_DRAKANOID; - break; - case 5: - DrakType1 = CREATURE_BLUE_DRAKANOID; - DrakType2 = CREATURE_RED_DRAKANOID; - break; - case 6: - DrakType1 = CREATURE_BLUE_DRAKANOID; - DrakType2 = CREATURE_GREEN_DRAKANOID; - break; - case 7: - DrakType1 = CREATURE_BLUE_DRAKANOID; - DrakType2 = CREATURE_BLACK_DRAKANOID; - break; - case 8: - DrakType1 = CREATURE_RED_DRAKANOID; - DrakType2 = CREATURE_BRONZE_DRAKANOID; - break; - case 9: - DrakType1 = CREATURE_RED_DRAKANOID; - DrakType2 = CREATURE_BLUE_DRAKANOID; - break; - case 10: - DrakType1 = CREATURE_RED_DRAKANOID; - DrakType2 = CREATURE_GREEN_DRAKANOID; - break; - case 11: - DrakType1 = CREATURE_RED_DRAKANOID; - DrakType2 = CREATURE_BLACK_DRAKANOID; - break; - case 12: - DrakType1 = CREATURE_GREEN_DRAKANOID; - DrakType2 = CREATURE_BRONZE_DRAKANOID; - break; - case 13: - DrakType1 = CREATURE_GREEN_DRAKANOID; - DrakType2 = CREATURE_BLUE_DRAKANOID; - break; - case 14: - DrakType1 = CREATURE_GREEN_DRAKANOID; - DrakType2 = CREATURE_RED_DRAKANOID; - break; - case 15: - DrakType1 = CREATURE_GREEN_DRAKANOID; - DrakType2 = CREATURE_BLACK_DRAKANOID; - break; - case 16: - DrakType1 = CREATURE_BLACK_DRAKANOID; - DrakType2 = CREATURE_BRONZE_DRAKANOID; - break; - case 17: - DrakType1 = CREATURE_BLACK_DRAKANOID; - DrakType2 = CREATURE_BLUE_DRAKANOID; - break; - case 18: - DrakType1 = CREATURE_BLACK_DRAKANOID; - DrakType2 = CREATURE_GREEN_DRAKANOID; - break; - case 19: - DrakType1 = CREATURE_BLACK_DRAKANOID; - DrakType2 = CREATURE_RED_DRAKANOID; - break; - } - } - - void Reset() - { - if(me->GetMapId() == 229) - { - _events.ScheduleEvent(EVENT_PLAYER_CHECK, 5000); - } - - if(me->GetMapId() == 469) - { - SpawnedAdds = 0; - AddSpawnTimer = 10000; - ShadowBoltTimer = 5000; - FearTimer = 8000; - ResetTimer = 900000; // On official it takes him 15 minutes(900 seconds) to reset. We are only doing 1 minute to make testing easier - NefarianGUID = 0; - NefCheckTime = 2000; - me->SetUInt32Value(UNIT_NPC_FLAGS, 1); - me->setFaction(35); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - } - - void BeginEvent(Player* target) - { - Talk(SAY_GAMESBEGIN_2); - - //Trinity::Singleton<MapManager>::Instance().GetMap(me->GetMapId(), me)->GetPlayers().begin(); - /* - list <Player*>::const_iterator i = sMapMgr->GetMap(me->GetMapId(), me)->GetPlayers().begin(); - - for (i = sMapMgr->GetMap(me->GetMapId(), me)->GetPlayers().begin(); i != sMapMgr->GetMap(me->GetMapId(), me)->GetPlayers().end(); ++i) - { - AttackStart((*i)); - } - */ - me->SetUInt32Value(UNIT_NPC_FLAGS, 0); - me->setFaction(103); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - AttackStart(target); - } - - void EnterCombat(Unit* /*who*/) - { - } - - void MoveInLineOfSight(Unit* who) - { - //We simply use this function to find players until we can use map->GetPlayers() - - if (who && who->GetTypeId() == TYPEID_PLAYER && me->IsHostileTo(who)) - { - //Add them to our threat list - me->AddThreat(who, 0.0f); - } - } - - void UpdateAI(uint32 diff) - { - - if(me->GetMapId() == 229) // UBRS EVENTS - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_PLAYER_CHECK: - // If player found within 30.0f - // _events.ScheduleEvent(EVENT_GYTH_REND_1, 1000); - // else - // events.ScheduleEvent(EVENT_PLAYER_CHECK, 5000); - break; - case EVENT_GYTH_REND_1: - Talk(SAY_GYTH_REND_1); - _events.ScheduleEvent(EVENT_GYTH_REND_2, 4000); - break; - case EVENT_GYTH_REND_2: - if (Unit* player = SelectTarget(SELECT_TARGET_NEAREST, 0, 30.0f, false)) - me->SetInFront(player); - me->SendMovementFlagUpdate(); - me->HandleEmoteCommand(EMOTE_ONESHOT_POINT); - _events.ScheduleEvent(EVENT_GYTH_REND_3, 4000); - break; - case EVENT_GYTH_REND_3: - Talk(SAY_GYTH_REND_2); - _events.ScheduleEvent(EVENT_GYTH_REND_4, 4000); - break; - case EVENT_GYTH_REND_4: - if (Creature* rend = me->FindNearestCreature(NPC_REND_BLACKHAND, 5.0f, true)) - me->SetInFront(rend); - me->SendMovementFlagUpdate(); - _events.ScheduleEvent(EVENT_GYTH_REND_5, 4000); - break; - case EVENT_GYTH_REND_5: - me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); - _events.ScheduleEvent(EVENT_GYTH_REND_5, 4000); - default: - break; - } - } - } - - if (!UpdateVictim()) - return; - - //Only do this if we haven't spawned nef yet - if (SpawnedAdds < 42) - { - //ShadowBoltTimer - if (ShadowBoltTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_SHADOWBOLT); - - ShadowBoltTimer = urand(3000, 10000); - } else ShadowBoltTimer -= diff; - - //FearTimer - if (FearTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_FEAR); - - FearTimer = 10000 + (rand()%10000); - } else FearTimer -= diff; - - //Add spawning mechanism - if (AddSpawnTimer <= diff) - { - //Spawn 2 random types of creatures at the 2 locations - uint32 CreatureID; - Creature* Spawned = NULL; - Unit* target = NULL; - - //1 in 3 chance it will be a chromatic - if (urand(0, 2) == 0) - CreatureID = CREATURE_CHROMATIC_DRAKANOID; - else - CreatureID = DrakType1; - - ++SpawnedAdds; - - //Spawn Creature and force it to start attacking a random target - Spawned = me->SummonCreature(CreatureID, ADD_X1, ADD_Y1, ADD_Z1, 5.000f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); - if (target && Spawned) - { - Spawned->AI()->AttackStart(target); - Spawned->setFaction(103); - } - - //1 in 3 chance it will be a chromatic - if (urand(0, 2) == 0) - CreatureID = CREATURE_CHROMATIC_DRAKANOID; - else - CreatureID = DrakType2; - - ++SpawnedAdds; - - Spawned = me->SummonCreature(CreatureID, ADD_X2, ADD_Y2, ADD_Z2, 5.000f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); - if (target && Spawned) - { - Spawned->AI()->AttackStart(target); - Spawned->setFaction(103); - } - - //Begin phase 2 by spawning Nefarian and what not - if (SpawnedAdds >= 42) - { - //Teleport Victor Nefarius way out of the map - //sMapMgr->GetMap(me->GetMapId(), me)->CreatureRelocation(me, 0, 0, -5000, 0); - - //Interrupt any spell casting - me->InterruptNonMeleeSpells(false); - - //Root self - DoCast(me, 33356); - - //Make super invis - DoCast(me, 8149); - - //Teleport self to a hiding spot (this causes errors in the Trinity log but no real issues) - DoTeleportTo(HIDE_X, HIDE_Y, HIDE_Z); - me->AddUnitState(UNIT_STATE_FLEEING); - - //Spawn nef and have him attack a random target - Creature* Nefarian = me->SummonCreature(CREATURE_NEFARIAN, NEF_X, NEF_Y, NEF_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); - if (target && Nefarian) - { - Nefarian->AI()->AttackStart(target); - Nefarian->setFaction(103); - NefarianGUID = Nefarian->GetGUID(); - } - else TC_LOG_ERROR(LOG_FILTER_TSCR, "Blackwing Lair: Unable to spawn nefarian properly."); - } - - AddSpawnTimer = 4000; - } else AddSpawnTimer -= diff; - } - else if (NefarianGUID) - { - if (NefCheckTime <= diff) - { - Unit* Nefarian = Unit::GetCreature((*me), NefarianGUID); - - //If nef is dead then we die to so the players get out of combat - //and cannot repeat the event - if (!Nefarian || !Nefarian->IsAlive()) - { - NefarianGUID = 0; - me->DespawnOrUnsummon(); - } - - NefCheckTime = 2000; - } else NefCheckTime -= diff; - } - } - - private: - EventMap _events; - // UBRS - - // BWL - uint32 SpawnedAdds; - uint32 AddSpawnTimer; - uint32 ShadowBoltTimer; - uint32 FearTimer; - uint32 MindControlTimer; - uint32 ResetTimer; - uint32 DrakType1; - uint32 DrakType2; - uint64 NefarianGUID; - uint32 NefCheckTime; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_victor_nefariusAI (creature); - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(7198, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(7199, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->CLOSE_GOSSIP_MENU(); - creature->AI()->Talk(SAY_GAMESBEGIN_1); - CAST_AI(boss_victor_nefarius::boss_victor_nefariusAI, creature->AI())->BeginEvent(player); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(7134, creature->GetGUID()); - return true; - } -}; - -void AddSC_boss_victor_nefarius() -{ - new boss_victor_nefarius(); -} diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/instance_blackwing_lair.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/instance_blackwing_lair.cpp index 279375be228..4541ee07a03 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/instance_blackwing_lair.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/instance_blackwing_lair.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 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 @@ -16,12 +15,339 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Instance_Blackwing_Lair -SD%Complete: 0 -SDComment: -SDCategory: Blackwing Lair -EndScriptData */ - #include "ScriptMgr.h" -#include "InstanceScript.h" +#include "ScriptedCreature.h" +#include "PassiveAI.h" +#include "blackwing_lair.h" +#include "Player.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 +*/ + +Position const SummonPosition[8] = +{ + {-7661.207520f, -1043.268188f, 407.199554f, 6.280452f}, + {-7644.145020f, -1065.628052f, 407.204956f, 0.501492f}, + {-7624.260742f, -1095.196899f, 407.205017f, 0.544694f}, + {-7608.501953f, -1116.077271f, 407.199921f, 0.816443f}, + {-7531.841797f, -1063.765381f, 407.199615f, 2.874187f}, + {-7547.319336f, -1040.971924f, 407.205078f, 3.789175f}, + {-7568.547852f, -1013.112488f, 407.204926f, 3.773467f}, + {-7584.175781f, -989.6691289f, 407.199585f, 4.527447f}, +}; + +uint32 const Entry[5] = {12422, 12458, 12416, 12402, 12459}; + +class instance_blackwing_lair : public InstanceMapScript +{ +public: + instance_blackwing_lair() : InstanceMapScript(BRLScriptName, 469) { } + + struct instance_blackwing_lair_InstanceMapScript : public InstanceScript + { + instance_blackwing_lair_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + } + + void Initialize() + { + // Razorgore + EggCount = 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) + { + 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); + 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(); + break; + } + } + + void OnGameObjectCreate(GameObject* go) + { + switch (go->GetEntry()) + { + case 177807: // Egg + if (GetBossState(BOSS_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); + 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); + break; + } + } + + void OnGameObjectRemove(GameObject* go) + { + if (go->GetEntry() == 177807) // Egg + EggList.remove(go->GetGUID()); + } + + bool SetBossState(uint32 type, EncounterState state) + { + if (!InstanceScript::SetBossState(type, state)) + return false; + + switch (type) + { + case BOSS_RAZORGORE: + HandleGameObject(RazorgoreDoorGUID, state == DONE); + if (state == DONE) + { + for (std::list<uint64>::const_iterator itr = EggList.begin(); itr != EggList.end(); ++itr) + if (GameObject* egg = instance->GetGameObject((*itr))) + egg->SetPhaseMask(2, true); + } + 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: + switch (state) + { + case NOT_STARTED: + if (Creature* nefarian = instance->GetCreature(NefarianGUID)) + nefarian->DespawnOrUnsummon(); + break; + case FAIL: + _events.ScheduleEvent(EVENT_RESPAWN_NEFARIUS, 15*IN_MILLISECONDS*MINUTE); + SetBossState(BOSS_NEFARIAN, NOT_STARTED); + break; + } + break; + } + return true; + } + + uint64 GetData64(uint32 id) const + { + 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) + { + if (type == DATA_EGG_EVENT) + { + switch (data) + { + case IN_PROGRESS: + _events.ScheduleEvent(EVENT_RAZOR_SPAWN, 45*IN_MILLISECONDS); + EggEvent = data; + EggCount = 0; + break; + case NOT_STARTED: + _events.CancelEvent(EVENT_RAZOR_SPAWN); + EggEvent = data; + EggCount = 0; + break; + case SPECIAL: + if (++EggCount == 15) + { + if (Creature* razor = instance->GetCreature(RazorgoreTheUntamedGUID)) + { + SetData(DATA_EGG_EVENT, DONE); + razor->RemoveAurasDueToSpell(42013); // MindControl + DoRemoveAurasDueToSpellOnPlayers(42013); + } + _events.ScheduleEvent(EVENT_RAZOR_PHASE_TWO, IN_MILLISECONDS); + _events.CancelEvent(EVENT_RAZOR_SPAWN); + } + if (EggEvent == NOT_STARTED) + SetData(DATA_EGG_EVENT, IN_PROGRESS); + break; + } + } + } + + void OnUnitDeath(Unit* unit) + { + //! HACK, needed because of buggy CreatureAI after charm + if (unit->GetEntry() == NPC_RAZORGORE && GetBossState(BOSS_RAZORGORE) != DONE) + SetBossState(BOSS_RAZORGORE, DONE); + } + + void Update(uint32 diff) + { + if (_events.Empty()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_RAZOR_SPAWN: + for (uint8 i = urand(2, 5); i > 0 ; --i) + if (Creature* summon = instance->SummonCreature(Entry[urand(0, 5)], SummonPosition[urand(0, 8)])) + summon->SetInCombatWithZone(); + _events.ScheduleEvent(EVENT_RAZOR_SPAWN, urand(12, 17)*IN_MILLISECONDS); + break; + case EVENT_RAZOR_PHASE_TWO: + _events.CancelEvent(EVENT_RAZOR_SPAWN); + if (Creature* razor = instance->GetCreature(RazorgoreTheUntamedGUID)) + razor->AI()->DoAction(ACTION_PHASE_TWO); + break; + case EVENT_RESPAWN_NEFARIUS: + if (Creature* nefarius = instance->GetCreature(LordVictorNefariusGUID)) + { + nefarius->SetPhaseMask(1, true); + nefarius->setActive(true); + nefarius->Respawn(); + nefarius->GetMotionMaster()->MoveTargetedHome(); + } + break; + } + } + } + + 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 + { + return new instance_blackwing_lair_InstanceMapScript(map); + } +}; + +void AddSC_instance_blackwing_lair() +{ + new instance_blackwing_lair(); +}
\ No newline at end of file diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt index f581baa31fa..1d1e40ca042 100644 --- a/src/server/scripts/EasternKingdoms/CMakeLists.txt +++ b/src/server/scripts/EasternKingdoms/CMakeLists.txt @@ -174,7 +174,7 @@ set(scripts_STAT_SRCS EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp EasternKingdoms/BlackwingLair/boss_nefarian.cpp EasternKingdoms/BlackwingLair/boss_flamegor.cpp - EasternKingdoms/BlackwingLair/boss_victor_nefarius.cpp + EasternKingdoms/BlackwingLair/blackwing_lair.h EasternKingdoms/zone_blasted_lands.cpp EasternKingdoms/zone_stormwind_city.cpp EasternKingdoms/ZulAman/boss_halazzi.cpp |