Professional Documents
Culture Documents
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright
information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 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 Affero 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/>.
*/
#include "GridNotifiers.h"
#include "PassiveAI.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "Spell.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
//
// Emerald Dragon NPCs and IDs (kept here for reference)
//
enum EmeraldDragonNPC
{
NPC_DREAM_FOG = 15224,
DRAGON_YSONDRE = 14887,
DRAGON_LETHON = 14888,
DRAGON_EMERISS = 14889,
DRAGON_TAERAR = 14890,
};
//
// Emerald Dragon Spells (used for the dragons)
//
enum EmeraldDragonSpells
{
SPELL_TAIL_SWEEP = 15847, // tail sweep - slap everything
behind dragon (2 seconds interval)
SPELL_SUMMON_PLAYER = 24776, // teleport highest threat player
in front of dragon if wandering off
SPELL_DREAM_FOG = 24777, // auraspell for Dream Fog NPC
(15224)
SPELL_SLEEP = 24778, // sleep triggerspell (used for
Dream Fog)
SPELL_SEEPING_FOG_LEFT = 24813, // dream fog - summon left
SPELL_SEEPING_FOG_RIGHT = 24814, // dream fog - summon right
SPELL_NOXIOUS_BREATH = 24818,
SPELL_MARK_OF_NATURE = 25040, // Mark of Nature trigger (applied
on target death - 15 minutes of being suspectible to Aura Of Nature)
SPELL_MARK_OF_NATURE_AURA = 25041, // Mark of Nature (passive marker-
test, ticks every 10 seconds from boss, triggers spellID 25042 (scripted)
SPELL_AURA_OF_NATURE = 25043, // Stun for 2 minutes (used when
SPELL_MARK_OF_NATURE exists on the target)
};
//
// Emerald Dragon Eventlists (shared and specials)
//
enum Events
{
// General events for all dragons
EVENT_SEEPING_FOG = 1,
EVENT_NOXIOUS_BREATH,
EVENT_TAIL_SWEEP,
// Ysondre
EVENT_LIGHTNING_WAVE,
EVENT_SUMMON_DRUID_SPIRITS,
// Lethon
EVENT_SHADOW_BOLT_WHIRL,
// Emeriss
EVENT_VOLATILE_INFECTION,
EVENT_CORRUPTION_OF_EARTH,
// Taerar
EVENT_ARCANE_BLAST,
EVENT_BELLOWING_ROAR,
};
/*
* ---
* --- Emerald Dragons : Base AI-structure used for all the Emerald dragons
* ---
*/
// Target killed during encounter, mark them as suspectible for Aura Of Nature
void KilledUnit(Unit* who) override
{
if (who->GetTypeId() == TYPEID_PLAYER)
who->CastSpell(who, SPELL_MARK_OF_NATURE, true);
}
// Execute and reschedule base events shared between all Emerald Dragons
void ExecuteEvent(uint32 eventId) override
{
switch (eventId)
{
case EVENT_SEEPING_FOG:
// Seeping Fog appears only as "pairs", and only ONE pair at any
given time!
// Despawntime is 2 minutes, so reschedule it for new cast after 2
minutes + a minor "random time" (30 seconds at max)
DoCast(me, SPELL_SEEPING_FOG_LEFT, true);
DoCast(me, SPELL_SEEPING_FOG_RIGHT, true);
events.ScheduleEvent(EVENT_SEEPING_FOG, urand(120000, 150000));
break;
case EVENT_NOXIOUS_BREATH:
// Noxious Breath is cast on random intervals, no less than 7.5
seconds between
DoCast(me, SPELL_NOXIOUS_BREATH);
events.ScheduleEvent(EVENT_NOXIOUS_BREATH, urand(7500, 15000));
break;
case EVENT_TAIL_SWEEP:
// Tail Sweep is cast every two seconds, no matter what goes on in
front of the dragon
DoCast(me, SPELL_TAIL_SWEEP);
events.ScheduleEvent(EVENT_TAIL_SWEEP, 2000);
break;
}
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
}
};
/*
* --- NPC: Dream Fog
*/
if (!_roamTimer)
{
// Chase target, but don't attack - otherwise just roam around
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0,
0.0f, true))
{
_roamTimer = urand(15000, 30000);
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveChase(target, 0.2f);
}
else
{
_roamTimer = 2500;
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveRandom(25.0f);
}
// Seeping fog movement is slow enough for a player to be able to
walk backwards and still outpace it
me->SetWalk(true);
me->SetSpeed(MOVE_WALK, 0.75f);
}
else
_roamTimer -= diff;
}
private:
uint32 _roamTimer;
};
/*
* ---
* --- Dragonspecific scripts and handling: YSONDRE
* ---
*/
enum YsondreNPC
{
NPC_DEMENTED_DRUID = 15260,
};
enum YsondreTexts
{
SAY_YSONDRE_AGGRO = 0,
SAY_YSONDRE_SUMMON_DRUIDS = 1,
};
enum YsondreSpells
{
SPELL_LIGHTNING_WAVE = 24819,
SPELL_SUMMON_DRUID_SPIRITS = 24795,
};
private:
uint8 _stage;
};
/*
* ---
* --- Dragonspecific scripts and handling: LETHON
* ---
*/
enum LethonTexts
{
SAY_LETHON_AGGRO = 0,
SAY_LETHON_DRAW_SPIRIT = 1,
};
enum LethonSpells
{
SPELL_DRAW_SPIRIT = 24811,
SPELL_SHADOW_BOLT_WHIRL = 24834,
SPELL_DARK_OFFERING = 24804,
SPELL_SHADOW_BOLT_WHIRL1 = 24820,
SPELL_SHADOW_BOLT_WHIRL2 = 24821,
SPELL_SHADOW_BOLT_WHIRL3 = 24822,
SPELL_SHADOW_BOLT_WHIRL4 = 24823,
SPELL_SHADOW_BOLT_WHIRL5 = 24835,
SPELL_SHADOW_BOLT_WHIRL6 = 24836,
SPELL_SHADOW_BOLT_WHIRL7 = 24837,
SPELL_SHADOW_BOLT_WHIRL8 = 24838,
};
enum LethonCreatures
{
NPC_SPIRIT_SHADE = 15261,
};
private:
uint8 _stage;
};
_summonerGuid = summoner->GetGUID();
me->GetMotionMaster()->MoveFollow(summoner, 0.0f, 0.0f);
}
private:
ObjectGuid _summonerGuid;
};
/*
* ---
* --- Dragonspecific scripts and handling: EMERISS
* ---
*/
enum EmerissTexts
{
SAY_EMERISS_AGGRO = 0,
SAY_EMERISS_CAST_CORRUPTION = 1,
};
enum EmerissSpells
{
SPELL_PUTRID_MUSHROOM = 24904,
SPELL_CORRUPTION_OF_EARTH = 24910,
SPELL_VOLATILE_INFECTION = 24928,
};
emerald_dragonAI::KilledUnit(who);
}
private:
uint8 _stage;
};
/*
* ---
* --- Dragonspecific scripts and handling: TAERAR
* ---
*/
enum TaerarTexts
{
SAY_TAERAR_AGGRO = 0,
SAY_TAERAR_SUMMON_SHADES = 1,
};
enum TaerarSpells
{
SPELL_BELLOWING_ROAR = 22686,
SPELL_SHADE = 24313,
SPELL_SUMMON_SHADE_1 = 24841,
SPELL_SUMMON_SHADE_2 = 24842,
SPELL_SUMMON_SHADE_3 = 24843,
SPELL_ARCANE_BLAST = 24857,
};
_shades = 0;
_banished = false;
_banishedTimer = 0;
emerald_dragonAI::Reset();
events.ScheduleEvent(EVENT_ARCANE_BLAST, 12000);
events.ScheduleEvent(EVENT_BELLOWING_ROAR, 30000);
}
me->InterruptNonMeleeSpells(false);
DoStopAttack();
Talk(SAY_TAERAR_SUMMON_SHADES);
++_stage;
}
}
void ExecuteEvent(uint32 eventId) override
{
switch (eventId)
{
case EVENT_ARCANE_BLAST:
DoCast(SPELL_ARCANE_BLAST);
events.ScheduleEvent(EVENT_ARCANE_BLAST, urand(7000, 12000));
break;
case EVENT_BELLOWING_ROAR:
DoCast(SPELL_BELLOWING_ROAR);
events.ScheduleEvent(EVENT_BELLOWING_ROAR, urand(20000,
30000));
break;
default:
emerald_dragonAI::ExecuteEvent(eventId);
break;
}
}
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE |
UNIT_FLAG_NON_ATTACKABLE);
me->RemoveAurasDueToSpell(SPELL_SHADE);
me->SetReactState(REACT_AGGRESSIVE);
}
// _banishtimer has not expired, and we still have active shades:
else
_banishedTimer -= diff;
return;
}
emerald_dragonAI::UpdateAI(diff);
}
private:
bool _banished; // used for shades
activation testing
uint32 _banishedTimer; // counter for banishment
timeout
uint8 _shades; // keep track of how many
shades are dead
uint8 _stage; // check which "shade phase"
we're at (75-50-25 percentage counters)
};
/*
* --- Spell: Dream Fog
*/
/*
* --- Spell: Mark of Nature
*/
class MarkOfNatureTargetSelector
{
public:
MarkOfNatureTargetSelector() { }
void AddSC_emerald_dragons()
{
// helper NPC scripts
new npc_dream_fog();
new npc_spirit_shade();
// dragons
new boss_ysondre();
new boss_taerar();
new boss_emeriss();
new boss_lethon();
// dragon spellscripts
new spell_dream_fog_sleep();
new spell_mark_of_nature();
RegisterSpellScript(spell_shadow_bolt_whirl);
};