mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-05 12:03:48 +00:00
Big re-organization of repository [W.I.P]
This commit is contained in:
@@ -1,340 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_kri, boss_yauj, boss_vem : The Bug Trio
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CLEAVE = 26350,
|
||||
SPELL_TOXIC_VOLLEY = 25812,
|
||||
SPELL_POISON_CLOUD = 38718, //Only Spell with right dmg.
|
||||
SPELL_ENRAGE = 34624, //Changed cause 25790 is cast on gamers too. Same prob with old explosion of twin emperors.
|
||||
|
||||
SPELL_CHARGE = 26561,
|
||||
SPELL_KNOCKBACK = 26027,
|
||||
|
||||
SPELL_HEAL = 25807,
|
||||
SPELL_FEAR = 19408
|
||||
};
|
||||
|
||||
class boss_kri : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kri() : CreatureScript("boss_kri") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_kriAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_kriAI : public ScriptedAI
|
||||
{
|
||||
boss_kriAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Cleave_Timer;
|
||||
uint32 ToxicVolley_Timer;
|
||||
uint32 Check_Timer;
|
||||
|
||||
bool VemDead;
|
||||
bool Death;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Cleave_Timer = urand(4000, 8000);
|
||||
ToxicVolley_Timer = urand(6000, 12000);
|
||||
Check_Timer = 2000;
|
||||
|
||||
VemDead = false;
|
||||
Death = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
|
||||
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||
|
||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
||||
}
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Cleave_Timer
|
||||
if (Cleave_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
Cleave_Timer = urand(5000, 12000);
|
||||
} else Cleave_Timer -= diff;
|
||||
|
||||
//ToxicVolley_Timer
|
||||
if (ToxicVolley_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_TOXIC_VOLLEY);
|
||||
ToxicVolley_Timer = urand(10000, 15000);
|
||||
} else ToxicVolley_Timer -= diff;
|
||||
|
||||
if (!HealthAbovePct(5) && !Death)
|
||||
{
|
||||
DoCastVictim(SPELL_POISON_CLOUD);
|
||||
Death = true;
|
||||
}
|
||||
|
||||
if (!VemDead)
|
||||
{
|
||||
//Checking if Vem is dead. If yes we will enrage.
|
||||
if (Check_Timer <= diff)
|
||||
{
|
||||
if (instance->GetData(DATA_VEMISDEAD))
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
VemDead = true;
|
||||
}
|
||||
Check_Timer = 2000;
|
||||
} else Check_Timer -=diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class boss_vem : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_vem() : CreatureScript("boss_vem") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_vemAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_vemAI : public ScriptedAI
|
||||
{
|
||||
boss_vemAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Charge_Timer;
|
||||
uint32 KnockBack_Timer;
|
||||
uint32 Enrage_Timer;
|
||||
|
||||
bool Enraged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Charge_Timer = urand(15000, 27000);
|
||||
KnockBack_Timer = urand(8000, 20000);
|
||||
Enrage_Timer = 120000;
|
||||
|
||||
Enraged = false;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
instance->SetData(DATA_VEM_DEATH, 0);
|
||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
|
||||
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Charge_Timer
|
||||
if (Charge_Timer <= diff)
|
||||
{
|
||||
Unit* target = NULL;
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 0);
|
||||
if (target)
|
||||
{
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
//me->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, true, 1);
|
||||
AttackStart(target);
|
||||
}
|
||||
|
||||
Charge_Timer = urand(8000, 16000);
|
||||
} else Charge_Timer -= diff;
|
||||
|
||||
//KnockBack_Timer
|
||||
if (KnockBack_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_KNOCKBACK);
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
DoModifyThreatPercent(me->GetVictim(), -80);
|
||||
KnockBack_Timer = urand(15000, 25000);
|
||||
} else KnockBack_Timer -= diff;
|
||||
|
||||
//Enrage_Timer
|
||||
if (!Enraged && Enrage_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
Enraged = true;
|
||||
} else Charge_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class boss_yauj : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_yauj() : CreatureScript("boss_yauj") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_yaujAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_yaujAI : public ScriptedAI
|
||||
{
|
||||
boss_yaujAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Heal_Timer;
|
||||
uint32 Fear_Timer;
|
||||
uint32 Check_Timer;
|
||||
|
||||
bool VemDead;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Heal_Timer = urand(25000, 40000);
|
||||
Fear_Timer = urand(12000, 24000);
|
||||
Check_Timer = 2000;
|
||||
|
||||
VemDead = false;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
|
||||
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
||||
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (Creature* Summoned = me->SummonCreature(15621, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000))
|
||||
Summoned->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Fear_Timer
|
||||
if (Fear_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FEAR);
|
||||
DoResetThreat();
|
||||
Fear_Timer = 20000;
|
||||
} else Fear_Timer -= diff;
|
||||
|
||||
//Casting Heal to other twins or herself.
|
||||
if (Heal_Timer <= diff)
|
||||
{
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KRI)))
|
||||
DoCast(kri, SPELL_HEAL);
|
||||
break;
|
||||
case 1:
|
||||
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_VEM)))
|
||||
DoCast(vem, SPELL_HEAL);
|
||||
break;
|
||||
case 2:
|
||||
DoCast(me, SPELL_HEAL);
|
||||
break;
|
||||
}
|
||||
|
||||
Heal_Timer = 15000+rand()%15000;
|
||||
} else Heal_Timer -= diff;
|
||||
|
||||
//Checking if Vem is dead. If yes we will enrage.
|
||||
if (Check_Timer <= diff)
|
||||
{
|
||||
if (!VemDead)
|
||||
{
|
||||
if (instance->GetData(DATA_VEMISDEAD))
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
VemDead = true;
|
||||
}
|
||||
}
|
||||
Check_Timer = 2000;
|
||||
} else Check_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_bug_trio()
|
||||
{
|
||||
new boss_kri();
|
||||
new boss_vem();
|
||||
new boss_yauj();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Fankriss
|
||||
SD%Complete: 100
|
||||
SDComment: sound not implemented
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
#define SOUND_SENTENCE_YOU 8588
|
||||
#define SOUND_SERVE_TO 8589
|
||||
#define SOUND_LAWS 8590
|
||||
#define SOUND_TRESPASS 8591
|
||||
#define SOUND_WILL_BE 8592
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MORTAL_WOUND = 28467,
|
||||
SPELL_ROOT = 28858,
|
||||
|
||||
// Enrage for his spawns
|
||||
SPELL_ENRAGE = 28798
|
||||
};
|
||||
|
||||
class boss_fankriss : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_fankriss() : CreatureScript("boss_fankriss") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_fankrissAI(creature);
|
||||
}
|
||||
|
||||
struct boss_fankrissAI : public ScriptedAI
|
||||
{
|
||||
boss_fankrissAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 MortalWound_Timer;
|
||||
uint32 SpawnHatchlings_Timer;
|
||||
uint32 SpawnSpawns_Timer;
|
||||
int Rand;
|
||||
float RandX;
|
||||
float RandY;
|
||||
|
||||
Creature* Hatchling;
|
||||
Creature* Spawn;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
MortalWound_Timer = urand(10000, 15000);
|
||||
SpawnHatchlings_Timer = urand(6000, 12000);
|
||||
SpawnSpawns_Timer = urand(15000, 45000);
|
||||
}
|
||||
|
||||
void SummonSpawn(Unit* victim)
|
||||
{
|
||||
if (!victim)
|
||||
return;
|
||||
|
||||
Rand = 10 + (rand()%10);
|
||||
switch (rand()%2)
|
||||
{
|
||||
case 0: RandX = 0.0f - Rand; break;
|
||||
case 1: RandX = 0.0f + Rand; break;
|
||||
}
|
||||
|
||||
Rand = 10 + (rand()%10);
|
||||
switch (rand()%2)
|
||||
{
|
||||
case 0: RandY = 0.0f - Rand; break;
|
||||
case 1: RandY = 0.0f + Rand; break;
|
||||
}
|
||||
Rand = 0;
|
||||
Spawn = DoSpawnCreature(15630, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
if (Spawn)
|
||||
Spawn->AI()->AttackStart(victim);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//MortalWound_Timer
|
||||
if (MortalWound_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_MORTAL_WOUND);
|
||||
MortalWound_Timer = urand(10000, 20000);
|
||||
} else MortalWound_Timer -= diff;
|
||||
|
||||
//Summon 1-3 Spawns of Fankriss at random time.
|
||||
if (SpawnSpawns_Timer <= diff)
|
||||
{
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
break;
|
||||
case 1:
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
break;
|
||||
case 2:
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
break;
|
||||
}
|
||||
SpawnSpawns_Timer = urand(30000, 60000);
|
||||
} else SpawnSpawns_Timer -= diff;
|
||||
|
||||
// Teleporting Random Target to one of the three tunnels and spawn 4 hatchlings near the gamer.
|
||||
//We will only telport if fankriss has more than 3% of hp so teleported gamers can always loot.
|
||||
if (HealthAbovePct(3))
|
||||
{
|
||||
if (SpawnHatchlings_Timer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
|
||||
{
|
||||
DoCast(target, SPELL_ROOT);
|
||||
|
||||
if (DoGetThreat(target))
|
||||
DoModifyThreatPercent(target, -100);
|
||||
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
DoTeleportPlayer(target, -8106.0142f, 1289.2900f, -74.419533f, 5.112f);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
break;
|
||||
case 1:
|
||||
DoTeleportPlayer(target, -7990.135354f, 1155.1907f, -78.849319f, 2.608f);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
break;
|
||||
case 2:
|
||||
DoTeleportPlayer(target, -8159.7753f, 1127.9064f, -76.868660f, 0.675f);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SpawnHatchlings_Timer = urand(45000, 60000);
|
||||
} else SpawnHatchlings_Timer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_fankriss()
|
||||
{
|
||||
new boss_fankriss();
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Huhuran
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
enum Huhuran
|
||||
{
|
||||
EMOTE_FRENZY_KILL = 0,
|
||||
EMOTE_BERSERK = 1,
|
||||
|
||||
SPELL_FRENZY = 26051,
|
||||
SPELL_BERSERK = 26068,
|
||||
SPELL_POISONBOLT = 26052,
|
||||
SPELL_NOXIOUSPOISON = 26053,
|
||||
SPELL_WYVERNSTING = 26180,
|
||||
SPELL_ACIDSPIT = 26050
|
||||
};
|
||||
|
||||
class boss_huhuran : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_huhuran() : CreatureScript("boss_huhuran") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_huhuranAI(creature);
|
||||
}
|
||||
|
||||
struct boss_huhuranAI : public ScriptedAI
|
||||
{
|
||||
boss_huhuranAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 Frenzy_Timer;
|
||||
uint32 Wyvern_Timer;
|
||||
uint32 Spit_Timer;
|
||||
uint32 PoisonBolt_Timer;
|
||||
uint32 NoxiousPoison_Timer;
|
||||
uint32 FrenzyBack_Timer;
|
||||
|
||||
bool Frenzy;
|
||||
bool Berserk;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Frenzy_Timer = urand(25000, 35000);
|
||||
Wyvern_Timer = urand(18000, 28000);
|
||||
Spit_Timer = 8000;
|
||||
PoisonBolt_Timer = 4000;
|
||||
NoxiousPoison_Timer = urand(10000, 20000);
|
||||
FrenzyBack_Timer = 15000;
|
||||
|
||||
Frenzy = false;
|
||||
Berserk = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Frenzy_Timer
|
||||
if (!Frenzy && Frenzy_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_FRENZY);
|
||||
Talk(EMOTE_FRENZY_KILL);
|
||||
Frenzy = true;
|
||||
PoisonBolt_Timer = 3000;
|
||||
Frenzy_Timer = urand(25000, 35000);
|
||||
} else Frenzy_Timer -= diff;
|
||||
|
||||
// Wyvern Timer
|
||||
if (Wyvern_Timer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_WYVERNSTING);
|
||||
Wyvern_Timer = urand(15000, 32000);
|
||||
} else Wyvern_Timer -= diff;
|
||||
|
||||
//Spit Timer
|
||||
if (Spit_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_ACIDSPIT);
|
||||
Spit_Timer = urand(5000, 10000);
|
||||
} else Spit_Timer -= diff;
|
||||
|
||||
//NoxiousPoison_Timer
|
||||
if (NoxiousPoison_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_NOXIOUSPOISON);
|
||||
NoxiousPoison_Timer = urand(12000, 24000);
|
||||
} else NoxiousPoison_Timer -= diff;
|
||||
|
||||
//PoisonBolt only if frenzy or berserk
|
||||
if (Frenzy || Berserk)
|
||||
{
|
||||
if (PoisonBolt_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_POISONBOLT);
|
||||
PoisonBolt_Timer = 3000;
|
||||
} else PoisonBolt_Timer -= diff;
|
||||
}
|
||||
|
||||
//FrenzyBack_Timer
|
||||
if (Frenzy && FrenzyBack_Timer <= diff)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
Frenzy = false;
|
||||
FrenzyBack_Timer = 15000;
|
||||
} else FrenzyBack_Timer -= diff;
|
||||
|
||||
if (!Berserk && HealthBelowPct(31))
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
Talk(EMOTE_BERSERK);
|
||||
DoCast(me, SPELL_BERSERK);
|
||||
Berserk = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_huhuran()
|
||||
{
|
||||
new boss_huhuran();
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Ouro
|
||||
SD%Complete: 85
|
||||
SDComment: No model for submerging. Currently just invisible.
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SWEEP = 26103,
|
||||
SPELL_SANDBLAST = 26102,
|
||||
SPELL_GROUND_RUPTURE = 26100,
|
||||
SPELL_BIRTH = 26262, // The Birth Animation
|
||||
SPELL_DIRTMOUND_PASSIVE = 26092
|
||||
};
|
||||
|
||||
class boss_ouro : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_ouro() : CreatureScript("boss_ouro") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_ouroAI(creature);
|
||||
}
|
||||
|
||||
struct boss_ouroAI : public ScriptedAI
|
||||
{
|
||||
boss_ouroAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 Sweep_Timer;
|
||||
uint32 SandBlast_Timer;
|
||||
uint32 Submerge_Timer;
|
||||
uint32 Back_Timer;
|
||||
uint32 ChangeTarget_Timer;
|
||||
uint32 Spawn_Timer;
|
||||
|
||||
bool Enrage;
|
||||
bool Submerged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Sweep_Timer = urand(5000, 10000);
|
||||
SandBlast_Timer = urand(20000, 35000);
|
||||
Submerge_Timer = urand(90000, 150000);
|
||||
Back_Timer = urand(30000, 45000);
|
||||
ChangeTarget_Timer = urand(5000, 8000);
|
||||
Spawn_Timer = urand(10000, 20000);
|
||||
|
||||
Enrage = false;
|
||||
Submerged = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
DoCastVictim(SPELL_BIRTH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Sweep_Timer
|
||||
if (!Submerged && Sweep_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SWEEP);
|
||||
Sweep_Timer = urand(15000, 30000);
|
||||
} else Sweep_Timer -= diff;
|
||||
|
||||
//SandBlast_Timer
|
||||
if (!Submerged && SandBlast_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SANDBLAST);
|
||||
SandBlast_Timer = urand(20000, 35000);
|
||||
} else SandBlast_Timer -= diff;
|
||||
|
||||
//Submerge_Timer
|
||||
if (!Submerged && Submerge_Timer <= diff)
|
||||
{
|
||||
//Cast
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->setFaction(35);
|
||||
DoCast(me, SPELL_DIRTMOUND_PASSIVE);
|
||||
|
||||
Submerged = true;
|
||||
Back_Timer = urand(30000, 45000);
|
||||
} else Submerge_Timer -= diff;
|
||||
|
||||
//ChangeTarget_Timer
|
||||
if (Submerged && ChangeTarget_Timer <= diff)
|
||||
{
|
||||
Unit* target = NULL;
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 0);
|
||||
|
||||
if (target)
|
||||
me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), me->GetOrientation());
|
||||
|
||||
ChangeTarget_Timer = urand(10000, 20000);
|
||||
} else ChangeTarget_Timer -= diff;
|
||||
|
||||
//Back_Timer
|
||||
if (Submerged && Back_Timer <= diff)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->setFaction(14);
|
||||
|
||||
DoCastVictim(SPELL_GROUND_RUPTURE);
|
||||
|
||||
Submerged = false;
|
||||
Submerge_Timer = urand(60000, 120000);
|
||||
} else Back_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_ouro()
|
||||
{
|
||||
new boss_ouro();
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Sartura
|
||||
SD%Complete: 95
|
||||
SDComment:
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
enum Sartura
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2,
|
||||
|
||||
SPELL_WHIRLWIND = 26083,
|
||||
SPELL_ENRAGE = 28747, //Not sure if right ID.
|
||||
SPELL_ENRAGEHARD = 28798,
|
||||
|
||||
//Guard Spell
|
||||
SPELL_WHIRLWINDADD = 26038,
|
||||
SPELL_KNOCKBACK = 26027
|
||||
};
|
||||
|
||||
class boss_sartura : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_sartura() : CreatureScript("boss_sartura") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_sarturaAI(creature);
|
||||
}
|
||||
|
||||
struct boss_sarturaAI : public ScriptedAI
|
||||
{
|
||||
boss_sarturaAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 WhirlWind_Timer;
|
||||
uint32 WhirlWindRandom_Timer;
|
||||
uint32 WhirlWindEnd_Timer;
|
||||
uint32 AggroReset_Timer;
|
||||
uint32 AggroResetEnd_Timer;
|
||||
uint32 EnrageHard_Timer;
|
||||
|
||||
bool Enraged;
|
||||
bool EnragedHard;
|
||||
bool WhirlWind;
|
||||
bool AggroReset;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
WhirlWind_Timer = 30000;
|
||||
WhirlWindRandom_Timer = urand(3000, 7000);
|
||||
WhirlWindEnd_Timer = 15000;
|
||||
AggroReset_Timer = urand(45000, 55000);
|
||||
AggroResetEnd_Timer = 5000;
|
||||
EnrageHard_Timer = 10*60000;
|
||||
|
||||
WhirlWind = false;
|
||||
AggroReset = false;
|
||||
Enraged = false;
|
||||
EnragedHard = false;
|
||||
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (WhirlWind)
|
||||
{
|
||||
if (WhirlWindRandom_Timer <= diff)
|
||||
{
|
||||
//Attack random Gamers
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
WhirlWindRandom_Timer = urand(3000, 7000);
|
||||
} else WhirlWindRandom_Timer -= diff;
|
||||
|
||||
if (WhirlWindEnd_Timer <= diff)
|
||||
{
|
||||
WhirlWind = false;
|
||||
WhirlWind_Timer = urand(25000, 40000);
|
||||
} else WhirlWindEnd_Timer -= diff;
|
||||
}
|
||||
|
||||
if (!WhirlWind)
|
||||
{
|
||||
if (WhirlWind_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_WHIRLWIND);
|
||||
WhirlWind = true;
|
||||
WhirlWindEnd_Timer = 15000;
|
||||
} else WhirlWind_Timer -= diff;
|
||||
|
||||
if (AggroReset_Timer <= diff)
|
||||
{
|
||||
//Attack random Gamers
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
AggroReset = true;
|
||||
AggroReset_Timer = urand(2000, 5000);
|
||||
} else AggroReset_Timer -= diff;
|
||||
|
||||
if (AggroReset)
|
||||
{
|
||||
if (AggroResetEnd_Timer <= diff)
|
||||
{
|
||||
AggroReset = false;
|
||||
AggroResetEnd_Timer = 5000;
|
||||
AggroReset_Timer = urand(35000, 45000);
|
||||
} else AggroResetEnd_Timer -= diff;
|
||||
}
|
||||
|
||||
//If she is 20% enrage
|
||||
if (!Enraged)
|
||||
{
|
||||
if (!HealthAbovePct(20) && !me->IsNonMeleeSpellCast(false))
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
Enraged = true;
|
||||
}
|
||||
}
|
||||
|
||||
//After 10 minutes hard enrage
|
||||
if (!EnragedHard)
|
||||
{
|
||||
if (EnrageHard_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGEHARD);
|
||||
EnragedHard = true;
|
||||
} else EnrageHard_Timer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class npc_sartura_royal_guard : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_sartura_royal_guard() : CreatureScript("npc_sartura_royal_guard") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_sartura_royal_guardAI(creature);
|
||||
}
|
||||
|
||||
struct npc_sartura_royal_guardAI : public ScriptedAI
|
||||
{
|
||||
npc_sartura_royal_guardAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 WhirlWind_Timer;
|
||||
uint32 WhirlWindRandom_Timer;
|
||||
uint32 WhirlWindEnd_Timer;
|
||||
uint32 AggroReset_Timer;
|
||||
uint32 AggroResetEnd_Timer;
|
||||
uint32 KnockBack_Timer;
|
||||
|
||||
bool WhirlWind;
|
||||
bool AggroReset;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
WhirlWind_Timer = 30000;
|
||||
WhirlWindRandom_Timer = urand(3000, 7000);
|
||||
WhirlWindEnd_Timer = 15000;
|
||||
AggroReset_Timer = urand(45000, 55000);
|
||||
AggroResetEnd_Timer = 5000;
|
||||
KnockBack_Timer = 10000;
|
||||
|
||||
WhirlWind = false;
|
||||
AggroReset = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!WhirlWind && WhirlWind_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_WHIRLWINDADD);
|
||||
WhirlWind = true;
|
||||
WhirlWind_Timer = urand(25000, 40000);
|
||||
WhirlWindEnd_Timer = 15000;
|
||||
} else WhirlWind_Timer -= diff;
|
||||
|
||||
if (WhirlWind)
|
||||
{
|
||||
if (WhirlWindRandom_Timer <= diff)
|
||||
{
|
||||
//Attack random Gamers
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
|
||||
WhirlWindRandom_Timer = urand(3000, 7000);
|
||||
} else WhirlWindRandom_Timer -= diff;
|
||||
|
||||
if (WhirlWindEnd_Timer <= diff)
|
||||
{
|
||||
WhirlWind = false;
|
||||
} else WhirlWindEnd_Timer -= diff;
|
||||
}
|
||||
|
||||
if (!WhirlWind)
|
||||
{
|
||||
if (AggroReset_Timer <= diff)
|
||||
{
|
||||
//Attack random Gamers
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
|
||||
AggroReset = true;
|
||||
AggroReset_Timer = urand(2000, 5000);
|
||||
} else AggroReset_Timer -= diff;
|
||||
|
||||
if (KnockBack_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_WHIRLWINDADD);
|
||||
KnockBack_Timer = urand(10000, 20000);
|
||||
} else KnockBack_Timer -= diff;
|
||||
}
|
||||
|
||||
if (AggroReset)
|
||||
{
|
||||
if (AggroResetEnd_Timer <= diff)
|
||||
{
|
||||
AggroReset = false;
|
||||
AggroResetEnd_Timer = 5000;
|
||||
AggroReset_Timer = urand(30000, 40000);
|
||||
} else AggroResetEnd_Timer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_sartura()
|
||||
{
|
||||
new boss_sartura();
|
||||
new npc_sartura_royal_guard();
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_SPLIT = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_ARCANE_EXPLOSION = 26192,
|
||||
SPELL_EARTH_SHOCK = 26194,
|
||||
SPELL_TRUE_FULFILLMENT = 785,
|
||||
SPELL_INITIALIZE_IMAGE = 3730,
|
||||
SPELL_SUMMON_IMAGES = 747
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_ARCANE_EXPLOSION = 1,
|
||||
EVENT_FULLFILMENT = 2,
|
||||
EVENT_BLINK = 3,
|
||||
EVENT_EARTH_SHOCK = 4
|
||||
};
|
||||
|
||||
uint32 const BlinkSpells[3] = { 4801, 8195, 20449 };
|
||||
|
||||
class boss_skeram : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_skeram() : CreatureScript("boss_skeram") { }
|
||||
|
||||
struct boss_skeramAI : public BossAI
|
||||
{
|
||||
boss_skeramAI(Creature* creature) : BossAI(creature, DATA_SKERAM) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_flag = 0;
|
||||
_hpct = 75.0f;
|
||||
me->SetVisible(true);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
if (me->IsSummon())
|
||||
((TempSummon*)me)->UnSummon();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* creature)
|
||||
{
|
||||
// Shift the boss and images (Get it? *Shift*?)
|
||||
uint8 rand = 0;
|
||||
if (_flag != 0)
|
||||
{
|
||||
while (_flag & (1 << rand))
|
||||
rand = urand(0, 2);
|
||||
DoCast(me, BlinkSpells[rand]);
|
||||
_flag |= (1 << rand);
|
||||
_flag |= (1 << 7);
|
||||
}
|
||||
|
||||
while (_flag & (1 << rand))
|
||||
rand = urand(0, 2);
|
||||
creature->CastSpell(creature, BlinkSpells[rand]);
|
||||
_flag |= (1 << rand);
|
||||
|
||||
if (_flag & (1 << 7))
|
||||
_flag = 0;
|
||||
|
||||
if (Unit* Target = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
creature->AI()->AttackStart(Target);
|
||||
|
||||
float ImageHealthPct;
|
||||
|
||||
if (me->GetHealthPct() < 25.0f)
|
||||
ImageHealthPct = 0.50f;
|
||||
else if (me->GetHealthPct() < 50.0f)
|
||||
ImageHealthPct = 0.20f;
|
||||
else
|
||||
ImageHealthPct = 0.10f;
|
||||
|
||||
creature->SetMaxHealth(me->GetMaxHealth() * ImageHealthPct);
|
||||
creature->SetHealth(creature->GetMaxHealth() * (me->GetHealthPct() / 100.0f));
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (!me->IsSummon())
|
||||
Talk(SAY_DEATH);
|
||||
else
|
||||
me->RemoveCorpse();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.Reset();
|
||||
|
||||
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(6000, 12000));
|
||||
events.ScheduleEvent(EVENT_FULLFILMENT, 15000);
|
||||
events.ScheduleEvent(EVENT_BLINK, urand(30000, 45000));
|
||||
events.ScheduleEvent(EVENT_EARTH_SHOCK, 2000);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_ARCANE_EXPLOSION:
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION, true);
|
||||
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(8000, 18000));
|
||||
break;
|
||||
case EVENT_FULLFILMENT:
|
||||
/// @todo For some weird reason boss does not cast this
|
||||
// Spell actually works, tested in duel
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true), SPELL_TRUE_FULFILLMENT, true);
|
||||
events.ScheduleEvent(EVENT_FULLFILMENT, urand(20000, 30000));
|
||||
break;
|
||||
case EVENT_BLINK:
|
||||
DoCast(me, BlinkSpells[urand(0, 2)]);
|
||||
DoResetThreat();
|
||||
me->SetVisible(true);
|
||||
events.ScheduleEvent(EVENT_BLINK, urand(10000, 30000));
|
||||
break;
|
||||
case EVENT_EARTH_SHOCK:
|
||||
DoCastVictim(SPELL_EARTH_SHOCK);
|
||||
events.ScheduleEvent(EVENT_EARTH_SHOCK, 2000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!me->IsSummon() && me->GetHealthPct() < _hpct)
|
||||
{
|
||||
DoCast(me, SPELL_SUMMON_IMAGES);
|
||||
Talk(SAY_SPLIT);
|
||||
_hpct -= 25.0f;
|
||||
me->SetVisible(false);
|
||||
events.RescheduleEvent(EVENT_BLINK, 2000);
|
||||
}
|
||||
|
||||
if (me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
events.RescheduleEvent(EVENT_EARTH_SHOCK, 2000);
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
float _hpct;
|
||||
uint8 _flag;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_skeramAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_skeram_arcane_explosion : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_skeram_arcane_explosion() : SpellScriptLoader("spell_skeram_arcane_explosion") { }
|
||||
|
||||
class spell_skeram_arcane_explosion_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_skeram_arcane_explosion_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if(PlayerOrPetCheck());
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_skeram_arcane_explosion_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_skeram_arcane_explosion_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_skeram()
|
||||
{
|
||||
new boss_skeram();
|
||||
new spell_skeram_arcane_explosion();
|
||||
}
|
||||
@@ -1,594 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Twinemperors
|
||||
SD%Complete: 95
|
||||
SDComment:
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Item.h"
|
||||
#include "Spell.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_HEAL_BROTHER = 7393,
|
||||
SPELL_TWIN_TELEPORT = 800, // CTRA watches for this spell to start its teleport timer
|
||||
SPELL_TWIN_TELEPORT_VISUAL = 26638, // visual
|
||||
SPELL_EXPLODEBUG = 804,
|
||||
SPELL_MUTATE_BUG = 802,
|
||||
SPELL_BERSERK = 26662,
|
||||
SPELL_UPPERCUT = 26007,
|
||||
SPELL_UNBALANCING_STRIKE = 26613,
|
||||
SPELL_SHADOWBOLT = 26006,
|
||||
SPELL_BLIZZARD = 26607,
|
||||
SPELL_ARCANEBURST = 568,
|
||||
};
|
||||
|
||||
enum Sound
|
||||
{
|
||||
SOUND_VL_AGGRO = 8657, //8657 - Aggro - To Late
|
||||
SOUND_VL_KILL = 8658, //8658 - Kill - You will not
|
||||
SOUND_VL_DEATH = 8659, //8659 - Death
|
||||
SOUND_VN_DEATH = 8660, //8660 - Death - Feel
|
||||
SOUND_VN_AGGRO = 8661, //8661 - Aggro - Let none
|
||||
SOUND_VN_KILL = 8662, //8661 - Kill - your fate
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
PULL_RANGE = 50,
|
||||
ABUSE_BUG_RANGE = 20,
|
||||
VEKLOR_DIST = 20, // VL will not come to melee when attacking
|
||||
TELEPORTTIME = 30000
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct boss_twinemperorsAI : public ScriptedAI
|
||||
{
|
||||
boss_twinemperorsAI(Creature* creature): ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Heal_Timer;
|
||||
uint32 Teleport_Timer;
|
||||
bool AfterTeleport;
|
||||
uint32 AfterTeleportTimer;
|
||||
bool DontYellWhenDead;
|
||||
uint32 Abuse_Bug_Timer, BugsTimer;
|
||||
bool tspellcast;
|
||||
uint32 EnrageTimer;
|
||||
|
||||
virtual bool IAmVeklor() = 0;
|
||||
virtual void Reset() = 0;
|
||||
virtual void CastSpellOnBug(Creature* target) = 0;
|
||||
|
||||
void TwinReset()
|
||||
{
|
||||
Heal_Timer = 0; // first heal immediately when they get close together
|
||||
Teleport_Timer = TELEPORTTIME;
|
||||
AfterTeleport = false;
|
||||
tspellcast = false;
|
||||
AfterTeleportTimer = 0;
|
||||
Abuse_Bug_Timer = urand(10000, 17000);
|
||||
BugsTimer = 2000;
|
||||
me->ClearUnitState(UNIT_STATE_STUNNED);
|
||||
DontYellWhenDead = false;
|
||||
EnrageTimer = 15*60000;
|
||||
}
|
||||
|
||||
Creature* GetOtherBoss()
|
||||
{
|
||||
return ObjectAccessor::GetCreature(*me, instance->GetData64(IAmVeklor() ? DATA_VEKNILASH : DATA_VEKLOR));
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
Unit* pOtherBoss = GetOtherBoss();
|
||||
if (pOtherBoss)
|
||||
{
|
||||
float dPercent = ((float)damage) / ((float)me->GetMaxHealth());
|
||||
int odmg = (int)(dPercent * ((float)pOtherBoss->GetMaxHealth()));
|
||||
int ohealth = pOtherBoss->GetHealth()-odmg;
|
||||
pOtherBoss->SetHealth(ohealth > 0 ? ohealth : 0);
|
||||
if (ohealth <= 0)
|
||||
{
|
||||
pOtherBoss->setDeathState(JUST_DIED);
|
||||
pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Creature* pOtherBoss = GetOtherBoss();
|
||||
if (pOtherBoss)
|
||||
{
|
||||
pOtherBoss->SetHealth(0);
|
||||
pOtherBoss->setDeathState(JUST_DIED);
|
||||
pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||
CAST_AI(boss_twinemperorsAI, pOtherBoss->AI())->DontYellWhenDead = true;
|
||||
}
|
||||
if (!DontYellWhenDead) // I hope AI is not threaded
|
||||
DoPlaySoundToSet(me, IAmVeklor() ? SOUND_VL_DEATH : SOUND_VN_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
DoPlaySoundToSet(me, IAmVeklor() ? SOUND_VL_KILL : SOUND_VN_KILL);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoZoneInCombat();
|
||||
Creature* pOtherBoss = GetOtherBoss();
|
||||
if (pOtherBoss)
|
||||
{
|
||||
/// @todo we should activate the other boss location so he can start attackning even if nobody
|
||||
// is near I dont know how to do that
|
||||
ScriptedAI* otherAI = CAST_AI(ScriptedAI, pOtherBoss->AI());
|
||||
if (!pOtherBoss->IsInCombat())
|
||||
{
|
||||
DoPlaySoundToSet(me, IAmVeklor() ? SOUND_VL_AGGRO : SOUND_VN_AGGRO);
|
||||
otherAI->AttackStart(who);
|
||||
otherAI->DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellInfo* entry)
|
||||
{
|
||||
if (caster == me)
|
||||
return;
|
||||
|
||||
Creature* pOtherBoss = GetOtherBoss();
|
||||
if (entry->Id != SPELL_HEAL_BROTHER || !pOtherBoss)
|
||||
return;
|
||||
|
||||
// add health so we keep same percentage for both brothers
|
||||
uint32 mytotal = me->GetMaxHealth(), histotal = pOtherBoss->GetMaxHealth();
|
||||
float mult = ((float)mytotal) / ((float)histotal);
|
||||
if (mult < 1)
|
||||
mult = 1.0f/mult;
|
||||
#define HEAL_BROTHER_AMOUNT 30000.0f
|
||||
uint32 largerAmount = (uint32)((HEAL_BROTHER_AMOUNT * mult) - HEAL_BROTHER_AMOUNT);
|
||||
|
||||
if (mytotal > histotal)
|
||||
{
|
||||
uint32 h = me->GetHealth()+largerAmount;
|
||||
me->SetHealth(std::min(mytotal, h));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 h = pOtherBoss->GetHealth()+largerAmount;
|
||||
pOtherBoss->SetHealth(std::min(histotal, h));
|
||||
}
|
||||
}
|
||||
|
||||
void TryHealBrother(uint32 diff)
|
||||
{
|
||||
if (IAmVeklor()) // this spell heals caster and the other brother so let VN cast it
|
||||
return;
|
||||
|
||||
if (Heal_Timer <= diff)
|
||||
{
|
||||
Unit* pOtherBoss = GetOtherBoss();
|
||||
if (pOtherBoss && pOtherBoss->IsWithinDist(me, 60))
|
||||
{
|
||||
DoCast(pOtherBoss, SPELL_HEAL_BROTHER);
|
||||
Heal_Timer = 1000;
|
||||
}
|
||||
} else Heal_Timer -= diff;
|
||||
}
|
||||
|
||||
void TeleportToMyBrother()
|
||||
{
|
||||
Teleport_Timer = TELEPORTTIME;
|
||||
|
||||
if (IAmVeklor())
|
||||
return; // mechanics handled by veknilash so they teleport exactly at the same time and to correct coordinates
|
||||
|
||||
Creature* pOtherBoss = GetOtherBoss();
|
||||
if (pOtherBoss)
|
||||
{
|
||||
//me->MonsterYell("Teleporting ...", LANG_UNIVERSAL, 0);
|
||||
Position thisPos;
|
||||
thisPos.Relocate(me);
|
||||
Position otherPos;
|
||||
otherPos.Relocate(pOtherBoss);
|
||||
pOtherBoss->SetPosition(thisPos);
|
||||
me->SetPosition(otherPos);
|
||||
|
||||
SetAfterTeleport();
|
||||
CAST_AI(boss_twinemperorsAI, pOtherBoss->AI())->SetAfterTeleport();
|
||||
}
|
||||
}
|
||||
|
||||
void SetAfterTeleport()
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoStopAttack();
|
||||
DoResetThreat();
|
||||
DoCast(me, SPELL_TWIN_TELEPORT_VISUAL);
|
||||
me->AddUnitState(UNIT_STATE_STUNNED);
|
||||
AfterTeleport = true;
|
||||
AfterTeleportTimer = 2000;
|
||||
tspellcast = false;
|
||||
}
|
||||
|
||||
bool TryActivateAfterTTelep(uint32 diff)
|
||||
{
|
||||
if (AfterTeleport)
|
||||
{
|
||||
if (!tspellcast)
|
||||
{
|
||||
me->ClearUnitState(UNIT_STATE_STUNNED);
|
||||
DoCast(me, SPELL_TWIN_TELEPORT);
|
||||
me->AddUnitState(UNIT_STATE_STUNNED);
|
||||
}
|
||||
|
||||
tspellcast = true;
|
||||
|
||||
if (AfterTeleportTimer <= diff)
|
||||
{
|
||||
AfterTeleport = false;
|
||||
me->ClearUnitState(UNIT_STATE_STUNNED);
|
||||
if (Unit* nearu = me->SelectNearestTarget(100))
|
||||
{
|
||||
//DoYell(nearu->GetName(), LANG_UNIVERSAL, 0);
|
||||
AttackStart(nearu);
|
||||
me->AddThreat(nearu, 10000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AfterTeleportTimer -= diff;
|
||||
// update important timers which would otherwise get skipped
|
||||
if (EnrageTimer > diff)
|
||||
EnrageTimer -= diff;
|
||||
else
|
||||
EnrageTimer = 0;
|
||||
if (Teleport_Timer > diff)
|
||||
Teleport_Timer -= diff;
|
||||
else
|
||||
Teleport_Timer = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (!who || me->GetVictim())
|
||||
return;
|
||||
|
||||
if (me->_CanDetectFeignDeathOf(who) && me->CanCreatureAttack(who))
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, PULL_RANGE) && me->GetDistanceZ(who) <= /*CREATURE_Z_ATTACK_RANGE*/7 /*there are stairs*/)
|
||||
{
|
||||
//if (who->HasStealthAura())
|
||||
// who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Creature* RespawnNearbyBugsAndGetOne()
|
||||
{
|
||||
std::list<Creature*> lUnitList;
|
||||
me->GetCreatureListWithEntryInGrid(lUnitList, 15316, 150.0f);
|
||||
me->GetCreatureListWithEntryInGrid(lUnitList, 15317, 150.0f);
|
||||
|
||||
if (lUnitList.empty())
|
||||
return NULL;
|
||||
|
||||
Creature* nearb = NULL;
|
||||
|
||||
for (std::list<Creature*>::const_iterator iter = lUnitList.begin(); iter != lUnitList.end(); ++iter)
|
||||
{
|
||||
Creature* c = *iter;
|
||||
if (c)
|
||||
{
|
||||
if (c->isDead())
|
||||
{
|
||||
c->Respawn();
|
||||
c->setFaction(7);
|
||||
c->RemoveAllAuras();
|
||||
}
|
||||
if (c->IsWithinDistInMap(me, ABUSE_BUG_RANGE))
|
||||
{
|
||||
if (!nearb || (rand()%4) == 0)
|
||||
nearb = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nearb;
|
||||
}
|
||||
|
||||
void HandleBugs(uint32 diff)
|
||||
{
|
||||
if (BugsTimer < diff || Abuse_Bug_Timer <= diff)
|
||||
{
|
||||
Creature* c = RespawnNearbyBugsAndGetOne();
|
||||
if (Abuse_Bug_Timer <= diff)
|
||||
{
|
||||
if (c)
|
||||
{
|
||||
CastSpellOnBug(c);
|
||||
Abuse_Bug_Timer = urand(10000, 17000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Abuse_Bug_Timer = 1000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abuse_Bug_Timer -= diff;
|
||||
}
|
||||
BugsTimer = 2000;
|
||||
}
|
||||
else
|
||||
{
|
||||
BugsTimer -= diff;
|
||||
Abuse_Bug_Timer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckEnrage(uint32 diff)
|
||||
{
|
||||
if (EnrageTimer <= diff)
|
||||
{
|
||||
if (!me->IsNonMeleeSpellCast(true))
|
||||
{
|
||||
DoCast(me, SPELL_BERSERK);
|
||||
EnrageTimer = 60*60000;
|
||||
} else EnrageTimer = 0;
|
||||
} else EnrageTimer-=diff;
|
||||
}
|
||||
};
|
||||
|
||||
class boss_veknilash : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_veknilash() : CreatureScript("boss_veknilash") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_veknilashAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_veknilashAI : public boss_twinemperorsAI
|
||||
{
|
||||
bool IAmVeklor() {return false;}
|
||||
boss_veknilashAI(Creature* creature) : boss_twinemperorsAI(creature) { }
|
||||
|
||||
uint32 UpperCut_Timer;
|
||||
uint32 UnbalancingStrike_Timer;
|
||||
uint32 Scarabs_Timer;
|
||||
int Rand;
|
||||
int RandX;
|
||||
int RandY;
|
||||
|
||||
Creature* Summoned;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
TwinReset();
|
||||
UpperCut_Timer = urand(14000, 29000);
|
||||
UnbalancingStrike_Timer = urand(8000, 18000);
|
||||
Scarabs_Timer = urand(7000, 14000);
|
||||
|
||||
//Added. Can be removed if its included in DB.
|
||||
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
|
||||
}
|
||||
|
||||
void CastSpellOnBug(Creature* target)
|
||||
{
|
||||
target->setFaction(14);
|
||||
target->AI()->AttackStart(me->getThreatManager().getHostilTarget());
|
||||
target->AddAura(SPELL_MUTATE_BUG, target);
|
||||
target->SetFullHealth();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!TryActivateAfterTTelep(diff))
|
||||
return;
|
||||
|
||||
//UnbalancingStrike_Timer
|
||||
if (UnbalancingStrike_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_UNBALANCING_STRIKE);
|
||||
UnbalancingStrike_Timer = 8000+rand()%12000;
|
||||
} else UnbalancingStrike_Timer -= diff;
|
||||
|
||||
if (UpperCut_Timer <= diff)
|
||||
{
|
||||
Unit* randomMelee = SelectTarget(SELECT_TARGET_RANDOM, 0, NOMINAL_MELEE_RANGE, true);
|
||||
if (randomMelee)
|
||||
DoCast(randomMelee, SPELL_UPPERCUT);
|
||||
UpperCut_Timer = 15000+rand()%15000;
|
||||
} else UpperCut_Timer -= diff;
|
||||
|
||||
HandleBugs(diff);
|
||||
|
||||
//Heal brother when 60yrds close
|
||||
TryHealBrother(diff);
|
||||
|
||||
//Teleporting to brother
|
||||
if (Teleport_Timer <= diff)
|
||||
{
|
||||
TeleportToMyBrother();
|
||||
} else Teleport_Timer -= diff;
|
||||
|
||||
CheckEnrage(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class boss_veklor : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_veklor() : CreatureScript("boss_veklor") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_veklorAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_veklorAI : public boss_twinemperorsAI
|
||||
{
|
||||
bool IAmVeklor() {return true;}
|
||||
boss_veklorAI(Creature* creature) : boss_twinemperorsAI(creature) { }
|
||||
|
||||
uint32 ShadowBolt_Timer;
|
||||
uint32 Blizzard_Timer;
|
||||
uint32 ArcaneBurst_Timer;
|
||||
uint32 Scorpions_Timer;
|
||||
int Rand;
|
||||
int RandX;
|
||||
int RandY;
|
||||
|
||||
Creature* Summoned;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
TwinReset();
|
||||
ShadowBolt_Timer = 0;
|
||||
Blizzard_Timer = urand(15000, 20000);
|
||||
ArcaneBurst_Timer = 1000;
|
||||
Scorpions_Timer = urand(7000, 14000);
|
||||
|
||||
//Added. Can be removed if its included in DB.
|
||||
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true);
|
||||
}
|
||||
|
||||
void CastSpellOnBug(Creature* target)
|
||||
{
|
||||
target->setFaction(14);
|
||||
target->AddAura(SPELL_EXPLODEBUG, target);
|
||||
target->SetFullHealth();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// reset arcane burst after teleport - we need to do this because
|
||||
// when VL jumps to VN's location there will be a warrior who will get only 2s to run away
|
||||
// which is almost impossible
|
||||
if (AfterTeleport)
|
||||
ArcaneBurst_Timer = 5000;
|
||||
if (!TryActivateAfterTTelep(diff))
|
||||
return;
|
||||
|
||||
//ShadowBolt_Timer
|
||||
if (ShadowBolt_Timer <= diff)
|
||||
{
|
||||
if (!me->IsWithinDist(me->GetVictim(), 45.0f))
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim(), VEKLOR_DIST, 0);
|
||||
else
|
||||
DoCastVictim(SPELL_SHADOWBOLT);
|
||||
ShadowBolt_Timer = 2000;
|
||||
} else ShadowBolt_Timer -= diff;
|
||||
|
||||
//Blizzard_Timer
|
||||
if (Blizzard_Timer <= diff)
|
||||
{
|
||||
Unit* target = NULL;
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45, true);
|
||||
if (target)
|
||||
DoCast(target, SPELL_BLIZZARD);
|
||||
Blizzard_Timer = 15000+rand()%15000;
|
||||
} else Blizzard_Timer -= diff;
|
||||
|
||||
if (ArcaneBurst_Timer <= diff)
|
||||
{
|
||||
Unit* mvic;
|
||||
if ((mvic=SelectTarget(SELECT_TARGET_NEAREST, 0, NOMINAL_MELEE_RANGE, true)) != NULL)
|
||||
{
|
||||
DoCast(mvic, SPELL_ARCANEBURST);
|
||||
ArcaneBurst_Timer = 5000;
|
||||
}
|
||||
} else ArcaneBurst_Timer -= diff;
|
||||
|
||||
HandleBugs(diff);
|
||||
|
||||
//Heal brother when 60yrds close
|
||||
TryHealBrother(diff);
|
||||
|
||||
//Teleporting to brother
|
||||
if (Teleport_Timer <= diff)
|
||||
{
|
||||
TeleportToMyBrother();
|
||||
} else Teleport_Timer -= diff;
|
||||
|
||||
CheckEnrage(diff);
|
||||
|
||||
//VL doesn't melee
|
||||
//DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who)
|
||||
{
|
||||
if (!who)
|
||||
return;
|
||||
|
||||
if (who->isTargetableForAttack())
|
||||
{
|
||||
// VL doesn't melee
|
||||
if (me->Attack(who, false))
|
||||
{
|
||||
me->GetMotionMaster()->MoveChase(who, VEKLOR_DIST, 0);
|
||||
me->AddThreat(who, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_twinemperors()
|
||||
{
|
||||
new boss_veknilash();
|
||||
new boss_veklor();
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_POISON_SHOCK = 25993,
|
||||
SPELL_POISONBOLT_VOLLEY = 25991,
|
||||
SPELL_TOXIN = 26575,
|
||||
SPELL_VISCIDUS_SLOWED = 26034,
|
||||
SPELL_VISCIDUS_SLOWED_MORE = 26036,
|
||||
SPELL_VISCIDUS_FREEZE = 25937,
|
||||
SPELL_REJOIN_VISCIDUS = 25896,
|
||||
SPELL_VISCIDUS_EXPLODE = 25938,
|
||||
SPELL_VISCIDUS_SUICIDE = 26003,
|
||||
SPELL_VISCIDUS_SHRINKS = 25893, // Removed from client, in world.spell_dbc
|
||||
|
||||
SPELL_MEMBRANE_VISCIDUS = 25994, // damage reduction spell - removed from DBC
|
||||
SPELL_VISCIDUS_WEAKNESS = 25926, // aura which procs at damage - should trigger the slow spells - removed from DBC
|
||||
SPELL_VISCIDUS_GROWS = 25897, // removed from DBC
|
||||
SPELL_SUMMON_GLOBS = 25885, // summons npc 15667 using spells from 25865 to 25884; All spells have target coords - removed from DBC
|
||||
SPELL_VISCIDUS_TELEPORT = 25904, // removed from DBC
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_POISONBOLT_VOLLEY = 1,
|
||||
EVENT_POISON_SHOCK = 2,
|
||||
EVENT_RESET_PHASE = 3
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_FROST = 1,
|
||||
PHASE_MELEE = 2,
|
||||
PHASE_GLOB = 3
|
||||
};
|
||||
|
||||
enum Emotes
|
||||
{
|
||||
EMOTE_SLOW = 0,
|
||||
EMOTE_FREEZE = 1,
|
||||
EMOTE_FROZEN = 2,
|
||||
|
||||
EMOTE_CRACK = 3,
|
||||
EMOTE_SHATTER = 4,
|
||||
EMOTE_EXPLODE = 5
|
||||
};
|
||||
|
||||
enum HitCounter
|
||||
{
|
||||
HITCOUNTER_SLOW = 100,
|
||||
HITCOUNTER_SLOW_MORE = 150,
|
||||
HITCOUNTER_FREEZE = 200,
|
||||
|
||||
HITCOUNTER_CRACK = 50,
|
||||
HITCOUNTER_SHATTER = 100,
|
||||
HITCOUNTER_EXPLODE = 150,
|
||||
};
|
||||
|
||||
enum MovePoints
|
||||
{
|
||||
ROOM_CENTER = 1
|
||||
};
|
||||
|
||||
Position const ViscidusCoord = { -7992.36f, 908.19f, -52.62f, 1.68f }; /// @todo Visci isn't in room middle
|
||||
float const RoomRadius = 40.0f; /// @todo Not sure if its correct
|
||||
|
||||
class boss_viscidus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_viscidus() : CreatureScript("boss_viscidus") { }
|
||||
|
||||
struct boss_viscidusAI : public BossAI
|
||||
{
|
||||
boss_viscidusAI(Creature* creature) : BossAI(creature, DATA_VISCIDUS) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
_hitcounter = 0;
|
||||
_phase = PHASE_FROST;
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32& /*damage*/, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (!attacker || _phase != PHASE_MELEE)
|
||||
return;
|
||||
|
||||
++_hitcounter;
|
||||
|
||||
if (attacker->HasUnitState(UNIT_STATE_MELEE_ATTACKING) && _hitcounter >= HITCOUNTER_EXPLODE)
|
||||
{
|
||||
Talk(EMOTE_EXPLODE);
|
||||
events.Reset();
|
||||
_phase = PHASE_GLOB;
|
||||
DoCast(me, SPELL_VISCIDUS_EXPLODE);
|
||||
me->SetVisible(false);
|
||||
me->RemoveAura(SPELL_TOXIN);
|
||||
me->RemoveAura(SPELL_VISCIDUS_FREEZE);
|
||||
|
||||
uint8 NumGlobes = me->GetHealthPct() / 5.0f;
|
||||
for (uint8 i = 0; i < NumGlobes; ++i)
|
||||
{
|
||||
float Angle = i * 2 * M_PI / NumGlobes;
|
||||
float X = ViscidusCoord.GetPositionX() + std::cos(Angle) * RoomRadius;
|
||||
float Y = ViscidusCoord.GetPositionY() + std::sin(Angle) * RoomRadius;
|
||||
float Z = -35.0f;
|
||||
|
||||
if (TempSummon* Glob = me->SummonCreature(NPC_GLOB_OF_VISCIDUS, X, Y, Z))
|
||||
{
|
||||
Glob->UpdateAllowedPositionZ(X, Y, Z);
|
||||
Glob->NearTeleportTo(X, Y, Z, 0.0f);
|
||||
Glob->GetMotionMaster()->MovePoint(ROOM_CENTER, ViscidusCoord);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_hitcounter == HITCOUNTER_SHATTER)
|
||||
Talk(EMOTE_SHATTER);
|
||||
else if (_hitcounter == HITCOUNTER_CRACK)
|
||||
Talk(EMOTE_CRACK);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell)
|
||||
{
|
||||
if ((spell->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST) && _phase == PHASE_FROST && me->GetHealthPct() > 5.0f)
|
||||
{
|
||||
++_hitcounter;
|
||||
|
||||
if (_hitcounter >= HITCOUNTER_FREEZE)
|
||||
{
|
||||
_hitcounter = 0;
|
||||
Talk(EMOTE_FROZEN);
|
||||
_phase = PHASE_MELEE;
|
||||
DoCast(me, SPELL_VISCIDUS_FREEZE);
|
||||
me->RemoveAura(SPELL_VISCIDUS_SLOWED_MORE);
|
||||
events.ScheduleEvent(EVENT_RESET_PHASE, 15000);
|
||||
}
|
||||
else if (_hitcounter >= HITCOUNTER_SLOW_MORE)
|
||||
{
|
||||
Talk(EMOTE_FREEZE);
|
||||
me->RemoveAura(SPELL_VISCIDUS_SLOWED);
|
||||
DoCast(me, SPELL_VISCIDUS_SLOWED_MORE);
|
||||
}
|
||||
else if (_hitcounter >= HITCOUNTER_SLOW)
|
||||
{
|
||||
Talk(EMOTE_SLOW);
|
||||
DoCast(me, SPELL_VISCIDUS_SLOWED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.Reset();
|
||||
InitSpells();
|
||||
}
|
||||
|
||||
void InitSpells()
|
||||
{
|
||||
DoCast(me, SPELL_TOXIN);
|
||||
events.ScheduleEvent(EVENT_POISONBOLT_VOLLEY, urand(10000, 15000));
|
||||
events.ScheduleEvent(EVENT_POISON_SHOCK, urand(7000, 12000));
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
summons.DespawnAll();
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
DoCast(me, SPELL_VISCIDUS_SUICIDE);
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (_phase == PHASE_GLOB && summons.empty())
|
||||
{
|
||||
DoResetThreat();
|
||||
me->NearTeleportTo(ViscidusCoord.GetPositionX(),
|
||||
ViscidusCoord.GetPositionY(),
|
||||
ViscidusCoord.GetPositionZ(),
|
||||
ViscidusCoord.GetOrientation());
|
||||
|
||||
_hitcounter = 0;
|
||||
_phase = PHASE_FROST;
|
||||
InitSpells();
|
||||
me->SetVisible(true);
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_POISONBOLT_VOLLEY:
|
||||
DoCast(me, SPELL_POISONBOLT_VOLLEY);
|
||||
events.ScheduleEvent(EVENT_POISONBOLT_VOLLEY, urand(10000, 15000));
|
||||
break;
|
||||
case EVENT_POISON_SHOCK:
|
||||
DoCast(me, SPELL_POISON_SHOCK);
|
||||
events.ScheduleEvent(EVENT_POISON_SHOCK, urand(7000, 12000));
|
||||
break;
|
||||
case EVENT_RESET_PHASE:
|
||||
_hitcounter = 0;
|
||||
_phase = PHASE_FROST;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_phase != PHASE_GLOB)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _hitcounter;
|
||||
Phases _phase;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_viscidusAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_glob_of_viscidus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_glob_of_viscidus() : CreatureScript("boss_glob_of_viscidus") { }
|
||||
|
||||
struct npc_glob_of_viscidusAI : public ScriptedAI
|
||||
{
|
||||
npc_glob_of_viscidusAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
InstanceScript* Instance = me->GetInstanceScript();
|
||||
|
||||
if (Creature* Viscidus = me->GetMap()->GetCreature(Instance->GetData64(DATA_VISCIDUS)))
|
||||
{
|
||||
if (BossAI* ViscidusAI = dynamic_cast<BossAI*>(Viscidus->GetAI()))
|
||||
ViscidusAI->SummonedCreatureDespawn(me);
|
||||
|
||||
if (Viscidus->IsAlive() && Viscidus->GetHealthPct() < 5.0f)
|
||||
{
|
||||
Viscidus->SetVisible(true);
|
||||
Unit::Kill(Viscidus->GetVictim(), Viscidus);
|
||||
}
|
||||
else
|
||||
{
|
||||
Viscidus->SetHealth(Viscidus->GetHealth() - Viscidus->GetMaxHealth() / 20);
|
||||
Viscidus->CastSpell(Viscidus, SPELL_VISCIDUS_SHRINKS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 /*type*/, uint32 id)
|
||||
{
|
||||
if (id == ROOM_CENTER)
|
||||
{
|
||||
DoCast(me, SPELL_REJOIN_VISCIDUS);
|
||||
if (TempSummon* summon = me->ToTempSummon())
|
||||
summon->UnSummon();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_glob_of_viscidusAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_viscidus()
|
||||
{
|
||||
new boss_viscidus();
|
||||
new npc_glob_of_viscidus();
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Instance_Temple_of_Ahnqiraj
|
||||
SD%Complete: 80
|
||||
SDComment:
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
|
||||
class instance_temple_of_ahnqiraj : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_temple_of_ahnqiraj() : InstanceMapScript("instance_temple_of_ahnqiraj", 531) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_temple_of_ahnqiraj_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_temple_of_ahnqiraj_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_temple_of_ahnqiraj_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
//If Vem is dead...
|
||||
bool IsBossDied[3];
|
||||
|
||||
//Storing Skeram, Vem and Kri.
|
||||
uint64 SkeramGUID;
|
||||
uint64 VemGUID;
|
||||
uint64 KriGUID;
|
||||
uint64 VeklorGUID;
|
||||
uint64 VeknilashGUID;
|
||||
uint64 ViscidusGUID;
|
||||
|
||||
uint32 BugTrioDeathCount;
|
||||
|
||||
uint32 CthunPhase;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
IsBossDied[0] = false;
|
||||
IsBossDied[1] = false;
|
||||
IsBossDied[2] = false;
|
||||
|
||||
SkeramGUID = 0;
|
||||
VemGUID = 0;
|
||||
KriGUID = 0;
|
||||
VeklorGUID = 0;
|
||||
VeknilashGUID = 0;
|
||||
ViscidusGUID = 0;
|
||||
|
||||
BugTrioDeathCount = 0;
|
||||
|
||||
CthunPhase = 0;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_SKERAM:
|
||||
SkeramGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VEM:
|
||||
VemGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_KRI:
|
||||
KriGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VEKLOR:
|
||||
VeklorGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VEKNILASH:
|
||||
VeknilashGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VISCIDUS:
|
||||
ViscidusGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
//not active in AQ40
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_VEMISDEAD:
|
||||
if (IsBossDied[0])
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case DATA_VEKLORISDEAD:
|
||||
if (IsBossDied[1])
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case DATA_VEKNILASHISDEAD:
|
||||
if (IsBossDied[2])
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case DATA_BUG_TRIO_DEATH:
|
||||
return BugTrioDeathCount;
|
||||
|
||||
case DATA_CTHUN_PHASE:
|
||||
return CthunPhase;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 identifier) const
|
||||
{
|
||||
switch (identifier)
|
||||
{
|
||||
case DATA_SKERAM:
|
||||
return SkeramGUID;
|
||||
case DATA_VEM:
|
||||
return VemGUID;
|
||||
case DATA_KRI:
|
||||
return KriGUID;
|
||||
case DATA_VEKLOR:
|
||||
return VeklorGUID;
|
||||
case DATA_VEKNILASH:
|
||||
return VeknilashGUID;
|
||||
case DATA_VISCIDUS:
|
||||
return ViscidusGUID;
|
||||
}
|
||||
return 0;
|
||||
} // end GetData64
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_VEM_DEATH:
|
||||
IsBossDied[0] = true;
|
||||
break;
|
||||
|
||||
case DATA_BUG_TRIO_DEATH:
|
||||
++BugTrioDeathCount;
|
||||
break;
|
||||
|
||||
case DATA_VEKLOR_DEATH:
|
||||
IsBossDied[1] = true;
|
||||
break;
|
||||
|
||||
case DATA_VEKNILASH_DEATH:
|
||||
IsBossDied[2] = true;
|
||||
break;
|
||||
|
||||
case DATA_CTHUN_PHASE:
|
||||
CthunPhase = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_instance_temple_of_ahnqiraj()
|
||||
{
|
||||
new instance_temple_of_ahnqiraj();
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: npc_anubisath_sentinel
|
||||
SD%Complete: 95
|
||||
SDComment: Shadow storm is not properly implemented in core it should only target ppl outside of melee range.
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
#include "Item.h"
|
||||
#include "Player.h"
|
||||
#include "Spell.h"
|
||||
|
||||
#include "Cell.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MENDING_BUFF = 2147,
|
||||
|
||||
SPELL_KNOCK_BUFF = 21737,
|
||||
SPELL_KNOCK = 25778,
|
||||
SPELL_MANAB_BUFF = 812,
|
||||
SPELL_MANAB = 25779,
|
||||
|
||||
SPELL_REFLECTAF_BUFF = 13022,
|
||||
SPELL_REFLECTSFr_BUFF = 19595,
|
||||
SPELL_THORNS_BUFF = 25777,
|
||||
|
||||
SPELL_THUNDER_BUFF = 2834,
|
||||
SPELL_THUNDER = 8732,
|
||||
|
||||
SPELL_MSTRIKE_BUFF = 9347,
|
||||
SPELL_MSTRIKE = 24573,
|
||||
|
||||
SPELL_STORM_BUFF = 2148,
|
||||
SPELL_STORM = 26546
|
||||
};
|
||||
|
||||
class npc_anubisath_sentinel : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_anubisath_sentinel() : CreatureScript("npc_anubisath_sentinel") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new aqsentinelAI(creature);
|
||||
}
|
||||
|
||||
struct aqsentinelAI : public ScriptedAI
|
||||
{
|
||||
uint32 ability;
|
||||
int abselected;
|
||||
|
||||
void selectAbility(int asel)
|
||||
{
|
||||
switch (asel)
|
||||
{
|
||||
case 0: ability = SPELL_MENDING_BUFF;break;
|
||||
case 1: ability = SPELL_KNOCK_BUFF;break;
|
||||
case 2: ability = SPELL_MANAB_BUFF;break;
|
||||
case 3: ability = SPELL_REFLECTAF_BUFF;break;
|
||||
case 4: ability = SPELL_REFLECTSFr_BUFF;break;
|
||||
case 5: ability = SPELL_THORNS_BUFF;break;
|
||||
case 6: ability = SPELL_THUNDER_BUFF;break;
|
||||
case 7: ability = SPELL_MSTRIKE_BUFF;break;
|
||||
case 8: ability = SPELL_STORM_BUFF;break;
|
||||
}
|
||||
}
|
||||
|
||||
aqsentinelAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
ClearBuddyList();
|
||||
abselected = 0; // just initialization of variable
|
||||
}
|
||||
|
||||
uint64 NearbyGUID[3];
|
||||
|
||||
void ClearBuddyList()
|
||||
{
|
||||
NearbyGUID[0] = NearbyGUID[1] = NearbyGUID[2] = 0;
|
||||
}
|
||||
|
||||
void AddBuddyToList(uint64 CreatureGUID)
|
||||
{
|
||||
if (CreatureGUID == me->GetGUID())
|
||||
return;
|
||||
|
||||
for (int i=0; i<3; ++i)
|
||||
{
|
||||
if (NearbyGUID[i] == CreatureGUID)
|
||||
return;
|
||||
if (!NearbyGUID[i])
|
||||
{
|
||||
NearbyGUID[i] = CreatureGUID;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GiveBuddyMyList(Creature* c)
|
||||
{
|
||||
aqsentinelAI* cai = CAST_AI(aqsentinelAI, (c)->AI());
|
||||
for (int i=0; i<3; ++i)
|
||||
if (NearbyGUID[i] && NearbyGUID[i] != c->GetGUID())
|
||||
cai->AddBuddyToList(NearbyGUID[i]);
|
||||
cai->AddBuddyToList(me->GetGUID());
|
||||
}
|
||||
|
||||
void SendMyListToBuddies()
|
||||
{
|
||||
for (int i=0; i<3; ++i)
|
||||
if (Creature* pNearby = ObjectAccessor::GetCreature(*me, NearbyGUID[i]))
|
||||
GiveBuddyMyList(pNearby);
|
||||
}
|
||||
|
||||
void CallBuddiesToAttack(Unit* who)
|
||||
{
|
||||
for (int i=0; i<3; ++i)
|
||||
{
|
||||
Creature* c = ObjectAccessor::GetCreature(*me, NearbyGUID[i]);
|
||||
if (c)
|
||||
{
|
||||
if (!c->IsInCombat())
|
||||
{
|
||||
c->SetNoCallAssistance(true);
|
||||
if (c->AI())
|
||||
c->AI()->AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddSentinelsNear(Unit* /*nears*/)
|
||||
{
|
||||
std::list<Creature*> assistList;
|
||||
me->GetCreatureListWithEntryInGrid(assistList, 15264, 70.0f);
|
||||
|
||||
if (assistList.empty())
|
||||
return;
|
||||
|
||||
for (std::list<Creature*>::const_iterator iter = assistList.begin(); iter != assistList.end(); ++iter)
|
||||
AddBuddyToList((*iter)->GetGUID());
|
||||
}
|
||||
|
||||
int pickAbilityRandom(bool *chosenAbilities)
|
||||
{
|
||||
for (int t = 0; t < 2; ++t)
|
||||
{
|
||||
for (int i = !t ? (rand()%9) : 0; i < 9; ++i)
|
||||
{
|
||||
if (!chosenAbilities[i])
|
||||
{
|
||||
chosenAbilities[i] = true;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; // should never happen
|
||||
}
|
||||
|
||||
void GetOtherSentinels(Unit* who)
|
||||
{
|
||||
bool *chosenAbilities = new bool[9];
|
||||
memset(chosenAbilities, 0, 9*sizeof(bool));
|
||||
selectAbility(pickAbilityRandom(chosenAbilities));
|
||||
|
||||
ClearBuddyList();
|
||||
AddSentinelsNear(me);
|
||||
int bli;
|
||||
for (bli = 0; bli < 3; ++bli)
|
||||
{
|
||||
if (!NearbyGUID[bli])
|
||||
break;
|
||||
|
||||
Creature* pNearby = ObjectAccessor::GetCreature(*me, NearbyGUID[bli]);
|
||||
if (!pNearby)
|
||||
break;
|
||||
|
||||
AddSentinelsNear(pNearby);
|
||||
CAST_AI(aqsentinelAI, pNearby->AI())->gatherOthersWhenAggro = false;
|
||||
CAST_AI(aqsentinelAI, pNearby->AI())->selectAbility(pickAbilityRandom(chosenAbilities));
|
||||
}
|
||||
/*if (bli < 3)
|
||||
DoYell("I dont have enough buddies.", LANG_NEUTRAL, 0);*/
|
||||
SendMyListToBuddies();
|
||||
CallBuddiesToAttack(who);
|
||||
|
||||
delete[] chosenAbilities;
|
||||
}
|
||||
|
||||
bool gatherOthersWhenAggro;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (!me->isDead())
|
||||
{
|
||||
for (int i=0; i<3; ++i)
|
||||
{
|
||||
if (!NearbyGUID[i])
|
||||
continue;
|
||||
if (Creature* pNearby = ObjectAccessor::GetCreature(*me, NearbyGUID[i]))
|
||||
{
|
||||
if (pNearby->isDead())
|
||||
pNearby->Respawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
ClearBuddyList();
|
||||
gatherOthersWhenAggro = true;
|
||||
}
|
||||
|
||||
void GainSentinelAbility(uint32 id)
|
||||
{
|
||||
me->AddAura(id, me);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
if (gatherOthersWhenAggro)
|
||||
GetOtherSentinels(who);
|
||||
|
||||
GainSentinelAbility(ability);
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
for (int ni=0; ni<3; ++ni)
|
||||
{
|
||||
Creature* sent = ObjectAccessor::GetCreature(*me, NearbyGUID[ni]);
|
||||
if (!sent)
|
||||
continue;
|
||||
if (sent->isDead())
|
||||
continue;
|
||||
sent->ModifyHealth(int32(sent->CountPctFromMaxHealth(50)));
|
||||
CAST_AI(aqsentinelAI, sent->AI())->GainSentinelAbility(ability);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_npc_anubisath_sentinel()
|
||||
{
|
||||
new npc_anubisath_sentinel();
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DEF_TEMPLE_OF_AHNQIRAJ_H
|
||||
#define DEF_TEMPLE_OF_AHNQIRAJ_H
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
DATA_SKERAM = 1,
|
||||
DATA_KRI = 2,
|
||||
DATA_VEM = 3,
|
||||
DATA_VEMISDEAD = 4,
|
||||
DATA_VEM_DEATH = 5,
|
||||
DATA_VEKLOR = 6,
|
||||
DATA_VEKLORISDEAD = 7,
|
||||
DATA_VEKLOR_DEATH = 8,
|
||||
DATA_VEKNILASH = 9,
|
||||
DATA_VEKNILASHISDEAD = 10,
|
||||
DATA_VEKNILASH_DEATH = 11,
|
||||
DATA_BUG_TRIO_DEATH = 14,
|
||||
DATA_CTHUN_PHASE = 20,
|
||||
DATA_VISCIDUS = 21
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
BOSS_EYE_OF_CTHUN = 15589,
|
||||
NPC_CTHUN_PORTAL = 15896,
|
||||
NPC_CLAW_TENTACLE = 15725,
|
||||
NPC_EYE_TENTACLE = 15726,
|
||||
NPC_SMALL_PORTAL = 15904,
|
||||
NPC_BODY_OF_CTHUN = 15809,
|
||||
NPC_GIANT_CLAW_TENTACLE = 15728,
|
||||
NPC_GIANT_EYE_TENTACLE = 15334,
|
||||
NPC_FLESH_TENTACLE = 15802,
|
||||
NPC_GIANT_PORTAL = 15910,
|
||||
|
||||
NPC_VISCIDUS = 15299,
|
||||
NPC_GLOB_OF_VISCIDUS = 15667,
|
||||
|
||||
NPC_SKERAM = 15263,
|
||||
NPC_VEM = 15544,
|
||||
NPC_KRI = 15511,
|
||||
NPC_VEKLOR = 15276,
|
||||
NPC_VEKNILASH = 15275
|
||||
};
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user