/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#include "ScriptMgr.h"
#include "CombatAI.h"
#include "CreatureAIImpl.h"
#include "DB2Stores.h"
#include "MotionMaster.h"
#include "ObjectAccessor.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "SpellAuras.h"
#include "SpellAuraEffects.h"
#include "SpellInfo.h"
#include "SpellScript.h"
#include "TemporarySummon.h"
#include "Vehicle.h"
/*#####
# npc_commander_eligor_dawnbringer
#####*/
enum CommanderEligorDawnbringer
{
MODEL_IMAGE_OF_KELTHUZAD = 24787, // Image of Kel'Thuzad
MODEL_IMAGE_OF_SAPPHIRON = 24788, // Image of Sapphiron
MODEL_IMAGE_OF_RAZUVIOUS = 24799, // Image of Razuvious
MODEL_IMAGE_OF_GOTHIK = 24804, // Image of Gothik
MODEL_IMAGE_OF_THANE = 24802, // Image of Thane Korth'azz
MODEL_IMAGE_OF_BLAUMEUX = 24794, // Image of Lady Blaumeux
MODEL_IMAGE_OF_ZELIEK = 24800, // Image of Sir Zeliek
MODEL_IMAGE_OF_PATCHWERK = 24798, // Image of Patchwerk
MODEL_IMAGE_OF_GROBBULUS = 24792, // Image of Grobbulus
MODEL_IMAGE_OF_THADDIUS = 24801, // Image of Thaddius
MODEL_IMAGE_OF_GLUTH = 24803, // Image of Gluth
MODEL_IMAGE_OF_ANUBREKHAN = 24789, // Image of Anub'rekhan
MODEL_IMAGE_OF_FAERLINA = 24790, // Image of Faerlina
MODEL_IMAGE_OF_MAEXXNA = 24796, // Image of Maexxna
MODEL_IMAGE_OF_NOTH = 24797, // Image of Noth
MODEL_IMAGE_OF_HEIGAN = 24793, // Image of Heigan
MODEL_IMAGE_OF_LOATHEB = 24795, // Image of Loatheb
NPC_IMAGE_OF_KELTHUZAD = 27766, // Image of Kel'Thuzad
NPC_IMAGE_OF_SAPPHIRON = 27767, // Image of Sapphiron
NPC_IMAGE_OF_RAZUVIOUS = 27768, // Image of Razuvious
NPC_IMAGE_OF_GOTHIK = 27769, // Image of Gothik
NPC_IMAGE_OF_THANE = 27770, // Image of Thane Korth'azz
NPC_IMAGE_OF_BLAUMEUX = 27771, // Image of Lady Blaumeux
NPC_IMAGE_OF_ZELIEK = 27772, // Image of Sir Zeliek
NPC_IMAGE_OF_PATCHWERK = 27773, // Image of Patchwerk
NPC_IMAGE_OF_GROBBULUS = 27774, // Image of Grobbulus
NPC_IMAGE_OF_THADDIUS = 27775, // Image of Thaddius
NPC_IMAGE_OF_GLUTH = 27782, // Image of Gluth
NPC_IMAGE_OF_ANUBREKHAN = 27776, // Image of Anub'rekhan
NPC_IMAGE_OF_FAERLINA = 27777, // Image of Faerlina
NPC_IMAGE_OF_MAEXXNA = 27778, // Image of Maexxna
NPC_IMAGE_OF_NOTH = 27779, // Image of Noth
NPC_IMAGE_OF_HEIGAN = 27780, // Image of Heigan
NPC_IMAGE_OF_LOATHEB = 27781, // Image of Loatheb
NPC_INFANTRYMAN = 27160, // Add in case I randomize the spawning
NPC_SENTINAL = 27162,
NPC_BATTLE_MAGE = 27164,
// Five platforms to choose from
SAY_PINNACLE = 0,
SAY_DEATH_KNIGHT_WING = 1,
SAY_ABOMINATION_WING = 2,
SAY_SPIDER_WING = 3,
SAY_PLAGUE_WING = 4,
// Used in all talks
SAY_TALK_COMPLETE = 5,
// Pinnacle of Naxxramas
SAY_SAPPHIRON = 6,
SAY_KELTHUZAD_1 = 7,
SAY_KELTHUZAD_2 = 8,
SAY_KELTHUZAD_3 = 9,
// Death knight wing of Naxxramas
SAY_RAZUVIOUS = 10,
SAY_GOTHIK = 11,
SAY_DEATH_KNIGHTS_1 = 12,
SAY_DEATH_KNIGHTS_2 = 13,
SAY_DEATH_KNIGHTS_3 = 14,
SAY_DEATH_KNIGHTS_4 = 15,
// Blighted abomination wing of Naxxramas
SAY_PATCHWERK = 16,
SAY_GROBBULUS = 17,
SAY_GLUTH = 18,
SAY_THADDIUS = 19,
// Accursed spider wing of Naxxramas
SAY_ANUBREKHAN = 20,
SAY_FAERLINA = 21,
SAY_MAEXXNA = 22,
// Dread plague wing of Naxxramas
SAY_NOTH = 23,
SAY_HEIGAN_1 = 24,
SAY_HEIGAN_2 = 25,
SAY_LOATHEB = 26,
SPELL_HEROIC_IMAGE_CHANNEL = 49519,
EVENT_START_RANDOM = 1,
EVENT_MOVE_TO_POINT = 2,
EVENT_TALK_COMPLETE = 3,
EVENT_GET_TARGETS = 4,
EVENT_KELTHUZAD_2 = 5,
EVENT_KELTHUZAD_3 = 6,
EVENT_DEATH_KNIGHTS_2 = 7,
EVENT_DEATH_KNIGHTS_3 = 8,
EVENT_DEATH_KNIGHTS_4 = 9,
EVENT_HEIGAN_2 = 10
};
uint32 const AudienceMobs[3] = { NPC_INFANTRYMAN, NPC_SENTINAL, NPC_BATTLE_MAGE };
Position const PosTalkLocations[6] =
{
{ 3805.453f, -682.9075f, 222.2917f, 2.793398f }, // Pinnacle of Naxxramas
{ 3807.508f, -691.0882f, 221.9688f, 2.094395f }, // Death knight wing of Naxxramas
{ 3797.228f, -690.3555f, 222.5019f, 1.134464f }, // Blighted abomination wing of Naxxramas
{ 3804.038f, -672.3098f, 222.5019f, 4.578917f }, // Accursed spider wing of Naxxramas
{ 3815.097f, -680.2596f, 221.9777f, 2.86234f }, // Dread plague wing of Naxxramas
{ 3798.05f, -680.611f, 222.9825f, 6.038839f }, // Home
};
struct npc_commander_eligor_dawnbringer : public ScriptedAI
{
npc_commander_eligor_dawnbringer(Creature* creature) : ScriptedAI(creature)
{
talkWing = 0;
}
void Reset() override
{
talkWing = 0;
for (ObjectGuid& guid : audienceList)
guid.Clear();
for (ObjectGuid& guid : imageList)
guid.Clear();
_events.ScheduleEvent(EVENT_GET_TARGETS, 5s);
_events.ScheduleEvent(EVENT_START_RANDOM, 20s);
}
void MovementInform(uint32 type, uint32 id) override
{
if (type == POINT_MOTION_TYPE)
{
if (id == 1)
{
me->SetFacingTo(PosTalkLocations[talkWing].GetOrientation());
TurnAudience();
switch (talkWing)
{
case 0: // Pinnacle of Naxxramas
{
switch (urand (0, 1))
{
case 0: ChangeImage(NPC_IMAGE_OF_KELTHUZAD, MODEL_IMAGE_OF_KELTHUZAD, SAY_KELTHUZAD_1);
_events.ScheduleEvent(EVENT_KELTHUZAD_2, 8s); break;
case 1: ChangeImage(NPC_IMAGE_OF_SAPPHIRON, MODEL_IMAGE_OF_SAPPHIRON, SAY_SAPPHIRON); break;
}
}
break;
case 1: // Death knight wing of Naxxramas
{
switch (urand (0, 2))
{
case 0: ChangeImage(NPC_IMAGE_OF_RAZUVIOUS, MODEL_IMAGE_OF_RAZUVIOUS, SAY_RAZUVIOUS); break;
case 1: ChangeImage(NPC_IMAGE_OF_GOTHIK, MODEL_IMAGE_OF_GOTHIK, SAY_GOTHIK); break;
case 2: ChangeImage(NPC_IMAGE_OF_THANE, MODEL_IMAGE_OF_THANE, SAY_DEATH_KNIGHTS_1);
_events.ScheduleEvent(EVENT_DEATH_KNIGHTS_2, 10s); break;
}
}
break;
case 2: // Blighted abomination wing of Naxxramas
{
switch (urand (0, 3))
{
case 0: ChangeImage(NPC_IMAGE_OF_PATCHWERK, MODEL_IMAGE_OF_PATCHWERK, SAY_PATCHWERK); break;
case 1: ChangeImage(NPC_IMAGE_OF_GROBBULUS, MODEL_IMAGE_OF_GROBBULUS, SAY_GROBBULUS); break;
case 2: ChangeImage(NPC_IMAGE_OF_THADDIUS, MODEL_IMAGE_OF_THADDIUS, SAY_THADDIUS); break;
case 3: ChangeImage(NPC_IMAGE_OF_GLUTH, MODEL_IMAGE_OF_GLUTH, SAY_GLUTH); break;
}
}
break;
case 3: // Accursed spider wing of Naxxramas
{
switch (urand (0, 2))
{
case 0: ChangeImage(NPC_IMAGE_OF_ANUBREKHAN, MODEL_IMAGE_OF_ANUBREKHAN, SAY_ANUBREKHAN); break;
case 1: ChangeImage(NPC_IMAGE_OF_FAERLINA, MODEL_IMAGE_OF_FAERLINA, SAY_FAERLINA); break;
case 2: ChangeImage(NPC_IMAGE_OF_MAEXXNA, MODEL_IMAGE_OF_MAEXXNA, SAY_MAEXXNA); break;
}
}
break;
case 4: // Dread plague wing of Naxxramas
{
switch (urand (0, 2))
{
case 0: ChangeImage(NPC_IMAGE_OF_NOTH, MODEL_IMAGE_OF_NOTH, SAY_NOTH); break;
case 1: ChangeImage(NPC_IMAGE_OF_HEIGAN, MODEL_IMAGE_OF_HEIGAN, SAY_HEIGAN_1);
_events.ScheduleEvent(EVENT_HEIGAN_2, 8s); break;
case 2: ChangeImage(NPC_IMAGE_OF_LOATHEB, MODEL_IMAGE_OF_LOATHEB, SAY_LOATHEB); break;
}
}
break;
case 5: // Home
_events.ScheduleEvent(EVENT_START_RANDOM, 30s);
break;
}
}
}
}
void StoreTargets()
{
uint8 creaturecount;
creaturecount = 0;
for (uint8 ii = 0; ii < 3; ++ii)
{
std::list creatureList;
GetCreatureListWithEntryInGrid(creatureList, me, AudienceMobs[ii], 15.0f);
for (Creature* creature : creatureList)
{
audienceList[creaturecount] = creature->GetGUID();
++creaturecount;
}
}
if (Creature* creature = me->FindNearestCreature(NPC_IMAGE_OF_KELTHUZAD, 20.0f, true))
imageList[0] = creature->GetGUID();
if (Creature* creature = me->FindNearestCreature(NPC_IMAGE_OF_RAZUVIOUS, 20.0f, true))
imageList[1] = creature->GetGUID();
if (Creature* creature = me->FindNearestCreature(NPC_IMAGE_OF_PATCHWERK, 20.0f, true))
imageList[2] = creature->GetGUID();
if (Creature* creature = me->FindNearestCreature(NPC_IMAGE_OF_ANUBREKHAN, 20.0f, true))
imageList[3] = creature->GetGUID();
if (Creature* creature = me->FindNearestCreature(NPC_IMAGE_OF_NOTH, 20.0f, true))
imageList[4] = creature->GetGUID();
}
void ChangeImage(uint32 entry, uint32 model, uint8 text)
{
if (Creature* creature = ObjectAccessor::GetCreature(*me, imageList[talkWing]))
{
Talk(text);
creature->SetEntry(entry);
creature->SetDisplayId(model);
creature->CastSpell(creature, SPELL_HEROIC_IMAGE_CHANNEL);
_events.ScheduleEvent(EVENT_TALK_COMPLETE, 40s);
}
}
void TurnAudience()
{
for (uint8 i = 0; i < 10; ++i)
{
if (Creature* creature = ObjectAccessor::GetCreature(*me, audienceList[i]))
creature->SetFacingToObject(me);
}
}
void UpdateAI(uint32 diff) override
{
_events.Update(diff);
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_START_RANDOM:
talkWing = urand (0, 4);
Talk(talkWing);
_events.ScheduleEvent(EVENT_MOVE_TO_POINT, 8s);
break;
case EVENT_MOVE_TO_POINT:
me->SetWalk(true);
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MovePoint(1, PosTalkLocations[talkWing].m_positionX, PosTalkLocations[talkWing].m_positionY, PosTalkLocations[talkWing].m_positionZ);
break;
case EVENT_TALK_COMPLETE:
talkWing = 5;
Talk(talkWing);
_events.ScheduleEvent(EVENT_MOVE_TO_POINT, 5s);
break;
case EVENT_GET_TARGETS:
StoreTargets();
break;
case EVENT_KELTHUZAD_2:
Talk(SAY_KELTHUZAD_2);
_events.ScheduleEvent(EVENT_KELTHUZAD_3, 8s);
break;
case EVENT_KELTHUZAD_3:
Talk(SAY_KELTHUZAD_3);
break;
case EVENT_DEATH_KNIGHTS_2:
Talk(SAY_DEATH_KNIGHTS_2);
if (Creature* creature = ObjectAccessor::GetCreature(*me, imageList[talkWing]))
{
creature->SetEntry(NPC_IMAGE_OF_BLAUMEUX);
creature->SetDisplayId(MODEL_IMAGE_OF_BLAUMEUX);
}
_events.ScheduleEvent(EVENT_DEATH_KNIGHTS_3, 10s);
break;
case EVENT_DEATH_KNIGHTS_3:
Talk(SAY_DEATH_KNIGHTS_3);
if (Creature* creature = ObjectAccessor::GetCreature(*me, imageList[talkWing]))
{
creature->SetEntry(NPC_IMAGE_OF_ZELIEK);
creature->SetDisplayId(MODEL_IMAGE_OF_ZELIEK);
}
_events.ScheduleEvent(EVENT_DEATH_KNIGHTS_4, 10s);
break;
case EVENT_DEATH_KNIGHTS_4:
Talk(SAY_DEATH_KNIGHTS_4);
break;
case EVENT_HEIGAN_2:
Talk(SAY_HEIGAN_2);
break;
default:
break;
}
}
}
private:
EventMap _events;
ObjectGuid audienceList[10];
ObjectGuid imageList[5];
uint8 talkWing;
};
enum AlexstraszaWrGate
{
// Quest
QUEST_RETURN_TO_AG_A = 12499,
QUEST_RETURN_TO_AG_H = 12500,
// Movie
MOVIE_ID_GATES = 14
};
/*######
## Quest Strengthen the Ancients (12096|12092)
######*/
enum StrengthenAncientsMisc
{
SAY_WALKER_FRIENDLY = 0,
SAY_WALKER_ENEMY = 1,
SAY_LOTHALOR = 0,
SPELL_CREATE_ITEM_BARK = 47550,
SPELL_CONFUSED = 47044,
NPC_LOTHALOR = 26321
};
// 47575 - Strengthen the Ancients: On Interact Dummy to Woodlands Walker
class spell_q12096_q12092_dummy : public SpellScript
{
void HandleDummy(SpellEffIndex /*effIndex*/)
{
uint32 roll = rand32() % 2;
Creature* tree = GetHitCreature();
Player* player = GetCaster()->ToPlayer();
if (!tree || !player)
return;
tree->RemoveNpcFlag(UNIT_NPC_FLAG_SPELLCLICK);
if (roll == 1) // friendly version
{
tree->CastSpell(player, SPELL_CREATE_ITEM_BARK);
tree->AI()->Talk(SAY_WALKER_FRIENDLY, player);
tree->DespawnOrUnsummon(1s);
}
else // enemy version
{
tree->AI()->Talk(SAY_WALKER_ENEMY, player);
tree->SetFaction(FACTION_MONSTER);
tree->Attack(player, true);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_dummy::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// 47530 - Bark of the Walkers
class spell_q12096_q12092_bark : public SpellScript
{
void HandleDummy(SpellEffIndex /*effIndex*/)
{
Creature* lothalor = GetHitCreature();
if (!lothalor || lothalor->GetEntry() != NPC_LOTHALOR)
return;
lothalor->AI()->Talk(SAY_LOTHALOR);
lothalor->RemoveAura(SPELL_CONFUSED);
lothalor->DespawnOrUnsummon(4s);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_bark::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
/*######
## Quest: Defending Wyrmrest Temple ID: 12372
######*/
enum WyrmDefenderEnum
{
// Quest data
QUEST_DEFENDING_WYRMREST_TEMPLE = 12372,
GOSSIP_OPTION_ID = 0,
MENU_ID = 9568,
// Spells data
SPELL_CHARACTER_SCRIPT = 49213,
SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE = 52421, // ID - 52421 Wyrmrest Defender: On Low Health Boss Emote to Controller - Random /self/
SPELL_RENEW = 49263, // cast to heal drakes
SPELL_WYRMREST_DEFENDER_MOUNT = 49256,
// Texts data
WHISPER_MOUNTED = 0,
BOSS_EMOTE_ON_LOW_HEALTH = 2
};
struct npc_wyrmrest_defender : public VehicleAI
{
npc_wyrmrest_defender(Creature* creature) : VehicleAI(creature)
{
Initialize();
}
void Initialize()
{
hpWarningReady = true;
renewRecoveryCanCheck = false;
RenewRecoveryChecker = 0;
}
bool hpWarningReady;
bool renewRecoveryCanCheck;
uint32 RenewRecoveryChecker;
void Reset() override
{
Initialize();
}
void UpdateAI(uint32 diff) override
{
VehicleAI::UpdateAI(diff);
// Check system for Health Warning should happen first time whenever get under 30%,
// after it should be able to happen only after recovery of last renew is fully done (20 sec),
// next one used won't interfere
if (hpWarningReady && me->GetHealthPct() <= 30.0f)
{
me->CastSpell(me, SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE);
hpWarningReady = false;
}
if (renewRecoveryCanCheck)
{
if (RenewRecoveryChecker <= diff)
{
renewRecoveryCanCheck = false;
hpWarningReady = true;
}
else
RenewRecoveryChecker -= diff;
}
}
void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
{
switch (spellInfo->Id)
{
case SPELL_WYRMREST_DEFENDER_MOUNT:
Talk(WHISPER_MOUNTED, me->GetCharmerOrOwner());
me->SetImmuneToAll(false);
me->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED);
break;
// Both below are for checking low hp warning
case SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE:
Talk(BOSS_EMOTE_ON_LOW_HEALTH, me->GetCharmerOrOwner());
break;
case SPELL_RENEW:
if (!hpWarningReady && RenewRecoveryChecker <= 100)
RenewRecoveryChecker = 20000;
renewRecoveryCanCheck = true;
break;
}
}
bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
{
if (menuId == MENU_ID && gossipListId == GOSSIP_OPTION_ID)
{
// Makes player cast trigger spell for 49207 on self
player->CastSpell(player, SPELL_CHARACTER_SCRIPT, true);
CloseGossipMenuFor(player);
}
return true;
}
void OnCharmed(bool /*apply*/) override
{
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
}
};
/*######
## Quest 12053: The Might of the Horde
######*/
enum WarsongBattleStandard
{
TEXT_TAUNT_1 = 25888,
TEXT_TAUNT_2 = 25889,
TEXT_TAUNT_3 = 25890,
TEXT_TAUNT_4 = 25891,
TEXT_TAUNT_5 = 25892,
TEXT_TAUNT_6 = 25893,
TEXT_TAUNT_7 = 25894
};
// 47304 - Warsong Battle Standard
class spell_dragonblight_warsong_battle_standard : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return sBroadcastTextStore.HasRecord(TEXT_TAUNT_1) &&
sBroadcastTextStore.HasRecord(TEXT_TAUNT_2) &&
sBroadcastTextStore.HasRecord(TEXT_TAUNT_3) &&
sBroadcastTextStore.HasRecord(TEXT_TAUNT_4) &&
sBroadcastTextStore.HasRecord(TEXT_TAUNT_5) &&
sBroadcastTextStore.HasRecord(TEXT_TAUNT_6) &&
sBroadcastTextStore.HasRecord(TEXT_TAUNT_7);
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
caster->Unit::Say(RAND(TEXT_TAUNT_1, TEXT_TAUNT_2, TEXT_TAUNT_3, TEXT_TAUNT_4, TEXT_TAUNT_5, TEXT_TAUNT_6, TEXT_TAUNT_7), caster);
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_dragonblight_warsong_battle_standard::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
/*######
## Quest 12470 & 13343: Mystery of the Infinite & Mystery of the Infinite, Redux
######*/
enum MysteryOfTheInfinite
{
SPELL_MIRROR_IMAGE_AURA = 49889
};
// 49686 - Mystery of the Infinite: Script Effect Player Cast Mirror Image
class spell_dragonblight_moti_mirror_image_script_effect : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_MIRROR_IMAGE_AURA });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_MIRROR_IMAGE_AURA);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_dragonblight_moti_mirror_image_script_effect::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// 50020 - Mystery of the Infinite: Hourglass cast See Invis on Master
class spell_dragonblight_moti_hourglass_cast_see_invis_on_master : public SpellScript
{
bool Validate(SpellInfo const* spellInfo) override
{
return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (TempSummon* casterSummon = GetCaster()->ToTempSummon())
if (Unit* summoner = casterSummon->GetSummonerUnit())
summoner->CastSpell(summoner, uint32(GetEffectValue()));
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_dragonblight_moti_hourglass_cast_see_invis_on_master::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
/*######
## Quest 12457: The Chain Gun And You
######*/
enum TheChainGunAndYou
{
TEXT_CALL_OUT_1 = 27083,
TEXT_CALL_OUT_2 = 27084
};
// BasePoints of the dummy effect is ID of npc_text used to group texts, it's not implemented so texts are grouped manually. Same with 49556 but looks like it's not used
// 49550 - Call Out Injured Soldier
class spell_dragonblight_call_out_injured_soldier : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return sBroadcastTextStore.HasRecord(TEXT_CALL_OUT_1) && sBroadcastTextStore.HasRecord(TEXT_CALL_OUT_2);
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (Vehicle* vehicle = GetCaster()->GetVehicleKit())
if (Unit* passenger = vehicle->GetPassenger(0))
passenger->Unit::Say(RAND(TEXT_CALL_OUT_1, TEXT_CALL_OUT_2), passenger);
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_dragonblight_call_out_injured_soldier::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
/*######
## Quest 12252: Torture the Torturer
######*/
enum TortureTheTorturer
{
WHISPER_TORTURE_1 = 1,
WHISPER_TORTURE_2 = 2,
WHISPER_TORTURE_3 = 3,
WHISPER_TORTURE_4 = 4,
WHISPER_TORTURE_5 = 5,
WHISPER_TORTURE_RANDOM = 6,
SPELL_TORTURER_KILL_CREDIT = 48607,
SPELL_BRANDING_IRON_IMPACT = 48614
};
// 48603 - High Executor's Branding Iron
class spell_dragonblight_high_executor_branding_iron : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_TORTURER_KILL_CREDIT, SPELL_BRANDING_IRON_IMPACT });
}
void HandleWhisper()
{
Player* caster = GetCaster()->ToPlayer();
Creature* target = GetHitCreature();
if (!caster || !target)
return;
target->CastSpell(target, SPELL_BRANDING_IRON_IMPACT);
if (Aura* aura = caster->GetAura(GetSpellInfo()->Id))
{
switch (aura->GetStackAmount())
{
case 1:
target->AI()->Talk(WHISPER_TORTURE_1, caster);
break;
case 2:
target->AI()->Talk(WHISPER_TORTURE_2, caster);
break;
case 3:
target->AI()->Talk(WHISPER_TORTURE_3, caster);
break;
case 4:
target->AI()->Talk(WHISPER_TORTURE_4, caster);
break;
case 5:
target->AI()->Talk(WHISPER_TORTURE_5, caster);
target->CastSpell(caster, SPELL_TORTURER_KILL_CREDIT);
break;
case 6:
target->AI()->Talk(WHISPER_TORTURE_RANDOM, caster);
break;
default:
return;
}
}
}
void Register() override
{
AfterHit += SpellHitFn(spell_dragonblight_high_executor_branding_iron::HandleWhisper);
}
};
/*######
## Quest 12260: The Perfect Dissemblance
######*/
enum ThePerfectDissemblance
{
SPELL_BANSHEES_MAGIC_MIRROR = 48648
};
// 48692 - The Perfect Dissemblance: Quest Completion Script
class spell_dragonblight_cancel_banshees_magic_mirror : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_BANSHEES_MAGIC_MIRROR });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetCaster()->RemoveAurasDueToSpell(SPELL_BANSHEES_MAGIC_MIRROR);
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_dragonblight_cancel_banshees_magic_mirror::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
/*######
## Quest 12274: A Fall From Grace
######*/
enum AFallFromGrace
{
SPELL_PRIEST_IMAGE_FEMALE = 48761,
SPELL_PRIEST_IMAGE_MALE = 48763
};
// 48762 - A Fall from Grace: Scarlet Raven Priest Image - Master
class spell_dragonblight_scarlet_raven_priest_image_master : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_PRIEST_IMAGE_FEMALE, SPELL_PRIEST_IMAGE_MALE });
}
void HandleAfterHit()
{
if (Player* target = GetHitUnit()->ToPlayer())
target->CastSpell(target, target->GetNativeGender() == GENDER_FEMALE ? SPELL_PRIEST_IMAGE_FEMALE : SPELL_PRIEST_IMAGE_MALE);
}
void Register() override
{
AfterHit += SpellHitFn(spell_dragonblight_scarlet_raven_priest_image_master::HandleAfterHit);
}
};
// 48769 - A Fall from Grace: Quest Completion Script
class spell_dragonblight_cancel_scarlet_raven_priest_image : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_PRIEST_IMAGE_FEMALE, SPELL_PRIEST_IMAGE_MALE });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetCaster()->RemoveAurasDueToSpell(SPELL_PRIEST_IMAGE_FEMALE);
GetCaster()->RemoveAurasDueToSpell(SPELL_PRIEST_IMAGE_MALE);
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_dragonblight_cancel_scarlet_raven_priest_image::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
/*######
## Quest 12232: Bombard the Ballistae
######*/
enum BombardTheBallistae
{
SPELL_BALLISTA_BOW = 48351,
SPELL_BALLISTA_FRAME = 48352,
SPELL_BALLISTA_MISSILE = 48353,
SPELL_BALLISTA_WHEEL = 48354,
SPELL_BALLISTA_KNOCKBACK = 52687
};
// 48347 - Bombard the Ballistae: FX Master
class spell_dragonblight_bombard_the_ballistae_fx_master : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo(
{
SPELL_BALLISTA_BOW,
SPELL_BALLISTA_FRAME,
SPELL_BALLISTA_MISSILE,
SPELL_BALLISTA_WHEEL,
SPELL_BALLISTA_KNOCKBACK
});
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
caster->CastSpell(caster, SPELL_BALLISTA_BOW);
caster->CastSpell(caster, SPELL_BALLISTA_FRAME);
caster->CastSpell(caster, SPELL_BALLISTA_MISSILE);
caster->CastSpell(caster, SPELL_BALLISTA_WHEEL);
caster->CastSpell(caster, SPELL_BALLISTA_WHEEL);
caster->CastSpell(caster, SPELL_BALLISTA_WHEEL);
caster->CastSpell(caster, SPELL_BALLISTA_WHEEL);
caster->CastSpell(caster, SPELL_BALLISTA_KNOCKBACK);
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_dragonblight_bombard_the_ballistae_fx_master::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
/*######
## Quest 12060, 12061: Projections and Plans
######*/
enum ProjectionsAndPlans
{
SPELL_TELE_MOONREST_GARDENS = 47324,
SPELL_TELE_SURGE_NEEDLE = 47325,
AREA_SURGE_NEEDLE = 4156,
AREA_MOONREST_GARDENS = 4157
};
// 47097 - Surge Needle Teleporter
class spell_dragonblight_surge_needle_teleporter : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_TELE_MOONREST_GARDENS, SPELL_TELE_SURGE_NEEDLE });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
switch (caster->GetAreaId())
{
case AREA_SURGE_NEEDLE:
caster->CastSpell(caster, SPELL_TELE_MOONREST_GARDENS);
break;
case AREA_MOONREST_GARDENS:
caster->CastSpell(caster, SPELL_TELE_SURGE_NEEDLE);
break;
default:
break;
}
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_dragonblight_surge_needle_teleporter::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
/*######
## Quest 12125, 12126, 12127: In Service of Blood & In Service of the Unholy & In Service of Frost
######*/
// 47703 - Unholy Union
// 47724 - Frost Draw
// 50252 - Blood Draw
class spell_dragonblight_fill_blood_unholy_frost_gem : public SpellScript
{
bool Validate(SpellInfo const* spellInfo) override
{
return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetCaster()->CastSpell(GetCaster(), uint32(GetEffectValue()));
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_dragonblight_fill_blood_unholy_frost_gem::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// 47447 - Corrosive Spit
class spell_dragonblight_corrosive_spit : public AuraScript
{
bool Validate(SpellInfo const* spellInfo) override
{
return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
}
void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTarget()->HasAura(GetEffectInfo(EFFECT_0).CalcValue()))
GetAura()->Remove();
}
void PeriodicTick(AuraEffect const* /*aurEff*/)
{
if (GetTarget()->HasAura(GetEffectInfo(EFFECT_0).CalcValue()))
{
PreventDefaultAction();
GetAura()->Remove();
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_dragonblight_corrosive_spit::AfterApply, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectPeriodic += AuraEffectPeriodicFn(spell_dragonblight_corrosive_spit::PeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE);
}
};
void AddSC_dragonblight()
{
RegisterCreatureAI(npc_commander_eligor_dawnbringer);
RegisterSpellScript(spell_q12096_q12092_dummy);
RegisterSpellScript(spell_q12096_q12092_bark);
RegisterCreatureAI(npc_wyrmrest_defender);
RegisterSpellScript(spell_dragonblight_warsong_battle_standard);
RegisterSpellScript(spell_dragonblight_moti_mirror_image_script_effect);
RegisterSpellScript(spell_dragonblight_moti_hourglass_cast_see_invis_on_master);
RegisterSpellScript(spell_dragonblight_call_out_injured_soldier);
RegisterSpellScript(spell_dragonblight_high_executor_branding_iron);
RegisterSpellScript(spell_dragonblight_cancel_banshees_magic_mirror);
RegisterSpellScript(spell_dragonblight_scarlet_raven_priest_image_master);
RegisterSpellScript(spell_dragonblight_cancel_scarlet_raven_priest_image);
RegisterSpellScript(spell_dragonblight_bombard_the_ballistae_fx_master);
RegisterSpellScript(spell_dragonblight_surge_needle_teleporter);
RegisterSpellScript(spell_dragonblight_fill_blood_unholy_frost_gem);
RegisterSpellScript(spell_dragonblight_corrosive_spit);
}