Files
TrinityCore/src/scripts/outland/shadowmoon_valley.cpp
Anubisss 08b4748e62 Use GUIDs instead of "global" pointers in zone scripts.
This commit is like that: 7714 / rce505237e4aa

And use const_iterators where it is possible.

--HG--
branch : trunk
2010-04-02 15:41:37 +02:00

1829 lines
57 KiB
C++

/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Shadowmoon_Valley
SD%Complete: 100
SDComment: Quest support: 10519, 10583, 10601, 10814, 10804, 10854, 10458, 10481, 10480, 11082, 10781, 10451. Vendor Drake Dealer Hurlunk.
SDCategory: Shadowmoon Valley
EndScriptData */
/* ContentData
mob_mature_netherwing_drake
mob_enslaved_netherwing_drake
npc_drake_dealer_hurlunk
npcs_flanis_swiftwing_and_kagrosh
npc_murkblood_overseer
npc_neltharaku
npc_karynaku
npc_oronok_tornheart
npc_overlord_morghor
npc_earthmender_wilda
mob_torloth_the_magnificent
mob_illidari_spawn
npc_lord_illidan_stormrage
go_crystal_prison
npc_enraged_spirit
EndContentData */
#include "ScriptedPch.h"
#include "ScriptedEscortAI.h"
/*#####
# mob_mature_netherwing_drake
#####*/
enum eMatureNetherwing
{
SAY_JUST_EATEN = -1000222,
SPELL_PLACE_CARCASS = 38439,
SPELL_JUST_EATEN = 38502,
SPELL_NETHER_BREATH = 38467,
POINT_ID = 1,
GO_CARCASS = 185155,
QUEST_KINDNESS = 10804,
NPC_EVENT_PINGER = 22131
};
struct mob_mature_netherwing_drakeAI : public ScriptedAI
{
mob_mature_netherwing_drakeAI(Creature* c) : ScriptedAI(c) { }
uint64 uiPlayerGUID;
bool bCanEat;
bool bIsEating;
uint32 EatTimer;
uint32 CastTimer;
void Reset()
{
uiPlayerGUID = 0;
bCanEat = false;
bIsEating = false;
EatTimer = 5000;
CastTimer = 5000;
}
void SpellHit(Unit* pCaster, SpellEntry const* pSpell)
{
if (bCanEat || bIsEating)
return;
if (pCaster->GetTypeId() == TYPEID_PLAYER && pSpell->Id == SPELL_PLACE_CARCASS && !m_creature->HasAura(SPELL_JUST_EATEN))
{
uiPlayerGUID = pCaster->GetGUID();
bCanEat = true;
}
}
void MovementInform(uint32 type, uint32 id)
{
if (type != POINT_MOTION_TYPE)
return;
if (id == POINT_ID)
{
bIsEating = true;
EatTimer = 7000;
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_ATTACKUNARMED);
}
}
void UpdateAI(const uint32 diff)
{
if (bCanEat || bIsEating)
{
if (EatTimer <= diff)
{
if (bCanEat && !bIsEating)
{
if (Unit* pUnit = Unit::GetUnit(*m_creature, uiPlayerGUID))
{
if (GameObject* pGo = pUnit->FindNearestGameObject(GO_CARCASS, 10))
{
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
m_creature->GetMotionMaster()->MovementExpired();
m_creature->GetMotionMaster()->MoveIdle();
m_creature->StopMoving();
m_creature->GetMotionMaster()->MovePoint(POINT_ID, pGo->GetPositionX(), pGo->GetPositionY(), pGo->GetPositionZ());
}
}
bCanEat = false;
}
else if (bIsEating)
{
DoCast(m_creature, SPELL_JUST_EATEN);
DoScriptText(SAY_JUST_EATEN, m_creature);
if (Player* pPlr = Unit::GetPlayer(uiPlayerGUID))
{
pPlr->KilledMonsterCredit(NPC_EVENT_PINGER, m_creature->GetGUID());
if (GameObject* pGo = pPlr->FindNearestGameObject(GO_CARCASS, 10))
pGo->Delete();
}
Reset();
m_creature->GetMotionMaster()->Clear();
}
}
else
EatTimer -= diff;
return;
}
if (!UpdateVictim())
return;
if (CastTimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_NETHER_BREATH);
CastTimer = 5000;
} else CastTimer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_mature_netherwing_drake(Creature* pCreature)
{
return new mob_mature_netherwing_drakeAI(pCreature);
}
/*###
# mob_enslaved_netherwing_drake
####*/
#define FACTION_DEFAULT 62
#define FACTION_FRIENDLY 1840 // Not sure if this is correct, it was taken off of Mordenai.
#define SPELL_HIT_FORCE_OF_NELTHARAKU 38762
#define SPELL_FORCE_OF_NELTHARAKU 38775
#define CREATURE_DRAGONMAW_SUBJUGATOR 21718
#define CREATURE_ESCAPE_DUMMY 22317
struct mob_enslaved_netherwing_drakeAI : public ScriptedAI
{
mob_enslaved_netherwing_drakeAI(Creature* c) : ScriptedAI(c)
{
PlayerGUID = 0;
Tapped = false;
Reset();
}
uint64 PlayerGUID;
uint32 FlyTimer;
bool Tapped;
void Reset()
{
if (!Tapped)
m_creature->setFaction(FACTION_DEFAULT);
FlyTimer = 10000;
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->SetVisibility(VISIBILITY_ON);
}
void SpellHit(Unit* caster, const SpellEntry* spell)
{
if (!caster)
return;
if (caster->GetTypeId() == TYPEID_PLAYER && spell->Id == SPELL_HIT_FORCE_OF_NELTHARAKU && !Tapped)
{
Tapped = true;
PlayerGUID = caster->GetGUID();
m_creature->setFaction(FACTION_FRIENDLY);
DoCast(caster, SPELL_FORCE_OF_NELTHARAKU, true);
Unit* Dragonmaw = me->FindNearestCreature(CREATURE_DRAGONMAW_SUBJUGATOR, 50);
if (Dragonmaw)
{
m_creature->AddThreat(Dragonmaw, 100000.0f);
AttackStart(Dragonmaw);
}
HostileReference* ref = m_creature->getThreatManager().getOnlineContainer().getReferenceByTarget(caster);
if (ref)
ref->removeReference();
}
}
void MovementInform(uint32 type, uint32 id)
{
if (type != POINT_MOTION_TYPE)
return;
if (id == 1)
{
if (PlayerGUID)
{
Unit* plr = Unit::GetUnit((*m_creature), PlayerGUID);
if (plr)
DoCast(plr, SPELL_FORCE_OF_NELTHARAKU, true);
PlayerGUID = 0;
}
m_creature->SetVisibility(VISIBILITY_OFF);
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
m_creature->RemoveCorpse();
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
{
if (Tapped)
if (FlyTimer <= diff)
{
Tapped = false;
if (PlayerGUID)
{
Player* plr = Unit::GetPlayer(PlayerGUID);
if (plr && plr->GetQuestStatus(10854) == QUEST_STATUS_INCOMPLETE)
{
DoCast(plr, SPELL_FORCE_OF_NELTHARAKU, true);
/*
float x,y,z;
m_creature->GetPosition(x,y,z);
float dx,dy,dz;
m_creature->GetRandomPoint(x, y, z, 20, dx, dy, dz);
dz += 20; // so it's in the air, not ground*/
Position pos;
if(Unit* EscapeDummy = me->FindNearestCreature(CREATURE_ESCAPE_DUMMY, 30))
EscapeDummy->GetPosition(&pos);
else
{
m_creature->GetRandomNearPosition(pos, 20);
pos.m_positionZ += 25;
}
m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->GetMotionMaster()->MovePoint(1, pos);
}
}
} else FlyTimer -= diff;
return;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_enslaved_netherwing_drake(Creature* pCreature)
{
return new mob_enslaved_netherwing_drakeAI(pCreature);
}
/*#####
# mob_dragonmaw_peon
#####*/
struct mob_dragonmaw_peonAI : public ScriptedAI
{
mob_dragonmaw_peonAI(Creature* c) : ScriptedAI(c) {}
uint64 PlayerGUID;
bool Tapped;
uint32 PoisonTimer;
void Reset()
{
PlayerGUID = 0;
Tapped = false;
PoisonTimer = 0;
}
void SpellHit(Unit* caster, const SpellEntry* spell)
{
if (!caster)
return;
if (caster->GetTypeId() == TYPEID_PLAYER && spell->Id == 40468 && !Tapped)
{
PlayerGUID = caster->GetGUID();
Tapped = true;
float x, y, z;
caster->GetClosePoint(x, y, z, m_creature->GetObjectSize());
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
m_creature->GetMotionMaster()->MovePoint(1, x, y, z);
}
}
void MovementInform(uint32 type, uint32 id)
{
if (type != POINT_MOTION_TYPE)
return;
if (id)
{
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_EAT);
PoisonTimer = 15000;
}
}
void UpdateAI(const uint32 diff)
{
if (PoisonTimer)
if (PoisonTimer <= diff)
{
if (PlayerGUID)
{
Player* plr = Unit::GetPlayer(PlayerGUID);
if (plr && plr->GetQuestStatus(11020) == QUEST_STATUS_INCOMPLETE)
plr->KilledMonsterCredit(23209, m_creature->GetGUID());
}
PoisonTimer = 0;
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
} else PoisonTimer -= diff;
}
};
CreatureAI* GetAI_mob_dragonmaw_peon(Creature* pCreature)
{
return new mob_dragonmaw_peonAI(pCreature);
}
/*######
## npc_drake_dealer_hurlunk
######*/
bool GossipHello_npc_drake_dealer_hurlunk(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isVendor() && pPlayer->GetReputationRank(1015) == REP_EXALTED)
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_drake_dealer_hurlunk(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
if (uiAction == GOSSIP_ACTION_TRADE)
pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
return true;
}
/*######
## npc_flanis_swiftwing_and_kagrosh
######*/
#define GOSSIP_HSK1 "Take Flanis's Pack"
#define GOSSIP_HSK2 "Take Kagrosh's Pack"
bool GossipHello_npcs_flanis_swiftwing_and_kagrosh(Player* pPlayer, Creature* pCreature)
{
if (pPlayer->GetQuestStatus(10583) == QUEST_STATUS_INCOMPLETE && !pPlayer->HasItemCount(30658,1,true))
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_HSK1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
if (pPlayer->GetQuestStatus(10601) == QUEST_STATUS_INCOMPLETE && !pPlayer->HasItemCount(30659,1,true))
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_HSK2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
bool GossipSelect_npcs_flanis_swiftwing_and_kagrosh(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
{
ItemPosCountVec dest;
uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 30658, 1, false);
if (msg == EQUIP_ERR_OK)
{
pPlayer->StoreNewItem(dest, 30658, 1, true);
pPlayer->PlayerTalkClass->ClearMenus();
}
}
if (uiAction == GOSSIP_ACTION_INFO_DEF+2)
{
ItemPosCountVec dest;
uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 30659, 1, false);
if (msg == EQUIP_ERR_OK)
{
pPlayer->StoreNewItem(dest, 30659, 1, true);
pPlayer->PlayerTalkClass->ClearMenus();
}
}
return true;
}
/*######
## npc_murkblood_overseer
######*/
#define QUEST_11082 11082
#define GOSSIP_HMO "I am here for you, overseer."
#define GOSSIP_SMO1 "How dare you question an overseer of the Dragonmaw!"
#define GOSSIP_SMO2 "Who speaks of me? What are you talking about, broken?"
#define GOSSIP_SMO3 "Continue please."
#define GOSSIP_SMO4 "Who are these bidders?"
#define GOSSIP_SMO5 "Well... yes."
bool GossipHello_npc_murkblood_overseer(Player* pPlayer, Creature* pCreature)
{
if (pPlayer->GetQuestStatus(QUEST_11082) == QUEST_STATUS_INCOMPLETE)
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_HMO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(10940, pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_murkblood_overseer(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch (uiAction)
{
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
//correct id not known
pPlayer->SEND_GOSSIP_MENU(10940, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
//correct id not known
pPlayer->SEND_GOSSIP_MENU(10940, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
//correct id not known
pPlayer->SEND_GOSSIP_MENU(10940, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
//correct id not known
pPlayer->SEND_GOSSIP_MENU(10940, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+5:
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
//correct id not known
pPlayer->SEND_GOSSIP_MENU(10940, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+6:
//correct id not known
pPlayer->SEND_GOSSIP_MENU(10940, pCreature->GetGUID());
pCreature->CastSpell(pPlayer,41121,false);
pPlayer->AreaExploredOrEventHappens(QUEST_11082);
break;
}
return true;
}
/*######
## npc_neltharaku
######*/
#define GOSSIP_HN "I am listening, dragon"
#define GOSSIP_SN1 "But you are dragons! How could orcs do this to you?"
#define GOSSIP_SN2 "Your mate?"
#define GOSSIP_SN3 "I have battled many beasts, dragon. I will help you."
bool GossipHello_npc_neltharaku(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->GetQuestStatus(10814) == QUEST_STATUS_INCOMPLETE)
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_HN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(10613, pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_neltharaku(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch (uiAction)
{
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_SN1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
pPlayer->SEND_GOSSIP_MENU(10614, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_SN2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
pPlayer->SEND_GOSSIP_MENU(10615, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_SN3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
pPlayer->SEND_GOSSIP_MENU(10616, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
pPlayer->CLOSE_GOSSIP_MENU();
pPlayer->AreaExploredOrEventHappens(10814);
break;
}
return true;
}
/*######
## npc_oronok
######*/
#define GOSSIP_ORONOK1 "I am ready to hear your story, Oronok."
#define GOSSIP_ORONOK2 "How do I find the cipher?"
#define GOSSIP_ORONOK3 "How do you know all of this?"
#define GOSSIP_ORONOK4 "Yet what? What is it, Oronok?"
#define GOSSIP_ORONOK5 "Continue, please."
#define GOSSIP_ORONOK6 "So what of the cipher now? And your boys?"
#define GOSSIP_ORONOK7 "I will find your boys and the cipher, Oronok."
bool GossipHello_npc_oronok_tornheart(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pCreature->isVendor())
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
if (pPlayer->GetQuestStatus(10519) == QUEST_STATUS_INCOMPLETE)
{
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
pPlayer->SEND_GOSSIP_MENU(10312, pCreature->GetGUID());
}else
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_oronok_tornheart(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch (uiAction)
{
case GOSSIP_ACTION_TRADE:
pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(10313, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
pPlayer->SEND_GOSSIP_MENU(10314, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
pPlayer->SEND_GOSSIP_MENU(10315, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
pPlayer->SEND_GOSSIP_MENU(10316, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
pPlayer->SEND_GOSSIP_MENU(10317, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+5:
pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
pPlayer->SEND_GOSSIP_MENU(10318, pCreature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+6:
pPlayer->CLOSE_GOSSIP_MENU();
pPlayer->AreaExploredOrEventHappens(10519);
break;
}
return true;
}
/*####
# npc_karynaku
####*/
enum eKarynaku
{
QUEST_ALLY_OF_NETHER = 10870,
TAXI_PATH_ID = 649
};
bool QuestAccept_npc_karynaku(Player* pPlayer, Creature* pCreature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_ALLY_OF_NETHER)
pPlayer->ActivateTaxiPathTo(TAXI_PATH_ID); //pPlayer->ActivateTaxiPathTo(649);
return true;
}
/*####
# npc_overlord_morghor
####*/
#define QUEST_LORD_ILLIDAN_STORMRAGE 11108
#define C_ILLIDAN 22083
#define C_YARZILL 23141
#define SPELL_ONE 39990 // Red Lightning Bolt
#define SPELL_TWO 41528 // Mark of Stormrage
#define SPELL_THREE 40216 // Dragonaw Faction
#define SPELL_FOUR 42016 // Dragonaw Trasform
#define OVERLORD_SAY_1 -1000206
#define OVERLORD_SAY_2 -1000207
#define OVERLORD_SAY_3 -1000208 //signed for 28315
#define OVERLORD_SAY_4 -1000209
#define OVERLORD_SAY_5 -1000210
#define OVERLORD_SAY_6 -1000211
#define OVERLORD_YELL_1 -1000212
#define OVERLORD_YELL_2 -1000213
#define LORD_ILLIDAN_SAY_1 -1000214
#define LORD_ILLIDAN_SAY_2 -1000215
#define LORD_ILLIDAN_SAY_3 -1000216
#define LORD_ILLIDAN_SAY_4 -1000217
#define LORD_ILLIDAN_SAY_5 -1000218
#define LORD_ILLIDAN_SAY_6 -1000219
#define LORD_ILLIDAN_SAY_7 -1000220
#define YARZILL_THE_MERC_SAY -1000221
struct npc_overlord_morghorAI : public ScriptedAI
{
npc_overlord_morghorAI(Creature *c) : ScriptedAI(c) {}
uint64 PlayerGUID;
uint64 IllidanGUID;
uint32 ConversationTimer;
uint32 Step;
bool Event;
void Reset()
{
PlayerGUID = 0;
IllidanGUID = 0;
ConversationTimer = 0;
Step = 0;
Event = false;
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 2);
}
void StartEvent()
{
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0);
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
Unit* Illidan = m_creature->SummonCreature(C_ILLIDAN, -5107.83, 602.584, 85.2393, 4.92598, TEMPSUMMON_CORPSE_DESPAWN, 0);
if (Illidan)
{
IllidanGUID = Illidan->GetGUID();
Illidan->SetVisibility(VISIBILITY_OFF);
}
if (PlayerGUID)
{
Player* pPlayer = Unit::GetPlayer(PlayerGUID);
if (pPlayer)
DoScriptText(OVERLORD_SAY_1, m_creature, pPlayer);
}
ConversationTimer = 4200;
Step = 0;
Event = true;
}
uint32 NextStep(uint32 Step)
{
Unit* plr = Unit::GetUnit((*m_creature), PlayerGUID);
Unit* Illi = Unit::GetUnit((*m_creature), IllidanGUID);
if (!plr || !Illi)
{
EnterEvadeMode();
return 0;
}
switch(Step)
{
case 0: return 0; break;
case 1: m_creature->GetMotionMaster()->MovePoint(0, -5104.41, 595.297, 85.6838); return 9000; break;
case 2: DoScriptText(OVERLORD_YELL_1, m_creature, plr); return 4500; break;
case 3: m_creature->SetInFront(plr); return 3200; break;
case 4: DoScriptText(OVERLORD_SAY_2, m_creature, plr); return 2000; break;
case 5: Illi->SetVisibility(VISIBILITY_ON);
Illi->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); return 350; break;
case 6:
Illi->CastSpell(Illi, SPELL_ONE, true);
Illi->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, IllidanGUID);
return 2000; break;
case 7: DoScriptText(OVERLORD_YELL_2, m_creature); return 4500; break;
case 8: m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 8); return 2500; break;
case 9: DoScriptText(OVERLORD_SAY_3, m_creature); return 6500; break;
case 10: DoScriptText(LORD_ILLIDAN_SAY_1, Illi); return 5000; break;
case 11: DoScriptText(OVERLORD_SAY_4, m_creature, plr); return 6000; break;
case 12: DoScriptText(LORD_ILLIDAN_SAY_2, Illi); return 5500; break;
case 13: DoScriptText(LORD_ILLIDAN_SAY_3, Illi); return 4000; break;
case 14: Illi->SetUInt64Value(UNIT_FIELD_TARGET, PlayerGUID); return 1500; break;
case 15: DoScriptText(LORD_ILLIDAN_SAY_4, Illi); return 1500; break;
case 16:
if (plr)
{
Illi->CastSpell(plr, SPELL_TWO, true);
plr->RemoveAurasDueToSpell(SPELL_THREE);
plr->RemoveAurasDueToSpell(SPELL_FOUR);
return 5000;
}else{
CAST_PLR(plr)->FailQuest(QUEST_LORD_ILLIDAN_STORMRAGE); Step = 30; return 100;
}
break;
case 17: DoScriptText(LORD_ILLIDAN_SAY_5, Illi); return 5000; break;
case 18: DoScriptText(LORD_ILLIDAN_SAY_6, Illi); return 5000; break;
case 19: DoScriptText(LORD_ILLIDAN_SAY_7, Illi); return 5000; break;
case 20:
Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
Illi->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
return 500; break;
case 21: DoScriptText(OVERLORD_SAY_5, m_creature); return 500; break;
case 22:
Illi->SetVisibility(VISIBILITY_OFF);
Illi->setDeathState(JUST_DIED);
return 1000; break;
case 23: m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0); return 2000; break;
case 24: m_creature->SetUInt64Value(UNIT_FIELD_TARGET, PlayerGUID); return 5000; break;
case 25: DoScriptText(OVERLORD_SAY_6, m_creature); return 2000; break;
case 26:
if (plr)
CAST_PLR(plr)->GroupEventHappens(QUEST_LORD_ILLIDAN_STORMRAGE, m_creature);
return 6000; break;
case 27:
{
Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50);
if (Yarzill)
Yarzill->SetUInt64Value(UNIT_FIELD_TARGET, PlayerGUID);
return 500; }
break;
case 28:
plr->RemoveAurasDueToSpell(SPELL_TWO);
plr->RemoveAurasDueToSpell(41519);
plr->CastSpell(plr, SPELL_THREE, true);
plr->CastSpell(plr, SPELL_FOUR, true);
return 1000; break;
case 29:
{
Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50);
if (Yarzill)
DoScriptText(YARZILL_THE_MERC_SAY, Yarzill, plr);
return 5000; }
break;
case 30:
{
Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50);
if (Yarzill)
Yarzill->SetUInt64Value(UNIT_FIELD_TARGET, 0);
return 5000; }
break;
case 31:
{
Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50);
if (Yarzill)
Yarzill->CastSpell(plr, 41540, true);
return 1000;}
break;
case 32: m_creature->GetMotionMaster()->MovePoint(0, -5085.77, 577.231, 86.6719); return 5000; break;
case 33: Reset(); return 100; break;
default : return 0;
}
}
void UpdateAI(const uint32 diff)
{
if (!ConversationTimer)
return;
if (ConversationTimer <= diff)
{
if (Event && IllidanGUID && PlayerGUID)
{
ConversationTimer = NextStep(++Step);
}
} else ConversationTimer -= diff;
}
};
CreatureAI* GetAI_npc_overlord_morghor(Creature* pCreature)
{
return new npc_overlord_morghorAI(pCreature);
}
bool QuestAccept_npc_overlord_morghor(Player* pPlayer, Creature* pCreature, const Quest *_Quest)
{
if (_Quest->GetQuestId() == QUEST_LORD_ILLIDAN_STORMRAGE)
{
CAST_AI(npc_overlord_morghorAI, pCreature->AI())->PlayerGUID = pPlayer->GetGUID();
CAST_AI(npc_overlord_morghorAI, pCreature->AI())->StartEvent();
return true;
}
return false;
}
/*####
# npc_earthmender_wilda
####*/
enum eEarthmender
{
SAY_WIL_START = -1000381,
SAY_WIL_AGGRO1 = -1000382,
SAY_WIL_AGGRO2 = -1000383,
SAY_WIL_PROGRESS1 = -1000384,
SAY_WIL_PROGRESS2 = -1000385,
SAY_WIL_FIND_EXIT = -1000386,
SAY_WIL_PROGRESS4 = -1000387,
SAY_WIL_PROGRESS5 = -1000388,
SAY_WIL_JUST_AHEAD = -1000389,
SAY_WIL_END = -1000390,
SPELL_CHAIN_LIGHTNING = 16006,
SPELL_EARTHBING_TOTEM = 15786,
SPELL_FROST_SHOCK = 12548,
SPELL_HEALING_WAVE = 12491,
QUEST_ESCAPE_COILSCAR = 10451,
NPC_COILSKAR_ASSASSIN = 21044,
FACTION_EARTHEN = 1726 //guessed
};
struct npc_earthmender_wildaAI : public npc_escortAI
{
npc_earthmender_wildaAI(Creature* pCreature) : npc_escortAI(pCreature) { }
uint32 m_uiHealingTimer;
void Reset()
{
m_uiHealingTimer = 0;
}
void WaypointReached(uint32 uiPointId)
{
Player* pPlayer = GetPlayerForEscort();
if (!pPlayer)
return;
switch(uiPointId)
{
case 13:
DoScriptText(SAY_WIL_PROGRESS1, m_creature, pPlayer);
DoSpawnAssassin();
break;
case 14:
DoSpawnAssassin();
break;
case 15:
DoScriptText(SAY_WIL_FIND_EXIT, m_creature, pPlayer);
break;
case 19:
DoRandomSay();
break;
case 20:
DoSpawnAssassin();
break;
case 26:
DoRandomSay();
break;
case 27:
DoSpawnAssassin();
break;
case 33:
DoRandomSay();
break;
case 34:
DoSpawnAssassin();
break;
case 37:
DoRandomSay();
break;
case 38:
DoSpawnAssassin();
break;
case 39:
DoScriptText(SAY_WIL_JUST_AHEAD, m_creature, pPlayer);
break;
case 43:
DoRandomSay();
break;
case 44:
DoSpawnAssassin();
break;
case 50:
DoScriptText(SAY_WIL_END, m_creature, pPlayer);
if (Player* pPlayer = GetPlayerForEscort())
pPlayer->GroupEventHappens(QUEST_ESCAPE_COILSCAR, m_creature);
break;
}
}
void JustSummoned(Creature* pSummoned)
{
if (pSummoned->GetEntry() == NPC_COILSKAR_ASSASSIN)
pSummoned->AI()->AttackStart(m_creature);
}
//this is very unclear, random say without no real relevance to script/event
void DoRandomSay()
{
DoScriptText(RAND(SAY_WIL_PROGRESS2,SAY_WIL_PROGRESS4,SAY_WIL_PROGRESS5), m_creature);
}
void DoSpawnAssassin()
{
//unknown where they actually appear
DoSummon(NPC_COILSKAR_ASSASSIN, me, 15.0f, 5000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT);
}
void Aggro(Unit* pWho)
{
//don't always use
if (rand()%5)
return;
//only aggro text if not player
if (pWho->GetTypeId() != TYPEID_PLAYER)
{
//appears to be random
if (urand(0,1))
DoScriptText(RAND(SAY_WIL_AGGRO1, SAY_WIL_AGGRO2), pWho);
}
}
void UpdateAI(const uint32 uiDiff)
{
npc_escortAI::UpdateAI(uiDiff);
if (!UpdateVictim())
return;
//TODO: add more abilities
if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 30)
{
if (m_uiHealingTimer <= uiDiff)
{
DoCast(m_creature, SPELL_HEALING_WAVE);
m_uiHealingTimer = 15000;
}
else
m_uiHealingTimer -= uiDiff;
}
}
};
CreatureAI* GetAI_npc_earthmender_wilda(Creature* pCreature)
{
return new npc_earthmender_wildaAI(pCreature);
}
bool QuestAccept_npc_earthmender_wilda(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
{
if (pQuest->GetQuestId() == QUEST_ESCAPE_COILSCAR)
{
DoScriptText(SAY_WIL_START, pCreature, pPlayer);
pCreature->setFaction(FACTION_EARTHEN);
if (npc_earthmender_wildaAI* pEscortAI = CAST_AI(npc_earthmender_wildaAI, pCreature->AI()))
pEscortAI->Start(false, false, pPlayer->GetGUID(), pQuest);
}
return true;
}
/*#####
# Quest: Battle of the crimson watch
#####*/
/* ContentData
Battle of the crimson watch - creatures, gameobjects and defines
mob_illidari_spawn : Adds that are summoned in the Crimson Watch battle.
mob_torloth_the_magnificent : Final Creature that players have to face before quest is completed
npc_lord_illidan_stormrage : Creature that controls the event.
go_crystal_prison : GameObject that begins the event and hands out quest
EndContentData */
#define END_TEXT -1000366 //signed for 10646
#define QUEST_BATTLE_OF_THE_CRIMSON_WATCH 10781
#define EVENT_AREA_RADIUS 65 //65yds
#define EVENT_COOLDOWN 30000 //in ms. appear after event completed or failed (should be = Adds despawn time)
struct TorlothCinematic
{
int32 TextId;
uint32 pCreature, Timer;
};
// Creature 0 - Torloth, 1 - Illidan
static TorlothCinematic TorlothAnim[]=
{
{-1000367, 0, 2000},
{-1000368, 1, 7000},
{-1000369, 0, 3000},
{NULL, 0, 2000}, // Torloth stand
{-1000370, 0, 1000},
{NULL, 0, 3000},
{NULL, 0, NULL}
};
struct Location
{
float x, y, z, o;
};
//Cordinates for Spawns
static Location SpawnLocation[]=
{
//Cords used for:
{-4615.8556, 1342.2532, 139.9, 1.612},//Illidari Soldier
{-4598.9365, 1377.3182, 139.9, 3.917},//Illidari Soldier
{-4598.4697, 1360.8999, 139.9, 2.427},//Illidari Soldier
{-4589.3599, 1369.1061, 139.9, 3.165},//Illidari Soldier
{-4608.3477, 1386.0076, 139.9, 4.108},//Illidari Soldier
{-4633.1889, 1359.8033, 139.9, 0.949},//Illidari Soldier
{-4623.5791, 1351.4574, 139.9, 0.971},//Illidari Soldier
{-4607.2988, 1351.6099, 139.9, 2.416},//Illidari Soldier
{-4633.7764, 1376.0417, 139.9, 5.608},//Illidari Soldier
{-4600.2461, 1369.1240, 139.9, 3.056},//Illidari Mind Breaker
{-4631.7808, 1367.9459, 139.9, 0.020},//Illidari Mind Breaker
{-4600.2461, 1369.1240, 139.9, 3.056},//Illidari Highlord
{-4631.7808, 1367.9459, 139.9, 0.020},//Illidari Highlord
{-4615.5586, 1353.0031, 139.9, 1.540},//Illidari Highlord
{-4616.4736, 1384.2170, 139.9, 4.971},//Illidari Highlord
{-4627.1240, 1378.8752, 139.9, 2.544} //Torloth The Magnificent
};
struct WaveData
{
uint8 SpawnCount, UsedSpawnPoint;
uint32 CreatureId, SpawnTimer,YellTimer;
int32 WaveTextId;
};
static WaveData WavesInfo[]=
{
{9, 0, 22075, 10000, 7000, -1000371}, //Illidari Soldier
{2, 9, 22074, 10000, 7000, -1000372}, //Illidari Mind Breaker
{4, 11, 19797, 10000, 7000, -1000373}, //Illidari Highlord
{1, 15, 22076, 10000, 7000, -1000374} //Torloth The Magnificent
};
struct SpawnSpells
{
uint32 Timer1, Timer2, SpellId;
};
static SpawnSpells SpawnCast[]=
{
{10000, 15000, 35871}, // Illidari Soldier Cast - Spellbreaker
{10000, 10000, 38985}, // Illidari Mind Breake Cast - Focused Bursts
{35000, 35000, 22884}, // Illidari Mind Breake Cast - Psychic Scream
{20000, 20000, 17194}, // Illidari Mind Breake Cast - Mind Blast
{8000, 15000, 38010}, // Illidari Highlord Cast - Curse of Flames
{12000, 20000, 16102}, // Illidari Highlord Cast - Flamestrike
{10000, 15000, 15284}, // Torloth the Magnificent Cast - Cleave
{18000, 20000, 39082}, // Torloth the Magnificent Cast - Shadowfury
{25000, 28000, 33961} // Torloth the Magnificent Cast - Spell Reflection
};
/*######
# mob_illidari_spawn
######*/
struct mob_illidari_spawnAI : public ScriptedAI
{
mob_illidari_spawnAI(Creature* c) : ScriptedAI(c) {}
uint64 LordIllidanGUID;
uint32 SpellTimer1, SpellTimer2, SpellTimer3;
bool Timers;
void Reset()
{
LordIllidanGUID = 0;
Timers = false;
}
void EnterCombat(Unit* who) {}
void JustDied(Unit* slayer);
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (!Timers)
{
if (m_creature->GetEntry() == 22075)//Illidari Soldier
{
SpellTimer1 = SpawnCast[0].Timer1 + (rand()%4 * 1000);
}
if (m_creature->GetEntry() == 22074)//Illidari Mind Breaker
{
SpellTimer1 = SpawnCast[1].Timer1 + (rand()%10 * 1000);
SpellTimer2 = SpawnCast[2].Timer1 + (rand()%4 * 1000);
SpellTimer3 = SpawnCast[3].Timer1 + (rand()%4 * 1000);
}
if (m_creature->GetEntry() == 19797)// Illidari Highlord
{
SpellTimer1 = SpawnCast[4].Timer1 + (rand()%4 * 1000);
SpellTimer2 = SpawnCast[5].Timer1 + (rand()%4 * 1000);
}
Timers = true;
}
//Illidari Soldier
if (m_creature->GetEntry() == 22075)
{
if (SpellTimer1 <= diff)
{
DoCast(m_creature->getVictim(), SpawnCast[0].SpellId);//Spellbreaker
SpellTimer1 = SpawnCast[0].Timer2 + (rand()%5 * 1000);
} else SpellTimer1 -= diff;
}
//Illidari Mind Breaker
if (m_creature->GetEntry() == 22074)
{
if (SpellTimer1 <= diff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
{
if (pTarget->GetTypeId() == TYPEID_PLAYER)
{
DoCast(pTarget, SpawnCast[1].SpellId); //Focused Bursts
SpellTimer1 = SpawnCast[1].Timer2 + (rand()%5 * 1000);
} else SpellTimer1 = 2000;
}
} else SpellTimer1 -= diff;
if (SpellTimer2 <= diff)
{
DoCast(m_creature->getVictim(), SpawnCast[2].SpellId);//Psychic Scream
SpellTimer2 = SpawnCast[2].Timer2 + (rand()%13 * 1000);
} else SpellTimer2 -= diff;
if (SpellTimer3 <= diff)
{
DoCast(m_creature->getVictim(), SpawnCast[3].SpellId);//Mind Blast
SpellTimer3 = SpawnCast[3].Timer2 + (rand()%8 * 1000);
} else SpellTimer3 -= diff;
}
//Illidari Highlord
if (m_creature->GetEntry() == 19797)
{
if (SpellTimer1 <= diff)
{
DoCast(m_creature->getVictim(), SpawnCast[4].SpellId);//Curse Of Flames
SpellTimer1 = SpawnCast[4].Timer2 + (rand()%10 * 1000);
} else SpellTimer1 -= diff;
if (SpellTimer2 <= diff)
{
DoCast(m_creature->getVictim(), SpawnCast[5].SpellId);//Flamestrike
SpellTimer2 = SpawnCast[5].Timer2 + (rand()%7 * 13000);
} else SpellTimer2 -= diff;
}
DoMeleeAttackIfReady();
}
};
/*######
# mob_torloth_the_magnificent
#####*/
struct mob_torloth_the_magnificentAI : public ScriptedAI
{
mob_torloth_the_magnificentAI(Creature* c) : ScriptedAI(c) {}
uint32 AnimationTimer, SpellTimer1, SpellTimer2, SpellTimer3;
uint8 AnimationCount;
uint64 LordIllidanGUID;
uint64 AggroTargetGUID;
bool Timers;
void Reset()
{
AnimationTimer = 4000;
AnimationCount = 0;
LordIllidanGUID = 0;
AggroTargetGUID = 0;
Timers = false;
m_creature->addUnitState(UNIT_STAT_ROOT);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
}
void EnterCombat(Unit* who){}
void HandleAnimation()
{
Creature* pCreature = m_creature;
if (TorlothAnim[AnimationCount].pCreature == 1)
{
pCreature = (Unit::GetCreature(*m_creature, LordIllidanGUID));
if (!pCreature)
return;
}
if (TorlothAnim[AnimationCount].TextId)
DoScriptText(TorlothAnim[AnimationCount].TextId, pCreature);
AnimationTimer = TorlothAnim[AnimationCount].Timer;
switch(AnimationCount)
{
case 0:
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,8);
break;
case 3:
m_creature->RemoveFlag(UNIT_FIELD_BYTES_1,8);
break;
case 5:
if (Player* AggroTarget = (Unit::GetPlayer(AggroTargetGUID)))
{
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, AggroTarget->GetGUID());
m_creature->AddThreat(AggroTarget, 1);
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
}
break;
case 6:
if (Player* AggroTarget = (Unit::GetPlayer(AggroTargetGUID)))
{
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->clearUnitState(UNIT_STAT_ROOT);
float x, y, z;
AggroTarget->GetPosition(x,y,z);
m_creature->GetMotionMaster()->MovePoint(0,x,y,z);
}
break;
}
++AnimationCount;
}
void UpdateAI(const uint32 diff)
{
if (AnimationTimer)
{
if (AnimationTimer <= diff)
{
HandleAnimation();
} else AnimationTimer -= diff;
}
if (AnimationCount < 6)
{
m_creature->CombatStop();
} else if (!Timers)
{
SpellTimer1 = SpawnCast[6].Timer1;
SpellTimer2 = SpawnCast[7].Timer1;
SpellTimer3 = SpawnCast[8].Timer1;
Timers = true;
}
if (Timers)
{
if (SpellTimer1 <= diff)
{
DoCast(m_creature->getVictim(), SpawnCast[6].SpellId);//Cleave
SpellTimer1 = SpawnCast[6].Timer2 + (rand()%10 * 1000);
} else SpellTimer1 -= diff;
if (SpellTimer2 <= diff)
{
DoCast(m_creature->getVictim(), SpawnCast[7].SpellId);//Shadowfury
SpellTimer2 = SpawnCast[7].Timer2 + (rand()%5 * 1000);
} else SpellTimer2 -= diff;
if (SpellTimer3 <= diff)
{
DoCast(m_creature, SpawnCast[8].SpellId);
SpellTimer3 = SpawnCast[8].Timer2 + (rand()%7 * 1000);//Spell Reflection
} else SpellTimer3 -= diff;
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* slayer)
{
if (slayer)
switch(slayer->GetTypeId())
{
case TYPEID_UNIT:
if (Unit *owner = slayer->GetOwner())
if (owner->GetTypeId() == TYPEID_PLAYER)
CAST_PLR(owner)->GroupEventHappens(QUEST_BATTLE_OF_THE_CRIMSON_WATCH, m_creature);
break;
case TYPEID_PLAYER:
CAST_PLR(slayer)->GroupEventHappens(QUEST_BATTLE_OF_THE_CRIMSON_WATCH, m_creature);
break;
}
if (Creature* LordIllidan = (Unit::GetCreature(*m_creature, LordIllidanGUID)))
{
DoScriptText(END_TEXT, LordIllidan, slayer);
LordIllidan->AI()->EnterEvadeMode();
}
}
};
/*#####
# npc_lord_illidan_stormrage
#####*/
struct npc_lord_illidan_stormrageAI : public ScriptedAI
{
npc_lord_illidan_stormrageAI(Creature* c) : ScriptedAI(c) {}
uint64 PlayerGUID;
uint32 WaveTimer;
uint32 AnnounceTimer;
int8 LiveCount;
uint8 WaveCount;
bool EventStarted;
bool Announced;
bool Failed;
void Reset()
{
PlayerGUID = 0;
WaveTimer = 10000;
AnnounceTimer = 7000;
LiveCount = 0;
WaveCount = 0;
EventStarted = false;
Announced = false;
Failed = false;
m_creature->SetVisibility(VISIBILITY_OFF);
}
void EnterCombat(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void AttackStart(Unit* who) {}
void SummonNextWave()
{
uint8 count = WavesInfo[WaveCount].SpawnCount;
uint8 locIndex = WavesInfo[WaveCount].UsedSpawnPoint;
srand(time(NULL));//initializing random seed
uint8 FelguardCount = 0;
uint8 DreadlordCount = 0;
for (uint8 i = 0; i < count; ++i)
{
Creature* Spawn = NULL;
float X = SpawnLocation[locIndex + i].x;
float Y = SpawnLocation[locIndex + i].y;
float Z = SpawnLocation[locIndex + i].z;
float O = SpawnLocation[locIndex + i].o;
Spawn = m_creature->SummonCreature(WavesInfo[WaveCount].CreatureId, X, Y, Z, O, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
++LiveCount;
if (Spawn)
{
Spawn->LoadCreaturesAddon();
if (WaveCount == 0)//1 Wave
{
if (rand()%3 == 1 && FelguardCount<2)
{
Spawn->SetDisplayId(18654);
++FelguardCount;
}
else if (DreadlordCount < 3)
{
Spawn->SetDisplayId(19991);
++DreadlordCount;
}
else if (FelguardCount<2)
{
Spawn->SetDisplayId(18654);
++FelguardCount;
}
}
if (WaveCount < 3)//1-3 Wave
{
if (PlayerGUID)
{
if (Player* pTarget = Unit::GetPlayer(PlayerGUID))
{
float x, y, z;
pTarget->GetPosition(x,y,z);
Spawn->GetMotionMaster()->MovePoint(0,x, y, z);
}
}
CAST_AI(mob_illidari_spawnAI, Spawn->AI())->LordIllidanGUID = m_creature->GetGUID();
}
if (WavesInfo[WaveCount].CreatureId == 22076) // Torloth
{
CAST_AI(mob_torloth_the_magnificentAI, Spawn->AI())->LordIllidanGUID = m_creature->GetGUID();
if (PlayerGUID)
CAST_AI(mob_torloth_the_magnificentAI, Spawn->AI())->AggroTargetGUID = PlayerGUID;
}
}
}
++WaveCount;
WaveTimer = WavesInfo[WaveCount].SpawnTimer;
AnnounceTimer = WavesInfo[WaveCount].YellTimer;
}
void CheckEventFail()
{
Player* pPlayer = Unit::GetPlayer(PlayerGUID);
if (!pPlayer)
return;
if (Group *EventGroup = pPlayer->GetGroup())
{
Player* GroupMember;
uint8 GroupMemberCount = 0;
uint8 DeadMemberCount = 0;
uint8 FailedMemberCount = 0;
const Group::MemberSlotList members = EventGroup->GetMemberSlots();
for (Group::member_citerator itr = members.begin(); itr!= members.end(); ++itr)
{
GroupMember = (Unit::GetPlayer(itr->guid));
if (!GroupMember)
continue;
if (!GroupMember->IsWithinDistInMap(m_creature, EVENT_AREA_RADIUS) && GroupMember->GetQuestStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH) == QUEST_STATUS_INCOMPLETE)
{
GroupMember->FailQuest(QUEST_BATTLE_OF_THE_CRIMSON_WATCH);
GroupMember->SetQuestStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH, QUEST_STATUS_NONE);
++FailedMemberCount;
}
++GroupMemberCount;
if (GroupMember->isDead())
{
++DeadMemberCount;
}
}
if (GroupMemberCount == FailedMemberCount)
{
Failed = true;
}
if (GroupMemberCount == DeadMemberCount)
{
for (Group::member_citerator itr = members.begin(); itr!= members.end(); ++itr)
{
GroupMember = Unit::GetPlayer(itr->guid);
if (GroupMember && GroupMember->GetQuestStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH) == QUEST_STATUS_INCOMPLETE)
{
GroupMember->FailQuest(QUEST_BATTLE_OF_THE_CRIMSON_WATCH);
GroupMember->SetQuestStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH, QUEST_STATUS_NONE);
}
}
Failed = true;
}
} else if (pPlayer->isDead() || !pPlayer->IsWithinDistInMap(m_creature, EVENT_AREA_RADIUS))
{
pPlayer->FailQuest(QUEST_BATTLE_OF_THE_CRIMSON_WATCH);
Failed = true;
}
}
void LiveCounter()
{
--LiveCount;
if (!LiveCount)
Announced = false;
}
void UpdateAI(const uint32 diff)
{
if (!PlayerGUID || !EventStarted)
return;
if (!LiveCount && WaveCount < 4)
{
if (!Announced && AnnounceTimer <= diff)
{
DoScriptText(WavesInfo[WaveCount].WaveTextId, m_creature);
Announced = true;
} else AnnounceTimer -= diff;
if (WaveTimer <= diff)
{
SummonNextWave();
} else WaveTimer -= diff;
}
CheckEventFail();
if (Failed)
EnterEvadeMode();
}
};
void mob_illidari_spawnAI::JustDied(Unit *slayer)
{
m_creature->RemoveCorpse();
if (Creature* LordIllidan = (Unit::GetCreature(*m_creature, LordIllidanGUID)))
if (LordIllidan)
CAST_AI(npc_lord_illidan_stormrageAI, LordIllidan->AI())->LiveCounter();
}
/*#####
# go_crystal_prison
######*/
bool GOQuestAccept_GO_crystal_prison(Player* plr, GameObject* go, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_BATTLE_OF_THE_CRIMSON_WATCH)
{
Creature* Illidan = plr->FindNearestCreature(22083, 50);
if (Illidan && !CAST_AI(npc_lord_illidan_stormrageAI, Illidan->AI())->EventStarted)
{
CAST_AI(npc_lord_illidan_stormrageAI, Illidan->AI())->PlayerGUID = plr->GetGUID();
CAST_AI(npc_lord_illidan_stormrageAI, Illidan->AI())->LiveCount = 0;
CAST_AI(npc_lord_illidan_stormrageAI, Illidan->AI())->EventStarted=true;
}
}
return true;
}
CreatureAI* GetAI_npc_lord_illidan_stormrage(Creature* c)
{
return new npc_lord_illidan_stormrageAI(c);
}
CreatureAI* GetAI_mob_illidari_spawn(Creature* c)
{
return new mob_illidari_spawnAI(c);
}
CreatureAI* GetAI_mob_torloth_the_magnificent(Creature* c)
{
return new mob_torloth_the_magnificentAI(c);
}
/*####
# npc_enraged_spirits
####*/
/* QUESTS */
#define QUEST_ENRAGED_SPIRITS_FIRE_EARTH 10458
#define QUEST_ENRAGED_SPIRITS_AIR 10481
#define QUEST_ENRAGED_SPIRITS_WATER 10480
/* Totem */
#define ENTRY_TOTEM_OF_SPIRITS 21071
#define RADIUS_TOTEM_OF_SPIRITS 15
/* SPIRITS */
#define ENTRY_ENRAGED_EARTH_SPIRIT 21050
#define ENTRY_ENRAGED_FIRE_SPIRIT 21061
#define ENTRY_ENRAGED_AIR_SPIRIT 21060
#define ENTRY_ENRAGED_WATER_SPIRIT 21059
/* SOULS */
#define ENTRY_EARTHEN_SOUL 21073
#define ENTRY_FIERY_SOUL 21097
#define ENTRY_ENRAGED_AIRY_SOUL 21116
#define ENTRY_ENRAGED_WATERY_SOUL 21109 // wrong model
/* SPELL KILLCREDIT - not working!?! - using KilledMonsterCredit */
#define SPELL_EARTHEN_SOUL_CAPTURED_CREDIT 36108
#define SPELL_FIERY_SOUL_CAPTURED_CREDIT 36117
#define SPELL_AIRY_SOUL_CAPTURED_CREDIT 36182
#define SPELL_WATERY_SOUL_CAPTURED_CREDIT 36171
/* KilledMonsterCredit Workaround */
#define CREDIT_FIRE 21094
#define CREDIT_WATER 21095
#define CREDIT_AIR 21096
#define CREDIT_EARTH 21092
/* Captured Spell/Buff */
#define SPELL_SOUL_CAPTURED 36115
/* Factions */
#define ENRAGED_SOUL_FRIENDLY 35
#define ENRAGED_SOUL_HOSTILE 14
struct npc_enraged_spiritAI : public ScriptedAI
{
npc_enraged_spiritAI(Creature *c) : ScriptedAI(c) {}
void Reset() { }
void EnterCombat(Unit *who){}
void JustDied(Unit* killer)
{
// always spawn spirit on death
// if totem around
// move spirit to totem and cast kill count
uint32 entry = 0;
uint32 credit = 0;
switch(m_creature->GetEntry()) {
case ENTRY_ENRAGED_FIRE_SPIRIT:
entry = ENTRY_FIERY_SOUL;
//credit = SPELL_FIERY_SOUL_CAPTURED_CREDIT;
credit = CREDIT_FIRE;
break;
case ENTRY_ENRAGED_EARTH_SPIRIT:
entry = ENTRY_EARTHEN_SOUL;
//credit = SPELL_EARTHEN_SOUL_CAPTURED_CREDIT;
credit = CREDIT_EARTH;
break;
case ENTRY_ENRAGED_AIR_SPIRIT:
entry = ENTRY_ENRAGED_AIRY_SOUL;
//credit = SPELL_AIRY_SOUL_CAPTURED_CREDIT;
credit = CREDIT_AIR;
break;
case ENTRY_ENRAGED_WATER_SPIRIT:
entry = ENTRY_ENRAGED_WATERY_SOUL;
//credit = SPELL_WATERY_SOUL_CAPTURED_CREDIT;
credit = CREDIT_WATER;
break;
}
// Spawn Soul on Kill ALWAYS!
Creature* Summoned = NULL;
Unit* totemOspirits = NULL;
if (entry != 0)
Summoned = DoSpawnCreature(entry, 0, 0, 1, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000);
// FIND TOTEM, PROCESS QUEST
if (Summoned)
{
totemOspirits = me->FindNearestCreature(ENTRY_TOTEM_OF_SPIRITS, RADIUS_TOTEM_OF_SPIRITS);
if (totemOspirits)
{
Summoned->setFaction(ENRAGED_SOUL_FRIENDLY);
Summoned->GetMotionMaster()->MovePoint(0,totemOspirits->GetPositionX(), totemOspirits->GetPositionY(), Summoned->GetPositionZ());
Unit* Owner = totemOspirits->GetOwner();
if (Owner && Owner->GetTypeId() == TYPEID_PLAYER)
// DoCast(Owner, credit); -- not working!
CAST_PLR(Owner)->KilledMonsterCredit(credit, Summoned->GetGUID());
DoCast(totemOspirits, SPELL_SOUL_CAPTURED);
}
}
}
};
CreatureAI* GetAI_npc_enraged_spirit(Creature* pCreature)
{
return new npc_enraged_spiritAI(pCreature);
}
/*#####
#
######*/
void AddSC_shadowmoon_valley()
{
Script *newscript;
newscript = new Script;
newscript->Name = "mob_mature_netherwing_drake";
newscript->GetAI = &GetAI_mob_mature_netherwing_drake;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_enslaved_netherwing_drake";
newscript->GetAI = &GetAI_mob_enslaved_netherwing_drake;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_dragonmaw_peon";
newscript->GetAI = &GetAI_mob_dragonmaw_peon;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_drake_dealer_hurlunk";
newscript->pGossipHello = &GossipHello_npc_drake_dealer_hurlunk;
newscript->pGossipSelect = &GossipSelect_npc_drake_dealer_hurlunk;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npcs_flanis_swiftwing_and_kagrosh";
newscript->pGossipHello = &GossipHello_npcs_flanis_swiftwing_and_kagrosh;
newscript->pGossipSelect = &GossipSelect_npcs_flanis_swiftwing_and_kagrosh;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_murkblood_overseer";
newscript->pGossipHello = &GossipHello_npc_murkblood_overseer;
newscript->pGossipSelect = &GossipSelect_npc_murkblood_overseer;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_neltharaku";
newscript->pGossipHello = &GossipHello_npc_neltharaku;
newscript->pGossipSelect = &GossipSelect_npc_neltharaku;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_karynaku";
newscript->pQuestAccept = &QuestAccept_npc_karynaku;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_oronok_tornheart";
newscript->pGossipHello = &GossipHello_npc_oronok_tornheart;
newscript->pGossipSelect = &GossipSelect_npc_oronok_tornheart;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_overlord_morghor";
newscript->GetAI = &GetAI_npc_overlord_morghor;
newscript->pQuestAccept = &QuestAccept_npc_overlord_morghor;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_earthmender_wilda";
newscript->GetAI = &GetAI_npc_earthmender_wilda;
newscript->pQuestAccept = &QuestAccept_npc_earthmender_wilda;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_lord_illidan_stormrage";
newscript->GetAI = &GetAI_npc_lord_illidan_stormrage;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "go_crystal_prison";
newscript->pGOQuestAccept = &GOQuestAccept_GO_crystal_prison;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_illidari_spawn";
newscript->GetAI = &GetAI_mob_illidari_spawn;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_torloth_the_magnificent";
newscript->GetAI = &GetAI_mob_torloth_the_magnificent;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_enraged_spirit";
newscript->GetAI = &GetAI_npc_enraged_spirit;
newscript->RegisterSelf();
}