rendered paste body/* Copyright (C) 2006,2007 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../../../sc_defines.h"
#include "../../../../../../game/Player.h"
#include "../../../../../../game/Group.h"
#include "../../../../../../game/GossipDef.h"
#define GOSSIP_ITEM_BEGIN "We are ready to defend the Alliance base."
#define GOSSIP_ITEM_ANETHERON "The defenses are holding up; we can continue."
#define GOSSIP_ITEM_RETREAT "We can't keep this up. It's time to retreat."
// Trash Mobs summoned in waves
#define NECROMANCER 17899
#define ABOMINATION 17898
#define GHOUL 17895
#define BANSHEE 17905
#define CRYPT_FIEND 17897
#define GARGOYLE 17906
#define FROST_WYRM 17907
#define GIANT_INFERNAL 17908
#define FEL_STALKER 17916
// Bosses summoned after every 8 waves
#define RAGE_WINTERCHILL 17767
#define ANETHERON 17808
#define KAZROGAL 17888
#define AZGALOR 17842
#define ARCHIMONDE 17968
#define HORDEBASE_X 5464.5522
#define HORDEBASE_Y -2731.5644
#define HORDEBASE_Z 1485.7075
#define SPELL_TELEPORT_VISUAL 41232
struct Wave
{
uint32 Mob1, Mob2, Mob3, Mob4, Mob5, Mob6, Mob7, Mob8, Mob9, Mob10, Mob11, Mob12, Mob13, Mob14, Mob15, Mob16, Mob17, Mob18;
uint32 WaveTimer;
bool IsBoss;
};
static Wave AllianceWaves[]=
{
{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, 0, 0, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 1
{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 2
{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 3
{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 4
{GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 5
{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 120000, false}, // Wave 6
{GHOUL, GHOUL, GHOUL, GHOUL, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 7
{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 120000, false}, // Wave 8
{RAGE_WINTERCHILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true}, // All 8 Waves are summoned, summon Rage Winterchill, next few waves are for Anetheron
{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, 0, 0, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 1
{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 2
{GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 3
{GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 4
{CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, BANSHEE, BANSHEE, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 5
{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 6
{CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, BANSHEE, BANSHEE, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0, 120000, false}, // Wave 7
{GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, // Wave 8
{ANETHERON, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true} // All 8 Waves are summoned, summon Anatheron
};
struct Location
{
float x, y, z;
};
static Location AllianceBase[]=
{
{4979.010, -1709.134, 1339.674},
{4969.123, -1705.904, 1341.363},
{4970.260, -1698.546, 1341.200},
{4975.262, -1698.239, 1341.427}
};
struct MANGOS_DLL_DECL npc_jaina_proudmooreAI : public ScriptedAI
{
npc_jaina_proudmooreAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
SetVariables();
}
ScriptedInstance* pInstance;
uint64 PlayerGUID;
uint64 WinterchillGUID;
uint64 AnetheronGUID;
uint32 NextWaveTimer;
uint32 WaveCount;
uint32 CheckTimer;
bool EventBegun;
bool AllianceOverrun;
bool InCombat;
bool RageWinterchillDead;
bool AnetheronDead;
void SetVariables()
{
PlayerGUID = 0;
WinterchillGUID = 0;
AnetheronGUID = 0;
NextWaveTimer = 30000;
WaveCount = 0;
CheckTimer = 0;
EventBegun = false;
AllianceOverrun = false;
InCombat = false;
RageWinterchillDead = false;
AnetheronDead = false;
}
void EnterEvadeMode()
{
SetVariables();
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop();
DoGoHome();
}
void AttackStart(Unit *who)
{
if(!who)
return;
if(who->isTargetableForAttack() && who!= m_creature)
{
DoStartMeleeAttack(who);
if(!InCombat)
{
InCombat = true;
}
}
}
void MoveInLineOfSight(Unit *who)
{
if(who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
{
float attackRadius = m_creature->GetAttackDistance(who);
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
{
if(who->HasStealthAura())
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
if(who && who->isAlive())
m_creature->AddThreat(who, 1.0f);
if(!InCombat)
{
InCombat = true;
}
}
}
}
void SummonCreature(uint32 entry, bool IsBoss = true)
{
uint32 random = rand()%4;
float X = AllianceBase[random].x;
float Y = AllianceBase[random].y;
float Z = AllianceBase[random].z;
Creature* pCreature = m_creature->SummonCreature(entry, X, Y, Z, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
if(pCreature)
{
if(PlayerGUID)
{
Unit* pUnit = Unit::GetUnit((*m_creature), PlayerGUID);
if(pUnit)
pCreature->AddThreat(pUnit, 1.0f);
else pCreature->AddThreat(m_creature, 1.0f);
}else pCreature->AddThreat(m_creature, 1.0f);
if(IsBoss)
{
if(!RageWinterchillDead)
WinterchillGUID = pCreature->GetGUID();
else AnetheronGUID = pCreature->GetGUID();
}
}
}
void SummonNextWave(uint32 Wave)
{
if(AllianceWaves[Wave].IsBoss)
SummonCreature(AllianceWaves[Wave].Mob1, true);
if(AllianceWaves[Wave].Mob1 && (!AllianceWaves[Wave].IsBoss))
SummonCreature(AllianceWaves[Wave].Mob1);
if(AllianceWaves[Wave].Mob2)
SummonCreature(AllianceWaves[Wave].Mob2);
if(AllianceWaves[Wave].Mob3)
SummonCreature(AllianceWaves[Wave].Mob3);
if(AllianceWaves[Wave].Mob4)
SummonCreature(AllianceWaves[Wave].Mob4);
if(AllianceWaves[Wave].Mob5)
SummonCreature(AllianceWaves[Wave].Mob5);
if(AllianceWaves[Wave].Mob6)
SummonCreature(AllianceWaves[Wave].Mob6);
if(AllianceWaves[Wave].Mob7)
SummonCreature(AllianceWaves[Wave].Mob7);
if(AllianceWaves[Wave].Mob8)
SummonCreature(AllianceWaves[Wave].Mob8);
if(AllianceWaves[Wave].Mob9)
SummonCreature(AllianceWaves[Wave].Mob9);
if(AllianceWaves[Wave].Mob10)
SummonCreature(AllianceWaves[Wave].Mob10);
if(AllianceWaves[Wave].Mob11)
SummonCreature(AllianceWaves[Wave].Mob11);
if(AllianceWaves[Wave].Mob12)
SummonCreature(AllianceWaves[Wave].Mob12);
if(AllianceWaves[Wave].Mob13)
SummonCreature(AllianceWaves[Wave].Mob13);
if(AllianceWaves[Wave].Mob14)
SummonCreature(AllianceWaves[Wave].Mob14);
if(AllianceWaves[Wave].Mob15)
SummonCreature(AllianceWaves[Wave].Mob15);
if(AllianceWaves[Wave].Mob16)
SummonCreature(AllianceWaves[Wave].Mob16);
if(AllianceWaves[Wave].Mob17)
SummonCreature(AllianceWaves[Wave].Mob17);
if(AllianceWaves[Wave].Mob18)
SummonCreature(AllianceWaves[Wave].Mob18);
if(!AllianceWaves[Wave].IsBoss)
NextWaveTimer = AllianceWaves[Wave].WaveTimer;
else NextWaveTimer = 0;
}
void TeleportRaid(Player* player)
{
if(!player)
{
if(PlayerGUID)
{
player = ((Player*)Unit::GetUnit((*m_creature), PlayerGUID));
if(!player) return;
}else return;
}
Group* Raid = player->GetGroup();
if(Raid)
{
const Group::MemberSlotList list = Raid->GetMemberSlots();
Group::member_citerator itr = list.begin();
for( ; itr != list.end(); itr++)
{
Player* member = ((Player*)Unit::GetUnit((*m_creature), itr->guid));
if(member && member->isAlive())
{
member->CastSpell(member, SPELL_TELEPORT_VISUAL, true);
member->TeleportTo(m_creature->GetMapId(), HORDEBASE_X, HORDEBASE_Y, HORDEBASE_Z, member->GetOrientation());
}
}
}
}
void StartEvent(Player* player)
{
if(player)
{
EventBegun = true;
PlayerGUID = player->GetGUID();
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0);
}
}
void StartAnetheronPhase(Player* player)
{
if(player)
{
EventBegun = true;
PlayerGUID = player->GetGUID();
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0);
}
}
void UpdateAI(const uint32 diff)
{
if(!EventBegun) return;
if(NextWaveTimer)
{
if(NextWaveTimer < diff)
{
SummonNextWave(WaveCount);
WaveCount++;
}else NextWaveTimer -= diff;
}
if(CheckTimer < diff)
{
if(PlayerGUID)
{
Player* target = ((Player*)Unit::GetUnit((*m_creature), PlayerGUID));
if(target)
{
if(!target->isAlive())
{
Group* Raid = target->GetGroup();
if(Raid)
{
const Group::MemberSlotList list = Raid->GetMemberSlots();
Group::member_citerator itr = list.begin();
uint32 DeathCount = 0;
uint32 RaidCount = Raid->GetMembersCount();
for( ; itr != list.end(); itr++)
{
Player* member = ((Player*)Unit::GetUnit((*m_creature), itr->guid));
if(member && member->isAlive())
break;
else DeathCount++;
}
if(DeathCount == RaidCount)
{
EventBegun = false;
SetVariables();
EnterEvadeMode();
}
}
}
}
}
if(WinterchillGUID)
{
Unit* pUnit = Unit::GetUnit((*m_creature), WinterchillGUID);
if(pUnit && (!pUnit->isAlive()))
{
RageWinterchillDead = true;
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 1);
WinterchillGUID = 0;
}
}
if(AnetheronGUID)
{
Unit* pUnit = Unit::GetUnit((*m_creature), AnetheronGUID);
if(pUnit && (!pUnit->isAlive()))
{
AnetheronDead = true;
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 1);
AnetheronDead = 0;
}
}
CheckTimer = 15000;
}else CheckTimer -= diff;
}
};
bool GossipSelect_npc_jaina_proudmoore(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
switch(action)
{
case GOSSIP_ACTION_INFO_DEF + 1:
player->PlayerTalkClass->CloseGossip();
((npc_jaina_proudmooreAI*)_Creature->AI())->StartEvent(player);
break;
case GOSSIP_ACTION_INFO_DEF + 2:
player->PlayerTalkClass->CloseGossip();
((npc_jaina_proudmooreAI*)_Creature->AI())->StartAnetheronPhase(player);
break;
case GOSSIP_ACTION_INFO_DEF + 3:
player->PlayerTalkClass->CloseGossip();
((npc_jaina_proudmooreAI*)_Creature->AI())->TeleportRaid(player);
break;
}
return true;
}
bool GossipHello_npc_jaina_proudmoore(Player *player, Creature *_Creature)
{
if(player->isAlive())
{
if(!((npc_jaina_proudmooreAI*)_Creature->AI())->EventBegun)
{
if(((npc_jaina_proudmooreAI*)_Creature->AI())->RageWinterchillDead)
{
player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM_ANETHERON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
player->PlayerTalkClass->SendGossipMenu(907, _Creature->GetGUID());
}
else
{
player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM_BEGIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
player->PlayerTalkClass->SendGossipMenu(907, _Creature->GetGUID());
}
}
else
{
if(((npc_jaina_proudmooreAI*)_Creature->AI())->AnetheronDead)
{
player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM_RETREAT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
player->PlayerTalkClass->SendGossipMenu(907, _Creature->GetGUID());
}
}
}
return true;
}
CreatureAI* GetAI_npc_jaina_proudmoore(Creature* _Creature)
{
return new npc_jaina_proudmooreAI(_Creature);
}
void AddSC_npc_jaina_proudmoore()
{
Script *newscript;
newscript = new Script;
newscript->Name="npc_jaina_proudmoore";
newscript->GetAI = GetAI_npc_jaina_proudmoore;
newscript->pGossipHello = &GossipHello_npc_jaina_proudmoore;
newscript->pGossipSelect = &GossipSelect_npc_jaina_proudmoore;
m_scripts[nrscripts++] = newscript;
}